def __signal_pbCopyKml_clicked(self, cheked): # Extent Openlayers action = "map.getExtent().toGeometry().toString();" wkt = self.webViewMap.page().mainFrame().evaluateJavaScript(action) rect = QgsGeometry.fromWkt(wkt).boundingBox() srsGE = QgsCoordinateReferenceSystem( 4326, QgsCoordinateReferenceSystem.EpsgCrsId) coodTrans = QgsCoordinateTransform(self.__srsOL, srsGE, QgsProject.instance()) rect = coodTrans.transform( rect, QgsCoordinateTransform.ForwardTransform) line = QgsGeometry.fromRect(rect).asPolygon()[0] wkt = str(QgsGeometry.fromPolylineXY(line).asWkt()) # Kml proj4 = str(srsGE.toProj4()) kmlLine = bindogr.exportKml(wkt, proj4) kml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"\ "<kml xmlns=\"http://www.opengis.net/kml/2.2\" " \ "xmlns:gx=\"http://www.google.com/kml/ext/2.2\" " \ "xmlns:kml=\"http://www.opengis.net/kml/2.2\" " \ "xmlns:atom=\"http://www.w3.org/2005/Atom\">" \ "<Placemark>" \ "<name>KML from Plugin Openlayers Overview for QGIS</name>" \ "<description>Extent of openlayers map from Plugin Openlayers \ Overview for QGIS</description>"\ "%s" \ "</Placemark></kml>" % kmlLine clipBoard = QApplication.clipboard() clipBoard.setText(kml)
def processAlgorithm(self, progress): source = self.getParameterValue(self.INPUT) vlayer = dataobjects.getObjectFromUri(source) output = self.getOutputFromName(self.OUTPUT) fields = vlayer.fields() writer = output.getVectorWriter(fields, QgsWkbTypes.Point, self.crs) xfieldindex = vlayer.fieldNameIndex(self.getParameterValue(self.XFIELD)) yfieldindex = vlayer.fieldNameIndex(self.getParameterValue(self.YFIELD)) crsId = self.getParameterValue(self.TARGET_CRS) targetCrs = QgsCoordinateReferenceSystem() targetCrs.createFromUserInput(crsId) self.crs = targetCrs outFeat = QgsFeature() features = vector.features(vlayer) total = 100.0 / len(features) for current, feature in enumerate(features): progress.setPercentage(int(current * total)) attrs = feature.attributes() try: x = float(attrs[xfieldindex]) y = float(attrs[yfieldindex]) except: continue pt = QgsPoint(x, y) outFeat.setGeometry(QgsGeometry.fromPoint(pt)) outFeat.setAttributes(attrs) writer.addFeature(outFeat) del writer
def calculateSquare(self, point): ''' point in layer coordinates(QgsPoint) ''' mapCrs = self.canvas.mapSettings().destinationCrs() utmCrs = QgsCoordinateReferenceSystem() utmCrs.createFromProj4(self.proj4Utm(point)) ctFwd = QgsCoordinateTransform(mapCrs, utmCrs) ctBwd = QgsCoordinateTransform(utmCrs, mapCrs) pointGeom = QgsGeometry.fromPoint(point) pointGeom.transform(ctFwd) pointUtm = QgsPoint(pointGeom.asPoint()) # calculate d d = self.diagonal/(2*(2**0.5)) l = pointUtm.x() - d b = pointUtm.y() - d r = pointUtm.x() + d t = pointUtm.y() + d p1 = QgsGeometry.fromPoint(QgsPoint(l, b)) p2 = QgsGeometry.fromPoint(QgsPoint(r, b)) p3 = QgsGeometry.fromPoint(QgsPoint(r, t)) p4 = QgsGeometry.fromPoint(QgsPoint(l, t)) p1.transform(ctBwd) p2.transform(ctBwd) p3.transform(ctBwd) p4.transform(ctBwd) mapPol = [p1.asPoint(), p2.asPoint(), p3.asPoint(), p4.asPoint(), p1.asPoint()] return mapPol
def processAlgorithm(self, progress): source = self.getParameterValue(self.INPUT) vlayer = dataobjects.getObjectFromUri(source) output = self.getOutputFromName(self.OUTPUT) vprovider = vlayer.dataProvider() fields = vprovider.fields() writer = output.getVectorWriter(fields, QGis.WKBPoint, self.crs) xfieldindex = vlayer.fieldNameIndex(self.getParameterValue(self.XFIELD)) yfieldindex = vlayer.fieldNameIndex(self.getParameterValue(self.YFIELD)) crsId = self.getParameterValue(self.TARGET_CRS) targetCrs = QgsCoordinateReferenceSystem() targetCrs.createFromUserInput(crsId) self.crs = targetCrs outFeat = QgsFeature() nElement = 0 features = vector.features(vlayer) nFeat = len(features) for feature in features: nElement += 1 progress.setPercentage(nElement * 100 / nFeat) attrs = feature.attributes() try: x = float(attrs[xfieldindex]) y = float(attrs[yfieldindex]) except: continue pt = QgsPoint(x, y) outFeat.setGeometry(QgsGeometry.fromPoint(pt)) outFeat.setAttributes(attrs) writer.addFeature(outFeat) del writer
def set_destination_coordinate_system(self, srid_val): """ :return: """ spRef = QgsCoordinateReferenceSystem() return spRef.createFromId(srid_val)
def extentToGeoArray(theExtent, theSourceCrs): """Convert the supplied extent to geographic and return as as array. Args: theExtent: QgsRectangle to be transformed to geocrs. theSourceCrs: QgsCoordinateReferenceSystem representing the original extent's CRS. Returns: list: Transformed extents in EPSG:4326 in the form [xmin, ymin, xmix, ymax] Raises: None """ myGeoCrs = QgsCoordinateReferenceSystem() myGeoCrs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) myXForm = QgsCoordinateTransform( theSourceCrs, myGeoCrs) # Get the clip area in the layer's crs myTransformedExtent = myXForm.transformBoundingBox(theExtent) myGeoExtent = [myTransformedExtent.xMinimum(), myTransformedExtent.yMinimum(), myTransformedExtent.xMaximum(), myTransformedExtent.yMaximum()] return myGeoExtent
def testWriteShapefileWithMultiConversion(self): """Check writing geometries to an ESRI shapefile with conversion to multi.""" ml = QgsVectorLayer(("Point?crs=epsg:4326&field=id:int"), "test", "memory") self.assertIsNotNone(ml, "Provider not initialized") self.assertTrue(ml.isValid(), "Source layer not valid") provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromWkt("Point (1 2)")) ft.setAttributes([1]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) dest_file_name = os.path.join(str(QDir.tempPath()), "to_multi.shp") crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, "utf-8", crs, "ESRI Shapefile", forceMulti=True ) self.assertEqual(write_result, QgsVectorFileWriter.NoError) # Open result and check created_layer = QgsVectorLayer("{}|layerid=0".format(dest_file_name), "test", "ogr") f = next(created_layer.getFeatures(QgsFeatureRequest())) g = f.geometry() wkt = g.exportToWkt() expWkt = "MultiPoint ((1 2))" self.assertTrue( compareWkt(expWkt, wkt), "saving geometry with multi conversion failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt), )
def _calc_north(self): extent = self.canvas.extent() if self.canvas.layerCount() == 0 or extent.isEmpty(): print "No layers or extent" return 0 outcrs = self.canvas.mapSettings().destinationCrs() if outcrs.isValid() and not outcrs.geographicFlag(): crs = QgsCoordinateReferenceSystem() crs.createFromOgcWmsCrs("EPSG:4326") transform = QgsCoordinateTransform(outcrs, crs) p1 = QgsPoint(extent.center()) p2 = QgsPoint(p1.x(), p1.y() + extent.height() * 0.25) try: pp1 = transform.transform(p1) pp2 = transform.transform(p2) except QgsCsException: roam.utils.warning("North arrow. Error transforming.") return None area = QgsDistanceArea() area.setEllipsoid(crs.ellipsoidAcronym()) area.setEllipsoidalMode(True) area.setSourceCrs(crs) distance, angle, _ = area.computeDistanceBearing(pp1, pp2) angle = math.degrees(angle) return angle else: return 0
def setUp(self): """Fixture run before all tests""" register_impact_functions() self.maxDiff = None # show full diff for assert errors os.environ['LANG'] = 'en' self.DOCK.show_only_visible_layers_flag = True load_standard_layers(self.DOCK) self.DOCK.cboHazard.setCurrentIndex(0) self.DOCK.cboExposure.setCurrentIndex(0) self.DOCK.cboFunction.setCurrentIndex(0) self.DOCK.run_in_thread_flag = False self.DOCK.show_only_visible_layers_flag = False self.DOCK.set_layer_from_title_flag = False self.DOCK.zoom_to_impact_flag = False self.DOCK.hide_exposure_flag = False self.DOCK.show_intermediate_layers = False set_jakarta_extent() self._keywordIO = KeywordIO() self._defaults = get_defaults() # Set extent as Jakarta extent geo_crs = QgsCoordinateReferenceSystem() geo_crs.createFromSrid(4326) self.extent = extent_to_geo_array(CANVAS.extent(), geo_crs)
def extent_to_geo_array(extent, source_crs, dest_crs=None): """Convert the supplied extent to geographic and return as an array. :param extent: Rectangle defining a spatial extent in any CRS. :type extent: QgsRectangle :param source_crs: Coordinate system used for extent. :type source_crs: QgsCoordinateReferenceSystem :returns: a list in the form [xmin, ymin, xmax, ymax] where all coordinates provided are in Geographic / EPSG:4326. :rtype: list """ if dest_crs is None: geo_crs = QgsCoordinateReferenceSystem() geo_crs.createFromSrid(4326) else: geo_crs = dest_crs transform = QgsCoordinateTransform(source_crs, geo_crs) # Get the clip area in the layer's crs transformed_extent = transform.transformBoundingBox(extent) geo_extent = [ transformed_extent.xMinimum(), transformed_extent.yMinimum(), transformed_extent.xMaximum(), transformed_extent.yMaximum()] return geo_extent
def extent_to_geoarray(extent, source_crs): """Convert the supplied extent to geographic and return as as array. :param extent: QgsRectangle to be transformed to geocrs. :type extent: :param source_crs: QgsCoordinateReferenceSystem representing the original extent's CRS. :type source_crs: :returns: Transformed extents in EPSG:4326 in the form [xmin, ymin, xmax, ymax] """ myGeoCrs = QgsCoordinateReferenceSystem() myGeoCrs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) myXForm = QgsCoordinateTransform( source_crs, myGeoCrs) # Get the clip area in the layer's crs myTransformedExtent = myXForm.transformBoundingBox(extent) myGeoExtent = [myTransformedExtent.xMinimum(), myTransformedExtent.yMinimum(), myTransformedExtent.xMaximum(), myTransformedExtent.yMaximum()] return myGeoExtent
def processCommand(alg): # Creates a new location with the CRS crsParam = alg.getParameterFromName('crs') crsId = int(crsParam.value[5:]) #QgsMessageLog.logMessage('crs = {}'.format(crs), 'DEBUG', QgsMessageLog.INFO) crs = QgsCoordinateReferenceSystem() crs.createFromId(crsId, QgsCoordinateReferenceSystem.EpsgCrsId) command = "g.proj proj4=\"{}\" location=TARGET".format(crs.toProj4()) alg.commands.append(command) alg.parameters.remove(crsParam) # Regroup rasters rasters = alg.getParameterFromName('rasters') rastersList = rasters.value.split(';') alg.parameters.remove(rasters) # Insert a i.group command group = getParameterFromString("ParameterString|group|group of rasters|None|False|False") group.value = alg.getTempFilename() alg.addParameter(group) command = 'i.group group={} input={}'.format( group.value, ','.join([alg.exportedLayers[f] for f in rastersList]) ) alg.commands.append(command) # Handle POINT File gcp = alg.getParameterFromName('gcp') extFileName = gcp.value destPath = path.join(Grass7Utils.grassMapsetFolder(), 'PERMANENT', 'group', group.value, 'POINTS') copyFile(alg, extFileName, destPath) alg.parameters.remove(gcp) # Add a target destination for our group command = "i.target group={} location=TARGET mapset=PERMANENT".format(group.value) alg.commands.append(command) # remove output output = alg.getOutputFromName('output') alg.removeOutputFromName('output') # Add an extension #extension = getParameterFromString("ParameterString|extension|Output raster map(s) suffix|None|False|False") #extension.value = "rectified" #alg.addParameter(extension) # modify parameters values alg.processCommand() # Re-add input rasters alg.addParameter(rasters) alg.addParameter(gcp) alg.addParameter(crs) # Re-add output alg.addOutput(output)
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) crsId = self.getParameterValue(self.TARGET_CRS) targetCrs = QgsCoordinateReferenceSystem() targetCrs.createFromUserInput(crsId) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields().toList(), layer.wkbType(), targetCrs) layerCrs = layer.crs() crsTransform = QgsCoordinateTransform(layerCrs, targetCrs) outFeat = QgsFeature() features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): geom = f.geometry() geom.transform(crsTransform) outFeat.setGeometry(geom) outFeat.setAttributes(f.attributes()) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) del writer self.crs = targetCrs
def testTrueNorth(self): """ test calculating bearing to true north""" # short circuit - already a geographic crs crs = QgsCoordinateReferenceSystem.fromEpsgId(4326) self.assertEqual(QgsBearingUtils.bearingTrueNorth(crs, QgsPoint(0, 0)), 0) self.assertEqual(QgsBearingUtils.bearingTrueNorth(crs, QgsPoint(44, 0)), 0) self.assertEqual(QgsBearingUtils.bearingTrueNorth(crs, QgsPoint(44, -43)), 0) self.assertEqual(QgsBearingUtils.bearingTrueNorth(crs, QgsPoint(44, 43)), 0) self.assertEqual(QgsBearingUtils.bearingTrueNorth(crs, QgsPoint(44, 200)), 0) self.assertEqual(QgsBearingUtils.bearingTrueNorth(crs, QgsPoint(44, -200)), 0) # no short circuit crs = QgsCoordinateReferenceSystem.fromEpsgId(3111) self.assertAlmostEqual(QgsBearingUtils.bearingTrueNorth(crs, QgsPoint(2508807, 2423425)), 0.06, 2) # try a south-up crs crs = QgsCoordinateReferenceSystem.fromEpsgId(2053) self.assertAlmostEqual(QgsBearingUtils.bearingTrueNorth(crs, QgsPoint(29, -27.55)), -180.0, 1) # try a north pole crs crs = QgsCoordinateReferenceSystem.fromEpsgId(3575) self.assertAlmostEqual(QgsBearingUtils.bearingTrueNorth(crs, QgsPoint(-780770, 652329)), 129.9, 1) self.assertAlmostEqual(QgsBearingUtils.bearingTrueNorth(crs, QgsPoint(513480, 873173)), -149.5, 1)
def test_ExpressionFieldEllipsoidLengthCalculation(self): #create a temporary layer temp_layer = QgsVectorLayer("LineString?crs=epsg:3111&field=pk:int", "vl", "memory") self.assertTrue(temp_layer.isValid()) f1 = QgsFeature(temp_layer.dataProvider().fields(), 1) f1.setAttribute("pk", 1) f1.setGeometry(QgsGeometry.fromPolyline([QgsPoint(2484588, 2425722), QgsPoint(2482767, 2398853)])) temp_layer.dataProvider().addFeatures([f1]) # set project CRS and ellipsoid srs = QgsCoordinateReferenceSystem(3111, QgsCoordinateReferenceSystem.EpsgCrsId) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSID", srs.srsid()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCrs", srs.authid()) QgsProject.instance().writeEntry("Measure", "/Ellipsoid", "WGS84") QgsProject.instance().writeEntry("Measurement", "/DistanceUnits", QgsUnitTypes.encodeUnit(QGis.Meters)) idx = temp_layer.addExpressionField('$length', QgsField('length', QVariant.Double)) # NOQA # check value f = temp_layer.getFeatures().next() expected = 26932.156 self.assertAlmostEqual(f['length'], expected, 3) # change project length unit, check calculation respects unit QgsProject.instance().writeEntry("Measurement", "/DistanceUnits", QgsUnitTypes.encodeUnit(QGis.Feet)) f = temp_layer.getFeatures().next() expected = 88360.0918635 self.assertAlmostEqual(f['length'], expected, 3)
def viewport_geo_array(map_canvas): """Obtain the map canvas current extent in EPSG:4326. :param map_canvas: A map canvas instance. :type map_canvas: QgsMapCanvas :returns: A list in the form [xmin, ymin, xmax, ymax] where all coordinates provided are in Geographic / EPSG:4326. :rtype: list .. note:: Delegates to extent_to_geo_array() """ # get the current viewport extent rectangle = map_canvas.extent() if map_canvas.hasCrsTransformEnabled(): crs = map_canvas.mapRenderer().destinationCrs() else: # some code duplication from extentToGeoArray here # in favour of clarity of logic... crs = QgsCoordinateReferenceSystem() crs.createFromSrid(4326) return extent_to_geo_array(rectangle, crs)
def test_ExpressionFieldEllipsoidAreaCalculation(self): #create a temporary layer temp_layer = QgsVectorLayer("Polygon?crs=epsg:3111&field=pk:int", "vl", "memory") self.assertTrue(temp_layer.isValid()) f1 = QgsFeature(temp_layer.dataProvider().fields(), 1) f1.setAttribute("pk", 1) f1.setGeometry(QgsGeometry.fromPolygon([[QgsPoint(2484588, 2425722), QgsPoint(2482767, 2398853), QgsPoint(2520109, 2397715), QgsPoint(2520792, 2425494), QgsPoint(2484588, 2425722)]])) temp_layer.dataProvider().addFeatures([f1]) # set project CRS and ellipsoid srs = QgsCoordinateReferenceSystem(3111, QgsCoordinateReferenceSystem.EpsgCrsId) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSID", srs.srsid()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCrs", srs.authid()) QgsProject.instance().writeEntry("Measure", "/Ellipsoid", "WGS84") QgsProject.instance().writeEntry("Measurement", "/AreaUnits", QgsUnitTypes.encodeUnit(QgsUnitTypes.SquareMeters)) idx = temp_layer.addExpressionField('$area', QgsField('area', QVariant.Double)) # NOQA # check value f = temp_layer.getFeatures().next() expected = 1009089817.0 self.assertAlmostEqual(f['area'], expected, delta=1.0) # change project area unit, check calculation respects unit QgsProject.instance().writeEntry("Measurement", "/AreaUnits", QgsUnitTypes.encodeUnit(QgsUnitTypes.SquareMiles)) f = temp_layer.getFeatures().next() expected = 389.6117565069 self.assertAlmostEqual(f['area'], expected, 3)
def processAlgorithm(self, parameters, context, feedback): fileName = self.getParameterValue(self.INPUT) layer = QgsProcessingUtils.mapLayerFromString(fileName, context) crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.CRS)) provider = layer.dataProvider() ds = provider.dataSourceUri() p = re.compile('\|.*') dsPath = p.sub('', ds) if dsPath.lower().endswith('.shp'): dsPath = dsPath[:-4] wkt = crs.toWkt() with open(dsPath + '.prj', 'w') as f: f.write(wkt) qpjFile = dsPath + '.qpj' if os.path.exists(qpjFile): with open(qpjFile, 'w') as f: f.write(wkt) layer.setCrs(crs) iface.mapCanvas().refresh() self.setOutputValue(self.OUTPUT, fileName)
def testInteger64WriteTabfile(self): """Check writing Integer64 fields to an MapInfo tabfile (which does not support that type).""" ml = QgsVectorLayer(("Point?crs=epsg:4326&field=int8:int8"), "test", "memory") self.assertIsNotNone(ml, "Provider not initialized") self.assertTrue(ml.isValid(), "Source layer not valid") provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setAttributes([2123456789]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) dest_file_name = os.path.join(str(QDir.tempPath()), "integer64.tab") crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result = QgsVectorFileWriter.writeAsVectorFormat(ml, dest_file_name, "utf-8", crs, "MapInfo File") self.assertEqual(write_result, QgsVectorFileWriter.NoError) # Open result and check created_layer = QgsVectorLayer("{}|layerid=0".format(dest_file_name), "test", "ogr") fields = created_layer.dataProvider().fields() self.assertEqual(fields.at(fields.indexFromName("int8")).type(), QVariant.Double) f = next(created_layer.getFeatures(QgsFeatureRequest())) int8_idx = created_layer.fields().lookupField("int8") self.assertEqual(f.attributes()[int8_idx], 2123456789)
def coordRefSys(self, mapCoordSys): epsg = self.epsgList[0] # TODO: look for matching coord coordRefSys = QgsCoordinateReferenceSystem() createCrs = coordRefSys.createFromOgcWmsCrs("EPSG:%d" % epsg) if not createCrs: return None return coordRefSys
def read_settings(self): """Set the IF state from QSettings.""" extent = setting('user_extent', None, str) if extent: extent = QgsGeometry.fromWkt(extent) if not extent.isGeosValid(): extent = None crs = setting('user_extent_crs', None, str) if crs: crs = QgsCoordinateReferenceSystem(crs) if not crs.isValid(): crs = None mode = setting('analysis_extents_mode', HAZARD_EXPOSURE_VIEW) if crs and extent and mode == HAZARD_EXPOSURE_BOUNDINGBOX: self.extent.set_user_extent(extent, crs) self.extent.show_rubber_bands = setting( 'showRubberBands', False, bool) self.zoom_to_impact_flag = setting('setZoomToImpactFlag', True, bool) # whether exposure layer should be hidden after model completes self.hide_exposure_flag = setting('setHideExposureFlag', False, bool)
def extent_to_geo_array(extent, source_crs): """Convert the supplied extent to geographic and return as an array. :param extent: Rectangle defining a spatial extent in any CRS. :type extent: QgsRectangle :param source_crs: Coordinate system used for extent. :type source_crs: QgsCoordinateReferenceSystem :returns: a list in the form [xmin, ymin, xmax, ymax] where all coordinates provided are in Geographic / EPSG:4326. :rtype: list """ myGeoCrs = QgsCoordinateReferenceSystem() myGeoCrs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) myXForm = QgsCoordinateTransform(source_crs, myGeoCrs) # Get the clip area in the layer's crs myTransformedExtent = myXForm.transformBoundingBox(extent) myGeoExtent = [myTransformedExtent.xMinimum(), myTransformedExtent.yMinimum(), myTransformedExtent.xMaximum(), myTransformedExtent.yMaximum()] return myGeoExtent
def processAlgorithm(self, feedback): fileName = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(fileName) crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.CRS)) provider = layer.dataProvider() ds = provider.dataSourceUri() p = re.compile("\|.*") dsPath = p.sub("", ds) if dsPath.lower().endswith(".shp"): dsPath = dsPath[:-4] wkt = crs.toWkt() with open(dsPath + ".prj", "w") as f: f.write(wkt) qpjFile = dsPath + ".qpj" if os.path.exists(qpjFile): with open(qpjFile, "w") as f: f.write(wkt) layer.setCrs(crs) iface.mapCanvas().refresh() self.setOutputValue(self.OUTPUT, fileName)
def viewport_geo_array(map_canvas): """Obtain the map canvas current extent in EPSG:4326. :param map_canvas: A map canvas instance. :type map_canvas: QgsMapCanvas :returns: A list in the form [xmin, ymin, xmax, ymax] where all coordinates provided are in Geographic / EPSG:4326. :rtype: list .. note:: Delegates to extent_to_array() """ # get the current viewport extent rectangle = map_canvas.extent() destination_crs = QgsCoordinateReferenceSystem() destination_crs.createFromSrid(4326) if map_canvas.hasCrsTransformEnabled(): source_crs = map_canvas.mapRenderer().destinationCrs() else: source_crs = destination_crs return extent_to_array(rectangle, source_crs, destination_crs)
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) crsId = self.getParameterValue(self.TARGET_CRS) targetCrs = QgsCoordinateReferenceSystem() targetCrs.createFromUserInput(crsId) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), targetCrs, context) layerCrs = layer.crs() crsTransform = QgsCoordinateTransform(layerCrs, targetCrs) outFeat = QgsFeature() features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): geom = f.geometry() geom.transform(crsTransform) outFeat.setGeometry(geom) outFeat.setAttributes(f.attributes()) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer self.crs = targetCrs
def onReturnPressed(self): try: txt = self.editSearch.text().strip() self.plugin.lastSearch = self.editSearch.text() self.plugin.limitSearchToExtent = (self.cbExtent.isChecked()) options = self.plugin.gnOptions options2 = {} if self.plugin.limitSearchToExtent: sourceCrs = self.plugin.canvas.mapSettings().destinationCrs() targetCrs = QgsCoordinateReferenceSystem() targetCrs.createFromSrid(4326) xform = QgsCoordinateTransform(sourceCrs, targetCrs, QgsProject.instance()) geom = xform.transform(self.plugin.canvas.extent()) options2 = {'viewbox': str(geom.xMinimum()) + ',' + str(geom.yMaximum()) + ',' + str(geom.xMaximum()) + ',' + str(geom.yMinimum())} params = {'q': txt, 'addressdetails': '0'} self.searchJson(params, self.plugin.gnUsername, options, options2) except Exception as e: for m in e.args: QgsMessageLog.logMessage(m, 'Extensions') pass
def transformGeom(self, item): src_crs = QgsCoordinateReferenceSystem() src_crs.createFromSrid(item.srid) dest_crs = self.mapCanvas.mapRenderer().destinationCrs() geom = QgsGeometry(item.geometry) geom.transform(QgsCoordinateTransform(src_crs, dest_crs)) return geom
def processAlgorithm(self, feedback): extent = str(self.getParameterValue(self.EXTENT)).split(',') spacing = float(self.getParameterValue(self.SPACING)) inset = float(self.getParameterValue(self.INSET)) randomize = self.getParameterValue(self.RANDOMIZE) isSpacing = self.getParameterValue(self.IS_SPACING) crsId = self.getParameterValue(self.CRS) crs = QgsCoordinateReferenceSystem() crs.createFromUserInput(crsId) extent = QgsRectangle(float(extent[0]), float(extent[2]), float(extent[1]), float(extent[3])) fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.Point, crs) if randomize: seed() area = extent.width() * extent.height() if isSpacing: pSpacing = spacing else: pSpacing = sqrt(area / spacing) f = QgsFeature() f.initAttributes(1) f.setFields(fields) count = 0 total = 100.0 / (area / pSpacing) y = extent.yMaximum() - inset extent_geom = QgsGeometry.fromRect(extent) extent_engine = QgsGeometry.createGeometryEngine(extent_geom.geometry()) extent_engine.prepareGeometry() while y >= extent.yMinimum(): x = extent.xMinimum() + inset while x <= extent.xMaximum(): if randomize: geom = QgsGeometry().fromPoint(QgsPoint( uniform(x - (pSpacing / 2.0), x + (pSpacing / 2.0)), uniform(y - (pSpacing / 2.0), y + (pSpacing / 2.0)))) else: geom = QgsGeometry().fromPoint(QgsPoint(x, y)) if extent_engine.intersects(geom.geometry()): f.setAttribute('id', count) f.setGeometry(geom) writer.addFeature(f) x += pSpacing count += 1 feedback.setProgress(int(count * total)) y = y - pSpacing del writer
def processAlgorithm(self, progress): source = self.getParameterValue(self.INPUT) vlayer = dataobjects.getObjectFromUri(source) output = self.getOutputFromName(self.OUTPUT) fields = vlayer.fields() x_field_index = fields.lookupField(self.getParameterValue(self.XFIELD)) y_field_index = fields.lookupField(self.getParameterValue(self.YFIELD)) z_field_index = None if self.getParameterValue(self.ZFIELD): z_field_index = fields.lookupField(self.getParameterValue(self.ZFIELD)) m_field_index = None if self.getParameterValue(self.MFIELD): m_field_index = fields.lookupField(self.getParameterValue(self.MFIELD)) wkb_type = QgsWkbTypes.Point if z_field_index is not None: wkb_type = QgsWkbTypes.addZ(wkb_type) if m_field_index is not None: wkb_type = QgsWkbTypes.addM(wkb_type) crsId = self.getParameterValue(self.TARGET_CRS) target_crs = QgsCoordinateReferenceSystem() target_crs.createFromUserInput(crsId) writer = output.getVectorWriter(fields, wkb_type, target_crs) features = vector.features(vlayer) total = 100.0 / len(features) for current, feature in enumerate(features): progress.setPercentage(int(current * total)) attrs = feature.attributes() try: x = float(attrs[x_field_index]) y = float(attrs[y_field_index]) point = QgsPointV2(x, y) if z_field_index is not None: try: point.addZValue(float(attrs[z_field_index])) except: point.addZValue(0.0) if m_field_index is not None: try: point.addMValue(float(attrs[m_field_index])) except: point.addMValue(0.0) feature.setGeometry(QgsGeometry(point)) except: pass # no geometry writer.addFeature(feature) del writer
def selectProjection(self): dialog = QgsGenericProjectionSelector(self.widget) current_crs = QgsCoordinateReferenceSystem(self.combo.currentText()) if current_crs.isValid(): dialog.setSelectedCrsId(current_crs.srsid()) if dialog.exec_(): self.setValue(dialog.selectedAuthId())
def testShowingHiding(self): """ test showing and hiding options """ w = QgsProjectionSelectionWidget() # layer crs w.setOptionVisible(QgsProjectionSelectionWidget.LayerCrs, False) self.assertFalse(w.optionVisible( QgsProjectionSelectionWidget.LayerCrs)) w.setOptionVisible(QgsProjectionSelectionWidget.LayerCrs, True) # should still be hidden, because layer crs not set self.assertFalse(w.optionVisible( QgsProjectionSelectionWidget.LayerCrs)) w.setLayerCrs(QgsCoordinateReferenceSystem('EPSG:3111')) self.assertTrue(w.optionVisible(QgsProjectionSelectionWidget.LayerCrs)) w.setOptionVisible(QgsProjectionSelectionWidget.LayerCrs, False) self.assertFalse(w.optionVisible( QgsProjectionSelectionWidget.LayerCrs)) # project crs w.setOptionVisible(QgsProjectionSelectionWidget.ProjectCrs, False) self.assertFalse( w.optionVisible(QgsProjectionSelectionWidget.ProjectCrs)) w.setOptionVisible(QgsProjectionSelectionWidget.ProjectCrs, True) # should still be hidden, because project crs was not set self.assertFalse( w.optionVisible(QgsProjectionSelectionWidget.ProjectCrs)) QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:3113')) w = QgsProjectionSelectionWidget() w.setOptionVisible(QgsProjectionSelectionWidget.ProjectCrs, True) self.assertTrue( w.optionVisible(QgsProjectionSelectionWidget.ProjectCrs)) w.setOptionVisible(QgsProjectionSelectionWidget.ProjectCrs, False) self.assertFalse( w.optionVisible(QgsProjectionSelectionWidget.ProjectCrs)) # default crs w.setOptionVisible(QgsProjectionSelectionWidget.DefaultCrs, False) self.assertFalse( w.optionVisible(QgsProjectionSelectionWidget.DefaultCrs)) w.setOptionVisible(QgsProjectionSelectionWidget.DefaultCrs, True) self.assertTrue( w.optionVisible(QgsProjectionSelectionWidget.DefaultCrs)) # current crs w = QgsProjectionSelectionWidget() w.setOptionVisible(QgsProjectionSelectionWidget.CurrentCrs, False) self.assertFalse( w.optionVisible(QgsProjectionSelectionWidget.CurrentCrs)) w.setOptionVisible(QgsProjectionSelectionWidget.CurrentCrs, True) self.assertTrue( w.optionVisible(QgsProjectionSelectionWidget.CurrentCrs)) w = QgsProjectionSelectionWidget() w.setCrs(QgsCoordinateReferenceSystem('EPSG:3111')) w.setOptionVisible(QgsProjectionSelectionWidget.CurrentCrs, False) self.assertFalse( w.optionVisible(QgsProjectionSelectionWidget.CurrentCrs)) w.setOptionVisible(QgsProjectionSelectionWidget.CurrentCrs, True) self.assertTrue( w.optionVisible(QgsProjectionSelectionWidget.CurrentCrs)) # not set w = QgsProjectionSelectionWidget() w.setOptionVisible(QgsProjectionSelectionWidget.CrsNotSet, False) self.assertFalse( w.optionVisible(QgsProjectionSelectionWidget.CrsNotSet)) w.setOptionVisible(QgsProjectionSelectionWidget.CrsNotSet, True) self.assertTrue(w.optionVisible( QgsProjectionSelectionWidget.CrsNotSet)) w.setOptionVisible(QgsProjectionSelectionWidget.CrsNotSet, False) self.assertFalse( w.optionVisible(QgsProjectionSelectionWidget.CrsNotSet))
def testAreaMeasureAndUnits(self): """Test a variety of area measurements in different CRS and ellipsoid modes, to check that the calculated areas and units are always consistent """ da = QgsDistanceArea() da.setSourceCrs(QgsCoordinateReferenceSystem.fromSrsId(3452), QgsProject.instance().transformContext()) da.setEllipsoid("NONE") polygon = QgsGeometry.fromPolygonXY( [[ QgsPointXY(0, 0), QgsPointXY(1, 0), QgsPointXY(1, 1), QgsPointXY(2, 1), QgsPointXY(2, 2), QgsPointXY(0, 2), QgsPointXY(0, 0), ]] ) # We check both the measured area AND the units, in case the logic regarding # ellipsoids and units changes in future area = da.measureArea(polygon) units = da.areaUnits() print(("measured {} in {}".format(area, QgsUnitTypes.toString(units)))) assert ((abs(area - 3.0) < 0.00000001 and units == QgsUnitTypes.AreaSquareDegrees) or (abs(area - 37176087091.5) < 0.1 and units == QgsUnitTypes.AreaSquareMeters)) da.setEllipsoid("WGS84") area = da.measureArea(polygon) units = da.areaUnits() print(("measured {} in {}".format(area, QgsUnitTypes.toString(units)))) # should always be in Meters Squared self.assertAlmostEqual(area, 37416879192.9, delta=0.1) self.assertEqual(units, QgsUnitTypes.AreaSquareMeters) # test converting the resultant area area = da.convertAreaMeasurement(area, QgsUnitTypes.AreaSquareMiles) self.assertAlmostEqual(area, 14446.7378, delta=0.001) # now try with a source CRS which is in feet polygon = QgsGeometry.fromPolygonXY( [[ QgsPointXY(1850000, 4423000), QgsPointXY(1851000, 4423000), QgsPointXY(1851000, 4424000), QgsPointXY(1852000, 4424000), QgsPointXY(1852000, 4425000), QgsPointXY(1851000, 4425000), QgsPointXY(1850000, 4423000) ]] ) da.setSourceCrs(QgsCoordinateReferenceSystem.fromSrsId(27469), QgsProject.instance().transformContext()) da.setEllipsoid("NONE") # measurement should be in square feet area = da.measureArea(polygon) units = da.areaUnits() print(("measured {} in {}".format(area, QgsUnitTypes.toString(units)))) self.assertAlmostEqual(area, 2000000, delta=0.001) self.assertEqual(units, QgsUnitTypes.AreaSquareFeet) # test converting the resultant area area = da.convertAreaMeasurement(area, QgsUnitTypes.AreaSquareYards) self.assertAlmostEqual(area, 222222.2222, delta=0.001) da.setEllipsoid("WGS84") # now should be in Square Meters again area = da.measureArea(polygon) units = da.areaUnits() print(("measured {} in {}".format(area, QgsUnitTypes.toString(units)))) self.assertAlmostEqual(area, 184149.37, delta=1.0) self.assertEqual(units, QgsUnitTypes.AreaSquareMeters) # test converting the resultant area area = da.convertAreaMeasurement(area, QgsUnitTypes.AreaSquareYards) self.assertAlmostEqual(area, 220240.8172549, delta=1.0)
def testModel(self): conn = QgsProviderRegistry.instance().providerMetadata( 'postgres').createConnection(self.uri, {}) self.assertTrue(conn) model = QgsDatabaseTableModel(conn) self.assertGreaterEqual(model.rowCount(), 3) old_count = model.rowCount() self.assertEqual(model.columnCount(), 1) tables = [ model.data(model.index(r, 0, QModelIndex()), Qt.DisplayRole) for r in range(model.rowCount()) ] self.assertIn('qgis_test.someData', tables) self.assertIn('qgis_test.some_poly_data', tables) self.assertIn('information_schema.attributes', tables) self.assertEqual( model.data( model.index(tables.index('qgis_test.someData'), 0, QModelIndex()), QgsDatabaseTableModel.RoleTableName), 'someData') self.assertEqual( model.data( model.index(tables.index('qgis_test.someData'), 0, QModelIndex()), QgsDatabaseTableModel.RoleSchema), 'qgis_test') self.assertEqual( model.data( model.index(tables.index('qgis_test.someData'), 0, QModelIndex()), QgsDatabaseTableModel.RoleComment), 'QGIS Test Table') self.assertEqual( model.data( model.index(tables.index('qgis_test.someData'), 0, QModelIndex()), QgsDatabaseTableModel.RoleCrs), QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual( model.data( model.index(tables.index('qgis_test.someData'), 0, QModelIndex()), QgsDatabaseTableModel.RoleCustomInfo), {}) self.assertEqual( model.data( model.index(tables.index('qgis_test.someData'), 0, QModelIndex()), QgsDatabaseTableModel.RoleTableFlags), 4) self.assertEqual( model.data( model.index(tables.index('qgis_test.someData'), 0, QModelIndex()), QgsDatabaseTableModel.RoleWkbType), QgsWkbTypes.Point) self.assertEqual( model.data( model.index(tables.index('qgis_test.some_poly_data'), 0, QModelIndex()), QgsDatabaseTableModel.RoleWkbType), QgsWkbTypes.Polygon) self.assertIsNone( model.data(model.index(model.rowCount(), 0, QModelIndex()), Qt.DisplayRole)) model.refresh() self.assertEqual(model.rowCount(), old_count) fields = QgsFields() fields.append(QgsField('test', QVariant.String)) conn.createVectorTable('qgis_test', 'myNewTable', fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem('EPSG:3857'), False, {}) self.assertEqual(model.rowCount(), old_count) model.refresh() self.assertEqual(model.rowCount(), old_count + 1) tables = [ model.data(model.index(r, 0, QModelIndex()), Qt.DisplayRole) for r in range(model.rowCount()) ] self.assertIn('qgis_test.someData', tables) self.assertIn('qgis_test.some_poly_data', tables) self.assertIn('information_schema.attributes', tables) self.assertIn('qgis_test.myNewTable', tables) conn.createVectorTable('qgis_test', 'myNewTable2', fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem('EPSG:3857'), False, {}) conn.createVectorTable('qgis_test', 'myNewTable3', fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem('EPSG:3857'), False, {}) model.refresh() self.assertEqual(model.rowCount(), old_count + 3) tables = [ model.data(model.index(r, 0, QModelIndex()), Qt.DisplayRole) for r in range(model.rowCount()) ] self.assertIn('qgis_test.someData', tables) self.assertIn('qgis_test.some_poly_data', tables) self.assertIn('information_schema.attributes', tables) self.assertIn('qgis_test.myNewTable', tables) self.assertIn('qgis_test.myNewTable2', tables) self.assertIn('qgis_test.myNewTable3', tables) conn.createVectorTable('qgis_test', 'myNewTable4', fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem('EPSG:3857'), False, {}) conn.dropVectorTable('qgis_test', 'myNewTable2') conn.dropVectorTable('qgis_test', 'myNewTable') model.refresh() self.assertEqual(model.rowCount(), old_count + 2) tables = [ model.data(model.index(r, 0, QModelIndex()), Qt.DisplayRole) for r in range(model.rowCount()) ] self.assertIn('qgis_test.someData', tables) self.assertIn('qgis_test.some_poly_data', tables) self.assertIn('information_schema.attributes', tables) self.assertNotIn('qgis_test.myNewTable', tables) self.assertNotIn('qgis_test.myNewTable2', tables) self.assertIn('qgis_test.myNewTable3', tables) self.assertIn('qgis_test.myNewTable4', tables) conn.dropVectorTable('qgis_test', 'myNewTable3') conn.dropVectorTable('qgis_test', 'myNewTable4') model.refresh() self.assertEqual(model.rowCount(), old_count) tables = [ model.data(model.index(r, 0, QModelIndex()), Qt.DisplayRole) for r in range(model.rowCount()) ] self.assertIn('qgis_test.someData', tables) self.assertIn('qgis_test.some_poly_data', tables) self.assertIn('information_schema.attributes', tables) self.assertNotIn('qgis_test.myNewTable', tables) self.assertNotIn('qgis_test.myNewTable2', tables) self.assertNotIn('qgis_test.myNewTable3', tables) self.assertNotIn('qgis_test.myNewTable4', tables)
def setupUi(self): self.setWindowTitle(self.tr('Parameter definition')) self.setMinimumWidth(300) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setMargin(20) self.label = QLabel(self.tr('Parameter name')) self.verticalLayout.addWidget(self.label) self.nameTextBox = QLineEdit() self.verticalLayout.addWidget(self.nameTextBox) if isinstance(self.param, Parameter): self.nameTextBox.setText(self.param.description) if self.paramType == ModelerParameterDefinitionDialog.PARAMETER_BOOLEAN or \ isinstance(self.param, ParameterBoolean): self.state = QCheckBox() self.state.setText(self.tr('Checked')) self.state.setChecked(False) if self.param is not None: self.state.setChecked(bool(self.param.value)) self.verticalLayout.addWidget(self.state) elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_TABLE_FIELD or \ isinstance(self.param, ParameterTableField): self.verticalLayout.addWidget(QLabel(self.tr('Parent layer'))) self.parentCombo = QComboBox() idx = 0 for param in list(self.alg.inputs.values()): if isinstance(param.param, (ParameterVector, ParameterTable)): self.parentCombo.addItem(param.param.description, param.param.name) if self.param is not None: if self.param.parent == param.param.name: self.parentCombo.setCurrentIndex(idx) idx += 1 self.verticalLayout.addWidget(self.parentCombo) # add the datatype selector self.verticalLayout.addWidget(QLabel(self.tr('Allowed data type'))) self.datatypeCombo = QComboBox() self.datatypeCombo.addItem(self.tr('Any'), -1) self.datatypeCombo.addItem(self.tr('Number'), 0) self.datatypeCombo.addItem(self.tr('String'), 1) self.datatypeCombo.addItem(self.tr('Date/time'), 2) self.verticalLayout.addWidget(self.datatypeCombo) if self.param is not None and self.param.datatype is not None: # QComboBoxes indexes start at 0, # self.param.datatype start with -1 that is why I need to do +1 datatypeIndex = self.param.datatype + 1 self.datatypeCombo.setCurrentIndex(datatypeIndex) self.multipleCheck = QCheckBox() self.multipleCheck.setText(self.tr('Accept multiple fields')) self.multipleCheck.setChecked(False) if self.param is not None: self.multipleCheck.setChecked(self.param.multiple) self.verticalLayout.addWidget(self.multipleCheck) elif (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_VECTOR or isinstance(self.param, ParameterVector)): self.verticalLayout.addWidget(QLabel(self.tr('Shape type'))) self.shapetypeCombo = QComboBox() self.shapetypeCombo.addItem(self.tr('Any')) self.shapetypeCombo.addItem(self.tr('Point')) self.shapetypeCombo.addItem(self.tr('Line')) self.shapetypeCombo.addItem(self.tr('Polygon')) if self.param is not None: self.shapetypeCombo.setCurrentIndex(self.param.datatype[0] + 1) self.verticalLayout.addWidget(self.shapetypeCombo) elif (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_MULTIPLE or isinstance(self.param, ParameterMultipleInput)): self.verticalLayout.addWidget(QLabel(self.tr('Data type'))) self.datatypeCombo = QComboBox() self.datatypeCombo.addItem(self.tr('Vector (any)')) self.datatypeCombo.addItem(self.tr('Vector (point)')) self.datatypeCombo.addItem(self.tr('Vector (line)')) self.datatypeCombo.addItem(self.tr('Vector (polygon)')) self.datatypeCombo.addItem(self.tr('Raster')) self.datatypeCombo.addItem(self.tr('File')) if self.param is not None: self.datatypeCombo.setCurrentIndex(self.param.datatype + 1) self.verticalLayout.addWidget(self.datatypeCombo) elif (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_NUMBER or isinstance(self.param, ParameterNumber)): self.verticalLayout.addWidget(QLabel(self.tr('Min value'))) self.minTextBox = QLineEdit() self.verticalLayout.addWidget(self.minTextBox) self.verticalLayout.addWidget(QLabel(self.tr('Max value'))) self.maxTextBox = QLineEdit() self.verticalLayout.addWidget(self.maxTextBox) if self.param is not None: self.minTextBox.setText(str(self.param.min)) self.maxTextBox.setText(str(self.param.max)) self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultTextBox = QLineEdit() self.defaultTextBox.setText(self.tr('0')) if self.param is not None: default = self.param.default if self.param.isInteger: default = int(math.floor(default)) if default: self.defaultTextBox.setText(str(default)) self.verticalLayout.addWidget(self.defaultTextBox) elif (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_EXPRESSION or isinstance(self.param, ParameterExpression)): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultEdit = QgsExpressionLineEdit() if self.param is not None: self.defaultEdit.setExpression(self.param.default) self.verticalLayout.addWidget(self.defaultEdit) self.verticalLayout.addWidget(QLabel(self.tr('Parent layer'))) self.parentCombo = QComboBox() self.parentCombo.addItem(self.tr("None"), None) idx = 1 for param in list(self.alg.inputs.values()): if isinstance(param.param, (ParameterVector, ParameterTable)): self.parentCombo.addItem(param.param.description, param.param.name) if self.param is not None: if self.param.parent_layer == param.param.name: self.parentCombo.setCurrentIndex(idx) idx += 1 self.verticalLayout.addWidget(self.parentCombo) elif (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_STRING or isinstance(self.param, ParameterString)): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultTextBox = QLineEdit() if self.param is not None: self.defaultTextBox.setText(self.param.default) self.verticalLayout.addWidget(self.defaultTextBox) elif (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_FILE or isinstance(self.param, ParameterFile)): self.verticalLayout.addWidget(QLabel(self.tr('Type'))) self.fileFolderCombo = QComboBox() self.fileFolderCombo.addItem(self.tr('File')) self.fileFolderCombo.addItem(self.tr('Folder')) if self.param is not None: self.fileFolderCombo.setCurrentIndex( 1 if self.param.isFolder else 0) self.verticalLayout.addWidget(self.fileFolderCombo) elif (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_POINT or isinstance(self.param, ParameterPoint)): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultTextBox = QLineEdit() if self.param is not None: self.defaultTextBox.setText(self.param.default) self.verticalLayout.addWidget(self.defaultTextBox) elif (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_CRS or isinstance(self.param, ParameterCrs)): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.selector = QgsProjectionSelectionWidget() if self.param is not None: self.selector.setCrs(QgsCoordinateReferenceSystem(self.param.default)) else: self.selector.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.verticalLayout.addWidget(self.selector) self.verticalLayout.addSpacing(20) self.requiredCheck = QCheckBox() self.requiredCheck.setText(self.tr('Mandatory')) self.requiredCheck.setChecked(True) if self.param is not None: self.requiredCheck.setChecked(not self.param.optional) self.verticalLayout.addWidget(self.requiredCheck) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.buttonBox.setObjectName('buttonBox') self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) self.verticalLayout.addStretch() self.verticalLayout.addWidget(self.buttonBox) self.setLayout(self.verticalLayout)
def testMaterialize(self): """ Test materializing layers """ layer = createLayerWithFivePoints() original_features = {f[0]: f for f in layer.getFeatures()} # materialize all features, unchanged request = QgsFeatureRequest() new_layer = layer.materialize(request) self.assertEqual(new_layer.fields(), layer.fields()) self.assertEqual(new_layer.crs(), layer.crs()) self.assertEqual(new_layer.featureCount(), 5) self.assertEqual(new_layer.wkbType(), QgsWkbTypes.Point) new_features = {f[0]: f for f in new_layer.getFeatures()} for id, f in original_features.items(): self.assertEqual(new_features[id].attributes(), f.attributes()) self.assertEqual(new_features[id].geometry().asWkt(), f.geometry().asWkt()) # materialize with no geometry request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry) new_layer = layer.materialize(request) self.assertEqual(new_layer.fields(), layer.fields()) self.assertEqual(new_layer.crs(), layer.crs()) self.assertEqual(new_layer.featureCount(), 5) self.assertEqual(new_layer.wkbType(), QgsWkbTypes.NoGeometry) new_features = {f[0]: f for f in new_layer.getFeatures()} for id, f in original_features.items(): self.assertEqual(new_features[id].attributes(), f.attributes()) # materialize with reprojection request = QgsFeatureRequest().setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3785'), QgsProject.instance().transformContext()) new_layer = layer.materialize(request) self.assertEqual(new_layer.fields(), layer.fields()) self.assertEqual(new_layer.crs().authid(), 'EPSG:3785') self.assertEqual(new_layer.featureCount(), 5) self.assertEqual(new_layer.wkbType(), QgsWkbTypes.Point) new_features = {f[0]: f for f in new_layer.getFeatures()} expected_geometry = {1: 'Point (111319 222684)', 2: 'Point (222639 222684)', 3: 'Point (333958 222684)', 4: 'Point (445278 334111)', 5: 'Point (0 -0)'} for id, f in original_features.items(): self.assertEqual(new_features[id].attributes(), f.attributes()) self.assertEqual(new_features[id].geometry().asWkt(0), expected_geometry[id]) # materialize with attribute subset request = QgsFeatureRequest().setSubsetOfAttributes([0, 2]) new_layer = layer.materialize(request) self.assertEqual(new_layer.fields().count(), 2) self.assertEqual(new_layer.fields().at(0), layer.fields().at(0)) self.assertEqual(new_layer.fields().at(1), layer.fields().at(2)) self.assertEqual(new_layer.crs(), layer.crs()) self.assertEqual(new_layer.featureCount(), 5) self.assertEqual(new_layer.wkbType(), QgsWkbTypes.Point) new_features = {f.attributes()[0]: f for f in new_layer.getFeatures()} for id, f in original_features.items(): self.assertEqual(new_features[id].attributes()[0], f.attributes()[0]) self.assertEqual(new_features[id].attributes()[1], f.attributes()[2]) request = QgsFeatureRequest().setSubsetOfAttributes([0, 1]) new_layer = layer.materialize(request) self.assertEqual(new_layer.fields().count(), 2) self.assertEqual(new_layer.fields().at(0), layer.fields().at(0)) self.assertEqual(new_layer.fields().at(1), layer.fields().at(1)) new_features = {f.attributes()[0]: f for f in new_layer.getFeatures()} for id, f in original_features.items(): self.assertEqual(new_features[id].attributes()[0], f.attributes()[0]) self.assertEqual(new_features[id].attributes()[1], f.attributes()[1]) request = QgsFeatureRequest().setSubsetOfAttributes([0]) new_layer = layer.materialize(request) self.assertEqual(new_layer.fields().count(), 1) self.assertEqual(new_layer.fields().at(0), layer.fields().at(0)) new_features = {f.attributes()[0]: f for f in new_layer.getFeatures()} for id, f in original_features.items(): self.assertEqual(new_features[id].attributes()[0], f.attributes()[0])
def testLayerMode(self): """ Create a fully populated QgsLayerMetadata object, then set it to the widget and re-read back the generated metadata to ensure that no content is lost. """ w = QgsMetadataWidget() m = QgsLayerMetadata() m.setIdentifier('1234') m.setParentIdentifier('xyz') m.setLanguage('en-CA') m.setType('dataset') m.setTitle('roads') m.setAbstract('my roads') m.setFees('None') m.setConstraints([QgsLayerMetadata.Constraint('None', 'access')]) m.setRights(['Copyright foo 2017']) m.setLicenses(['WTFPL']) m.setHistory(['history a', 'history b']) m.setKeywords({ 'GEMET': ['kw1', 'kw2'], 'gmd:topicCategory': ['natural'], }) #m.setEncoding('utf-8') m.setCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326')) e = QgsLayerMetadata.Extent() se = QgsLayerMetadata.SpatialExtent() se.extentCrs = QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326') se.bounds = QgsBox3d(-180, -90, 0, 180, 90, 0) e.setSpatialExtents([se]) dates = [ QgsDateTimeRange( QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)), QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47))) ] e.setTemporalExtents(dates) m.setExtent(e) c = QgsLayerMetadata.Contact() c.name = 'John Smith' c.organization = 'ACME' c.position = 'staff' c.voice = '1500 515 555' c.fax = 'xx.xxx.xxx.xxxx' c.email = '*****@*****.**' c.role = 'pointOfContact' address = QgsLayerMetadata.Address() address.type = 'postal' address.address = '123 Main Street' address.city = 'anycity' address.administrativeArea = 'anyprovince' address.postalCode = '90210' address.country = 'Canada' c.addresses = [address] m.setContacts([c]) l = QgsLayerMetadata.Link() l.name = 'geonode:roads' l.type = 'OGC:WMS' l.description = 'my GeoNode road layer' l.url = 'http://example.org/wms' l2 = QgsLayerMetadata.Link() l2.name = 'geonode:roads' l2.type = 'OGC:WFS' l2.description = 'my GeoNode road layer' l2.url = 'http://example.org/wfs' l3 = QgsLayerMetadata.Link() l3.name = 'roads' l3.type = 'WWW:LINK' l3.description = 'full dataset download' l3.url = 'http://example.org/roads.tgz' l3.format = 'ESRI Shapefile' l3.mimeType = 'application/gzip' l3.size = '283676' m.setLinks([l, l2, l3]) # set widget metadata w.setMetadata(m) self.assertEqual(w.mode(), QgsMetadataWidget.LayerMetadata) m = w.metadata() self.assertIsInstance(m, QgsLayerMetadata) self.assertEqual(m.identifier(), '1234') self.assertEqual(m.parentIdentifier(), 'xyz') self.assertEqual(m.language(), 'en-CA') self.assertEqual(m.type(), 'dataset') self.assertEqual(m.title(), 'roads') self.assertEqual(m.abstract(), 'my roads') self.assertEqual(m.fees(), 'None') self.assertEqual(m.constraints()[0].constraint, 'None') self.assertEqual(m.constraints()[0].type, 'access') self.assertEqual(m.rights(), ['Copyright foo 2017']) self.assertEqual(m.licenses(), ['WTFPL']) self.assertEqual(m.history(), ['history a', 'history b']) #self.assertEqual(m.encoding(), 'utf-8') self.assertEqual( m.keywords(), {'GEMET': ['kw1', 'kw2'], 'gmd:topicCategory': ['natural']}) self.assertEqual(m.crs().authid(), 'EPSG:4326') extent = m.extent().spatialExtents()[0] self.assertEqual(extent.extentCrs.authid(), 'EPSG:4326') self.assertEqual(extent.bounds.xMinimum(), -180.0) self.assertEqual(extent.bounds.yMinimum(), -90.0) self.assertEqual(extent.bounds.xMaximum(), 180.0) self.assertEqual(extent.bounds.yMaximum(), 90.0) self.assertEqual(m.extent().temporalExtents()[0].begin(), QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47))) self.assertTrue(m.extent().temporalExtents()[0].isInstant()) self.assertEqual(m.contacts()[0].name, 'John Smith') self.assertEqual(m.contacts()[0].organization, 'ACME') self.assertEqual(m.contacts()[0].position, 'staff') self.assertEqual(m.contacts()[0].voice, '1500 515 555') self.assertEqual(m.contacts()[0].fax, 'xx.xxx.xxx.xxxx') self.assertEqual(m.contacts()[0].email, '*****@*****.**') self.assertEqual(m.contacts()[0].role, 'pointOfContact') self.assertEqual(m.contacts()[0].addresses[0].type, 'postal') self.assertEqual(m.contacts()[0].addresses[0].address, '123 Main Street') self.assertEqual(m.contacts()[0].addresses[0].city, 'anycity') self.assertEqual(m.contacts()[0].addresses[0].administrativeArea, 'anyprovince') self.assertEqual(m.contacts()[0].addresses[0].postalCode, '90210') self.assertEqual(m.contacts()[0].addresses[0].country, 'Canada') self.assertEqual(m.links()[0].name, 'geonode:roads') self.assertEqual(m.links()[0].type, 'OGC:WMS') self.assertEqual(m.links()[0].description, 'my GeoNode road layer') self.assertEqual(m.links()[0].url, 'http://example.org/wms') self.assertEqual(m.links()[1].name, 'geonode:roads') self.assertEqual(m.links()[1].type, 'OGC:WFS') self.assertEqual(m.links()[1].description, 'my GeoNode road layer') self.assertEqual(m.links()[1].url, 'http://example.org/wfs') self.assertEqual(m.links()[2].name, 'roads') self.assertEqual(m.links()[2].type, 'WWW:LINK') self.assertEqual(m.links()[2].description, 'full dataset download') self.assertEqual(m.links()[2].url, 'http://example.org/roads.tgz') self.assertEqual(m.links()[2].format, 'ESRI Shapefile') self.assertEqual(m.links()[2].mimeType, 'application/gzip') self.assertEqual(m.links()[2].size, '283676')
def testContextSingle(self): """ Various tests to ensure that datum transforms are correctly set respecting context """ context = QgsCoordinateTransformContext() context.addSourceDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), 1) context.addDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:4283'), 2) context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), 3, 4) transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28354'), QgsCoordinateReferenceSystem('EPSG:28353'), context) # should be no datum transforms self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), -1) # matching source transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:28353'), context) self.assertEqual(transform.sourceDatumTransformId(), 1) self.assertEqual(transform.destinationDatumTransformId(), -1) # matching dest transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28354'), QgsCoordinateReferenceSystem('EPSG:4283'), context) self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), 2) # matching src/dest pair transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem('EPSG:28356'), QgsCoordinateReferenceSystem('EPSG:4283'), context) self.assertEqual(transform.sourceDatumTransformId(), 3) self.assertEqual(transform.destinationDatumTransformId(), 4) # test manual overwriting transform.setSourceDatumTransform(11) transform.setDestinationDatumTransform(13) self.assertEqual(transform.sourceDatumTransformId(), 11) self.assertEqual(transform.destinationDatumTransformId(), 13) # test that auto datum setting occurs when updating src/dest crs transform.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:28356')) self.assertEqual(transform.sourceDatumTransformId(), 3) self.assertEqual(transform.destinationDatumTransformId(), 4) transform.setSourceDatumTransform(11) transform.setDestinationDatumTransform(13) transform.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4283')) self.assertEqual(transform.sourceDatumTransformId(), 3) self.assertEqual(transform.destinationDatumTransformId(), 4) transform.setSourceDatumTransform(11) transform.setDestinationDatumTransform(13) # delayed context set transform = QgsCoordinateTransform() self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), -1) transform.setSourceCrs(QgsCoordinateReferenceSystem('EPSG:28356')) transform.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4283')) self.assertEqual(transform.sourceDatumTransformId(), -1) self.assertEqual(transform.destinationDatumTransformId(), -1) transform.setContext(context) self.assertEqual(transform.sourceDatumTransformId(), 3) self.assertEqual(transform.destinationDatumTransformId(), 4)
def setupUi(self): self.setWindowTitle(self.tr('Parameter Definition')) self.setMinimumWidth(300) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setMargin(20) self.label = QLabel(self.tr('Parameter name')) self.verticalLayout.addWidget(self.label) self.nameTextBox = QLineEdit() self.verticalLayout.addWidget(self.nameTextBox) if isinstance(self.param, QgsProcessingParameterDefinition): self.nameTextBox.setText(self.param.description()) if self.paramType == parameters.PARAMETER_BOOLEAN or \ isinstance(self.param, QgsProcessingParameterBoolean): self.state = QCheckBox() self.state.setText(self.tr('Checked')) self.state.setChecked(False) if self.param is not None: self.state.setChecked(bool(self.param.defaultValue())) self.verticalLayout.addWidget(self.state) elif self.paramType == parameters.PARAMETER_TABLE_FIELD or \ isinstance(self.param, QgsProcessingParameterField): self.verticalLayout.addWidget(QLabel(self.tr('Parent layer'))) self.parentCombo = QComboBox() idx = 0 for param in list(self.alg.parameterComponents().values()): definition = self.alg.parameterDefinition( param.parameterName()) if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer)): self.parentCombo.addItem(definition.description(), definition.name()) if self.param is not None: if self.param.parentLayerParameterName( ) == definition.name(): self.parentCombo.setCurrentIndex(idx) idx += 1 self.verticalLayout.addWidget(self.parentCombo) # add the datatype selector self.verticalLayout.addWidget(QLabel(self.tr('Allowed data type'))) self.datatypeCombo = QComboBox() self.datatypeCombo.addItem(self.tr('Any'), -1) self.datatypeCombo.addItem(self.tr('Number'), 0) self.datatypeCombo.addItem(self.tr('String'), 1) self.datatypeCombo.addItem(self.tr('Date/time'), 2) self.verticalLayout.addWidget(self.datatypeCombo) if self.param is not None and self.param.dataType() is not None: # QComboBoxes indexes start at 0, # self.param.datatype start with -1 that is why I need to do +1 datatypeIndex = self.param.dataType() + 1 self.datatypeCombo.setCurrentIndex(datatypeIndex) self.multipleCheck = QCheckBox() self.multipleCheck.setText(self.tr('Accept multiple fields')) self.multipleCheck.setChecked(False) if self.param is not None: self.multipleCheck.setChecked(self.param.allowMultiple()) self.verticalLayout.addWidget(self.multipleCheck) self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultTextBox = QLineEdit() self.defaultTextBox.setToolTip( self. tr('Default field name, or ; separated list of field names for multiple field parameters' )) if self.param is not None: default = self.param.defaultValue() if default is not None: self.defaultTextBox.setText(str(default)) self.verticalLayout.addWidget(self.defaultTextBox) elif self.paramType == parameters.PARAMETER_BAND or \ isinstance(self.param, QgsProcessingParameterBand): self.verticalLayout.addWidget(QLabel(self.tr('Parent layer'))) self.parentCombo = QComboBox() idx = 0 for param in list(self.alg.parameterComponents().values()): definition = self.alg.parameterDefinition( param.parameterName()) if isinstance(definition, (QgsProcessingParameterRasterLayer)): self.parentCombo.addItem(definition.description(), definition.name()) if self.param is not None: if self.param.parentLayerParameterName( ) == definition.name(): self.parentCombo.setCurrentIndex(idx) idx += 1 self.verticalLayout.addWidget(self.parentCombo) elif (self.paramType in (parameters.PARAMETER_VECTOR, parameters.PARAMETER_TABLE) or isinstance(self.param, (QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer))): self.verticalLayout.addWidget(QLabel(self.tr('Geometry type'))) self.shapetypeCombo = QComboBox() self.shapetypeCombo.addItem(self.tr('Geometry Not Required'), QgsProcessing.TypeVector) self.shapetypeCombo.addItem(self.tr('Point'), QgsProcessing.TypeVectorPoint) self.shapetypeCombo.addItem(self.tr('Line'), QgsProcessing.TypeVectorLine) self.shapetypeCombo.addItem(self.tr('Polygon'), QgsProcessing.TypeVectorPolygon) self.shapetypeCombo.addItem(self.tr('Any Geometry Type'), QgsProcessing.TypeVectorAnyGeometry) if self.param is not None: self.shapetypeCombo.setCurrentIndex( self.shapetypeCombo.findData(self.param.dataTypes()[0])) self.verticalLayout.addWidget(self.shapetypeCombo) elif (self.paramType == parameters.PARAMETER_MULTIPLE or isinstance(self.param, QgsProcessingParameterMultipleLayers)): self.verticalLayout.addWidget(QLabel(self.tr('Data type'))) self.datatypeCombo = QComboBox() self.datatypeCombo.addItem(self.tr('Any Map Layer'), QgsProcessing.TypeMapLayer) self.datatypeCombo.addItem( self.tr('Vector (No Geometry Required)'), QgsProcessing.TypeVector) self.datatypeCombo.addItem(self.tr('Vector (Point)'), QgsProcessing.TypeVectorPoint) self.datatypeCombo.addItem(self.tr('Vector (Line)'), QgsProcessing.TypeVectorLine) self.datatypeCombo.addItem(self.tr('Vector (Polygon)'), QgsProcessing.TypeVectorPolygon) self.datatypeCombo.addItem(self.tr('Vector (Any Geometry Type)'), QgsProcessing.TypeVectorAnyGeometry) self.datatypeCombo.addItem(self.tr('Raster'), QgsProcessing.TypeRaster) self.datatypeCombo.addItem(self.tr('File'), QgsProcessing.TypeFile) if self.param is not None: self.datatypeCombo.setCurrentIndex( self.datatypeCombo.findData(self.param.layerType())) self.verticalLayout.addWidget(self.datatypeCombo) elif (self.paramType == parameters.PARAMETER_NUMBER or self.paramType == parameters.PARAMETER_DISTANCE or isinstance(self.param, (QgsProcessingParameterNumber, QgsProcessingParameterDistance))): self.verticalLayout.addWidget(QLabel(self.tr('Min value'))) self.minTextBox = QLineEdit() self.verticalLayout.addWidget(self.minTextBox) self.verticalLayout.addWidget(QLabel(self.tr('Max value'))) self.maxTextBox = QLineEdit() self.verticalLayout.addWidget(self.maxTextBox) if self.param is not None: self.minTextBox.setText(str(self.param.minimum())) self.maxTextBox.setText(str(self.param.maximum())) self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultTextBox = QLineEdit() self.defaultTextBox.setText(self.tr('0')) if self.param is not None: default = self.param.defaultValue() if self.param.dataType( ) == QgsProcessingParameterNumber.Integer: default = int(math.floor(default)) if default: self.defaultTextBox.setText(str(default)) self.verticalLayout.addWidget(self.defaultTextBox) elif (self.paramType == parameters.PARAMETER_EXPRESSION or isinstance(self.param, QgsProcessingParameterExpression)): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultEdit = QgsExpressionLineEdit() if self.param is not None: self.defaultEdit.setExpression(self.param.defaultValue()) self.verticalLayout.addWidget(self.defaultEdit) self.verticalLayout.addWidget(QLabel(self.tr('Parent layer'))) self.parentCombo = QComboBox() self.parentCombo.addItem(self.tr("None"), None) idx = 1 for param in list(self.alg.parameterComponents().values()): definition = self.alg.parameterDefinition( param.parameterName()) if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer)): self.parentCombo.addItem(definition.description(), definition.name()) if self.param is not None: if self.param.parentLayerParameterName( ) == definition.name(): self.parentCombo.setCurrentIndex(idx) idx += 1 self.verticalLayout.addWidget(self.parentCombo) elif (self.paramType == parameters.PARAMETER_STRING or isinstance(self.param, QgsProcessingParameterString)): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultTextBox = QLineEdit() if self.param is not None: self.defaultTextBox.setText(self.param.defaultValue()) self.verticalLayout.addWidget(self.defaultTextBox) elif (self.paramType == parameters.PARAMETER_FILE or isinstance(self.param, QgsProcessingParameterFile)): self.verticalLayout.addWidget(QLabel(self.tr('Type'))) self.fileFolderCombo = QComboBox() self.fileFolderCombo.addItem(self.tr('File')) self.fileFolderCombo.addItem(self.tr('Folder')) if self.param is not None: self.fileFolderCombo.setCurrentIndex(1 if self.param.behavior( ) == QgsProcessingParameterFile.Folder else 0) self.verticalLayout.addWidget(self.fileFolderCombo) elif (self.paramType == parameters.PARAMETER_POINT or isinstance(self.param, QgsProcessingParameterPoint)): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultTextBox = QLineEdit() if self.param is not None: self.defaultTextBox.setText(self.param.defaultValue()) self.verticalLayout.addWidget(self.defaultTextBox) elif (self.paramType == parameters.PARAMETER_CRS or isinstance(self.param, QgsProcessingParameterCrs)): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.selector = QgsProjectionSelectionWidget() if self.param is not None: self.selector.setCrs( QgsCoordinateReferenceSystem(self.param.defaultValue())) else: self.selector.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.verticalLayout.addWidget(self.selector) elif self.paramType == parameters.PARAMETER_ENUM or \ isinstance(self.param, QgsProcessingParameterEnum): self.widget = EnumModelerWidget(self) if self.param is not None: self.widget.setAllowMultiple(bool(self.param.allowMultiple())) self.widget.setOptions(self.param.options()) self.widget.setDefault(self.param.defaultValue()) self.verticalLayout.addWidget(self.widget) elif self.paramType == parameters.PARAMETER_MATRIX or \ isinstance(self.param, QgsProcessingParameterMatrix): self.widget = MatrixModelerWidget(self) if self.param is not None: self.widget.setValue(self.param.headers(), self.param.defaultValue()) self.widget.setFixedRows(self.param.hasFixedNumberRows()) self.verticalLayout.addWidget(self.widget) elif isinstance(self.param, QgsProcessingDestinationParameter): self.verticalLayout.addWidget(QLabel(self.tr('Default value'))) self.defaultWidget = DestinationSelectionPanel( self.param, self.alg, default_selection=True) self.verticalLayout.addWidget(self.defaultWidget) self.verticalLayout.addSpacing(20) self.requiredCheck = QCheckBox() self.requiredCheck.setText(self.tr('Mandatory')) self.requiredCheck.setChecked(True) if self.param is not None: self.requiredCheck.setChecked( not self.param.flags() & QgsProcessingParameterDefinition.FlagOptional) self.verticalLayout.addWidget(self.requiredCheck) # If child algorithm output is mandatory, disable checkbox if isinstance(self.param, QgsProcessingDestinationParameter): provider_name, child_name, output_name = self.param.name().split( ':') child = self.alg.childAlgorithms()['{}:{}'.format( provider_name, child_name)] model_output = child.modelOutput(output_name) param_def = child.algorithm().parameterDefinition( model_output.childOutputName()) if not (param_def.flags() & QgsProcessingParameterDefinition.FlagOptional): self.requiredCheck.setEnabled(False) self.requiredCheck.setChecked(True) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.buttonBox.setObjectName('buttonBox') self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.verticalLayout.addStretch() self.verticalLayout.addWidget(self.buttonBox) self.setLayout(self.verticalLayout)
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) value_field_name = self.parameterAsString(parameters, self.VALUES_FIELD_NAME, context) category_field_name = self.parameterAsString( parameters, self.CATEGORIES_FIELD_NAME, context) value_field_index = source.fields().lookupField(value_field_name) category_field_index = source.fields().lookupField(category_field_name) features = source.getFeatures(QgsFeatureRequest().setFlags( QgsFeatureRequest.NoGeometry)) total = 100.0 / source.featureCount() if source.featureCount() else 0 values = {} for current, feat in enumerate(features): if feedback.isCanceled(): break feedback.setProgress(int(current * total)) attrs = feat.attributes() try: value = float(attrs[value_field_index]) cat = attrs[category_field_index] if cat not in values: values[cat] = [] values[cat].append(value) except: pass fields = QgsFields() fields.append(source.fields().at(category_field_index)) fields.append(QgsField('min', QVariant.Double)) fields.append(QgsField('max', QVariant.Double)) fields.append(QgsField('mean', QVariant.Double)) fields.append(QgsField('stddev', QVariant.Double)) fields.append(QgsField('sum', QVariant.Double)) fields.append(QgsField('count', QVariant.Int)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem()) stat = QgsStatisticalSummary(QgsStatisticalSummary.Min | QgsStatisticalSummary.Max | QgsStatisticalSummary.Mean | QgsStatisticalSummary.StDevSample | QgsStatisticalSummary.Sum | QgsStatisticalSummary.Count) for (cat, v) in list(values.items()): stat.calculate(v) f = QgsFeature() f.setAttributes([ cat, stat.min(), stat.max(), stat.mean(), stat.sampleStDev(), stat.sum(), stat.count() ]) sink.addFeature(f, QgsFeatureSink.FastInsert) return {self.OUTPUT: dest_id}
def testSetOutputCrs(self): w = qgis.gui.QgsExtentGroupBox() w.setCheckable(True) # ensure setting output crs doesn't change state of group box w.setChecked(False) w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326')) self.assertFalse(w.isChecked()) w.setChecked(True) w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326')) self.assertTrue(w.isChecked()) w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326')) w.setCurrentExtent(QgsRectangle(1, 2, 3, 4), QgsCoordinateReferenceSystem('epsg:4326')) w.setOutputExtentFromCurrent() self.assertEqual(w.outputExtent(), QgsRectangle(1, 2, 3, 4)) # with reprojection w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:3785')) self.assertEqual( w.outputExtent().toString(4), QgsRectangle(111319.4908, 222684.2085, 333958.4724, 445640.1097).toString(4)) # change CRS back w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326')) # extent should be back to current - not a reprojection of the reprojected bounds self.assertEqual(w.outputExtent().toString(20), QgsRectangle(1, 2, 3, 4).toString(20)) # repeat, this time using original extents w = qgis.gui.QgsExtentGroupBox() w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326')) w.setOriginalExtent(QgsRectangle(1, 2, 3, 4), QgsCoordinateReferenceSystem('epsg:4326')) w.setOutputExtentFromOriginal() self.assertEqual(w.outputExtent(), QgsRectangle(1, 2, 3, 4)) # with reprojection w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:3785')) self.assertEqual( w.outputExtent().toString(4), QgsRectangle(111319.4908, 222684.2085, 333958.4724, 445640.1097).toString(4)) # change CRS back w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326')) # extent should be back to original - not a reprojection of the reprojected bounds self.assertEqual(w.outputExtent().toString(20), QgsRectangle(1, 2, 3, 4).toString(20)) # repeat, this time using layer extent layer = QgsVectorLayer("Polygon?crs=4326", 'memory', 'memory') self.assertTrue(layer.isValid()) f = QgsFeature() f.setGeometry( QgsGeometry.fromWkt('Polygon((1 2, 3 2, 3 4, 1 4, 1 2))')) layer.dataProvider().addFeatures([f]) QgsProject.instance().addMapLayer(layer) w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326')) w.setOutputExtentFromLayer(layer) self.assertEqual(w.outputExtent(), QgsRectangle(1, 2, 3, 4)) w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:3785')) self.assertEqual( w.outputExtent().toString(4), QgsRectangle(111319.4908, 222684.2085, 333958.4724, 445640.1097).toString(4)) # change CRS back w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326')) # extent should be back to original - not a reprojection of the reprojected bounds self.assertEqual(w.outputExtent().toString(20), QgsRectangle(1, 2, 3, 4).toString(20)) # custom extent w = qgis.gui.QgsExtentGroupBox() w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326')) w.setOutputExtentFromUser(QgsRectangle(1, 2, 3, 4), QgsCoordinateReferenceSystem('epsg:4326')) self.assertEqual(w.outputExtent(), QgsRectangle(1, 2, 3, 4)) # with reprojection w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:3785')) self.assertEqual( w.outputExtent().toString(4), QgsRectangle(111319.4908, 222684.2085, 333958.4724, 445640.1097).toString(4)) # change CRS back w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326')) # in this case we can't retrieve the original user extent in 4326, so we have a reprojection of the reprojected bounds # just test this by restricting the test to 4 decimals self.assertEqual(w.outputExtent().toString(4), QgsRectangle(1, 2, 3, 4).toString(4))
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) if source is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT)) field_names = self.parameterAsFields(parameters, self.FIELDS, context) fields = QgsFields() field_indices = [] for field_name in field_names: field_index = source.fields().lookupField(field_name) if field_index < 0: feedback.reportError( self.tr('Invalid field name {}').format(field_name)) continue field = source.fields()[field_index] fields.append(field) field_indices.append(field_index) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem()) results = {} values = set() if len(field_indices) == 1: # one field, can use provider optimised method values = tuple([v] for v in source.uniqueValues(field_indices[0])) else: # have to scan whole table # TODO - add this support to QgsVectorDataProvider so we can run it on # the backend request = QgsFeatureRequest().setFlags( QgsFeatureRequest.NoGeometry) request.setSubsetOfAttributes(field_indices) total = 100.0 / source.featureCount() if source.featureCount( ) else 0 for current, f in enumerate( source.getFeatures( request, QgsProcessingFeatureSource. FlagSkipGeometryValidityChecks)): if feedback.isCanceled(): break value = tuple(f.attribute(i) for i in field_indices) values.add(value) feedback.setProgress(int(current * total)) if sink: for value in values: if feedback.isCanceled(): break f = QgsFeature() f.setAttributes([attr for attr in value]) sink.addFeature(f, QgsFeatureSink.FastInsert) results[self.OUTPUT] = dest_id output_file = self.parameterAsFileOutput(parameters, self.OUTPUT_HTML_FILE, context) if output_file: self.createHTML(output_file, values) results[self.OUTPUT_HTML_FILE] = output_file results[self.TOTAL_VALUES] = len(values) results[self.UNIQUE_VALUES] = ';'.join( [','.join([str(attr) for attr in v]) for v in values]) return results
def accept(self): if self.mode == self.ASK_FOR_INPUT_MODE: # create the input layer (if not already done) and # update available options self.reloadInputLayer() # sanity checks if self.inLayer is None: QMessageBox.information(self, self.tr("Import to database"), self.tr("Input layer missing or not valid")) return if self.cboTable.currentText() == "": QMessageBox.information(self, self.tr("Import to database"), self.tr("Output table name is required")) return if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked(): try: sourceSrid = self.editSourceSrid.text() except ValueError: QMessageBox.information(self, self.tr("Import to database"), self.tr("Invalid source srid: must be an integer")) return if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked(): try: targetSrid = self.editTargetSrid.text() except ValueError: QMessageBox.information(self, self.tr("Import to database"), self.tr("Invalid target srid: must be an integer")) return # override cursor QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # store current input layer crs and encoding, so I can restore it prevInCrs = self.inLayer.crs() prevInEncoding = self.inLayer.dataProvider().encoding() try: schema = self.outUri.schema() if not self.cboSchema.isEnabled() else self.cboSchema.currentText() table = self.cboTable.currentText() # get pk and geom field names from the source layer or use the # ones defined by the user srcUri = QgsDataSourceUri(self.inLayer.source()) pk = srcUri.keyColumn() if not self.chkPrimaryKey.isChecked() else self.editPrimaryKey.text() if not pk: pk = self.default_pk if self.inLayer.hasGeometryType() and self.chkGeomColumn.isEnabled(): geom = srcUri.geometryColumn() if not self.chkGeomColumn.isChecked() else self.editGeomColumn.text() if not geom: geom = self.default_geom else: geom = None options = {} if self.chkLowercaseFieldNames.isEnabled() and self.chkLowercaseFieldNames.isChecked(): pk = pk.lower() if geom: geom = geom.lower() options['lowercaseFieldNames'] = True # get output params, update output URI self.outUri.setDataSource(schema, table, geom, "", pk) uri = self.outUri.uri(False) providerName = self.db.dbplugin().providerName() if self.chkDropTable.isChecked(): options['overwrite'] = True if self.chkSinglePart.isEnabled() and self.chkSinglePart.isChecked(): options['forceSinglePartGeometryType'] = True outCrs = QgsCoordinateReferenceSystem() if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked(): targetSrid = int(self.editTargetSrid.text()) outCrs = QgsCoordinateReferenceSystem(targetSrid) # update input layer crs and encoding if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked(): sourceSrid = int(self.editSourceSrid.text()) inCrs = QgsCoordinateReferenceSystem(sourceSrid) self.inLayer.setCrs(inCrs) if self.chkEncoding.isEnabled() and self.chkEncoding.isChecked(): enc = self.cboEncoding.currentText() self.inLayer.setProviderEncoding(enc) onlySelected = self.chkSelectedFeatures.isChecked() # do the import! ret, errMsg = QgsVectorLayerImport.importLayer(self.inLayer, uri, providerName, outCrs, onlySelected, False, options) except Exception as e: ret = -1 errMsg = str(e) finally: # restore input layer crs and encoding self.inLayer.setCrs(prevInCrs) self.inLayer.setProviderEncoding(prevInEncoding) # restore cursor QApplication.restoreOverrideCursor() if ret != 0: output = QgsMessageViewer() output.setTitle(self.tr("Import to database")) output.setMessageAsPlainText(self.tr("Error {0}\n{1}").format(ret, errMsg)) output.showMessage() return # create spatial index if self.chkSpatialIndex.isEnabled() and self.chkSpatialIndex.isChecked(): self.db.connector.createSpatialIndex((schema, table), geom) QMessageBox.information(self, self.tr("Import to database"), self.tr("Import was successful.")) return QDialog.accept(self)
def start_progress(self): import datetime start = datetime.datetime.now() # Check OS and dep if sys.platform == 'darwin': gdal_os_dep = '/Library/Frameworks/GDAL.framework/Versions/Current/Programs/' else: gdal_os_dep = '' if self.dlg.canvasButton.isChecked(): # Map Canvas extentCanvasCRS = self.iface.mapCanvas() srs = extentCanvasCRS.mapSettings().destinationCrs() crs = str(srs.authid()) # old_crs = osr.SpatialReference() # old_crs.ImportFromEPSG(int(crs[5:])) can_crs = QgsCoordinateReferenceSystem(int(crs[5:])) # can_wkt = extentCanvasCRS.mapRenderer().destinationCrs().toWkt() # can_crs = osr.SpatialReference() # can_crs.ImportFromWkt(can_wkt) # Raster Layer dem_layer = self.layerComboManagerDEM.currentLayer() dem_prov = dem_layer.dataProvider() dem_path = str(dem_prov.dataSourceUri()) dem_raster = gdal.Open(dem_path) projdsm = osr.SpatialReference(wkt=dem_raster.GetProjection()) projdsm.AutoIdentifyEPSG() projdsmepsg = int(projdsm.GetAttrValue('AUTHORITY', 1)) dem_crs = QgsCoordinateReferenceSystem(projdsmepsg) # dem_wkt = dem_raster.GetProjection() # dem_crs = osr.SpatialReference() # dem_crs.ImportFromWkt(dem_wkt) if can_crs != dem_crs: extentCanvas = self.iface.mapCanvas().extent() extentDEM = dem_layer.extent() transformExt = QgsCoordinateTransform(can_crs, dem_crs) # transformExt = osr.CoordinateTransformation(can_crs, dem_crs) canminx = extentCanvas.xMinimum() canmaxx = extentCanvas.xMaximum() canminy = extentCanvas.yMinimum() canmaxy = extentCanvas.yMaximum() canxymin = transformExt.TransformPoint(canminx, canminy) canxymax = transformExt.TransformPoint(canmaxx, canmaxy) extDiffminx = canxymin[0] - extentDEM.xMinimum( ) # If smaller than zero = warning extDiffminy = canxymin[1] - extentDEM.yMinimum( ) # If smaller than zero = warning extDiffmaxx = canxymax[0] - extentDEM.xMaximum( ) # If larger than zero = warning extDiffmaxy = canxymax[0] - extentDEM.yMaximum( ) # If larger than zero = warning if extDiffminx < 0 or extDiffminy < 0 or extDiffmaxx > 0 or extDiffmaxy > 0: QMessageBox.warning( None, "Warning! Extent of map canvas is larger than raster extent.", "Change to an extent equal to or smaller than the raster extent." ) return # Extent self.yMax = self.dlg.lineEditNorth.text() self.yMin = self.dlg.lineEditSouth.text() self.xMin = self.dlg.lineEditWest.text() self.xMax = self.dlg.lineEditEast.text() if not self.DSMoutputfile: QMessageBox.critical(None, "Error", "Specify a raster output file") return if self.dlg.checkBoxPolygon.isChecked() and not self.OSMoutputfile: QMessageBox.critical(None, "Error", "Specify an output file for OSM data") return # Acquiring geodata and attributes dem_layer = self.layerComboManagerDEM.currentLayer() if dem_layer is None: QMessageBox.critical(None, "Error", "No valid raster layer is selected") return else: provider = dem_layer.dataProvider() filepath_dem = str(provider.dataSourceUri()) demRaster = gdal.Open(filepath_dem) dem_layer_crs = osr.SpatialReference() dem_layer_crs.ImportFromWkt(demRaster.GetProjection()) self.dem_layer_unit = dem_layer_crs.GetAttrValue("UNIT") posUnits = [ 'metre', 'US survey foot', 'meter', 'm', 'ft', 'feet', 'foot', 'ftUS', 'International foot' ] # Possible units if not self.dem_layer_unit in posUnits: QMessageBox.critical( None, "Error", "Raster projection is not in metre or foot. Please reproject.") return polygon_layer = self.layerComboManagerPolygon.currentLayer() osm_layer = self.dlg.checkBoxOSM.isChecked() if polygon_layer is None and osm_layer is False: QMessageBox.critical(None, "Error", "No valid building height layer is selected") return elif polygon_layer: vlayer = QgsVectorLayer(polygon_layer.source(), "buildings", "ogr") fileInfo = QFileInfo(polygon_layer.source()) polygon_ln = fileInfo.baseName() polygon_field = self.layerComboManagerPolygonField.currentField() idx = vlayer.fieldNameIndex(polygon_field) flname = vlayer.attributeDisplayName(idx) if idx == -1: QMessageBox.critical( None, "Error", "An attribute with unique fields must be selected") return ### main code ### self.dlg.progressBar.setRange(0, 5) self.dlg.progressBar.setValue(1) if self.dlg.checkBoxOSM.isChecked(): # TODO replace osr.CoordinateTransformation with QgsCoordinateTransform dem_original = gdal.Open(filepath_dem) dem_wkt = dem_original.GetProjection() ras_crs = osr.SpatialReference() ras_crs.ImportFromWkt(dem_wkt) rasEPSG = ras_crs.GetAttrValue("PROJCS|AUTHORITY", 1) if self.dlg.layerButton.isChecked(): old_crs = ras_crs elif self.dlg.canvasButton.isChecked(): canvasCRS = self.iface.mapCanvas() outputWkt = canvasCRS.mapRenderer().destinationCrs().toWkt() old_crs = osr.SpatialReference() old_crs.ImportFromWkt(outputWkt) wgs84_wkt = """ GEOGCS["WGS 84", DATUM["WGS_1984", SPHEROID["WGS 84",6378137,298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich",0, AUTHORITY["EPSG","8901"]], UNIT["degree",0.01745329251994328, AUTHORITY["EPSG","9122"]], AUTHORITY["EPSG","4326"]]""" new_crs = osr.SpatialReference() new_crs.ImportFromWkt(wgs84_wkt) transform = osr.CoordinateTransformation(old_crs, new_crs) minx = float(self.xMin) miny = float(self.yMin) maxx = float(self.xMax) maxy = float(self.yMax) lonlatmin = transform.TransformPoint(minx, miny) lonlatmax = transform.TransformPoint(maxx, maxy) if ras_crs != old_crs: rasTrans = osr.CoordinateTransformation(old_crs, ras_crs) raslonlatmin = rasTrans.TransformPoint(float(self.xMin), float(self.yMin)) raslonlatmax = rasTrans.TransformPoint(float(self.xMax), float(self.yMax)) #else: #raslonlatmin = [float(self.xMin), float(self.yMin)] #raslonlatmax = [float(self.xMax), float(self.yMax)] self.xMin = raslonlatmin[0] self.yMin = raslonlatmin[1] self.xMax = raslonlatmax[0] self.yMax = raslonlatmax[1] # Make data queries to overpass-api urlStr = 'http://overpass-api.de/api/map?bbox=' + str( lonlatmin[0]) + ',' + str(lonlatmin[1]) + ',' + str( lonlatmax[0]) + ',' + str(lonlatmax[1]) osmXml = urllib.urlopen(urlStr).read() #print urlStr # Make OSM building file osmPath = self.plugin_dir + '/temp/OSM_building.osm' osmFile = open(osmPath, 'w') osmFile.write(osmXml) if os.fstat(osmFile.fileno()).st_size < 1: urlStr = 'http://api.openstreetmap.org/api/0.6/map?bbox=' + str( lonlatmin[0]) + ',' + str(lonlatmin[1]) + ',' + str( lonlatmax[0]) + ',' + str(lonlatmax[1]) osmXml = urllib.urlopen(urlStr).read() osmFile.write(osmXml) #print 'Open Street Map' if os.fstat(osmFile.fileno()).st_size < 1: QMessageBox.critical(None, "Error", "No OSM data available") return osmFile.close() outputshp = self.plugin_dir + '/temp/' osmToShape = gdal_os_dep + 'ogr2ogr --config OSM_CONFIG_FILE "' + self.plugin_dir + '/osmconf.ini" -skipfailures -t_srs EPSG:' + str( rasEPSG ) + ' -overwrite -nlt POLYGON -f "ESRI Shapefile" "' + outputshp + '" "' + osmPath + '"' if sys.platform == 'win32': si = subprocess.STARTUPINFO() si.dwFlags |= subprocess.STARTF_USESHOWWINDOW subprocess.call(osmToShape, startupinfo=si) else: os.system(osmToShape) driver = ogr.GetDriverByName('ESRI Shapefile') driver.DeleteDataSource(outputshp + 'lines.shp') driver.DeleteDataSource(outputshp + 'multilinestrings.shp') driver.DeleteDataSource(outputshp + 'other_relations.shp') driver.DeleteDataSource(outputshp + 'points.shp') osmPolygonPath = outputshp + 'multipolygons.shp' vlayer = QgsVectorLayer(osmPolygonPath, 'multipolygons', 'ogr') polygon_layer = vlayer fileInfo = QFileInfo(polygon_layer.source()) polygon_ln = fileInfo.baseName() def renameField(srcLayer, oldFieldName, newFieldName): ds = gdal.OpenEx(srcLayer.source(), gdal.OF_VECTOR | gdal.OF_UPDATE) ds.ExecuteSQL('ALTER TABLE {} RENAME COLUMN {} TO {}'.format( srcLayer.name(), oldFieldName, newFieldName)) srcLayer.reload() vlayer.startEditing() renameField(vlayer, 'building_l', 'bld_levels') renameField(vlayer, 'building_h', 'bld_hght') renameField(vlayer, 'building_c', 'bld_colour') renameField(vlayer, 'building_m', 'bld_materi') renameField(vlayer, 'building_u', 'bld_use') vlayer.commitChanges() vlayer.startEditing() vlayer.dataProvider().addAttributes( [QgsField('bld_height', QVariant.Double, 'double', 3, 2)]) vlayer.updateFields() bld_lvl = vlayer.fieldNameIndex('bld_levels') hght = vlayer.fieldNameIndex('height') bld_hght = vlayer.fieldNameIndex('bld_hght') bld_height = vlayer.fieldNameIndex('bld_height') bldLvlHght = float(self.dlg.doubleSpinBoxBldLvl.value()) illegal_chars = string.ascii_letters + "!#$%&'*+^_`|~:" + " " counterNone = 0 counter = 0 #counterWeird = 0 for feature in vlayer.getFeatures(): if feature[hght]: try: #feature[bld_height] = float(re.sub("[^0-9]", ".", str(feature[hght]))) feature[bld_height] = float( str(feature[hght]).translate(None, illegal_chars)) except: counterNone += 1 elif feature[bld_hght]: try: #feature[bld_height] = float(re.sub("[^0-9]", ".", str(feature[bld_hght]))) feature[bld_height] = float( str(feature[bld_hght]).translate( None, illegal_chars)) except: counterNone += 1 elif feature[bld_lvl]: try: #feature[bld_height] = float(re.sub("[^0-9]", "", str(feature[bld_lvl])))*bldLvlHght feature[bld_height] = float( str(feature[bld_lvl]).translate( None, illegal_chars)) * bldLvlHght except: counterNone += 1 else: counterNone += 1 vlayer.updateFeature(feature) counter += 1 vlayer.commitChanges() flname = vlayer.attributeDisplayName(bld_height) counterDiff = counter - counterNone # Zonal statistics vlayer.startEditing() zoneStat = QgsZonalStatistics(vlayer, filepath_dem, "stat_", 1, QgsZonalStatistics.Mean) zoneStat.calculateStatistics(None) vlayer.dataProvider().addAttributes( [QgsField('height_asl', QVariant.Double)]) vlayer.updateFields() e = QgsExpression('stat_mean + ' + flname) e.prepare(vlayer.pendingFields()) idx = vlayer.fieldNameIndex('height_asl') for f in vlayer.getFeatures(): f[idx] = e.evaluate(f) vlayer.updateFeature(f) vlayer.commitChanges() vlayer.startEditing() idx2 = vlayer.fieldNameIndex('stat_mean') vlayer.dataProvider().deleteAttributes([idx2]) vlayer.updateFields() vlayer.commitChanges() self.dlg.progressBar.setValue(2) # Convert polygon layer to raster # Define pixel_size and NoData value of new raster pixel_size = self.dlg.spinBox.value() # half picture size # Create the destination data source gdalrasterize = gdal_os_dep + 'gdal_rasterize -a ' + 'height_asl' + ' -te ' + str(self.xMin) + ' ' + str(self.yMin) + ' ' + str(self.xMax) + ' ' + str(self.yMax) +\ ' -tr ' + str(pixel_size) + ' ' + str(pixel_size) + ' -l "' + str(polygon_ln) + '" "' \ + str(polygon_layer.source()) + '" "' + self.plugin_dir + '/temp/clipdsm.tif"' # gdalclipdem = gdal_os_dep + 'gdalwarp -dstnodata -9999 -q -overwrite -te ' + str(self.xMin) + ' ' + str(self.yMin) + ' ' + str(self.xMax) + ' ' + str(self.yMax) +\ # ' -tr ' + str(pixel_size) + ' ' + str(pixel_size) + \ # ' -of GTiff ' + '"' + filepath_dem + '" "' + self.plugin_dir + '/temp/clipdem.tif"' # Rasterize if sys.platform == 'win32': si = subprocess.STARTUPINFO() si.dwFlags |= subprocess.STARTF_USESHOWWINDOW subprocess.call(gdalrasterize, startupinfo=si) # subprocess.call(gdalclipdem, startupinfo=si) gdal.Warp(self.plugin_dir + '/temp/clipdem.tif', filepath_dem, xRes=pixel_size, yRes=pixel_size) else: os.system(gdalrasterize) # os.system(gdalclipdem) gdal.Warp(self.plugin_dir + '/temp/clipdem.tif', filepath_dem, xRes=pixel_size, yRes=pixel_size) # Remove gdalwarp with gdal.Translate # bigraster = gdal.Open(filepath_dem) # bbox = (self.xMin, self.yMax, self.xMax, self.yMin) # gdal.Translate(self.plugin_dir + '/data/clipdem.tif', bigraster, projWin=bbox) self.dlg.progressBar.setValue(3) # Adding DSM to DEM # Read DEM dem_raster = gdal.Open(self.plugin_dir + '/temp/clipdem.tif') dem_array = np.array(dem_raster.ReadAsArray().astype(np.float)) dsm_raster = gdal.Open(self.plugin_dir + '/temp/clipdsm.tif') dsm_array = np.array(dsm_raster.ReadAsArray().astype(np.float)) indx = dsm_array.shape for ix in range(0, int(indx[0])): for iy in range(0, int(indx[1])): if int(dsm_array[ix, iy]) == 0: dsm_array[ix, iy] = dem_array[ix, iy] if self.dlg.checkBoxPolygon.isChecked(): vlayer.startEditing() idxHght = vlayer.fieldNameIndex('height_asl') idxBld = vlayer.fieldNameIndex('building') features = vlayer.getFeatures() #for f in vlayer.getFeatures(): for f in features: geom = f.geometry() posUnitsMetre = ['metre', 'meter', 'm'] # Possible metre units posUnitsFt = [ 'US survey foot', 'ft', 'feet', 'foot', 'ftUS', 'International foot' ] # Possible foot units if self.dem_layer_unit in posUnitsMetre: sqUnit = 1 elif self.dem_layer_unit in posUnitsFt: sqUnit = 10.76 if int(geom.area()) > 50000 * sqUnit: vlayer.deleteFeature(f.id()) #if not f[idxHght]: #vlayer.deleteFeature(f.id()) #elif not f[idxBld]: #vlayer.deleteFeature(f.id()) vlayer.updateFields() vlayer.commitChanges() QgsVectorFileWriter.writeAsVectorFormat(vlayer, str(self.OSMoutputfile), "UTF-8", None, "ESRI Shapefile") else: vlayer.startEditing() idx3 = vlayer.fieldNameIndex('height_asl') vlayer.dataProvider().deleteAttributes([idx3]) vlayer.updateFields() vlayer.commitChanges() self.dlg.progressBar.setValue(4) # Save raster def saveraster( gdal_data, filename, raster ): # gdal_data = raster extent, filename = output filename, raster = numpy array (raster to be saved) rows = gdal_data.RasterYSize cols = gdal_data.RasterXSize outDs = gdal.GetDriverByName("GTiff").Create( filename, cols, rows, int(1), gdal.GDT_Float32) outBand = outDs.GetRasterBand(1) # write the data outBand.WriteArray(raster, 0, 0) # flush data to disk, set the NoData value and calculate stats outBand.FlushCache() outBand.SetNoDataValue(-9999) # georeference the image and set the projection outDs.SetGeoTransform(gdal_data.GetGeoTransform()) outDs.SetProjection(gdal_data.GetProjection()) saveraster(dsm_raster, self.DSMoutputfile, dsm_array) # Load result into canvas rlayer = self.iface.addRasterLayer(self.DSMoutputfile) # Trigger a repaint if hasattr(rlayer, "setCacheImage"): rlayer.setCacheImage(None) rlayer.triggerRepaint() self.dlg.progressBar.setValue(5) #runTime = datetime.datetime.now() - start if self.dlg.checkBoxOSM.isChecked(): QMessageBox.information( self.dlg, 'DSM Generator', 'Operation successful! ' + str(counterDiff) + ' building polygons out of ' + str(counter) + ' contained height values.') #self.iface.messageBar().pushMessage("DSM Generator. Operation successful! " + str(counterDiff) + " buildings out of " + str(counter) + " contained height values.", level=QgsMessageBar.INFO, duration=5) else: #self.iface.messageBar().pushMessage("DSM Generator. Operation successful!", level=QgsMessageBar.INFO, duration=5) QMessageBox.information(self.dlg, 'DSM Generator', 'Operation successful!') self.resetPlugin()
def run(self, layers): """Run the impact function. :param layers: List of layers expected to contain at least: H: Polygon layer of inundation areas E: Vector layer of roads :type layers: list :returns: A new line layer with inundated roads marked. :type: safe_layer """ target_field = self.parameters['target_field'] road_type_field = self.parameters['road_type_field'] threshold_min = self.parameters['min threshold [m]'] threshold_max = self.parameters['max threshold [m]'] if threshold_min > threshold_max: message = tr( 'The minimal threshold is greater then the maximal specified ' 'threshold. Please check the values.') raise GetDataError(message) # Extract data H = get_hazard_layer(layers) # Flood E = get_exposure_layer(layers) # Roads question = get_question( H.get_name(), E.get_name(), self) H = H.get_layer() E = E.get_layer() # reproject self.extent to the hazard projection hazard_crs = H.crs() hazard_authid = hazard_crs.authid() if hazard_authid == 'EPSG:4326': viewport_extent = self.extent else: geo_crs = QgsCoordinateReferenceSystem() geo_crs.createFromSrid(4326) viewport_extent = extent_to_geo_array( QgsRectangle(*self.extent), geo_crs, hazard_crs) # Align raster extent and viewport # assuming they are both in the same projection raster_extent = H.dataProvider().extent() clip_xmin = raster_extent.xMinimum() # clip_xmax = raster_extent.xMaximum() clip_ymin = raster_extent.yMinimum() # clip_ymax = raster_extent.yMaximum() if viewport_extent[0] > clip_xmin: clip_xmin = viewport_extent[0] if viewport_extent[1] > clip_ymin: clip_ymin = viewport_extent[1] # TODO: Why have these two clauses when they are not used? # Commenting out for now. # if viewport_extent[2] < clip_xmax: # clip_xmax = viewport_extent[2] # if viewport_extent[3] < clip_ymax: # clip_ymax = viewport_extent[3] height = ((viewport_extent[3] - viewport_extent[1]) / H.rasterUnitsPerPixelY()) height = int(height) width = ((viewport_extent[2] - viewport_extent[0]) / H.rasterUnitsPerPixelX()) width = int(width) raster_extent = H.dataProvider().extent() xmin = raster_extent.xMinimum() xmax = raster_extent.xMaximum() ymin = raster_extent.yMinimum() ymax = raster_extent.yMaximum() x_delta = (xmax - xmin) / H.width() x = xmin for i in range(H.width()): if abs(x - clip_xmin) < x_delta: # We have found the aligned raster boundary break x += x_delta _ = i y_delta = (ymax - ymin) / H.height() y = ymin for i in range(H.width()): if abs(y - clip_ymin) < y_delta: # We have found the aligned raster boundary break y += y_delta clip_extent = [x, y, x + width * x_delta, y + height * y_delta] # Clip and polygonize small_raster = clip_raster( H, width, height, QgsRectangle(*clip_extent)) (flooded_polygon_inside, flooded_polygon_outside) = polygonize_gdal( small_raster, threshold_min, threshold_max) # Filter geometry and data using the extent extent = QgsRectangle(*self.extent) request = QgsFeatureRequest() request.setFilterRect(extent) if flooded_polygon_inside is None: message = tr( 'There are no objects in the hazard layer with "value">%s.' 'Please check the value or use other extent.' % ( threshold_min, )) raise GetDataError(message) # reproject the flood polygons to exposure projection exposure_crs = E.crs() exposure_authid = exposure_crs.authid() if hazard_authid != exposure_authid: flooded_polygon_inside = reproject_vector_layer( flooded_polygon_inside, E.crs()) flooded_polygon_outside = reproject_vector_layer( flooded_polygon_outside, E.crs()) # Clip exposure by the extent # extent_as_polygon = QgsGeometry().fromRect(extent) # no need to clip since It is using a bbox request # line_layer = clip_by_polygon( # E, # extent_as_polygon # ) # Find inundated roads, mark them line_layer = split_by_polygon_in_out( E, flooded_polygon_inside, flooded_polygon_outside, target_field, 1, request) target_field_index = line_layer.dataProvider().\ fieldNameIndex(target_field) # Generate simple impact report epsg = get_utm_epsg(self.extent[0], self.extent[1]) output_crs = QgsCoordinateReferenceSystem(epsg) transform = QgsCoordinateTransform(E.crs(), output_crs) road_len = flooded_len = 0 # Length of roads roads_by_type = dict() # Length of flooded roads by types roads_data = line_layer.getFeatures() road_type_field_index = line_layer.fieldNameIndex(road_type_field) for road in roads_data: attributes = road.attributes() road_type = attributes[road_type_field_index] if road_type.__class__.__name__ == 'QPyNullVariant': road_type = tr('Other') geom = road.geometry() geom.transform(transform) length = geom.length() road_len += length if road_type not in roads_by_type: roads_by_type[road_type] = {'flooded': 0, 'total': 0} roads_by_type[road_type]['total'] += length if attributes[target_field_index] == 1: flooded_len += length roads_by_type[road_type]['flooded'] += length table_body = [ question, TableRow( [ tr('Road Type'), tr('Flooded in the threshold (m)'), tr('Total (m)')], header=True), TableRow([tr('All'), int(flooded_len), int(road_len)]), TableRow(tr('Breakdown by road type'), header=True)] for t, v in roads_by_type.iteritems(): table_body.append( TableRow([t, int(v['flooded']), int(v['total'])]) ) impact_summary = Table(table_body).toNewlineFreeString() map_title = tr('Roads inundated') style_classes = [ dict( label=tr('Not Inundated'), value=0, colour='#1EFC7C', transparency=0, size=0.5), dict( label=tr('Inundated'), value=1, colour='#F31A1C', transparency=0, size=0.5)] style_info = dict( target_field=target_field, style_classes=style_classes, style_type='categorizedSymbol') # Convert QgsVectorLayer to inasafe layer and return it line_layer = Vector( data=line_layer, name=tr('Flooded roads'), keywords={ 'impact_summary': impact_summary, 'map_title': map_title, 'target_field': target_field}, style_info=style_info) return line_layer
def open_lyr_stream(stream, input_file=''): # pylint:disable=too-many-statements """ Opens a lyr file from a binary object """ # maybe we should create a cache of unknown crs properties to selected crs? fallback_crs = QgsCoordinateReferenceSystem() warnings = set() errors = set() def unsupported_object_callback(msg, level=Context.WARNING): if level == Context.WARNING: warnings.add(msg) elif level == Context.CRITICAL: errors.add(msg) context = Context() context.unsupported_object_callback = unsupported_object_callback if Qgis.QGIS_VERSION_INT < 30600: context.invalid_layer_resolver = GuiUtils.get_valid_mime_uri def add_layer(layer, group_node): nonlocal fallback_crs layers = LayerConverter.layer_to_QgsLayer(layer, input_file, context, fallback_crs) for _layer in layers: if not fallback_crs.isValid() and _layer.crs().isValid(): fallback_crs = _layer.crs() QgsProject.instance().addMapLayer(_layer, False) node = group_node.addLayer(_layer) if not layer.visible: node.setItemVisibilityChecked(False) if hasattr(layer, 'renderer') and hasattr( layer.renderer, 'legend_group'): node.setExpanded( layer.renderer.legend_group.editable_or_expanded) elif len(node.children()) > 10: node.setExpanded(False) def add_group(group, parent): group_node = parent.addGroup(group.name) for c in group.children: if isinstance(c, (GroupLayer, BaseMapLayer)): add_group(c, group_node) else: add_layer(c, group_node) if not group.visible: group_node.setItemVisibilityChecked(False) group_node.setExpanded(group.expanded) obj = stream.read_object() if LayerConverter.is_layer(obj): add_layer(obj, QgsProject.instance().layerTreeRoot()) elif LayerConverter.is_group(obj): add_group(obj, QgsProject.instance().layerTreeRoot()) else: iface.messageBar().pushCritical( 'SLYR', '{} layers are not yet supported'.format( obj.__class__.__name__)) return True if warnings or errors: message = '' if errors: message = '<p>The following errors were generated while converting the LYR file:</p>' message += '<ul>' for w in errors: message += '<li>{}</li>'.format( html.escape(w).replace('\n', '<br>')) message += '</ul>' if warnings: if message: message += '<p>Additionally, some warnings were generated:</p>' else: message += '<p>The following warnings were generated while converting the LYR file:</p>' message += '<ul>' for w in warnings: message += '<li>{}</li>'.format( html.escape(w).replace('\n', '<br>')) message += '</ul>' BrowserUtils.show_warning( 'LYR could not be completely converted', 'Convert LYR', message, level=Qgis.Critical if errors else Qgis.Warning) return True
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) value_field_name = self.parameterAsString(parameters, self.VALUES_FIELD_NAME, context) category_field_names = self.parameterAsFields( parameters, self.CATEGORIES_FIELD_NAME, context) value_field_index = source.fields().lookupField(value_field_name) if value_field_index >= 0: value_field = source.fields().at(value_field_index) else: value_field = None category_field_indexes = [ source.fields().lookupField(n) for n in category_field_names ] # generate output fields fields = QgsFields() for c in category_field_indexes: fields.append(source.fields().at(c)) def addField(name): """ Adds a field to the output, keeping the same data type as the value_field """ field = QgsField(value_field) field.setName(name) fields.append(field) if value_field is None: field_type = 'none' fields.append(QgsField('count', QVariant.Int)) elif value_field.isNumeric(): field_type = 'numeric' fields.append(QgsField('count', QVariant.Int)) fields.append(QgsField('unique', QVariant.Int)) fields.append(QgsField('min', QVariant.Double)) fields.append(QgsField('max', QVariant.Double)) fields.append(QgsField('range', QVariant.Double)) fields.append(QgsField('sum', QVariant.Double)) fields.append(QgsField('mean', QVariant.Double)) fields.append(QgsField('median', QVariant.Double)) fields.append(QgsField('stddev', QVariant.Double)) fields.append(QgsField('minority', QVariant.Double)) fields.append(QgsField('majority', QVariant.Double)) fields.append(QgsField('q1', QVariant.Double)) fields.append(QgsField('q3', QVariant.Double)) fields.append(QgsField('iqr', QVariant.Double)) elif value_field.type() in (QVariant.Date, QVariant.Time, QVariant.DateTime): field_type = 'datetime' fields.append(QgsField('count', QVariant.Int)) fields.append(QgsField('unique', QVariant.Int)) fields.append(QgsField('empty', QVariant.Int)) fields.append(QgsField('filled', QVariant.Int)) # keep same data type for these fields addField('min') addField('max') else: field_type = 'string' fields.append(QgsField('count', QVariant.Int)) fields.append(QgsField('unique', QVariant.Int)) fields.append(QgsField('empty', QVariant.Int)) fields.append(QgsField('filled', QVariant.Int)) # keep same data type for these fields addField('min') addField('max') fields.append(QgsField('min_length', QVariant.Int)) fields.append(QgsField('max_length', QVariant.Int)) fields.append(QgsField('mean_length', QVariant.Double)) request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry) if value_field is not None: attrs = [value_field_index] else: attrs = [] attrs.extend(category_field_indexes) request.setSubsetOfAttributes(attrs) features = source.getFeatures(request) total = 50.0 / source.featureCount() if source.featureCount() else 0 if field_type == 'none': values = defaultdict(lambda: 0) else: values = defaultdict(list) for current, feat in enumerate(features): if feedback.isCanceled(): break feedback.setProgress(int(current * total)) attrs = feat.attributes() cat = tuple([attrs[c] for c in category_field_indexes]) if field_type == 'none': values[cat] += 1 continue if field_type == 'numeric': if attrs[value_field_index] == NULL: continue else: value = float(attrs[value_field_index]) elif field_type == 'string': if attrs[value_field_index] == NULL: value = '' else: value = str(attrs[value_field_index]) elif attrs[value_field_index] == NULL: value = NULL else: value = attrs[value_field_index] values[cat].append(value) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem()) if field_type == 'none': self.saveCounts(values, sink, feedback) elif field_type == 'numeric': self.calcNumericStats(values, sink, feedback) elif field_type == 'datetime': self.calcDateTimeStats(values, sink, feedback) else: self.calcStringStats(values, sink, feedback) return {self.OUTPUT: dest_id}
def appGmlToMetadataElementDict(gmlPath): """słownik metadataElementDict na podstawie pliku zbioru APP""" metadataElementDict = {} ns = { 'gco': "http://www.isotc211.org/2005/gco", 'app': "https://www.gov.pl/static/zagospodarowanieprzestrzenne/schemas/app/1.0", 'gmd': "http://www.isotc211.org/2005/gmd", 'gml': "http://www.opengis.net/gml/3.2", 'wfs': "http://www.opengis.net/wfs/2.0", 'xlink': "http://www.w3.org/1999/xlink", 'xsi': "http://www.w3.org/2001/XMLSchema-instance" } root = ET.parse(gmlPath) # E1 element = root.find('//app:AktPlanowaniaPrzestrzennego/app:typPlanu', ns) if element is not None: typPlanu = element.attrib['{%s}title' % ns['xlink']].replace( 'miejscowy', 'miejscowych').replace('plan', 'planów').replace( 'kier.', 'kierunków').replace('zagosp.', 'zagospodarowania').replace( 'przestrz.', 'przestrzennego') metadataElementDict['e1'] = { 'e1_lineEdit': "Zbiór danych przestrzennych dla %s <typ_jednostki> <nazwa_jednostki>" % typPlanu } # E5 date = root.find('//app:AktPlanowaniaPrzestrzennego//app:przestrzenNazw', ns) if date is None: utils.showPopup( "Błąd pliku", "wczytany plik nie jest poprawną definicją GML dla zbioru APP. Zwaliduj plik przed wczytaniem do formularza metadanych", QMessageBox.Warning) return False metadataElementDict['e5'] = [{'e5_lineEdit': date.text}] # E7 - kodowanie z nagłówka GML with open(gmlPath, 'r') as file: line = file.readlines(1)[0] line.replace("'", '"') encoding = re.search('encoding="[a-zA-Z0-9\-]{3,10}"', line)[0].split("=")[-1].strip('"').replace( ' ', '').replace('-', '').lower() if encoding == 'usascii': encoding = 'usAscii' metadataElementDict['e7'] = [{'e7_cmbbx': encoding}] # E9, E10 - słowa kluczowe itemsList = [] date = root.find('//app:AktPlanowaniaPrzestrzennego/app:poziomHierarchii', ns) if date is not None: atrybut_title = date.attrib['{%s}title' % ns['xlink']] atrybut_href = date.attrib['{%s}href' % ns['xlink']] tekst = 'Regionalnym' if atrybut_title == 'regionalny' else 'Lokalne' # poziom administracyjny itemsList.append({ 'e9_lineEdit': tekst, 'e10_cmbbx': 'Data opublikowania', 'e10_dateTimeEdit': QDateTime(2019, 5, 22, 0, 0), 'e10_lineEdit': 'Zakres przestrzenny', 'xlink': "http://inspire.ec.europa.eu/metadata-codelist/SpatialScope" }) # poziom jednostki itemsList.append({ 'e9_lineEdit': atrybut_title, 'e10_cmbbx': 'Data opublikowania', 'e10_dateTimeEdit': QDateTime(2013, 12, 10, 0, 0), 'e10_lineEdit': 'Poziom planu zagospodarowania przestrzennego', 'xlink': "http://inspire.ec.europa.eu/codelist/LevelOfSpatialPlanValue" }) # dodanie domyslnych wartosci kluczowych itemsList.extend(dictionaries.metadataListWidgetsDefaultItems['e9']) metadataElementDict['e9'] = itemsList # E11 layer = QgsVectorLayer(gmlPath + '|layername=AktPlanowaniaPrzestrzennego', "gml", 'ogr') # if not layer.isValid(): # sprawdzanie czy AktPlanowaniaPrzestrzennego jest w wfs:member lub gml:featureMember (bezpośrednio) # layer = QgsVectorLayer(gmlPath + '|layername=featureMember', "gml", 'ogr') if layer.isValid(): sourceCrs = layer.crs() extent = layer.extent() # w zwiazku z niepoprawnym zaczytywaniem zasiegu GML przez QGIS - odwrocenie osi ''' Dla wersji QGIS <= 3.14 przy wczytywaniu GML # z definicją układu # jako uri do opengis.net np. http://www.opengis.net/def/crs/EPSG/0/2177 # QGIS wczytuje zasięg z odwróconymi X i Y # TODO: do wykomentowania gdy błąd zostanie naprawiony w nowej wersji programu # dla starych - pozostaje ''' extentInverted = QgsRectangle(extent.yMinimum(), extent.xMinimum(), extent.yMaximum(), extent.xMaximum()) crsDest = QgsCoordinateReferenceSystem(4326) # WGS84 xform = QgsCoordinateTransform(sourceCrs, crsDest, QgsProject.instance()) extent84 = xform.transform(extentInverted) metadataElementDict['e11'] = [{ 'e11_lineEdit': '%s,%s,%s,%s' % (extent84.xMinimum(), extent84.xMaximum(), extent84.yMinimum(), extent84.yMaximum()) }] # E12 itemsList = [] # szukaj w rysunkach APP for uklad in root.findall('//*/app:ukladOdniesieniaPrzestrzennego', ns): if {'e12_cmbbx': uklad.text} not in itemsList: itemsList.append({'e12_cmbbx': uklad.text}) # szukaj w zasięgach APP for multiSurface in root.findall( '//*/app:zasiegPrzestrzenny/gml:MultiSurface', ns): if {'e12_cmbbx': multiSurface.attrib['srsName']} not in itemsList: itemsList.append({'e12_cmbbx': multiSurface.attrib['srsName']}) metadataElementDict['e12'] = itemsList # E13 dates = [] for date in root.findall( '//app:AktPlanowaniaPrzestrzennego/app:poczatekWersjiObiektu', ns): dates.append(QDateTime.fromString(date.text, "yyyy-MM-dd'T'hh:mm:ss")) oldestDate = utils.oldestQDateTime(dates) if oldestDate is not None: metadataElementDict['e13'] = {'e13_dateTimeEdit': oldestDate} # E16 itemsList = [] for rozdzielczosc in root.findall('//*/app:rozdzielczoscPrzestrzenna', ns): if {'e16_lineEdit': rozdzielczosc.text} not in itemsList: itemsList.append({'e16_lineEdit': rozdzielczosc.text}) metadataElementDict['e16'] = itemsList # E18 i E19 i E24 i E25 itemsList = [] inspire1 = "Rozporządzenie Komisji (UE) Nr 1089/2010 z dnia 23 listopada 2010 r. w sprawie wykonania dyrektywy 2007/2/WE Parlamentu Europejskiego i Rady w zakresie interoperacyjności zbiorów i usług danych przestrzennych" inspire2 = "D2.8.III.4 Data Specification on Land Use – Technical Guidelines" krajowy1 = "Rozporządzenie Ministra Rozwoju, Pracy i Technologii z dnia 26 października 2020 r. w sprawie zbiorów danych przestrzennych oraz metadanych w zakresie zagospodarowania przestrzennego" krajowy2 = "Planowanie przestrzenne: Specyfikacja danych" ifKrajowy = False ifInspire = False namespaces = dict( [node for _, node in ET.iterparse(gmlPath, events=['start-ns'])]) for v in namespaces.values(): if 'https://www.gov.pl/static/zagospodarowanieprzestrzenne' in v: ifKrajowy = True # ifInspire = False break if 'http://inspire.ec.europa.eu/schemas/plu/4.0/PlannedLandUse.xsd' in v: # ifKrajowy = False ifInspire = True break # E18 i E19 inspire1 itemsList.append({ 'e18_lineEdit': inspire1, 'e18_dateTimeEdit': QDateTime(2010, 12, 8, 0, 0), 'e18_cmbbx': 'Data opublikowania', 'e19_cmbbx': 'Zgodny (conformant)' if ifInspire else 'Niezgodny (notConformant)', 'xlink': "http://data.europa.eu/eli/reg/2010/1089" }) # E18 i E19 inspire2 itemsList.append({ 'e18_lineEdit': inspire2, 'e18_dateTimeEdit': QDateTime(2013, 12, 10, 0, 0), 'e18_cmbbx': 'Data opublikowania', 'e19_cmbbx': 'Zgodny (conformant)' if ifInspire else 'Niezgodny (notConformant)' }) # E18 i E19 krajowy1 itemsList.append({ 'e18_lineEdit': krajowy1, 'e18_dateTimeEdit': QDateTime(2020, 10, 31, 0, 0), 'e18_cmbbx': 'Data opublikowania', 'e19_cmbbx': 'Zgodny (conformant)' if ifKrajowy else 'Niezgodny (notConformant)', 'xlink': "https://dziennikustaw.gov.pl/DU/2020/1916" }) # E18 i E19 krajowy2 itemsList.append({ 'e18_lineEdit': krajowy2, 'e18_dateTimeEdit': QDateTime(2020, 10, 31, 0, 0), 'e18_cmbbx': 'Data opublikowania', 'e19_cmbbx': 'Zgodny (conformant)' if ifKrajowy else 'Niezgodny (notConformant)', 'xlink': "" # TODO: uaktualnić po publikacji }) metadataElementDict['e18'] = itemsList # E24 i E25 krajowy itemsList = [] if ifKrajowy: itemsList.append({ 'e24_lineEdit': "Schemat aplikacyjny GML Planowanie przestrzenne", 'e25_lineEdit': "1.0" }) if ifInspire: itemsList.append({ 'e24_lineEdit': "Planned Land Use GML Application Schema", 'e25_lineEdit': "4.0" }) metadataElementDict['e24'] = itemsList return metadataElementDict
def testCreateMemoryLayer(self): """ Test QgsMemoryProviderUtils.createMemoryLayer() """ # no fields layer = QgsMemoryProviderUtils.createMemoryLayer( 'my name', QgsFields()) self.assertTrue(layer.isValid()) self.assertEqual(layer.name(), 'my name') self.assertTrue(layer.fields().isEmpty()) # similar layers should have unique sources layer2 = QgsMemoryProviderUtils.createMemoryLayer( 'my name', QgsFields()) self.assertNotEqual(layer.source(), layer2.source()) # geometry type layer = QgsMemoryProviderUtils.createMemoryLayer( 'my name', QgsFields(), QgsWkbTypes.Point) self.assertTrue(layer.isValid()) self.assertEqual(layer.wkbType(), QgsWkbTypes.Point) layer = QgsMemoryProviderUtils.createMemoryLayer( 'my name', QgsFields(), QgsWkbTypes.PolygonZM) self.assertTrue(layer.isValid()) self.assertEqual(layer.wkbType(), QgsWkbTypes.PolygonZM) # crs layer = QgsMemoryProviderUtils.createMemoryLayer( 'my name', QgsFields(), QgsWkbTypes.PolygonZM, QgsCoordinateReferenceSystem.fromEpsgId(3111)) self.assertTrue(layer.isValid()) self.assertEqual(layer.wkbType(), QgsWkbTypes.PolygonZM) self.assertTrue(layer.crs().isValid()) self.assertEqual(layer.crs().authid(), 'EPSG:3111') # fields fields = QgsFields() fields.append(QgsField("string", QVariant.String)) fields.append(QgsField("long", QVariant.LongLong)) fields.append(QgsField("double", QVariant.Double)) fields.append(QgsField("integer", QVariant.Int)) fields.append(QgsField("date", QVariant.Date)) fields.append(QgsField("datetime", QVariant.DateTime)) fields.append(QgsField("time", QVariant.Time)) layer = QgsMemoryProviderUtils.createMemoryLayer('my name', fields) self.assertTrue(layer.isValid()) self.assertFalse(layer.fields().isEmpty()) self.assertEqual(len(layer.fields()), len(fields)) for i in range(len(fields)): self.assertEqual(layer.fields()[i].name(), fields[i].name()) self.assertEqual(layer.fields()[i].type(), fields[i].type()) # unsupported field type fields = QgsFields() fields.append(QgsField("rect", QVariant.RectF)) layer = QgsMemoryProviderUtils.createMemoryLayer('my name', fields) self.assertTrue(layer.isValid()) self.assertFalse(layer.fields().isEmpty()) self.assertEqual(layer.fields()[0].name(), 'rect') self.assertEqual(layer.fields()[0].type(), QVariant.String) # should be mapped to string
def writeLeaflet(cls, iface, feedback, folder, layer_list, visible, interactive, cluster, json, getFeatureInfo, params, popup): outputProjectFileName = folder QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) legends = {} mapUnitLayers = [] canvas = iface.mapCanvas() project = QgsProject.instance() mapSettings = canvas.mapSettings() title = project.title() abstract = project.metadata().abstract() pluginDir = os.path.dirname(os.path.realpath(__file__)) stamp = datetime.now().strftime("%Y_%m_%d-%H_%M_%S_%f") outputProjectFileName = os.path.join(outputProjectFileName, 'qgis2web_' + stamp) outputIndex = os.path.join(outputProjectFileName, 'index.html') minify = params["Data export"]["Minify GeoJSON files"] precision = params["Data export"]["Precision"] extent = params["Scale/Zoom"]["Extent"] minZoom = params["Scale/Zoom"]["Min zoom level"] maxZoom = params["Scale/Zoom"]["Max zoom level"] restrictToExtent = params["Scale/Zoom"]["Restrict to extent"] matchCRS = params["Appearance"]["Match project CRS"] addressSearch = params["Appearance"]["Add address search"] abstractOptions = params["Appearance"]["Add abstract"] locate = params["Appearance"]["Geolocate user"] measure = params["Appearance"]["Measure tool"] highlight = params["Appearance"]["Highlight on hover"] layerSearch = params["Appearance"]["Layer search"] layerFilter = params["Appearance"]["Attribute filter"] popupsOnHover = params["Appearance"]["Show popups on hover"] template = params["Appearance"]["Template"] widgetAccent = params["Appearance"]["Widget Icon"] widgetBackground = params["Appearance"]["Widget Background"] usedFields = [ALL_ATTRIBUTES] * len(popup) QgsApplication.initQgis() dataStore, cssStore = writeFoldersAndFiles( pluginDir, feedback, outputProjectFileName, cluster, measure, matchCRS, layerSearch, layerFilter, canvas, addressSearch, locate) writeCSS(cssStore, mapSettings.backgroundColor().name(), feedback, widgetAccent, widgetBackground) wfsLayers = "" labelCode = "" vtLabels = {} vtStyles = {} useMultiStyle = False useHeat = False useVT = False useShapes = False useOSMB = False useWMS = False useWMTS = False useRaster = False scaleDependentLayers = "" labelVisibility = "" new_src = "" jsons = "" crs = QgsCoordinateReferenceSystem.EpsgCrsId exp_crs = QgsCoordinateReferenceSystem(4326, crs) lyrCount = 0 for layer, jsonEncode, eachPopup, clst in zip(layer_list, json, popup, cluster): rawLayerName = layer.name() safeLayerName = safeName(rawLayerName) + "_" + str(lyrCount) vts = layer.customProperty("VectorTilesReader/vector_tile_url") if layer.providerType() != 'WFS' or jsonEncode is True: if layer.type() == QgsMapLayer.VectorLayer and vts is None: feedback.showFeedback('Exporting %s to JSON...' % layer.name()) exportVector(layer, safeLayerName, dataStore, restrictToExtent, iface, extent, precision, exp_crs, minify) jsons += jsonScript(safeLayerName) scaleDependentLabels = \ scaleDependentLabelScript(layer, safeLayerName) labelVisibility += scaleDependentLabels feedback.completeStep() elif layer.type() == QgsMapLayer.RasterLayer: if layer.dataProvider().name() != "wms": layersFolder = os.path.join(outputProjectFileName, "data") exportRaster(layer, lyrCount, layersFolder, feedback, iface, matchCRS) if layer.hasScaleBasedVisibility(): scaleDependentLayers += scaleDependentLayerScript( layer, safeLayerName, clst) lyrCount += 1 if scaleDependentLayers != "": scaleDependentLayers = scaleDependentScript(scaleDependentLayers) crsSrc = mapSettings.destinationCrs() crsAuthId = crsSrc.authid() crsProj4 = crsSrc.toProj4() middle = """ """ if highlight or popupsOnHover: selectionColor = mapSettings.selectionColor().name() middle += highlightScript(highlight, popupsOnHover, selectionColor) if extent == "Canvas extent": pt0 = canvas.extent() crsDest = QgsCoordinateReferenceSystem(4326) try: xform = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) except Exception: xform = QgsCoordinateTransform(crsSrc, crsDest) pt1 = xform.transformBoundingBox(pt0) bounds = '[[' + str(pt1.yMinimum()) + ',' bounds += str(pt1.xMinimum()) + '],[' bounds += str(pt1.yMaximum()) + ',' bounds += str(pt1.xMaximum()) + ']]' if matchCRS and crsAuthId != 'EPSG:4326': middle += crsScript(crsAuthId, crsProj4) else: bounds = 0 if matchCRS and crsAuthId != 'EPSG:4326': middle += crsScript(crsAuthId, crsProj4) middle += mapScript(extent, matchCRS, crsAuthId, measure, maxZoom, minZoom, bounds, locate) middle += featureGroupsScript() extentCode = extentScript(extent, restrictToExtent) new_src += middle new_src += extentCode for count, layer in enumerate(layer_list): rawLayerName = layer.name() safeLayerName = safeName(rawLayerName) + "_" + str(count) if (layer.type() == QgsMapLayer.VectorLayer and layer.wkbType() != QgsWkbTypes.NoGeometry): (new_src, legends, wfsLayers, labelCode, vtLabels, vtStyles, useMapUnits, useMultiStyle, useHeat, useVT, useShapes, useOSMB) = writeVectorLayer( layer, safeLayerName, usedFields[count], highlight, popupsOnHover, popup[count], outputProjectFileName, wfsLayers, cluster[count], visible[count], interactive[count], json[count], legends, new_src, canvas, count, restrictToExtent, extent, feedback, labelCode, vtLabels, vtStyles, useMultiStyle, useHeat, useVT, useShapes, useOSMB) if useMapUnits: mapUnitLayers.append(safeLayerName) elif layer.type() == QgsMapLayer.RasterLayer: if layer.dataProvider().name() == "wms": feedback.showFeedback('Writing %s as WMS layer...' % layer.name()) new_obj, useWMS, useWMTS = wmsScript( layer, safeLayerName, useWMS, useWMTS, getFeatureInfo[count]) feedback.completeStep() else: useRaster = True feedback.showFeedback('Writing %s as raster layer...' % layer.name()) new_obj = rasterScript(layer, safeLayerName) feedback.completeStep() if visible[count]: new_obj += """ map.addLayer(layer_""" + safeLayerName + """);""" new_src += new_obj the_src = new_src new_src = jsons + """ <script>""" if len(mapUnitLayers) > 0: new_src += """ var m2px = 1; function newM2px() { var centerLatLng = map.getCenter(); var pointC = map.latLngToContainerPoint(centerLatLng); var pointX = [pointC.x + 100, pointC.y]; var latLngC = map.containerPointToLatLng(pointC); var latLngX = map.containerPointToLatLng(pointX); var distanceX = latLngC.distanceTo(latLngX)/100; reciprocal = 1 / distanceX; m2px = reciprocal; } function geoStyle(m) { return Math.ceil(m * m2px); }""" new_src += getVTStyles(vtStyles) new_src += getVTLabels(vtLabels) new_src += the_src + scaleDependentLayers if title != "": titleStart = titleSubScript(title, 1, "upper right") new_src += titleStart if abstract != "": abstractStart = titleSubScript(abstract, 2, abstractOptions) new_src += abstractStart if addressSearch: address_text = addressSearchScript() new_src += address_text if (params["Appearance"]["Add layers list"] and params["Appearance"]["Add layers list"] != "" and params["Appearance"]["Add layers list"] != "None"): new_src += addLayersList( [], matchCRS, layer_list, cluster, legends, params["Appearance"]["Add layers list"] == "Expanded") if project.readBoolEntry("ScaleBar", "/Enabled", False)[0]: # placement = project.readNumEntry("ScaleBar", "/Placement", 0)[0] # placement = PLACEMENT[placement] # end = scaleBar(placement) end = scaleBar() else: end = '' layerType = "layer" try: if cluster[count]: layerType = "cluster" except Exception: pass searchLayer = "%s_%s" % (layerType, params["Appearance"]["Search layer"]) filterItems = [] for item in params["Appearance"]["Attribute filter"]: filterItem = returnFilterValues(layer_list, item.text().split(": ")[0], item.text().split(": ")[1]) if filterItem: filterItems.append(filterItem) labelList = [] for count, layer in enumerate(layer_list): vts = layer.customProperty("VectorTilesReader/vector_tile_url") safeLayerName = safeName(layer.name()) + "_" + str(count) if (layer.type() == QgsMapLayer.VectorLayer and vts is None): labelling = layer.labeling() if labelling is not None: palyr = labelling.settings() if palyr.fieldName and palyr.fieldName != "": labelList.append("layer_%s" % safeLayerName) labelsList = ",".join(labelList) end += endHTMLscript(wfsLayers, layerSearch, filterItems, labelCode, labelVisibility, searchLayer, useHeat, useRaster, labelsList, mapUnitLayers) new_src += end try: writeHTMLstart(outputIndex, title, cluster, addressSearch, measure, matchCRS, layerSearch, filterItems, canvas, locate, new_src, template, feedback, useMultiStyle, useHeat, useShapes, useOSMB, useWMS, useWMTS, useVT) except Exception: QgsMessageLog.logMessage(traceback.format_exc(), "qgis2web", level=Qgis.Critical) finally: QApplication.restoreOverrideCursor() return outputIndex
def testValidateNative(self): # spellok """ Test validating metadata against QGIS native schema """ m = self.createTestMetadata() v = QgsNativeMetadataValidator() res, list = v.validate(m) self.assertTrue(res) self.assertFalse(list) # corrupt metadata piece by piece... m = self.createTestMetadata() m.setIdentifier('') res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'identifier') m = self.createTestMetadata() m.setLanguage('') res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'language') m = self.createTestMetadata() m.setType('') res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'type') m = self.createTestMetadata() m.setTitle('') res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'title') m = self.createTestMetadata() m.setAbstract('') res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'abstract') m = self.createTestMetadata() m.setLicenses([]) res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'license') m = self.createTestMetadata() m.setCrs(QgsCoordinateReferenceSystem()) res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'crs') m = self.createTestMetadata() m.setContacts([]) res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'contacts') m = self.createTestMetadata() m.setLinks([]) res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'links') m = self.createTestMetadata() m.setKeywords({'': ['kw1', 'kw2']}) res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'keywords') self.assertEqual(list[0].identifier, 0) m = self.createTestMetadata() m.setKeywords({'AA': []}) res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'keywords') self.assertEqual(list[0].identifier, 0) m = self.createTestMetadata() e = m.extent() se = e.spatialExtents()[0] se.extentCrs = QgsCoordinateReferenceSystem() e.setSpatialExtents([se]) m.setExtent(e) res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'extent') self.assertEqual(list[0].identifier, 0) m = self.createTestMetadata() e = m.extent() se = e.spatialExtents()[0] se.bounds = QgsBox3d(1, 1, 0, 1, 2) e.setSpatialExtents([se]) m.setExtent(e) res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'extent') self.assertEqual(list[0].identifier, 0) m = self.createTestMetadata() c = m.contacts()[0] c.name = '' m.setContacts([c]) res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'contacts') self.assertEqual(list[0].identifier, 0) m = self.createTestMetadata() l = m.links()[0] l.name = '' m.setLinks([l]) res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'links') self.assertEqual(list[0].identifier, 0) m = self.createTestMetadata() l = m.links()[0] l.type = '' m.setLinks([l]) res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'links') self.assertEqual(list[0].identifier, 0) m = self.createTestMetadata() l = m.links()[0] l.url = '' m.setLinks([l]) res, list = v.validate(m) self.assertFalse(res) self.assertEqual(list[0].section, 'links') self.assertEqual(list[0].identifier, 0)
def processAlgorithm(self, feedback): extent = str(self.getParameterValue(self.EXTENT)).split(',') spacing = float(self.getParameterValue(self.SPACING)) inset = float(self.getParameterValue(self.INSET)) randomize = self.getParameterValue(self.RANDOMIZE) isSpacing = self.getParameterValue(self.IS_SPACING) crsId = self.getParameterValue(self.CRS) crs = QgsCoordinateReferenceSystem() crs.createFromUserInput(crsId) extent = QgsRectangle(float(extent[0]), float(extent[2]), float(extent[1]), float(extent[3])) fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.Point, crs) if randomize: seed() area = extent.width() * extent.height() if isSpacing: pSpacing = spacing else: pSpacing = sqrt(area / spacing) f = QgsFeature() f.initAttributes(1) f.setFields(fields) count = 0 total = 100.0 / (area / pSpacing) y = extent.yMaximum() - inset extent_geom = QgsGeometry.fromRect(extent) extent_engine = QgsGeometry.createGeometryEngine( extent_geom.geometry()) extent_engine.prepareGeometry() while y >= extent.yMinimum(): x = extent.xMinimum() + inset while x <= extent.xMaximum(): if randomize: geom = QgsGeometry().fromPoint( QgsPoint( uniform(x - (pSpacing / 2.0), x + (pSpacing / 2.0)), uniform(y - (pSpacing / 2.0), y + (pSpacing / 2.0)))) else: geom = QgsGeometry().fromPoint(QgsPoint(x, y)) if extent_engine.intersects(geom.geometry()): f.setAttribute('id', count) f.setGeometry(geom) writer.addFeature(f) x += pSpacing count += 1 feedback.setProgress(int(count * total)) y = y - pSpacing del writer
def createTestMetadata(self): """ Returns a standard metadata which can be tested with checkExpectedMetadata """ m = QgsLayerMetadata() m.setIdentifier('1234') m.setParentIdentifier('xyz') m.setLanguage('en-CA') m.setType('dataset') m.setTitle('roads') m.setAbstract('my roads') m.setFees('None') m.setConstraints([QgsLayerMetadata.Constraint('None', 'access')]) m.setRights(['Copyright foo 2017']) m.setLicenses(['WTFPL']) m.setHistory(['history a', 'history b']) m.setKeywords({'GEMET': ['kw1', 'kw2']}) m.setEncoding('utf-8') m.setCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326')) e = QgsLayerMetadata.Extent() se = QgsLayerMetadata.SpatialExtent() se.extentCrs = QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326') se.bounds = QgsBox3d(-180, -90, 0, 180, 90, 0) e.setSpatialExtents([se]) e.setTemporalExtents([QgsDateTimeRange(QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)), QDateTime(QDate(2001, 12, 17), QTime(9, 30, 47)))]) m.setExtent(e) c = QgsLayerMetadata.Contact() c.name = 'John Smith' c.organization = 'ACME' c.position = 'staff' c.voice = '1500 515 555' c.fax = 'xx.xxx.xxx.xxxx' c.email = '*****@*****.**' c.role = 'pointOfContact' address = QgsLayerMetadata.Address() address.type = 'postal' address.address = '123 Main Street' address.city = 'anycity' address.administrativeArea = 'anyprovince' address.postalCode = '90210' address.country = 'Canada' c.addresses = [address] m.setContacts([c]) l = QgsLayerMetadata.Link() l.name = 'geonode:roads' l.type = 'OGC:WMS' l.description = 'my GeoNode road layer' l.url = 'http://example.org/wms' l2 = QgsLayerMetadata.Link() l2.name = 'geonode:roads' l2.type = 'OGC:WFS' l2.description = 'my GeoNode road layer' l2.url = 'http://example.org/wfs' l3 = QgsLayerMetadata.Link() l3.name = 'roads' l3.type = 'WWW:LINK' l3.description = 'full dataset download' l3.url = 'http://example.org/roads.tgz' l3.format = 'ESRI Shapefile' l3.mimeType = 'application/gzip' l3.size = '283676' m.setLinks([l, l2, l3]) return m
def processAlgorithm(self, parameters, context, feedback): interpolationData = ParameterInterpolationData.parseValue( parameters[self.INTERPOLATION_DATA]) method = self.parameterAsEnum(parameters, self.METHOD, context) columns = self.parameterAsInt(parameters, self.COLUMNS, context) rows = self.parameterAsInt(parameters, self.ROWS, context) cellsizeX = self.parameterAsDouble(parameters, self.CELLSIZE_X, context) cellsizeY = self.parameterAsDouble(parameters, self.CELLSIZE_Y, context) bbox = self.parameterAsExtent(parameters, self.EXTENT, context) output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) if interpolationData is None: raise QgsProcessingException( self.tr('You need to specify at least one input layer.')) if cellsizeX == 0.0 or cellsizeY == 0.0: raise QgsProcessingException( self.tr('Cellsize should be greater than 0.')) layerData = [] layers = [] crs = QgsCoordinateReferenceSystem() for row in interpolationData.split(';'): v = row.split(',') data = QgsInterpolator.LayerData() # need to keep a reference until interpolation is complete layer = QgsProcessingUtils.mapLayerFromString(v[0], context) data.vectorLayer = layer layers.append(layer) if not crs.isValid(): crs = layer.crs() data.zCoordInterpolation = bool(v[1]) data.interpolationAttribute = int(v[2]) if v[3] == '0': data.mInputType = QgsInterpolator.POINTS elif v[3] == '1': data.mInputType = QgsInterpolator.STRUCTURE_LINES else: data.mInputType = QgsInterpolator.BREAK_LINES layerData.append(data) if method == 0: interpolationMethod = QgsTINInterpolator.Linear else: interpolationMethod = QgsTINInterpolator.CloughTocher (triangulation_sink, triangulation_dest_id) = self.parameterAsSink( parameters, self.TRIANGULATION, context, QgsTINInterpolator.triangulationFields(), QgsWkbTypes.LineString, crs) interpolator = QgsTINInterpolator(layerData, interpolationMethod, feedback) if triangulation_sink is not None: interpolator.setTriangulationSink(triangulation_sink) writer = QgsGridFileWriter(interpolator, output, bbox, columns, rows, cellsizeX, cellsizeY) writer.writeFile(feedback) return {self.OUTPUT: output, self.TRIANGULATION: triangulation_dest_id}
def testDistance(self): self.checkConstructWrapper(QgsProcessingParameterDistance('test'), DistanceWidgetWrapper) alg = QgsApplication.processingRegistry().algorithmById('native:centroids') dlg = AlgorithmDialog(alg) param = QgsProcessingParameterDistance('test') wrapper = DistanceWidgetWrapper(param, dlg) widget = wrapper.createWidget() # test units widget.show() # crs values widget.setUnitParameterValue('EPSG:3111') self.assertEqual(widget.label.text(), 'meters') self.assertFalse(widget.warning_label.isVisible()) self.assertTrue(widget.units_combo.isVisible()) self.assertFalse(widget.label.isVisible()) self.assertEqual(widget.units_combo.currentData(), QgsUnitTypes.DistanceMeters) widget.setUnitParameterValue('EPSG:4326') self.assertEqual(widget.label.text(), 'degrees') self.assertTrue(widget.warning_label.isVisible()) self.assertFalse(widget.units_combo.isVisible()) self.assertTrue(widget.label.isVisible()) widget.setUnitParameterValue(QgsCoordinateReferenceSystem('EPSG:3111')) self.assertEqual(widget.label.text(), 'meters') self.assertFalse(widget.warning_label.isVisible()) self.assertTrue(widget.units_combo.isVisible()) self.assertFalse(widget.label.isVisible()) self.assertEqual(widget.units_combo.currentData(), QgsUnitTypes.DistanceMeters) widget.setUnitParameterValue(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(widget.label.text(), 'degrees') self.assertTrue(widget.warning_label.isVisible()) self.assertFalse(widget.units_combo.isVisible()) self.assertTrue(widget.label.isVisible()) # layer values vl = QgsVectorLayer("Polygon?crs=epsg:3111&field=pk:int", "vl", "memory") widget.setUnitParameterValue(vl) self.assertEqual(widget.label.text(), 'meters') self.assertFalse(widget.warning_label.isVisible()) self.assertTrue(widget.units_combo.isVisible()) self.assertFalse(widget.label.isVisible()) self.assertEqual(widget.units_combo.currentData(), QgsUnitTypes.DistanceMeters) vl2 = QgsVectorLayer("Polygon?crs=epsg:4326&field=pk:int", "vl", "memory") widget.setUnitParameterValue(vl2) self.assertEqual(widget.label.text(), 'degrees') self.assertTrue(widget.warning_label.isVisible()) self.assertFalse(widget.units_combo.isVisible()) self.assertTrue(widget.label.isVisible()) # unresolvable values widget.setUnitParameterValue(vl.id()) self.assertEqual(widget.label.text(), '<unknown>') self.assertFalse(widget.warning_label.isVisible()) self.assertFalse(widget.units_combo.isVisible()) self.assertTrue(widget.label.isVisible()) # resolvable text value QgsProject.instance().addMapLayer(vl) widget.setUnitParameterValue(vl.id()) self.assertEqual(widget.label.text(), 'meters') self.assertFalse(widget.warning_label.isVisible()) self.assertTrue(widget.units_combo.isVisible()) self.assertFalse(widget.label.isVisible()) self.assertEqual(widget.units_combo.currentData(), QgsUnitTypes.DistanceMeters) widget.setValue(5) self.assertEqual(widget.getValue(), 5) widget.units_combo.setCurrentIndex(widget.units_combo.findData(QgsUnitTypes.DistanceKilometers)) self.assertEqual(widget.getValue(), 5000) widget.setValue(2) self.assertEqual(widget.getValue(), 2000) widget.setUnitParameterValue(vl.id()) self.assertEqual(widget.getValue(), 2) widget.setValue(5) self.assertEqual(widget.getValue(), 5) widget.deleteLater()
def testMeasureLineProjected(self): # +-+ # | | # +-+ + # test setting/getting the source CRS da_3068 = QgsDistanceArea() da_wsg84 = QgsDistanceArea() da_3068.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:3068'), QgsProject.instance().transformContext()) if (da_3068.sourceCrs().isGeographic()): da_3068.setEllipsoid(da_3068.sourceCrs().ellipsoidAcronym()) print(("setting [{}] srid [{}] description [{}]".format(u'Soldner Berlin', da_3068.sourceCrs().authid(), da_3068.sourceCrs().description()))) self.assertEqual(da_3068.sourceCrs().authid(), 'EPSG:3068') da_wsg84.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326'), QgsProject.instance().transformContext()) if (da_wsg84.sourceCrs().isGeographic()): da_wsg84.setEllipsoid(da_wsg84.sourceCrs().ellipsoidAcronym()) self.assertEqual(da_wsg84.sourceCrs().authid(), 'EPSG:4326') print(("setting [{}] srid [{}] description [{}] isGeographic[{}]".format(u'Wsg84', da_wsg84.sourceCrs().authid(), da_wsg84.sourceCrs().description(), da_wsg84.sourceCrs().isGeographic()))) # print(("-- projectionAcronym[{}] ellipsoidAcronym[{}] toWkt[{}] mapUnits[{}] toProj4[{}]".format(da_wsg84.sourceCrs().projectionAcronym(),da_wsg84.sourceCrs().ellipsoidAcronym(), da_wsg84.sourceCrs().toWkt(),da_wsg84.sourceCrs().mapUnits(),da_wsg84.sourceCrs().toProj4()))) print(("Testing Position change for[{}] years[{}]".format(u'Ampelanlage - Potsdamer Platz, Verkehrsinsel', u'1924 and 1998'))) # 1924-10-24 SRID=3068;POINT(23099.49 20296.69) # 1924-10-24 SRID=4326;POINT(13.37650707988041 52.50952361017194) # 1998-10-02 SRID=3068;POINT(23082.30 20267.80) # 1998-10-02 SRID=4326;POINT(13.37625537334001 52.50926345498337) # values returned by SpatiaLite point_soldner_1924 = QgsPointXY(23099.49, 20296.69) point_soldner_1998 = QgsPointXY(23082.30, 20267.80) distance_soldner_meters = 33.617379 azimuth_soldner_1924 = 3.678339 # ST_Transform(point_soldner_1924,point_soldner_1998,4326) point_wsg84_1924 = QgsPointXY(13.37650707988041, 52.50952361017194) point_wsg84_1998 = QgsPointXY(13.37625537334001, 52.50926345498337) # ST_Distance(point_wsg84_1924,point_wsg84_1998,1) distance_wsg84_meters = 33.617302 # ST_Distance(point_wsg84_1924,point_wsg84_1998) # distance_wsg84_mapunits=0.000362 distance_wsg84_mapunits_format = QgsDistanceArea.formatDistance(0.000362, 7, QgsUnitTypes.DistanceDegrees, True) # ST_Azimuth(point_wsg84_1924,point_wsg84_1998) azimuth_wsg84_1924 = 3.674878 # ST_Azimuth(point_wsg84_1998,point_wsg84_1998) azimuth_wsg84_1998 = 0.533282 # ST_Project(point_wsg84_1924,33.617302,3.674878) # SRID=4326;POINT(13.37625537318728 52.50926345503591) point_soldner_1998_project = QgsPointXY(13.37625537318728, 52.50926345503591) # ST_Project(point_wsg84_1998,33.617302,0.533282) # SRID=4326;POINT(13.37650708009255 52.50952361009799) point_soldner_1924_project = QgsPointXY(13.37650708009255, 52.50952361009799) distance_qpoint = point_soldner_1924.distance(point_soldner_1998) azimuth_qpoint = point_soldner_1924.azimuth(point_soldner_1998) point_soldner_1998_result = point_soldner_1924.project(distance_qpoint, azimuth_qpoint) point_soldner_1924_result = QgsPointXY(0, 0) point_soldner_1998_result = QgsPointXY(0, 0) # Test meter based projected point from point_1924 to point_1998 length_1998_mapunits, point_soldner_1998_result = da_3068.measureLineProjected(point_soldner_1924, distance_soldner_meters, azimuth_qpoint) self.assertEqual(point_soldner_1998_result.toString(6), point_soldner_1998.toString(6)) # Test degree based projected point from point_1924 1 meter due East point_wsg84_meter_result = QgsPointXY(0, 0) point_wsg84_1927_meter = QgsPointXY(13.37652180838435, 52.50952361017102) length_meter_mapunits, point_wsg84_meter_result = da_wsg84.measureLineProjected(point_wsg84_1924, 1.0, (math.pi / 2)) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, QgsUnitTypes.DistanceDegrees, True), '0.0000147 deg') self.assertEqual(point_wsg84_meter_result.toString(7), point_wsg84_1927_meter.toString(7)) point_wsg84_1998_result = QgsPointXY(0, 0) length_1928_mapunits, point_wsg84_1998_result = da_wsg84.measureLineProjected(point_wsg84_1924, distance_wsg84_meters, azimuth_wsg84_1924) self.assertEqual(QgsDistanceArea.formatDistance(length_1928_mapunits, 7, QgsUnitTypes.DistanceDegrees, True), distance_wsg84_mapunits_format) self.assertEqual(point_wsg84_1998_result.toString(7), point_wsg84_1998.toString(7))
def _test_operations(self, md, conn): """Common tests""" capabilities = conn.capabilities() # Schema operations if (capabilities & QgsAbstractDatabaseProviderConnection.CreateSchema and capabilities & QgsAbstractDatabaseProviderConnection.Schemas and capabilities & QgsAbstractDatabaseProviderConnection.RenameSchema and capabilities & QgsAbstractDatabaseProviderConnection.DropSchema): if capabilities & QgsAbstractDatabaseProviderConnection.DropSchema and 'myNewSchema' in conn.schemas( ): conn.dropSchema('myNewSchema', True) # Create conn.createSchema('myNewSchema') schemas = conn.schemas() self.assertTrue('myNewSchema' in schemas) # Create again with self.assertRaises(QgsProviderConnectionException) as ex: conn.createSchema('myNewSchema') # Rename conn.renameSchema('myNewSchema', 'myVeryNewSchema') schemas = conn.schemas() self.assertTrue('myVeryNewSchema' in schemas) self.assertFalse('myNewSchema' in schemas) # Drop conn.dropSchema('myVeryNewSchema') schemas = conn.schemas() self.assertFalse('myVeryNewSchema' in schemas) # Table operations if (capabilities & QgsAbstractDatabaseProviderConnection.CreateVectorTable and capabilities & QgsAbstractDatabaseProviderConnection.Tables and capabilities & QgsAbstractDatabaseProviderConnection.RenameVectorTable and capabilities & QgsAbstractDatabaseProviderConnection.DropVectorTable): if capabilities & QgsAbstractDatabaseProviderConnection.DropSchema and 'myNewSchema' in conn.schemas( ): conn.dropSchema('myNewSchema', True) if capabilities & QgsAbstractDatabaseProviderConnection.CreateSchema: schema = 'myNewSchema' conn.createSchema('myNewSchema') else: schema = 'public' if 'myNewTable' in self._table_names(conn.tables(schema)): conn.dropVectorTable(schema, 'myNewTable') fields = QgsFields() fields.append(QgsField("string", QVariant.String)) fields.append(QgsField("long", QVariant.LongLong)) fields.append(QgsField("double", QVariant.Double)) fields.append(QgsField("integer", QVariant.Int)) fields.append(QgsField("date", QVariant.Date)) fields.append(QgsField("datetime", QVariant.DateTime)) fields.append(QgsField("time", QVariant.Time)) options = {} crs = QgsCoordinateReferenceSystem.fromEpsgId(3857) typ = QgsWkbTypes.LineString # Create conn.createVectorTable(schema, 'myNewTable', fields, typ, crs, True, options) table_names = self._table_names(conn.tables(schema)) self.assertTrue('myNewTable' in table_names) # Check table information table_properties = conn.tables(schema) table_property = self._table_by_name(table_properties, 'myNewTable') self.assertEqual(table_property.maxCoordinateDimensions(), 2) self.assertIsNotNone(table_property) self.assertEqual(table_property.tableName(), 'myNewTable') self.assertEqual(table_property.geometryColumnCount(), 1) self.assertEqual(table_property.geometryColumnTypes()[0].wkbType, QgsWkbTypes.LineString) cols = table_property.geometryColumnTypes() self.assertEqual(cols[0].crs, QgsCoordinateReferenceSystem.fromEpsgId(3857)) self.assertEqual(table_property.defaultName(), 'myNewTable') # Check aspatial tables conn.createVectorTable(schema, 'myNewAspatialTable', fields, QgsWkbTypes.NoGeometry, crs, True, options) table_properties = conn.tables( schema, QgsAbstractDatabaseProviderConnection.Aspatial) table_property = self._table_by_name(table_properties, 'myNewAspatialTable') self.assertIsNotNone(table_property) self.assertEqual(table_property.maxCoordinateDimensions(), 0) self.assertEqual(table_property.tableName(), 'myNewAspatialTable') self.assertEqual(table_property.geometryColumnCount(), 0) self.assertEqual(table_property.geometryColumn(), '') self.assertEqual(table_property.defaultName(), 'myNewAspatialTable') cols = table_property.geometryColumnTypes() self.assertEqual(cols[0].wkbType, QgsWkbTypes.NoGeometry) self.assertFalse(cols[0].crs.isValid()) self.assertFalse(table_property.flags() & QgsAbstractDatabaseProviderConnection.Raster) self.assertFalse(table_property.flags() & QgsAbstractDatabaseProviderConnection.Vector) self.assertTrue(table_property.flags() & QgsAbstractDatabaseProviderConnection.Aspatial) # Check executeSql has_schema = capabilities & QgsAbstractDatabaseProviderConnection.Schemas if capabilities & QgsAbstractDatabaseProviderConnection.ExecuteSql: if has_schema: table = "\"%s\".\"myNewAspatialTable\"" % schema else: table = 'myNewAspatialTable' sql = "INSERT INTO %s (string, long, double, integer, date, datetime, time) VALUES ('QGIS Rocks - \U0001f604', 666, 1.234, 1234, '2019-07-08', '2019-07-08T12:00:12', '12:00:13.00')" % table res = conn.executeSql(sql) self.assertEqual(res, []) sql = "SELECT string, long, double, integer, date, datetime FROM %s" % table res = conn.executeSql(sql) # GPKG has no type for time and spatialite has no support for dates and time ... if self.providerKey == 'spatialite': self.assertEqual(res, [[ 'QGIS Rocks - \U0001f604', 666, 1.234, 1234, '2019-07-08', '2019-07-08T12:00:12' ]]) else: self.assertEqual(res, [[ 'QGIS Rocks - \U0001f604', 666, 1.234, 1234, QtCore.QDate(2019, 7, 8), QtCore.QDateTime(2019, 7, 8, 12, 0, 12) ]]) sql = "SELECT time FROM %s" % table res = conn.executeSql(sql) self.assertIn(res, ([[QtCore.QTime(12, 0, 13)]], [['12:00:13.00']])) sql = "DELETE FROM %s WHERE string = 'QGIS Rocks - \U0001f604'" % table res = conn.executeSql(sql) self.assertEqual(res, []) sql = "SELECT string, integer FROM %s" % table res = conn.executeSql(sql) self.assertEqual(res, []) # Check that we do NOT get the aspatial table when querying for vectors table_names = self._table_names( conn.tables(schema, QgsAbstractDatabaseProviderConnection.Vector)) self.assertTrue('myNewTable' in table_names) self.assertFalse('myNewAspatialTable' in table_names) # Query for rasters (in qgis_test schema or no schema for GPKG, spatialite has no support) if self.providerKey != 'spatialite': table_properties = conn.tables( 'qgis_test', QgsAbstractDatabaseProviderConnection.Raster) # At least one raster should be there (except for spatialite) self.assertTrue(len(table_properties) >= 1) table_property = table_properties[0] self.assertTrue(table_property.flags() & QgsAbstractDatabaseProviderConnection.Raster) self.assertFalse( table_property.flags() & QgsAbstractDatabaseProviderConnection.Vector) self.assertFalse( table_property.flags() & QgsAbstractDatabaseProviderConnection.Aspatial) # Rename conn.renameVectorTable(schema, 'myNewTable', 'myVeryNewTable') tables = self._table_names(conn.tables(schema)) self.assertFalse('myNewTable' in tables) self.assertTrue('myVeryNewTable' in tables) # Vacuum if capabilities & QgsAbstractDatabaseProviderConnection.Vacuum: conn.vacuum('myNewSchema', 'myVeryNewTable') if capabilities & QgsAbstractDatabaseProviderConnection.DropSchema: # Drop schema (should fail) with self.assertRaises(QgsProviderConnectionException) as ex: conn.dropSchema('myNewSchema') # Check some column types operations table = self._table_by_name(conn.tables(schema), 'myVeryNewTable') self.assertEqual(len(table.geometryColumnTypes()), 1) ct = table.geometryColumnTypes()[0] self.assertEqual(ct.crs, QgsCoordinateReferenceSystem.fromEpsgId(3857)) self.assertEqual(ct.wkbType, QgsWkbTypes.LineString) # Add a new (existing type) table.addGeometryColumnType( QgsWkbTypes.LineString, QgsCoordinateReferenceSystem.fromEpsgId(3857)) self.assertEqual(len(table.geometryColumnTypes()), 1) ct = table.geometryColumnTypes()[0] self.assertEqual(ct.crs, QgsCoordinateReferenceSystem.fromEpsgId(3857)) self.assertEqual(ct.wkbType, QgsWkbTypes.LineString) # Add a new one table.addGeometryColumnType( QgsWkbTypes.LineString, QgsCoordinateReferenceSystem.fromEpsgId(4326)) self.assertEqual(len(table.geometryColumnTypes()), 2) ct = table.geometryColumnTypes()[0] self.assertEqual(ct.crs, QgsCoordinateReferenceSystem.fromEpsgId(3857)) self.assertEqual(ct.wkbType, QgsWkbTypes.LineString) ct = table.geometryColumnTypes()[1] self.assertEqual(ct.crs, QgsCoordinateReferenceSystem.fromEpsgId(4326)) self.assertEqual(ct.wkbType, QgsWkbTypes.LineString) # Drop table conn.dropVectorTable(schema, 'myVeryNewTable') conn.dropVectorTable(schema, 'myNewAspatialTable') table_names = self._table_names(conn.tables(schema)) self.assertFalse('myVeryNewTable' in table_names) if capabilities & QgsAbstractDatabaseProviderConnection.DropSchema: # Drop schema conn.dropSchema('myNewSchema') self.assertFalse('myNewSchema' in conn.schemas()) conns = md.connections() self.assertTrue( isinstance( list(conns.values())[0], QgsAbstractDatabaseProviderConnection)) # Remove connection md.deleteConnection('qgis_test1') self.assertEqual(list(md.connections().values()), [])
def testMeasureLineProjectedWorldPoints(self): # +-+ # | | # +-+ + # checking returned length_mapunits/projected_points of diffferent world points with results from SpatiaLite ST_Project da_3068 = QgsDistanceArea() da_3068.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:3068'), QgsProject.instance().transformContext()) if (da_3068.sourceCrs().isGeographic()): da_3068.setEllipsoid(da_3068.sourceCrs().ellipsoidAcronym()) self.assertEqual(da_3068.sourceCrs().authid(), 'EPSG:3068') print(("setting [{}] srid [{}] description [{}] isGeographic[{}] lengthUnits[{}] projectionAcronym[{}] ellipsoidAcronym[{}]".format(u'EPSG:3068', da_3068.sourceCrs().authid(), da_3068.sourceCrs().description(), da_3068.sourceCrs().isGeographic(), QgsUnitTypes.toString(da_3068.lengthUnits()), da_3068.sourceCrs().projectionAcronym(), da_3068.sourceCrs().ellipsoidAcronym()))) da_wsg84 = QgsDistanceArea() da_wsg84.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326'), QgsProject.instance().transformContext()) if (da_wsg84.sourceCrs().isGeographic()): da_wsg84.setEllipsoid(da_wsg84.sourceCrs().ellipsoidAcronym()) self.assertEqual(da_wsg84.sourceCrs().authid(), 'EPSG:4326') print(("setting [{}] srid [{}] description [{}] isGeographic[{}] lengthUnits[{}] projectionAcronym[{}] ellipsoidAcronym[{}] ellipsoid[{}]".format(u'EPSG:4326', da_wsg84.sourceCrs().authid(), da_wsg84.sourceCrs().description(), da_wsg84.sourceCrs().isGeographic(), QgsUnitTypes.toString(da_wsg84.lengthUnits()), da_wsg84.sourceCrs().projectionAcronym(), da_wsg84.sourceCrs().ellipsoidAcronym(), da_wsg84.ellipsoid()))) da_4314 = QgsDistanceArea() da_4314.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4314'), QgsProject.instance().transformContext()) if (da_4314.sourceCrs().isGeographic()): da_4314.setEllipsoid(da_4314.sourceCrs().ellipsoidAcronym()) self.assertEqual(da_4314.sourceCrs().authid(), 'EPSG:4314') print(("setting [{}] srid [{}] description [{}] isGeographic[{}] lengthUnits[{}] projectionAcronym[{}] ellipsoidAcronym[{}]".format(u'EPSG:4314', da_4314.sourceCrs().authid(), da_4314.sourceCrs().description(), da_4314.sourceCrs().isGeographic(), QgsUnitTypes.toString(da_4314.lengthUnits()), da_4314.sourceCrs().projectionAcronym(), da_4314.sourceCrs().ellipsoidAcronym()))) da_4805 = QgsDistanceArea() da_4805.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4805'), QgsProject.instance().transformContext()) if (da_4805.sourceCrs().isGeographic()): da_4805.setEllipsoid(da_4805.sourceCrs().ellipsoidAcronym()) self.assertEqual(da_4805.sourceCrs().authid(), 'EPSG:4805') print(("setting [{}] srid [{}] description [{}] isGeographic[{}] lengthUnits[{}] projectionAcronym[{}] ellipsoidAcronym[{}]".format(u'EPSG:4805', da_4805.sourceCrs().authid(), da_4805.sourceCrs().description(), da_4805.sourceCrs().isGeographic(), QgsUnitTypes.toString(da_4805.lengthUnits()), da_4805.sourceCrs().projectionAcronym(), da_4805.sourceCrs().ellipsoidAcronym()))) # EPSG:5665 unknown, why? da_5665 = QgsDistanceArea() da_5665.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:5665'), QgsProject.instance().transformContext()) if (da_5665.sourceCrs().isGeographic()): da_5665.setEllipsoid(da_5665.sourceCrs().ellipsoidAcronym()) print(("setting [{}] srid [{}] description [{}] isGeographic[{}] lengthUnits[{}] projectionAcronym[{}] ellipsoidAcronym[{}]".format(u'EPSG:5665', da_5665.sourceCrs().authid(), da_5665.sourceCrs().description(), da_5665.sourceCrs().isGeographic(), QgsUnitTypes.toString(da_5665.lengthUnits()), da_5665.sourceCrs().projectionAcronym(), da_5665.sourceCrs().ellipsoidAcronym()))) #self.assertEqual(da_5665.sourceCrs().authid(), 'EPSG:5665') da_25833 = QgsDistanceArea() da_25833.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:25833'), QgsProject.instance().transformContext()) if (da_25833.sourceCrs().isGeographic()): da_25833.setEllipsoid(da_25833.sourceCrs().ellipsoidAcronym()) print(("setting [{}] srid [{}] description [{}] isGeographic[{}] lengthUnits[{}] projectionAcronym[{}] ellipsoidAcronym[{}]".format(u'EPSG:25833', da_25833.sourceCrs().authid(), da_25833.sourceCrs().description(), da_25833.sourceCrs().isGeographic(), QgsUnitTypes.toString(da_25833.lengthUnits()), da_25833.sourceCrs().projectionAcronym(), da_25833.sourceCrs().ellipsoidAcronym()))) self.assertEqual(da_25833.sourceCrs().authid(), 'EPSG:25833') # Berlin - Brandenburg Gate - Quadriga point_berlin_3068 = QgsPointXY(23183.38449999984, 21047.3225000017) point_berlin_3068_project = point_berlin_3068.project(1, (math.pi / 2)) point_meter_result = QgsPointXY(0, 0) length_meter_mapunits, point_meter_result = da_3068.measureLineProjected(point_berlin_3068, 1.0, (math.pi / 2)) pprint(point_meter_result) print('-I-> Berlin 3068 length_meter_mapunits[{}] point_meter_result[{}]'.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_3068.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 1, da_3068.lengthUnits(), True), '1.0 m') self.assertEqual(point_meter_result.toString(7), point_berlin_3068_project.toString(7)) point_berlin_wsg84 = QgsPointXY(13.37770458660236, 52.51627178856762) point_berlin_wsg84_project = QgsPointXY(13.37771931736259, 52.51627178856669) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_berlin_wsg84, 1.0, (math.pi / 2)) print('-I-> Berlin Wsg84 length_meter_mapunits[{}] point_meter_result[{}] ellipsoid[{}]'.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 20, da_wsg84.lengthUnits(), True), point_meter_result.asWkt(), da_wsg84.ellipsoid())) # for unknown reasons, this is returning '0.00001473026 m' instead of '0.00001473026 deg' when using da_wsg84.lengthUnits() # self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits,11,da_wsg84.lengthUnits(),True), '0.00001473026 deg') self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 11, QgsUnitTypes.DistanceDegrees, True), '0.00001473026 deg') self.assertEqual(point_meter_result.toString(7), point_berlin_wsg84_project.toString(7)) point_berlin_4314 = QgsPointXY(13.37944343021465, 52.51767872437083) point_berlin_4314_project = QgsPointXY(13.37945816324759, 52.5176787243699) length_meter_mapunits, point_meter_result = da_4314.measureLineProjected(point_berlin_4314, 1.0, (math.pi / 2)) print('-I-> Berlin 4314 length_meter_mapunits[{}] point_meter_result[{}]'.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_4314.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 9, QgsUnitTypes.DistanceDegrees, True), '0.000014733 deg') self.assertEqual(point_meter_result.toString(7), point_berlin_4314_project.toString(7)) point_berlin_4805 = QgsPointXY(31.04960570069176, 52.5174657497405) point_berlin_4805_project = QgsPointXY(31.04962043365347, 52.51746574973957) length_meter_mapunits, point_meter_result = da_4805.measureLineProjected(point_berlin_4805, 1.0, (math.pi / 2)) print('-I-> Berlin 4805 length_meter_mapunits[{}] point_meter_result[{}]'.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_4805.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 9, QgsUnitTypes.DistanceDegrees, True), '0.000014733 deg') self.assertEqual(point_meter_result.toString(7), point_berlin_4805_project.toString(7)) point_berlin_25833 = QgsPointXY(389918.0748318382, 5819698.772194743) point_berlin_25833_project = point_berlin_25833.project(1, (math.pi / 2)) length_meter_mapunits, point_meter_result = da_25833.measureLineProjected(point_berlin_25833, 1.0, (math.pi / 2)) print('-I-> Berlin 25833 length_meter_mapunits[{}] point_meter_result[{}]'.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_25833.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_25833.lengthUnits(), True), '1.0000000 m') self.assertEqual(point_meter_result.toString(7), point_berlin_25833_project.toString(7)) if da_5665.sourceCrs().authid() != "": point_berlin_5665 = QgsPointXY(3389996.871728864, 5822169.719727578) point_berlin_5665_project = point_berlin_5665.project(1, (math.pi / 2)) length_meter_mapunits, point_meter_result = da_5665.measureLineProjected(point_berlin_5665, 1.0, (math.pi / 2)) print('-I-> Berlin 5665 length_meter_mapunits[{}] point_meter_result[{}]'.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_5665.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 1.0, da_5665.lengthUnits(), True), '1.0 m') self.assertEqual(point_meter_result.toString(7), point_berlin_5665_project.toString(7)) print('\n12 points ''above over'' and on the Equator') point_wsg84 = QgsPointXY(25.7844, 71.1725) point_wsg84_project = QgsPointXY(25.78442775215388, 71.17249999999795) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Nordkap, Norway - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, QgsUnitTypes.DistanceDegrees, True), '0.0000278 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(24.95995, 60.16841) point_wsg84_project = QgsPointXY(24.95996801277454, 60.16840999999877) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Helsinki, Finnland - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001801 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(12.599278, 55.692861) point_wsg84_project = QgsPointXY(12.59929390161872, 55.69286099999897) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Copenhagen, Denmark - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001590 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-0.001389, 51.477778) point_wsg84_project = QgsPointXY(-0.001374606184398, 51.4777779999991) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Royal Greenwich Observatory, United Kingdom - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001439 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(7.58769, 47.55814) point_wsg84_project = QgsPointXY(7.587703287209086, 47.55813999999922) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Basel, Switzerland - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001329 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(11.255278, 43.775278) point_wsg84_project = QgsPointXY(11.25529042107924, 43.77527799999933) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Florenz, Italy - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001242 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(14.514722, 35.899722) point_wsg84_project = QgsPointXY(14.51473307693308, 35.89972199999949) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Valletta, Malta - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001108 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-79.933333, 32.783333) point_wsg84_project = QgsPointXY(-79.93332232547254, 32.78333299999955) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Charlston, South Carolina - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001067 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-17.6666666, 27.733333) point_wsg84_project = QgsPointXY(-17.66665645831515, 27.73333299999962) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Ferro, Spain - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001014 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-99.133333, 19.433333) point_wsg84_project = QgsPointXY(-99.1333234776827, 19.43333299999975) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Mexico City, Mexico - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000952 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-79.894444, 9.341667) point_wsg84_project = QgsPointXY(-79.89443489691369, 9.341666999999882) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Colón, Panama - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000910 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-74.075833, 4.598056) point_wsg84_project = QgsPointXY(-74.07582398803629, 4.598055999999943) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Bogotá, Colombia - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000901 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(0, 0) point_wsg84_project = QgsPointXY(0.000008983152841, 0) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Equator, Atlantic Ocean - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000898 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) print('\n12 points ''down under'' and 1 point that should be considered invalid') point_wsg84 = QgsPointXY(-78.509722, -0.218611) point_wsg84_project = QgsPointXY(-78.50971301678221, -0.218610999999997) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Quito, Ecuador - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000898 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(106.816667, -6.2) point_wsg84_project = QgsPointXY(106.8166760356519, -6.199999999999922) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Jakarta, Indonesia - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000904 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-77.018611, -12.035) point_wsg84_project = QgsPointXY(-77.01860181630058, -12.03499999999985) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Lima, Peru - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000918 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(25.466667, -10.716667) point_wsg84_project = QgsPointXY(25.46667614155322, -10.71666699999986) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Kolwezi, Congo - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000914 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-70.333333, -18.483333) point_wsg84_project = QgsPointXY(-70.3333235314429, -18.48333299999976) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Arica, Chile - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000947 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-70.666667, -33.45) point_wsg84_project = QgsPointXY(-70.66665624452817, -33.44999999999953) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Santiago, Chile - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001076 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(144.9604, -37.8191) point_wsg84_project = QgsPointXY(144.96041135746983741, -37.81909999999945171) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Melbourne, Australia - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001136 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(147.29, -42.88) point_wsg84_project = QgsPointXY(147.2900122399815, -42.87999999999934) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Hobart City,Tasmania, Australia - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001224 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(168.101667, -46.899722) point_wsg84_project = QgsPointXY(168.101680123673, -46.89972199999923) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Ryan''s Creek Aerodrome, New Zealand - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001312 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-69.216667, -51.633333) point_wsg84_project = QgsPointXY(-69.21665255700216, -51.6333329999991) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Río Gallegos, Argentina - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001444 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-68.3, -54.8) point_wsg84_project = QgsPointXY(-68.29998445081456, -54.79999999999899) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Ushuaia, Tierra del Fuego, Argentina - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001555 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-63.494444, -64.825278) point_wsg84_project = QgsPointXY(-63.49442294002932, -64.82527799999851) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Port Lockroy, Antarctica - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00002106 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-180, -84.863272250) point_wsg84_project = QgsPointXY(-179.9999000000025, -84.8632722499922) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-I-> Someware, Antarctica - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00010000 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7)) point_wsg84 = QgsPointXY(-180, -85.0511300) point_wsg84_project = QgsPointXY(-179.9998962142197, -85.05112999999191) length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2)) print('-W-> Mercator''s Last Stop, Antarctica - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt())) self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00010379 deg') self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
def calculate_locally(self): if not self.sqi_setup_tab.use_custom.isChecked(): QtWidgets.QMessageBox.critical(None, self.tr("Error"), self.tr("Due to the options you have chosen, this calculation must occur offline. You MUST select a custom land cover dataset.")) return if len(self.sqi_setup_tab.use_custom_pm.layer_list) == 0: QtWidgets.QMessageBox.critical(None, self.tr("Error"), self.tr("You must add an parent material layer to your map before you can run the calculation.")) return if len(self.sqi_setup_tab.use_custom_rock_frag.layer_list) == 0: QtWidgets.QMessageBox.critical(None, self.tr("Error"), self.tr("You must add a rock fragment layer to your map before you can run the calculation.")) return if len(self.sqi_setup_tab.use_custom_texture.layer_list) == 0: QtWidgets.QMessageBox.critical(None, self.tr("Error"), self.tr("You must add a soil texture layer to your map before you can run the calculation.")) return if len(self.sqi_setup_tab.use_custom_drainage.layer_list) == 0: QtWidgets.QMessageBox.critical(None, self.tr("Error"), self.tr("You must add a drainage layer to your map before you can run the calculation.")) return # select the parent material, slope, soil texture, drainage and rock fragment datasets pm_vrt = self.sqi_setup_tab.use_custom_pm.get_vrt() drainage_vrt = self.sqi_setup_tab.use_custom_drainage.get_vrt() texture_vrt = self.sqi_setup_tab.use_custom_texture.get_vrt() rock_frag_vrt = self.sqi_setup_tab.use_custom_rock_frag.get_vrt() soil_depth = self.sqi_setup_tab.use_depth.value() if self.aoi.calc_frac_overlap(QgsGeometry.fromRect(self.sqi_setup_tab.use_custom_pm.get_layer().extent())) < .99: QtWidgets.QMessageBox.critical(None, self.tr("Error"), self.tr("Area of interest is not entirely within the parent material layer.")) return if self.aoi.calc_frac_overlap(QgsGeometry.fromRect(self.sqi_setup_tab.use_custom_drainage.get_layer().extent())) < .99: QtWidgets.QMessageBox.critical(None, self.tr("Error"), self.tr("Area of interest is not entirely within the drainage layer.")) return if self.aoi.calc_frac_overlap(QgsGeometry.fromRect(self.sqi_setup_tab.use_custom_rock_frag.get_layer().extent())) < .99: QtWidgets.QMessageBox.critical(None, self.tr("Error"), self.tr("Area of interest is not entirely within the rock fragment layer.")) return if self.aoi.calc_frac_overlap(QgsGeometry.fromRect(self.sqi_setup_tab.use_custom_texture.get_layer().extent())) < .99: QtWidgets.QMessageBox.critical(None, self.tr("Error"), self.tr("Area of interest is not entirely within the soil texture layer.")) return out_f = self.get_save_raster() if not out_f: return self.close() crosses_180th, geojsons = self.aoi.bounding_box_gee_geojson() val = [] n = 1 if self.area_tab.area_fromfile.isChecked(): for f in self.aoi.get_layer_wgs84().getFeatures(): # Get an OGR geometry from the QGIS geometry geom = f.geometry() val.append(geom) n += 1 # stringify json object val_string = '{}'.format(json.loads(val[0].asJson())) # create ogr geometry val_geom = ogr.CreateGeometryFromJson(val_string) # simplify polygon to tolerance of 0.003 val_geom_simplified = val_geom.Simplify(0.003) # fetch coordinates from json coords= json.loads(val_geom_simplified.ExportToJson())['coordinates'] geometries = { "coordinates":coords, "type":"Polygon" } elif self.area_tab.area_fromadmin.isChecked(): geometries ={ "coordinates":self.get_admin_poly_geojson()['geometry']['coordinates'][0], "type":"Polygon" } elif self.area_tab.area_frompoint.isChecked(): point = QgsPointXY(float(self.area_tab.area_frompoint_point_x.text()), float(self.area_tab.area_frompoint_point_y.text())) crs_src = QgsCoordinateReferenceSystem(self.area_tab.canvas.mapSettings().destinationCrs().authid()) point = QgsCoordinateTransform(crs_src, self.aoi.crs_dst, QgsProject.instance()).transform(point) geometries = json.loads(QgsGeometry.fromPointXY(point).asJson()) # write aoi geometry to file for masking output aoi_geom = { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": geometries } ] } aoi_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data', 'aoi.geojson') with open(aoi_file, 'w') as filetowrite: filetowrite.write(json.dumps(aoi_geom)) # Add the sqi layers to a VRT in case they don't match in resolution, # and set proper output bounds sqi_files = [pm_vrt, texture_vrt, drainage_vrt, rock_frag_vrt] # in_vrt = tempfile.NamedTemporaryFile(suffix='.vrt').name sqi_vrts = [] for i in range(len(sqi_files)): f = tempfile.NamedTemporaryFile(suffix='.vrt').name gdal.BuildVRT(f, sqi_files[i], bandList=[i + 1], resolution='highest', resampleAlg=gdal.GRA_NearestNeighbour, outputBounds=self.aoi.get_aligned_output_bounds_deprecated(texture_vrt), separate=True) sqi_vrts.append(f) slope_v = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data', 'slope.tif') if not os.path.exists(slope_v): slope_zip = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data', 'slope.zip') slope_unzip = ZipFile(slope_zip) slope_unzip.extractall(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data')) slope_unzip.close() log("Extracting slope file...") else: log("Slope.tif already exists") in_files = [slope_v] in_files.extend(sqi_vrts) in_vrt = tempfile.NamedTemporaryFile(suffix='.vrt').name log(u'Saving SQI input files to {}'.format(in_vrt)) gdal.BuildVRT(in_vrt, in_files, resolution='highest', resampleAlg=gdal.GRA_NearestNeighbour, outputBounds=self.aoi.get_aligned_output_bounds_deprecated(texture_vrt), separate=True) # sqi_band_nums = np.arange(len(lc_files)) + 6 sqi_worker = StartWorker(SoilQualityWorker, 'calculating soil quality index', soil_depth, in_vrt, out_f ) if not sqi_worker.success: QtWidgets.QMessageBox.critical(None, self.tr("Error"), self.tr("Error calculating soil quality index."), None) return band_info = [BandInfo("Soil Quality Index (cm deep)", add_to_map=True, metadata={'depth': soil_depth})] out_json = os.path.splitext(out_f)[0] + '.json' create_local_json_metadata(out_json, out_f, band_info) schema = BandInfoSchema() for band_number in range(len(band_info)): b = schema.dump(band_info[band_number]) if b['add_to_map']: # The +1 is because band numbers start at 1, not zero add_layer(out_f, band_number + 1, b)
def testDialogGettersSetters(self): """ basic tests for QgsProjectionSelectionTreeWidget """ w = QgsProjectionSelectionDialog() w.show() w.setCrs(QgsCoordinateReferenceSystem('EPSG:3111')) self.assertEqual(w.crs().authid(), 'EPSG:3111')
def testWriteShapefileWithAttributeSubsets(self): """Tests writing subsets of attributes to files.""" ml = QgsVectorLayer(( 'Point?crs=epsg:4326&field=id:int&field=field1:int&field=field2:int&field=field3:int' ), 'test', 'memory') self.assertIsNotNone(ml, 'Provider not initialized') self.assertTrue(ml.isValid(), 'Source layer not valid') provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromWkt('Point (1 2)')) ft.setAttributes([1, 11, 12, 13]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) # first write out with all attributes dest_file_name = os.path.join(str(QDir.tempPath()), 'all_attributes.shp') crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', attributes=[]) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') self.assertEqual(created_layer.fields().count(), 4) f = next(created_layer.getFeatures(QgsFeatureRequest())) self.assertEqual(f['id'], 1) self.assertEqual(f['field1'], 11) self.assertEqual(f['field2'], 12) self.assertEqual(f['field3'], 13) # now test writing out only a subset of attributes dest_file_name = os.path.join(str(QDir.tempPath()), 'subset_attributes.shp') write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', attributes=[1, 3]) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') self.assertEqual(created_layer.fields().count(), 2) f = next(created_layer.getFeatures(QgsFeatureRequest())) self.assertEqual(f['field1'], 11) self.assertEqual(f['field3'], 13) # finally test writing no attributes dest_file_name = os.path.join(str(QDir.tempPath()), 'no_attributes.shp') write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', skipAttributeCreation=True) self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') # expect only a default 'FID' field for shapefiles self.assertEqual(created_layer.fields().count(), 1) self.assertEqual(created_layer.fields()[0].name(), 'FID') # in this case we also check that the geometry exists, to make sure feature has been correctly written # even without attributes f = next(created_layer.getFeatures(QgsFeatureRequest())) g = f.geometry() wkt = g.asWkt() expWkt = 'Point (1 2)' self.assertTrue( compareWkt(expWkt, wkt), "geometry not saved correctly when saving without attributes : mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)) self.assertEqual(f['FID'], 0)