def testReadExtentOnTable(self): # vector layer based on a standard table vl0 = QgsVectorLayer(self.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POLYGON table="qgis_test"."some_poly_data" (geom) sql=', 'test', 'postgres') self.assertTrue(vl0.isValid()) self.assertTrue(vl0.dataProvider().hasMetadata()) # set a custom extent originalExtent = vl0.extent() customExtent = QgsRectangle(-80, 80, -70, 90) vl0.setExtent(customExtent) # write xml doc = QDomDocument("testdoc") elem = doc.createElement("maplayer") self.assertTrue(vl0.writeLayerXml(elem, doc, QgsReadWriteContext())) # read xml with the custom extent. It should not be used by default vl1 = QgsVectorLayer() vl1.readLayerXml(elem, QgsReadWriteContext()) self.assertTrue(vl1.isValid()) self.assertEqual(vl1.extent(), originalExtent) # read xml with custom extent with readExtent option. Extent read from # xml document should NOT be used because we don't have a view or a # materialized view vl2 = QgsVectorLayer() vl2.setReadExtentFromXml(True) vl2.readLayerXml(elem, QgsReadWriteContext()) self.assertTrue(vl2.isValid()) self.assertEqual(vl2.extent(), originalExtent)
def render_layers(layer_paths): """ :param layer_paths: A list of layer paths. :return: Buffer containing output. Note caller is responsible for closing the buffer with buffer.close() :rtype: QBuffer """ layers = [] extent = None crs = QgsCoordinateReferenceSystem() crs.createFromSrid(3857) for layer_path in layer_paths: map_layer = QgsVectorLayer(layer_path, None, 'ogr') QgsMapLayerRegistry.instance().addMapLayer(map_layer) transform = QgsCoordinateTransform(map_layer.crs(), crs) print map_layer.extent().toString() layer_extent = transform.transform(map_layer.extent()) if extent is None: extent = layer_extent else: extent.combineExtentWith(layer_extent) print extent.toString() # set layer set layers.append(map_layer.id()) # add ID of every layer map_settings = QgsMapSettings() map_settings.setDestinationCrs(crs) map_settings.setCrsTransformEnabled(True) map_settings.setExtent(extent) map_settings.setOutputSize(QSize(1000, 1000)) map_settings.setLayers(layers) # job = QgsMapRendererParallelJob(settings) job = QgsMapRendererSequentialJob(map_settings) job.start() job.waitForFinished() image = job.renderedImage() # Save teh image to a buffer map_buffer = QBuffer() map_buffer.open(QIODevice.ReadWrite) image.save(map_buffer, "PNG") image.save('/tmp/test.png', 'png') # clean up QgsMapLayerRegistry.instance().removeAllMapLayers() return map_buffer
def test_run(self): function = FloodPolygonBuildingFunction.instance() hazard_path = test_data_path('hazard', 'flood_multipart_polygons.shp') # exposure_path = test_data_path('exposure', 'buildings.shp') # noinspection PyCallingNonCallable hazard_layer = QgsVectorLayer(hazard_path, 'Flood', 'ogr') # noinspection PyCallingNonCallable # exposure_layer = QgsVectorLayer(exposure_path, 'Buildings', 'ogr') exposure_layer = clone_shp_layer( name='buildings', include_keywords=True, source_directory=test_data_path('exposure')) # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum()] function.hazard = SafeLayer(hazard_layer) function.exposure = SafeLayer(exposure_layer) function.requested_extent = rect_extent function.run() impact = function.impact # Count of flooded objects is calculated "by the hands" # total flooded = 27, total buildings = 129 count = sum(impact.get_data(attribute=function.target_field)) self.assertEquals(count, 33) count = len(impact.get_data()) self.assertEquals(count, 176)
def test_run(self): function = FloodPolygonBuildingFunction.instance() hazard_path = test_data_path('hazard', 'flood_multipart_polygons.shp') exposure_path = test_data_path('exposure', 'buildings.shp') # noinspection PyCallingNonCallable hazard_layer = QgsVectorLayer(hazard_path, 'Flood', 'ogr') # noinspection PyCallingNonCallable exposure_layer = QgsVectorLayer(exposure_path, 'Buildings', 'ogr') # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum()] function.hazard = QgisWrapper(hazard_layer) function.exposure = QgisWrapper(exposure_layer) function.requested_extent = rect_extent function.parameters['building_type_field'] = 'TYPE' function.parameters['affected_field'] = 'FLOODPRONE' function.parameters['affected_value'] = 'YES' function.run() impact = function.impact # Count of flooded objects is calculated "by the hands" # total flooded = 27, total buildings = 129 count = sum(impact.get_data(attribute='INUNDATED')) self.assertEquals(count, 33) count = len(impact.get_data()) self.assertEquals(count, 176)
def create_layer(self, data): display_name = 'some-layer' uri = 'Point?crs=epsg:4326&index=yes&uuid=%s' % uuid.uuid4() vlayer = QgsVectorLayer(uri, display_name, 'memory') QgsMapLayerRegistry.instance().addMapLayer(vlayer) provider = vlayer.dataProvider() vlayer.startEditing() provider.addAttributes([ QgsField('population_density', QtCore.QVariant.Double), ]) features = [] for x, y, density in data: feat = QgsFeature() geom = QgsGeometry.fromPoint(QgsPoint(x, y)) feat.setGeometry(geom) feat.setAttributes([density]) features.append(feat) provider.addFeatures(features) vlayer.commitChanges() vlayer.updateExtents() self.canvas.setExtent(vlayer.extent()) cl = QgsMapCanvasLayer(vlayer) self.canvas.setLayerSet([cl]) vlayer.triggerRepaint()
def loadLayerTable(self, carhabLayer, tableName): # Retrieve layer from provider. uri = QgsDataSourceURI() uri.setDatabase(carhabLayer.dbPath) schema = '' geom_column = 'the_geom' uri.setDataSource(schema, tableName, geom_column) display_name = carhabLayer.getName()+'_'+tableName layer = QgsVectorLayer(uri.uri(), display_name, 'spatialite') crsType = QgsCoordinateReferenceSystem.EpsgCrsId crsVal = 2154 crs = QgsCoordinateReferenceSystem(crsVal, crsType) layer.setCrs(crs) # "Bind" layer to carhab layer. if self.getCarhabLayerByDbPath(carhabLayer.dbPath): layer.setCustomProperty('carhabLayer', carhabLayer.id) # Add layer to map (False to add to group) QgsMapLayerRegistry.instance().addMapLayer(layer, False) iface.mapCanvas().setExtent(layer.extent()) return layer
def test_run(self): function = FloodPolygonRoadsFunction.instance() hazard_path = test_data_path('hazard', 'flood_multipart_polygons.shp') exposure_path = test_data_path('exposure', 'roads.shp') # noinspection PyCallingNonCallable hazard_layer = QgsVectorLayer(hazard_path, 'Flood', 'ogr') # noinspection PyCallingNonCallable exposure_layer = QgsVectorLayer(exposure_path, 'Roads', 'ogr') # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum()] function.hazard = SafeLayer(hazard_layer) function.exposure = SafeLayer(exposure_layer) function.requested_extent = rect_extent function.run() impact = function.impact # Count of flooded objects is calculated "by the hands" # the count = 69 expected_feature_total = 69 count = sum(impact.get_data(attribute=function.target_field)) message = 'Expecting %s, but it returns %s' % ( expected_feature_total, count) self.assertEquals(count, expected_feature_total, message)
def aoiExtent(cls): """Area of interest extent, which matches output aspect ratio""" uri = QgsDataSourceURI() uri.setDatabase(cls._PalFeaturesDb) uri.setDataSource("", "aoi", "geometry") aoilayer = QgsVectorLayer(uri.uri(), "aoi", "spatialite") return aoilayer.extent()
def testApproxFeatureCountAndExtent(self): """ Test perf improvement for for https://issues.qgis.org/issues/18402 """ tmpfile = os.path.join(self.basetestpath, 'testApproxFeatureCountAndExtent.gpkg') ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile) lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(0 1)')) lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(2 3)')) lyr.CreateFeature(f) fid = f.GetFID() f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(4 5)')) lyr.CreateFeature(f) lyr.DeleteFeature(fid) ds = None ds = ogr.Open(tmpfile, update=1) ds.ExecuteSQL('DROP TABLE gpkg_ogr_contents') ds = None os.environ['QGIS_GPKG_FC_THRESHOLD'] = '1' vl = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr') self.assertTrue(vl.isValid()) fc = vl.featureCount() del os.environ['QGIS_GPKG_FC_THRESHOLD'] self.assertEqual(fc, 3) # didn't notice the hole reference = QgsGeometry.fromRect(QgsRectangle(0, 1, 4, 5)) provider_extent = QgsGeometry.fromRect(vl.extent()) self.assertTrue(QgsGeometry.compare(provider_extent.asPolygon()[0], reference.asPolygon()[0], 0.00001), provider_extent.asPolygon()[0])
def aoiExtent(cls): """Area of interest extent, which matches output aspect ratio""" uri = QgsDataSourceUri() uri.setDatabase(cls._PalFeaturesDb) uri.setDataSource('', 'aoi', 'geometry') aoilayer = QgsVectorLayer(uri.uri(), 'aoi', 'spatialite') return aoilayer.extent()
def runTestForLayer(self, layer, testname): tempdir = tempfile.mkdtemp() layer = QgsVectorLayer(layer, 'Layer', 'ogr') QgsProject.instance().addMapLayer(layer) self.iface.mapCanvas().setExtent(layer.extent()) geom = next(layer.getFeatures()).geometry() highlight = QgsHighlight(self.iface.mapCanvas(), geom, layer) color = QColor(Qt.red) highlight.setColor(color) highlight.setWidth(2) color.setAlpha(50) highlight.setFillColor(color) highlight.show() image = QImage(QSize(400, 400), QImage.Format_ARGB32) image.fill(Qt.white) painter = QPainter() painter.begin(image) self.iface.mapCanvas().render(painter) painter.end() control_image = os.path.join(tempdir, 'highlight_{}.png'.format(testname)) image.save(control_image) checker = QgsRenderChecker() checker.setControlPathPrefix("highlight") checker.setControlName("expected_highlight_{}".format(testname)) checker.setRenderedImage(control_image) self.assertTrue(checker.compareImages("highlight_{}".format(testname))) shutil.rmtree(tempdir)
def testGeopackageExtentUpdate(self): """ test http://hub.qgis.org/issues/15273 """ tmpfile = os.path.join(self.basetestpath, "testGeopackageExtentUpdate.gpkg") ds = ogr.GetDriverByName("GPKG").CreateDataSource(tmpfile) lyr = ds.CreateLayer("test", geom_type=ogr.wkbPoint) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt("POINT(0 0)")) lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt("POINT(1 1)")) lyr.CreateFeature(f) f = None f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt("POINT(1 0.5)")) lyr.CreateFeature(f) f = None gdal.ErrorReset() ds.ExecuteSQL("RECOMPUTE EXTENT ON test") has_error = gdal.GetLastErrorMsg() != "" ds = None if has_error: print("Too old GDAL trunk version. Please update") return vl = QgsVectorLayer(u"{}".format(tmpfile), u"test", u"ogr") # Test moving a geometry that touches the bbox self.assertTrue(vl.startEditing()) self.assertTrue(vl.changeGeometry(1, QgsGeometry.fromWkt("Point (0.5 0)"))) self.assertTrue(vl.commitChanges()) reference = QgsGeometry.fromRect(QgsRectangle(0.5, 0.0, 1.0, 1.0)) provider_extent = QgsGeometry.fromRect(vl.extent()) self.assertTrue( QgsGeometry.compare(provider_extent.asPolygon()[0], reference.asPolygon()[0], 0.00001), provider_extent.asPolygon()[0], ) # Test deleting a geometry that touches the bbox self.assertTrue(vl.startEditing()) self.assertTrue(vl.deleteFeature(2)) self.assertTrue(vl.commitChanges()) reference = QgsGeometry.fromRect(QgsRectangle(0.5, 0.0, 1.0, 0.5)) provider_extent = QgsGeometry.fromRect(vl.extent()) self.assertTrue( QgsGeometry.compare(provider_extent.asPolygon()[0], reference.asPolygon()[0], 0.00001), provider_extent.asPolygon()[0], )
def add_resource_as_geojson(resource, return_extent=False): if not isinstance(resource, NGWVectorLayer): raise NGWError('Resource type is not VectorLayer!') qgs_geojson_layer = QgsVectorLayer(resource.get_geojson_url(), resource.common.display_name, 'ogr') if not qgs_geojson_layer.isValid(): raise NGWError('Layer %s can\'t be added to the map!' % resource.alias) qgs_geojson_layer.dataProvider().setEncoding('UTF-8') QgsMapLayerRegistry.instance().addMapLayer(qgs_geojson_layer) if return_extent: if qgs_geojson_layer.extent().isEmpty() and qgs_geojson_layer.type() == QgsMapLayer.VectorLayer: qgs_geojson_layer.updateExtents() return qgs_geojson_layer.extent()
def test_split_by_polygon(self): """Test split_by_polygon work""" line_before = QgsVectorLayer( self.line_before + '.shp', 'test', 'ogr') expected_lines = QgsVectorLayer( self.line_after + '.shp', 'test', 'ogr') polygon_layer = QgsVectorLayer( self.polygon_base + '.shp', 'test', 'ogr') # Only one polygon is stored in the layer for feature in polygon_layer.getFeatures(): polygon = feature.geometry() split_lines = split_by_polygon( line_before, polygon, mark_value=('flooded', 1)) # Test the lines is not multipart for feature in split_lines.getFeatures(): self.assertFalse(feature.geometry().isMultipart()) self.assertEqual(expected_lines.featureCount(), split_lines.featureCount()) # Assert for every line from split_lines # we can find the same line for feature in split_lines.getFeatures(): found = False for expected in expected_lines.getFeatures(): if (feature.attributes() == expected.attributes()) and \ (feature.geometry().isGeosEqual(expected.geometry())): found = True break self.assertTrue(found) # Split by the extent (The result is the copy of the layer) line_before.updateExtents() # Expand extent to cover the lines (add epsilon to bounds) epsilon = 0.0001 # A small number extent = line_before.extent() new_extent = QgsRectangle( extent.xMinimum() - epsilon, extent.yMinimum() - epsilon, extent.xMaximum() + epsilon, extent.yMaximum() + epsilon ) new_extent = QgsGeometry().fromRect(new_extent) split_lines = split_by_polygon( line_before, new_extent) for feature in split_lines.getFeatures(): found = False for expected in line_before.getFeatures(): if (feature.attributes() == expected.attributes()) and \ (feature.geometry().isGeosEqual(expected.geometry())): found = True break self.assertTrue(found)
def testInitialSizeSymbolMapUnits(self): """Test initial size of legend with a symbol size in map units""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) marker_symbol = QgsMarkerSymbol.createSimple({'color': '#ff0000', 'outline_style': 'no', 'size': '5', 'size_unit': 'MapUnit'}) point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol)) s = QgsMapSettings() s.setLayers([point_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') layout.addLayoutItem(legend) legend.setLinkedMap(map) checker = QgsLayoutChecker( 'composer_legend_mapunits', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.assertTrue(result, message) # resize with non-top-left reference point legend.setResizeToContents(False) legend.setReferencePoint(QgsLayoutItem.LowerRight) legend.attemptMove(QgsLayoutPoint(120, 90)) legend.attemptResize(QgsLayoutSize(50, 60)) self.assertEqual(legend.positionWithUnits().x(), 120.0) self.assertEqual(legend.positionWithUnits().y(), 90.0) self.assertAlmostEqual(legend.pos().x(), 70, -1) self.assertAlmostEqual(legend.pos().y(), 30, -1) legend.setResizeToContents(True) legend.updateLegend() self.assertEqual(legend.positionWithUnits().x(), 120.0) self.assertEqual(legend.positionWithUnits().y(), 90.0) self.assertAlmostEqual(legend.pos().x(), 91, -1) self.assertAlmostEqual(legend.pos().y(), 71, -1) QgsProject.instance().removeMapLayers([point_layer.id()])
def special_search(self, easter_code="isogeo"): """Make some special actions in certains cases. :param str easter_code: easter egg label. Available values: * isogeo: display Isogeo logo and zoom in our office location * picasa: change QGS project title """ canvas = iface.mapCanvas() if easter_code == "isogeo": # WMS wms_params = {"service": "WMS", "version": "1.3.0", "request": "GetMap", "layers": "Isogeo:isogeo_logo", "crs": "EPSG:3857", "format": "image/png", "styles": "isogeo_logo", "url": "http://noisy.hq.isogeo.fr:6090/geoserver/Isogeo/ows?" } wms_uri = unquote(urlencode(wms_params)) wms_lyr = QgsRasterLayer(wms_uri, u"Ici c'est Isogeo !", "wms") if wms_lyr.isValid: QgsMapLayerRegistry.instance().addMapLayer(wms_lyr) logger.info("Isogeo easter egg used and WMS displayed!") else: logger.error("WMS layer failed: {}" .format(wms_lyr.error().message())) # WFS uri = QgsDataSourceURI() uri.setParam("url", "http://noisy.hq.isogeo.fr:6090/geoserver/Isogeo/ows?") uri.setParam("service", "WFS") uri.setParam("version", "1.1.0") uri.setParam("typename", "Isogeo:isogeo_logo") uri.setParam("srsname", "EPSG:3857") uri.setParam("restrictToRequestBBOX", "0") wfs_uri = uri.uri() wfs_lyr = QgsVectorLayer(wfs_uri, u"Ici c'est Isogeo !", "WFS") if wfs_lyr.isValid: wfs_style = path.join(path.dirname(path.realpath(__file__)), "isogeo.qml") wfs_lyr.loadNamedStyle(wfs_style) QgsMapLayerRegistry.instance().addMapLayer(wfs_lyr) canvas.setExtent(wfs_lyr.extent()) logger.debug("Isogeo easter egg used") else: logger.error("Esater egg - WFS layer failed: {}" .format(wfs_lyr.error().message())) elif easter_code == "picasa": project = QgsProject.instance() project.setTitle(u"Isogeo, le Picasa de l'information géographique") logger.debug("Picasa easter egg used") else: pass # ending method return
def loadLayer(self, path, name): layer = QgsVectorLayer(path, name, "ogr") if not layer.isValid(): raise IOError, "Failed to open the layer" self.canvas.setExtent(layer.extent()) QgsMapLayerRegistry.instance().addMapLayer(layer) layers = self.canvas.mapRenderer().layerSet() layers.append(layer.id()) self.canvas.mapRenderer().setLayerSet(layers)
def testExpressionInText(self): """Test expressions embedded in legend node text""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') layout = QgsPrintLayout(QgsProject.instance()) layout.setName('LAYOUT') layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 100, 100)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') legend.setLegendFilterByMapEnabled(False) legend.setStyleFont(QgsLegendStyle.Title, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Group, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Subgroup, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Symbol, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.SymbolLabel, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setAutoUpdateModel(False) QgsProject.instance().addMapLayers([point_layer]) s = QgsMapSettings() s.setLayers([point_layer]) group = legend.model().rootGroup().addGroup("Group [% 1 + 5 %] [% @layout_name %]") layer_tree_layer = group.addLayer(point_layer) layer_tree_layer.setCustomProperty("legend/title-label", 'bbbb [% 1+2 %] xx [% @layout_name %] [% @layer_name %]') QgsMapLayerLegendUtils.setLegendNodeUserLabel(layer_tree_layer, 0, 'xxxx') legend.model().refreshLayerLegend(layer_tree_layer) legend.model().layerLegendNodes(layer_tree_layer)[0].setUserLabel('bbbb [% 1+2 %] xx [% @layout_name %] [% @layer_name %]') layout.addLayoutItem(legend) legend.setLinkedMap(map) map.setExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30)) checker = QgsLayoutChecker( 'composer_legend_expressions', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testReadExtentOnView(self): # vector layer based on view vl0 = QgsVectorLayer(self.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POLYGON table="qgis_test"."some_poly_data_view" (geom) sql=', 'test', 'postgres') self.assertTrue(vl0.isValid()) self.assertFalse(vl0.dataProvider().hasMetadata()) # set a custom extent originalExtent = vl0.extent() customExtent = QgsRectangle(-80, 80, -70, 90) vl0.setExtent(customExtent) # write xml doc = QDomDocument("testdoc") elem = doc.createElement("maplayer") self.assertTrue(vl0.writeLayerXml(elem, doc, QgsReadWriteContext())) # read xml with the custom extent. It should not be used by default vl1 = QgsVectorLayer() vl1.readLayerXml(elem, QgsReadWriteContext()) self.assertTrue(vl1.isValid()) self.assertEqual(vl1.extent(), originalExtent) # read xml with custom extent with readExtent option. Extent read from # xml document should be used because we have a view vl2 = QgsVectorLayer() vl2.setReadExtentFromXml(True) vl2.readLayerXml(elem, QgsReadWriteContext()) self.assertTrue(vl2.isValid()) self.assertEqual(vl2.extent(), customExtent) # but a force update on extent should allow retrieveing the data # provider extent vl2.updateExtents() vl2.readLayerXml(elem, QgsReadWriteContext()) self.assertEqual(vl2.extent(), customExtent) vl2.updateExtents(force=True) vl2.readLayerXml(elem, QgsReadWriteContext()) self.assertEqual(vl2.extent(), originalExtent)
def load_countries(self): display_name = 'Population density' uri = DATA_DIR + 'Countries.shp' vlayer = QgsVectorLayer(uri, display_name, 'ogr') QgsMapLayerRegistry.instance().addMapLayers([vlayer]) vlayer.updateExtents() self.canvas.setExtent(vlayer.extent()) # set the map canvas layer set cl = QgsMapCanvasLayer(vlayer) self.layers.insert(0, cl) self.canvas.setLayerSet(self.layers) vlayer.triggerRepaint()
def testSubsetStringExtent_bug17863(self): """Check that the extent is correct when applied in the ctor and when modified after a subset string is set """ def _lessdigits(s): return re.sub(r'(\d+\.\d{3})\d+', r'\1', s) testPath = TEST_DATA_DIR + '/' + 'points.shp' subSetString = '"Class" = \'Biplane\'' subSet = '|layerid=0|subset=%s' % subSetString # unfiltered vl = QgsVectorLayer(testPath, 'test', 'ogr') self.assertTrue(vl.isValid()) unfiltered_extent = _lessdigits(vl.extent().toString()) del(vl) # filter after construction ... subSet_vl2 = QgsVectorLayer(testPath, 'test', 'ogr') self.assertEqual(_lessdigits(subSet_vl2.extent().toString()), unfiltered_extent) # ... apply filter now! subSet_vl2.setSubsetString(subSetString) self.assertEqual(subSet_vl2.subsetString(), subSetString) self.assertNotEqual(_lessdigits(subSet_vl2.extent().toString()), unfiltered_extent) filtered_extent = _lessdigits(subSet_vl2.extent().toString()) del(subSet_vl2) # filtered in constructor subSet_vl = QgsVectorLayer(testPath + subSet, 'subset_test', 'ogr') self.assertEqual(subSet_vl.subsetString(), subSetString) self.assertTrue(subSet_vl.isValid()) # This was failing in bug 17863 self.assertEqual(_lessdigits(subSet_vl.extent().toString()), filtered_extent) self.assertNotEqual(_lessdigits(subSet_vl.extent().toString()), unfiltered_extent)
def test_run_point_exposure(self): """Run the IF for point exposure. See https://github.com/AIFDR/inasafe/issues/2156. """ generic_polygon_path = test_data_path( 'hazard', 'classified_generic_polygon.shp') building_path = test_data_path('exposure', 'building-points.shp') hazard_layer = QgsVectorLayer(generic_polygon_path, 'Hazard', 'ogr') exposure_layer = QgsVectorLayer(building_path, 'Buildings', 'ogr') # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum()] impact_function = ClassifiedPolygonHazardBuildingFunction.instance() impact_function.hazard = SafeLayer(hazard_layer) impact_function.exposure = SafeLayer(exposure_layer) impact_function.requested_extent = rect_extent impact_function.run() impact_layer = impact_function.impact # Check the question expected_question = ('In each of the hazard zones how many buildings ' 'might be affected.') message = 'The question should be %s, but it returns %s' % ( expected_question, impact_function.question) self.assertEqual(expected_question, impact_function.question, message) zone_sum = impact_layer.get_data( attribute=impact_function.target_field) high_zone_count = zone_sum.count('High Hazard Zone') medium_zone_count = zone_sum.count('Medium Hazard Zone') low_zone_count = zone_sum.count('Low Hazard Zone') # The result expected_high_count = 12 expected_medium_count = 172 expected_low_count = 3 message = 'Expecting %s for High Hazard Zone, but it returns %s' % ( high_zone_count, expected_high_count) self.assertEqual(high_zone_count, expected_high_count, message) message = 'Expecting %s for Medium Hazard Zone, but it returns %s' % ( expected_medium_count, medium_zone_count) self.assertEqual(medium_zone_count, expected_medium_count, message) message = 'Expecting %s for Low Hazard Zone, but it returns %s' % ( expected_low_count, low_zone_count) self.assertEqual(expected_low_count, low_zone_count, message)
def test_interpolation_from_polygons_one_poly(self): """Point interpolation using one polygon from Maumere works There's a test with the same name in test_engine.py not using QGIS API. This one deals correctly with holes in polygons, so the resulting numbers are a bit different. """ # Name file names for hazard level and exposure hazard_filename = ('%s/tsunami_polygon_WGS84.shp' % TESTDATA) exposure_filename = ('%s/building_Maumere.shp' % TESTDATA) # Read input data H_all = QgsVectorLayer(hazard_filename, 'Hazard', 'ogr') # Cut down to make test quick # Polygon #799 is the one used in separate test H = create_layer(H_all) polygon799 = H_all.getFeatures(QgsFeatureRequest(799)).next() H.dataProvider().addFeatures([polygon799]) E = QgsVectorLayer(exposure_filename, 'Exposure', 'ogr') # Test interpolation function I = interpolate_polygon_polygon(H, E, E.extent()) N = I.dataProvider().featureCount() assert N == I.dataProvider().featureCount() # Assert that expected attribute names exist I_names = [field.name() for field in I.dataProvider().fields()] for field in H.dataProvider().fields(): name = field.name() msg = 'Did not find hazard name "%s" in %s' % (name, I_names) assert name in I_names, msg for field in E.dataProvider().fields(): name = field.name() msg = 'Did not find exposure name "%s" in %s' % (name, I_names) assert name in I_names, msg # Verify interpolated values with test result count = 0 for f in I.getFeatures(): category = f['Category'] if category is not None: count += 1 msg = ('Expected 453 points tagged with category, ' 'but got only %i' % count) assert count == 453, msg
def loadFeatureLayer(cls, table): uri = QgsDataSourceURI() uri.setDatabase(cls._PalFeaturesDb) uri.setDataSource('', table, 'geometry') vlayer = QgsVectorLayer(uri.uri(), table, 'spatialite') # .qml should contain only style for symbology vlayer.loadNamedStyle(os.path.join(cls._PalDataDir, '{0}.qml'.format(table))) cls._MapRegistry.addMapLayer(vlayer) cls._MapRenderer.setLayerSet([vlayer.id()]) # zoom to area of interest, which matches output aspect ratio uri.setDataSource('', 'aoi', 'geometry') aoilayer = QgsVectorLayer(uri.uri(), table, 'spatialite') cls._MapRenderer.setExtent(aoilayer.extent()) cls._Canvas.zoomToFullExtent() return vlayer
def show_canvas(app): canvas = QgsMapCanvas() layer = QgsVectorLayer("D:\\Software\\QGis\\StatPlanet_France\\map\\map.shp", "teste" , "ogr") if not layer.isValid(): raise IOError, "Failed to open the layer" else: # add layer to the registry QgsMapLayerRegistry.instance().addMapLayer(layer) # set extent to the extent of our layer canvas.setExtent(layer.extent()) # set the map canvas layer set canvas.setLayerSet([QgsMapCanvasLayer(layer)]) canvas.show() app.exec_()
def testResizeDisabledCrop(self): """Test that if legend resizing is disabled, and legend is too small, then content is cropped""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) s = QgsMapSettings() s.setLayers([point_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 20, 20)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') legend.setLegendFilterByMapEnabled(True) # disable auto resizing legend.setResizeToContents(False) layout.addLayoutItem(legend) legend.setLinkedMap(map) map.setExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30)) checker = QgsLayoutChecker( 'composer_legend_noresize_crop', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testSubsetStringExtent_bug17863(self): """Check that the extent is correct when applied in the ctor and when modified after a subset string is set """ def _lessdigits(s): return re.sub(r'(\d+\.\d{3})\d+', r'\1', s) testPath = "dbname=%s table='test_filter' (geometry) key='id'" % self.dbname subSetString = '"name" = \'int\'' subSet = ' sql=%s' % subSetString # unfiltered vl = QgsVectorLayer(testPath, 'test', 'spatialite') self.assertTrue(vl.isValid()) self.assertEqual(vl.featureCount(), 8) unfiltered_extent = _lessdigits(vl.extent().toString()) self.assertNotEqual('Empty', unfiltered_extent) del(vl) # filter after construction ... subSet_vl2 = QgsVectorLayer(testPath, 'test', 'spatialite') self.assertEqual(_lessdigits(subSet_vl2.extent().toString()), unfiltered_extent) self.assertEqual(subSet_vl2.featureCount(), 8) # ... apply filter now! subSet_vl2.setSubsetString(subSetString) self.assertEqual(subSet_vl2.featureCount(), 4) self.assertEqual(subSet_vl2.subsetString(), subSetString) self.assertNotEqual(_lessdigits(subSet_vl2.extent().toString()), unfiltered_extent) filtered_extent = _lessdigits(subSet_vl2.extent().toString()) del(subSet_vl2) # filtered in constructor subSet_vl = QgsVectorLayer(testPath + subSet, 'subset_test', 'spatialite') self.assertEqual(subSet_vl.subsetString(), subSetString) self.assertTrue(subSet_vl.isValid()) # This was failing in bug 17863 self.assertEqual(subSet_vl.featureCount(), 4) self.assertEqual(_lessdigits(subSet_vl.extent().toString()), filtered_extent) self.assertNotEqual(_lessdigits(subSet_vl.extent().toString()), unfiltered_extent) self.assertTrue(subSet_vl.setSubsetString('')) self.assertEqual(subSet_vl.featureCount(), 8) self.assertEqual(_lessdigits(subSet_vl.extent().toString()), unfiltered_extent)
def testGeopackageRefreshIfTableListUpdated(self): ''' test that creating/deleting a layer is reflected when opening a new layer ''' tmpfile = os.path.join(self.basetestpath, 'testGeopackageRefreshIfTableListUpdated.gpkg') ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile) ds.CreateLayer('test', geom_type=ogr.wkbPoint) ds = None vl = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr') self.assertTrue(vl.extent().isNull()) time.sleep(1) # so timestamp gets updated ds = ogr.Open(tmpfile, update=1) ds.CreateLayer('test2', geom_type=ogr.wkbPoint) ds = None vl2 = QgsVectorLayer(u'{}'.format(tmpfile), 'test', u'ogr') vl2.subLayers() self.assertEqual(vl2.dataProvider().subLayers(), ['0:test:0:Point:geom', '1:test2:0:Point:geom'])
def testResizeDisabledCrop(self): """Test that if legend resizing is disabled, and legend is too small, then content is cropped""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) s = QgsMapSettings() s.setLayers([point_layer]) s.setCrsTransformEnabled(False) composition = QgsComposition(s) composition.setPaperSize(297, 210) composer_map = QgsComposerMap(composition, 20, 20, 80, 80) composer_map.setFrameEnabled(True) composition.addComposerMap(composer_map) composer_map.setNewExtent(point_layer.extent()) legend = QgsComposerLegend(composition) legend.setSceneRect(QRectF(120, 20, 20, 20)) legend.setFrameEnabled(True) legend.setFrameOutlineWidth(2) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') legend.setLegendFilterByMapEnabled(True) # disable auto resizing legend.setResizeToContents(False) composition.addComposerLegend(legend) legend.setComposerMap(composer_map) composer_map.setNewExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30)) checker = QgsCompositionChecker( 'composer_legend_noresize_crop', composition) checker.setControlPathPrefix("composer_legend") result, message = checker.testComposition() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def _aggregate(self, myImpactLayer, myExpectedResults): myAggregationLayer = QgsVectorLayer( os.path.join(BOUNDDATA, 'kabupaten_jakarta.shp'), 'test aggregation', 'ogr') # create a copy of aggregation layer myGeoExtent = extent_to_geo_array( myAggregationLayer.extent(), myAggregationLayer.crs()) myAggrAttribute = self.keywordIO.read_keywords( myAggregationLayer, self.defaults['AGGR_ATTR_KEY']) # noinspection PyArgumentEqualDefault myAggregationLayer = clip_layer( layer=myAggregationLayer, extent=myGeoExtent, explode_flag=True, explode_attribute=myAggrAttribute) myAggregator = Aggregator(None, myAggregationLayer) # setting up myAggregator.isValid = True myAggregator.layer = myAggregationLayer myAggregator.safeLayer = safe_read_layer( str(myAggregator.layer.source())) myAggregator.aoiMode = False myAggregator.aggregate(myImpactLayer) myProvider = myAggregator.layer.dataProvider() myProvider.select(myProvider.attributeIndexes()) myFeature = QgsFeature() myResults = [] while myProvider.nextFeature(myFeature): myFeatureResults = {} myAtMap = myFeature.attributeMap() for (k, attr) in myAtMap.iteritems(): myFeatureResults[k] = str(attr.toString()) myResults.append(myFeatureResults) self.assertEqual(myExpectedResults, myResults)
def testResizeWithMapContent(self): """Test test legend resizes to match map content""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) s = QgsMapSettings() s.setLayers([point_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') legend.setLegendFilterByMapEnabled(True) layout.addLayoutItem(legend) legend.setLinkedMap(map) map.setExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30)) checker = QgsLayoutChecker('composer_legend_size_content', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testResizeWithMapContent(self): """Test test legend resizes to match map content""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) s = QgsMapSettings() s.setLayers([point_layer]) composition = QgsComposition(QgsProject.instance()) composition.setPaperSize(297, 210) composer_map = QgsComposerMap(composition, 20, 20, 80, 80) composer_map.setFrameEnabled(True) composer_map.setLayers([point_layer]) composition.addComposerMap(composer_map) composer_map.setNewExtent(point_layer.extent()) legend = QgsComposerLegend(composition) legend.setSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(2) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') legend.setLegendFilterByMapEnabled(True) composition.addComposerLegend(legend) legend.setComposerMap(composer_map) composer_map.setNewExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30)) checker = QgsCompositionChecker( 'composer_legend_size_content', composition) checker.setControlPathPrefix("composer_legend") result, message = checker.testComposition() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testApproxFeatureCountAndExtent(self): """ Test perf improvement for for https://issues.qgis.org/issues/18402 """ tmpfile = os.path.join(self.basetestpath, 'testApproxFeatureCountAndExtent.gpkg') ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile) lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(0 1)')) lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(2 3)')) lyr.CreateFeature(f) fid = f.GetFID() f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(4 5)')) lyr.CreateFeature(f) lyr.DeleteFeature(fid) ds = None ds = ogr.Open(tmpfile, update=1) ds.ExecuteSQL('DROP TABLE gpkg_ogr_contents') ds = None os.environ['QGIS_GPKG_FC_THRESHOLD'] = '1' vl = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr') self.assertTrue(vl.isValid()) fc = vl.featureCount() del os.environ['QGIS_GPKG_FC_THRESHOLD'] self.assertEqual(fc, 3) # didn't notice the hole reference = QgsGeometry.fromRect(QgsRectangle(0, 1, 4, 5)) provider_extent = QgsGeometry.fromRect(vl.extent()) self.assertTrue( QgsGeometry.compare(provider_extent.asPolygon()[0], reference.asPolygon()[0], 0.00001), provider_extent.asPolygon()[0])
def test_run(self): function = FloodPolygonBuildingFunction.instance() hazard_path = standard_data_path('hazard', 'flood_multipart_polygons.shp') # exposure_path = standard_data_path('exposure', 'buildings.shp') # noinspection PyCallingNonCallable hazard_layer = QgsVectorLayer(hazard_path, 'Flood', 'ogr') # noinspection PyCallingNonCallable # exposure_layer = QgsVectorLayer(exposure_path, 'Buildings', 'ogr') exposure_layer = clone_shp_layer( name='buildings', include_keywords=True, source_directory=standard_data_path('exposure')) # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum() ] function.hazard = SafeLayer(hazard_layer) function.exposure = SafeLayer(exposure_layer) function.requested_extent = rect_extent function.run() impact = function.impact # Count of flooded objects is calculated "by the hands" # total flooded = 27, total buildings = 129 count = sum(impact.get_data(attribute=function.target_field)) self.assertEquals(count, 33) count = len(impact.get_data()) self.assertEquals(count, 176)
def test_multi_poly_opacity(self): # test that multi-type features are only rendered once multipoly = QgsVectorLayer(os.path.join(TEST_DATA_DIR, 'multipatch.shp'), 'Polygons', 'ogr') sym = QgsFillSymbol.createSimple({'color': '#77fdbf6f', 'outline_color': 'black'}) buffer_layer = QgsGeometryGeneratorSymbolLayer.create({'geometryModifier': 'buffer($geometry, -0.01)', 'outline_color': 'black'}) buffer_layer.setSymbolType(QgsSymbol.Fill) buffer_layer.setSubSymbol(sym) geom_symbol = QgsFillSymbol() geom_symbol.changeSymbolLayer(0, buffer_layer) multipoly.renderer().setSymbol(geom_symbol) mapsettings = QgsMapSettings(self.mapsettings) mapsettings.setExtent(multipoly.extent()) mapsettings.setLayers([multipoly]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(mapsettings) renderchecker.setControlName('expected_geometrygenerator_opacity') res = renderchecker.runTest('geometrygenerator_opacity') self.report += renderchecker.report() self.assertTrue(res)
def test_clip_vector_with_unicode(self): """Test clipping vector layer with unicode attribute in feature. This issue is described at Github #2262 and #2233 TODO: FIXME: This is a hacky fix. See above ticket for further explanation. To fix this, we should be able to specify UTF-8 encoding for QgsVectorFileWriter """ # this layer contains unicode values in the layer_path = test_data_path('boundaries', 'district_osm_jakarta.shp') vector_layer = QgsVectorLayer(layer_path, 'District Jakarta', 'ogr') keyword_io = KeywordIO() aggregation_keyword = get_defaults()['AGGR_ATTR_KEY'] aggregation_attribute = keyword_io.read_keywords( vector_layer, keyword=aggregation_keyword) source_extent = vector_layer.extent() extent = [source_extent.xMinimum(), source_extent.yMinimum(), source_extent.xMaximum(), source_extent.yMaximum()] clipped_layer = clip_layer( layer=vector_layer, extent=extent, explode_flag=True, explode_attribute=aggregation_attribute) # cross check vector layer attribute in clipped layer vector_values = [] for f in vector_layer.getFeatures(): vector_values.append(f.attributes()) clipped_values = [] for f in clipped_layer.getFeatures(): clipped_values.append(f.attributes()) for val in clipped_values: self.assertIn(val, vector_values)
def testSubsetStringExtent_bug17863(self): """Check that the extent is correct when applied in the ctor and when modified after a subset string is set """ def _lessdigits(s): return re.sub(r'(\d+\.\d{3})\d+', r'\1', s) tmpfile = os.path.join(self.basetestpath, 'testSubsetStringExtent_bug17863.gpkg') shutil.copy(TEST_DATA_DIR + '/' + 'provider/bug_17795.gpkg', tmpfile) testPath = tmpfile + '|layername=bug_17795' subSetString = '"name" = \'int\'' subSet = '|layername=bug_17795|subset=%s' % subSetString # unfiltered vl = QgsVectorLayer(testPath, 'test', 'ogr') self.assertTrue(vl.isValid()) unfiltered_extent = _lessdigits(vl.extent().toString()) del (vl) # filter after construction ... subSet_vl2 = QgsVectorLayer(testPath, 'test', 'ogr') self.assertEqual(_lessdigits(subSet_vl2.extent().toString()), unfiltered_extent) # ... apply filter now! subSet_vl2.setSubsetString(subSetString) self.assertEqual(subSet_vl2.subsetString(), subSetString) self.assertNotEqual(_lessdigits(subSet_vl2.extent().toString()), unfiltered_extent) filtered_extent = _lessdigits(subSet_vl2.extent().toString()) del (subSet_vl2) # filtered in constructor subSet_vl = QgsVectorLayer(testPath + subSet, 'subset_test', 'ogr') self.assertEqual(subSet_vl.subsetString(), subSetString) self.assertTrue(subSet_vl.isValid()) # This was failing in bug 17863 self.assertEqual(_lessdigits(subSet_vl.extent().toString()), filtered_extent) self.assertNotEqual(_lessdigits(subSet_vl.extent().toString()), unfiltered_extent)
def testSubsetStringExtent_bug17863(self): """Check that the extent is correct when applied in the ctor and when modified after a subset string is set """ def _lessdigits(s): return re.sub(r'(\d+\.\d{3})\d+', r'\1', s) testPath = TEST_DATA_DIR + '/' + 'points.shp' subSetString = '"Class" = \'Biplane\'' subSet = '|layerid=0|subset=%s' % subSetString # unfiltered vl = QgsVectorLayer(testPath, 'test', 'ogr') self.assertTrue(vl.isValid()) unfiltered_extent = _lessdigits(vl.extent().toString()) del (vl) # filter after construction ... subSet_vl2 = QgsVectorLayer(testPath, 'test', 'ogr') self.assertEqual(_lessdigits(subSet_vl2.extent().toString()), unfiltered_extent) # ... apply filter now! subSet_vl2.setSubsetString(subSetString) self.assertEqual(subSet_vl2.subsetString(), subSetString) self.assertNotEqual(_lessdigits(subSet_vl2.extent().toString()), unfiltered_extent) filtered_extent = _lessdigits(subSet_vl2.extent().toString()) del (subSet_vl2) # filtered in constructor subSet_vl = QgsVectorLayer(testPath + subSet, 'subset_test', 'ogr') self.assertEqual(subSet_vl.subsetString(), subSetString) self.assertTrue(subSet_vl.isValid()) # This was failing in bug 17863 self.assertEqual(_lessdigits(subSet_vl.extent().toString()), filtered_extent) self.assertNotEqual(_lessdigits(subSet_vl.extent().toString()), unfiltered_extent)
def testBlockingItems(self): """ Test rendering map item with blocking items """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) map.setId('map') layout.addLayoutItem(map) map2 = QgsLayoutItemMap(layout) map2.attemptSetSceneRect(QRectF(0, 5, 50, 80)) map2.setFrameEnabled(True) map2.setBackgroundEnabled(False) map2.setId('map2') layout.addLayoutItem(map2) map3 = QgsLayoutItemMap(layout) map3.attemptSetSceneRect(QRectF(150, 160, 50, 50)) map3.setFrameEnabled(True) map3.setBackgroundEnabled(False) map3.setId('map3') layout.addLayoutItem(map3) map.addLabelBlockingItem(map2) map.addLabelBlockingItem(map3) map.setMapFlags(QgsLayoutItemMap.MapItemFlags()) checker = QgsLayoutChecker('composermap_label_blockers', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) doc = QDomDocument("testdoc") elem = layout.writeXml(doc, QgsReadWriteContext()) l2 = QgsLayout(p) self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext())) map_restore = [ i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map' ][0] map2_restore = [ i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map2' ][0] map3_restore = [ i for i in l2.items() if isinstance(i, QgsLayoutItemMap) and i.id() == 'map3' ][0] self.assertTrue(map_restore.isLabelBlockingItem(map2_restore)) self.assertTrue(map_restore.isLabelBlockingItem(map3_restore))
def testPartialLabels(self): """ Test rendering map item with a show partial labels flag """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False) engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) # default should always be to hide partial labels self.assertFalse(map.mapFlags() & QgsLayoutItemMap.ShowPartialLabels) # hiding partial labels (the default) map.setMapFlags(QgsLayoutItemMap.MapItemFlags()) checker = QgsLayoutChecker('composermap_label_nomargin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # showing partial labels map.setMapFlags(QgsLayoutItemMap.ShowPartialLabels) checker = QgsLayoutChecker('composermap_show_partial_labels', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message)
def testLabelMargin(self): """ Test rendering map item with a label margin set """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False) engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) checker = QgsLayoutChecker('composermap_label_nomargin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setLabelMargin( QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters)) checker = QgsLayoutChecker('composermap_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setLabelMargin( QgsLayoutMeasurement(3, QgsUnitTypes.LayoutCentimeters)) checker = QgsLayoutChecker('composermap_label_cm_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setMapRotation(45) map.zoomToExtent(vl.extent()) map.setScale(map.scale() * 1.2) checker = QgsLayoutChecker('composermap_rotated_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # data defined map.setMapRotation(0) map.zoomToExtent(vl.extent()) map.dataDefinedProperties().setProperty( QgsLayoutObject.MapLabelMargin, QgsProperty.fromExpression('1+3')) map.refresh() checker = QgsLayoutChecker('composermap_dd_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message)
def _aggregate(self, impact_layer, expected_results, use_native_zonal_stats=False): """Helper to calculate aggregation. Expected results is split into two lists - one list contains numeric attributes, the other strings. This is done so that we can use numpy .testing.assert_allclose which doesn't work on strings """ expected_string_results = [] expected_numeric_results = [] for item in expected_results: string_results = [] numeric_results = [] for field in item: try: value = float(field) numeric_results.append(value) except ValueError: string_results.append(str(field)) expected_numeric_results.append(numeric_results) expected_string_results.append(string_results) aggregation_layer = QgsVectorLayer( os.path.join(BOUNDDATA, 'kabupaten_jakarta.shp'), 'test aggregation', 'ogr') # create a copy of aggregation layer geo_extent = extent_to_geo_array(aggregation_layer.extent(), aggregation_layer.crs()) aggregation_attribute = self.keywordIO.read_keywords( aggregation_layer, self.defaults['AGGR_ATTR_KEY']) # noinspection PyArgumentEqualDefault aggregation_layer = clip_layer(layer=aggregation_layer, extent=geo_extent, explode_flag=True, explode_attribute=aggregation_attribute) aggregator = Aggregator(None, aggregation_layer) # setting up aggregator.is_valid = True aggregator.layer = aggregation_layer aggregator.safe_layer = safe_read_layer(str(aggregator.layer.source())) aggregator.aoi_mode = False aggregator.use_native_zonal_stats = use_native_zonal_stats aggregator.aggregate(impact_layer) provider = aggregator.layer.dataProvider() string_results = [] numeric_results = [] for feature in provider.getFeatures(): feature_string_results = [] feature_numeric_results = [] attributes = feature.attributes() for attr in attributes: if isinstance(attr, (int, float)): feature_numeric_results.append(attr) else: feature_string_results.append(attr) numeric_results.append(feature_numeric_results) string_results.append(feature_string_results) # check string attributes self.assertEqual(expected_string_results, string_results) # check numeric attributes with a 0.01% tolerance compared to the # native QGIS stats numpy.testing.assert_allclose(expected_numeric_results, numeric_results, rtol=0.01)
def create_unicorn_layer(self): endpointIndex = self.dlg.comboBox.currentIndex() # SPARQL query #print(self.loadedfromfile) # query query = self.dlg.inp_sparql2.toPlainText() if self.loadedfromfile: curindex = self.dlg.proxyModel.mapToSource( self.dlg.geoClassList.selectionModel().currentIndex()) if curindex != None and self.dlg.geoClassListModel.itemFromIndex( curindex) != None: concept = self.dlg.geoClassListModel.itemFromIndex( curindex).data(1) else: concept = "http://www.opengis.net/ont/geosparql#Feature" geojson = self.getGeoJSONFromGeoConcept(self.currentgraph, concept) vlayer = QgsVectorLayer( json.dumps(geojson, sort_keys=True, indent=4), "unicorn_" + self.dlg.inp_label.text(), "ogr") print(vlayer.isValid()) QgsProject.instance().addMapLayer(vlayer) canvas = iface.mapCanvas() canvas.setExtent(vlayer.extent()) iface.messageBar().pushMessage("Add layer", "OK", level=Qgis.Success) #iface.messageBar().pushMessage("Error", "An error occured", level=Qgis.Critical) #self.dlg.close() return else: endpoint_url = self.triplestoreconf[endpointIndex]["endpoint"] missingmandvars = [] for mandvar in self.triplestoreconf[endpointIndex][ "mandatoryvariables"]: if mandvar not in query: missingmandvars.append("?" + mandvar) if missingmandvars != [] and not self.dlg.allownongeo.isChecked(): msgBox = QMessageBox() msgBox.setWindowTitle("Mandatory variables missing!") msgBox.setText( "The SPARQL query is missing the following mandatory variables: " + str(missingmandvars)) msgBox.exec() return progress = QProgressDialog( "Querying layer from " + endpoint_url + "...", "Abort", 0, 0, self.dlg) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) progress.show() queryprefixes = [] prefixestoadd = "" for line in query.split("\n"): if line.startswith("PREFIX"): queryprefixes.append(line[line.find("http"):].replace(">", "")) url = line[line.find("http"):].replace(">", "") for endpoint in self.triplestoreconf[endpointIndex]["prefixes"]: if not self.triplestoreconf[endpointIndex]["prefixes"][ endpoint] in queryprefixes: prefixestoadd += "PREFIX " + endpoint + ": <" + self.triplestoreconf[ endpointIndex]["prefixes"][endpoint] + "> \n" self.qtask = QueryLayerTask("Querying QGIS Layer from " + endpoint_url, endpoint_url, prefixestoadd + query, self.triplestoreconf[endpointIndex], self.dlg.allownongeo.isChecked(), self.dlg.inp_label.text(), progress) QgsApplication.taskManager().addTask(self.qtask)
class TestQgsBlendModes(TestCase): def __init__(self, methodName): """Run once on class initialisation.""" unittest.TestCase.__init__(self, methodName) # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL self.mMapRegistry = QgsMapLayerRegistry.instance() # create point layer myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr') self.mMapRegistry.addMapLayer(self.mPointLayer) # create polygon layer myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp') self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr') self.mMapRegistry.addMapLayer(self.mPolygonLayer) # create line layer myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp') self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr') self.mMapRegistry.addMapLayer(self.mLineLayer) # create two raster layers myRasterFile = os.path.join(TEST_DATA_DIR, 'landsat.tif') self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1") self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2") myMultiBandRenderer1 = QgsMultiBandColorRenderer( self.mRasterLayer1.dataProvider(), 2, 3, 4) self.mRasterLayer1.setRenderer(myMultiBandRenderer1) self.mMapRegistry.addMapLayer(self.mRasterLayer1) myMultiBandRenderer2 = QgsMultiBandColorRenderer( self.mRasterLayer2.dataProvider(), 2, 3, 4) self.mRasterLayer2.setRenderer(myMultiBandRenderer2) self.mMapRegistry.addMapLayer(self.mRasterLayer2) # to match blend modes test comparisons background self.mCanvas = CANVAS self.mCanvas.setCanvasColor(QColor(152, 219, 249)) self.mMap = self.mCanvas.map() self.mMap.resize(QSize(400, 400)) self.mMapRenderer = self.mCanvas.mapRenderer() self.mMapRenderer.setOutputSize(QSize(400, 400), 72) def testVectorBlending(self): """Test that blend modes work for vector layers.""" #Add vector layers to map myLayers = QStringList() myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mPointLayer.extent()) #Set blending modes for both layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsRenderChecker() checker.setControlName("expected_vector_blendmodes") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("vector_blendmodes") myMessage = ('vector blending failed') assert myResult, myMessage #Reset layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver) def testVectorFeatureBlending(self): """Test that feature blend modes work for vector layers.""" #Add vector layers to map myLayers = QStringList() myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mPointLayer.extent()) #Set feature blending for line layer self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus) checker = QgsRenderChecker() checker.setControlName("expected_vector_featureblendmodes") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("vector_featureblendmodes") myMessage = ('vector feature blending failed') assert myResult, myMessage #Reset layers self.mLineLayer.setFeatureBlendMode( QPainter.CompositionMode_SourceOver) def testVectorLayerTransparency(self): """Test that layer transparency works for vector layers.""" #Add vector layers to map myLayers = QStringList() myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mPointLayer.extent()) #Set feature blending for line layer self.mLineLayer.setLayerTransparency(50) checker = QgsRenderChecker() checker.setControlName("expected_vector_layertransparency") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("vector_layertransparency") myMessage = ('vector layer transparency failed') assert myResult, myMessage def testRasterBlending(self): """Test that blend modes work for raster layers.""" #Add raster layers to map myLayers = QStringList() myLayers.append(self.mRasterLayer1.id()) myLayers.append(self.mRasterLayer2.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mRasterLayer1.extent()) #Set blending mode for top layer self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Plus) checker = QgsRenderChecker() checker.setControlName("expected_raster_blendmodes") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("raster_blendmodes") myMessage = ('raster blending failed') assert myResult, myMessage
def run(item, action, mainwindow): db = item.database() uri = db.uri() iface = mainwindow.iface quoteId = db.connector.quoteId quoteStr = db.connector.quoteString # check if the selected item is a topology schema isTopoSchema = False if not hasattr(item, 'schema'): mainwindow.infoBar.pushMessage( "Invalid topology", u'Select a topology schema to continue.', QgsMessageBar.INFO, mainwindow.iface.messageTimeout()) return False if item.schema() is not None: sql = u"SELECT srid FROM topology.topology WHERE name = %s" % quoteStr( item.schema().name) c = db.connector._get_cursor() db.connector._execute(c, sql) res = db.connector._fetchone(c) isTopoSchema = res is not None if not isTopoSchema: mainwindow.infoBar.pushMessage( "Invalid topology", u'Schema "{0}" is not registered in topology.topology.'.format( item.schema().name), QgsMessageBar.WARNING, mainwindow.iface.messageTimeout()) return False if (res[0] < 0): mainwindow.infoBar.pushMessage( "WARNING", u'Topology "{0}" is registered as having a srid of {1} in topology.topology, we will assume 0 (for unknown)' .format(item.schema().name, res[0]), QgsMessageBar.WARNING, mainwindow.iface.messageTimeout()) toposrid = '0' else: toposrid = str(res[0]) # load layers into the current project toponame = item.schema().name template_dir = os.path.join(current_path, 'templates') # do not refresh the canvas until all the layers are added wasFrozen = iface.mapCanvas().isFrozen() iface.mapCanvas().freeze() try: provider = db.dbplugin().providerName() uri = db.uri() # Force use of estimated metadata (topologies can be big) uri.setUseEstimatedMetadata(True) # FACES # face mbr uri.setDataSource(toponame, 'face', 'mbr', '', 'face_id') uri.setSrid(toposrid) uri.setWkbType(QgsWkbTypes.Polygon) layerFaceMbr = QgsVectorLayer(uri.uri(False), u'%s.face_mbr' % toponame, provider) layerFaceMbr.loadNamedStyle(os.path.join(template_dir, 'face_mbr.qml')) face_extent = layerFaceMbr.extent() # face geometry sql = u'SELECT face_id, topology.ST_GetFaceGeometry(%s,' \ 'face_id)::geometry(polygon, %s) as geom ' \ 'FROM %s.face WHERE face_id > 0' % \ (quoteStr(toponame), toposrid, quoteId(toponame)) uri.setDataSource('', u'(%s\n)' % sql, 'geom', '', 'face_id') uri.setSrid(toposrid) uri.setWkbType(QgsWkbTypes.Polygon) layerFaceGeom = QgsVectorLayer(uri.uri(False), u'%s.face' % toponame, provider) layerFaceGeom.setExtent(face_extent) layerFaceGeom.loadNamedStyle(os.path.join(template_dir, 'face.qml')) # face_seed sql = u'SELECT face_id, ST_PointOnSurface(' \ 'topology.ST_GetFaceGeometry(%s,' \ 'face_id))::geometry(point, %s) as geom ' \ 'FROM %s.face WHERE face_id > 0' % \ (quoteStr(toponame), toposrid, quoteId(toponame)) uri.setDataSource('', u'(%s)' % sql, 'geom', '', 'face_id') uri.setSrid(toposrid) uri.setWkbType(QgsWkbTypes.Point) layerFaceSeed = QgsVectorLayer(uri.uri(False), u'%s.face_seed' % toponame, provider) layerFaceSeed.setExtent(face_extent) layerFaceSeed.loadNamedStyle( os.path.join(template_dir, 'face_seed.qml')) # TODO: add polygon0, polygon1 and polygon2 ? # NODES # node uri.setDataSource(toponame, 'node', 'geom', '', 'node_id') uri.setSrid(toposrid) uri.setWkbType(QgsWkbTypes.Point) layerNode = QgsVectorLayer(uri.uri(False), u'%s.node' % toponame, provider) layerNode.loadNamedStyle(os.path.join(template_dir, 'node.qml')) node_extent = layerNode.extent() # node labels uri.setDataSource(toponame, 'node', 'geom', '', 'node_id') uri.setSrid(toposrid) uri.setWkbType(QgsWkbTypes.Point) layerNodeLabel = QgsVectorLayer(uri.uri(False), u'%s.node_id' % toponame, provider) layerNodeLabel.setExtent(node_extent) layerNodeLabel.loadNamedStyle( os.path.join(template_dir, 'node_label.qml')) # EDGES # edge uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid(toposrid) uri.setWkbType(QgsWkbTypes.LineString) layerEdge = QgsVectorLayer(uri.uri(False), u'%s.edge' % toponame, provider) edge_extent = layerEdge.extent() # directed edge uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid(toposrid) uri.setWkbType(QgsWkbTypes.LineString) layerDirectedEdge = QgsVectorLayer(uri.uri(False), u'%s.directed_edge' % toponame, provider) layerDirectedEdge.setExtent(edge_extent) layerDirectedEdge.loadNamedStyle(os.path.join(template_dir, 'edge.qml')) # edge labels uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid(toposrid) uri.setWkbType(QgsWkbTypes.LineString) layerEdgeLabel = QgsVectorLayer(uri.uri(False), u'%s.edge_id' % toponame, provider) layerEdgeLabel.setExtent(edge_extent) layerEdgeLabel.loadNamedStyle( os.path.join(template_dir, 'edge_label.qml')) # face_left uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid(toposrid) uri.setWkbType(QgsWkbTypes.LineString) layerFaceLeft = QgsVectorLayer(uri.uri(False), u'%s.face_left' % toponame, provider) layerFaceLeft.setExtent(edge_extent) layerFaceLeft.loadNamedStyle( os.path.join(template_dir, 'face_left.qml')) # face_right uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid(toposrid) uri.setWkbType(QgsWkbTypes.LineString) layerFaceRight = QgsVectorLayer(uri.uri(False), u'%s.face_right' % toponame, provider) layerFaceRight.setExtent(edge_extent) layerFaceRight.loadNamedStyle( os.path.join(template_dir, 'face_right.qml')) # next_left uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid(toposrid) uri.setWkbType(QgsWkbTypes.LineString) layerNextLeft = QgsVectorLayer(uri.uri(False), u'%s.next_left' % toponame, provider) layerNextLeft.setExtent(edge_extent) layerNextLeft.loadNamedStyle( os.path.join(template_dir, 'next_left.qml')) # next_right uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid(toposrid) uri.setWkbType(QgsWkbTypes.LineString) layerNextRight = QgsVectorLayer(uri.uri(False), u'%s.next_right' % toponame, provider) layerNextRight.setExtent(edge_extent) layerNextRight.loadNamedStyle( os.path.join(template_dir, 'next_right.qml')) # Add layers to the layer tree faceLayers = [layerFaceMbr, layerFaceGeom, layerFaceSeed] nodeLayers = [layerNode, layerNodeLabel] edgeLayers = [ layerEdge, layerDirectedEdge, layerEdgeLabel, layerEdgeFaceLeft, layerEdgeFaceRight, layerEdgeNextLeft, layerEdgeNextRight ] QgsProject.instance().addMapLayers(faceLayers, False) groupFaces = QgsLayerTreeGroup(u'Faces') for layer in faceLayers: nodeLayer = groupFaces.addLayer(layer) nodeLayer.setVisible(Qt.Unchecked) nodeLayer.setExpanded(False) groupNodes = QgsLayerTreeGroup(u'Nodes') for layer in faceLayers: nodeLayer = groupNodes.addLayer(layer) nodeLayer.setVisible(Qt.Unchecked) nodeLayer.setExpanded(False) groupEdges = QgsLayerTreeGroup(u'Edges') for layer in faceLayers: nodeLayer = groupEdges.addLayer(layer) nodeLayer.setVisible(Qt.Unchecked) nodeLayer.setExpanded(False) supergroup = QgsLayerTreeGroup(u'Topology "%s"' % toponame) supergroup.insertChildNodes(-1, [groupFaces, groupNodes, groupEdges]) QgsProject.instance().layerTreeRoot().addChildNode(supergroup) finally: # Set canvas extent to topology extent, if not yet initialized canvas = iface.mapCanvas() if (canvas.fullExtent().isNull()): ext = node_extent ext.combineExtentWith(edge_extent) # Grow by 1/20 of largest side ext = ext.buffer(max(ext.width(), ext.height()) / 20) canvas.setExtent(ext) # restore canvas render flag if not wasFrozen: iface.mapCanvas().freeze(False) return True
def test_interpolation_from_polygons_multiple(self): """Point interpolation using multiple polygons from Maumere works There's a test with the same name in test_engine.py not using QGIS API. This one deals correctly with holes in polygons, so the resulting numbers are a bit different. """ # Name file names for hazard and exposure hazard_filename = ('%s/tsunami_polygon_WGS84.shp' % TESTDATA) exposure_filename = ('%s/building_Maumere.shp' % TESTDATA) # Read input data H = QgsVectorLayer(hazard_filename, 'Hazard', 'ogr') E = QgsVectorLayer(exposure_filename, 'Exposure', 'ogr') # Test interpolation function I = interpolate_polygon_polygon(H, E, E.extent()) N = I.dataProvider().featureCount() assert N == E.dataProvider().featureCount() # Assert that expected attribute names exist I_names = [field.name() for field in I.dataProvider().fields()] for field in H.dataProvider().fields(): name = field.name() msg = 'Did not find hazard name "%s" in %s' % (name, I_names) assert name in I_names, msg for field in E.dataProvider().fields(): name = field.name() msg = 'Did not find exposure name "%s" in %s' % (name, I_names) assert name in I_names, msg # Verify interpolated values with test result counts = {} for f in I.getFeatures(): # Count items in each specific category category = f['Category'] if category not in counts: counts[category] = 0 counts[category] += 1 assert H.dataProvider().featureCount() == 1032 assert I.dataProvider().featureCount() == 3528 # The full version msg = ('Expected 2267 points tagged with category "High", ' 'but got only %i' % counts['High']) assert counts['High'] == 2267, msg msg = ('Expected 1179 points tagged with category "Very High", ' 'but got only %i' % counts['Very High']) assert counts['Very High'] == 1179, msg msg = ('Expected 2 points tagged with category "Medium" ' 'but got only %i' % counts['Medium']) assert counts['Medium'] == 2, msg msg = ('Expected 4 points tagged with category "Low" ' 'but got only %i' % counts['Low']) assert counts['Low'] == 4, msg msg = ('Expected 76 points tagged with no category ' 'but got only %i' % counts[None]) assert counts[None] == 76, msg
def add_layers_old_method(self): """ this method is depreceated and should no longer be used """ try: #newstyle MyGroup = self.legend.addGroup("Midvatten_OBS_DB", 1, -1) except: #olddstyle MyGroup = self.legend.addGroup("Midvatten_OBS_DB") uri = QgsDataSourceUri() uri.setDatabase( self.settingsdict['database'] ) #MacOSX fix1 #earlier sent byte string, now intending to send unicode string for tablename in self.default_nonspatlayers: # first the non-spatial tables, THEY DO NOT ALL HAVE CUSTOM UI FORMS firststring = 'dbname="' + self.settingsdict[ 'database'] + '" table="' + tablename + '"' #MacOSX fix1 #earlier sent byte string, now unicode layer = QgsVectorLayer( firststring, self.dbtype ) # Adding the layer as 'spatialite' and not ogr vector layer is preferred if not layer.isValid(): utils.MessagebarAndLog.critical( bar_msg='Error, Failed to load layer %s!' % tablename) else: QgsProject.instance().addMapLayers([layer]) group_index = self.legend.groups().index('Midvatten_OBS_DB') self.legend.moveLayer(self.legend.layers()[0], group_index) filename = tablename + ".qml" # load styles stylefile = os.path.join(os.sep, os.path.dirname(__file__), "..", "definitions", filename) layer.loadNamedStyle(stylefile) if tablename in ('w_levels', 'w_flow', 'stratigraphy'): if utils.getcurrentlocale( )[0] == 'sv_SE': #swedish forms are loaded only if locale settings indicate sweden filename = tablename + ".ui" else: filename = tablename + "_en.ui" try: # python bindings for setEditorLayout were introduced in qgis-master commit 9183adce9f257a097fc54e5a8a700e4d494b2962 november 2012 layer.setEditorLayout(2) except: pass uifile = os.path.join(os.sep, os.path.dirname(__file__), "..", "ui", filename) layer.setEditForm(uifile) formlogic = "form_logics." + tablename + "_form_open" layer.setEditFormInit(formlogic) for tablename in self.default_layers: # then the spatial ones, NOT ALL HAVE CUSTOM UI FORMS uri.setDataSource('', tablename, 'Geometry') layer = QgsVectorLayer( uri.uri(), self.dbtype ) # Adding the layer as 'spatialite' instead of ogr vector layer is preferred if not layer.isValid(): utils.MessagebarAndLog.critical( bar_msg='Error, Failed to load layer %s!' % tablename) else: filename = tablename + ".qml" stylefile = os.path.join(os.sep, os.path.dirname(__file__), "..", "definitions", filename) layer.loadNamedStyle(stylefile) if tablename in defs.get_subset_of_tables_fr_db( category='default_layers_w_ui' ): #= THE ONES WITH CUSTOM UI FORMS if utils.getcurrentlocale( )[0] == 'sv_SE': #swedish forms are loaded only if locale settings indicate sweden filename = tablename + ".ui" else: filename = tablename + "_en.ui" uifile = os.path.join(os.sep, os.path.dirname(__file__), "..", "ui", filename) try: # python bindings for setEditorLayout were introduced in qgis-master commit 9183adce9f257a097fc54e5a8a700e4d494b2962 november 2012 layer.setEditorLayout(2) except: pass layer.setEditForm(uifile) if tablename in ('obs_points', 'obs_lines'): formlogic = "form_logics." + tablename + "_form_open" layer.setEditFormInit(formlogic) QgsProject.instance().addMapLayers([layer]) group_index = self.legend.groups().index( 'Midvatten_OBS_DB') # SIPAPI UPDATE 2.0 self.legend.moveLayer(self.legend.layers()[0], group_index) if tablename == 'obs_points': #zoom to obs_points extent qgis.utils.iface.mapCanvas().setExtent(layer.extent()) elif tablename == 'w_lvls_last_geom': #we do not want w_lvls_last_geom to be visible by default self.legend.setLayerVisible(layer, False)
def testExtentFromGeometryTable(self): """ Check if the behavior of the mssql provider if extent is defined in the geometry_column table """ # Create a layer layer = QgsVectorLayer( "Point?field=id:integer&field=fldtxt:string&field=fldint:integer", "layer", "memory") pr = layer.dataProvider() f1 = QgsFeature() f1.setAttributes([1, "test", 1]) f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2))) f2 = QgsFeature() f2.setAttributes([2, "test2", 3]) f3 = QgsFeature() f3.setAttributes([3, "test2", NULL]) f3.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(3, 2))) f4 = QgsFeature() f4.setAttributes([4, NULL, 3]) f4.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(4, 3))) pr.addFeatures([f1, f2, f3, f4]) uri = '{} table="qgis_test"."layer_extent_in_geometry_table" sql='.format( self.dbconn) QgsVectorLayerExporter.exportLayer( layer, uri, 'mssql', QgsCoordinateReferenceSystem('EPSG:4326')) layerUri = QgsDataSourceUri(uri) # Load and check if the layer is valid loadedLayer = QgsVectorLayer(layerUri.uri(), "valid", "mssql") self.assertTrue(loadedLayer.isValid()) extent = loadedLayer.extent() self.assertEqual(extent.toString(1), QgsRectangle(1.0, 2.0, 4.0, 3.0).toString(1)) # Load with flag extent in geometry_columns table and check if the layer is still valid and extent doesn't change layerUri.setParam('extentInGeometryColumns', '1') loadedLayer = QgsVectorLayer(layerUri.uri(), "invalid", "mssql") self.assertTrue(loadedLayer.isValid()) extent = loadedLayer.extent() self.assertEqual(extent.toString(1), QgsRectangle(1.0, 2.0, 4.0, 3.0).toString(1)) md = QgsProviderRegistry.instance().providerMetadata('mssql') conn = md.createConnection(self.dbconn, {}) conn.addField(QgsField('qgis_xmin', QVariant.Double, 'FLOAT(24)'), 'dbo', 'geometry_columns') conn.addField(QgsField('qgis_xmax', QVariant.Double, 'FLOAT(24)'), 'dbo', 'geometry_columns') conn.addField(QgsField('qgis_ymin', QVariant.Double, 'FLOAT(24)'), 'dbo', 'geometry_columns') conn.addField(QgsField('qgis_ymax', QVariant.Double, 'FLOAT(24)'), 'dbo', 'geometry_columns') # try with empty attribute layerUri.setParam('extentInGeometryColumns', '1') loadedLayer = QgsVectorLayer(layerUri.uri(), "invalid", "mssql") self.assertTrue(loadedLayer.isValid()) self.assertTrue(loadedLayer.isValid()) extent = loadedLayer.extent() self.assertEqual(extent.toString(1), QgsRectangle(1.0, 2.0, 4.0, 3.0).toString(1)) conn.execSql( 'UPDATE dbo.geometry_columns SET qgis_xmin=0, qgis_xmax=5.5, qgis_ymin=0.5, qgis_ymax=6 WHERE f_table_name=\'layer_extent_in_geometry_table\'' ) # try with valid attribute layerUri.setParam('extentInGeometryColumns', '1') loadedLayer = QgsVectorLayer(layerUri.uri(), "valid", "mssql") self.assertTrue(loadedLayer.isValid()) extent = loadedLayer.extent() self.assertEqual(extent.toString(1), QgsRectangle(0.0, 0.5, 5.5, 6.0).toString(1))
def run(item, action, mainwindow): db = item.database() uri = db.uri() iface = mainwindow.iface quoteId = db.connector.quoteId quoteStr = db.connector.quoteString # check if the selected item is a topology schema isTopoSchema = False if not hasattr(item, 'schema'): mainwindow.infoBar.pushMessage("Invalid topology", u'Select a topology schema to continue.', QgsMessageBar.INFO, mainwindow.iface.messageTimeout()) return False if item.schema() is not None: sql = u"SELECT srid FROM topology.topology WHERE name = %s" % quoteStr(item.schema().name) c = db.connector._get_cursor() db.connector._execute( c, sql ) res = db.connector._fetchone( c ) isTopoSchema = res is not None if not isTopoSchema: mainwindow.infoBar.pushMessage("Invalid topology", u'Schema "{0}" is not registered in topology.topology.'.format(item.schema().name), QgsMessageBar.WARNING, mainwindow.iface.messageTimeout()) return False toposrid = str(res[0]) # load layers into the current project toponame = item.schema().name template_dir = os.path.join(current_path, 'templates') registry = QgsMapLayerRegistry.instance() legend = iface.legendInterface() # do not refresh the canvas until all the layers are added prevRenderFlagState = iface.mapCanvas().renderFlag() iface.mapCanvas().setRenderFlag( False ) try: supergroup = legend.addGroup(u'Topology "%s"' % toponame, False) provider = db.dbplugin().providerName() uri = db.uri() # FACES group = legend.addGroup(u'Faces', False, supergroup) # face mbr uri.setDataSource(toponame, 'face', 'mbr', '', 'face_id') uri.setSrid( toposrid ) uri.setWkbType( QGis.WKBPolygon ) layer = QgsVectorLayer(uri.uri(), u'%s.face_mbr' % toponame, provider) layer.loadNamedStyle(os.path.join(template_dir, 'face_mbr.qml')) registry.addMapLayers([layer]) legend.moveLayer(layer, group) legend.setLayerVisible(layer, False) legend.setLayerExpanded(layer, False) face_extent = layer.extent() # face geometry sql = u'SELECT face_id, topology.ST_GetFaceGeometry(%s, face_id) as geom ' \ 'FROM %s.face WHERE face_id > 0' % (quoteStr(toponame), quoteId(toponame)) uri.setDataSource('', u'(%s\n)' % sql, 'geom', '', 'face_id') uri.setSrid( toposrid ) uri.setWkbType( QGis.WKBPolygon ) layer = QgsVectorLayer(uri.uri(), u'%s.face' % toponame, provider) layer.setExtent(face_extent) layer.loadNamedStyle(os.path.join(template_dir, 'face.qml')) registry.addMapLayers([layer]) legend.moveLayer(layer, group) legend.setLayerVisible(layer, False) legend.setLayerExpanded(layer, False) # face_seed sql = u'SELECT face_id, ST_PointOnSurface(topology.ST_GetFaceGeometry(%s, face_id)) as geom ' \ 'FROM %s.face WHERE face_id > 0' % (quoteStr(toponame), quoteId(toponame)) uri.setDataSource('', u'(%s)' % sql, 'geom', '', 'face_id') uri.setSrid( toposrid ) uri.setWkbType( QGis.WKBPoint ) layer = QgsVectorLayer(uri.uri(), u'%s.face_seed' % toponame, provider) layer.setExtent(face_extent) layer.loadNamedStyle(os.path.join(template_dir, 'face_seed.qml')) registry.addMapLayers([layer]) legend.moveLayer(layer, group) legend.setLayerVisible(layer, False) legend.setLayerExpanded(layer, False) # TODO: add polygon0, polygon1 and polygon2 ? # NODES group = legend.addGroup(u'Nodes', False, supergroup) # node uri.setDataSource(toponame, 'node', 'geom', '', 'node_id') uri.setSrid( toposrid ) uri.setWkbType( QGis.WKBPoint ) layer = QgsVectorLayer(uri.uri(), u'%s.node' % toponame, provider) layer.loadNamedStyle(os.path.join(template_dir, 'node.qml')) registry.addMapLayers([layer]) legend.moveLayer(layer, group) legend.setLayerVisible(layer, False) legend.setLayerExpanded(layer, False) node_extent = layer.extent() # node labels uri.setDataSource(toponame, 'node', 'geom', '', 'node_id') uri.setSrid( toposrid ) uri.setWkbType( QGis.WKBPoint ) layer = QgsVectorLayer(uri.uri(), u'%s.node_id' % toponame, provider) layer.setExtent(node_extent) layer.loadNamedStyle(os.path.join(template_dir, 'node_label.qml')) registry.addMapLayers([layer]) legend.moveLayer(layer, group) legend.setLayerVisible(layer, False) legend.setLayerExpanded(layer, False) # EDGES group = legend.addGroup(u'Edges', False, supergroup) # edge uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid( toposrid ) uri.setWkbType( QGis.WKBLineString ) layer = QgsVectorLayer(uri.uri(), u'%s.edge' % toponame, provider) registry.addMapLayers([layer]) legend.moveLayer(layer, group) legend.setLayerVisible(layer, False) legend.setLayerExpanded(layer, False) edge_extent = layer.extent() # directed edge uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid( toposrid ) uri.setWkbType( QGis.WKBLineString ) layer = QgsVectorLayer(uri.uri(), u'%s.directed_edge' % toponame, provider) layer.setExtent(edge_extent) layer.loadNamedStyle(os.path.join(template_dir, 'edge.qml')) registry.addMapLayers([layer]) legend.moveLayer(layer, group) legend.setLayerVisible(layer, False) legend.setLayerExpanded(layer, False) # edge labels uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid( toposrid ) uri.setWkbType( QGis.WKBLineString ) layer = QgsVectorLayer(uri.uri(), u'%s.edge_id' % toponame, provider) layer.setExtent(edge_extent) layer.loadNamedStyle(os.path.join(template_dir, 'edge_label.qml')) registry.addMapLayers([layer]) legend.moveLayer(layer, group) legend.setLayerVisible(layer, False) legend.setLayerExpanded(layer, False) # face_left uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid( toposrid ) uri.setWkbType( QGis.WKBLineString ) layer = QgsVectorLayer(uri.uri(), u'%s.face_left' % toponame, provider) layer.setExtent(edge_extent) layer.loadNamedStyle(os.path.join(template_dir, 'face_left.qml')) registry.addMapLayers([layer]) legend.moveLayer(layer, group) legend.setLayerVisible(layer, False) legend.setLayerExpanded(layer, False) # face_right uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid( toposrid ) uri.setWkbType( QGis.WKBLineString ) layer = QgsVectorLayer(uri.uri(), u'%s.face_right' % toponame, provider) layer.setExtent(edge_extent) layer.loadNamedStyle(os.path.join(template_dir, 'face_right.qml')) registry.addMapLayers([layer]) legend.moveLayer(layer, group) legend.setLayerVisible(layer, False) legend.setLayerExpanded(layer, False) # next_left uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid( toposrid ) uri.setWkbType( QGis.WKBLineString ) layer = QgsVectorLayer(uri.uri(), u'%s.next_left' % toponame, provider) layer.setExtent(edge_extent) layer.loadNamedStyle(os.path.join(template_dir, 'next_left.qml')) registry.addMapLayers([layer]) legend.moveLayer(layer, group) legend.setLayerVisible(layer, False) legend.setLayerExpanded(layer, False) # next_right uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id') uri.setSrid( toposrid ) uri.setWkbType( QGis.WKBLineString ) layer = QgsVectorLayer(uri.uri(), u'%s.next_right' % toponame, provider) layer.setExtent(edge_extent) layer.loadNamedStyle(os.path.join(template_dir, 'next_right.qml')) registry.addMapLayers([layer]) legend.moveLayer(layer, group) legend.setLayerVisible(layer, False) legend.setLayerExpanded(layer, False) finally: # restore canvas render flag iface.mapCanvas().setRenderFlag( prevRenderFlagState ) return True
def my_shortest_path(pointTool): try: #reading the coordinate of the points clicked #and writing in a string format to call shortest path algorithm startPoint = str(pointTool.x()) + "," + str( pointTool.y()) + " [EPSG:4326-WGS84]" endPoint = "144.963403,-37.808179 [EPSG:4326-WGS84]" #coordinate of RMIT #path to the road network data (please change accordingly) roads_path = r"/Users/chhanda/Desktop/GIS_Programming/Major_project/Street_network_2018/shp/road.shp" #set outputfile directory outputfilepath = r"Users/chhanda/Desktop/GIS_Programming/Major_project/" #setting up the shortest path parameters shortestpathParam = { 'DEFAULT_DIRECTION': 2, 'DEFAULT_SPEED': 50, 'DIRECTION_FIELD': None, 'END_POINT': endPoint, 'ENTRY_COST_CALCULATION_METHOD': 0, 'INPUT': roads_path, 'OUTPUT': outputfilepath + "shortestpath_output", 'SPEED_FIELD': None, 'START_POINT': startPoint, 'STRATEGY': 0, 'TOLERANCE': 0, 'VALUE_BACKWARD': '', 'VALUE_BOTH': '', 'VALUE_FORWARD': '' } processing.run("qneat3:shortestpathpointtopoint", shortestpathParam) #loading the shortest path layer from the poutput of the previous processing run sp_file_path = outputfilepath + "shortestpath_output.gpkg" sp_layer = QgsVectorLayer(sp_file_path, "shortest_path", "ogr") if not sp_layer.isValid(): print("Shortest Path Layer failed to load!") #loading road network layer road_layer = QgsVectorLayer(roads_path, "roads", "ogr") if not road_layer.isValid(): print("road Layer failed to load!") #setting the url of the base layer from ESRI base_layer = QgsRasterLayer( "http://server.arcgisonline.com/arcgis/rest/services/ESRI_Imagery_World_2D/MapServer?f=json&pretty=true", "raster") #styling the shortest path layer (color and line width) sp_layer.renderer().symbol().setWidth(0.6) sp_layer.renderer().symbol().setColor(QColor("red")) #creating a point layer to show the start point and the end point point_layer = QgsVectorLayer("Point", "temporary_points", "memory") pr = point_layer.dataProvider() #enter editing mode point_layer.startEditing() #add a field to display the labels pr.addAttributes([QgsField("name", QVariant.String)]) point_layer.updateFields() #add features fet = QgsFeature() fet.setGeometry( QgsGeometry.fromPointXY(QgsPointXY(pointTool.x(), pointTool.y()))) pr.addFeatures([fet]) point_layer.changeAttributeValue(1, 0, "Your Home") fet.setGeometry( QgsGeometry.fromPointXY(QgsPointXY(144.963403, -37.808179))) pr.addFeatures([fet]) point_layer.changeAttributeValue(2, 0, "RMIT UNIVERSITY") # Commit changes point_layer.commitChanges() #styling the point layer (size and color) point_layer.renderer().symbol().setSize(6) point_layer.renderer().symbol().setColor(QColor("red")) #styling the labels to make them appear with white background layer_settings = QgsPalLayerSettings() text_format = QgsTextFormat() background_color = QgsTextBackgroundSettings() background_color.setFillColor(QColor('white')) background_color.setEnabled(True) text_format.setFont(QFont("Arial", 12)) text_format.setSize(12) text_format.setBackground(background_color) buffer_settings = QgsTextBufferSettings() buffer_settings.setEnabled(True) buffer_settings.setSize(0.10) buffer_settings.setColor(QColor("black")) text_format.setBuffer(buffer_settings) layer_settings.setFormat(text_format) layer_settings.fieldName = "name" layer_settings.placement = 4 layer_settings.enabled = True layer_settings = QgsVectorLayerSimpleLabeling(layer_settings) point_layer.setLabelsEnabled(True) point_layer.setLabeling(layer_settings) #initialising an output fgrame output_canvas = QgsMapCanvas() #chosing the layers to display output_canvas.setLayers([sp_layer, point_layer, base_layer]) #getting the extent of the shortest path layer to zoom into the path ext = sp_layer.extent() xmin = ext.xMinimum() xmax = ext.xMaximum() ymin = ext.yMinimum() ymax = ext.yMaximum() #setting extent of the output to that of a box slightly larger than the shortest path layer #such that the labels don't get chopped output_canvas.setExtent( QgsRectangle(xmin - 0.01, ymin - 0.01, xmax + 0.01, ymax + 0.01)) output_canvas.show() #the function raises an error because eiting without error causes the output window to disappear raise except AttributeError: pass
text_format.setSize(12) text_format.setBackground(background_color) buffer_settings = QgsTextBufferSettings() buffer_settings.setEnabled(True) buffer_settings.setSize(0.10) buffer_settings.setColor(QColor("black")) text_format.setBuffer(buffer_settings) layer_settings.setFormat(text_format) layer_settings.fieldName = "name" layer_settings.placement = 4 layer_settings.enabled = True layer_settings = QgsVectorLayerSimpleLabeling(layer_settings) point_layer.setLabelsEnabled(True) point_layer.setLabeling(layer_settings) #creating a window to display the map of Melbourne and the RMIT location canvas = QgsMapCanvas() canvas.setLayers([point_layer, base_layer]) canvas.setExtent(road_layer.extent()) canvas.show() #setup click trigger to capture the clicked location and then call the shortest path calculator function pointTool = QgsMapToolEmitPoint(canvas) pointTool.canvasClicked.connect(my_shortest_path) canvas.setMapTool(pointTool)
class Layer: ''' wrapper of a vector layer in the QGIS layer tree with some convenient functions. Can be grouped and addressed by its name. ''' def __init__(self, layername: str, data_path: str, groupname: str = '', prepend: bool = True): ''' Parameters ---------- layername : str name of the layer in the data source data_path : str path to the data source of the layer groupname : str, optional name of the parent group, will be created if not existing, can be nested by joining groups with '/' e.g. 'Projekt/Hintergrundkarten', defaults to add layer to the root of the layer tree prepend : bool prepend the group of the layer if True (prepends each group if nested), append if False, defaults to prepending the group ''' self.layername = layername self.data_path = data_path self.layer = None self._l = None self.groupname = groupname self.prepend = prepend @property def parent(self) -> QgsLayerTreeGroup: ''' the parent group of the layer ''' parent = QgsProject.instance().layerTreeRoot() if self.groupname: parent = Layer.add_group(self.groupname, prepend=self.prepend) return parent @property def _tree_layer(self) -> QgsLayerTreeLayer: ''' tree representation of the layer ''' if not self.layer: return None return self.parent.findLayer(self.layer) @property def layer(self) -> QgsVectorLayer: ''' the wrapped vector layer ''' try: layer = self._layer if layer is not None: # call function on layer to check if it still exists layer.id() except RuntimeError: return None return layer @layer.setter def layer(self, layer: QgsVectorLayer): self._layer = layer @classmethod def add_group(cls, groupname: str, prepend: bool = True) -> QgsLayerTreeGroup: ''' add a group to the layer tree Parameters ---------- groupname : str name of the parent group, will be created if not existing, can be nested by joining groups with '/' e.g. 'Projekt/Hintergrundkarten' prepend : bool, optional prepend the group if True (prepends each group if nested), append if False, defaults to prepending the group Returns ---------- QgsLayerTreeGroup the created group (the deepest one in hierarchy if nested) ''' groupnames = groupname.split('/') parent = QgsProject.instance().layerTreeRoot() group = cls._nest_groups(parent, groupnames, prepend=prepend) return group @classmethod def _nest_groups(cls, parent: QgsLayerTreeGroup, groupnames: List[str], prepend: bool = True) -> QgsLayerTreeGroup: '''recursively nests groups in order of groupnames''' if len(groupnames) == 0: return parent next_parent = parent.findGroup(groupnames[0]) if not next_parent: next_parent = (parent.insertGroup(0, groupnames[0]) if prepend else parent.addGroup(groupnames[0])) return cls._nest_groups(next_parent, groupnames[1:], prepend=prepend) @classmethod def find(cls, label: str, groupname: str = '') -> List[QgsLayerTreeLayer]: ''' deep find tree layer by name in a group recursively Parameters ---------- label : str label of the tree layer groupname : str, optional name of the group to search in, can be nested by joining groups with '/' e.g. 'Projekt/Hintergrundkarten', defaults to searching in layer tree root Returns ---------- list list of tree layers matching the name, empty list if none found ''' parent = QgsProject.instance().layerTreeRoot() if groupname: groupnames = groupname.split('/') while groupnames: g = groupnames.pop(0) parent = parent.findGroup(g) if not parent: return [] def deep_find(node, label): found = [] if node: for child in node.children(): if child.name() == label: found.append(child) found.extend(deep_find(child, label)) return found found = deep_find(parent, label) return found def draw(self, style_path: str = None, label: str = '', redraw: str = True, checked: bool = True, filter: str = None, expanded: bool = True, prepend: bool = False) -> QgsVectorLayer: ''' load the data into a vector layer, draw it and add it to the layer tree Parameters ---------- label : str, optional label of the layer, defaults to layer name this is initialized with style_path : str, optional a QGIS style (.qml) can be applied to the layer, defaults to no style redraw : bool, optional replace old layer with same name in same group if True, only create if not existing if set to False, else it is refreshed, defaults to redrawing the layer checked: bool, optional set check state of layer in layer tree, defaults to being checked filter: str, optional QGIS filter expression to filter the layer, defaults to no filtering expanded: str, optional sets the legend to expanded or not, defaults to an expanded legend prepend: bool, optional prepend the layer to the other layers in its group if True, append it if False, defaults to appending the layer Returns ---------- QgsVectorLayer the created, replaced or refreshed vector layer ''' if not self.layer: layers = Layer.find(label, groupname=self.groupname) if layers: self.layer = layers[0].layer() if redraw: self.remove() else: iface.mapCanvas().refreshAllLayers() if not self.layer: self.layer = QgsVectorLayer(self.data_path, self.layername, "ogr") if label: self.layer.setName(label) QgsProject.instance().addMapLayer(self.layer, False) self.layer.loadNamedStyle(style_path) tree_layer = self._tree_layer if not tree_layer: tree_layer = self.parent.insertLayer(0, self.layer) if prepend else\ self.parent.addLayer(self.layer) tree_layer.setItemVisibilityChecked(checked) tree_layer.setExpanded(expanded) if filter is not None: self.layer.setSubsetString(filter) return self.layer def set_visibility(self, state: bool): ''' change check state of layer, layer is not visible if unchecked Parameters ---------- state: bool set check state of layer in layer tree ''' tree_layer = self._tree_layer if tree_layer: tree_layer.setItemVisibilityChecked(state) def zoom_to(self): ''' zooms map canvas to the extent of this layer ''' if not self.layer: return canvas = iface.mapCanvas() self.layer.updateExtents() transform = QgsCoordinateTransform( self.layer.crs(), canvas.mapSettings().destinationCrs(), QgsProject.instance()) canvas.setExtent(transform.transform(self.layer.extent())) def remove(self): ''' remove the layer from map and layer tree ''' if not self.layer: return QgsProject.instance().removeMapLayer(self.layer.id()) self.layer = None
class VisuValideMultiCriteriaMatching: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor.""" # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # Create the dialog (after translation) and keep reference self.pluginIsActive = False self.dockwidget = None # Declare instance attributes self.actions = [] self.menu = "Visualisation et validation de l'appariement" # We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar( u'VisuValideMultiCriteriaMatching') self.toolbar.setObjectName(u'VisuValideMultiCriteriaMatching') def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar.""" icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/VisuValideMultiCriteriaMatching/img/match.png' self.add_action( icon_path, text="Panneau de contrôle pour visualiser et valider l'appariement", callback=self.initWidget, parent=self.iface.mainWindow()) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu('&VisuValideMultiCriteriaMatching', action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar # remove layer ? def onClosePlugin(self): """Cleanup necessary items here when plugin dockwidget is closed""" # disconnects self.pluginIsActive = False # On recharge pour repartir #self.reload() # On supprime les layers de la fenêtre self.vider() # On ferme self.dockwidget.close() def vider(self): # ---------------------------------------------------------------------------- # supprime les layers if self.layerCOMP != None: QgsProject.instance().removeMapLayers([self.layerCOMP.id()]) if self.layerREF != None: QgsProject.instance().removeMapLayers([self.layerREF.id()]) def initWidget(self): """Run method that performs all the real work""" if not self.pluginIsActive: self.pluginIsActive = True if self.dockwidget == None: self.dockwidget = VisuResultatDialog() self.layerCOMP = None self.layerREF = None self.dockwidget.btPrec.setStyleSheet( 'color : black;font: 8pt MS Shell Dlg 2') self.dockwidget.btSuiv.setStyleSheet( 'color : black;font: 8pt MS Shell Dlg 2') self.dockwidget.currentId.setStyleSheet( 'color : black;font: 8pt MS Shell Dlg 2') self.dockwidget.fileResultat.setStyleSheet( 'color : black;font: 8pt MS Shell Dlg 2') self.dockwidget.btSuiv.clicked.connect(self.doSuivant) self.dockwidget.btPrec.clicked.connect(self.doPrecedent) self.dockwidget.currentId.setDisabled(True) self.dockwidget.currentId.setText("-1") self.dockwidget.btFermer.clicked.connect(self.onClosePlugin) self.dockwidget.btZoomGrille.clicked.connect(self.zoom) self.dockwidget.fileResultat.fileChanged.connect( self.importFichier) self.dockwidget.rbID.toggled.connect(self.visuDistance) self.dockwidget.rbD1.toggled.connect(self.visuDistance) self.dockwidget.rbD2.toggled.connect(self.visuDistance) self.dockwidget.rbD3.toggled.connect(self.visuDistance) self.dockwidget.rbD4.toggled.connect(self.visuDistance) self.dockwidget.rbD5.toggled.connect(self.visuDistance) self.iface.mapCanvas().refresh() # show the dockwidget self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget) self.dockwidget.show() def importFichier(self): # On supprime les layers car on va les recreer self.vider() # On charge le chemin du fichier de résultat self.uriGrille = self.dockwidget.fileResultat.filePath().strip() # print (self.uriGrille) # On ouvre le fichier pour le type de la géométrie et les distances self.DISTANCE_NOM = [] self.ATTRS_NOM = [] self.CRITERE_SEUIL = [] self.TYPE_GEOM = '' self.seuilIndecision = -1 (DISTANCE_NOM, ATTRS_NOM, TYPE_GEOM, CRITERE_SEUIL, seuilIndecision) = util.entete(self.uriGrille) self.DISTANCE_NOM = DISTANCE_NOM self.ATTRS_NOM = ATTRS_NOM self.TYPE_GEOM = TYPE_GEOM self.CRITERE_SEUIL = CRITERE_SEUIL self.seuilIndecision = seuilIndecision self.dockwidget.seuilP.setText(str(self.seuilIndecision)) # self.dockwidget.seuilP.setEnabled(False) #self.dockwidget.pign1.setEnabled(False) #self.dockwidget.pign2.setEnabled(False) self.dockwidget.currentId.setText("-1") self.createLayerComp() self.createLayerRef() self.dockwidget.labelSeuil1.setEnabled(False) self.dockwidget.D1_T1.setEnabled(False) self.dockwidget.D1_T2.setEnabled(False) self.dockwidget.labelSeuil2.setEnabled(False) self.dockwidget.D2_T1.setEnabled(False) self.dockwidget.D2_T2.setEnabled(False) self.dockwidget.labelSeuil3.setEnabled(False) self.dockwidget.D3_T1.setEnabled(False) self.dockwidget.D3_T2.setEnabled(False) self.dockwidget.labelSeuil4.setEnabled(False) self.dockwidget.D4_T1.setEnabled(False) self.dockwidget.D4_T2.setEnabled(False) self.dockwidget.labelSeuil5.setEnabled(False) self.dockwidget.D5_T1.setEnabled(False) self.dockwidget.D5_T2.setEnabled(False) # print (self.DISTANCE_NOM) # print (self.CRITERE_SEUIL) self.dockwidget.rbD1.setEnabled(False) self.dockwidget.rbD2.setEnabled(False) self.dockwidget.rbD3.setEnabled(False) self.dockwidget.rbD4.setEnabled(False) self.dockwidget.rbD5.setEnabled(False) for i in range(len(self.DISTANCE_NOM)): if i == 0: self.dockwidget.labelSeuil1.setEnabled(True) self.dockwidget.D1_T1.setEnabled(True) self.dockwidget.D1_T2.setEnabled(True) seuils = self.CRITERE_SEUIL[i] if len(seuils) > 0: self.dockwidget.D1_T1.setText(seuils[0]) if len(seuils) > 1: self.dockwidget.D1_T2.setText(seuils[1]) else: self.dockwidget.D1_T2.setEnabled(False) self.dockwidget.rbD1.setEnabled(True) if i == 1: self.dockwidget.labelSeuil2.setEnabled(True) self.dockwidget.D2_T1.setEnabled(True) self.dockwidget.D2_T2.setEnabled(True) seuils = self.CRITERE_SEUIL[i] if len(seuils) > 0: self.dockwidget.D2_T1.setText(seuils[0]) if len(seuils) > 1: self.dockwidget.D2_T2.setText(seuils[1]) else: self.dockwidget.D2_T2.setEnabled(False) self.dockwidget.rbD2.setEnabled(True) if i == 2: self.dockwidget.labelSeuil3.setEnabled(True) self.dockwidget.D3_T1.setEnabled(True) self.dockwidget.D3_T2.setEnabled(True) seuils = self.CRITERE_SEUIL[i] if len(seuils) > 0: self.dockwidget.D3_T1.setText(seuils[0]) if len(seuils) > 1: self.dockwidget.D3_T2.setText(seuils[1]) else: self.dockwidget.D3_T2.setEnabled(False) self.dockwidget.rbD3.setEnabled(True) if i == 3: self.dockwidget.labelSeuil4.setEnabled(True) self.dockwidget.D4_T1.setEnabled(True) self.dockwidget.D4_T2.setEnabled(True) seuils = self.CRITERE_SEUIL[i] if len(seuils) > 0: self.dockwidget.D4_T1.setText(seuils[0]) if len(seuils) > 1: self.dockwidget.D4_T2.setText(seuils[1]) else: self.dockwidget.D4_T2.setEnabled(False) self.dockwidget.rbD4.setEnabled(True) if i == 4: self.dockwidget.labelSeuil5.setEnabled(True) self.dockwidget.D5_T1.setEnabled(True) self.dockwidget.D5_T2.setEnabled(True) seuils = self.CRITERE_SEUIL[i] if len(seuils) > 0: self.dockwidget.D5_T1.setText(seuils[0]) if len(seuils) > 1: self.dockwidget.D5_T2.setText(seuils[1]) else: self.dockwidget.D5_T2.setEnabled(False) self.dockwidget.rbD5.setEnabled(True) def createLayerRef(self): # ====================================================================================== # Layer IGN self.layerREF = QgsVectorLayer(self.TYPE_GEOM + "?crs=epsg:2154", "REF", "memory") if self.TYPE_GEOM == 'Polygon' or self.TYPE_GEOM == 'MultiPolygon': self.layerREF = style.getRefPolygoneStyle(self.layerREF) if self.TYPE_GEOM == 'Point' or self.TYPE_GEOM == 'MultiPoint': self.layerREF = style.getRefPointStyle(self.layerREF) QgsProject.instance().addMapLayer(self.layerREF) def createLayerComp(self): # ====================================================================================== # Layer OSM self.layerCOMP = QgsVectorLayer(self.TYPE_GEOM + "?crs=epsg:2154", "COMP", "memory") # Eventuellement si vous voulez ajouter des attributs pr = self.layerCOMP.dataProvider() pr.addAttributes([QgsField("position", QVariant.String)]) for i in range(len(self.ATTRS_NOM)): pr.addAttributes([QgsField(self.ATTRS_NOM[i], QVariant.String)]) for i in range(len(self.DISTANCE_NOM)): if i == 0: pr.addAttributes( [QgsField(self.DISTANCE_NOM[i], QVariant.Double)]) if i == 1: pr.addAttributes( [QgsField(self.DISTANCE_NOM[i], QVariant.Double)]) if i == 2: pr.addAttributes( [QgsField(self.DISTANCE_NOM[i], QVariant.Double)]) if i == 3: pr.addAttributes( [QgsField(self.DISTANCE_NOM[i], QVariant.Double)]) if i == 4: pr.addAttributes( [QgsField(self.DISTANCE_NOM[i], QVariant.Double)]) self.layerCOMP.commitChanges() if self.TYPE_GEOM == 'Polygon' or self.TYPE_GEOM == 'MultiPolygon': self.layerCOMP = style.getCompPolygoneStyle( self.layerCOMP, 'position') if self.TYPE_GEOM == 'Point' or self.TYPE_GEOM == 'MultiPoint': self.layerCOMP = style.getCompPointStyle(self.layerCOMP) QgsProject.instance().addMapLayer(self.layerCOMP) def afficheContexte(self, currId): self.removeFeatures() candList = util.getCandidat(self.uriGrille, currId, self.DISTANCE_NOM, self.ATTRS_NOM) # print (len(candList)) if len(candList) > 0: candidat = candList[1] # ====================================================================================== # Layer REF pr = self.layerREF.dataProvider() self.layerREF.startEditing() poly = QgsFeature() poly.setGeometry(QgsGeometry.fromWkt(candidat['geomref'])) pr.addFeatures([poly]) # Sauvegarde les changements self.layerREF.commitChanges() # ====================================================================================== # Layer OSM pr = self.layerCOMP.dataProvider() self.layerCOMP.startEditing() for i in range(len(candList)): if i > 0: poly = QgsFeature() candidat = candList[i] poly.setGeometry(QgsGeometry.fromWkt(candidat['geomcomp'])) attrs = [] attrs.append(str(candidat['id'])) for j in range(len(self.ATTRS_NOM)): nom = self.ATTRS_NOM[j] attrs.append(candidat[nom]) for i in range(len(self.DISTANCE_NOM)): nom = self.DISTANCE_NOM[i] s = float(candidat[nom]) #print (s) attrs.append(s) poly.setAttributes(attrs) pr.addFeatures([poly]) # Sauvegarde les changements self.layerCOMP.commitChanges() # Zoom self.zoom() # remplir le tableau self.initTable(candList) def zoom(self): # ZOOM extent = self.layerCOMP.extent() self.iface.mapCanvas().setExtent(extent) self.iface.mapCanvas().refresh() def doPrecedent(self): # On recupere l'id en cours currId = self.dockwidget.currentId.text() id = util.getLignePrec(self.uriGrille, currId) self.dockwidget.currentId.setText(str(id)) self.afficheContexte(id) def doSuivant(self): # On recupere l'id en cours currId = self.dockwidget.currentId.text() id = util.getLigneSuiv(self.uriGrille, currId) self.dockwidget.currentId.setText(str(id)) self.afficheContexte(id) def removeFeatures(self): self.layerREF.startEditing() for feature in self.layerREF.getFeatures(): self.layerREF.deleteFeature(feature.id()) # commit to stop editing the layer self.layerREF.commitChanges() # =========================================== self.layerCOMP.startEditing() for feature in self.layerCOMP.getFeatures(): self.layerCOMP.deleteFeature(feature.id()) # commit to stop editing the layer self.layerCOMP.commitChanges() def initTable(self, candList): self.vide(self.dockwidget.tableCoordFeu) if (len(candList)) == 0: self.dockwidget.tableCoordFeu.setRowCount(0) self.dockwidget.tableCoordFeu.setColumnCount(0) else: orange = QColor(255, 196, 109) vert = QColor(0, 255, 0) nbApp = 0 nbNonApp = 0 nbIndecis = 0 labelRes = '' pign1 = '' pign2 = '' for i in range(len(candList)): candidat = candList[i] # On ajoute les coordonnées au tableau n = self.dockwidget.tableCoordFeu.rowCount() self.dockwidget.tableCoordFeu.insertRow(n) item1 = QTableWidgetItem(str(candidat['id'])) self.dockwidget.tableCoordFeu.setItem(n, 0, item1) for i in range(len(self.ATTRS_NOM)): nom = self.ATTRS_NOM[i] itemDistance = QTableWidgetItem(str(candidat[nom])) self.dockwidget.tableCoordFeu.setItem( n, 1 + i, itemDistance) for i in range(len(self.DISTANCE_NOM)): nom = self.DISTANCE_NOM[i] itemDistance = QTableWidgetItem(str(candidat[nom])) self.dockwidget.tableCoordFeu.setItem( n, 1 + len(self.ATTRS_NOM) + i, itemDistance) s = float(candidat[nom]) if i == 0: if self.dockwidget.D1_T1.isEnabled(): seuil1 = float(self.dockwidget.D1_T1.text()) if self.dockwidget.D1_T2.isEnabled(): seuil2 = float(self.dockwidget.D1_T2.text()) if i == 1: if self.dockwidget.D2_T1.isEnabled(): seuil1 = float(self.dockwidget.D2_T1.text()) if self.dockwidget.D2_T2.isEnabled(): seuil2 = float(self.dockwidget.D2_T2.text()) if i == 2: if self.dockwidget.D3_T1.isEnabled(): seuil1 = float(self.dockwidget.D3_T1.text()) if self.dockwidget.D3_T2.isEnabled(): seuil2 = float(self.dockwidget.D3_T2.text()) if i == 3: if self.dockwidget.D4_T1.isEnabled(): seuil1 = float(self.dockwidget.D4_T1.text()) if self.dockwidget.D4_T2.isEnabled(): seuil2 = float(self.dockwidget.D4_T2.text()) if i == 4: if self.dockwidget.D5_T1.isEnabled(): seuil1 = float(self.dockwidget.D5_T1.text()) if self.dockwidget.D5_T2.isEnabled(): seuil2 = float(self.dockwidget.D5_T2.text()) # print (i) if s < seuil1 and i < 2: self.dockwidget.tableCoordFeu.item( n, 1 + i + len(self.ATTRS_NOM)).setBackground(vert) elif s < seuil2 and i < 2: self.dockwidget.tableCoordFeu.item( n, 1 + i + len(self.ATTRS_NOM)).setBackground(orange) isNA = False if candidat['nom'] == 'NA': isNA = True # print (candidat['decision']) # decision et resultat if (isNA and candidat['decision'] == 'true'): nbNonApp = nbNonApp + 1 if (not isNA and candidat['decision'] == 'true'): nbApp = nbApp + 1 labelRes = candidat['id'] pign1 = candidat['pign1'] pign2 = candidat['pign2'] if (isNA and candidat['decision'] == 'indécis'): nbIndecis = nbIndecis + 1 self.dockwidget.tableCoordFeu.scrollToBottom() if nbIndecis > 0: self.dockwidget.labelResultat.setText('INDECIS') self.dockwidget.labelResultat.setStyleSheet( 'color:black;font: 8pt MS Shell Dlg 2;background-color:orange' ) elif nbNonApp > 0: self.dockwidget.labelResultat.setText("Pas d'appariement") self.dockwidget.labelResultat.setStyleSheet( 'color:black;font: 8pt MS Shell Dlg 2;background-color:white' ) elif nbApp > 0: self.dockwidget.labelResultat.setText("Appariement avec " + labelRes) self.dockwidget.labelResultat.setStyleSheet( 'color:black;font: 8pt MS Shell Dlg 2;background-color:lightgreen' ) #else: # print ('Inconnu') self.dockwidget.pign1.setText(pign1) self.dockwidget.pign2.setText(pign2) # header = self.dockwidget.tableCoordFeu.horizontalHeader() # header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents) # header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) # header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) # header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents) # header.setSectionResizeMode(4, QtWidgets.QHeaderView.ResizeToContents) def vide(self, table): self.dockwidget.tableCoordFeu.setRowCount(0) self.dockwidget.tableCoordFeu.setColumnCount( len(self.ATTRS_NOM) + len(self.DISTANCE_NOM) + 1) colHearder = [] colHearder.append('id') for i in range(len(self.ATTRS_NOM)): nom = self.ATTRS_NOM[i] colHearder.append(nom) for i in range(len(self.DISTANCE_NOM)): nom = self.DISTANCE_NOM[i] nom = nom.replace('Distance', 'D').replace('distance', 'D') colHearder.append(nom) if i == 0: self.dockwidget.labelSeuil1.setText(nom) if i == 1: self.dockwidget.labelSeuil2.setText(nom) if i == 2: self.dockwidget.labelSeuil3.setText(nom) if i == 3: self.dockwidget.labelSeuil4.setText(nom) if i == 4: self.dockwidget.labelSeuil5.setText(nom) # table.setHorizontalHeaderLabels(colHearder) def visuDistance(self): # print (self.DISTANCE_NOM[0]) nomAttr = ''
def testLegendRenderWithMapTheme(self): """Test rendering legends linked to map themes""" QgsProject.instance().removeAllMapLayers() point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') line_path = os.path.join(TEST_DATA_DIR, 'lines.shp') line_layer = QgsVectorLayer(line_path, 'lines', 'ogr') QgsProject.instance().clear() QgsProject.instance().addMapLayers([point_layer, line_layer]) marker_symbol = QgsMarkerSymbol.createSimple({ 'color': '#ff0000', 'outline_style': 'no', 'size': '5' }) point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol)) point_layer.styleManager().addStyleFromLayer("red") line_symbol = QgsLineSymbol.createSimple({ 'color': '#ff0000', 'line_width': '2' }) line_layer.setRenderer(QgsSingleSymbolRenderer(line_symbol)) line_layer.styleManager().addStyleFromLayer("red") red_record = QgsMapThemeCollection.MapThemeRecord() point_red_record = QgsMapThemeCollection.MapThemeLayerRecord( point_layer) point_red_record.usingCurrentStyle = True point_red_record.currentStyle = 'red' red_record.addLayerRecord(point_red_record) line_red_record = QgsMapThemeCollection.MapThemeLayerRecord(line_layer) line_red_record.usingCurrentStyle = True line_red_record.currentStyle = 'red' red_record.addLayerRecord(line_red_record) QgsProject.instance().mapThemeCollection().insert('red', red_record) marker_symbol1 = QgsMarkerSymbol.createSimple({ 'color': '#0000ff', 'outline_style': 'no', 'size': '5' }) marker_symbol2 = QgsMarkerSymbol.createSimple({ 'color': '#0000ff', 'name': 'diamond', 'outline_style': 'no', 'size': '5' }) marker_symbol3 = QgsMarkerSymbol.createSimple({ 'color': '#0000ff', 'name': 'rectangle', 'outline_style': 'no', 'size': '5' }) point_layer.setRenderer( QgsCategorizedSymbolRenderer('Class', [ QgsRendererCategory('B52', marker_symbol1, ''), QgsRendererCategory('Biplane', marker_symbol2, ''), QgsRendererCategory('Jet', marker_symbol3, ''), ])) point_layer.styleManager().addStyleFromLayer("blue") line_symbol = QgsLineSymbol.createSimple({ 'color': '#0000ff', 'line_width': '2' }) line_layer.setRenderer(QgsSingleSymbolRenderer(line_symbol)) line_layer.styleManager().addStyleFromLayer("blue") blue_record = QgsMapThemeCollection.MapThemeRecord() point_blue_record = QgsMapThemeCollection.MapThemeLayerRecord( point_layer) point_blue_record.usingCurrentStyle = True point_blue_record.currentStyle = 'blue' blue_record.addLayerRecord(point_blue_record) line_blue_record = QgsMapThemeCollection.MapThemeLayerRecord( line_layer) line_blue_record.usingCurrentStyle = True line_blue_record.currentStyle = 'blue' blue_record.addLayerRecord(line_blue_record) QgsProject.instance().mapThemeCollection().insert('blue', blue_record) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map1 = QgsLayoutItemMap(layout) map1.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map1.setFrameEnabled(True) map1.setLayers([point_layer, line_layer]) layout.addLayoutItem(map1) map1.setExtent(point_layer.extent()) map1.setFollowVisibilityPreset(True) map1.setFollowVisibilityPresetName('red') map2 = QgsLayoutItemMap(layout) map2.attemptSetSceneRect(QRectF(20, 120, 80, 80)) map2.setFrameEnabled(True) map2.setLayers([point_layer, line_layer]) layout.addLayoutItem(map2) map2.setExtent(point_layer.extent()) map2.setFollowVisibilityPreset(True) map2.setFollowVisibilityPresetName('blue') legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') layout.addLayoutItem(legend) legend.setLinkedMap(map1) legend2 = QgsLayoutItemLegend(layout) legend2.setTitle("Legend") legend2.attemptSetSceneRect(QRectF(120, 120, 80, 80)) legend2.setFrameEnabled(True) legend2.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend2.setBackgroundColor(QColor(200, 200, 200)) legend2.setTitle('') layout.addLayoutItem(legend2) legend2.setLinkedMap(map2) checker = QgsLayoutChecker('composer_legend_theme', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) QgsProject.instance().clear()
def testWFS10(self): """Test WFS 1.0 read-only""" endpoint = self.__class__.basetestpath + '/fake_qgis_http_endpoint_WFS1.0' with open( sanitize(endpoint, '?SERVICE=WFS?REQUEST=GetCapabilities?VERSION=1.0.0'), 'wb') as f: f.write(""" <WFS_Capabilities version="1.0.0" xmlns="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc"> <FeatureTypeList> <FeatureType> <Name>my:typename</Name> <Title>Title</Title> <Abstract>Abstract</Abstract> <SRS>EPSG:4326</SRS> <LatLongBoundingBox minx="-71.123" miny="66.33" maxx="-65.32" maxy="78.3"/> </FeatureType> </FeatureTypeList> </WFS_Capabilities>""") with open( sanitize( endpoint, '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=my:typename' ), 'wb') as f: f.write(""" <xsd:schema xmlns:my="http://my" xmlns:gml="http://www.opengis.net/gml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://my"> <xsd:import namespace="http://www.opengis.net/gml"/> <xsd:complexType name="my:typenameType"> <xsd:complexContent> <xsd:extension base="gml:AbstractFeatureType"> <xsd:sequence> <xsd:element maxOccurs="1" minOccurs="0" name="INTFIELD" nillable="true" type="xsd:int"/> <xsd:element maxOccurs="1" minOccurs="0" name="GEOMETRY" nillable="true" type="xsd:int"/> <xsd:element maxOccurs="1" minOccurs="0" name="longfield" nillable="true" type="xsd:long"/> <xsd:element maxOccurs="1" minOccurs="0" name="stringfield" nillable="true" type="xsd:string"/> <xsd:element maxOccurs="1" minOccurs="0" name="geometryProperty" nillable="true" type="gml:PointPropertyType"/> </xsd:sequence> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:element name="typename" substitutionGroup="gml:_Feature" type="my:typenameType"/> </xsd:schema> """) vl = QgsVectorLayer( u"url='http://" + endpoint + u"' typename='my:typename' version='1.0.0'", u'test', u'WFS') assert vl.isValid() self.assertEquals(vl.wkbType(), QgsWKBTypes.Point) self.assertEquals(len(vl.fields()), 4) self.assertEquals(vl.featureCount(), 0) reference = QgsGeometry.fromRect( QgsRectangle(-71.123, 66.33, -65.32, 78.3)) vl_extent = QgsGeometry.fromRect(vl.extent()) assert QgsGeometry.compare(vl_extent.asPolygon(), reference.asPolygon(), 0.00001), 'Expected {}, got {}'.format( reference.exportToWkt(), vl_extent.exportToWkt()) with open( sanitize( endpoint, '?SERVICE=WFS&REQUEST=GetFeature&VERSION=1.0.0&TYPENAME=my:typename&SRSNAME=EPSG:4326' ), 'wb') as f: f.write(""" <wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs" xmlns:gml="http://www.opengis.net/gml" xmlns:my="http://my"> <gml:boundedBy><gml:null>unknown</gml:null></gml:boundedBy> <gml:featureMember> <my:typename fid="typename.0"> <my:geometryProperty> <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"><gml:coordinates decimal="." cs="," ts=" ">2,49</gml:coordinates></gml:Point></my:geometryProperty> <my:INTFIELD>1</my:INTFIELD> <my:GEOMETRY>2</my:GEOMETRY> <my:longfield>1234567890123</my:longfield> <my:stringfield>foo</my:stringfield> </my:typename> </gml:featureMember> </wfs:FeatureCollection>""") values = [f['INTFIELD'] for f in vl.getFeatures()] self.assertEquals(values, [1]) values = [f['GEOMETRY'] for f in vl.getFeatures()] self.assertEquals(values, [2]) values = [f['longfield'] for f in vl.getFeatures()] self.assertEquals(values, [1234567890123]) values = [f['stringfield'] for f in vl.getFeatures()] self.assertEquals(values, ['foo']) got = [f.geometry() for f in vl.getFeatures()][0].geometry() self.assertEquals((got.x(), got.y()), (2.0, 49.0)) self.assertEquals(vl.featureCount(), 1) self.assertEquals(vl.dataProvider().capabilities(), 0) (ret, _) = vl.dataProvider().addFeatures([QgsFeature()]) assert not ret assert not vl.dataProvider().deleteFeatures([0])
class QueryBuilderWidget(QtWidgets.QDockWidget): closingWidget = pyqtSignal() def __init__(self, parent=None, iface=None): super(QueryBuilderWidget, self).__init__(parent) self.iface = iface self._polygons = QgsVectorLayer( "polygon?crs={0}&field=name:string(20)".format(28992), "building", "memory") self._points = QgsVectorLayer( "point?crs={0}&field=ahn:double".format(28992), "point", "memory") QgsProject.instance().addMapLayer( self._polygons, False) QgsProject.instance().addMapLayer( self._points, False) root = QgsProject.instance().layerTreeRoot() group = root.addGroup('GeoGraphQL') group.addLayer(self._points) group.addLayer(self._polygons) self.setup_ui() self.api = PythonAPI(self.on_new_data) self.frame = self.web_view.page().mainFrame() self.frame.javaScriptWindowObjectCleared.connect(self.load_api) QNetworkProxyFactory.setUseSystemConfiguration(True) QWebSettings.globalSettings().setAttribute(QWebSettings.PluginsEnabled, True) QWebSettings.globalSettings().setAttribute(QWebSettings.DnsPrefetchEnabled, True) QWebSettings.globalSettings().setAttribute(QWebSettings.JavascriptEnabled, True) QWebSettings.globalSettings().setAttribute(QWebSettings.JavascriptCanOpenWindows, True) QWebSettings.globalSettings().setAttribute(QWebSettings.OfflineStorageDatabaseEnabled, True) QWebSettings.globalSettings().setAttribute(QWebSettings.AutoLoadImages, True) QWebSettings.globalSettings().setAttribute(QWebSettings.LocalStorageEnabled, True) QWebSettings.globalSettings().setAttribute(QWebSettings.PrivateBrowsingEnabled, True) QWebSettings.globalSettings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True) QWebSettings.globalSettings().setAttribute(QWebSettings.LocalContentCanAccessRemoteUrls, True) # url = "https://gateway.geographql.com/" url = 'http://localhost:4005/console' # url = 'http://localhost:3000/' url = QUrl(url) file_path = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'build', 'index.html') url = QUrl.fromLocalFile(file_path) self.web_view.load(url) def on_unload(self): self.frame.javaScriptWindowObjectCleared.disconnect(self.load_api) def load_api(self): print('load_api') self.frame.addToJavaScriptWindowObject('pyapi', self.api) def add_point(self, feature): self._points.dataProvider().addFeatures([feature]) self._points.updateExtents() def add_polygon(self, feature): self._polygons.dataProvider().addFeatures([feature]) self._polygons.updateExtents() def make_feature_recursive(self, key, value): if value.get("__typename"): if value.get("__typename") == "Point" and value.get('x') is not None and value.get('y') is not None: feat = QgsFeature(self._points.fields()) geom = QgsGeometry.fromPointXY(QgsPointXY(value.get('x'), value.get('y'))) feat.setGeometry(geom) feat.setAttribute('ahn', value.get('ahn')) self.add_point(feat) elif value.get("__typename") == "Building" and type(value.get('geom') == dict): feat = QgsFeature(self._polygons.fields()) geom = QgsGeometry.fromWkt(value.get('geom')) feat.setGeometry(geom) feat.setAttribute('name', value.get('name')) self.add_polygon(feat) for k, v in value.items(): if type(v) == list: for list_v in v: if type(list_v) == dict: self.make_feature_recursive("{}-{}".format(key, k), list_v) elif type(v) == dict: self.make_feature_recursive("{}-{}".format(key, k), v) def on_new_data(self, obj): print(obj) if 'data' in obj: for key, value in obj['data'].items(): if type(value) == dict: self.make_feature_recursive(key, value) extent = self._points.extent() extent.combineExtentWith(self._polygons.extent()) extent.scale(1.1) canvas = self.iface.mapCanvas() canvas.setExtent(extent) canvas.refresh() def setup_ui(self): self.dock_widget_content = QtWidgets.QWidget(self) self.setObjectName("graphqlDockWidget") self.dock_widget_content.setObjectName("graphqlMainWidget") self.main_vlayout = QtWidgets.QVBoxLayout(self.dock_widget_content) self.dock_widget_content.setLayout(self.main_vlayout) #self.web_view = QtWebEngineWidgets.QWebEngineView(self.dock_widget_content) self.web_view = QtWebKitWidgets.QWebView(self.dock_widget_content) self.main_vlayout.addWidget(self.web_view) self.button_bar = QtWidgets.QHBoxLayout(self.dock_widget_content) self.load_button = QtWidgets.QPushButton(self.dock_widget_content) self.refresh_button = QtWidgets.QPushButton(self.dock_widget_content) spacer = QtWidgets.QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.button_bar.addWidget(self.load_button) self.button_bar.addSpacerItem(spacer) self.button_bar.addWidget(self.refresh_button) self.main_vlayout.addLayout(self.button_bar) self.setWidget(self.dock_widget_content) self.setWindowTitle("GeoGraphQL") self.load_button.setText("Laad data") self.refresh_button.setText("Refresh")
def testSymbolExpressionRender(self): """Test expressions embedded in legend node text""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') layout = QgsPrintLayout(QgsProject.instance()) layout.setName('LAYOUT') layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 100, 100)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') legend.setLegendFilterByMapEnabled(False) legend.setStyleFont(QgsLegendStyle.Title, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Group, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Subgroup, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Symbol, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.SymbolLabel, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setAutoUpdateModel(False) QgsProject.instance().addMapLayers([point_layer]) s = QgsMapSettings() s.setLayers([point_layer]) group = legend.model().rootGroup().addGroup( "Group [% 1 + 5 %] [% @layout_name %]") layer_tree_layer = group.addLayer(point_layer) counterTask = point_layer.countSymbolFeatures() counterTask.waitForFinished() # does this even work? layer_tree_layer.setCustomProperty( "legend/title-label", 'bbbb [% 1+2 %] xx [% @layout_name %] [% @layer_name %]') QgsMapLayerLegendUtils.setLegendNodeUserLabel(layer_tree_layer, 0, 'xxxx') legend.model().refreshLayerLegend(layer_tree_layer) layer_tree_layer.setLabelExpression( 'Concat(@symbol_id, @symbol_label, count("Class"))') legend.model().layerLegendNodes(layer_tree_layer)[0].setUserLabel( ' sym 1') legend.model().layerLegendNodes(layer_tree_layer)[1].setUserLabel( '[%@symbol_count %]') legend.model().layerLegendNodes(layer_tree_layer)[2].setUserLabel( '[% count("Class") %]') layout.addLayoutItem(legend) legend.setLinkedMap(map) legend.updateLegend() print(layer_tree_layer.labelExpression()) TM = QgsApplication.taskManager() actask = TM.activeTasks() print(TM.tasks(), actask) count = actask[0] count.waitForFinished() map.setExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30)) checker = QgsLayoutChecker('composer_legend_symbol_expression', layout) checker.setControlPathPrefix("composer_legend") sleep(4) result, message = checker.testLayout() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testExpressionInText(self): """Test expressions embedded in legend node text""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') layout = QgsPrintLayout(QgsProject.instance()) layout.setName('LAYOUT') layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 100, 100)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') legend.setLegendFilterByMapEnabled(False) legend.setStyleFont(QgsLegendStyle.Title, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Group, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Subgroup, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Symbol, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.SymbolLabel, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setAutoUpdateModel(False) QgsProject.instance().addMapLayers([point_layer]) s = QgsMapSettings() s.setLayers([point_layer]) group = legend.model().rootGroup().addGroup( "Group [% 1 + 5 %] [% @layout_name %]") layer_tree_layer = group.addLayer(point_layer) layer_tree_layer.setCustomProperty( "legend/title-label", 'bbbb [% 1+2 %] xx [% @layout_name %] [% @layer_name %]') QgsMapLayerLegendUtils.setLegendNodeUserLabel(layer_tree_layer, 0, 'xxxx') legend.model().refreshLayerLegend(layer_tree_layer) legend.model().layerLegendNodes(layer_tree_layer)[0].setUserLabel( 'bbbb [% 1+2 %] xx [% @layout_name %] [% @layer_name %]') layout.addLayoutItem(legend) legend.setLinkedMap(map) map.setExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30)) checker = QgsLayoutChecker('composer_legend_expressions', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testInitialSizeSymbolMapUnits(self): """Test initial size of legend with a symbol size in map units""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().addMapLayers([point_layer]) marker_symbol = QgsMarkerSymbol.createSimple({ 'color': '#ff0000', 'outline_style': 'no', 'size': '5', 'size_unit': 'MapUnit' }) point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol)) s = QgsMapSettings() s.setLayers([point_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') layout.addLayoutItem(legend) legend.setLinkedMap(map) checker = QgsLayoutChecker('composer_legend_mapunits', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() self.assertTrue(result, message) # resize with non-top-left reference point legend.setResizeToContents(False) legend.setReferencePoint(QgsLayoutItem.LowerRight) legend.attemptMove(QgsLayoutPoint(120, 90)) legend.attemptResize(QgsLayoutSize(50, 60)) self.assertEqual(legend.positionWithUnits().x(), 120.0) self.assertEqual(legend.positionWithUnits().y(), 90.0) self.assertAlmostEqual(legend.pos().x(), 70, -1) self.assertAlmostEqual(legend.pos().y(), 30, -1) legend.setResizeToContents(True) legend.updateLegend() self.assertEqual(legend.positionWithUnits().x(), 120.0) self.assertEqual(legend.positionWithUnits().y(), 90.0) self.assertAlmostEqual(legend.pos().x(), 91, -1) self.assertAlmostEqual(legend.pos().y(), 71, -1) QgsProject.instance().removeMapLayers([point_layer.id()])
def calcQneatInterpolation(self, iso_pointcloud_featurelist, resolution, interpolation_raster_path): #prepare spatial index uri = 'PointM?crs={}&field=vertex_id:int(254)&field=cost:double(254,7)&key=vertex_id&index=yes'.format( self.AnalysisCrs.authid()) mIsoPointcloud = QgsVectorLayer(uri, "mIsoPointcloud_layer", "memory") mIsoPointcloud_provider = mIsoPointcloud.dataProvider() mIsoPointcloud_provider.addFeatures(iso_pointcloud_featurelist, QgsFeatureSink.FastInsert) #implement spatial index for lines (closest line, etc...) spt_idx = QgsSpatialIndex( mIsoPointcloud.getFeatures(QgsFeatureRequest()), self.feedback) #prepare numpy coordinate grids NoData_value = -9999 raster_rectangle = mIsoPointcloud.extent() #top left point xmin = raster_rectangle.xMinimum() ymin = raster_rectangle.yMinimum() xmax = raster_rectangle.xMaximum() ymax = raster_rectangle.yMaximum() cols = int((xmax - xmin) / resolution) rows = int((ymax - ymin) / resolution) output_interpolation_raster = gdal.GetDriverByName('GTiff').Create( interpolation_raster_path, cols, rows, 1, gdal.GDT_Float64) output_interpolation_raster.SetGeoTransform( (xmin, resolution, 0, ymax, 0, -resolution)) band = output_interpolation_raster.GetRasterBand(1) band.SetNoDataValue(NoData_value) #initialize zero array with 2 dimensions (according to rows and cols) raster_data = zeros(shape=(rows, cols)) #compute raster cell MIDpoints x_pos = linspace(xmin + (resolution / 2), xmax - (resolution / 2), raster_data.shape[1]) y_pos = linspace(ymax - (resolution / 2), ymin + (resolution / 2), raster_data.shape[0]) x_grid, y_grid = meshgrid(x_pos, y_pos) self.feedback.pushInfo( '[QNEAT3Network][calcQneatInterpolation] Beginning with interpolation' ) total_work = rows * cols counter = 0 self.feedback.pushInfo( '[QNEAT3Network][calcQneatInterpolation] Total workload: {} cells'. format(total_work)) self.feedback.setProgress(0) for i in range(rows): for j in range(cols): current_pixel_midpoint = QgsPointXY(x_grid[i, j], y_grid[i, j]) nearest_vertex_fid = spt_idx.nearestNeighbor( current_pixel_midpoint, 1)[0] nearest_feature = mIsoPointcloud.getFeature(nearest_vertex_fid) nearest_vertex = self.network.vertex( nearest_feature['vertex_id']) edges = nearest_vertex.incomingEdges( ) + nearest_vertex.outgoingEdges() vertex_found = False nearest_counter = 2 while vertex_found == False: n_nearest_feature_fid = spt_idx.nearestNeighbor( current_pixel_midpoint, nearest_counter)[nearest_counter - 1] n_nearest_feature = mIsoPointcloud.getFeature( n_nearest_feature_fid) n_nearest_vertex_id = n_nearest_feature['vertex_id'] for edge_id in edges: from_vertex_id = self.network.edge( edge_id).fromVertex() to_vertex_id = self.network.edge(edge_id).toVertex() if n_nearest_vertex_id == from_vertex_id: vertex_found = True vertex_type = "from_vertex" from_point = n_nearest_feature.geometry().asPoint() from_vertex_cost = n_nearest_feature['cost'] if n_nearest_vertex_id == to_vertex_id: vertex_found = True vertex_type = "to_vertex" to_point = n_nearest_feature.geometry().asPoint() to_vertex_cost = n_nearest_feature['cost'] nearest_counter = nearest_counter + 1 """ if nearest_counter == 5: vertex_found = True vertex_type = "end_vertex" """ if vertex_type == "from_vertex": nearest_edge_geometry = QgsGeometry().fromPolylineXY( [from_point, nearest_vertex.point()]) res = nearest_edge_geometry.closestSegmentWithContext( current_pixel_midpoint) segment_point = res[ 1] #[0: distance, 1: point, 2: left_of, 3: epsilon for snapping] dist_to_segment = segment_point.distance( current_pixel_midpoint) dist_edge = from_point.distance(segment_point) #self.feedback.pushInfo("dist_to_segment = {}".format(dist_to_segment)) #self.feedback.pushInfo("dist_on_edge = {}".format(dist_edge)) #self.feedback.pushInfo("cost = {}".format(from_vertex_cost)) pixel_cost = from_vertex_cost + dist_edge + dist_to_segment raster_data[i, j] = pixel_cost elif vertex_type == "to_vertex": nearest_edge_geometry = QgsGeometry().fromPolylineXY( [nearest_vertex.point(), to_point]) res = nearest_edge_geometry.closestSegmentWithContext( current_pixel_midpoint) segment_point = res[ 1] #[0: distance, 1: point, 2: left_of, 3: epsilon for snapping] dist_to_segment = segment_point.distance( current_pixel_midpoint) dist_edge = to_point.distance(segment_point) #self.feedback.pushInfo("dist_to_segment = {}".format(dist_to_segment)) #self.feedback.pushInfo("dist_on_edge = {}".format(dist_edge)) #self.feedback.pushInfo("cost = {}".format(from_vertex_cost)) pixel_cost = to_vertex_cost + dist_edge + dist_to_segment raster_data[i, j] = pixel_cost else: pixel_cost = -99999 #nearest_feature['cost'] + (nearest_vertex.point().distance(current_pixel_midpoint)) """ nearest_feature_pointxy = nearest_feature.geometry().asPoint() nearest_feature_cost = nearest_feature['cost'] dist_to_vertex = current_pixel_midpoint.distance(nearest_feature_pointxy) #implement time cost pixel_cost = dist_to_vertex + nearest_feature_cost raster_data[i,j] = pixel_cost """ counter = counter + 1 if counter % 1000 == 0: self.feedback.pushInfo( "[QNEAT3Network][calcQneatInterpolation] Interpolated {} cells..." .format(counter)) self.feedback.setProgress((counter / total_work) * 100) band.WriteArray(raster_data) outRasterSRS = osr.SpatialReference() outRasterSRS.ImportFromWkt(self.AnalysisCrs.toWkt()) output_interpolation_raster.SetProjection(outRasterSRS.ExportToWkt()) band.FlushCache()