mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Merge pull request #7105 from PeterPetrik/quick-3-identity
[qgsquick] [feature] Identify and highlight
This commit is contained in:
commit
c780d607cc
66
python/core/auto_generated/qgstessellator.sip.in
Normal file
66
python/core/auto_generated/qgstessellator.sip.in
Normal file
@ -0,0 +1,66 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/qgstessellator.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsTessellator
|
||||
{
|
||||
%Docstring
|
||||
Class that takes care of tessellation of polygons into triangles.
|
||||
|
||||
It is expected that client code will create the tessellator object, then repeatedly call
|
||||
addPolygon() method that will generate triangles, and finally call data() to get final vertex data.
|
||||
|
||||
Optionally provides extrusion by adding triangles that serve as walls when extrusion height is non-zero.
|
||||
|
||||
.. versionadded:: 3.4
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgstessellator.h"
|
||||
%End
|
||||
public:
|
||||
QgsTessellator( double originX, double originY, bool addNormals, bool invertNormals = false, bool addBackFaces = false );
|
||||
%Docstring
|
||||
Creates tessellator with a specified origin point of the world (in map coordinates)
|
||||
%End
|
||||
|
||||
void addPolygon( const QgsPolygon &polygon, float extrusionHeight );
|
||||
%Docstring
|
||||
Tessellates a triangle and adds its vertex entries to the output data array
|
||||
%End
|
||||
|
||||
QVector<float> data() const;
|
||||
%Docstring
|
||||
Returns array of triangle vertex data
|
||||
|
||||
Vertice coordinates are stored as (x, z, -y)
|
||||
%End
|
||||
|
||||
int dataVerticesCount() const;
|
||||
%Docstring
|
||||
Returns the number of vertices stored in the output data array
|
||||
%End
|
||||
|
||||
int stride() const;
|
||||
%Docstring
|
||||
Returns size of one vertex entry in bytes
|
||||
%End
|
||||
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/qgstessellator.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -3,6 +3,7 @@
|
||||
%Include auto_generated/expression/qgsexpressionnode.sip
|
||||
%Include auto_generated/expression/qgsexpressionnodeimpl.sip
|
||||
%Include auto_generated/expression/qgsexpressionfunction.sip
|
||||
%Include auto_generated/qgstessellator.sip
|
||||
%Include auto_generated/qgis.sip
|
||||
%Include auto_generated/qgsaction.sip
|
||||
%Include auto_generated/qgsactionscope.sip
|
||||
|
@ -9,7 +9,6 @@ SET(QGIS_3D_SRCS
|
||||
qgscameracontroller.cpp
|
||||
qgsphongmaterialsettings.cpp
|
||||
qgstessellatedpolygongeometry.cpp
|
||||
qgstessellator.cpp
|
||||
qgstilingscheme.cpp
|
||||
qgsvectorlayer3drenderer.cpp
|
||||
|
||||
@ -41,12 +40,6 @@ SET(QGIS_3D_SRCS
|
||||
terrain/qgsterraintileloader_p.cpp
|
||||
#terrain/quantizedmeshgeometry.cpp
|
||||
#terrain/quantizedmeshterraingenerator.cpp
|
||||
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri/common/shapes.cc
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri/sweep/advancing_front.cc
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri/sweep/cdt.cc
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri/sweep/sweep_context.cc
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri/sweep/sweep.cc
|
||||
)
|
||||
|
||||
SET(QGIS_3D_MOC_HDRS
|
||||
@ -82,7 +75,6 @@ SET(QGIS_3D_HDRS
|
||||
qgscameracontroller.h
|
||||
qgsphongmaterialsettings.h
|
||||
qgstessellatedpolygongeometry.h
|
||||
qgstessellator.h
|
||||
qgstilingscheme.h
|
||||
qgsvectorlayer3drenderer.h
|
||||
|
||||
@ -127,7 +119,6 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
${CMAKE_SOURCE_DIR}/src/core/3d
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri
|
||||
${CMAKE_BINARY_DIR}/src/core
|
||||
${CMAKE_BINARY_DIR}/src/3d
|
||||
)
|
||||
|
@ -10,6 +10,12 @@ SET(QGIS_CORE_SRCS
|
||||
${CMAKE_SOURCE_DIR}/external/nmea/time.c
|
||||
${CMAKE_SOURCE_DIR}/external/nmea/tok.c
|
||||
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri/common/shapes.cc
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri/sweep/advancing_front.cc
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri/sweep/cdt.cc
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri/sweep/sweep_context.cc
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri/sweep/sweep.cc
|
||||
|
||||
gps/qgsgpsconnection.cpp
|
||||
gps/qgsgpsconnectionregistry.cpp
|
||||
gps/qgsgpsdconnection.cpp
|
||||
@ -291,6 +297,7 @@ SET(QGIS_CORE_SRCS
|
||||
qgsstringstatisticalsummary.cpp
|
||||
qgsstringutils.cpp
|
||||
qgstaskmanager.cpp
|
||||
qgstessellator.cpp
|
||||
qgstextlabelfeature.cpp
|
||||
qgstextrenderer.cpp
|
||||
qgstolerance.cpp
|
||||
@ -811,6 +818,8 @@ SET(QGIS_CORE_HDRS
|
||||
expression/qgsexpressionnodeimpl.h
|
||||
expression/qgsexpressionfunction.h
|
||||
|
||||
qgstessellator.h
|
||||
|
||||
qgis.h
|
||||
qgis_sip.h
|
||||
qgsaction.h
|
||||
@ -1204,6 +1213,7 @@ INCLUDE_DIRECTORIES(
|
||||
metadata
|
||||
mesh
|
||||
${CMAKE_SOURCE_DIR}/external/nmea
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri
|
||||
)
|
||||
IF (WITH_INTERNAL_QEXTSERIALPORT)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/external/qextserialport)
|
||||
|
@ -540,6 +540,11 @@ QgsPoint getPointFromData( QVector< float >::const_iterator &it )
|
||||
return QgsPoint( x, y, z );
|
||||
}
|
||||
|
||||
int QgsTessellator::dataVerticesCount() const
|
||||
{
|
||||
return mData.size() / 3;
|
||||
}
|
||||
|
||||
std::unique_ptr<QgsMultiPolygon> QgsTessellator::asMultiPolygon() const
|
||||
{
|
||||
std::unique_ptr< QgsMultiPolygon > mp = qgis::make_unique< QgsMultiPolygon >();
|
@ -16,16 +16,18 @@
|
||||
#ifndef QGSTESSELLATOR_H
|
||||
#define QGSTESSELLATOR_H
|
||||
|
||||
#include "qgis_3d.h"
|
||||
#include "qgis_core.h"
|
||||
#include "qgis.h"
|
||||
|
||||
class QgsPolygon;
|
||||
class QgsMultiPolygon;
|
||||
|
||||
#include <QVector>
|
||||
#include <memory>
|
||||
#include "qgspoint.h"
|
||||
|
||||
/**
|
||||
* \ingroup 3d
|
||||
* \ingroup core
|
||||
* Class that takes care of tessellation of polygons into triangles.
|
||||
*
|
||||
* It is expected that client code will create the tessellator object, then repeatedly call
|
||||
@ -33,9 +35,9 @@ class QgsMultiPolygon;
|
||||
*
|
||||
* Optionally provides extrusion by adding triangles that serve as walls when extrusion height is non-zero.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
* \since QGIS 3.4 (since QGIS 3.0 in QGIS_3D library)
|
||||
*/
|
||||
class _3D_EXPORT QgsTessellator
|
||||
class CORE_EXPORT QgsTessellator
|
||||
{
|
||||
public:
|
||||
//! Creates tessellator with a specified origin point of the world (in map coordinates)
|
||||
@ -44,15 +46,23 @@ class _3D_EXPORT QgsTessellator
|
||||
//! Tessellates a triangle and adds its vertex entries to the output data array
|
||||
void addPolygon( const QgsPolygon &polygon, float extrusionHeight );
|
||||
|
||||
//! Returns array of triangle vertex data
|
||||
/**
|
||||
* Returns array of triangle vertex data
|
||||
*
|
||||
* Vertice coordinates are stored as (x, z, -y)
|
||||
*/
|
||||
QVector<float> data() const { return mData; }
|
||||
|
||||
//! Returns the number of vertices stored in the output data array
|
||||
int dataVerticesCount() const;
|
||||
|
||||
//! Returns size of one vertex entry in bytes
|
||||
int stride() const { return mStride; }
|
||||
|
||||
/**
|
||||
* Returns the triangulation as a multipolygon geometry.
|
||||
*/
|
||||
std::unique_ptr< QgsMultiPolygon > asMultiPolygon() const;
|
||||
std::unique_ptr< QgsMultiPolygon > asMultiPolygon() const SIP_SKIP;
|
||||
|
||||
private:
|
||||
double mOriginX = 0, mOriginY = 0;
|
@ -1,19 +1,29 @@
|
||||
############################################################
|
||||
# sources
|
||||
SET(QGIS_QUICK_GUI_MOC_HDRS
|
||||
qgsquickfeaturelayerpair.h
|
||||
qgsquickfeaturehighlight.h
|
||||
qgsquickidentifykit.h
|
||||
qgsquickmapcanvasmap.h
|
||||
qgsquickmapsettings.h
|
||||
qgsquickmaptransform.h
|
||||
qgsquickmessagelogmodel.h
|
||||
qgsquickscalebarkit.h
|
||||
qgsquickutils.h
|
||||
)
|
||||
|
||||
SET(QGIS_QUICK_GUI_HDRS
|
||||
qgsquickhighlightsgnode.h
|
||||
)
|
||||
|
||||
SET(QGIS_QUICK_GUI_SRC
|
||||
qgsquickfeaturelayerpair.cpp
|
||||
qgsquickfeaturehighlight.cpp
|
||||
qgsquickhighlightsgnode.cpp
|
||||
qgsquickidentifykit.cpp
|
||||
qgsquickmapcanvasmap.cpp
|
||||
qgsquickmapsettings.cpp
|
||||
qgsquickmaptransform.cpp
|
||||
qgsquickmessagelogmodel.cpp
|
||||
qgsquickscalebarkit.cpp
|
||||
qgsquickutils.cpp
|
||||
|
@ -29,8 +29,12 @@
|
||||
#include "qgscoordinatetransformcontext.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include "qgsquickfeaturehighlight.h"
|
||||
#include "qgsquickidentifykit.h"
|
||||
#include "qgsquickfeaturelayerpair.h"
|
||||
#include "qgsquickmapcanvasmap.h"
|
||||
#include "qgsquickmapsettings.h"
|
||||
#include "qgsquickmaptransform.h"
|
||||
#include "qgsquickmessagelogmodel.h"
|
||||
#include "qgsquickplugin.h"
|
||||
#include "qgsquickscalebarkit.h"
|
||||
@ -53,10 +57,14 @@ void QgsQuickPlugin::registerTypes( const char *uri )
|
||||
qRegisterMetaType< QgsFeatureId > ( "QgsFeatureId" );
|
||||
qRegisterMetaType< QgsPoint >( "QgsPoint" );
|
||||
qRegisterMetaType< QgsPointXY >( "QgsPointXY" );
|
||||
qRegisterMetaType< QgsQuickFeatureLayerPair >( "QgsQuickFeatureLayerPair" );
|
||||
|
||||
qmlRegisterType< QgsProject >( uri, 0, 1, "Project" );
|
||||
qmlRegisterType< QgsQuickFeatureHighlight >( uri, 0, 1, "FeatureHighlight" );
|
||||
qmlRegisterType< QgsQuickIdentifyKit >( uri, 0, 1, "IdentifyKit" );
|
||||
qmlRegisterType< QgsQuickMapCanvasMap >( uri, 0, 1, "MapCanvasMap" );
|
||||
qmlRegisterType< QgsQuickMapSettings >( uri, 0, 1, "MapSettings" );
|
||||
qmlRegisterType< QgsQuickMapTransform >( uri, 0, 1, "MapTransform" );
|
||||
qmlRegisterType< QgsQuickMessageLogModel >( uri, 0, 1, "MessageLogModel" );
|
||||
qmlRegisterType< QgsQuickScaleBarKit >( uri, 0, 1, "ScaleBarKit" );
|
||||
qmlRegisterType< QgsVectorLayer >( uri, 0, 1, "VectorLayer" );
|
||||
|
84
src/quickgui/qgsquickfeaturehighlight.cpp
Normal file
84
src/quickgui/qgsquickfeaturehighlight.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
/***************************************************************************
|
||||
qgsqguickfeaturehighlight.cpp
|
||||
--------------------------------------
|
||||
Date : May 2018
|
||||
Copyright : (C) 2018 by Peter Petrik
|
||||
Email : zilolv at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include "qgsquickfeaturehighlight.h"
|
||||
#include "qgsquickmapsettings.h"
|
||||
#include "qgsquickhighlightsgnode.h"
|
||||
|
||||
|
||||
QgsQuickFeatureHighlight::QgsQuickFeatureHighlight( QQuickItem *parent )
|
||||
: QQuickItem( parent )
|
||||
{
|
||||
setFlags( QQuickItem::ItemHasContents );
|
||||
setAntialiasing( true );
|
||||
|
||||
// transform to device coords
|
||||
mTransform.appendToItem( this );
|
||||
|
||||
connect( this, &QgsQuickFeatureHighlight::mapSettingsChanged, this, &QgsQuickFeatureHighlight::onMapSettingsChanged );
|
||||
connect( this, &QgsQuickFeatureHighlight::featureLayerPairChanged, this, &QgsQuickFeatureHighlight::markDirty );
|
||||
connect( this, &QgsQuickFeatureHighlight::colorChanged, this, &QgsQuickFeatureHighlight::markDirty );
|
||||
connect( this, &QgsQuickFeatureHighlight::widthChanged, this, &QgsQuickFeatureHighlight::markDirty );
|
||||
}
|
||||
|
||||
void QgsQuickFeatureHighlight::markDirty()
|
||||
{
|
||||
mDirty = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void QgsQuickFeatureHighlight::onMapSettingsChanged()
|
||||
{
|
||||
mTransform.setMapSettings( mMapSettings );
|
||||
markDirty();
|
||||
}
|
||||
|
||||
QSGNode *QgsQuickFeatureHighlight::updatePaintNode( QSGNode *n, QQuickItem::UpdatePaintNodeData * )
|
||||
{
|
||||
if ( !mDirty || !mMapSettings || !mFeatureLayerPair.isValid() )
|
||||
return n;
|
||||
|
||||
delete n;
|
||||
n = new QSGNode;
|
||||
|
||||
QgsVectorLayer *layer = mFeatureLayerPair.layer();
|
||||
Q_ASSERT( layer ); // we checked the validity of feature-layer pair
|
||||
QgsCoordinateTransform transf( layer->crs(), mMapSettings->destinationCrs(), mMapSettings->transformContext() );
|
||||
|
||||
QgsFeature feature = mFeatureLayerPair.feature();
|
||||
if ( feature.hasGeometry() )
|
||||
{
|
||||
QgsGeometry geom( feature.geometry() );
|
||||
try
|
||||
{
|
||||
geom.transform( transf );
|
||||
std::unique_ptr<QgsQuickHighlightSGNode> rb( new QgsQuickHighlightSGNode( geom, mColor, mWidth ) );
|
||||
rb->setFlag( QSGNode::OwnedByParent );
|
||||
n->appendChildNode( rb.release() );
|
||||
}
|
||||
catch ( QgsCsException &e )
|
||||
{
|
||||
Q_UNUSED( e );
|
||||
// Caught an error in transform
|
||||
}
|
||||
}
|
||||
mDirty = false;
|
||||
|
||||
return n;
|
||||
}
|
99
src/quickgui/qgsquickfeaturehighlight.h
Normal file
99
src/quickgui/qgsquickfeaturehighlight.h
Normal file
@ -0,0 +1,99 @@
|
||||
/***************************************************************************
|
||||
qgsqguickfeaturehighlight.h
|
||||
---------------------------
|
||||
Date : May 2018
|
||||
Copyright : (C) 2018 by Peter Petrik
|
||||
Email : zilolv at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSQUICKFEATUREHIGHLIGHT_H
|
||||
#define QGSQUICKFEATUREHIGHLIGHT_H
|
||||
|
||||
#include <QQuickItem>
|
||||
|
||||
#include "qgsquickfeaturelayerpair.h"
|
||||
#include "qgis_quick.h"
|
||||
#include "qgsquickmaptransform.h"
|
||||
|
||||
class QgsQuickMapSettings;
|
||||
|
||||
/**
|
||||
* \ingroup quick
|
||||
*
|
||||
* Creates map highlights for a geometry provided by a FeatureModel.
|
||||
*
|
||||
* The highlights are compatible with the QtQuick scene graph and
|
||||
* can be direcly shown on map canvas
|
||||
*
|
||||
* \note QML Type: FeatureHighlight
|
||||
*
|
||||
* \since QGIS 3.4
|
||||
*/
|
||||
class QUICK_EXPORT QgsQuickFeatureHighlight : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
/**
|
||||
* Associated map settings. Should be initialized from QML component before the first use.
|
||||
*/
|
||||
Q_PROPERTY( QgsQuickMapSettings *mapSettings MEMBER mMapSettings NOTIFY mapSettingsChanged )
|
||||
|
||||
/**
|
||||
* Feature to highlight
|
||||
*/
|
||||
Q_PROPERTY( QgsQuickFeatureLayerPair featureLayerPair MEMBER mFeatureLayerPair NOTIFY featureLayerPairChanged )
|
||||
|
||||
/**
|
||||
* Color of the highlighted geometry (feature).
|
||||
*
|
||||
* Default is yellow color
|
||||
*/
|
||||
Q_PROPERTY( QColor color MEMBER mColor NOTIFY colorChanged )
|
||||
|
||||
/**
|
||||
* Pen width of the highlighted geometry (feature).
|
||||
*
|
||||
* Default is 20, see QSGGeometry::setLineWidth()
|
||||
*/
|
||||
Q_PROPERTY( float width MEMBER mWidth NOTIFY widthChanged )
|
||||
|
||||
public:
|
||||
//! Creates a new feature highlight
|
||||
explicit QgsQuickFeatureHighlight( QQuickItem *parent = nullptr );
|
||||
|
||||
signals:
|
||||
//! \copydoc QgsQuickFeatureHighlight::featureLayerPair
|
||||
void featureLayerPairChanged();
|
||||
|
||||
//! \copydoc QgsQuickFeatureHighlight::color
|
||||
void colorChanged();
|
||||
|
||||
//! \copydoc QgsQuickFeatureHighlight::width
|
||||
void widthChanged();
|
||||
|
||||
//! \copydoc QgsQuickFeatureHighlight::mapSettings
|
||||
void mapSettingsChanged();
|
||||
|
||||
private slots:
|
||||
void markDirty();
|
||||
void onMapSettingsChanged();
|
||||
|
||||
private:
|
||||
QSGNode *updatePaintNode( QSGNode *n, UpdatePaintNodeData * ) override;
|
||||
|
||||
QColor mColor = Qt::yellow;
|
||||
bool mDirty = false;
|
||||
float mWidth = 20;
|
||||
QgsQuickFeatureLayerPair mFeatureLayerPair;
|
||||
QgsQuickMapSettings *mMapSettings = nullptr; // not owned
|
||||
QgsQuickMapTransform mTransform;
|
||||
};
|
||||
|
||||
#endif // QGSQUICKFEATUREHIGHLIGHT_H
|
68
src/quickgui/qgsquickfeaturelayerpair.cpp
Normal file
68
src/quickgui/qgsquickfeaturelayerpair.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
/***************************************************************************
|
||||
qgsquickfeaturelayerpair.cpp
|
||||
---------------------
|
||||
Date : Nov 2017
|
||||
Copyright : (C) 2017 by Peter Petrik
|
||||
Email : zilolv at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsfeature.h"
|
||||
|
||||
#include "qgsquickfeaturelayerpair.h"
|
||||
|
||||
QgsQuickFeatureLayerPair::QgsQuickFeatureLayerPair() = default;
|
||||
|
||||
QgsQuickFeatureLayerPair::QgsQuickFeatureLayerPair( const QgsFeature &feature, QgsVectorLayer *layer )
|
||||
: mLayer( layer )
|
||||
, mFeature( feature )
|
||||
{
|
||||
}
|
||||
|
||||
QgsVectorLayer *QgsQuickFeatureLayerPair::layer() const
|
||||
{
|
||||
return mLayer;
|
||||
}
|
||||
|
||||
QgsFeature QgsQuickFeatureLayerPair::feature() const
|
||||
{
|
||||
return mFeature;
|
||||
}
|
||||
|
||||
bool QgsQuickFeatureLayerPair::isValid() const
|
||||
{
|
||||
return ( mLayer && mFeature.isValid() && hasValidGeometry() );
|
||||
}
|
||||
|
||||
bool QgsQuickFeatureLayerPair::operator==( const QgsQuickFeatureLayerPair &other ) const
|
||||
{
|
||||
return ( mLayer == other.layer() ) && ( mFeature == other.feature() );
|
||||
}
|
||||
|
||||
bool QgsQuickFeatureLayerPair::operator!=( const QgsQuickFeatureLayerPair &other ) const
|
||||
{
|
||||
return ( mLayer != other.layer() ) || ( mFeature != other.feature() );
|
||||
}
|
||||
|
||||
bool QgsQuickFeatureLayerPair::hasValidGeometry() const
|
||||
{
|
||||
Q_ASSERT( mLayer );
|
||||
|
||||
if ( !mFeature.hasGeometry() )
|
||||
return false;
|
||||
|
||||
if ( mFeature.geometry().type() != mLayer->geometryType() )
|
||||
return false;
|
||||
|
||||
if ( QgsWkbTypes::hasZ( mLayer->wkbType() ) != QgsWkbTypes::hasZ( mFeature.geometry().wkbType() ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
102
src/quickgui/qgsquickfeaturelayerpair.h
Normal file
102
src/quickgui/qgsquickfeaturelayerpair.h
Normal file
@ -0,0 +1,102 @@
|
||||
/***************************************************************************
|
||||
qgsquickfeaturelayerpair.h
|
||||
---------------------------
|
||||
Date : Nov 2017
|
||||
Copyright : (C) 2017 by Peter Petrik
|
||||
Email : zilolv at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSQUICKFEATURELAYERPAIR_H
|
||||
#define QGSQUICKFEATURELAYERPAIR_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "qgsfeature.h"
|
||||
|
||||
#include "qgis_quick.h"
|
||||
|
||||
class QgsVectorLayer;
|
||||
|
||||
/**
|
||||
* \ingroup quick
|
||||
* Pair of QgsFeature and QgsVectorLayer
|
||||
*
|
||||
* Vector layer is commonly used to gather geometry type or CRS
|
||||
* for the feature.
|
||||
*
|
||||
* Note that the feature may or may not be part of the layer's features
|
||||
*
|
||||
* \note QML Type: QgsQuickFeatureLayerPair
|
||||
*
|
||||
* \since QGIS 3.4
|
||||
*/
|
||||
class QUICK_EXPORT QgsQuickFeatureLayerPair
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
/**
|
||||
* Vector layer to which the feature belongs. May be nullptr if pair is not valid
|
||||
*
|
||||
* This is a readonly property.
|
||||
*/
|
||||
Q_PROPERTY( QgsVectorLayer *layer READ layer )
|
||||
|
||||
/**
|
||||
* Feature that belongs to layer.
|
||||
*
|
||||
* This is a readonly property.
|
||||
*/
|
||||
Q_PROPERTY( QgsFeature feature READ feature )
|
||||
|
||||
/**
|
||||
* Whether
|
||||
* - layer is not nullptr
|
||||
* - feature is valid
|
||||
* - feature has geometry and the geometry is the same as geometry expected by layer
|
||||
*
|
||||
* This is a readonly property.
|
||||
*/
|
||||
Q_PROPERTY( bool valid READ isValid )
|
||||
|
||||
public:
|
||||
//! Constructs invalid feature-layer pair.
|
||||
QgsQuickFeatureLayerPair();
|
||||
|
||||
/**
|
||||
* Constructor of a new feature-layer pair
|
||||
* \param feature QgsFeature associated.
|
||||
* \param layer Vector layer which the feature belongs to
|
||||
*/
|
||||
QgsQuickFeatureLayerPair( const QgsFeature &feature, QgsVectorLayer *layer );
|
||||
|
||||
//! \copydoc QgsQuickFeatureLayerPair::layer
|
||||
QgsVectorLayer *layer() const;
|
||||
|
||||
//! \copydoc QgsQuickFeatureLayerPair::feature
|
||||
QgsFeature feature() const;
|
||||
|
||||
//! \copydoc QgsQuickFeatureLayerPair::valid
|
||||
bool isValid() const;
|
||||
|
||||
bool operator==( const QgsQuickFeatureLayerPair &other ) const;
|
||||
bool operator!=( const QgsQuickFeatureLayerPair &other ) const;
|
||||
|
||||
private:
|
||||
bool hasValidGeometry() const;
|
||||
|
||||
QgsVectorLayer *mLayer = nullptr; // not owned
|
||||
QgsFeature mFeature;
|
||||
};
|
||||
|
||||
typedef QList<QgsQuickFeatureLayerPair> QgsQuickFeatureLayerPairs;
|
||||
|
||||
Q_DECLARE_METATYPE( QgsQuickFeatureLayerPair )
|
||||
|
||||
#endif // QGSQUICKFEATURELAYERPAIR_H
|
174
src/quickgui/qgsquickhighlightsgnode.cpp
Normal file
174
src/quickgui/qgsquickhighlightsgnode.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
/***************************************************************************
|
||||
qgsquickhighlightsgnode.cpp
|
||||
--------------------------------------
|
||||
Date : Nov 2017
|
||||
Copyright : (C) 2017 by Matthias Kuhn
|
||||
Email : matthias@opengis.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsquickhighlightsgnode.h"
|
||||
|
||||
#include "qgstessellator.h"
|
||||
#include "qgsgeometrycollection.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgslinestring.h"
|
||||
#include "qgspoint.h"
|
||||
#include "qgspolygon.h"
|
||||
|
||||
QgsQuickHighlightSGNode::QgsQuickHighlightSGNode( const QgsGeometry &geom,
|
||||
const QColor &color, float width )
|
||||
: QSGNode()
|
||||
, mWidth( width )
|
||||
{
|
||||
mMaterial.setColor( color );
|
||||
handleGeometryCollection( geom.constGet(), geom.type() );
|
||||
}
|
||||
|
||||
void QgsQuickHighlightSGNode::handleGeometryCollection( const QgsAbstractGeometry *geom, QgsWkbTypes::GeometryType type )
|
||||
{
|
||||
const QgsGeometryCollection *collection = qgsgeometry_cast<const QgsGeometryCollection *>( geom );
|
||||
if ( collection && !collection->isEmpty() )
|
||||
{
|
||||
for ( int i = 0; i < collection->numGeometries(); ++i )
|
||||
{
|
||||
const QgsAbstractGeometry *geomN = collection->geometryN( i );
|
||||
handleSingleGeometry( geomN, type );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
handleSingleGeometry( geom, type );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsQuickHighlightSGNode::handleSingleGeometry( const QgsAbstractGeometry *geom, QgsWkbTypes::GeometryType type )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case QgsWkbTypes::PointGeometry:
|
||||
{
|
||||
const QgsPoint *point = qgsgeometry_cast<const QgsPoint *>( geom );
|
||||
if ( point )
|
||||
appendChildNode( createPointGeometry( point ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::LineGeometry:
|
||||
{
|
||||
const QgsLineString *line = qgsgeometry_cast<const QgsLineString *>( geom );
|
||||
if ( line )
|
||||
appendChildNode( createLineGeometry( line ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::PolygonGeometry:
|
||||
{
|
||||
const QgsPolygon *poly = qgsgeometry_cast<const QgsPolygon *>( geom );
|
||||
if ( poly )
|
||||
appendChildNode( createPolygonGeometry( poly ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsWkbTypes::UnknownGeometry:
|
||||
case QgsWkbTypes::NullGeometry:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QSGGeometryNode *QgsQuickHighlightSGNode::createLineGeometry( const QgsLineString *line )
|
||||
{
|
||||
Q_ASSERT( line );
|
||||
|
||||
std::unique_ptr<QSGGeometryNode> node = qgis::make_unique< QSGGeometryNode>();
|
||||
std::unique_ptr<QSGGeometry> sgGeom = qgis::make_unique< QSGGeometry>( QSGGeometry::defaultAttributes_Point2D(), line->numPoints() );
|
||||
QSGGeometry::Point2D *vertices = sgGeom->vertexDataAsPoint2D();
|
||||
|
||||
const double *x = line->xData();
|
||||
const double *y = line->yData();
|
||||
|
||||
for ( int i = 0; i < line->numPoints(); ++i )
|
||||
{
|
||||
vertices[i].set(
|
||||
static_cast< float >( x[i] ),
|
||||
static_cast< float >( y[i] )
|
||||
);
|
||||
}
|
||||
|
||||
sgGeom->setLineWidth( mWidth );
|
||||
sgGeom->setDrawingMode( GL_LINE_STRIP );
|
||||
node->setGeometry( sgGeom.release() );
|
||||
node->setMaterial( &mMaterial );
|
||||
node->setFlag( QSGNode::OwnsGeometry );
|
||||
node->setFlag( QSGNode::OwnedByParent );
|
||||
return node.release();
|
||||
}
|
||||
|
||||
QSGGeometryNode *QgsQuickHighlightSGNode::createPointGeometry( const QgsPoint *point )
|
||||
{
|
||||
Q_ASSERT( point );
|
||||
|
||||
std::unique_ptr<QSGGeometryNode> node = qgis::make_unique< QSGGeometryNode>();
|
||||
std::unique_ptr<QSGGeometry> sgGeom = qgis::make_unique<QSGGeometry>( QSGGeometry::defaultAttributes_Point2D(), 1 );
|
||||
|
||||
QSGGeometry::Point2D *vertices = sgGeom->vertexDataAsPoint2D();
|
||||
vertices[0].set(
|
||||
static_cast< float >( point->x() ),
|
||||
static_cast< float >( point->y() )
|
||||
);
|
||||
sgGeom->setDrawingMode( GL_POINTS );
|
||||
sgGeom->setLineWidth( mWidth );
|
||||
|
||||
node->setGeometry( sgGeom.release() );
|
||||
node->setMaterial( &mMaterial );
|
||||
node->setFlag( QSGNode::OwnsGeometry );
|
||||
node->setFlag( QSGNode::OwnedByParent );
|
||||
return node.release();
|
||||
}
|
||||
|
||||
QSGGeometryNode *QgsQuickHighlightSGNode::createPolygonGeometry( const QgsPolygon *polygon )
|
||||
{
|
||||
Q_ASSERT( polygon );
|
||||
|
||||
const QgsRectangle bounds = polygon->boundingBox();
|
||||
QgsTessellator tes( bounds.xMinimum(), bounds.yMinimum(), false, false, false );
|
||||
tes.addPolygon( *polygon, 0.0 );
|
||||
|
||||
QSGGeometryNode *node = new QSGGeometryNode;
|
||||
QSGGeometry *sgGeom = new QSGGeometry( QSGGeometry::defaultAttributes_Point2D(), tes.dataVerticesCount() );
|
||||
|
||||
QSGGeometry::Point2D *vertices = sgGeom->vertexDataAsPoint2D();
|
||||
|
||||
// we need to revert translation in tessellator
|
||||
float translateX = static_cast< float >( bounds.xMinimum() );
|
||||
float translateY = static_cast< float >( bounds.yMinimum() );
|
||||
|
||||
const QVector<float> data = tes.data();
|
||||
int i = 0;
|
||||
for ( auto it = data.constBegin(); it != data.constEnd(); )
|
||||
{
|
||||
float x = *it;
|
||||
vertices[i].x = translateX + x;
|
||||
++it;
|
||||
|
||||
++it; // we do not need z coordinate
|
||||
|
||||
float y = -( *it );
|
||||
vertices[i].y = translateY + y;
|
||||
++it;
|
||||
|
||||
++i;
|
||||
}
|
||||
sgGeom->setDrawingMode( GL_TRIANGLES );
|
||||
node->setGeometry( sgGeom );
|
||||
node->setMaterial( &mMaterial );
|
||||
node->setFlag( QSGNode::OwnsGeometry );
|
||||
node->setFlag( QSGNode::OwnedByParent );
|
||||
return node;
|
||||
}
|
65
src/quickgui/qgsquickhighlightsgnode.h
Normal file
65
src/quickgui/qgsquickhighlightsgnode.h
Normal file
@ -0,0 +1,65 @@
|
||||
/***************************************************************************
|
||||
qgsquickhighlightsgnode.h
|
||||
--------------------------------------
|
||||
Date : Nov 2017
|
||||
Copyright : (C) 2017 by Matthias Kuhn
|
||||
Email : matthias@opengis.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSQUICKHIGHLIGHTSGNODE_H
|
||||
#define QGSQUICKHIGHLIGHTSGNODE_H
|
||||
|
||||
#include <QtQuick/QSGNode>
|
||||
#include <QtQuick/QSGFlatColorMaterial>
|
||||
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgis_quick.h"
|
||||
|
||||
class QgsLineString;
|
||||
class QgsPoint;
|
||||
class QgsPolygon;
|
||||
|
||||
/**
|
||||
* \ingroup quick
|
||||
*
|
||||
* This is used to transform (render) QgsGeometry to node for QtQuick scene graph.
|
||||
*
|
||||
* \note QML Type: not exported
|
||||
*
|
||||
* \since QGIS 3.4
|
||||
*/
|
||||
class QUICK_EXPORT QgsQuickHighlightSGNode : public QSGNode
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor of new QT Quick scene node based on geometry
|
||||
*
|
||||
* \param geom Geometry to render in the map coordinates
|
||||
* \param color color used to render geom
|
||||
* \param width width of pen, see QSGGeometry::setLineWidth()
|
||||
*/
|
||||
QgsQuickHighlightSGNode( const QgsGeometry &geom, const QColor &color, float width );
|
||||
//! Destructor
|
||||
~QgsQuickHighlightSGNode() = default;
|
||||
|
||||
private:
|
||||
void handleGeometryCollection( const QgsAbstractGeometry *geom, QgsWkbTypes::GeometryType type );
|
||||
void handleSingleGeometry( const QgsAbstractGeometry *geom, QgsWkbTypes::GeometryType type );
|
||||
|
||||
QSGGeometryNode *createLineGeometry( const QgsLineString *line );
|
||||
QSGGeometryNode *createPointGeometry( const QgsPoint *point );
|
||||
QSGGeometryNode *createPolygonGeometry( const QgsPolygon *polygon );
|
||||
|
||||
QSGFlatColorMaterial mMaterial;
|
||||
float mWidth = 20;
|
||||
};
|
||||
|
||||
#endif // QGSQUICKHIGHLIGHTSGNODE
|
259
src/quickgui/qgsquickidentifykit.cpp
Normal file
259
src/quickgui/qgsquickidentifykit.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
/***************************************************************************
|
||||
qgsquickidentifykit.cpp
|
||||
---------------------
|
||||
Date : 30.8.2016
|
||||
Copyright : (C) 2016 by Matthias Kuhn
|
||||
Email : matthias (at) opengis.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsrenderer.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include "qgsquickidentifykit.h"
|
||||
#include "qgsquickmapsettings.h"
|
||||
|
||||
#include "qgis.h"
|
||||
|
||||
QgsQuickIdentifyKit::QgsQuickIdentifyKit( QObject *parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
}
|
||||
|
||||
QgsQuickMapSettings *QgsQuickIdentifyKit::mapSettings() const
|
||||
{
|
||||
return mMapSettings;
|
||||
}
|
||||
|
||||
void QgsQuickIdentifyKit::setMapSettings( QgsQuickMapSettings *mapSettings )
|
||||
{
|
||||
if ( mapSettings == mMapSettings )
|
||||
return;
|
||||
|
||||
mMapSettings = mapSettings;
|
||||
emit mapSettingsChanged();
|
||||
}
|
||||
|
||||
QgsQuickFeatureLayerPairs QgsQuickIdentifyKit::identify( const QPointF &point, QgsVectorLayer *layer )
|
||||
{
|
||||
QgsQuickFeatureLayerPairs results;
|
||||
|
||||
if ( !mMapSettings )
|
||||
{
|
||||
QgsDebugMsg( QStringLiteral( "Unable to use IdentifyKit without mapSettings property set." ) );
|
||||
return results;
|
||||
}
|
||||
QgsPointXY mapPoint = mMapSettings->mapSettings().mapToPixel().toMapCoordinates( point.toPoint() );
|
||||
|
||||
if ( layer )
|
||||
{
|
||||
QgsFeatureList featureList = identifyVectorLayer( layer, mapPoint );
|
||||
for ( const QgsFeature &feature : featureList )
|
||||
{
|
||||
results.append( QgsQuickFeatureLayerPair( feature, layer ) );
|
||||
}
|
||||
QgsDebugMsg( QStringLiteral( "IdentifyKit identified %1 results for layer %2" ).arg( results.count() ).arg( layer->name() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
QStringList noIdentifyLayerIdList;
|
||||
if ( mMapSettings->project() )
|
||||
{
|
||||
noIdentifyLayerIdList = mMapSettings->project()->nonIdentifiableLayers();
|
||||
}
|
||||
|
||||
for ( QgsMapLayer *layer : mMapSettings->mapSettings().layers() )
|
||||
{
|
||||
if ( mMapSettings->project() && noIdentifyLayerIdList.contains( layer->id() ) )
|
||||
continue;
|
||||
|
||||
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
|
||||
if ( vl )
|
||||
{
|
||||
QgsFeatureList featureList = identifyVectorLayer( vl, mapPoint );
|
||||
|
||||
for ( const QgsFeature &feature : featureList )
|
||||
{
|
||||
results.append( QgsQuickFeatureLayerPair( feature, vl ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QgsDebugMsg( QStringLiteral( "IdentifyKit identified %1 results" ).arg( results.count() ) );
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
static QgsQuickFeatureLayerPair _closestFeature( const QgsQuickFeatureLayerPairs &results, const QgsMapSettings &mapSettings, const QPointF &point )
|
||||
{
|
||||
QgsPointXY mapPoint = mapSettings.mapToPixel().toMapCoordinates( point.toPoint() );
|
||||
QgsGeometry mapPointGeom( QgsGeometry::fromPointXY( mapPoint ) );
|
||||
|
||||
double distMin = 1e10;
|
||||
int iMin = -1;
|
||||
for ( int i = 0; i < results.count(); ++i )
|
||||
{
|
||||
const QgsQuickFeatureLayerPair &res = results.at( i );
|
||||
QgsGeometry geom( res.feature().geometry() );
|
||||
try
|
||||
{
|
||||
geom.transform( mapSettings.layerTransform( res.layer() ) );
|
||||
}
|
||||
catch ( QgsCsException &e )
|
||||
{
|
||||
Q_UNUSED( e );
|
||||
// Caught an error in transform
|
||||
continue;
|
||||
}
|
||||
|
||||
double dist = geom.distance( mapPointGeom );
|
||||
if ( dist < distMin )
|
||||
{
|
||||
iMin = i;
|
||||
distMin = dist;
|
||||
}
|
||||
}
|
||||
|
||||
if ( results.empty() )
|
||||
{
|
||||
return QgsQuickFeatureLayerPair();
|
||||
}
|
||||
else
|
||||
{
|
||||
return results.at( iMin );
|
||||
}
|
||||
}
|
||||
|
||||
QgsQuickFeatureLayerPair QgsQuickIdentifyKit::identifyOne( const QPointF &point, QgsVectorLayer *layer )
|
||||
{
|
||||
QgsQuickFeatureLayerPairs results = identify( point, layer );
|
||||
return _closestFeature( results, mMapSettings->mapSettings(), point );
|
||||
}
|
||||
|
||||
QgsFeatureList QgsQuickIdentifyKit::identifyVectorLayer( QgsVectorLayer *layer, const QgsPointXY &point ) const
|
||||
{
|
||||
QgsFeatureList results;
|
||||
|
||||
if ( !layer || !layer->isSpatial() )
|
||||
return results;
|
||||
|
||||
if ( !layer->isInScaleRange( mMapSettings->mapSettings().scale() ) )
|
||||
return results;
|
||||
|
||||
QgsFeatureList featureList;
|
||||
|
||||
// toLayerCoordinates will throw an exception for an 'invalid' point.
|
||||
// For example, if you project a world map onto a globe using EPSG 2163
|
||||
// and then click somewhere off the globe, an exception will be thrown.
|
||||
try
|
||||
{
|
||||
// create the search rectangle
|
||||
double searchRadius = searchRadiusMU();
|
||||
|
||||
QgsRectangle r;
|
||||
r.setXMinimum( point.x() - searchRadius );
|
||||
r.setXMaximum( point.x() + searchRadius );
|
||||
r.setYMinimum( point.y() - searchRadius );
|
||||
r.setYMaximum( point.y() + searchRadius );
|
||||
|
||||
r = toLayerCoordinates( layer, r );
|
||||
|
||||
QgsFeatureRequest req;
|
||||
req.setFilterRect( r );
|
||||
req.setLimit( mFeaturesLimit );
|
||||
req.setFlags( QgsFeatureRequest::ExactIntersect );
|
||||
|
||||
QgsFeatureIterator fit = layer->getFeatures( req );
|
||||
QgsFeature f;
|
||||
while ( fit.nextFeature( f ) )
|
||||
featureList << QgsFeature( f );
|
||||
}
|
||||
catch ( QgsCsException &cse )
|
||||
{
|
||||
QgsDebugMsg( tr( "Invalid point and proceed with no features found." ) );
|
||||
Q_UNUSED( cse );
|
||||
}
|
||||
|
||||
bool filter = false;
|
||||
|
||||
QgsRenderContext context( QgsRenderContext::fromMapSettings( mMapSettings->mapSettings() ) );
|
||||
context.expressionContext() << QgsExpressionContextUtils::layerScope( layer );
|
||||
QgsFeatureRenderer *renderer = layer->renderer();
|
||||
if ( renderer && renderer->capabilities() & QgsFeatureRenderer::ScaleDependent )
|
||||
{
|
||||
// setup scale for scale dependent visibility (rule based)
|
||||
renderer->startRender( context, layer->fields() );
|
||||
filter = renderer->capabilities() & QgsFeatureRenderer::Filter;
|
||||
}
|
||||
|
||||
for ( const QgsFeature &feature : featureList )
|
||||
{
|
||||
context.expressionContext().setFeature( feature );
|
||||
|
||||
if ( filter && !renderer->willRenderFeature( const_cast<QgsFeature &>( feature ), context ) )
|
||||
continue;
|
||||
|
||||
results.append( feature );
|
||||
}
|
||||
|
||||
if ( renderer && renderer->capabilities() & QgsFeatureRenderer::ScaleDependent )
|
||||
{
|
||||
renderer->stopRender( context );
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
double QgsQuickIdentifyKit::searchRadiusMU( const QgsRenderContext &context ) const
|
||||
{
|
||||
return mSearchRadiusMm * context.scaleFactor() * context.mapToPixel().mapUnitsPerPixel();
|
||||
}
|
||||
|
||||
double QgsQuickIdentifyKit::searchRadiusMU() const
|
||||
{
|
||||
QgsRenderContext context = QgsRenderContext::fromMapSettings( mMapSettings->mapSettings() );
|
||||
return searchRadiusMU( context );
|
||||
}
|
||||
|
||||
QgsRectangle QgsQuickIdentifyKit::toLayerCoordinates( QgsMapLayer *layer, const QgsRectangle &rect ) const
|
||||
{
|
||||
return mMapSettings->mapSettings().mapToLayerCoordinates( layer, rect );
|
||||
}
|
||||
|
||||
double QgsQuickIdentifyKit::searchRadiusMm() const
|
||||
{
|
||||
return mSearchRadiusMm;
|
||||
}
|
||||
|
||||
void QgsQuickIdentifyKit::setSearchRadiusMm( double searchRadiusMm )
|
||||
{
|
||||
if ( qgsDoubleNear( mSearchRadiusMm, searchRadiusMm ) )
|
||||
return;
|
||||
|
||||
mSearchRadiusMm = searchRadiusMm;
|
||||
emit searchRadiusMmChanged();
|
||||
}
|
||||
|
||||
int QgsQuickIdentifyKit::featuresLimit() const
|
||||
{
|
||||
return mFeaturesLimit;
|
||||
}
|
||||
|
||||
void QgsQuickIdentifyKit::setFeaturesLimit( int limit )
|
||||
{
|
||||
if ( mFeaturesLimit == limit )
|
||||
return;
|
||||
|
||||
mFeaturesLimit = limit;
|
||||
emit featuresLimitChanged();
|
||||
}
|
139
src/quickgui/qgsquickidentifykit.h
Normal file
139
src/quickgui/qgsquickidentifykit.h
Normal file
@ -0,0 +1,139 @@
|
||||
/***************************************************************************
|
||||
qgsquickidentifykit.h
|
||||
---------------------
|
||||
Date : 30.8.2016
|
||||
Copyright : (C) 2016 by Matthias Kuhn
|
||||
Email : matthias (at) opengis.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSQUICKIDENTIFYKIT_H
|
||||
#define QGSQUICKIDENTIFYKIT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QPair>
|
||||
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsmapsettings.h"
|
||||
#include "qgspoint.h"
|
||||
#include "qgsrendercontext.h"
|
||||
|
||||
#include "qgis_quick.h"
|
||||
#include "qgsquickfeaturelayerpair.h"
|
||||
|
||||
class QgsMapLayer;
|
||||
class QgsQuickMapSettings;
|
||||
class QgsVectorLayer;
|
||||
|
||||
/**
|
||||
* \ingroup quick
|
||||
*
|
||||
* Convenient set of tools to identify features
|
||||
*
|
||||
* - get a list of features in a defined radius from a point.
|
||||
* - get a feature with the closest distance to the point
|
||||
*
|
||||
* \note QML Type: IdentifyKit
|
||||
*
|
||||
* \since QGIS 3.4
|
||||
*/
|
||||
class QUICK_EXPORT QgsQuickIdentifyKit : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
/**
|
||||
* Map settings. Set directly when creating QML object.
|
||||
*/
|
||||
Q_PROPERTY( QgsQuickMapSettings *mapSettings READ mapSettings WRITE setMapSettings NOTIFY mapSettingsChanged )
|
||||
|
||||
/**
|
||||
* Search radius for the identify functions
|
||||
*
|
||||
* Default is 8.
|
||||
*/
|
||||
Q_PROPERTY( double searchRadiusMm READ searchRadiusMm WRITE setSearchRadiusMm NOTIFY searchRadiusMmChanged )
|
||||
|
||||
/**
|
||||
* Maximum number of features returned from the QgsQuickIdentifyKit::identify()
|
||||
*
|
||||
* Default is 100.
|
||||
*/
|
||||
Q_PROPERTY( int featuresLimit READ featuresLimit WRITE setFeaturesLimit NOTIFY featuresLimitChanged )
|
||||
|
||||
public:
|
||||
//! Constructor of new identify kit.
|
||||
explicit QgsQuickIdentifyKit( QObject *parent = nullptr );
|
||||
|
||||
//! \copydoc QgsQuickIdentifyKit::mapSettings
|
||||
QgsQuickMapSettings *mapSettings() const;
|
||||
|
||||
//! \copydoc QgsQuickIdentifyKit::mapSettings
|
||||
void setMapSettings( QgsQuickMapSettings *mapSettings );
|
||||
|
||||
//! \copydoc QgsQuickIdentifyKit::searchRadiusMm
|
||||
double searchRadiusMm() const;
|
||||
|
||||
//! \copydoc QgsQuickIdentifyKit::searchRadiusMm
|
||||
void setSearchRadiusMm( double searchRadiusMm );
|
||||
|
||||
//! \copydoc QgsQuickIdentifyKit::featuresLimit
|
||||
int featuresLimit() const;
|
||||
|
||||
//! \copydoc QgsQuickIdentifyKit::featuresLimit
|
||||
void setFeaturesLimit( int limit );
|
||||
|
||||
/**
|
||||
* Gets the closest feature to the point within the search radius
|
||||
*
|
||||
* If layer is nullptr, identifies the closest feature from all identifiable layers
|
||||
* If layer is not nullptr, identifies the closest feature from given layer
|
||||
*
|
||||
* To modify search radius, use QgsQuickIdentifyKit::searchRadiusMm
|
||||
*
|
||||
* \param point position to search a feature from
|
||||
* \param layer if defined, search for a feature only from this layer
|
||||
*/
|
||||
Q_INVOKABLE QgsQuickFeatureLayerPair identifyOne( const QPointF &point, QgsVectorLayer *layer = nullptr );
|
||||
|
||||
/**
|
||||
* Gets all features in the search radius
|
||||
*
|
||||
* If layer is nullptr, identifies features from all identifiable layers
|
||||
* If layer is not nullptr, identifies only features from given layer
|
||||
*
|
||||
* To limit number of results, use QgsQuickIdentifyKit::featuresLimit
|
||||
* To modify search radius, use QgsQuickIdentifyKit::searchRadiusMm
|
||||
*
|
||||
* \param point position to search features ob
|
||||
* \param layer if defined, search for features only from this layer
|
||||
*/
|
||||
Q_INVOKABLE QgsQuickFeatureLayerPairs identify( const QPointF &point, QgsVectorLayer *layer = nullptr );
|
||||
|
||||
signals:
|
||||
//! \copydoc QgsQuickIdentifyKit::mapSettings
|
||||
void mapSettingsChanged();
|
||||
//! \copydoc QgsQuickIdentifyKit::searchRadiusMm
|
||||
void searchRadiusMmChanged();
|
||||
//! \copydoc QgsQuickIdentifyKit::featuresLimit
|
||||
void featuresLimitChanged();
|
||||
|
||||
private:
|
||||
QgsQuickMapSettings *mMapSettings = nullptr; // not owned
|
||||
|
||||
double searchRadiusMU( const QgsRenderContext &context ) const;
|
||||
double searchRadiusMU() const;
|
||||
|
||||
QgsRectangle toLayerCoordinates( QgsMapLayer *layer, const QgsRectangle &rect ) const;
|
||||
QgsFeatureList identifyVectorLayer( QgsVectorLayer *layer, const QgsPointXY &point ) const;
|
||||
|
||||
double mSearchRadiusMm = 8;
|
||||
int mFeaturesLimit = 100;
|
||||
};
|
||||
|
||||
#endif // QGSQUICKIDENTIFYKIT_H
|
57
src/quickgui/qgsquickmaptransform.cpp
Normal file
57
src/quickgui/qgsquickmaptransform.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/***************************************************************************
|
||||
qgsquickmaptransform.cpp
|
||||
--------------------------------------
|
||||
Date : 27.12.2014
|
||||
Copyright : (C) 2014 by Matthias Kuhn
|
||||
Email : matthias (at) opengis.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsquickmaptransform.h"
|
||||
#include "qgsquickmapsettings.h"
|
||||
|
||||
void QgsQuickMapTransform::applyTo( QMatrix4x4 *matrix ) const
|
||||
{
|
||||
*matrix *= mMatrix;
|
||||
matrix->optimize();
|
||||
}
|
||||
|
||||
QgsQuickMapSettings *QgsQuickMapTransform::mapSettings() const
|
||||
{
|
||||
return mMapSettings;
|
||||
}
|
||||
|
||||
void QgsQuickMapTransform::setMapSettings( QgsQuickMapSettings *mapSettings )
|
||||
{
|
||||
if ( mapSettings == mMapSettings )
|
||||
return;
|
||||
|
||||
if ( mMapSettings )
|
||||
disconnect( mMapSettings, &QgsQuickMapSettings::visibleExtentChanged, this, &QgsQuickMapTransform::updateMatrix );
|
||||
|
||||
mMapSettings = mapSettings;
|
||||
|
||||
if ( mMapSettings )
|
||||
connect( mMapSettings, &QgsQuickMapSettings::visibleExtentChanged, this, &QgsQuickMapTransform::updateMatrix );
|
||||
|
||||
emit mapSettingsChanged();
|
||||
}
|
||||
|
||||
void QgsQuickMapTransform::updateMatrix()
|
||||
{
|
||||
QMatrix4x4 matrix;
|
||||
float scaleFactor = static_cast<float>( 1.0 / mMapSettings->mapUnitsPerPixel() );
|
||||
|
||||
matrix.scale( scaleFactor, -scaleFactor );
|
||||
matrix.translate( static_cast<float>( -mMapSettings->visibleExtent().xMinimum( ) ),
|
||||
static_cast<float>( -mMapSettings->visibleExtent().yMaximum() ) );
|
||||
|
||||
mMatrix = matrix;
|
||||
update();
|
||||
}
|
77
src/quickgui/qgsquickmaptransform.h
Normal file
77
src/quickgui/qgsquickmaptransform.h
Normal file
@ -0,0 +1,77 @@
|
||||
/***************************************************************************
|
||||
qgsquickmaptransform.h
|
||||
--------------------------------------
|
||||
Date : 27.12.2014
|
||||
Copyright : (C) 2014 by Matthias Kuhn
|
||||
Email : matthias (at) opengis.ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSQUICKMAPTRANSFORM_H
|
||||
#define QGSQUICKMAPTRANSFORM_H
|
||||
|
||||
#include <QQuickItem>
|
||||
#include <QMatrix4x4>
|
||||
|
||||
#include "qgis_quick.h"
|
||||
|
||||
class QgsQuickMapSettings;
|
||||
|
||||
/**
|
||||
* \ingroup quick
|
||||
* The QgsQuickMapTransform is transformation that can be attached to any QQuickItem.
|
||||
*
|
||||
* If the item is based on the map coordinates, QgsQuickMapTransform will
|
||||
* transform it to the device coordintes based on the attached map settings.
|
||||
*
|
||||
* \note QML Type: MapTransform
|
||||
*
|
||||
* \since QGIS 3.4
|
||||
*/
|
||||
class QUICK_EXPORT QgsQuickMapTransform : public QQuickTransform
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
/**
|
||||
* Associated map settings. Should be initialized before the first use from mapcanvas map settings.
|
||||
*/
|
||||
Q_PROPERTY( QgsQuickMapSettings *mapSettings READ mapSettings WRITE setMapSettings NOTIFY mapSettingsChanged )
|
||||
|
||||
public:
|
||||
//! create new map transform
|
||||
QgsQuickMapTransform() = default;
|
||||
~QgsQuickMapTransform() = default;
|
||||
|
||||
/**
|
||||
* Apply transformation based on current map settings to a matrix.
|
||||
*
|
||||
* Also optimize resulting matrix after transformation
|
||||
* \param matrix Matrix to be transformed
|
||||
*/
|
||||
void applyTo( QMatrix4x4 *matrix ) const;
|
||||
|
||||
//! \copydoc QgsQuickMapTransform::mapSettings
|
||||
QgsQuickMapSettings *mapSettings() const;
|
||||
|
||||
//! \copydoc QgsQuickMapTransform::mapSettings
|
||||
void setMapSettings( QgsQuickMapSettings *mapSettings );
|
||||
|
||||
signals:
|
||||
//! \copydoc QgsQuickMapTransform::mapSettings
|
||||
void mapSettingsChanged();
|
||||
|
||||
private slots:
|
||||
void updateMatrix();
|
||||
|
||||
private:
|
||||
QgsQuickMapSettings *mMapSettings = nullptr;
|
||||
QMatrix4x4 mMatrix;
|
||||
};
|
||||
|
||||
#endif // QGSQUICKMAPTRANSFORM_H
|
@ -18,7 +18,9 @@
|
||||
#include "qgis.h"
|
||||
#include "qgsdistancearea.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
#include "qgsquickfeaturelayerpair.h"
|
||||
#include "qgsquickmapsettings.h"
|
||||
#include "qgsquickutils.h"
|
||||
#include "qgsunittypes.h"
|
||||
@ -52,6 +54,11 @@ void QgsQuickUtils::logMessage( const QString &message, const QString &tag, Qgis
|
||||
QgsMessageLog::logMessage( message, tag, level );
|
||||
}
|
||||
|
||||
QgsQuickFeatureLayerPair QgsQuickUtils::featureFactory( const QgsFeature &feature, QgsVectorLayer *layer ) const
|
||||
{
|
||||
return QgsQuickFeatureLayerPair( feature, layer );
|
||||
}
|
||||
|
||||
QString QgsQuickUtils::dumpScreenInfo() const
|
||||
{
|
||||
QRect rec = QApplication::desktop()->screenGeometry();
|
||||
|
@ -24,8 +24,11 @@
|
||||
#include "qgsmessagelog.h"
|
||||
|
||||
#include "qgsquickmapsettings.h"
|
||||
#include "qgsquickfeaturelayerpair.h"
|
||||
#include "qgis_quick.h"
|
||||
#include "qgsfeature.h"
|
||||
|
||||
class QgsVectorLayer;
|
||||
class QgsCoordinateReferenceSystem;
|
||||
|
||||
/**
|
||||
@ -73,6 +76,15 @@ class QUICK_EXPORT QgsQuickUtils: public QObject
|
||||
const QString &tag = QString( "QgsQuick" ),
|
||||
Qgis::MessageLevel level = Qgis::Warning );
|
||||
|
||||
/**
|
||||
* QgsQuickFeatureLayerPair factory for tuple of QgsFeature and QgsVectorLayer used in QgsQUick library.
|
||||
* \param feature QgsFeature linked to new QgsQuickFeature instance.
|
||||
* \param layer QgsVectorLayer which the feature belongs to, optional.
|
||||
*
|
||||
* \since QGIS 3.4
|
||||
*/
|
||||
Q_INVOKABLE QgsQuickFeatureLayerPair featureFactory( const QgsFeature &feature, QgsVectorLayer *layer = nullptr ) const;
|
||||
|
||||
/**
|
||||
* Returns a string with information about screen size and resolution
|
||||
*
|
||||
|
@ -78,6 +78,7 @@ ENDMACRO (ADD_QGIS_TEST)
|
||||
#############################################################
|
||||
# Tests:
|
||||
|
||||
ADD_QGIS_TEST(qgsquickidentifykit testqgsquickidentifykit.cpp)
|
||||
ADD_QGIS_TEST(qgsquickutils testqgsquickutils.cpp)
|
||||
ADD_QGIS_TEST(qgsquickscalebarkit testqgsquickscalebarkit.cpp)
|
||||
|
||||
|
@ -32,12 +32,26 @@ ApplicationWindow {
|
||||
mapSettings.project: __project
|
||||
mapSettings.layers: __layers
|
||||
|
||||
QgsQuick.IdentifyKit {
|
||||
id: identifyKit
|
||||
mapSettings: mapCanvas.mapSettings
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
var screenPoint = Qt.point(mouse.x, mouse.y)
|
||||
console.log("clicked:" + screenPoint)
|
||||
var res = identifyKit.identifyOne(screenPoint);
|
||||
highlight.featureLayerPair = res
|
||||
}
|
||||
}
|
||||
|
||||
QgsQuick.FeatureHighlight {
|
||||
anchors.fill: mapCanvas
|
||||
id: highlight
|
||||
color: "red"
|
||||
mapSettings: mapCanvas.mapSettings
|
||||
z: 1
|
||||
}
|
||||
|
||||
Drawer {
|
||||
id: logPanel
|
||||
visible: true
|
||||
|
185
tests/src/quickgui/testqgsquickidentifykit.cpp
Normal file
185
tests/src/quickgui/testqgsquickidentifykit.cpp
Normal file
@ -0,0 +1,185 @@
|
||||
/***************************************************************************
|
||||
testqgsquickidentifykit.cpp.cpp
|
||||
--------------------------------------
|
||||
Date : May 2018
|
||||
Copyright : (C) 2018 by Viktor Sklencar
|
||||
Email : vsklencar at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include <QObject>
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
#include "qgsapplication.h"
|
||||
#include "qgstest.h"
|
||||
#include "qgis.h"
|
||||
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
|
||||
#include "qgsquickmapcanvasmap.h"
|
||||
#include "qgsquickidentifykit.h"
|
||||
|
||||
|
||||
class TestQgsQuickScaleBarKit: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void init() {} // will be called before each testfunction is executed.
|
||||
void cleanup() {} // will be called after every testfunction.
|
||||
|
||||
void identifyOne(); // tests identifyOne function without given layer
|
||||
void identifyOneDefinedVector(); // tests identifyOne function with given layer
|
||||
void identifyInRadius();
|
||||
};
|
||||
|
||||
void TestQgsQuickScaleBarKit::identifyOne()
|
||||
{
|
||||
QgsCoordinateReferenceSystem crsGPS = QgsCoordinateReferenceSystem::fromEpsgId( 4326 );
|
||||
QVERIFY( crsGPS.authid() == "EPSG:4326" );
|
||||
|
||||
QgsRectangle extent = QgsRectangle( -120, 23, -82, 47 );
|
||||
QgsQuickMapCanvasMap canvas;
|
||||
|
||||
QgsVectorLayer *tempLayer = new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:4326" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) );
|
||||
QVERIFY( tempLayer->isValid() );
|
||||
|
||||
QgsQuickMapSettings *ms = canvas.mapSettings();
|
||||
ms->setDestinationCrs( crsGPS );
|
||||
ms->setExtent( extent );
|
||||
ms->setOutputSize( QSize( 1000, 500 ) );
|
||||
ms->setLayers( QList<QgsMapLayer *>() << tempLayer );
|
||||
|
||||
QgsQuickIdentifyKit kit;
|
||||
kit.setMapSettings( ms );
|
||||
|
||||
double pointX = -31.208;
|
||||
double pointY = 20.407999999999998;
|
||||
double pointX2 = pointX + 1;
|
||||
|
||||
// add feature
|
||||
QgsFeature f1( tempLayer->dataProvider()->fields(), 1 );
|
||||
QgsPointXY point( pointX, pointY );
|
||||
QgsGeometry geom = QgsGeometry::fromPointXY( point ) ;
|
||||
f1.setGeometry( geom );
|
||||
|
||||
// add another feature
|
||||
QgsFeature f2( tempLayer->dataProvider()->fields(), 1 );
|
||||
QgsPointXY point2( pointX2, pointY );
|
||||
QgsGeometry geom2 = QgsGeometry::fromPointXY( point2 ) ;
|
||||
f2.setGeometry( geom2 );
|
||||
|
||||
tempLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 << f2 );
|
||||
|
||||
// exactly matches f1 point
|
||||
QgsPointXY screenPoint( 1954.0, 554.0 );
|
||||
QgsQuickFeatureLayerPair identifiedFeature = kit.identifyOne( screenPoint.toQPointF() );
|
||||
QVERIFY( identifiedFeature.isValid() );
|
||||
QVERIFY( identifiedFeature.feature().geometry().asPoint() == point );
|
||||
}
|
||||
|
||||
void TestQgsQuickScaleBarKit::identifyOneDefinedVector()
|
||||
{
|
||||
QgsCoordinateReferenceSystem crsGPS = QgsCoordinateReferenceSystem::fromEpsgId( 4326 );
|
||||
QVERIFY( crsGPS.authid() == "EPSG:4326" );
|
||||
|
||||
QgsRectangle extent = QgsRectangle( -120, 23, -82, 47 );
|
||||
QgsQuickMapCanvasMap canvas;
|
||||
|
||||
QgsVectorLayer *tempLayer = new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:4326" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) );
|
||||
QVERIFY( tempLayer->isValid() );
|
||||
|
||||
QgsVectorLayer *tempLayer2 = new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:4326" ), QStringLiteral( "vl2" ), QStringLiteral( "memory" ) );
|
||||
QVERIFY( tempLayer->isValid() );
|
||||
|
||||
QgsQuickMapSettings *ms = canvas.mapSettings();
|
||||
ms->setDestinationCrs( crsGPS );
|
||||
ms->setExtent( extent );
|
||||
ms->setOutputSize( QSize( 1000, 500 ) );
|
||||
ms->setLayers( QList<QgsMapLayer *>() << tempLayer );
|
||||
|
||||
QgsQuickIdentifyKit kit;
|
||||
kit.setMapSettings( ms );
|
||||
|
||||
double pointX = -31.208;
|
||||
double pointY = 20.407999999999998;
|
||||
double pointX2 = pointX + 1;
|
||||
|
||||
// add feature
|
||||
QgsFeature f1( tempLayer->dataProvider()->fields(), 1 );
|
||||
QgsPointXY point( pointX, pointY );
|
||||
QgsGeometry geom = QgsGeometry::fromPointXY( point ) ;
|
||||
f1.setGeometry( geom );
|
||||
|
||||
// add another feature
|
||||
QgsFeature f2( tempLayer2->dataProvider()->fields(), 1 );
|
||||
QgsPointXY point2( pointX2, pointY );
|
||||
QgsGeometry geom2 = QgsGeometry::fromPointXY( point2 ) ;
|
||||
f2.setGeometry( geom2 );
|
||||
|
||||
tempLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 );
|
||||
tempLayer2->dataProvider()->addFeatures( QgsFeatureList() << f2 );
|
||||
|
||||
QgsPointXY screenPoint( 1954.0, 554.0 );
|
||||
QgsQuickFeatureLayerPair identifiedFeature = kit.identifyOne( screenPoint.toQPointF(), tempLayer2 );
|
||||
QVERIFY( identifiedFeature.isValid() );
|
||||
QVERIFY( identifiedFeature.feature().geometry().asPoint() == point2 );
|
||||
|
||||
}
|
||||
|
||||
void TestQgsQuickScaleBarKit::identifyInRadius()
|
||||
{
|
||||
QgsCoordinateReferenceSystem crsGPS = QgsCoordinateReferenceSystem::fromEpsgId( 4326 );
|
||||
QVERIFY( crsGPS.authid() == "EPSG:4326" );
|
||||
|
||||
QgsRectangle extent = QgsRectangle( -120, 23, -82, 47 );
|
||||
QgsQuickMapCanvasMap canvas;
|
||||
|
||||
QgsVectorLayer *tempLayer = new QgsVectorLayer( QStringLiteral( "Point?crs=epsg:4326" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) );
|
||||
QVERIFY( tempLayer->isValid() );
|
||||
|
||||
QgsQuickMapSettings *ms = canvas.mapSettings();
|
||||
ms->setDestinationCrs( crsGPS );
|
||||
ms->setExtent( extent );
|
||||
ms->setOutputSize( QSize( 1000, 500 ) );
|
||||
ms->setLayers( QList<QgsMapLayer *>() << tempLayer );
|
||||
|
||||
QgsQuickIdentifyKit kit;
|
||||
kit.setMapSettings( ms );
|
||||
|
||||
double pointX = -31.208;
|
||||
double pointY = 20.407999999999998;
|
||||
double pointX2 = pointX + 5;
|
||||
|
||||
QgsFeature f1( tempLayer->dataProvider()->fields(), 1 );
|
||||
QgsPointXY point( pointX, pointY );
|
||||
QgsGeometry geom = QgsGeometry::fromPointXY( point ) ;
|
||||
f1.setGeometry( geom );
|
||||
|
||||
QgsFeature f2( tempLayer->dataProvider()->fields(), 1 );
|
||||
QgsPointXY point2( pointX2, pointY );
|
||||
QgsGeometry geom2 = QgsGeometry::fromPointXY( point2 ) ;
|
||||
f2.setGeometry( geom2 );
|
||||
|
||||
tempLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 << f2 );
|
||||
|
||||
kit.setSearchRadiusMm( 1.0 );
|
||||
QgsPointXY screenPoint( 1954.0, 554.0 );
|
||||
QgsQuickFeatureLayerPairs res = kit.identify( screenPoint.toQPointF() );
|
||||
QVERIFY( res.size() == 1 );
|
||||
|
||||
kit.setSearchRadiusMm( 100.0 );
|
||||
res = kit.identify( screenPoint.toQPointF() );
|
||||
QVERIFY( res.size() == 2 );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsQuickScaleBarKit )
|
||||
#include "testqgsquickidentifykit.moc"
|
@ -59,7 +59,7 @@ void TestQgsQuickUtils::screenUnitsToMeters()
|
||||
ms.setExtent( QgsRectangle( 49, 16, 50, 17 ) );
|
||||
ms.setOutputSize( QSize( 1000, 500 ) );
|
||||
double sutm = utils.screenUnitsToMeters( &ms, 1 );
|
||||
QVERIFY( fabs( sutm - 213 ) < 1.0 );
|
||||
QGSCOMPARENEAR( sutm, 213, 1.0 );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsQuickUtils )
|
||||
|
Loading…
x
Reference in New Issue
Block a user