@@ -1035,7 +1035,7 @@ bool QgsGeometryAnalyzer::eventLayer( QgsVectorLayer* lineLayer, QgsVectorLayer*
1035
1035
return true ;
1036
1036
}
1037
1037
1038
- void QgsGeometryAnalyzer::addEventLayerFeature ( QgsFeature& feature, QgsGeometry* geom, const QgsGeometry* lineGeom, QgsVectorFileWriter* fileWriter, QgsFeatureList& memoryFeatures,
1038
+ void QgsGeometryAnalyzer::addEventLayerFeature ( QgsFeature& feature, QgsGeometry* geom, QgsGeometry* lineGeom, QgsVectorFileWriter* fileWriter, QgsFeatureList& memoryFeatures,
1039
1039
int offsetField, double offsetScale, bool forceSingleType )
1040
1040
{
1041
1041
if ( !geom )
@@ -1081,9 +1081,177 @@ void QgsGeometryAnalyzer::addEventLayerFeature( QgsFeature& feature, QgsGeometry
1081
1081
}
1082
1082
}
1083
1083
1084
- void QgsGeometryAnalyzer::createOffsetGeometry ( QgsGeometry* geom, const QgsGeometry* lineGeom, double offset )
1084
+ void QgsGeometryAnalyzer::createOffsetGeometry ( QgsGeometry* geom, QgsGeometry* lineGeom, double offset )
1085
1085
{
1086
- // todo...
1086
+ if ( !geom || !lineGeom )
1087
+ {
1088
+ return ;
1089
+ }
1090
+
1091
+ QList<QgsGeometry*> inputGeomList;
1092
+
1093
+ if ( geom->isMultipart () )
1094
+ {
1095
+ inputGeomList = geom->asGeometryCollection ();
1096
+ }
1097
+ else
1098
+ {
1099
+ inputGeomList.push_back ( geom );
1100
+ }
1101
+
1102
+ QList<GEOSGeometry*> outputGeomList;
1103
+ QList<QgsGeometry*>::const_iterator inputGeomIt = inputGeomList.constBegin ();
1104
+ for (; inputGeomIt != inputGeomList.constEnd (); ++inputGeomIt )
1105
+ {
1106
+ if ( geom->type () == QGis::Line )
1107
+ {
1108
+ // geos 3.3 needed for line offsets
1109
+ #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
1110
+ ((GEOS_VERSION_MAJOR>3 ) || ((GEOS_VERSION_MAJOR==3 ) && (GEOS_VERSION_MINOR>=3 )))
1111
+ outputGeomList.push_back ( GEOSOffsetCurve ( (*inputGeomIt)->asGeos (), offset, 8 /* quadSegments*/ , 0 /* joinStyle*/ , 5.0 /* mitreLimit*/ ) );
1112
+ #else
1113
+ outputGeomList.push_back ( 0 );
1114
+ #endif
1115
+ }
1116
+ else if ( geom->type () == QGis::Point )
1117
+ {
1118
+ QgsPoint p = (*inputGeomIt)->asPoint ();
1119
+ p = createPointOffset ( p.x (), p.y (), offset, lineGeom );
1120
+ GEOSCoordSequence* ptSeq = GEOSCoordSeq_create ( 1 , 2 );
1121
+ GEOSCoordSeq_setX ( ptSeq, 0 , p.x () );
1122
+ GEOSCoordSeq_setY ( ptSeq, 0 , p.y () );
1123
+ GEOSGeometry* geosPt = GEOSGeom_createPoint ( ptSeq );
1124
+ outputGeomList.push_back ( geosPt );
1125
+ }
1126
+ }
1127
+
1128
+ if ( !geom->isMultipart () )
1129
+ {
1130
+ GEOSGeometry* outputGeom = outputGeomList.at ( 0 );
1131
+ if ( outputGeom )
1132
+ {
1133
+ geom->fromGeos ( outputGeom );
1134
+ }
1135
+ }
1136
+ else
1137
+ {
1138
+ GEOSGeometry** geomArray = new GEOSGeometry*[outputGeomList.size ()];
1139
+ for ( int i = 0 ; i < outputGeomList.size (); ++i )
1140
+ {
1141
+ geomArray[i] = outputGeomList.at ( i );
1142
+ }
1143
+ GEOSGeometry* collection = 0 ;
1144
+ if ( geom->type () == QGis::Point )
1145
+ {
1146
+ collection = GEOSGeom_createCollection ( GEOS_MULTIPOINT, geomArray, outputGeomList.size () );
1147
+ }
1148
+ else if ( geom->type () == QGis::Line )
1149
+ {
1150
+ collection = GEOSGeom_createCollection ( GEOS_MULTILINESTRING, geomArray, outputGeomList.size () );
1151
+ }
1152
+ geom->fromGeos ( collection );
1153
+ delete[] geomArray;
1154
+ }
1155
+ }
1156
+
1157
+ #if 0
1158
+ if( geom->type() == QGis::Line )
1159
+ {
1160
+ QList<GEOSGeometry*> outputGeomList;
1161
+ QList<QgsGeometry*>::const_iterator inputGeomIt = inputGeomList.constBegin();
1162
+ for(; inputGeomIt != inputGeomList.constEnd(); ++inputGeomIt )
1163
+ {
1164
+ //geos 3.3 needed for line offsets
1165
+ #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
1166
+ ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)))
1167
+ outputGeomList.push_back( GEOSOffsetCurve( (*inputGeomIt)->asGeos(), offset, 8 /*quadSegments*/, 0 /*joinStyle*/, 5.0 /*mitreLimit*/ ) );
1168
+ #else
1169
+ outputGeomList.push_back( 0 );
1170
+ #endif
1171
+ }
1172
+
1173
+ if( !geom->isMultipart() )
1174
+ {
1175
+ GEOSGeometry* outputGeom = outputGeomList.at( 0 );
1176
+ if( outputGeom )
1177
+ {
1178
+ geom->fromGeos( outputGeom );
1179
+ }
1180
+ }
1181
+ else
1182
+ {
1183
+ GEOSGeometry** geomArray = new GEOSGeometry*[outputGeomList.size()];
1184
+ for( int i = 0; i < outputGeomList.size(); ++i )
1185
+ {
1186
+ geomArray[i] = outputGeomList.at( i );
1187
+ }
1188
+ GEOSGeometry* collection = GEOSGeom_createCollection( GEOS_MULTILINESTRING, geomArray, outputGeomList.size() );
1189
+ geom->fromGeos( collection );
1190
+ delete[] geomArray;
1191
+ }
1192
+ }
1193
+ else if( geom->type() == QGis::Point )
1194
+ {
1195
+ QList<GEOSGeometry*> outputGeomList;
1196
+ QList<QgsGeometry*>::const_iterator inputGeomIt = inputGeomList.constBegin();
1197
+ for(; inputGeomIt != inputGeomList.constEnd(); ++inputGeomIt )
1198
+ {
1199
+ QgsPoint p = (*inputGeomIt)->asPoint();
1200
+ p = createPointOffset( p.x(), p.y(), offset, lineGeom );
1201
+ GEOSCoordSequence* ptSeq = GEOSCoordSeq_create( 1, 2 );
1202
+ GEOSCoordSeq_setX( ptSeq, 0, p.x() );
1203
+ GEOSCoordSeq_setY( ptSeq, 0, p.y() );
1204
+ GEOSGeometry* geosPt = GEOSGeom_createPoint( ptSeq );
1205
+ outputGeomList.push_back( geosPt );
1206
+ //geom->fromGeos( geosPt );
1207
+ }
1208
+
1209
+ if( !geom->isMultipart() )
1210
+ {
1211
+ GEOSGeometry* outputGeom = outputGeomList.at( 0 );
1212
+ if( outputGeom )
1213
+ {
1214
+ geom->fromGeos( outputGeom );
1215
+ }
1216
+ }
1217
+ else
1218
+ {
1219
+ GEOSGeometry** geomArray = new GEOSGeometry*[outputGeomList.size()];
1220
+ for( int i = 0; i < outputGeomList.size(); ++i )
1221
+ {
1222
+ geomArray[i] = outputGeomList.at( i );
1223
+ }
1224
+ GEOSGeometry* collection = GEOSGeom_createCollection( GEOS_MULTIPOINT, geomArray, outputGeomList.size() );
1225
+ geom->fromGeos( collection );
1226
+ delete[] geomArray;
1227
+ }
1228
+ }
1229
+ }
1230
+ #endif // 0
1231
+
1232
+ QgsPoint QgsGeometryAnalyzer::createPointOffset ( double x, double y, double dist, QgsGeometry* lineGeom ) const
1233
+ {
1234
+ QgsPoint p ( x, y );
1235
+ QgsPoint minDistPoint;
1236
+ int beforeVertexNr;
1237
+ lineGeom->closestSegmentWithContext ( p, minDistPoint, beforeVertexNr );
1238
+
1239
+ int afterVertexNr = beforeVertexNr + 1 ;
1240
+ QgsPoint beforeVertex = lineGeom->vertexAt ( beforeVertexNr );
1241
+ QgsPoint afterVertex = lineGeom->vertexAt ( afterVertexNr );
1242
+
1243
+ // get normal vector
1244
+ double dx = afterVertex.x () - beforeVertex.x ();
1245
+ double dy = afterVertex.y () - beforeVertex.y ();
1246
+ double normalX = -dy;
1247
+ double normalY = dx;
1248
+ double normalLength = sqrt ( normalX * normalX + normalY * normalY );
1249
+ normalX *= ( dist / normalLength );
1250
+ normalY *= ( dist / normalLength );
1251
+
1252
+ double debugLength = sqrt ( normalX * normalX + normalY * normalY ); // control
1253
+
1254
+ return QgsPoint ( x - normalX, y - normalY ); // negative values -> left side, positive values -> right side
1087
1255
}
1088
1256
1089
1257
QgsGeometry* QgsGeometryAnalyzer::locateBetweenMeasures ( double fromMeasure, double toMeasure, QgsGeometry* lineGeom )
0 commit comments