def testMissingTransformsProj6(self): return # TODO -- this seems impossible to determine with existing PROJ6 api # fudge context xml with a missing transform doc = QDomDocument("testdoc") elem = doc.createElement("test") contextElem = doc.createElement("transformContext") transformElem = doc.createElement("srcDest") transformElem.setAttribute("source", 'EPSG:4204') transformElem.setAttribute("dest", 'EPSG:4326') # fake a proj string with a grid which will NEVER exist fake_proj = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +inv +proj=hgridshift +grids=this_is_not_a_real_grid.gsb +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' transformElem.setAttribute("coordinateOp", fake_proj) contextElem.appendChild(transformElem) elem2 = doc.createElement("test2") elem2.appendChild(contextElem) # restore from xml context2 = QgsCoordinateTransformContext() ok, errors = context2.readXml(elem2, QgsReadWriteContext()) self.assertFalse(ok) # check result self.assertEqual(errors, ['not valid'])
def testWriteReadXml(self): # setup a context context = QgsCoordinateTransformContext() source_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204), QgsCoordinateReferenceSystem(4326))[0].sourceTransformId dest_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204), QgsCoordinateReferenceSystem(4326))[0].destinationTransformId source_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205), QgsCoordinateReferenceSystem(4326))[0].sourceTransformId dest_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205), QgsCoordinateReferenceSystem(4326))[0].destinationTransformId self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4204), QgsCoordinateReferenceSystem(4326), source_id_1, dest_id_1)) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4205), QgsCoordinateReferenceSystem(4326), source_id_2, dest_id_2)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:4204', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_1, dest_id_1), ('EPSG:4205', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_2, dest_id_2)}) # save to xml doc = QDomDocument("testdoc") elem = doc.createElement("test") context.writeXml(elem, QgsReadWriteContext()) # restore from xml context2 = QgsCoordinateTransformContext() context2.readXml(elem, QgsReadWriteContext()) # check result self.assertEqual(context2.sourceDestinationDatumTransforms(), {('EPSG:4204', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_1, dest_id_1), ('EPSG:4205', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_2, dest_id_2)})
def testContext(self): """ Various tests to ensure that datum transforms are correctly set respecting context """ context = QgsCoordinateTransformContext() context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), 3, 4) transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28354'), QgsCoordinateReferenceSystem('EPSG:28353'), context) self.assertEqual(list(transform.context().sourceDestinationDatumTransforms().keys()), [('EPSG:28356', 'EPSG:4283')]) # should be no datum transforms self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), -1) # matching source transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:28353'), context) self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), -1) # matching dest transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28354'), QgsCoordinateReferenceSystem('EPSG:4283'), context) self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), -1) # matching src/dest pair transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), context) self.assertEqual(transform.sourceDatumTransformId(), 3) self.assertEqual(transform.destinationDatumTransformId(), 4) # test manual overwriting transform.setSourceDatumTransformId(11) transform.setDestinationDatumTransformId(13) self.assertEqual(transform.sourceDatumTransformId(), 11) self.assertEqual(transform.destinationDatumTransformId(), 13) # test that auto datum setting occurs when updating src/dest crs transform.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:28356')) self.assertEqual(transform.sourceDatumTransformId(), 3) self.assertEqual(transform.destinationDatumTransformId(), 4) transform.setSourceDatumTransformId(11) transform.setDestinationDatumTransformId(13) transform.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4283')) self.assertEqual(transform.sourceDatumTransformId(), 3) self.assertEqual(transform.destinationDatumTransformId(), 4) transform.setSourceDatumTransformId(11) transform.setDestinationDatumTransformId(13) # delayed context set transform = QgsCoordinateTransform() self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), -1) transform.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:28356')) transform.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4283')) self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), -1) transform.setContext(context) self.assertEqual(transform.sourceDatumTransformId(), 3) self.assertEqual(transform.destinationDatumTransformId(), 4) self.assertEqual(list(transform.context().sourceDestinationDatumTransforms().keys()), [('EPSG:28356', 'EPSG:4283')])
def testTransformContextSignalIsEmitted(self): """Test that when a project transform context changes a transformContextChanged signal is emitted""" p = QgsProject() spy = QSignalSpy(p.transformContextChanged) ctx = QgsCoordinateTransformContext() ctx.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857), 1234, 1235) p.setTransformContext(ctx) self.assertEqual(len(spy), 1)
class TestQgsRasterLayerTransformContext(unittest.TestCase): def setUp(self): """Prepare tc""" super(TestQgsRasterLayerTransformContext, self).setUp() self.ctx = QgsCoordinateTransformContext() self.ctx.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857), 1234, 1235) self.rpath = os.path.join(unitTestDataPath(), 'landsat.tif') def testTransformContextIsSetInCtor(self): """Test transform context can be set from ctor""" rl = QgsRasterLayer(self.rpath, 'raster') self.assertFalse(rl.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) options = QgsRasterLayer.LayerOptions(transformContext=self.ctx) rl = QgsRasterLayer(self.rpath, 'raster', 'gdal', options) self.assertTrue(rl.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) def testTransformContextInheritsFromProject(self): """Test that when a layer is added to a project it inherits its context""" rl = QgsRasterLayer(self.rpath, 'raster') self.assertFalse(rl.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p = QgsProject() self.assertFalse(p.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p.setTransformContext(self.ctx) self.assertTrue(p.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p.addMapLayers([rl]) self.assertTrue(rl.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) def testTransformContextIsSyncedFromProject(self): """Test that when a layer is synced when project context changes""" rl = QgsRasterLayer(self.rpath, 'raster') self.assertFalse(rl.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p = QgsProject() self.assertFalse(p.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p.setTransformContext(self.ctx) self.assertTrue(p.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p.addMapLayers([rl]) self.assertTrue(rl.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) # Now change the project context tc2 = QgsCoordinateTransformContext() p.setTransformContext(tc2) self.assertFalse(p.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) self.assertFalse(rl.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p.setTransformContext(self.ctx) self.assertTrue(p.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) self.assertTrue(rl.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857)))
def testCalculateSourceDestProj6(self): context = QgsCoordinateTransformContext() # empty context self.assertEqual(context.calculateCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), '') # add specific source/dest pair - should take precedence context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), 'proj 1') self.assertEqual(context.calculateCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283')), 'proj 1') self.assertEqual(context.calculateCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), '') self.assertEqual(context.calculateCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:3111')), '') # check that reverse transforms are automatically supported self.assertEqual(context.calculateCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:28356')), 'proj 1')
def testCalculateSourceDest(self): context = QgsCoordinateTransformContext() #empty context self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), QgsDatumTransform.TransformPair(-1, -1)) #add specific source/dest pair - should take precedence context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), 3, 4) self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283')), QgsDatumTransform.TransformPair(3, 4)) self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), QgsDatumTransform.TransformPair(-1, -1)) self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:3111')), QgsDatumTransform.TransformPair(-1, -1)) # check that reverse transforms are automatically supported self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:28356')), QgsDatumTransform.TransformPair(4, 3))
def testContextProj6(self): """ Various tests to ensure that datum transforms are correctly set respecting context """ context = QgsCoordinateTransformContext() context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), 'proj') transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28354'), QgsCoordinateReferenceSystem('EPSG:28353'), context) self.assertEqual(list(transform.context().coordinateOperations().keys()), [('EPSG:28356', 'EPSG:4283')]) # should be no coordinate operation self.assertEqual(transform.coordinateOperation(), '') # matching source transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:28353'), context) self.assertEqual(transform.coordinateOperation(), '') # matching dest transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28354'), QgsCoordinateReferenceSystem('EPSG:4283'), context) self.assertEqual(transform.coordinateOperation(), '') # matching src/dest pair transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), context) self.assertEqual(transform.coordinateOperation(), 'proj') # test manual overwriting transform.setCoordinateOperation('proj2') self.assertEqual(transform.coordinateOperation(), 'proj2') # test that auto operation setting occurs when updating src/dest crs transform.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:28356')) self.assertEqual(transform.coordinateOperation(), 'proj') transform.setCoordinateOperation('proj2') transform.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4283')) self.assertEqual(transform.coordinateOperation(), 'proj') transform.setCoordinateOperation('proj2') # delayed context set transform = QgsCoordinateTransform() self.assertEqual(transform.coordinateOperation(), '') transform.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:28356')) transform.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4283')) self.assertEqual(transform.coordinateOperation(), '') transform.setContext(context) self.assertEqual(transform.coordinateOperation(), 'proj') self.assertEqual(list(transform.context().coordinateOperations().keys()), [('EPSG:28356', 'EPSG:4283')])
def testMissingTransforms(self): # fudge context xml with a missing transform doc = QDomDocument("testdoc") elem = doc.createElement("test") contextElem = doc.createElement("transformContext") transformElem = doc.createElement("srcDest") transformElem.setAttribute("source", 'EPSG:4204') transformElem.setAttribute("dest", 'EPSG:4326') transformElem.setAttribute("sourceTransform", 'not valid') transformElem.setAttribute("destTransform", 'not valid 2') contextElem.appendChild(transformElem) elem2 = doc.createElement("test2") elem2.appendChild(contextElem) # restore from xml context2 = QgsCoordinateTransformContext() ok, errors = context2.readXml(elem2, QgsReadWriteContext()) self.assertFalse(ok) # check result self.assertEqual(errors, ['not valid', 'not valid 2'])
def testEqualOperator(self): context1 = QgsCoordinateTransformContext() context2 = QgsCoordinateTransformContext() self.assertTrue(context1 == context2) context1.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'), 1, 2) self.assertFalse(context1 == context2) context2.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'), 1, 2) self.assertTrue(context1 == context2)
def testEqualOperatorProj6(self): context1 = QgsCoordinateTransformContext() context2 = QgsCoordinateTransformContext() self.assertTrue(context1 == context2) context1.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'), 'p1') self.assertFalse(context1 == context2) context2.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'), 'p1') self.assertTrue(context1 == context2)
def testReadWriteSettingsProj6(self): context = QgsCoordinateTransformContext() context.readSettings() proj_1 = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=intl +step +proj=helmert +x=-18.944 +y=-379.364 +z=-24.063 +rx=-0.04 +ry=0.764 +rz=-6.431 +s=3.657 +convention=coordinate_frame +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' proj_2 = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=intl +step +proj=helmert +x=-150 +y=-250 +z=-1 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' # should be empty self.assertEqual(context.coordinateOperations(), {}) self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem(4204), QgsCoordinateReferenceSystem(4326), proj_1)) self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem(4205), QgsCoordinateReferenceSystem(4326), proj_2)) self.assertEqual(context.coordinateOperations(), {('EPSG:4204', 'EPSG:4326'): proj_1, ('EPSG:4205', 'EPSG:4326'): proj_2}) # save to settings context.writeSettings() # restore from settings context2 = QgsCoordinateTransformContext() self.assertEqual(context2.coordinateOperations(), {}) context2.readSettings() # check result self.assertEqual(context2.coordinateOperations(), {('EPSG:4204', 'EPSG:4326'): proj_1, ('EPSG:4205', 'EPSG:4326'): proj_2})
def test_nested_groups(self): """ Test logic relating to nested groups with group layers """ p = QgsProject() layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") p.addMapLayer(layer, False) layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") p.addMapLayer(layer2, False) layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") p.addMapLayer(layer3, False) layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4", "memory") p.addMapLayer(layer4, False) group_node = p.layerTreeRoot().addGroup('my group') group_node.addLayer(layer) group_node.addLayer(layer2) child_group = group_node.addGroup('child') layer3_node = child_group.addLayer(layer3) grandchild_group = child_group.addGroup('grandchild') layer4_node = grandchild_group.addLayer(layer4) self.assertEqual(p.layerTreeRoot().layerOrder(), [layer, layer2, layer3, layer4]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [layer, layer2, layer3, layer4]) spy = QSignalSpy(p.layerTreeRoot().layerOrderChanged) options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext()) group_layer = group_node.convertToGroupLayer(options) p.addMapLayer(group_layer, False) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [layer4, layer3, layer2, layer]) spy_count = len(spy) self.assertEqual(spy_count, 1) grandchild_group_layer = grandchild_group.convertToGroupLayer(options) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [grandchild_group_layer, layer3, layer2, layer]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) layer4_node.setItemVisibilityChecked(False) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [grandchild_group_layer, layer3, layer2, layer]) self.assertEqual(grandchild_group_layer.childLayers(), []) self.assertGreater(len(spy), spy_count) spy_count = len(spy) layer4_node.setItemVisibilityChecked(True) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [grandchild_group_layer, layer3, layer2, layer]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) grandchild_group.setItemVisibilityChecked(False) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [layer3, layer2, layer]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) grandchild_group.setItemVisibilityChecked(True) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [grandchild_group_layer, layer3, layer2, layer]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) child_group_layer = child_group.convertToGroupLayer(options) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) layer4_node.setItemVisibilityChecked(False) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3]) self.assertEqual(grandchild_group_layer.childLayers(), []) self.assertGreater(len(spy), spy_count) spy_count = len(spy) layer4_node.setItemVisibilityChecked(True) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) grandchild_group.setItemVisibilityChecked(False) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [layer3]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) grandchild_group.setItemVisibilityChecked(True) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) layer3_node.setItemVisibilityChecked(False) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) layer3_node.setItemVisibilityChecked(True) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) grandchild_group.setGroupLayer(None) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [layer4, layer3]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) child_group.setGroupLayer(None) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [layer4, layer3, layer2, layer]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) group_node.setGroupLayer(None) self.assertEqual(p.layerTreeRoot().layerOrder(), [layer, layer2, layer3, layer4]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [layer, layer2, layer3, layer4]) self.assertGreater(len(spy), spy_count)
def testSourceDestinationDatumTransformsProj6(self): context = QgsCoordinateTransformContext() self.assertEqual(context.sourceDestinationDatumTransforms(), {}) proj_string = '+proj=pipeline +step +inv +proj=lcc +lat_0=-37 +lon_0=145 +lat_1=-36 +lat_2=-38 +x_0=2500000 +y_0=2500000 +ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' self.assertFalse( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'), proj_string)) self.assertTrue( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertFalse( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4326'))) self.assertFalse( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3113'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string}) proj_string_2 = '+proj=pipeline +step +inv +proj=utm +zone=56 +south +ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem(4283), proj_string_2)) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2}) proj_string_3 = '+proj=pipeline +step +inv +proj=utm +zone=56 +south +ellps=GRS80 +step +proj=utm +zone=57 +south +ellps=GRS80' self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem(28357), proj_string_3)) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): proj_string_3}) self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:28357'), 'some other proj string')) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string'}) # invalid additions self.assertFalse(context.addCoordinateOperation(QgsCoordinateReferenceSystem(), QgsCoordinateReferenceSystem('EPSG:28357'), 'bad proj')) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string'}) self.assertFalse(context.addCoordinateOperation(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem(), 'bad proj')) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string'}) # indicate no transform required self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem(28357), QgsCoordinateReferenceSystem(28356), '')) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string', ('EPSG:28357', 'EPSG:28356'): ''}) # remove non-existing context.removeCoordinateOperation(QgsCoordinateReferenceSystem(3113), QgsCoordinateReferenceSystem(3111)) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string', ('EPSG:28357', 'EPSG:28356'): ''}) # remove existing context.removeCoordinateOperation(QgsCoordinateReferenceSystem(3111), QgsCoordinateReferenceSystem(4283)) self.assertEqual(context.coordinateOperations(), {('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string', ('EPSG:28357', 'EPSG:28356'): ''}) context.removeCoordinateOperation(QgsCoordinateReferenceSystem(28356), QgsCoordinateReferenceSystem(28357)) self.assertEqual(context.coordinateOperations(), {('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28357', 'EPSG:28356'): ''}) context.clear() self.assertEqual(context.coordinateOperations(), {})
def testSourceDestinationDatumTransforms(self): context = QgsCoordinateTransformContext() self.assertEqual(context.sourceDestinationDatumTransforms(), {}) self.assertFalse(context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'), 1, 2)) self.assertTrue( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertFalse( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4326'))) self.assertFalse( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3113'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2)}) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem(4283), 3, 4)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4)}) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem(28357), 7, 8)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(7, 8)}) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:28357'), 9, 11)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11)}) # invalid additions self.assertFalse(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(), QgsCoordinateReferenceSystem('EPSG:28357'), 9, 11)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11)}) self.assertFalse(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem(), 9, 11)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11)}) # indicate no transform required self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(28357), QgsCoordinateReferenceSystem(28356), -1, -1)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1)}) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(3111), QgsCoordinateReferenceSystem(28356), 17, -1)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1), ('EPSG:3111', 'EPSG:28356'): QgsDatumTransform.TransformPair(17, -1)}) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(3113), QgsCoordinateReferenceSystem(28356), -1, 18)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1), ('EPSG:3111', 'EPSG:28356'): QgsDatumTransform.TransformPair(17, -1), ('EPSG:3113', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, 18)}) # remove non-existing context.removeSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(3113), QgsCoordinateReferenceSystem(3111)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1), ('EPSG:3111', 'EPSG:28356'): QgsDatumTransform.TransformPair(17, -1), ('EPSG:3113', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, 18)}) # remove existing context.removeSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(3111), QgsCoordinateReferenceSystem(4283)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1), ('EPSG:3111', 'EPSG:28356'): QgsDatumTransform.TransformPair(17, -1), ('EPSG:3113', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, 18)}) context.removeSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(3111), QgsCoordinateReferenceSystem(28356)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1), ('EPSG:3113', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, 18)}) context.clear() self.assertEqual(context.sourceDestinationDatumTransforms(), {})
def setUp(self): """Prepare tc""" super(TestQgsRasterLayerTransformContext, self).setUp() self.ctx = QgsCoordinateTransformContext() self.ctx.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857), 1234, 1235) self.rpath = os.path.join(unitTestDataPath(), 'landsat.tif')
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) if source is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT)) extent = self.parameterAsExtent(parameters, self.TARGET_AREA, context) target_crs = self.parameterAsCrs(parameters, self.TARGET_AREA_CRS, context) target_geom = QgsGeometry.fromRect(extent) fields = QgsFields() fields.append(QgsField('auth_id', QVariant.String, '', 20)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem()) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) # make intersection tests nice and fast engine = QgsGeometry.createGeometryEngine(target_geom.constGet()) engine.prepareGeometry() layer_bounds = QgsGeometry.fromRect(source.sourceExtent()) crses_to_check = QgsCoordinateReferenceSystem.validSrsIds() total = 100.0 / len(crses_to_check) found_results = 0 transform_context = QgsCoordinateTransformContext() for current, srs_id in enumerate(crses_to_check): if feedback.isCanceled(): break candidate_crs = QgsCoordinateReferenceSystem.fromSrsId(srs_id) if not candidate_crs.isValid(): continue transform_candidate = QgsCoordinateTransform( candidate_crs, target_crs, transform_context) transformed_bounds = QgsGeometry(layer_bounds) try: if not transformed_bounds.transform(transform_candidate) == 0: continue except: continue try: if engine.intersects(transformed_bounds.constGet()): feedback.pushInfo( self.tr('Found candidate CRS: {}').format( candidate_crs.authid())) f = QgsFeature(fields) f.setAttributes([candidate_crs.authid()]) sink.addFeature(f, QgsFeatureSink.FastInsert) found_results += 1 except: continue feedback.setProgress(int(current * total)) if found_results == 0: feedback.reportError(self.tr('No matching projections found')) return {self.OUTPUT: dest_id}
def _test(autoTransaction): """Test buffer methods within and without transactions - create a feature - save - retrieve the feature - change geom and attrs - test changes are seen in the buffer """ def _check_feature(wkt): f = next(layer_a.getFeatures()) self.assertEqual(f.geometry().asWkt().upper(), wkt) f = list(buffer.addedFeatures().values())[0] self.assertEqual(f.geometry().asWkt().upper(), wkt) ml = QgsVectorLayer( 'Point?crs=epsg:4326&field=int:integer&field=int2:integer', 'test', 'memory') self.assertTrue(ml.isValid()) d = QTemporaryDir() options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = 'GPKG' options.layerName = 'layer_a' err, msg, newFileName, newLayer = QgsVectorFileWriter.writeAsVectorFormatV3( ml, os.path.join(d.path(), 'transaction_test.gpkg'), QgsCoordinateTransformContext(), options) self.assertEqual(err, QgsVectorFileWriter.NoError) self.assertTrue(os.path.isfile(newFileName)) layer_a = QgsVectorLayer(newFileName + '|layername=layer_a') self.assertTrue(layer_a.isValid()) project = QgsProject() project.setAutoTransaction(autoTransaction) project.addMapLayers([layer_a]) ########################################### # Tests with a new feature self.assertTrue(layer_a.startEditing()) buffer = layer_a.editBuffer() f = QgsFeature(layer_a.fields()) f.setAttribute('int', 123) f.setGeometry(QgsGeometry.fromWkt('point(7 45)')) self.assertTrue(layer_a.addFeatures([f])) _check_feature('POINT (7 45)') # Need to fetch the feature because its ID is NULL (-9223372036854775808) f = next(layer_a.getFeatures()) self.assertEqual(len(buffer.addedFeatures()), 1) layer_a.undoStack().undo() self.assertEqual(len(buffer.addedFeatures()), 0) layer_a.undoStack().redo() self.assertEqual(len(buffer.addedFeatures()), 1) f = list(buffer.addedFeatures().values())[0] self.assertEqual(f.attribute('int'), 123) # Now change attribute self.assertEqual(buffer.changedAttributeValues(), {}) spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged) layer_a.changeAttributeValue(f.id(), 1, 321) self.assertEqual(len(spy_attribute_changed), 1) self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 321]) self.assertEqual(len(buffer.addedFeatures()), 1) # This is surprising: because it was a new feature it has been changed directly self.assertEqual(buffer.changedAttributeValues(), {}) f = list(buffer.addedFeatures().values())[0] self.assertEqual(f.attribute('int'), 321) spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged) layer_a.undoStack().undo() self.assertEqual(len(spy_attribute_changed), 1) self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 123]) self.assertEqual(buffer.changedAttributeValues(), {}) f = list(buffer.addedFeatures().values())[0] self.assertEqual(f.attribute('int'), 123) f = next(layer_a.getFeatures()) self.assertEqual(f.attribute('int'), 123) # Change multiple attributes spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged) layer_a.changeAttributeValues(f.id(), {1: 321, 2: 456}) self.assertEqual(len(spy_attribute_changed), 2) self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 321]) self.assertEqual(spy_attribute_changed[1], [f.id(), 2, 456]) buffer = layer_a.editBuffer() # This is surprising: because it was a new feature it has been changed directly self.assertEqual(buffer.changedAttributeValues(), {}) spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged) layer_a.undoStack().undo() # This is because QgsVectorLayerUndoCommandChangeAttribute plural if not autoTransaction: layer_a.undoStack().undo() f = next(layer_a.getFeatures()) self.assertEqual(f.attribute('int'), 123) self.assertEqual(f.attribute('int2'), None) self.assertEqual(len(spy_attribute_changed), 2) self.assertEqual( spy_attribute_changed[1 if autoTransaction else 0], [f.id(), 2, None]) self.assertEqual( spy_attribute_changed[0 if autoTransaction else 1], [f.id(), 1, 123]) # Change geometry f = next(layer_a.getFeatures()) spy_geometry_changed = QSignalSpy(layer_a.geometryChanged) self.assertTrue( layer_a.changeGeometry(f.id(), QgsGeometry.fromWkt('point(9 43)'))) self.assertTrue(len(spy_geometry_changed), 1) self.assertEqual(spy_geometry_changed[0][0], f.id()) self.assertEqual(spy_geometry_changed[0][1].asWkt(), QgsGeometry.fromWkt('point(9 43)').asWkt()) _check_feature('POINT (9 43)') self.assertEqual(buffer.changedGeometries(), {}) layer_a.undoStack().undo() _check_feature('POINT (7 45)') self.assertEqual(buffer.changedGeometries(), {}) self.assertTrue( layer_a.changeGeometry(f.id(), QgsGeometry.fromWkt('point(9 43)'))) _check_feature('POINT (9 43)') self.assertTrue( layer_a.changeGeometry(f.id(), QgsGeometry.fromWkt('point(10 44)'))) _check_feature('POINT (10 44)') # This is another surprise: geometry edits get collapsed into a single # one because they have the same hardcoded id layer_a.undoStack().undo() _check_feature('POINT (7 45)') self.assertTrue(layer_a.commitChanges()) ########################################### # Tests with the existing feature # Get the feature f = next(layer_a.getFeatures()) self.assertTrue(f.isValid()) self.assertEqual(f.attribute('int'), 123) self.assertEqual(f.geometry().asWkt().upper(), 'POINT (7 45)') # Change single attribute self.assertTrue(layer_a.startEditing()) spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged) layer_a.changeAttributeValue(f.id(), 1, 321) self.assertEqual(len(spy_attribute_changed), 1) self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 321]) buffer = layer_a.editBuffer() self.assertEqual(buffer.changedAttributeValues(), {1: {1: 321}}) f = next(layer_a.getFeatures()) self.assertEqual(f.attribute(1), 321) spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged) layer_a.undoStack().undo() f = next(layer_a.getFeatures()) self.assertEqual(f.attribute(1), 123) self.assertEqual(len(spy_attribute_changed), 1) self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 123]) self.assertEqual(buffer.changedAttributeValues(), {}) # Change attributes spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged) layer_a.changeAttributeValues(f.id(), {1: 111, 2: 654}) self.assertEqual(len(spy_attribute_changed), 2) self.assertEqual(spy_attribute_changed[0], [1, 1, 111]) self.assertEqual(spy_attribute_changed[1], [1, 2, 654]) f = next(layer_a.getFeatures()) self.assertEqual(f.attributes(), [1, 111, 654]) self.assertEqual(buffer.changedAttributeValues(), {1: { 1: 111, 2: 654 }}) spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged) layer_a.undoStack().undo() # This is because QgsVectorLayerUndoCommandChangeAttribute plural if not autoTransaction: layer_a.undoStack().undo() self.assertEqual(len(spy_attribute_changed), 2) self.assertEqual( spy_attribute_changed[0 if autoTransaction else 1], [1, 1, 123]) self.assertEqual( spy_attribute_changed[1 if autoTransaction else 0], [1, 2, None]) f = next(layer_a.getFeatures()) self.assertEqual(f.attributes(), [1, 123, None]) self.assertEqual(buffer.changedAttributeValues(), {}) # Change geometry spy_geometry_changed = QSignalSpy(layer_a.geometryChanged) self.assertTrue( layer_a.changeGeometry(f.id(), QgsGeometry.fromWkt('point(9 43)'))) self.assertEqual(spy_geometry_changed[0][0], 1) self.assertEqual(spy_geometry_changed[0][1].asWkt(), QgsGeometry.fromWkt('point(9 43)').asWkt()) f = next(layer_a.getFeatures()) self.assertEqual(f.geometry().asWkt().upper(), 'POINT (9 43)') self.assertEqual(buffer.changedGeometries()[1].asWkt().upper(), 'POINT (9 43)') spy_geometry_changed = QSignalSpy(layer_a.geometryChanged) layer_a.undoStack().undo() self.assertEqual(spy_geometry_changed[0][0], 1) self.assertEqual(spy_geometry_changed[0][1].asWkt(), QgsGeometry.fromWkt('point(7 45)').asWkt()) self.assertEqual(buffer.changedGeometries(), {}) f = next(layer_a.getFeatures()) self.assertEqual(f.geometry().asWkt().upper(), 'POINT (7 45)') self.assertEqual(buffer.changedGeometries(), {}) # Delete an existing feature self.assertTrue(layer_a.deleteFeature(f.id())) with self.assertRaises(StopIteration): next(layer_a.getFeatures()) self.assertEqual(buffer.deletedFeatureIds(), [f.id()]) layer_a.undoStack().undo() self.assertTrue(layer_a.getFeature(f.id()).isValid()) self.assertEqual(buffer.deletedFeatureIds(), []) ########################################### # Test delete # Delete a new feature f = QgsFeature(layer_a.fields()) f.setAttribute('int', 555) f.setGeometry(QgsGeometry.fromWkt('point(8 46)')) self.assertTrue(layer_a.addFeatures([f])) f = [ f for f in layer_a.getFeatures() if f.attribute('int') == 555 ][0] self.assertTrue(f.id() in buffer.addedFeatures()) self.assertTrue(layer_a.deleteFeature(f.id())) self.assertFalse(f.id() in buffer.addedFeatures()) self.assertFalse(f.id() in buffer.deletedFeatureIds()) layer_a.undoStack().undo() self.assertTrue(f.id() in buffer.addedFeatures()) ########################################### # Add attribute field = QgsField('attr1', QVariant.String) self.assertTrue(layer_a.addAttribute(field)) self.assertNotEqual(layer_a.fields().lookupField(field.name()), -1) self.assertEqual(buffer.addedAttributes(), [field]) layer_a.undoStack().undo() self.assertEqual(layer_a.fields().lookupField(field.name()), -1) self.assertEqual(buffer.addedAttributes(), []) layer_a.undoStack().redo() self.assertNotEqual(layer_a.fields().lookupField(field.name()), -1) self.assertEqual(buffer.addedAttributes(), [field]) self.assertTrue(layer_a.commitChanges()) ########################################### # Remove attribute self.assertTrue(layer_a.startEditing()) buffer = layer_a.editBuffer() attr_idx = layer_a.fields().lookupField(field.name()) self.assertNotEqual(attr_idx, -1) self.assertTrue(layer_a.deleteAttribute(attr_idx)) self.assertEqual(buffer.deletedAttributeIds(), [attr_idx]) self.assertEqual(layer_a.fields().lookupField(field.name()), -1) layer_a.undoStack().undo() self.assertEqual(buffer.deletedAttributeIds(), []) self.assertEqual(layer_a.fields().lookupField(field.name()), attr_idx) # This is totally broken at least on OGR/GPKG: the rollback # does not restore the original fields if False: layer_a.undoStack().redo() self.assertEqual(buffer.deletedAttributeIds(), [attr_idx]) self.assertEqual(layer_a.fields().lookupField(field.name()), -1) # Rollback! self.assertTrue(layer_a.rollBack()) self.assertIn('attr1', layer_a.dataProvider().fields().names()) self.assertIn('attr1', layer_a.fields().names()) self.assertEqual(layer_a.fields().names(), layer_a.dataProvider().fields().names()) attr_idx = layer_a.fields().lookupField(field.name()) self.assertNotEqual(attr_idx, -1) self.assertTrue(layer_a.startEditing()) attr_idx = layer_a.fields().lookupField(field.name()) self.assertNotEqual(attr_idx, -1) ########################################### # Rename attribute attr_idx = layer_a.fields().lookupField(field.name()) self.assertEqual(layer_a.fields().lookupField('new_name'), -1) self.assertTrue(layer_a.renameAttribute(attr_idx, 'new_name')) self.assertEqual(layer_a.fields().lookupField('new_name'), attr_idx) layer_a.undoStack().undo() self.assertEqual(layer_a.fields().lookupField(field.name()), attr_idx) self.assertEqual(layer_a.fields().lookupField('new_name'), -1) layer_a.undoStack().redo() self.assertEqual(layer_a.fields().lookupField('new_name'), attr_idx) self.assertEqual(layer_a.fields().lookupField(field.name()), -1) ############################################# # Try hard to make this fail for transactions if autoTransaction: self.assertTrue(layer_a.commitChanges()) self.assertTrue(layer_a.startEditing()) f = next(layer_a.getFeatures()) # Do for i in range(10): spy_attribute_changed = QSignalSpy( layer_a.attributeValueChanged) layer_a.changeAttributeValue(f.id(), 2, i) self.assertEqual(len(spy_attribute_changed), 1) self.assertEqual(spy_attribute_changed[0], [f.id(), 2, i]) buffer = layer_a.editBuffer() self.assertEqual(buffer.changedAttributeValues(), {f.id(): { 2: i }}) f = next(layer_a.getFeatures()) self.assertEqual(f.attribute(2), i) # Undo/redo for i in range(9): # Undo spy_attribute_changed = QSignalSpy( layer_a.attributeValueChanged) layer_a.undoStack().undo() f = next(layer_a.getFeatures()) self.assertEqual(f.attribute(2), 8 - i) self.assertEqual(len(spy_attribute_changed), 1) self.assertEqual(spy_attribute_changed[0], [f.id(), 2, 8 - i]) buffer = layer_a.editBuffer() self.assertEqual(buffer.changedAttributeValues(), {f.id(): { 2: 8 - i }}) # Redo spy_attribute_changed = QSignalSpy( layer_a.attributeValueChanged) layer_a.undoStack().redo() f = next(layer_a.getFeatures()) self.assertEqual(f.attribute(2), 9 - i) self.assertEqual(len(spy_attribute_changed), 1) self.assertEqual(spy_attribute_changed[0], [f.id(), 2, 9 - i]) # Undo again spy_attribute_changed = QSignalSpy( layer_a.attributeValueChanged) layer_a.undoStack().undo() f = next(layer_a.getFeatures()) self.assertEqual(f.attribute(2), 8 - i) self.assertEqual(len(spy_attribute_changed), 1) self.assertEqual(spy_attribute_changed[0], [f.id(), 2, 8 - i]) buffer = layer_a.editBuffer() self.assertEqual(buffer.changedAttributeValues(), {f.id(): { 2: 8 - i }}) # Last check f = next(layer_a.getFeatures()) self.assertEqual(f.attribute(2), 8 - i) self.assertEqual(buffer.changedAttributeValues(), {f.id(): { 2: 0 }}) layer_a.undoStack().undo() buffer = layer_a.editBuffer() self.assertEqual(buffer.changedAttributeValues(), {}) f = next(layer_a.getFeatures()) self.assertEqual(f.attribute(2), None)
def get_feature_ids_that_intersect_bbox(layer, rect, crs): request = (QgsFeatureRequest() .setFilterRect(rect) .setDestinationCrs(crs=crs, context=QgsCoordinateTransformContext()) .setNoAttributes().setFlags(QgsFeatureRequest.NoGeometry)) return [f.id() for f in layer.getFeatures(request)]
def testOperations(self): w = QgsCoordinateOperationWidget() self.assertFalse(w.hasSelection()) spy = QSignalSpy(w.operationChanged) w.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:26745')) self.assertEqual(len(spy), 0) w.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(len(spy), 1) self.assertTrue(w.hasSelection()) self.assertGreaterEqual(len(w.availableOperations()), 3) available_operations = QgsDatumTransform.operations( w.sourceCrs(), w.destinationCrs()) for op in available_operations: if op.isAvailable: default_proj = op.proj break else: self.assertTrue(False, 'No operations available') self.assertEqual(w.defaultOperation().proj, default_proj) self.assertEqual(w.selectedOperation().proj, default_proj) self.assertTrue(w.selectedOperation().isAvailable) op = QgsCoordinateOperationWidget.OperationDetails() op.proj = '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84' op.allowFallback = True w.setSelectedOperation(op) self.assertEqual( w.selectedOperation().proj, '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84' ) self.assertTrue(w.selectedOperation().allowFallback) self.assertEqual(len(spy), 2) w.setSelectedOperation(op) self.assertEqual( w.selectedOperation().proj, '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84' ) self.assertTrue(w.selectedOperation().allowFallback) self.assertEqual(len(spy), 2) op.proj = '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84' op.allowFallback = False w.setSelectedOperation(op) self.assertEqual( w.selectedOperation().proj, '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84' ) self.assertFalse(w.selectedOperation().allowFallback) self.assertEqual(len(spy), 3) op.allowFallback = True w.setSelectedOperation(op) self.assertEqual( w.selectedOperation().proj, '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=159 +z=175 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84' ) self.assertTrue(w.selectedOperation().allowFallback) self.assertEqual(len(spy), 4) context = QgsCoordinateTransformContext() op.proj = '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84' w.setSelectedOperation(op) w.setSelectedOperationUsingContext(context) # should go to default, because there's nothing in the context matching these crs self.assertEqual(w.selectedOperation().proj, default_proj) self.assertEqual(len(spy), 6) # put something in the context context.addCoordinateOperation( w.sourceCrs(), w.destinationCrs(), '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84' ) w.setSelectedOperationUsingContext(context) self.assertEqual( w.selectedOperation().proj, '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84' ) self.assertTrue(w.selectedOperation().allowFallback) self.assertEqual(len(spy), 7) context.addCoordinateOperation( w.sourceCrs(), w.destinationCrs(), '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84', False) w.setSelectedOperationUsingContext(context) self.assertEqual( w.selectedOperation().proj, '+proj=pipeline +step +proj=unitconvert +xy_in=us-ft +xy_out=m +step +inv +proj=lcc +lat_0=33.5 +lon_0=-118 +lat_1=35.4666666666667 +lat_2=34.0333333333333 +x_0=609601.219202438 +y_0=0 +ellps=clrk66 +step +proj=push +v_3 +step +proj=cart +ellps=clrk66 +step +proj=helmert +x=-8 +y=160 +z=176 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=webmerc +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84' ) self.assertFalse(w.selectedOperation().allowFallback) self.assertEqual(len(spy), 8)
def testShapefilesWithNoAttributes(self): """Test issue GH #38834""" ml = QgsVectorLayer('Point?crs=epsg:4326', 'test', 'memory') self.assertTrue(ml.isValid()) d = QTemporaryDir() options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = 'ESRI Shapefile' options.layerName = 'writetest' err, _ = QgsVectorFileWriter.writeAsVectorFormatV2(ml, os.path.join(d.path(), 'writetest.shp'), QgsCoordinateTransformContext(), options) self.assertEqual(err, QgsVectorFileWriter.NoError) self.assertTrue(os.path.isfile(os.path.join(d.path(), 'writetest.shp'))) vl = QgsVectorLayer(os.path.join(d.path(), 'writetest.shp')) self.assertTrue(bool(vl.dataProvider().capabilities() & QgsVectorDataProvider.AddFeatures)) # Let's try if we can really add features feature = QgsFeature(vl.fields()) geom = QgsGeometry.fromWkt('POINT(9 45)') feature.setGeometry(geom) self.assertTrue(vl.startEditing()) self.assertTrue(vl.addFeatures([feature])) self.assertTrue(vl.commitChanges()) del (vl) vl = QgsVectorLayer(os.path.join(d.path(), 'writetest.shp')) self.assertEqual(vl.featureCount(), 1)
def testReadWriteSettingsProj6(self): context = QgsCoordinateTransformContext() context.readSettings() proj_1 = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=intl +step +proj=helmert +x=-18.944 +y=-379.364 +z=-24.063 +rx=-0.04 +ry=0.764 +rz=-6.431 +s=3.657 +convention=coordinate_frame +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' proj_2 = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=intl +step +proj=helmert +x=-150 +y=-250 +z=-1 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' # should be empty self.assertEqual(context.coordinateOperations(), {}) self.assertTrue( context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4204'), QgsCoordinateReferenceSystem('EPSG:4326'), proj_1, True)) self.assertTrue( context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4205'), QgsCoordinateReferenceSystem('EPSG:4326'), proj_2, False)) self.assertEqual(context.coordinateOperations(), { ('EPSG:4204', 'EPSG:4326'): proj_1, ('EPSG:4205', 'EPSG:4326'): proj_2 }) self.assertTrue( context.allowFallbackTransform( QgsCoordinateReferenceSystem('EPSG:4204'), QgsCoordinateReferenceSystem('EPSG:4326'))) self.assertFalse( context.allowFallbackTransform( QgsCoordinateReferenceSystem('EPSG:4205'), QgsCoordinateReferenceSystem('EPSG:4326'))) # save to settings context.writeSettings() # restore from settings context2 = QgsCoordinateTransformContext() self.assertEqual(context2.coordinateOperations(), {}) context2.readSettings() # check result self.assertEqual(context2.coordinateOperations(), { ('EPSG:4204', 'EPSG:4326'): proj_1, ('EPSG:4205', 'EPSG:4326'): proj_2 }) self.assertTrue( context2.allowFallbackTransform( QgsCoordinateReferenceSystem('EPSG:4204'), QgsCoordinateReferenceSystem('EPSG:4326'))) self.assertFalse( context2.allowFallbackTransform( QgsCoordinateReferenceSystem('EPSG:4205'), QgsCoordinateReferenceSystem('EPSG:4326')))
def testSourceDestinationDatumTransformsProj6(self): context = QgsCoordinateTransformContext() self.assertEqual(context.coordinateOperations(), {}) proj_string = '+proj=pipeline +step +inv +proj=lcc +lat_0=-37 +lon_0=145 +lat_1=-36 +lat_2=-38 +x_0=2500000 +y_0=2500000 +ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' self.assertFalse( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertFalse( context.mustReverseCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertFalse( context.mustReverseCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111'))) self.assertTrue( context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'), proj_string)) self.assertTrue( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertFalse( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4326'))) self.assertFalse( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3113'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertEqual(context.coordinateOperations(), {('EPSG:3111', 'EPSG:4283'): proj_string}) self.assertTrue( context.mustReverseCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111'))) self.assertTrue( context.allowFallbackTransform( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertTrue( context.allowFallbackTransform( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111'))) self.assertTrue( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111'))) self.assertEqual( context.calculateCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), proj_string) self.assertFalse( context.mustReverseCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'))) # ideally not equal, but for now it's all we can do, and return True for mustReverseCoordinateOperation here self.assertEqual( context.calculateCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111')), proj_string) self.assertTrue( context.mustReverseCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111'))) self.assertTrue( context.allowFallbackTransform( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111'))) proj_string_2 = 'dummy' self.assertTrue( context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111'), proj_string_2, False)) self.assertEqual( context.calculateCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111')), proj_string_2) self.assertFalse( context.mustReverseCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111'))) context.removeCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111')) self.assertTrue( context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3113'), proj_string_2, False)) self.assertFalse( context.allowFallbackTransform( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3113'))) self.assertFalse( context.allowFallbackTransform( QgsCoordinateReferenceSystem('EPSG:3113'), QgsCoordinateReferenceSystem('EPSG:4283'))) context.removeCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3113')) proj_string_2 = '+proj=pipeline +step +inv +proj=utm +zone=56 +south +ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' self.assertTrue( context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), proj_string_2)) self.assertEqual( context.coordinateOperations(), { ('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2 }) proj_string_3 = '+proj=pipeline +step +inv +proj=utm +zone=56 +south +ellps=GRS80 +step +proj=utm +zone=57 +south +ellps=GRS80' self.assertTrue( context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:28357'), proj_string_3)) self.assertEqual( context.coordinateOperations(), { ('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): proj_string_3 }) self.assertTrue( context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:28357'), 'some other proj string')) self.assertEqual( context.coordinateOperations(), { ('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string' }) # invalid additions self.assertFalse( context.addCoordinateOperation( QgsCoordinateReferenceSystem(), QgsCoordinateReferenceSystem('EPSG:28357'), 'bad proj')) self.assertEqual( context.coordinateOperations(), { ('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string' }) self.assertFalse( context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem(), 'bad proj')) self.assertEqual( context.coordinateOperations(), { ('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string' }) # indicate no transform required self.assertTrue( context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:28357'), QgsCoordinateReferenceSystem('EPSG:28356'), '')) self.assertEqual( context.coordinateOperations(), { ('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string', ('EPSG:28357', 'EPSG:28356'): '' }) # remove non-existing context.removeCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:3113'), QgsCoordinateReferenceSystem('EPSG:3111')) self.assertEqual( context.coordinateOperations(), { ('EPSG:3111', 'EPSG:4283'): proj_string, ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string', ('EPSG:28357', 'EPSG:28356'): '' }) # remove existing context.removeCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')) self.assertEqual( context.coordinateOperations(), { ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28356', 'EPSG:28357'): 'some other proj string', ('EPSG:28357', 'EPSG:28356'): '' }) context.removeCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:28357')) self.assertEqual( context.coordinateOperations(), { ('EPSG:28356', 'EPSG:4283'): proj_string_2, ('EPSG:28357', 'EPSG:28356'): '' }) context.clear() self.assertEqual(context.coordinateOperations(), {})
def testWriteReadXmlProj6(self): # setup a context context = QgsCoordinateTransformContext() proj_1 = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=intl +step +proj=helmert +x=-18.944 +y=-379.364 +z=-24.063 +rx=-0.04 +ry=0.764 +rz=-6.431 +s=3.657 +convention=coordinate_frame +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' proj_2 = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=intl +step +proj=helmert +x=-150 +y=-250 +z=-1 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' proj_3 = '+proj=pipeline +step +proj=axisswap +order=2,1' self.assertTrue( context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4204'), QgsCoordinateReferenceSystem('EPSG:4326'), proj_1, True)) self.assertTrue( context.addCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4205'), QgsCoordinateReferenceSystem('EPSG:4326'), proj_2, False)) # also insert a crs with no authid available self.assertTrue( context.addCoordinateOperation( QgsCoordinateReferenceSystem.fromProj( "+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs" ), QgsCoordinateReferenceSystem('EPSG:4326'), proj_3, False)) self.assertEqual( context.coordinateOperations(), { ('EPSG:4204', 'EPSG:4326'): proj_1, ('EPSG:4205', 'EPSG:4326'): proj_2, ('', 'EPSG:4326'): proj_3 }) # save to xml doc = QDomDocument("testdoc") elem = doc.createElement("test") context.writeXml(elem, QgsReadWriteContext()) # restore from xml context2 = QgsCoordinateTransformContext() context2.readXml(elem, QgsReadWriteContext()) # check result self.assertEqual( context2.coordinateOperations(), { ('EPSG:4204', 'EPSG:4326'): proj_1, ('EPSG:4205', 'EPSG:4326'): proj_2, ('', 'EPSG:4326'): proj_3 }) self.assertEqual( context2.calculateCoordinateOperation( QgsCoordinateReferenceSystem.fromProj( "+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs" ), QgsCoordinateReferenceSystem('EPSG:4326')), '+proj=pipeline +step +proj=axisswap +order=2,1') self.assertFalse( context2.mustReverseCoordinateOperation( QgsCoordinateReferenceSystem.fromProj( "+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs" ), QgsCoordinateReferenceSystem('EPSG:4326'))) self.assertEqual( context2.calculateCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4326'), QgsCoordinateReferenceSystem.fromProj( "+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs") ), '+proj=pipeline +step +proj=axisswap +order=2,1') self.assertTrue( context2.mustReverseCoordinateOperation( QgsCoordinateReferenceSystem('EPSG:4326'), QgsCoordinateReferenceSystem.fromProj( "+proj=longlat +a=6378137 +rf=298.25722356300003 +no_defs") )) self.assertTrue( context2.allowFallbackTransform( QgsCoordinateReferenceSystem('EPSG:4204'), QgsCoordinateReferenceSystem('EPSG:4326'))) self.assertFalse( context2.allowFallbackTransform( QgsCoordinateReferenceSystem('EPSG:4205'), QgsCoordinateReferenceSystem('EPSG:4326')))
def create_shapefile_full_layer_data_provider(path, name, srid, attributes, types, values, coords): """ Creates a shapefile using the Shapefile Data Provider Parameters ---------- path : `str` folder where the shapefile is to be saved name : `str` name of the shapefile srid : `str` CRS of the newly created shapefile attributes: array_like list of attribute (field) names types : array_like list of types (field) types, in sync with the `attributes` parameter values : array_like coordinates and attribute data, one array for each feature (F, C + A), F for features, C for coordinates and A for attribute data coords : array_like indices of the coordinate values within the `values` array Returns ------- vl : `QgsVectorLayer` the newly-created layer """ # create new layer with given attributes filename = path + "/" + name + ".shp" # create an instance of vector file writer, which will create the vector file. writer = None options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = "ESRI Shapefile" options.fileEncoding = 'utf-8' if len(coords) == 2: type = 'point' writer = QgsVectorFileWriter.create(filename, QgsFields(), QgsWkbTypes.Point, srid, QgsCoordinateTransformContext(), options) elif len(coords) == 4: type = 'line' writer = QgsVectorFileWriter.create(filename, QgsFields(), QgsWkbTypes.LineString, srid, QgsCoordinateTransformContext(), options) if writer.hasError() != QgsVectorFileWriter.NoError: print("Error when creating shapefile: ", writer.hasError()) return None del writer # open the newly created file vl = QgsVectorLayer(filename, name, "ogr") pr = vl.dataProvider() # create the required fields for i, attr in enumerate(attributes): pr.addAttributes([QgsField(attr, types[i])]) vl.commitChanges() # add features by iterating the values feat = QgsFeature() for i, val in enumerate(values): # add geometry try: if type == 'point': geometry = QgsGeometry.fromPoint([QgsPoint(float(val[coords[0]]), float(val[coords[1]]))]) elif type == 'line': geometry = QgsGeometry.fromPolyline([QgsPoint(float(val[coords[0]]), float(val[coords[1]])), QgsPoint(float(val[coords[2]]), float(val[coords[3]]))]) feat.setGeometry(geometry) except: pass # add attributes attrs = [] for j, attr in enumerate(attributes): attrs.append(val[j]) feat.setAttributes(attrs) pr.addFeature(feat) vl.updateExtents() vl = QgsVectorLayer(filename, name, "ogr") if not vl.isValid(): raise IOError("Layer could not be created") return None return vl
def search(self): plots_found = [] features_not_found = [] fields = PLOTS_LAYER_DEFAULT_FIELDS + self.additional_output_fields self.layer_found.startEditing() self.layer_found.dataProvider().addAttributes(fields) self.layer_not_found.startEditing() self.layer_not_found.dataProvider().addAttributes([ QgsField("tresc_bledu", QVariant.String), ]) features = [] features_iterator = self.source_layer.getSelectedFeatures( ) if self.selected_only else self.source_layer.getFeatures() source_crs = self.source_layer.sourceCrs() if source_crs != CRS_2180: transformation = (QgsCoordinateTransform( source_crs, CRS_2180, QgsCoordinateTransformContext())) for f in features_iterator: point = f.geometry().asPoint() point = transformation.transform(point) f.setGeometry(QgsGeometry.fromPointXY(point)) features.append(f) else: transformation = None features = features_iterator uldk_search = ULDKSearchPoint("dzialka", ("geom_wkt", "wojewodztwo", "powiat", "gmina", "obreb", "numer", "teryt")) uldk_search = ULDKSearchLogger(uldk_search) found_features = [] geometries = [] for source_feature in features: if QThread.currentThread().isInterruptionRequested(): self.__commit() self.interrupted.emit(self.layer_found, self.layer_not_found) return point = source_feature.geometry().asPoint() uldk_point = ULDKPoint(point.x(), point.y(), 2180) try: uldk_response_row = uldk_search.search(uldk_point) additional_attributes = [] for field in self.additional_output_fields: additional_attributes.append(source_feature[field.name()]) try: found_feature = uldk_response_to_qgs_feature( uldk_response_row, additional_attributes) geometry_wkt = found_feature.geometry().asWkt() except BadGeometryException: raise BadGeometryException("Niepoprawna geometria") saved = False if geometry_wkt not in geometries: saved = True found_features.append(found_feature) self.layer_found.dataProvider().addFeature(found_feature) geometries.append(geometry_wkt) self.progressed.emit(True, 0, saved) except Exception as e: not_found_feature = self.__make_not_found_feature( source_feature.geometry(), e) self.layer_not_found.dataProvider().addFeature( not_found_feature) self.progressed.emit(False, 0, False) self.__commit() self.finished.emit(self.layer_found, self.layer_not_found)
class TestQgsRasterLayerTransformContext(unittest.TestCase): def setUp(self): """Prepare tc""" super(TestQgsRasterLayerTransformContext, self).setUp() self.ctx = QgsCoordinateTransformContext() self.ctx.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857), 1234, 1235) self.rpath = os.path.join(unitTestDataPath(), 'landsat.tif') def testTransformContextIsSetInCtor(self): """Test transform context can be set from ctor""" rl = QgsRasterLayer(self.rpath, 'raster') self.assertFalse(rl.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) options = QgsRasterLayer.LayerOptions(transformContext=self.ctx) rl = QgsRasterLayer(self.rpath, 'raster', 'gdal', options) self.assertTrue(rl.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) def testTransformContextInheritsFromProject(self): """Test that when a layer is added to a project it inherits its context""" rl = QgsRasterLayer(self.rpath, 'raster') self.assertFalse(rl.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p = QgsProject() self.assertFalse(p.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p.setTransformContext(self.ctx) self.assertTrue(p.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p.addMapLayers([rl]) self.assertTrue(rl.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) def testTransformContextIsSyncedFromProject(self): """Test that when a layer is synced when project context changes""" rl = QgsRasterLayer(self.rpath, 'raster') self.assertFalse(rl.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p = QgsProject() self.assertFalse(p.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p.setTransformContext(self.ctx) self.assertTrue(p.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p.addMapLayers([rl]) self.assertTrue(rl.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) # Now change the project context tc2 = QgsCoordinateTransformContext() p.setTransformContext(tc2) self.assertFalse(p.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) self.assertFalse(rl.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) p.setTransformContext(self.ctx) self.assertTrue(p.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) self.assertTrue(rl.transformContext().hasTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857)))
def testSourceDestinationDatumTransforms(self): context = QgsCoordinateTransformContext() self.assertEqual(context.sourceDestinationDatumTransforms(), {}) self.assertFalse( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'), 1, 2)) self.assertTrue( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertFalse( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4326'))) self.assertFalse( context.hasTransform(QgsCoordinateReferenceSystem('EPSG:3113'), QgsCoordinateReferenceSystem('EPSG:4283'))) self.assertEqual(context.sourceDestinationDatumTransforms(), { ('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2) }) self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem(4283), 3, 4)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair( 1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair( 3, 4) }) self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem(28357), 7, 8)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair( 1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair( 3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair( 7, 8) }) self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:28357'), 9, 11)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11) }) # invalid additions self.assertFalse( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem(), QgsCoordinateReferenceSystem('EPSG:28357'), 9, 11)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11) }) self.assertFalse( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem(), 9, 11)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11) }) # indicate no transform required self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem(28357), QgsCoordinateReferenceSystem(28356), -1, -1)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1) }) self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem(3111), QgsCoordinateReferenceSystem(28356), 17, -1)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1), ('EPSG:3111', 'EPSG:28356'): QgsDatumTransform.TransformPair(17, -1) }) self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem(3113), QgsCoordinateReferenceSystem(28356), -1, 18)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1), ('EPSG:3111', 'EPSG:28356'): QgsDatumTransform.TransformPair(17, -1), ('EPSG:3113', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, 18) }) # remove non-existing context.removeSourceDestinationDatumTransform( QgsCoordinateReferenceSystem(3113), QgsCoordinateReferenceSystem(3111)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:3111', 'EPSG:4283'): QgsDatumTransform.TransformPair(1, 2), ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1), ('EPSG:3111', 'EPSG:28356'): QgsDatumTransform.TransformPair(17, -1), ('EPSG:3113', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, 18) }) # remove existing context.removeSourceDestinationDatumTransform( QgsCoordinateReferenceSystem(3111), QgsCoordinateReferenceSystem(4283)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1), ('EPSG:3111', 'EPSG:28356'): QgsDatumTransform.TransformPair(17, -1), ('EPSG:3113', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, 18) }) context.removeSourceDestinationDatumTransform( QgsCoordinateReferenceSystem(3111), QgsCoordinateReferenceSystem(28356)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:28356', 'EPSG:4283'): QgsDatumTransform.TransformPair(3, 4), ('EPSG:28356', 'EPSG:28357'): QgsDatumTransform.TransformPair(9, 11), ('EPSG:28357', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, -1), ('EPSG:3113', 'EPSG:28356'): QgsDatumTransform.TransformPair(-1, 18) }) context.clear() self.assertEqual(context.sourceDestinationDatumTransforms(), {})
def convert_to_gpkg(self, target_path): """ Convert a layer to geopackage in the target path and adjust its datasource. If a layer is already a geopackage, the dataset will merely be copied to the target path. :param layer: The layer to copy :param target_path: A path to a folder into which the data will be copied :param keep_existent: if True and target file already exists, keep it as it is """ if not self.layer.type( ) == QgsMapLayer.VectorLayer or not self.layer.isValid(): return file_path = self.filename suffix = "" uri_parts = self.layer.source().split("|", 1) if len(uri_parts) > 1: suffix = uri_parts[1] dest_file = "" new_source = "" # check if the source is a geopackage, and merely copy if it's the case if (os.path.isfile(file_path) and self.layer.dataProvider().storageType() == "GPKG"): source_path, file_name = os.path.split(file_path) dest_file = os.path.join(target_path, file_name) if not os.path.isfile(dest_file): shutil.copy(os.path.join(source_path, file_name), dest_file) if self.provider_metadata is not None: metadata = self.metadata metadata["path"] = dest_file new_source = self.provider_metadata.encodeUri(metadata) if new_source == "": new_source = os.path.join(target_path, file_name) if suffix != "": new_source = "{}|{}".format(new_source, suffix) layer_subset_string = self.layer.subsetString() if new_source == "": pattern = re.compile("[\W_]+") # NOQA cleaned_name = pattern.sub("", self.layer.name()) dest_file = os.path.join(target_path, "{}.gpkg".format(cleaned_name)) suffix = 0 while os.path.isfile(dest_file): suffix += 1 dest_file = os.path.join( target_path, "{}_{}.gpkg".format(cleaned_name, suffix)) # clone vector layer and strip it of filter, joins, and virtual fields source_layer = self.layer.clone() source_layer.setSubsetString("") source_layer_joins = source_layer.vectorJoins() for join in source_layer_joins: source_layer.removeJoin(join.joinLayerId()) fields = source_layer.fields() virtual_field_count = 0 for i in range(0, len(fields)): if fields.fieldOrigin(i) == QgsFields.OriginExpression: source_layer.removeExpressionField(i - virtual_field_count) virtual_field_count += 1 options = QgsVectorFileWriter.SaveVectorOptions() options.fileEncoding = "UTF-8" options.driverName = "GPKG" (error, returned_dest_file) = QgsVectorFileWriter.writeAsVectorFormatV2( source_layer, dest_file, QgsCoordinateTransformContext(), options) if error != QgsVectorFileWriter.NoError: return if returned_dest_file: new_source = returned_dest_file else: new_source = dest_file self._change_data_source(new_source, "ogr") if layer_subset_string: self.layer.setSubsetString(layer_subset_string) return dest_file
def testCalculate(self): context = QgsCoordinateTransformContext() #empty context self.assertEqual( context.calculateDatumTransforms( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), (-1, -1)) #add src transform context.addSourceDatumTransform( QgsCoordinateReferenceSystem('EPSG:28356'), 1) self.assertEqual( context.calculateDatumTransforms( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), (-1, -1)) self.assertEqual( context.calculateDatumTransforms( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283')), (1, -1)) self.assertEqual( context.calculateDatumTransforms( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:28356')), (-1, -1)) #add dest transform context.addDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:4283'), 2) self.assertEqual( context.calculateDatumTransforms( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4326')), (-1, -1)) self.assertEqual( context.calculateDatumTransforms( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), (-1, 2)) self.assertEqual( context.calculateDatumTransforms( QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111')), (-1, -1)) #add specific source/dest pair - should take precedence context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), 3, 4) self.assertEqual( context.calculateDatumTransforms( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283')), (3, 4)) self.assertEqual( context.calculateDatumTransforms( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), (-1, 2)) self.assertEqual( context.calculateDatumTransforms( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:3111')), (1, -1))
def testContextSingle(self): """ Various tests to ensure that datum transforms are correctly set respecting context """ context = QgsCoordinateTransformContext() context.addSourceDatumTransform( QgsCoordinateReferenceSystem('EPSG:28356'), 1) context.addDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:4283'), 2) context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), 3, 4) transform = QgsCoordinateTransform( QgsCoordinateReferenceSystem('EPSG:28354'), QgsCoordinateReferenceSystem('EPSG:28353'), context) # should be no datum transforms self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), -1) # matching source transform = QgsCoordinateTransform( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:28353'), context) self.assertEqual(transform.sourceDatumTransformId(), 1) self.assertEqual(transform.destinationDatumTransformId(), -1) # matching dest transform = QgsCoordinateTransform( QgsCoordinateReferenceSystem('EPSG:28354'), QgsCoordinateReferenceSystem('EPSG:4283'), context) self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), 2) # matching src/dest pair transform = QgsCoordinateTransform( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), context) self.assertEqual(transform.sourceDatumTransformId(), 3) self.assertEqual(transform.destinationDatumTransformId(), 4) # test manual overwriting transform.setSourceDatumTransform(11) transform.setDestinationDatumTransform(13) self.assertEqual(transform.sourceDatumTransformId(), 11) self.assertEqual(transform.destinationDatumTransformId(), 13) # test that auto datum setting occurs when updating src/dest crs transform.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:28356')) self.assertEqual(transform.sourceDatumTransformId(), 3) self.assertEqual(transform.destinationDatumTransformId(), 4) transform.setSourceDatumTransform(11) transform.setDestinationDatumTransform(13) transform.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4283')) self.assertEqual(transform.sourceDatumTransformId(), 3) self.assertEqual(transform.destinationDatumTransformId(), 4) transform.setSourceDatumTransform(11) transform.setDestinationDatumTransform(13) # delayed context set transform = QgsCoordinateTransform() self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), -1) transform.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:28356')) transform.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4283')) self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), -1) transform.setContext(context) self.assertEqual(transform.sourceDatumTransformId(), 3) self.assertEqual(transform.destinationDatumTransformId(), 4)
def testReadWriteSettings(self): context = QgsCoordinateTransformContext() context.readSettings() source_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204), QgsCoordinateReferenceSystem(4326))[0].sourceTransformId dest_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204), QgsCoordinateReferenceSystem(4326))[0].destinationTransformId source_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205), QgsCoordinateReferenceSystem(4326))[0].sourceTransformId dest_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205), QgsCoordinateReferenceSystem(4326))[0].destinationTransformId # should be empty self.assertEqual(context.sourceDestinationDatumTransforms(), {}) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:4204'), QgsCoordinateReferenceSystem('EPSG:4326'), source_id_1, dest_id_1)) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:4205'), QgsCoordinateReferenceSystem(4326), source_id_2, dest_id_2)) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:4204', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_1, dest_id_1), ('EPSG:4205', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_2, dest_id_2)}) # save to settings context.writeSettings() # restore from settings context2 = QgsCoordinateTransformContext() self.assertEqual(context2.sourceDestinationDatumTransforms(), {}) context2.readSettings() # check result self.assertEqual(context2.sourceDestinationDatumTransforms(), {('EPSG:4204', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_1, dest_id_1), ('EPSG:4205', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_2, dest_id_2)})
def testWriteReadXmlProj6(self): # setup a context context = QgsCoordinateTransformContext() proj_1 = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=intl +step +proj=helmert +x=-18.944 +y=-379.364 +z=-24.063 +rx=-0.04 +ry=0.764 +rz=-6.431 +s=3.657 +convention=coordinate_frame +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' proj_2 = '+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step +proj=cart +ellps=intl +step +proj=helmert +x=-150 +y=-250 +z=-1 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1' self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem(4204), QgsCoordinateReferenceSystem(4326), proj_1)) self.assertTrue(context.addCoordinateOperation(QgsCoordinateReferenceSystem(4205), QgsCoordinateReferenceSystem(4326), proj_2)) self.assertEqual(context.coordinateOperations(), {('EPSG:4204', 'EPSG:4326'): proj_1, ('EPSG:4205', 'EPSG:4326'): proj_2}) # save to xml doc = QDomDocument("testdoc") elem = doc.createElement("test") context.writeXml(elem, QgsReadWriteContext()) # restore from xml context2 = QgsCoordinateTransformContext() context2.readXml(elem, QgsReadWriteContext()) # check result self.assertEqual(context2.coordinateOperations(), {('EPSG:4204', 'EPSG:4326'): proj_1, ('EPSG:4205', 'EPSG:4326'): proj_2})
def testDestDatumTransforms(self): context = QgsCoordinateTransformContext() self.assertEqual(context.destinationDatumTransforms(), {}) self.assertTrue(context.addDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:3111'), 1)) self.assertEqual(context.destinationDatumTransforms(), {'EPSG:3111': 1}) self.assertTrue(context.addDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), 2)) self.assertEqual(context.destinationDatumTransforms(), {'EPSG:3111': 1, 'EPSG:28356': 2}) self.assertTrue(context.addDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), 3)) self.assertEqual(context.destinationDatumTransforms(), {'EPSG:3111': 1, 'EPSG:28356': 3}) self.assertTrue(context.addDestinationDatumTransform(QgsCoordinateReferenceSystem(28356), 3)) self.assertEqual(context.destinationDatumTransforms(), {'EPSG:3111': 1, 'EPSG:28356': 3}) # invalid crs should fail self.assertFalse(context.addDestinationDatumTransform(QgsCoordinateReferenceSystem(), 4)) self.assertEqual(context.destinationDatumTransforms(), {'EPSG:3111': 1, 'EPSG:28356': 3}) # indicate no transform required self.assertTrue(context.addDestinationDatumTransform(QgsCoordinateReferenceSystem(28357), -1)) self.assertEqual(context.destinationDatumTransforms(), {'EPSG:3111': 1, 'EPSG:28356': 3, 'EPSG:28357': -1}) # removing non-existing context.removeSourceDatumTransform(QgsCoordinateReferenceSystem(28354)) self.assertEqual(context.destinationDatumTransforms(), {'EPSG:3111': 1, 'EPSG:28356': 3, 'EPSG:28357': -1}) # remove existing context.removeDestinationDatumTransform(QgsCoordinateReferenceSystem(28356)) self.assertEqual(context.destinationDatumTransforms(), {'EPSG:3111': 1, 'EPSG:28357': -1}) context.clear() self.assertEqual(context.destinationDatumTransforms(), {})
def testCalculate(self): context = QgsCoordinateTransformContext() #empty context self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), (-1, -1)) #add src transform context.addSourceDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), 1) self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), (-1, -1)) self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283')), (1, -1)) self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:28356')), (-1, -1)) #add dest transform context.addDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:4283'), 2) self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4326')), (-1, -1)) self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), (-1, 2)) self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:4283'), QgsCoordinateReferenceSystem('EPSG:3111')), (-1, -1)) #add specific source/dest pair - should take precedence context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), 3, 4) self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283')), (3, 4)) self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283')), (-1, 2)) self.assertEqual(context.calculateDatumTransforms(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:3111')), (1, -1))
def test_insert_srsName(self): """Test srsName is respected when insering""" post_data = """ <Transaction xmlns="http://www.opengis.net/wfs" xsi:schemaLocation="http://www.qgis.org/gml http://localhost:8000/?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=as_symbols" service="WFS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="{version}" xmlns:gml="http://www.opengis.net/gml"> <Insert xmlns="http://www.opengis.net/wfs"> <as_symbols xmlns="http://www.qgis.org/gml"> <name xmlns="http://www.qgis.org/gml">{name}</name> <geometry xmlns="http://www.qgis.org/gml"> <gml:Point srsName="{srsName}"> <gml:coordinates cs="," ts=" ">{coordinates}</gml:coordinates> </gml:Point> </geometry> </as_symbols> </Insert> </Transaction> """ project = self.testdata_path + \ "test_project_wms_grouped_layers.qgs" assert os.path.exists(project), "Project file not found: " + project query_string = '?SERVICE=WFS&MAP={}'.format( urllib.parse.quote(project)) request = post_data.format(name='4326-test1', version='1.1.0', srsName='EPSG:4326', coordinates='10.67,52.48') header, body = self._execute_request( query_string, requestMethod=QgsServerRequest.PostMethod, data=request.encode('utf-8')) # Verify vl = QgsVectorLayer( self.testdata_path + 'test_project_wms_grouped_layers.gpkg|layername=as_symbols', 'as_symbols') self.assertTrue(vl.isValid()) feature = next( vl.getFeatures( QgsFeatureRequest(QgsExpression('"name" = \'4326-test1\'')))) geom = feature.geometry() tr = QgsCoordinateTransform( QgsCoordinateReferenceSystem.fromEpsgId(4326), vl.crs(), QgsCoordinateTransformContext()) geom_4326 = QgsGeometry.fromWkt('point( 10.67 52.48)') geom_4326.transform(tr) self.assertEqual(geom.asWkt(0), geom_4326.asWkt(0)) # Now: insert a feature in layer's CRS request = post_data.format(name='25832-test1', version='1.1.0', srsName='EPSG:25832', coordinates='613412,5815738') header, body = self._execute_request( query_string, requestMethod=QgsServerRequest.PostMethod, data=request.encode('utf-8')) feature = next( vl.getFeatures( QgsFeatureRequest(QgsExpression('"name" = \'25832-test1\'')))) geom = feature.geometry() self.assertEqual(geom.asWkt(0), geom_4326.asWkt(0)) # Tests for inverted axis issue GH #36584 # Cleanup self.assertTrue(vl.startEditing()) vl.selectByExpression('"name" LIKE \'4326-test%\'') vl.deleteSelectedFeatures() self.assertTrue(vl.commitChanges()) self.i = 0 def _test(version, srsName, lat_lon=False): self.i += 1 name = '4326-test_%s' % self.i request = post_data.format( name=name, version=version, srsName=srsName, coordinates='52.48,10.67' if lat_lon else '10.67,52.48') header, body = self._execute_request( query_string, requestMethod=QgsServerRequest.PostMethod, data=request.encode('utf-8')) feature = next( vl.getFeatures( QgsFeatureRequest(QgsExpression('"name" = \'%s\'' % name)))) geom = feature.geometry() self.assertEqual( geom.asWkt(0), geom_4326.asWkt(0), "Transaction Failed: %s , %s, lat_lon=%s" % (version, srsName, lat_lon)) _test('1.1.0', 'urn:ogc:def:crs:EPSG::4326', lat_lon=True) _test('1.1.0', 'http://www.opengis.net/def/crs/EPSG/0/4326', lat_lon=True) _test('1.1.0', 'http://www.opengis.net/gml/srs/epsg.xml#4326', lat_lon=False) _test('1.1.0', 'EPSG:4326', lat_lon=False) _test('1.0.0', 'urn:ogc:def:crs:EPSG::4326', lat_lon=True) _test('1.0.0', 'http://www.opengis.net/def/crs/EPSG/0/4326', lat_lon=True) _test('1.0.0', 'http://www.opengis.net/gml/srs/epsg.xml#4326', lat_lon=False) _test('1.0.0', 'EPSG:4326', lat_lon=False) def _test_getFeature(version, srsName, lat_lon=False): # Now get the feature through WFS using BBOX filter bbox = QgsGeometry.fromWkt('point( 10.7006 52.4317)').boundingBox() bbox.grow(0.0001) bbox_text = "%s,%s,%s,%s" % ( (bbox.yMinimum(), bbox.xMinimum(), bbox.yMaximum(), bbox.xMaximum()) if lat_lon else (bbox.xMinimum(), bbox.yMinimum(), bbox.xMaximum(), bbox.yMaximum())) req = query_string + '&REQUEST=GetFeature&VERSION={version}&TYPENAME=as_symbols&SRSNAME={srsName}&BBOX={bbox},{srsName}'.format( version=version, srsName=srsName, bbox=bbox_text) header, body = self._execute_request(req) self.assertTrue( b'gid>7' in body, "GetFeature Failed: %s , %s, lat_lon=%s" % (version, srsName, lat_lon)) _test_getFeature('1.1.0', 'urn:ogc:def:crs:EPSG::4326', lat_lon=True) _test_getFeature('1.1.0', 'EPSG:4326', lat_lon=False) _test_getFeature('1.0.0', 'urn:ogc:def:crs:EPSG::4326', lat_lon=True) _test_getFeature('1.0.0', 'EPSG:4326', lat_lon=False) # Cleanup self.assertTrue(vl.startEditing()) vl.selectByExpression('"name" LIKE \'4326-test%\'') vl.deleteSelectedFeatures() self.assertTrue(vl.commitChanges())
def testWriteReadXmlSingleVariant(self): # setup a context context = QgsCoordinateTransformContext() self.assertTrue(context.addSourceDatumTransform(QgsCoordinateReferenceSystem('EPSG:3111'), 1)) self.assertTrue(context.addSourceDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), 2)) self.assertTrue(context.addDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:3113'), 11)) self.assertTrue(context.addDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28355'), 12)) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'), 1, 2)) self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem(4283), 3, 4)) self.assertEqual(context.sourceDatumTransforms(), {'EPSG:3111': 1, 'EPSG:28356': 2}) self.assertEqual(context.destinationDatumTransforms(), {'EPSG:3113': 11, 'EPSG:28355': 12}) self.assertEqual(context.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): (1, 2), ('EPSG:28356', 'EPSG:4283'): (3, 4)}) # save to xml doc = QDomDocument("testdoc") elem = doc.createElement("test") context.writeXml(elem, QgsReadWriteContext()) # restore from xml context2 = QgsCoordinateTransformContext() context2.readXml(elem, QgsReadWriteContext()) # check result self.assertEqual(context2.sourceDatumTransforms(), {'EPSG:3111': 1, 'EPSG:28356': 2}) self.assertEqual(context2.destinationDatumTransforms(), {'EPSG:3113': 11, 'EPSG:28355': 12}) self.assertEqual(context2.sourceDestinationDatumTransforms(), {('EPSG:3111', 'EPSG:4283'): (1, 2), ('EPSG:28356', 'EPSG:4283'): (3, 4)})
def testReadWriteSettings(self): context = QgsCoordinateTransformContext() context.readSettings() source_id_1 = QgsDatumTransform.datumTransformations( QgsCoordinateReferenceSystem(4204), QgsCoordinateReferenceSystem(4326))[0].sourceTransformId dest_id_1 = QgsDatumTransform.datumTransformations( QgsCoordinateReferenceSystem(4204), QgsCoordinateReferenceSystem(4326))[0].destinationTransformId source_id_2 = QgsDatumTransform.datumTransformations( QgsCoordinateReferenceSystem(4205), QgsCoordinateReferenceSystem(4326))[0].sourceTransformId dest_id_2 = QgsDatumTransform.datumTransformations( QgsCoordinateReferenceSystem(4205), QgsCoordinateReferenceSystem(4326))[0].destinationTransformId # should be empty self.assertEqual(context.sourceDestinationDatumTransforms(), {}) self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:4204'), QgsCoordinateReferenceSystem('EPSG:4326'), source_id_1, dest_id_1)) self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:4205'), QgsCoordinateReferenceSystem(4326), source_id_2, dest_id_2)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:4204', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_1, dest_id_1), ('EPSG:4205', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_2, dest_id_2) }) # save to settings context.writeSettings() # restore from settings context2 = QgsCoordinateTransformContext() self.assertEqual(context2.sourceDestinationDatumTransforms(), {}) context2.readSettings() # check result self.assertEqual( context2.sourceDestinationDatumTransforms(), { ('EPSG:4204', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_1, dest_id_1), ('EPSG:4205', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_2, dest_id_2) })
def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = HarmonyQGISDialog() # get stored settings settings = QgsSettings() # Fetch the currently loaded layers layers = QgsProject.instance().layerTreeRoot().children() layerNames = [layer.name() for layer in layers] # Clear the contents of the comboBox from previous runs self.dlg.comboBox.clear() # Populate the comboBox with names of all the loaded layers self.dlg.comboBox.addItems(layerNames) # use the previous layer as the default if it is in the existing layers # layerName = settings.value("harmony_qgis/layer") # if layerName and layerName in layerNames: # self.dlg.comboBox.setCurrentIndex(layerNames.index(layerName)) layer = self.iface.activeLayer() if layer: self.dlg.comboBox.setCurrentIndex(layerNames.index(layer.name())) # fill the harmnoy url input with the saved setting if available harmonyUrl = settings.value("harmony_qgis/harmony_url") if harmonyUrl: self.dlg.harmonyUrlLineEdit.setText(harmonyUrl) collectionId = settings.value("harmony_qgis/collection_id") if collectionId: self.dlg.collectionField.setText(collectionId) version = settings.value("harmony_qgis/version") or "1.0.0" self.dlg.versionField.setText(version) variable = settings.value("harmony_qgis/variable") if variable: self.dlg.variableField.setText(variable) # clear the table self.dlg.tableWidget.setRowCount(0) # set the table header self.dlg.tableWidget.setHorizontalHeaderLabels('Parameter;Value'.split(';')) # add a parameter/value when the 'Add' button is clicked self.dlg.addButton.clicked.connect(self.addSearchParameter) # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: collectionId = str(self.dlg.collectionField.text()) version = str(self.dlg.versionField.text()) variable = str(self.dlg.variableField.text()) layerName = str(self.dlg.comboBox.currentText()) # TODO handle the case where there is more than one layer by this name layer = QgsProject.instance().mapLayersByName(layerName)[0] opts = QgsVectorFileWriter.SaveVectorOptions() opts.driverName = 'GeoJson' tempFile = '/tmp/qgis.json' QgsVectorFileWriter.writeAsVectorFormatV2(layer, tempFile, QgsCoordinateTransformContext(), opts) harmonyUrl = self.dlg.harmonyUrlLineEdit.text() path = collectionId + "/" + "ogc-api-coverages/" + version + "/collections/" + variable + "/coverage/rangeset" url = harmonyUrl + "/" + path print(url) tempFileHandle = open(tempFile, 'r') contents = tempFileHandle.read() tempFileHandle.close() geoJson = rewind(contents) tempFileHandle = open(tempFile, 'w') tempFileHandle.write(geoJson) tempFileHandle.close() tempFileHandle = open(tempFile, 'rb') multipart_form_data = { 'shapefile': (layerName + '.geojson', tempFileHandle, 'application/geo+json') } rowCount = self.dlg.tableWidget.rowCount() for row in range(rowCount): parameter = self.dlg.tableWidget.item(row, 0).text() value = self.dlg.tableWidget.item(row, 1).text() multipart_form_data[parameter] = (None, value) resp = requests.post(url, files=multipart_form_data, stream=True) tempFileHandle.close() # print(resp) # print(resp.text) with open('/tmp/harmony_output_image.tif', 'wb') as fd: for chunk in resp.iter_content(chunk_size=128): fd.write(chunk) os.remove(tempFile) self.iface.addRasterLayer('/tmp/harmony_output_image.tif', layerName + '-' + variable) # QgsRasterLayer('/tmp/harmony_output_image.tif', layerName) # save settings if collectionId != "": settings.setValue("harmony_qgis/collection_id", collectionId) if version != "": settings.setValue("harmony_qgis/version", version) if variable != "": settings.setValue("harmony_qgis/variable", variable) if harmonyUrl != "": settings.setValue("harmony_qgis/harmony_url", harmonyUrl) settings.setValue("harmony_qgis/layer", layerName)
crs: QgsCoordinateReferenceSystem = layer.crs() print(crs) if crs.isGeographic(): raise TypeError("Cannot process data with geographic coordinate system.") fields: QgsFields = layer.fields() save_options = QgsVectorFileWriter.SaveVectorOptions() save_options.fileEncoding = "UTF-8" writer: QgsVectorFileWriter = QgsVectorFileWriter.create( str(path_data_output), fields, QgsWkbTypes.Point, layer.crs(), QgsCoordinateTransformContext(), save_options) features: QgsFeatureIterator = layer.getFeatures() feature: QgsFeature for feature in features: new_feature = QgsFeature(fields) old_geom: QgsGeometry = feature.geometry() new_geom: QgsGeometry = old_geom.poleOfInaccessibility(precision)[0] new_feature.setAttributes(feature.attributes()) new_feature.setGeometry(new_geom)
def testWriteReadXml(self): # setup a context context = QgsCoordinateTransformContext() source_id_1 = QgsDatumTransform.datumTransformations( QgsCoordinateReferenceSystem(4204), QgsCoordinateReferenceSystem(4326))[0].sourceTransformId dest_id_1 = QgsDatumTransform.datumTransformations( QgsCoordinateReferenceSystem(4204), QgsCoordinateReferenceSystem(4326))[0].destinationTransformId source_id_2 = QgsDatumTransform.datumTransformations( QgsCoordinateReferenceSystem(4205), QgsCoordinateReferenceSystem(4326))[0].sourceTransformId dest_id_2 = QgsDatumTransform.datumTransformations( QgsCoordinateReferenceSystem(4205), QgsCoordinateReferenceSystem(4326))[0].destinationTransformId self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem(4204), QgsCoordinateReferenceSystem(4326), source_id_1, dest_id_1)) self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem(4205), QgsCoordinateReferenceSystem(4326), source_id_2, dest_id_2)) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:4204', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_1, dest_id_1), ('EPSG:4205', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_2, dest_id_2) }) # save to xml doc = QDomDocument("testdoc") elem = doc.createElement("test") context.writeXml(elem, QgsReadWriteContext()) # restore from xml context2 = QgsCoordinateTransformContext() context2.readXml(elem, QgsReadWriteContext()) # check result self.assertEqual( context2.sourceDestinationDatumTransforms(), { ('EPSG:4204', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_1, dest_id_1), ('EPSG:4205', 'EPSG:4326'): QgsDatumTransform.TransformPair(source_id_2, dest_id_2) })
def testSourceDatumTransforms(self): context = QgsCoordinateTransformContext() self.assertEqual(context.sourceDatumTransforms(), {}) self.assertTrue( context.addSourceDatumTransform( QgsCoordinateReferenceSystem('EPSG:3111'), 1)) self.assertEqual(context.sourceDatumTransforms(), {'EPSG:3111': 1}) self.assertTrue( context.addSourceDatumTransform( QgsCoordinateReferenceSystem('EPSG:28356'), 2)) self.assertEqual(context.sourceDatumTransforms(), { 'EPSG:3111': 1, 'EPSG:28356': 2 }) self.assertTrue( context.addSourceDatumTransform( QgsCoordinateReferenceSystem('EPSG:28356'), 3)) self.assertEqual(context.sourceDatumTransforms(), { 'EPSG:3111': 1, 'EPSG:28356': 3 }) self.assertTrue( context.addSourceDatumTransform( QgsCoordinateReferenceSystem(28356), 3)) self.assertEqual(context.sourceDatumTransforms(), { 'EPSG:3111': 1, 'EPSG:28356': 3 }) # invalid crs should fail self.assertFalse( context.addSourceDatumTransform(QgsCoordinateReferenceSystem(), 4)) self.assertEqual(context.sourceDatumTransforms(), { 'EPSG:3111': 1, 'EPSG:28356': 3 }) # indicate no transform required self.assertTrue( context.addSourceDatumTransform( QgsCoordinateReferenceSystem(28357), -1)) self.assertEqual(context.sourceDatumTransforms(), { 'EPSG:3111': 1, 'EPSG:28356': 3, 'EPSG:28357': -1 }) # removing non-existing context.removeSourceDatumTransform(QgsCoordinateReferenceSystem(28354)) self.assertEqual(context.sourceDatumTransforms(), { 'EPSG:3111': 1, 'EPSG:28356': 3, 'EPSG:28357': -1 }) # remove existing context.removeSourceDatumTransform(QgsCoordinateReferenceSystem(28356)) self.assertEqual(context.sourceDatumTransforms(), { 'EPSG:3111': 1, 'EPSG:28357': -1 }) context.clear() self.assertEqual(context.sourceDatumTransforms(), {})
def _test(autoTransaction): """Test buffer methods within and without transactions - create a feature - save - retrieve the feature - change geom and attrs - test changes are seen in the buffer """ def _check_feature(wkt): f = next(layer_a.getFeatures()) self.assertEqual(f.geometry().asWkt().upper(), wkt) f = list(buffer.addedFeatures().values())[0] self.assertEqual(f.geometry().asWkt().upper(), wkt) ml = QgsVectorLayer('Point?crs=epsg:4326&field=int:integer', 'test', 'memory') self.assertTrue(ml.isValid()) d = QTemporaryDir() options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = 'GPKG' options.layerName = 'layer_a' err, _ = QgsVectorFileWriter.writeAsVectorFormatV2(ml, os.path.join(d.path(), 'transaction_test.gpkg'), QgsCoordinateTransformContext(), options) self.assertEqual(err, QgsVectorFileWriter.NoError) self.assertTrue(os.path.isfile(os.path.join(d.path(), 'transaction_test.gpkg'))) options.layerName = 'layer_b' options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer err, _ = QgsVectorFileWriter.writeAsVectorFormatV2(ml, os.path.join(d.path(), 'transaction_test.gpkg'), QgsCoordinateTransformContext(), options) layer_a = QgsVectorLayer(os.path.join(d.path(), 'transaction_test.gpkg|layername=layer_a')) self.assertTrue(layer_a.isValid()) project = QgsProject() project.setAutoTransaction(autoTransaction) project.addMapLayers([layer_a]) ########################################### # Tests with a new feature self.assertTrue(layer_a.startEditing()) buffer = layer_a.editBuffer() f = QgsFeature(layer_a.fields()) f.setAttribute('int', 123) f.setGeometry(QgsGeometry.fromWkt('point(7 45)')) self.assertTrue(layer_a.addFeatures([f])) _check_feature('POINT (7 45)') # Need to fetch the feature because its ID is NULL (-9223372036854775808) f = next(layer_a.getFeatures()) self.assertEqual(len(buffer.addedFeatures()), 1) layer_a.undoStack().undo() self.assertEqual(len(buffer.addedFeatures()), 0) layer_a.undoStack().redo() self.assertEqual(len(buffer.addedFeatures()), 1) f = list(buffer.addedFeatures().values())[0] self.assertEqual(f.attribute('int'), 123) # Now change attribute self.assertEqual(buffer.changedAttributeValues(), {}) layer_a.changeAttributeValue(f.id(), 1, 321) self.assertEqual(len(buffer.addedFeatures()), 1) # This is surprising: because it was a new feature it has been changed directly self.assertEqual(buffer.changedAttributeValues(), {}) f = list(buffer.addedFeatures().values())[0] self.assertEqual(f.attribute('int'), 321) layer_a.undoStack().undo() self.assertEqual(buffer.changedAttributeValues(), {}) f = list(buffer.addedFeatures().values())[0] self.assertEqual(f.attribute('int'), 123) f = next(layer_a.getFeatures()) self.assertEqual(f.attribute('int'), 123) # Change geometry f = next(layer_a.getFeatures()) self.assertTrue(layer_a.changeGeometry(f.id(), QgsGeometry.fromWkt('point(9 43)'))) _check_feature('POINT (9 43)') self.assertEqual(buffer.changedGeometries(), {}) layer_a.undoStack().undo() _check_feature('POINT (7 45)') self.assertEqual(buffer.changedGeometries(), {}) self.assertTrue(layer_a.changeGeometry(f.id(), QgsGeometry.fromWkt('point(9 43)'))) _check_feature('POINT (9 43)') self.assertTrue(layer_a.changeGeometry(f.id(), QgsGeometry.fromWkt('point(10 44)'))) _check_feature('POINT (10 44)') # This is anothr surprise: geometry edits get collapsed into a single # one because they have the same hardcoded id layer_a.undoStack().undo() _check_feature('POINT (7 45)') self.assertTrue(layer_a.commitChanges()) ########################################### # Tests with the existing feature # Get the feature f = next(layer_a.getFeatures()) self.assertTrue(f.isValid()) self.assertEqual(f.attribute('int'), 123) self.assertEqual(f.geometry().asWkt().upper(), 'POINT (7 45)') self.assertTrue(layer_a.startEditing()) layer_a.changeAttributeValue(f.id(), 1, 321) buffer = layer_a.editBuffer() self.assertEqual(buffer.changedAttributeValues(), {1: {1: 321}}) layer_a.undoStack().undo() self.assertEqual(buffer.changedAttributeValues(), {}) # Change geometry self.assertTrue(layer_a.changeGeometry(f.id(), QgsGeometry.fromWkt('point(9 43)'))) f = next(layer_a.getFeatures()) self.assertEqual(f.geometry().asWkt().upper(), 'POINT (9 43)') self.assertEqual(buffer.changedGeometries()[1].asWkt().upper(), 'POINT (9 43)') layer_a.undoStack().undo() self.assertEqual(buffer.changedGeometries(), {}) f = next(layer_a.getFeatures()) self.assertEqual(f.geometry().asWkt().upper(), 'POINT (7 45)') self.assertEqual(buffer.changedGeometries(), {}) # Delete an existing feature self.assertTrue(layer_a.deleteFeature(f.id())) with self.assertRaises(StopIteration): next(layer_a.getFeatures()) self.assertEqual(buffer.deletedFeatureIds(), [f.id()]) layer_a.undoStack().undo() self.assertTrue(layer_a.getFeature(f.id()).isValid()) self.assertEqual(buffer.deletedFeatureIds(), []) ########################################### # Test delete # Delete a new feature f = QgsFeature(layer_a.fields()) f.setAttribute('int', 555) f.setGeometry(QgsGeometry.fromWkt('point(8 46)')) self.assertTrue(layer_a.addFeatures([f])) f = [f for f in layer_a.getFeatures() if f.attribute('int') == 555][0] self.assertTrue(f.id() in buffer.addedFeatures()) self.assertTrue(layer_a.deleteFeature(f.id())) self.assertFalse(f.id() in buffer.addedFeatures()) self.assertFalse(f.id() in buffer.deletedFeatureIds()) layer_a.undoStack().undo() self.assertTrue(f.id() in buffer.addedFeatures()) ########################################### # Add attribute field = QgsField('attr1', QVariant.String) self.assertTrue(layer_a.addAttribute(field)) self.assertNotEqual(layer_a.fields().lookupField(field.name()), -1) self.assertEqual(buffer.addedAttributes(), [field]) layer_a.undoStack().undo() self.assertEqual(layer_a.fields().lookupField(field.name()), -1) self.assertEqual(buffer.addedAttributes(), []) layer_a.undoStack().redo() self.assertNotEqual(layer_a.fields().lookupField(field.name()), -1) self.assertEqual(buffer.addedAttributes(), [field]) self.assertTrue(layer_a.commitChanges()) ########################################### # Remove attribute self.assertTrue(layer_a.startEditing()) buffer = layer_a.editBuffer() attr_idx = layer_a.fields().lookupField(field.name()) self.assertNotEqual(attr_idx, -1) self.assertTrue(layer_a.deleteAttribute(attr_idx)) self.assertEqual(buffer.deletedAttributeIds(), [2]) self.assertEqual(layer_a.fields().lookupField(field.name()), -1) layer_a.undoStack().undo() self.assertEqual(buffer.deletedAttributeIds(), []) self.assertEqual(layer_a.fields().lookupField(field.name()), attr_idx) layer_a.undoStack().redo() self.assertEqual(buffer.deletedAttributeIds(), [2]) self.assertEqual(layer_a.fields().lookupField(field.name()), -1) self.assertTrue(layer_a.rollBack()) ########################################### # Rename attribute self.assertTrue(layer_a.startEditing()) attr_idx = layer_a.fields().lookupField(field.name()) self.assertNotEqual(attr_idx, -1) self.assertEqual(layer_a.fields().lookupField('new_name'), -1) self.assertTrue(layer_a.renameAttribute(attr_idx, 'new_name')) self.assertEqual(layer_a.fields().lookupField('new_name'), attr_idx) layer_a.undoStack().undo() self.assertEqual(layer_a.fields().lookupField(field.name()), attr_idx) self.assertEqual(layer_a.fields().lookupField('new_name'), -1) layer_a.undoStack().redo() self.assertEqual(layer_a.fields().lookupField('new_name'), attr_idx) self.assertEqual(layer_a.fields().lookupField(field.name()), -1)
def testWriteReadXmlSingleVariant(self): # setup a context context = QgsCoordinateTransformContext() self.assertTrue( context.addSourceDatumTransform( QgsCoordinateReferenceSystem('EPSG:3111'), 1)) self.assertTrue( context.addSourceDatumTransform( QgsCoordinateReferenceSystem('EPSG:28356'), 2)) self.assertTrue( context.addDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:3113'), 11)) self.assertTrue( context.addDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:28355'), 12)) self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:3111'), QgsCoordinateReferenceSystem('EPSG:4283'), 1, 2)) self.assertTrue( context.addSourceDestinationDatumTransform( QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem(4283), 3, 4)) self.assertEqual(context.sourceDatumTransforms(), { 'EPSG:3111': 1, 'EPSG:28356': 2 }) self.assertEqual(context.destinationDatumTransforms(), { 'EPSG:3113': 11, 'EPSG:28355': 12 }) self.assertEqual( context.sourceDestinationDatumTransforms(), { ('EPSG:3111', 'EPSG:4283'): (1, 2), ('EPSG:28356', 'EPSG:4283'): (3, 4) }) # save to xml doc = QDomDocument("testdoc") elem = doc.createElement("test") context.writeXml(elem, QgsReadWriteContext()) # restore from xml context2 = QgsCoordinateTransformContext() context2.readXml(elem, QgsReadWriteContext()) # check result self.assertEqual(context2.sourceDatumTransforms(), { 'EPSG:3111': 1, 'EPSG:28356': 2 }) self.assertEqual(context2.destinationDatumTransforms(), { 'EPSG:3113': 11, 'EPSG:28355': 12 }) self.assertEqual( context2.sourceDestinationDatumTransforms(), { ('EPSG:3111', 'EPSG:4283'): (1, 2), ('EPSG:28356', 'EPSG:4283'): (3, 4) })
def to_layer(features, crs, encoding, geom_type, layer_type, path): first_feat = features[0] fields = first_feat.fields() layer = None if layer_type == 'memory': layer = QgsVectorLayer(geom_type + '?crs=' + crs.authid(), path, "memory") pr = layer.dataProvider() pr.addAttributes(fields.toList()) layer.updateFields() layer.startEditing() pr.addFeatures(features) layer.commitChanges() elif layer_type == 'shapefile': wkbTypes = { 'Point': QgsWkbTypes.Point, 'Linestring': QgsWkbTypes.LineString, 'Polygon': QgsWkbTypes.Polygon } options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = "ESRI Shapefile" options.fileEncoding = encoding file_writer = QgsVectorFileWriter.create( path, fields, wkbTypes[geom_type], crs, QgsCoordinateTransformContext(), options) if file_writer.hasError() != QgsVectorFileWriter.NoError: print("Error when creating shapefile: ", file_writer.errorMessage()) del file_writer layer = QgsVectorLayer(path, ntpath.basename(path)[:-4], "ogr") pr = layer.dataProvider() layer.startEditing() pr.addFeatures(features) layer.commitChanges() elif layer_type == 'postgis': # this is needed to load the table later # uri = connstring + """ type=""" + geom_types[geom_type] + """ table=\"""" + schema_name + """\".\"""" + table_name + """\" (geom) """ connstring, schema_name, table_name = path uri = connstring + """ type=""" + geom_type + """ table=\"""" + schema_name + """\".\"""" + table_name + """\" (geom) """ crs_id = crs.postgisSrid() try: con = psycopg2.connect(connstring) cur = con.cursor() create_query = cur.mogrify( """DROP TABLE IF EXISTS "%s"."%s"; CREATE TABLE "%s"."%s"( geom geometry(%s, %s))""", (AsIs(schema_name), AsIs(table_name), AsIs(schema_name), AsIs(table_name), geom_type, AsIs(crs_id))) cur.execute(create_query) con.commit() post_q_flds = { 2: 'bigint', 6: 'numeric', 1: 'bool', 'else': 'text', 4: 'numeric' } for f in fields: f_type = f.type() if f_type not in [2, 6, 1]: f_type = 'else' attr_query = cur.mogrify( """ALTER TABLE "%s"."%s" ADD COLUMN "%s" %s""", (AsIs(schema_name), AsIs(table_name), AsIs( f.name()), AsIs(post_q_flds[f_type]))) cur.execute(attr_query) con.commit() field_names = ",".join(['"' + f.name() + '"' for f in fields]) for feature in features: attrs = [i if i else None for i in feature.attributes()] insert_query = cur.mogrify( """INSERT INTO "%s"."%s" (%s, geom) VALUES %s, ST_GeomFromText(%s,%s))""", (AsIs(schema_name), AsIs(table_name), AsIs(field_names), tuple(attrs), feature.geometry().asWkt(), AsIs(crs_id))) idx = insert_query.find(b', ST_GeomFromText') - 1 insert_query = insert_query[:idx] + insert_query[(idx + 1):] # QgsMessageLog.logMessage('sql query %s' % insert_query, level=Qgis.Critical) cur.execute(insert_query) # con.commit() pkey_query = cur.mogrify( """ALTER TABLE "%s"."%s" DROP COLUMN IF EXISTS rcl_id; ALTER TABLE "%s"."%s" ADD COLUMN rcl_id serial PRIMARY KEY NOT NULL;""", (AsIs(schema_name), AsIs(table_name), AsIs(schema_name), AsIs(table_name))) cur.execute(pkey_query) con.commit() con.close() layer = QgsVectorLayer(uri, table_name, 'postgres') except psycopg2.DatabaseError as e: print(e) return layer