Skip to content

Commit 0f22a29

Browse files
committedOct 26, 2018
Fix dropping/adding z dimensions to certain output data types
where the layer geometry type is defined by features, not preset in advance Fixes #20220, #17669
1 parent 4bc561c commit 0f22a29

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed
 

‎src/core/qgsvectorfilewriter.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,6 +2236,19 @@ gdal::ogr_feature_unique_ptr QgsVectorFileWriter::createFeature( const QgsFeatur
22362236
}
22372237
}
22382238

2239+
// drop m/z value if not present in output wkb type
2240+
if ( !QgsWkbTypes::hasZ( mWkbType ) && QgsWkbTypes::hasZ( geom.wkbType() ) )
2241+
geom.get()->dropZValue();
2242+
if ( !QgsWkbTypes::hasM( mWkbType ) && QgsWkbTypes::hasM( geom.wkbType() ) )
2243+
geom.get()->dropMValue();
2244+
2245+
// add m/z values if not present in the input wkb type -- this is needed for formats which determine
2246+
// geometry type based on features, e.g. geojson
2247+
if ( QgsWkbTypes::hasZ( mWkbType ) && !QgsWkbTypes::hasZ( geom.wkbType() ) )
2248+
geom.get()->addZValue( 0 );
2249+
if ( QgsWkbTypes::hasM( mWkbType ) && !QgsWkbTypes::hasM( geom.wkbType() ) )
2250+
geom.get()->addMValue( 0 );
2251+
22392252
if ( !mGeom2 )
22402253
{
22412254
// there's a problem when layer type is set as wkbtype Polygon

‎tests/src/python/test_qgsvectorfilewriter.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,68 @@ def testCreateDGN(self):
982982

983983
os.unlink(filename)
984984

985+
def testAddZ(self):
986+
"""Check adding z values to non z input."""
987+
input = QgsVectorLayer(
988+
'Point?crs=epsg:4326&field=name:string(20)',
989+
'test',
990+
'memory')
991+
992+
self.assertTrue(input.isValid(), 'Provider not initialized')
993+
994+
ft = QgsFeature()
995+
ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10)))
996+
myResult, myFeatures = input.dataProvider().addFeatures([ft])
997+
self.assertTrue(myResult)
998+
self.assertTrue(myFeatures)
999+
1000+
dest_file_name = os.path.join(str(QDir.tempPath()), 'add_z.geojson')
1001+
options = QgsVectorFileWriter.SaveVectorOptions()
1002+
options.overrideGeometryType = QgsWkbTypes.PointZ
1003+
options.driverName = 'GeoJSON'
1004+
write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
1005+
input,
1006+
dest_file_name,
1007+
options)
1008+
self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message)
1009+
1010+
# Open result and check
1011+
created_layer = QgsVectorLayer(dest_file_name, 'test', 'ogr')
1012+
self.assertTrue(created_layer.isValid())
1013+
f = next(created_layer.getFeatures(QgsFeatureRequest()))
1014+
self.assertEqual(f.geometry().asWkt(), 'PointZ (10 10 0)')
1015+
1016+
def testDropZ(self):
1017+
"""Check dropping z values input."""
1018+
input = QgsVectorLayer(
1019+
'PointZ?crs=epsg:4326&field=name:string(20)',
1020+
'test',
1021+
'memory')
1022+
1023+
self.assertTrue(input.isValid(), 'Provider not initialized')
1024+
1025+
ft = QgsFeature()
1026+
ft.setGeometry(QgsGeometry.fromWkt('PointM(10 10 2)'))
1027+
myResult, myFeatures = input.dataProvider().addFeatures([ft])
1028+
self.assertTrue(myResult)
1029+
self.assertTrue(myFeatures)
1030+
1031+
dest_file_name = os.path.join(str(QDir.tempPath()), 'drop_z.geojson')
1032+
options = QgsVectorFileWriter.SaveVectorOptions()
1033+
options.overrideGeometryType = QgsWkbTypes.PointM
1034+
options.driverName = 'GeoJSON'
1035+
write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
1036+
input,
1037+
dest_file_name,
1038+
options)
1039+
self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message)
1040+
1041+
# Open result and check
1042+
created_layer = QgsVectorLayer(dest_file_name, 'test', 'ogr')
1043+
self.assertTrue(created_layer.isValid())
1044+
f = next(created_layer.getFeatures(QgsFeatureRequest()))
1045+
self.assertEqual(f.geometry().asWkt(), 'Point (10 10)')
1046+
9851047

9861048
if __name__ == '__main__':
9871049
unittest.main()

0 commit comments

Comments
 (0)
Please sign in to comment.