28 #include <QProgressDialog>
31 const QString& shapefileName,
33 bool onlySelectedFeatures,
54 if ( onlySelectedFeatures )
60 p->setMaximum( selection.size() );
63 int processedFeatures = 0;
64 QgsFeatureIds::const_iterator it = selection.constBegin();
65 for ( ; it != selection.constEnd(); ++it )
69 p->setValue( processedFeatures );
72 if ( p && p->wasCanceled() )
86 p->setValue( selection.size() );
97 p->setMaximum( featureCount );
99 int processedFeatures = 0;
105 p->setValue( processedFeatures );
107 if ( p && p->wasCanceled() )
116 p->setValue( featureCount );
128 if ( !featureGeometry )
133 tmpGeometry = featureGeometry->
simplify( tolerance );
147 bool onlySelectedFeatures, QProgressDialog* p )
158 QgsDebugMsg(
"No data provider for layer passed to centroids" );
169 if ( onlySelectedFeatures )
175 p->setMaximum( selection.size() );
178 int processedFeatures = 0;
179 QgsFeatureIds::const_iterator it = selection.constBegin();
180 for ( ; it != selection.constEnd(); ++it )
184 p->setValue( processedFeatures );
187 if ( p && p->wasCanceled() )
201 p->setValue( selection.size() );
212 p->setMaximum( featureCount );
214 int processedFeatures = 0;
220 p->setValue( processedFeatures );
222 if ( p && p->wasCanceled() )
231 p->setValue( featureCount );
244 if ( !featureGeometry )
249 tmpGeometry = featureGeometry->
centroid();
263 const QString& shapefileName,
264 bool onlySelectedFeatures,
289 fields.
append(
QgsField( QString(
"PERIM" ), QVariant::Double ) );
290 fields.
append(
QgsField( QString(
"HEIGHT" ), QVariant::Double ) );
291 fields.
append(
QgsField( QString(
"WIDTH" ), QVariant::Double ) );
296 if ( onlySelectedFeatures )
306 double miny = rect.yMinimum();
307 double maxx = rect.xMaximum();
308 double maxy = rect.yMaximum();
309 double height = rect.height();
310 double width = rect.width();
311 double cntx = minx + ( width / 2.0 );
312 double cnty = miny + ( height / 2.0 );
313 double area = width * height;
314 double perim = ( 2 * width ) + ( 2 * height );
318 attrs[0] = QVariant( minx );
319 attrs[1] = QVariant( miny );
320 attrs[2] = QVariant( maxx );
321 attrs[3] = QVariant( maxy );
322 attrs[4] = QVariant( cntx );
323 attrs[5] = QVariant( cnty );
324 attrs[6] = QVariant( area );
325 attrs[7] = QVariant( perim );
326 attrs[8] = QVariant( height );
327 attrs[9] = QVariant( width );
330 vWriter.addFeature( feat );
341 list.append( pt.
x() );
342 list.append( pt.
y() );
347 list.append( measure.
measure( mpGeometry ) );
351 list.append( perim );
363 QgsMultiPolygon::iterator it;
364 QgsPolygon::iterator jt;
365 for ( it = poly.begin(); it != poly.end(); ++it )
367 for ( jt = it->begin(); jt != it->end(); ++jt )
375 QgsPolygon::iterator jt;
377 for ( jt = poly.begin(); jt != poly.end(); ++jt )
386 bool onlySelectedFeatures,
int uniqueIdField, QProgressDialog* p )
397 bool useField =
false;
398 if ( uniqueIdField == -1 )
409 fields.
append(
QgsField( QString(
"PERIM" ), QVariant::Double ) );
417 QMultiMap<QString, QgsFeatureId> map;
419 if ( onlySelectedFeatures )
423 QgsFeatureIds::const_iterator it = selection.constBegin();
424 for ( ; it != selection.constEnd(); ++it )
429 p->setValue( processedFeatures );
431 if ( p && p->wasCanceled() )
441 map.insert( currentFeature.attribute( uniqueIdField ).toString(), currentFeature.id() );
452 p->setValue( processedFeatures );
454 if ( p && p->wasCanceled() )
460 map.insert( currentFeature.attribute( uniqueIdField ).toString(), currentFeature.id() );
464 QMultiMap<QString, QgsFeatureId>::const_iterator jt = map.constBegin();
465 while ( jt != map.constEnd() )
467 QString currentKey = jt.key();
468 int processedFeatures = 0;
470 if ( onlySelectedFeatures )
476 p->setMaximum( selection.size() );
478 processedFeatures = 0;
479 while ( jt != map.constEnd() && ( jt.key() == currentKey || !useField ) )
481 if ( p && p->wasCanceled() )
485 if ( selection.contains( jt.value() ) )
489 p->setValue( processedFeatures );
495 convexFeature( currentFeature, processedFeatures, &dissolveGeometry );
500 QList<double> values;
501 if ( !dissolveGeometry )
503 QgsDebugMsg(
"no dissolved geometry - should not happen" );
506 dissolveGeometry = dissolveGeometry->
convexHull();
509 attributes[0] = QVariant( currentKey );
510 attributes[1] = values[ 0 ];
511 attributes[2] = values[ 1 ];
515 vWriter.addFeature( dissolveFeature );
523 p->setMaximum( featureCount );
525 processedFeatures = 0;
526 while ( jt != map.constEnd() && ( jt.key() == currentKey || !useField ) )
530 p->setValue( processedFeatures );
533 if ( p && p->wasCanceled() )
541 convexFeature( currentFeature, processedFeatures, &dissolveGeometry );
545 QList<double> values;
547 if ( !dissolveGeometry )
549 QgsDebugMsg(
"no dissolved geometry - should not happen" );
552 dissolveGeometry = dissolveGeometry->
convexHull();
556 attributes[0] = QVariant( currentKey );
557 attributes[1] = QVariant( values[ 0 ] );
558 attributes[2] = QVariant( values[ 1 ] );
562 vWriter.addFeature( dissolveFeature );
575 if ( !featureGeometry )
580 convexGeometry = featureGeometry->
convexHull();
582 if ( nProcessedFeatures == 0 )
584 *dissolveGeometry = convexGeometry;
588 tmpGeometry = *dissolveGeometry;
589 *dissolveGeometry = ( *dissolveGeometry )->
combine( convexGeometry );
591 delete convexGeometry;
596 bool onlySelectedFeatures,
int uniqueIdField, QProgressDialog* p )
607 bool useField =
false;
608 if ( uniqueIdField == -1 )
622 QMultiMap<QString, QgsFeatureId> map;
624 if ( onlySelectedFeatures )
628 QgsFeatureIds::const_iterator it = selection.constBegin();
629 for ( ; it != selection.constEnd(); ++it )
635 map.insert( currentFeature.attribute( uniqueIdField ).toString(), currentFeature.id() );
643 map.insert( currentFeature.attribute( uniqueIdField ).toString(), currentFeature.id() );
648 QMultiMap<QString, QgsFeatureId>::const_iterator jt = map.constBegin();
650 while ( jt != map.constEnd() )
652 QString currentKey = jt.key();
653 int processedFeatures = 0;
656 if ( onlySelectedFeatures )
662 p->setMaximum( selection.size() );
664 while ( jt != map.constEnd() && ( jt.key() == currentKey || !useField ) )
666 if ( p && p->wasCanceled() )
670 if ( selection.contains( jt.value() ) )
674 p->setValue( processedFeatures );
685 dissolveFeature( currentFeature, processedFeatures, &dissolveGeometry );
697 p->setMaximum( featureCount );
699 while ( jt != map.constEnd() && ( jt.key() == currentKey || !useField ) )
703 p->setValue( processedFeatures );
706 if ( p && p->wasCanceled() )
718 dissolveFeature( currentFeature, processedFeatures, &dissolveGeometry );
724 vWriter.addFeature( outputFeature );
733 if ( !featureGeometry )
738 if ( nProcessedFeatures == 0 )
740 size_t geomSize = featureGeometry->
wkbSize();
742 unsigned char* wkb =
new unsigned char[geomSize];
743 memcpy( wkb, featureGeometry->
asWkb(), geomSize );
744 ( *dissolveGeometry )->fromWkb( wkb, geomSize );
748 *dissolveGeometry = ( *dissolveGeometry )->
combine( featureGeometry );
753 bool onlySelectedFeatures,
bool dissolve,
int bufferDistanceField, QProgressDialog* p )
778 if ( onlySelectedFeatures )
784 p->setMaximum( selection.size() );
787 int processedFeatures = 0;
788 QgsFeatureIds::const_iterator it = selection.constBegin();
789 for ( ; it != selection.constEnd(); ++it )
793 p->setValue( processedFeatures );
796 if ( p && p->wasCanceled() )
804 bufferFeature( currentFeature, processedFeatures, &vWriter, dissolve, &dissolveGeometry, bufferDistance, bufferDistanceField );
810 p->setValue( selection.size() );
821 p->setMaximum( featureCount );
823 int processedFeatures = 0;
829 p->setValue( processedFeatures );
831 if ( p && p->wasCanceled() )
835 bufferFeature( currentFeature, processedFeatures, &vWriter, dissolve, &dissolveGeometry, bufferDistance, bufferDistanceField );
840 p->setValue( featureCount );
847 if ( !dissolveGeometry )
849 QgsDebugMsg(
"no dissolved geometry - should not happen" );
853 vWriter.addFeature( dissolveFeature );
859 QgsGeometry** dissolveGeometry,
double bufferDistance,
int bufferDistanceField )
861 double currentBufferDistance;
866 if ( !featureGeometry )
872 if ( bufferDistanceField == -1 )
874 currentBufferDistance = bufferDistance;
878 currentBufferDistance = f.
attribute( bufferDistanceField ).toDouble();
880 bufferGeometry = featureGeometry->
buffer( currentBufferDistance, 5 );
884 if ( nProcessedFeatures == 0 )
886 *dissolveGeometry = bufferGeometry;
890 tmpGeometry = *dissolveGeometry;
891 *dissolveGeometry = ( *dissolveGeometry )->
combine( bufferGeometry );
893 delete bufferGeometry;
911 const QString& outputFormat,
int locationField1,
int locationField2,
int offsetField,
double offsetScale,
914 if ( !lineLayer || !eventLayer || !lineLayer->
isValid() || !eventLayer->
isValid() )
920 QMultiHash< QString, QgsFeatureId > lineLayerIdMap;
925 lineLayerIdMap.insert( fet.
attribute( lineField ).toString(), fet.
id() );
931 if ( !memoryProvider )
934 if ( locationField2 == -1 )
946 &( lineLayer->
crs() ),
958 double measure1, measure2 = 0.0;
961 int featureCounter = 0;
962 int nOutputFeatures = 0;
965 p->setWindowModality( Qt::WindowModal );
967 p->setMaximum( nEventFeatures );
978 if ( p->wasCanceled() )
982 p->setValue( featureCounter );
986 measure1 = fet.
attribute( locationField1 ).toDouble();
987 if ( locationField2 != -1 )
989 measure2 = fet.
attribute( locationField2 ).toDouble();
992 QList<QgsFeatureId> featureIdList = lineLayerIdMap.values( fet.
attribute( eventField ).toString() );
993 QList<QgsFeatureId>::const_iterator featureIdIt = featureIdList.constBegin();
994 for ( ; featureIdIt != featureIdList.constEnd(); ++featureIdIt )
1001 if ( locationField2 == -1 )
1013 addEventLayerFeature( fet, lrsGeom, lineFeature.
geometry(), fileWriter, memoryProviderFeatures, offsetField, offsetScale, forceSingleGeometry );
1016 if ( nOutputFeatures < 1 )
1018 unlocatedFeatureIds.push_back( fet.
id() );
1024 p->setValue( nEventFeatures );
1027 if ( memoryProvider )
1029 memoryProvider->
addFeatures( memoryProviderFeatures );
1036 int offsetField,
double offsetScale,
bool forceSingleType )
1043 QList<QgsGeometry*> geomList;
1044 if ( forceSingleType )
1050 geomList.push_back( geom );
1053 QList<QgsGeometry*>::iterator geomIt = geomList.begin();
1054 for ( ; geomIt != geomList.end(); ++geomIt )
1057 if ( offsetField >= 0 )
1059 double offsetVal = feature.
attribute( offsetField ).toDouble();
1060 offsetVal *= offsetScale;
1071 memoryFeatures << feature;
1075 if ( forceSingleType )
1083 if ( !geom || !lineGeom )
1088 QList<QgsGeometry*> inputGeomList;
1096 inputGeomList.push_back( geom );
1099 QList<GEOSGeometry*> outputGeomList;
1100 QList<QgsGeometry*>::const_iterator inputGeomIt = inputGeomList.constBegin();
1101 for ( ; inputGeomIt != inputGeomList.constEnd(); ++inputGeomIt )
1106 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
1107 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)))
1108 outputGeomList.push_back( GEOSOffsetCurve(( *inputGeomIt )->asGeos(), -offset, 8 , 0 , 5.0 ) );
1110 outputGeomList.push_back( GEOSGeom_clone(( *inputGeomIt )->asGeos() ) );
1115 QgsPoint p = ( *inputGeomIt )->asPoint();
1117 GEOSCoordSequence* ptSeq = GEOSCoordSeq_create( 1, 2 );
1118 GEOSCoordSeq_setX( ptSeq, 0, p.
x() );
1119 GEOSCoordSeq_setY( ptSeq, 0, p.
y() );
1120 GEOSGeometry* geosPt = GEOSGeom_createPoint( ptSeq );
1121 outputGeomList.push_back( geosPt );
1127 GEOSGeometry* outputGeom = outputGeomList.at( 0 );
1135 GEOSGeometry** geomArray =
new GEOSGeometry*[outputGeomList.size()];
1136 for (
int i = 0; i < outputGeomList.size(); ++i )
1138 geomArray[i] = outputGeomList.at( i );
1140 GEOSGeometry* collection = 0;
1143 collection = GEOSGeom_createCollection( GEOS_MULTIPOINT, geomArray, outputGeomList.size() );
1147 collection = GEOSGeom_createCollection( GEOS_MULTILINESTRING, geomArray, outputGeomList.size() );
1161 int beforeVertexNr = afterVertexNr - 1;
1166 double dx = afterVertex.
x() - beforeVertex.
x();
1167 double dy = afterVertex.
y() - beforeVertex.
y();
1168 double normalX = -dy;
1169 double normalY = dx;
1170 double normalLength = sqrt( normalX * normalX + normalY * normalY );
1171 normalX *= ( dist / normalLength );
1172 normalY *= ( dist / normalLength );
1174 double debugLength = sqrt( normalX * normalX + normalY * normalY );
1175 Q_UNUSED( debugLength );
1176 return QgsPoint( x - normalX, y - normalY );
1189 const unsigned char* lineWkb = lineGeom->
asWkb();
1191 const unsigned char* ptr = lineWkb + 1;
1193 memcpy( &wkbType, ptr,
sizeof( wkbType ) );
1194 ptr +=
sizeof( wkbType );
1207 int* nLines = (
int* )ptr;
1208 ptr +=
sizeof( int );
1209 for (
int i = 0; i < *nLines; ++i )
1211 ptr += ( 1 +
sizeof( wkbType ) );
1216 if ( resultGeom.size() < 1 )
1233 const unsigned char* lineWkb = lineGeom->
asWkb();
1235 const unsigned char* ptr = lineWkb + 1;
1237 memcpy( &wkbType, ptr,
sizeof( wkbType ) );
1238 ptr +=
sizeof( wkbType );
1251 int* nLines = (
int* )ptr;
1252 ptr +=
sizeof( int );
1253 for (
int i = 0; i < *nLines; ++i )
1255 ptr += ( 1 +
sizeof( wkbType ) );
1260 if ( resultGeom.size() < 1 )
1269 int* nPoints = (
int* ) ptr;
1270 ptr +=
sizeof( int );
1271 double prevx = 0.0, prevy = 0.0, prevz = 0.0;
1276 bool measureInSegment;
1277 bool secondPointClipped;
1280 for (
int i = 0; i < *nPoints; ++i )
1283 ptr +=
sizeof( double );
1285 ptr +=
sizeof( double );
1286 z = (
double* ) ptr;
1287 ptr +=
sizeof( double );
1291 measureInSegment =
clipSegmentByRange( prevx, prevy, prevz, *x, *y, *z, fromMeasure, toMeasure, pt1, pt2, secondPointClipped );
1292 if ( measureInSegment )
1294 if ( currentLine.size() < 1 )
1296 currentLine.append( pt1 );
1301 currentLine.append( pt2 );
1304 if ( secondPointClipped || i == *nPoints - 1 )
1306 if ( currentLine.size() > 1 )
1308 result.append( currentLine );
1310 currentLine.clear();
1314 prevx = *x; prevy = *y; prevz = *z;
1321 int* nPoints = (
int* ) ptr;
1322 ptr +=
sizeof( int );
1323 double prevx = 0.0, prevy = 0.0, prevz = 0.0;
1329 for (
int i = 0; i < *nPoints; ++i )
1332 ptr +=
sizeof( double );
1334 ptr +=
sizeof( double );
1335 z = (
double* ) ptr;
1336 ptr +=
sizeof( double );
1340 locateAlongSegment( prevx, prevy, prevz, *x, *y, *z, measure, pt1Ok, pt1, pt2Ok, pt2 );
1343 result.append( pt1 );
1345 if ( pt2Ok && ( i == ( *nPoints - 1 ) ) )
1347 result.append( pt2 );
1350 prevx = *x; prevy = *y; prevz = *z;
1356 QgsPoint& pt2,
bool& secondPointClipped )
1358 bool reversed = m1 > m2;
1378 if ( range1 > range2 )
1386 if ( m2 < range1 || m1 > range2 )
1392 if ( m2 <= range2 && m1 >= range1 )
1404 secondPointClipped =
false;
1409 if ( m1 >= range1 && m1 <= range2 )
1412 double dist = ( range2 - m1 ) / ( m2 - m1 );
1413 pt2.
setX( x1 + ( x2 - x1 ) * dist );
1414 pt2.
setY( y1 + ( y2 - y1 ) * dist );
1415 secondPointClipped = !reversed;
1419 if ( m2 >= range1 && m2 <= range2 )
1422 double dist = ( m2 - range1 ) / ( m2 - m1 );
1423 pt1.
setX( x2 - ( x2 - x1 ) * dist );
1424 pt1.
setY( y2 - ( y2 - y1 ) * dist );
1425 secondPointClipped = reversed;
1429 if ( range1 >= m1 && range2 <= m2 )
1431 double dist1 = ( range1 - m1 ) / ( m2 - m1 );
1432 double dist2 = ( range2 - m1 ) / ( m2 - m1 );
1433 pt1.
setX( x1 + ( x2 - x1 ) * dist1 );
1434 pt1.
setY( y1 + ( y2 - y1 ) * dist1 );
1435 pt2.
setX( x1 + ( x2 - x1 ) * dist2 );
1436 pt2.
setY( y1 + ( y2 - y1 ) * dist2 );
1437 secondPointClipped =
true;
1450 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 )
1452 bool reversed =
false;
1455 double tolerance = 0.000001;
1466 if (( m1 - measure ) > tolerance || ( measure - m2 ) > tolerance )
1504 if ( pt1Ok || pt2Ok )
1517 double dist = ( measure - m1 ) / ( m2 - m1 );
1523 pt1.
setX( x1 + dist * ( x2 - x1 ) );
1524 pt1.
setY( y1 + dist * ( y2 - y1 ) );