30 #include <QProgressDialog> 35 bool onlySelectedFeatures,
56 if ( onlySelectedFeatures )
65 int processedFeatures = 0;
67 for ( ; it != selection.
constEnd(); ++it )
82 simplifyFeature( currentFeature, &vWriter, tolerance );
101 int processedFeatures = 0;
113 simplifyFeature( currentFeature, &vWriter, tolerance );
136 tmpGeometry = featureGeometry->
simplify( tolerance );
161 QgsDebugMsg(
"No data provider for layer passed to centroids" );
172 if ( onlySelectedFeatures )
181 int processedFeatures = 0;
183 for ( ; it != selection.
constEnd(); ++it )
198 centroidFeature( currentFeature, &vWriter );
217 int processedFeatures = 0;
229 centroidFeature( currentFeature, &vWriter );
252 tmpGeometry = featureGeometry->
centroid();
267 bool onlySelectedFeatures,
299 if ( onlySelectedFeatures )
309 double miny = rect.yMinimum();
310 double maxx = rect.xMaximum();
311 double maxy = rect.yMaximum();
312 double height = rect.height();
313 double width = rect.width();
314 double cntx = minx + ( width / 2.0 );
315 double cnty = miny + ( height / 2.0 );
316 double area = width * height;
317 double perim = ( 2 * width ) + ( 2 * height );
333 vWriter.addFeature( feat );
353 perim = perimeterMeasure( mpGeometry, measure );
377 bool useField =
false;
378 if ( uniqueIdField == -1 )
399 if ( onlySelectedFeatures )
404 for ( ; it != selection.
constEnd(); ++it )
421 map.
insert( currentFeature.attribute( uniqueIdField ).toString(), currentFeature.id() );
440 map.
insert( currentFeature.attribute( uniqueIdField ).toString(), currentFeature.id() );
448 int processedFeatures = 0;
450 if ( onlySelectedFeatures )
458 processedFeatures = 0;
459 while ( jt != map.
constEnd() && ( jt.
key() == currentKey || !useField ) )
475 convexFeature( currentFeature, processedFeatures, &dissolveGeometry );
481 if ( !dissolveGeometry )
483 QgsDebugMsg(
"no dissolved geometry - should not happen" );
486 dissolveGeometry = dissolveGeometry->
convexHull();
487 values = simpleMeasure( dissolveGeometry );
489 attributes[0] =
QVariant( currentKey );
490 attributes[1] = values.
at( 0 );
491 attributes[2] = values.
at( 1 );
495 vWriter.addFeature( dissolveFeature );
505 processedFeatures = 0;
506 while ( jt != map.
constEnd() && ( jt.
key() == currentKey || !useField ) )
521 convexFeature( currentFeature, processedFeatures, &dissolveGeometry );
527 if ( !dissolveGeometry )
529 QgsDebugMsg(
"no dissolved geometry - should not happen" );
532 dissolveGeometry = dissolveGeometry->
convexHull();
534 values = simpleMeasure( dissolveGeometry );
536 attributes[0] =
QVariant( currentKey );
537 attributes[1] =
QVariant( values[ 0 ] );
538 attributes[2] =
QVariant( values[ 1 ] );
542 vWriter.addFeature( dissolveFeature );
549 void QgsGeometryAnalyzer::convexFeature(
QgsFeature& f,
int nProcessedFeatures,
QgsGeometry** dissolveGeometry )
560 convexGeometry = featureGeometry->
convexHull();
562 if ( nProcessedFeatures == 0 )
564 *dissolveGeometry = convexGeometry;
568 tmpGeometry = *dissolveGeometry;
569 *dissolveGeometry = ( *dissolveGeometry )->
combine( convexGeometry );
571 delete convexGeometry;
587 bool useField =
false;
588 if ( uniqueIdField == -1 )
604 if ( onlySelectedFeatures )
609 for ( ; it != selection.
constEnd(); ++it )
615 map.
insert( currentFeature.attribute( uniqueIdField ).toString(), currentFeature.id() );
623 map.
insert( currentFeature.attribute( uniqueIdField ).toString(), currentFeature.id() );
633 int processedFeatures = 0;
636 if ( onlySelectedFeatures )
644 while ( jt != map.
constEnd() && ( jt.
key() == currentKey || !useField ) )
665 dissolveFeature( currentFeature, processedFeatures, &dissolveGeometry );
679 while ( jt != map.
constEnd() && ( jt.
key() == currentKey || !useField ) )
698 dissolveFeature( currentFeature, processedFeatures, &dissolveGeometry );
704 vWriter.addFeature( outputFeature );
709 void QgsGeometryAnalyzer::dissolveFeature(
QgsFeature& f,
int nProcessedFeatures,
QgsGeometry** dissolveGeometry )
718 if ( nProcessedFeatures == 0 )
720 int geomSize = featureGeometry->
wkbSize();
722 unsigned char* wkb =
new unsigned char[geomSize];
723 memcpy( wkb, featureGeometry->
asWkb(), geomSize );
724 ( *dissolveGeometry )->fromWkb( wkb, geomSize );
728 *dissolveGeometry = ( *dissolveGeometry )->
combine( featureGeometry );
758 if ( onlySelectedFeatures )
767 int processedFeatures = 0;
769 for ( ; it != selection.
constEnd(); ++it )
784 bufferFeature( currentFeature, processedFeatures, &vWriter, dissolve, &dissolveGeometry, bufferDistance, bufferDistanceField );
803 int processedFeatures = 0;
815 bufferFeature( currentFeature, processedFeatures, &vWriter, dissolve, &dissolveGeometry, bufferDistance, bufferDistanceField );
827 if ( !dissolveGeometry )
829 QgsDebugMsg(
"no dissolved geometry - should not happen" );
833 vWriter.addFeature( dissolveFeature );
839 QgsGeometry** dissolveGeometry,
double bufferDistance,
int bufferDistanceField )
846 double currentBufferDistance;
852 if ( bufferDistanceField == -1 )
854 currentBufferDistance = bufferDistance;
860 bufferGeometry = featureGeometry->
buffer( currentBufferDistance, 5 );
864 if ( nProcessedFeatures == 0 )
866 *dissolveGeometry = bufferGeometry;
870 tmpGeometry = *dissolveGeometry;
871 *dissolveGeometry = ( *dissolveGeometry )->
combine( bufferGeometry );
873 delete bufferGeometry;
891 const QString& outputFormat,
int locationField1,
int locationField2,
int offsetField,
double offsetScale,
894 if ( !lineLayer || !eventLayer || !lineLayer->
isValid() || !eventLayer->
isValid() )
911 if ( !memoryProvider )
914 if ( locationField2 == -1 )
926 &( lineLayer->
crs() ),
937 double measure1, measure2 = 0.0;
940 int featureCounter = 0;
941 int nOutputFeatures = 0;
966 if ( locationField2 != -1 )
977 for ( ; featureIdIt != featureIdList.
end(); ++featureIdIt )
979 if ( locationField2 == -1 )
991 addEventLayerFeature( fet, lrsGeom, featureIdIt->geometry(), fileWriter, memoryProviderFeatures, offsetField, offsetScale, forceSingleGeometry );
994 if ( nOutputFeatures < 1 )
996 unlocatedFeatureIds.
insert( fet.
id() );
1005 if ( memoryProvider )
1007 memoryProvider->
addFeatures( memoryProviderFeatures );
1014 int offsetField,
double offsetScale,
bool forceSingleType )
1022 if ( forceSingleType )
1032 for ( ; geomIt != geomList.
end(); ++geomIt )
1035 if ( offsetField >= 0 )
1038 offsetVal *= offsetScale;
1039 if ( !createOffsetGeometry( *geomIt, lineGeom, offsetVal ) )
1053 memoryFeatures << feature;
1057 if ( forceSingleType )
1063 bool QgsGeometryAnalyzer::createOffsetGeometry(
QgsGeometry* geom,
QgsGeometry* lineGeom,
double offset )
1065 if ( !geom || !lineGeom )
1084 for ( ; inputGeomIt != inputGeomList.
constEnd(); ++inputGeomIt )
1089 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \ 1090 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3))) 1091 GEOSGeometry* offsetGeom = GEOSOffsetCurve_r( geosctxt, ( *inputGeomIt )->asGeos(), -offset, 8 , 0 , 5.0 );
1092 if ( !offsetGeom || !GEOSisValid_r( geosctxt, offsetGeom ) )
1096 if ( !GEOSisValid_r( geosctxt, offsetGeom ) || GEOSGeomTypeId_r( geosctxt, offsetGeom ) != GEOS_LINESTRING || GEOSGeomGetNumPoints_r( geosctxt, offsetGeom ) < 1 )
1098 GEOSGeom_destroy_r( geosctxt, offsetGeom );
1103 outputGeomList.
push_back( GEOSGeom_clone_r( geosctxt, ( *inputGeomIt )->asGeos() ) );
1108 QgsPoint p = ( *inputGeomIt )->asPoint();
1109 p = createPointOffset( p.
x(), p.
y(), offset, lineGeom );
1110 GEOSCoordSequence* ptSeq = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
1111 GEOSCoordSeq_setX_r( geosctxt, ptSeq, 0, p.
x() );
1112 GEOSCoordSeq_setY_r( geosctxt, ptSeq, 0, p.
y() );
1113 GEOSGeometry* geosPt = GEOSGeom_createPoint_r( geosctxt, ptSeq );
1120 GEOSGeometry* outputGeom = outputGeomList.
at( 0 );
1128 GEOSGeometry** geomArray =
new GEOSGeometry*[outputGeomList.
size()];
1129 for (
int i = 0; i < outputGeomList.
size(); ++i )
1131 geomArray[i] = outputGeomList.
at( i );
1133 GEOSGeometry* collection =
nullptr;
1136 collection = GEOSGeom_createCollection_r( geosctxt, GEOS_MULTIPOINT, geomArray, outputGeomList.
size() );
1140 collection = GEOSGeom_createCollection_r( geosctxt, GEOS_MULTILINESTRING, geomArray, outputGeomList.
size() );
1148 QgsPoint QgsGeometryAnalyzer::createPointOffset(
double x,
double y,
double dist,
QgsGeometry* lineGeom )
const 1155 int beforeVertexNr = afterVertexNr - 1;
1160 double dx = afterVertex.
x() - beforeVertex.
x();
1161 double dy = afterVertex.
y() - beforeVertex.
y();
1162 double normalX = -dy;
1163 double normalY = dx;
1164 double normalLength = sqrt( normalX * normalX + normalY * normalY );
1165 normalX *= ( dist / normalLength );
1166 normalY *= ( dist / normalLength );
1168 double debugLength = sqrt( normalX * normalX + normalY * normalY );
1169 Q_UNUSED( debugLength );
1170 return QgsPoint( x - normalX, y - normalY );
1197 locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure, hasZM );
1203 for (
int i = 0; i < nLines; ++i )
1205 wkbPtr.readHeader();
1206 wkbPtr = locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure, hasZM );
1210 if ( resultGeom.
size() < 1 )
1219 if ( !lineGeom || !lineGeom->
geometry() )
1241 locateAlongWkbString( wkbPtr, resultGeom, measure, hasZM );
1247 for (
int i = 0; i < nLines; ++i )
1249 wkbPtr.readHeader();
1250 wkbPtr = locateAlongWkbString( wkbPtr, resultGeom, measure, hasZM );
1254 if ( resultGeom.
size() < 1 )
1268 double prevx = 0.0, prevy = 0.0, prevz = 0.0;
1269 for (
int i = 0; i < nPoints; ++i )
1275 wkbPtr +=
sizeof( double );
1282 bool secondPointClipped;
1283 bool measureInSegment = clipSegmentByRange( prevx, prevy, prevz, x, y, z, fromMeasure, toMeasure, pt1, pt2, secondPointClipped );
1284 if ( measureInSegment )
1286 if ( currentLine.
size() < 1 )
1288 currentLine.
append( pt1 );
1293 currentLine.
append( pt2 );
1296 if ( secondPointClipped || i == nPoints - 1 )
1298 if ( currentLine.
size() > 1 )
1300 result.
append( currentLine );
1302 currentLine.
clear();
1320 double prevx = 0.0, prevy = 0.0, prevz = 0.0;
1321 for (
int i = 0; i < nPoints; ++i )
1326 wkbPtr +=
sizeof( double );
1334 locateAlongSegment( prevx, prevy, prevz, x, y, z, measure, pt1Ok, pt1, pt2Ok, pt2 );
1339 if ( pt2Ok && i == nPoints - 1 )
1352 bool QgsGeometryAnalyzer::clipSegmentByRange(
double x1,
double y1,
double m1,
double x2,
double y2,
double m2,
double range1,
double range2,
QgsPoint& pt1,
1353 QgsPoint& pt2,
bool& secondPointClipped )
1355 bool reversed = m1 > m2;
1375 if ( range1 > range2 )
1383 if ( m2 < range1 || m1 > range2 )
1389 if ( m2 <= range2 && m1 >= range1 )
1405 secondPointClipped =
false;
1410 if ( m1 >= range1 && m1 <= range2 )
1414 double dist = ( range2 - m1 ) / ( m2 - m1 );
1415 pt2.
setX( x1 + ( x2 - x1 ) * dist );
1416 pt2.
setY( y1 + ( y2 - y1 ) * dist );
1417 secondPointClipped = !reversed;
1421 if ( m2 >= range1 && m2 <= range2 )
1425 double dist = ( m2 - range1 ) / ( m2 - m1 );
1426 pt1.
setX( x2 - ( x2 - x1 ) * dist );
1427 pt1.
setY( y2 - ( y2 - y1 ) * dist );
1428 secondPointClipped = reversed;
1432 if ( range1 >= m1 && range2 <= m2 )
1434 double dist1 = ( range1 - m1 ) / ( m2 - m1 );
1435 double dist2 = ( range2 - m1 ) / ( m2 - m1 );
1436 pt1.
setX( x1 + ( x2 - x1 ) * dist1 );
1437 pt1.
setY( y1 + ( y2 - y1 ) * dist1 );
1438 pt2.
setX( x1 + ( x2 - x1 ) * dist2 );
1439 pt2.
setY( y1 + ( y2 - y1 ) * dist2 );
1440 secondPointClipped =
true;
1453 void QgsGeometryAnalyzer::locateAlongSegment(
double x1,
double y1,
double m1,
double x2,
double y2,
double m2,
double measure,
bool& pt1Ok,
QgsPoint& pt1,
bool& pt2Ok,
QgsPoint& pt2 )
1455 bool reversed =
false;
1458 double tolerance = 0.000001;
1469 if (( m1 - measure ) > tolerance || ( measure - m2 ) > tolerance )
1511 if ( pt1Ok || pt2Ok )
1524 double dist = ( measure - m1 ) / ( m2 - m1 );
1530 pt1.
setX( x1 + dist * ( x2 - x1 ) );
1531 pt1.
setY( y1 + dist * ( y2 - y1 ) );
bool eventLayer(QgsVectorLayer *lineLayer, QgsVectorLayer *eventLayer, int lineField, int eventField, QgsFeatureIds &unlocatedFeatureIds, const QString &outputLayer, const QString &outputFormat, int locationField1, int locationField2=-1, int offsetField=-1, double offsetScale=1.0, bool forceSingleGeometry=false, QgsVectorDataProvider *memoryProvider=nullptr, QProgressDialog *p=nullptr)
Creates an event layer (multipoint or multiline) by locating features from a (non-spatial) event tabl...
QString encoding() const
Get encoding which is used for accessing data.
static int coordDimensions(Type type)
Returns the coordinate dimension of the geometry type as an integer.
Wrapper for iterator of features from vector data provider or vector layer.
A rectangle specified with double values.
QgsGeometry * locateBetweenMeasures(double fromMeasure, double toMeasure, const QgsGeometry *lineGeom)
Returns linear reference geometry as a multiline (or 0 if no match).
QgsAttributes attributes() const
Returns the feature's attributes.
QGis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
QgsPoint asPoint() const
Return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
virtual bool addAttributes(const QList< QgsField > &attributes)
Adds new attributes.
bool simplify(QgsVectorLayer *layer, const QString &shapefileName, double tolerance, bool onlySelectedFeatures=false, QProgressDialog *p=nullptr)
Simplify vector layer using (a modified) Douglas-Peucker algorithm and write it to a new shape file...
void append(const T &value)
void setMaximum(int maximum)
void push_back(const T &value)
static bool hasM(Type type)
Tests whether a WKB type contains m values.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
bool extent(QgsVectorLayer *layer, const QString &shapefileName, bool onlySelectedFeatures=false, QProgressDialog *p=0)
Create a polygon based on the extent of all (selected) features and write it to a new shape file...
const_iterator constBegin() const
const T & at(int i) const
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
bool addFeature(QgsFeature &feature, QgsFeatureRendererV2 *renderer=nullptr, QGis::UnitType outputUnit=QGis::Meters)
Add feature to the currently opened data source.
WkbType
Used for symbology operations.
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
bool centroids(QgsVectorLayer *layer, const QString &shapefileName, bool onlySelectedFeatures=false, QProgressDialog *p=nullptr)
Calculate the true centroids, or 'center of mass' for a vector layer and write it to a new shape file...
A convenience class for writing vector files to disk.
const_iterator insert(const T &value)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
virtual bool addFeatures(QgsFeatureList &flist)
Adds a list of features.
int wkbSize() const
Returns the size of the WKB in asWkb().
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
double y() const
Get the y value of the point.
QgsGeometry * centroid() const
Returns the center of mass of a geometry.
QgsFields fields() const
Returns the list of fields of this layer.
long featureCount(QgsSymbolV2 *symbol)
Number of features rendered with specified symbol.
void setValue(int progress)
void setGeometry(const QgsGeometry &geom)
Set this feature's geometry from another QgsGeometry object.
QgsGeometry * convexHull() const
Returns the smallest convex polygon that contains all the points in the geometry. ...
void append(const T &value)
QgsRectangle extent() override
Return the extent of the layer.
QgsGeometry * buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
const_iterator constEnd() const
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QList< int > QgsAttributeList
void fromGeos(GEOSGeometry *geos)
Set the geometry, feeding in a geometry in GEOS format.
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Append a field. The field must have unique name, otherwise it is rejected (returns false) ...
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
QMap< Key, T >::iterator insert(const Key &key, const T &value)
const_iterator constEnd() const
Encapsulate a field in an attribute table or data source.
QHash< Key, T >::iterator insert(const Key &key, const T &value)
virtual QGis::WkbType geometryType() const =0
Get feature type.
QGis::GeometryType type() const
Returns type of the geometry as a QGis::GeometryType.
bool isValid()
Return the status of the layer.
A class to represent a point.
QgsGeometry * combine(const QgsGeometry *geometry) const
Returns a geometry representing all the points in this geometry and other (a union geometry operation...
QgsGeometry * simplify(double tolerance) const
Returns a simplified version of this geometry using a specified tolerance value.
QgsFeatureId id() const
Get the feature ID for this feature.
void setX(double x)
Sets the x value of the point.
QList< QgsGeometry * > asGeometryCollection() const
Return contents of the geometry as a list of geometries.
void setY(double y)
Sets the y value of the point.
double measureArea(const QgsGeometry *geometry) const
Measures the area of a geometry.
const_iterator constBegin() const
bool contains(const T &value) const
static QgsGeometry * fromMultiPolyline(const QgsMultiPolyline &multiline)
Creates a new geometry from a QgsMultiPolyline object.
const QgsFeatureIds & selectedFeaturesIds() const
Return reference to identifiers of selected features.
General purpose distance and area calculator.
double measurePerimeter(const QgsGeometry *geometry) const
Measures the perimeter of a polygon geometry.
double closestSegmentWithContext(const QgsPoint &point, QgsPoint &minDistPoint, int &afterVertex, double *leftOf=nullptr, double epsilon=DEFAULT_SEGMENT_EPSILON) const
Searches for the closest segment of geometry to the given point.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
QgsAbstractGeometryV2 * geometry() const
Returns the underlying geometry store.
static GEOSContextHandle_t getGEOSHandler()
Return GEOS context handle.
bool buffer(QgsVectorLayer *layer, const QString &shapefileName, double bufferDistance, bool onlySelectedFeatures=false, bool dissolve=false, int bufferDistanceField=-1, QProgressDialog *p=nullptr)
Create buffers for a vector layer and write it to a new shape file.
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry.
Class for storing a coordinate reference system (CRS)
QList< QgsField > toList() const
Utility function to return a list of QgsField instances.
QList< T > values() const
static QgsGeometry * fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
QgsGeometry * locateAlongMeasure(double measure, const QgsGeometry *lineGeom)
Returns linear reference geometry.
double xMinimum() const
Get the x minimum value (left side of rectangle)
static QgsGeometry * fromMultiPoint(const QgsMultiPoint &multipoint)
Creates a new geometry from a QgsMultiPoint object.
static Type flatType(Type type)
Returns the flat type for a WKB type.
double toDouble(bool *ok) const
void setMinimum(int minimum)
QgsWKBTypes::Type readHeader() const
QgsVectorDataProvider * dataProvider()
Returns the data provider.
const_iterator constEnd() const
bool nextFeature(QgsFeature &f)
const_iterator constBegin() const
This is the base class for vector data providers.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Represents a vector layer which manages a vector based data sets.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
double x() const
Get the x value of the point.
bool dissolve(QgsVectorLayer *layer, const QString &shapefileName, bool onlySelectedFeatures=false, int uniqueIdField=-1, QProgressDialog *p=nullptr)
Dissolve a vector layer and write it to a new shape file.
static Type singleType(Type type)
Returns the single type for a WKB type.
bool convexHull(QgsVectorLayer *layer, const QString &shapefileName, bool onlySelectedFeatures=false, int uniqueIdField=-1, QProgressDialog *p=nullptr)
Create convex hull(s) of a vector layer and write it to a new shape file.
QgsRectangle boundingBoxOfSelected()
Returns the bounding box of the selected features.