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 );
1194 locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure );
1200 for (
int i = 0; i < nLines; ++i )
1202 wkbPtr.readHeader();
1203 wkbPtr = locateBetweenWkbString( wkbPtr, resultGeom, fromMeasure, toMeasure );
1207 if ( resultGeom.
size() < 1 )
1234 locateAlongWkbString( wkbPtr, resultGeom, measure );
1240 for (
int i = 0; i < nLines; ++i )
1242 wkbPtr.readHeader();
1243 wkbPtr = locateAlongWkbString( wkbPtr, resultGeom, measure );
1247 if ( resultGeom.
size() < 1 )
1261 double prevx = 0.0, prevy = 0.0, prevz = 0.0;
1262 for (
int i = 0; i < nPoints; ++i )
1265 wkbPtr >> x >> y >> z;
1270 bool secondPointClipped;
1271 bool measureInSegment = clipSegmentByRange( prevx, prevy, prevz, x, y, z, fromMeasure, toMeasure, pt1, pt2, secondPointClipped );
1272 if ( measureInSegment )
1274 if ( currentLine.
size() < 1 )
1276 currentLine.
append( pt1 );
1281 currentLine.
append( pt2 );
1284 if ( secondPointClipped || i == nPoints - 1 )
1286 if ( currentLine.
size() > 1 )
1288 result.
append( currentLine );
1290 currentLine.
clear();
1308 double prevx = 0.0, prevy = 0.0, prevz = 0.0;
1309 for (
int i = 0; i < nPoints; ++i )
1311 wkbPtr >> x >> y >> z;
1317 locateAlongSegment( prevx, prevy, prevz, x, y, z, measure, pt1Ok, pt1, pt2Ok, pt2 );
1322 if ( pt2Ok && i == nPoints - 1 )
1335 bool QgsGeometryAnalyzer::clipSegmentByRange(
double x1,
double y1,
double m1,
double x2,
double y2,
double m2,
double range1,
double range2,
QgsPoint& pt1,
1336 QgsPoint& pt2,
bool& secondPointClipped )
1338 bool reversed = m1 > m2;
1358 if ( range1 > range2 )
1366 if ( m2 < range1 || m1 > range2 )
1372 if ( m2 <= range2 && m1 >= range1 )
1388 secondPointClipped =
false;
1393 if ( m1 >= range1 && m1 <= range2 )
1397 double dist = ( range2 - m1 ) / ( m2 - m1 );
1398 pt2.
setX( x1 + ( x2 - x1 ) * dist );
1399 pt2.
setY( y1 + ( y2 - y1 ) * dist );
1400 secondPointClipped = !reversed;
1404 if ( m2 >= range1 && m2 <= range2 )
1408 double dist = ( m2 - range1 ) / ( m2 - m1 );
1409 pt1.
setX( x2 - ( x2 - x1 ) * dist );
1410 pt1.
setY( y2 - ( y2 - y1 ) * dist );
1411 secondPointClipped = reversed;
1415 if ( range1 >= m1 && range2 <= m2 )
1417 double dist1 = ( range1 - m1 ) / ( m2 - m1 );
1418 double dist2 = ( range2 - m1 ) / ( m2 - m1 );
1419 pt1.
setX( x1 + ( x2 - x1 ) * dist1 );
1420 pt1.
setY( y1 + ( y2 - y1 ) * dist1 );
1421 pt2.
setX( x1 + ( x2 - x1 ) * dist2 );
1422 pt2.
setY( y1 + ( y2 - y1 ) * dist2 );
1423 secondPointClipped =
true;
1436 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 )
1438 bool reversed =
false;
1441 double tolerance = 0.000001;
1452 if (( m1 - measure ) > tolerance || ( measure - m2 ) > tolerance )
1494 if ( pt1Ok || pt2Ok )
1507 double dist = ( measure - m1 ) / ( m2 - m1 );
1513 pt1.
setX( x1 + dist * ( x2 - x1 ) );
1514 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.
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)
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...
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)
Compare two doubles (but allow some difference)
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.
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.
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.
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.
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.