def reprojectRubberBand(self, geom): """ Reprojects the geometry geom: QgsGeometry """ # Defining the crs from src and destiny epsg = self.canvas.mapSettings().destinationCrs().authid() crsSrc = QgsCoordinateReferenceSystem(epsg) #getting srid from something like 'EPSG:31983' layer = self.canvas.currentLayer() srid = layer.crs().authid() crsDest = QgsCoordinateReferenceSystem(srid) #here we have to put authid, not srid # Creating a transformer coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest) lyrType = self.iface.activeLayer().geometryType() # Transforming the points if lyrType == QGis.Line: geomList = geom.asPolyline() elif lyrType == QGis.Polygon: geomList = geom.asPolygon() newGeom = [] for j in xrange(len(geomList)): if lyrType == QGis.Line: newGeom.append(coordinateTransformer.transform(geomList[j])) elif lyrType == QGis.Polygon: line = geomList[j] for i in xrange(len(line)): point = line[i] newGeom.append(coordinateTransformer.transform(point)) if lyrType == QGis.Line: return QgsGeometry.fromPolyline(newGeom + [newGeom[0]]) elif lyrType == QGis.Polygon: return QgsGeometry.fromPolygon([newGeom])
def set_bbox_from_map(self): """set bounding box from map extent""" crs = self.map.mapSettings().destinationCrs() try: crsid = int(crs.authid().split(':')[1]) except IndexError: # no projection crsid = 4326 extent = self.map.extent() if crsid != 4326: # reproject to EPSG:4326 src = QgsCoordinateReferenceSystem(crsid) dest = QgsCoordinateReferenceSystem(4326) xform = QgsCoordinateTransform(src, dest, QgsProject.instance()) minxy = xform.transform(QgsPointXY(extent.xMinimum(), extent.yMinimum())) maxxy = xform.transform(QgsPointXY(extent.xMaximum(), extent.yMaximum())) minx, miny = minxy maxx, maxy = maxxy else: # 4326 minx = extent.xMinimum() miny = extent.yMinimum() maxx = extent.xMaximum() maxy = extent.yMaximum() self.leNorth.setText(str(maxy)[0:9]) self.leSouth.setText(str(miny)[0:9]) self.leWest.setText(str(minx)[0:9]) self.leEast.setText(str(maxx)[0:9])
def set_bbox_from_map(self): """set bounding box from map extent""" crs = self.map.mapRenderer().destinationCrs() crsid = int(crs.authid().split(':')[1]) extent = self.map.extent() if crsid != 4326: # reproject to EPSG:4326 src = QgsCoordinateReferenceSystem(crsid) dest = QgsCoordinateReferenceSystem(4326) xform = QgsCoordinateTransform(src, dest) minxy = xform.transform(QgsPoint(extent.xMinimum(), extent.yMinimum())) maxxy = xform.transform(QgsPoint(extent.xMaximum(), extent.yMaximum())) minx, miny = minxy maxx, maxy = maxxy else: # 4326 minx = extent.xMinimum() miny = extent.yMinimum() maxx = extent.xMaximum() maxy = extent.yMaximum() self.leNorth.setText(unicode(maxy)[0:9]) self.leSouth.setText(unicode(miny)[0:9]) self.leWest.setText(unicode(minx)[0:9]) self.leEast.setText(unicode(maxx)[0:9])
def __getValsAtPoint(self, pnt): vals = [] rasterNodata = [] for rObj in self.settings.mapData.rasters.selectedRasters(): raster = rObj.grid nodata = raster.dataProvider().sourceNoDataValue(1) if not math.isnan(nodata): rasterNodata.append(nodata) nodata = raster.dataProvider().userNoDataValues(1) for v in nodata: if v.min() not in rasterNodata: rasterNodata.append(v.min()) if v.max() not in rasterNodata: rasterNodata.append(v.max()) #TODO!!!! QGIS BUG: QGIS 2.0.1: raster.noDataValue() = > AttributeError: 'QgsRasterLayer' object has no attribute 'noDataValue' raster_val = self.settings.nodata_value #QgsMessageLog.logMessage('raster_val VOR identify:' + str(raster_val), 'VoGis', Qgis.Info) #check if coordinate systems match p = None if self.settings.modeLine == enumModeLine.line: if raster.crs() != self.settings.mapData.selectedLineLyr.line.crs(): transform = QgsCoordinateTransform(self.settings.mapData.selectedLineLyr.line.crs(), raster.crs(), QgsProject.instance()) p = transform.transform(pnt) else: if raster.crs() != self.iface.mapCanvas().mapSettings().destinationCrs(): transform = QgsCoordinateTransform(self.iface.mapCanvas().mapSettings().destinationCrs(), raster.crs(), QgsProject.instance()) p = transform.transform(pnt) if p is None: #QgsMessageLog.logMessage(u'point not transformed {0}'.format(str(pnt))) p = pnt identify_result = raster.dataProvider().identify(p, QgsRaster.IdentifyFormatValue) #QgsMessageLog.logMessage(u'identify_result: {0}'.format(identify_result.results()), 'VoGis', Qgis.Info) for bnd_nr, pix_val in identify_result.results().items(): if 1 == bnd_nr: try: if pix_val is None: raster_val = self.settings.nodata_value else: raster_val = float(pix_val) #except ValueError: except: QgsMessageLog.logMessage('pix_val Exception: ' + str(pix_val), 'VoGis', Qgis.Info) raster_val = self.settings.nodata_value #QgsMessageLog.logMessage('raster_val NACH identify:' + str(raster_val), 'VoGis', Qgis.Info) vals.append(raster_val) #QMessageBox.warning(self.InterFace.mainWindow(), "VoGIS-Profiltool", str(vals)) return vals, rasterNodata
def calcAreaPixelInLayerPolygon(crs_map, paramsTransform): crsImage = QgsCoordinateReferenceSystem( crs_map ) crsLayer = self.paramProcess['layerPolygon'].crs() ct = QgsCoordinateTransform( crsImage, crsLayer, QgsCoordinateTransformContext() ) p1 = ct.transform( paramsTransform[0], paramsTransform[3] ) p2 = ct.transform( p1.x() + paramsTransform[1], p1.y() + paramsTransform[5] ) dist = p1.distance( p2 ) return dist * dist
def prjLineToMapCrs(self, lineString, fromCRS=4326 ): fromCrs = QgsCoordinateReferenceSystem(fromCRS) toCrs = self.getGetMapCrs(self.iface) xform = QgsCoordinateTransform(fromCrs, toCrs, QgsProject.instance() ) if isinstance(lineString, QgsGeometry): wgsLine = [ QgsPoint( xform.transform( QgsPointXY(xy) ) ) for xy in lineString.asPolyline()] if isinstance( lineString, Iterable ): wgsLine = [ QgsPoint( xform.transform( QgsPointXY(list(xy)[0], list(xy)[1]) ) ) for xy in lineString] return QgsGeometry.fromPolyline( wgsLine )
def iterate(publishPath): canvasLayers = qgis.utils.iface.mapCanvas().layers() ol3layers = "" for canvasLayer in reversed(canvasLayers): # DO if layer is Vector if canvasLayer.type() == QgsMapLayer.VectorLayer: qgis.core.QgsVectorFileWriter.writeAsVectorFormat(canvasLayer, os.path.join(os.path.dirname(publishPath+"/"), '%s.json' % canvasLayer.name()), 'utf-8', canvasLayer.crs(), 'GeoJson') # Save layer to GeoJSON # SLD style is not implemented in Open Layers 3 so sld file is not used # canvasLayer.saveSldStyle(os.path.join(os.path.dirname(publishPath+"/"), '%s.sld' % canvasLayer.name())) ol3layers += u",\n new ol.layer.Vector({\n title: '%s',\n source: new ol.source.Vector({\n format: new ol.format.GeoJSON(),\n url: '%s.json'\n })\n })" % (canvasLayer.name(), canvasLayer.name()) # DO if layer is raster (file or WMS) if canvasLayer.type() == 1: # WMS layer if canvasLayer.providerType().lower() == "wms": sourceString = canvasLayer.source() sourceDict = dict(x.split('=') for x in sourceString.split('&')) sourceList = sourceString.split('&') #QMessageBox.information(qgis.utils.iface.mainWindow(),(u"Message!"), str(sourceList)) sourceLayers = "" # String to hold all wms layers for item in sourceList: if item.split('=')[0] == u'layers': if len(sourceLayers) > 1: sourceLayers += "," sourceLayers += item.split('=')[1] ol3layers += u'\n ,\n new ol.layer.Tile({\n title: "%s",\n source: new ol.source.TileWMS({\n url: "%s",\n params: { layers: [%s] }\n })\n })' % (canvasLayer.name(), sourceDict[u'url'], sourceLayers) # Image layer (only supported formats work in browser i.e. GeoTiff doesn't work!) if canvasLayer.rasterType() < 3: sourceString = canvasLayer.source() approvedFormat = (".png", ".jpg") # only accept jpg and png files! if sourceString.lower().endswith(approvedFormat): # Copy rasterfile to publish directory destinationFileName = canvasLayer.name() + sourceString[-4:] copy2(sourceString, os.path.join(os.path.dirname(publishPath+"/"), destinationFileName )) layerCrs = canvasLayer.crs().authid().split(":")[1] transf = QgsCoordinateTransform( QgsCoordinateReferenceSystem(int(layerCrs)), QgsCoordinateReferenceSystem(4326) ) minX = canvasLayer.extent().xMinimum() minY = canvasLayer.extent().yMinimum() pointLL = transf.transform(QgsPoint(minX, minY)) maxX = canvasLayer.extent().xMaximum() maxY = canvasLayer.extent().yMaximum() pointUR = transf.transform(QgsPoint(maxX, maxY)) layerExtent = str(pointLL.x())+","+str(pointLL.y())+","+str(pointUR.x())+","+str(pointUR.y()) layerSize = str(canvasLayer.width()) +","+ str(canvasLayer.height()) ol3layers += u',\n new ol.layer.Image({\n source: new ol.source.ImageStatic({\n url: "%s",\n imageExtent: ol.extent.applyTransform([%s], ol.proj.getTransform("EPSG:4326", "EPSG:3857"))\n })})' % (destinationFileName, layerExtent) #QMessageBox.information(qgis.utils.iface.mainWindow(),(u"Message!"), sourceDict[u'url']) return ol3layers
def reprojectTransformParameters(self, oldCrs, newCrs): transform = QgsCoordinateTransform(oldCrs, newCrs, QgsProject.instance()) newCenter = transform.transform(self.center) newExtent = transform.transform(self.extent()) # transform the parameters except rotation # TODO rotation could be better handled (maybe check rotation between # old and new extent) # but not really worth the effort ? self.setCrs(newCrs) self.setCenter(newCenter) self.resetScale(newExtent.width(), newExtent.height())
def transformCoordinates(self): if self.startPoint is None or self.endPoint is None: return None elif self.startPoint.x() == self.endPoint.x() or self.startPoint.y() == self.endPoint.y(): return None # Defining the crs from src and destiny epsg = self.canvas.mapSettings().destinationCrs().authid() crsSrc = QgsCoordinateReferenceSystem(epsg) crsDest = QgsCoordinateReferenceSystem(4326) # Creating a transformer coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) # Transforming the points self.startPoint = coordinateTransformer.transform(self.startPoint) self.endPoint = coordinateTransformer.transform(self.endPoint)
def _prepare_queries(self): """Get the coordinates for each viaroute to query""" if self.ComboBoxOrigin.isEnabled(): origin_layer = self.ComboBoxOrigin.currentLayer() destination_layer = self.ComboBoxDestination.currentLayer() if '4326' not in origin_layer.crs().authid(): xform = QgsCoordinateTransform( origin_layer.crs(), QgsCoordinateReferenceSystem(4326)) origin_ids_coords = \ [(ft.id(), xform.transform(ft.geometry().asPoint())) for ft in origin_layer.getFeatures()] else: origin_ids_coords = \ [(ft.id(), ft.geometry().asPoint()) for ft in origin_layer.getFeatures()] if '4326' not in destination_layer.crs().authid(): xform = QgsCoordinateTransform( origin_layer.crs(), QgsCoordinateReferenceSystem(4326)) destination_ids_coords = \ [(ft.id(), xform.transform(ft.geometry().asPoint())) for ft in destination_layer.getFeatures()] else: destination_ids_coords = \ [(ft.id(), ft.geometry().asPoint()) for ft in destination_layer.getFeatures()] if len(origin_ids_coords) * len(destination_ids_coords) > 100000: QtGui.QMessageBox.information( self.iface.mainWindow(), 'Info', "Too many route to calculate, try with less than 100000") return -1 return [(origin[1][1], origin[1][0], dest[1][1], dest[1][0]) for origin in origin_ids_coords for dest in destination_ids_coords] elif self.FieldOriginX.isEnabled(): # If the source file is a .csv : layer = self.ComboBoxCsv.currentLayer() xo_col = self.FieldOriginX.currentField() yo_col = self.FieldOriginY.currentField() xd_col = self.FieldDestinationX.currentField() yd_col = self.FieldDestinationY.currentField() return [(str(ft.attribute(yo_col)), str(ft.attribute(xo_col)), str(ft.attribute(yd_col)), str(ft.attribute(xd_col))) for ft in layer.getFeatures()] return -1
def josm_remote(self): map_settings = self.iface.mapCanvas().mapSettings() extent = map_settings.extent() crs_map = map_settings.destinationCrs() if crs_map.authid() != 'EPSG:4326': crs_4326 = QgsCoordinateReferenceSystem(4326) transform = QgsCoordinateTransform(crs_map, crs_4326, QgsProject.instance()) extent = transform.transform(extent) url = 'http://localhost:8111/load_and_zoom?' query_string = 'left=%f&right=%f&top=%f&bottom=%f' % ( extent.xMinimum(), extent.xMaximum(), extent.yMaximum(), extent.yMinimum()) url += query_string try: request = urllib.request.Request(url) result_request = urllib.request.urlopen(request) result = result_request.read() result = result.decode('utf8') if result.strip().upper() != 'OK': self.iface.messageBar().pushCritical( tr('JOSM Remote'), result) else: self.iface.messageBar().pushSuccess( tr('JOSM Remote'), tr('Import done, check JOSM')) except IOError: self.iface.messageBar().pushCritical( tr('JOSM Remote'), tr('Is the remote enabled?'))
def clicked(self, pt, b): '''Capture the coordinate when the mouse button has been released, format it, and copy it to the clipboard.''' if settings.captureShowLocation: if self.marker is None: self.marker = QgsVertexMarker(self.canvas) self.marker.setIconSize(18) self.marker.setPenWidth(2) self.marker.setIconType(QgsVertexMarker.ICON_CROSS) self.marker.setCenter(pt) else: self.removeMarker(); try: if self.capture4326: canvasCRS = self.canvas.mapSettings().destinationCrs() transform = QgsCoordinateTransform(canvasCRS, epsg4326, QgsProject.instance()) pt4326 = transform.transform(pt.x(), pt.y()) self.capturesig.emit(pt4326) return msg = self.formatCoord(pt, self.settings.delimiter) formatString = self.coordFormatString() if msg != None: clipboard = QApplication.clipboard() clipboard.setText(msg) self.iface.messageBar().pushMessage("", "{} coordinate {} copied to the clipboard".format(formatString, msg), level=Qgis.Info, duration=4) except Exception as e: self.iface.messageBar().pushMessage("", "Invalid coordinate: {}".format(e), level=Qgis.Warning, duration=4)
def selectVisibleRasters(self): self.refreshRasterList() self.selectingVisibleRasters = True extCanvas = self.iface.mapCanvas().extent() #alle raster in den einstellunge deselektieren for r in self.settings.mapData.rasters.rasters(): r.selected = False #alle raster in der ListView deselektieren for idx in range(self.ui.IDC_listRasters.count()): item = self.ui.IDC_listRasters.item(idx) item.setCheckState(Qt.Unchecked) #Raster im Extent selektieren canvasCrs = self.iface.mapCanvas().mapSettings().destinationCrs() for idx in range(self.ui.IDC_listRasters.count()): item = self.ui.IDC_listRasters.item(idx) raster = item.data(Qt.UserRole) for r in self.settings.mapData.rasters.rasters(): layerCrs = r.grid.crs() ct = QgsCoordinateTransform(layerCrs, canvasCrs, QgsProject.instance()) extent = ct.transform(r.grid.extent()) if extCanvas.intersects(extent): if r.id == raster.id: r.selected = True item.setCheckState(Qt.Checked) self.selectingVisibleRasters = False
def bounds(self): """ Function for recalculating the bounded extents of the layers as they are processed. Under construction :return: """ # Requires refinement for raster manipulation of bounds selected_extent = unicode(self.getParameterValue(self.MAP_EXTENT)).split(',') xMin = float(selected_extent[0]) xMax = float(selected_extent[1]) yMin = float(selected_extent[2]) yMax = float(selected_extent[3]) extent = QgsRectangle(xMin, yMin, xMax, yMax) mapCRS = iface.mapCanvas().mapSettings().destinationCrs() transform = QgsCoordinateTransform( mapCRS, QgsCoordinateReferenceSystem('EPSG:4326') # WGS84 # QgsCoordinateReferenceSystem('EPSG:3785') # Popular vis mercator ) try: layer_extent = transform.transform(extent) except QgsCsException: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, "exception in transform layer srs") layer_extent = QgsRectangle(-180, -90, 180, 90) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, layer_extent.toString()) return layer_extent
def calc_scale(bbox, map_renderer): coord_transform = QgsCoordinateTransform( QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(27700) ) # As we are using the QgsScaleCalculator to determine the scale we need to # create a standard bounding box to calculate the scale for the width and a # bounding box on it's side to calculate the scale to fit the height width_bbox = coord_transform.transform(QgsRectangle(bbox[0], bbox[1], bbox[2], bbox[3])) height_bbox = coord_transform.transform(QgsRectangle(bbox[1], bbox[0], bbox[3], bbox[2])) scale_calc = QgsScaleCalculator(map_renderer.outputDpi()) scale = max( scale_calc.calculate(width_bbox, map_renderer.width()), scale_calc.calculate(height_bbox, map_renderer.height()) ) return scale * 1.1
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 _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 test_province_for_point(self): """Test for province for point function.""" # Point falls in South Africa point = QgsPoint(21, -30) expected_province = 'Free State' province = province_for_point(self.database_manager, point) message = 'Should be %s but got %s' % (expected_province, province) self.assertEqual(expected_province, province, message) # Point falls in Indonesia point = QgsPoint(109, -7) expected_province = None province = province_for_point(self.database_manager, point) message = 'Should be %s but got %s' % (expected_province, province) self.assertEqual(expected_province, province, message) # Point falls in South Africa but uses different CRS point = QgsPoint(2265216.874, -3952469.869) expected_province = None province = province_for_point(self.database_manager, point) message = 'Should be %s but got %s' % (expected_province, province) self.assertEqual(expected_province, province, message) # Point falls in South Africa but uses different CRS, reproject to 4326 osm_crs = QgsCoordinateReferenceSystem(3857) wgs84_crs = QgsCoordinateReferenceSystem(4326) transformer = QgsCoordinateTransform(osm_crs, wgs84_crs) point = QgsPoint(2265216.874, -3952469.869) point_transformed = transformer.transform(point) expected_province = 'Western Cape' province = province_for_point(self.database_manager, point_transformed) message = 'Should be %s but got %s' % (expected_province, province) self.assertEqual(expected_province, province, message)
def EPSG(self): currentEPSG = self.canvas.mapRenderer().destinationCrs().authid() if currentEPSG != 'EPSG:4326': crsSrc = QgsCoordinateReferenceSystem(int(currentEPSG[5:])) crsDest = QgsCoordinateReferenceSystem(4326) ## WGS-84 xform = QgsCoordinateTransform(crsSrc, crsDest) self.coordsClick = xform.transform(self.pntGeom.asPoint())
def show_exposure(self, hostname, username, password): selected_extent = self.selectedExtent() if selected_extent is None: QtGui.QMessageBox.warning( self, 'Exposure Download Error', 'No region selected') return self.enableBusyCursor() try: crs = self.iface.mapCanvas().mapRenderer().destinationCrs() xform = QgsCoordinateTransform( crs, QgsCoordinateReferenceSystem(4326)) extent = xform.transform(selected_extent) lon_min, lon_max = extent.xMinimum(), extent.xMaximum() lat_min, lat_max = extent.yMinimum(), extent.yMaximum() # download data ed = ExposureDownloader(hostname) ed.login(username, password) try: fname, msg = ed.download(lat_min, lon_min, lat_max, lon_max) except ExposureDownloadError as e: QtGui.QMessageBox.warning( self, 'Exposure Download Error', str(e)) return QgsMessageLog.logMessage(msg, 'GEM Exposure Downloader') # don't remove the file, otherwise there will concurrency problems uri = 'file://%s?delimiter=%s&xField=%s&yField=%s&crs=epsg:4326&' \ 'skipLines=25&trimFields=yes' % (fname, ',', 'lon', 'lat') vlayer = QgsVectorLayer(uri, 'exposure_export', 'delimitedtext') QgsMapLayerRegistry.instance().addMapLayer(vlayer) finally: self.disableBusyCursor()
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 doGeocoding(self, address): address = unicodedata.normalize('NFKD', unicode(address)).encode('ASCII', 'ignore') url = "http://api-adresse.data.gouv.fr/search/?q="+address.replace(" ", "%20") result = self.request(url) try: data = json.loads(result) features = data["features"] if len(features) > 0: feature_list = [] for feature in features: feature_list.append(feature["properties"]["label"]+" - "+str(round(feature["properties"]["score"]*100))+"%") feature, ok = QInputDialog.getItem(self.iface.mainWindow(), self.tr("Result"), "", feature_list) if ok: index = feature_list.index(feature) x = features[index]["geometry"]["coordinates"][0] y = features[index]["geometry"]["coordinates"][1] point_4326 = QgsPoint(x, y) transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem(4326), self.canvas.mapSettings().destinationCrs()) point_2154 = transform.transform(point_4326) self.rb.addPoint(point_2154) self.iface.mapCanvas().setCenter(point_2154) self.iface.mapCanvas().refresh() else: QMessageBox.information(self.iface.mainWindow(), self.tr("Result"), self.tr("No result.")) except ValueError: QMessageBox.critical(self.iface.mainWindow(), self.tr("Error"), self.tr("An error occured. Check your network settings (proxy)."))
def gpsStateChanged(self, gpsInfo): if gpsInfo.fixType == NMEA_FIX_BAD or gpsInfo.status == 0 or gpsInfo.quality == 0: self.gpsfixed.emit(False, gpsInfo) return elif gpsInfo.fixType == NMEA_FIX_3D or NMEA_FIX_2D: self.gpsfixed.emit(True, gpsInfo) map_pos = QgsPoint(gpsInfo.longitude, gpsInfo.latitude) if self.crs: transform = QgsCoordinateTransform(self.wgs84CRS, self.crs) try: map_pos = transform.transform(map_pos) except QgsCsException: log("Transform exception") return if self.postion is None: self.firstfix.emit(map_pos, gpsInfo) self.gpspostion.emit(map_pos, gpsInfo) self.postion = map_pos self.elevation = gpsInfo.elevation
def gpsStateChanged(self, gpsInfo): if gpsInfo.fixType == NMEA_FIX_BAD or gpsInfo.status == 0 or gpsInfo.quality == 0: self.gpsfixed.emit(False, gpsInfo) return elif gpsInfo.fixType == NMEA_FIX_3D or NMEA_FIX_2D: self.gpsfixed.emit(True, gpsInfo) map_pos = QgsPoint(gpsInfo.longitude, gpsInfo.latitude) self.latlong_position = map_pos if self.crs: transform = QgsCoordinateTransform(self.wgs84CRS, self.crs) try: map_pos = transform.transform(map_pos) except QgsCsException: log("Transform exception") return if self.postion is None: self.firstfix.emit(map_pos, gpsInfo) self.info = gpsInfo if (datetime.now()-self._gpsupdate_last).total_seconds() > self._gpsupdate_frequency: self.gpsposition.emit(map_pos, gpsInfo) self._gpsupdate_last = datetime.now() self.postion = map_pos self.elevation = gpsInfo.elevation
def proj4Utm(self, p): mapCrs = self.canvas.mapSettings().destinationCrs() if not mapCrs.geographicFlag(): # if not geographic transform it to a geographic crs geographicCrs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId) ct = QgsCoordinateTransform(mapCrs, geographicCrs) p = ct.transform(p) x = p.x() y = p.y() z = math.floor((x + 180) / 6) + 1 if y >= 56.0 and y < 64.0 and x >= 3.0 and x < 12.0: ZoneNumber = 32 # Special zones for Svalbard if y >= 72.0 and y < 84.0: if y >= 0.0 and y < 9.0: z = 31 elif y >= 9.0 and y < 21.0: z = 33 elif y >= 21.0 and y < 33.0: z = 35 elif y >= 33.0 and y < 42.0: z = 37 return "+proj=utm +zone={0} +datum=WGS84 +units=m +no_defs".format(int(z))
def transform_to_epsg_4326(self, point): if self.canvas.mapRenderer().destinationCrs().authid() != 'EPSG:4326': crs_src = self.canvas.mapRenderer().destinationCrs() crs_dest = QgsCoordinateReferenceSystem(4326) xform = QgsCoordinateTransform(crs_src, crs_dest) return QgsGeometry.fromPoint(xform.transform(point)).asPoint() else: return point
def get_current_map(self): curX = self.iface.mapCanvas().extent().center().x() curY = self.iface.mapCanvas().extent().center().y() EPSG = self.iface.mapCanvas().mapRenderer().destinationCrs().authid().split(":")[1] transf = QgsCoordinateTransform( QgsCoordinateReferenceSystem(int(EPSG)), QgsCoordinateReferenceSystem(4326) ) centerPoint = transf.transform(QgsPoint(curX, curY)) centerCoordinate = str(centerPoint.x()) + "," + str(centerPoint.y()) return centerCoordinate
def __getCenterLongLat2OL(self): pntCenter = self.__canvas.extent().center() crsCanvas = self.__canvas.mapSettings().destinationCrs() if crsCanvas != self.__srsOL: coodTrans = QgsCoordinateTransform(crsCanvas, self.__srsOL, QgsProject.instance()) pntCenter = coodTrans.transform( pntCenter, QgsCoordinateTransform.ForwardTransform) return tuple([pntCenter.x(), pntCenter.y()])
def store_intermediate_acces(self, point): if '4326' not in self.canvas.mapSettings().destinationCrs().authid(): crsSrc = self.canvas.mapSettings().destinationCrs() xform = QgsCoordinateTransform( crsSrc, QgsCoordinateReferenceSystem(4326)) point = xform.transform(point) tmp = self.lineEdit_xyO.text() self.change_nb_center() self.lineEdit_xyO.setText(', '.join([tmp, repr(point)]))
def getBoudingBoxGeomCanvas(): crsLayer = layer.crs() crsCanvas = self.project.crs() if not crsLayer == crsCanvas: ct = QgsCoordinateTransform( layer.crs(), self.project.crs(), self.project ) bbox = ct.transform( geometry.boundingBox() ) else: bbox = geometry.boundingBox() return bbox
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 copyCanvas(self): extent = self.iface.mapCanvas().extent() canvasCrs = self.canvas.mapSettings().destinationCrs() if settings.bBoxCrs == 0 and canvasCrs != epsg4326: transform = QgsCoordinateTransform(canvasCrs, epsg4326, QgsProject.instance()) p1x, p1y = transform.transform(float(extent.xMinimum()), float(extent.yMinimum())) p2x, p2y = transform.transform(float(extent.xMaximum()), float(extent.yMaximum())) extent.set(p1x, p1y, p2x, p2y) delim = settings.bBoxDelimiter prefix = settings.bBoxPrefix suffix = settings.bBoxSuffix precision = settings.bBoxDigits outStr = '' minX = extent.xMinimum() minY = extent.yMinimum() maxX = extent.xMaximum() maxY = extent.yMaximum() if settings.bBoxFormat == 0: # minX,minY,maxX,maxY - using the delimiter outStr = '{:.{prec}f}{}{:.{prec}f}{}{:.{prec}f}{}{:.{prec}f}'.format( minX, delim, minY, delim, maxX, delim, maxY, prec=precision) elif settings.bBoxFormat == 1: # minX,maxX,minY,maxY - Using the selected delimiter' outStr = '{:.{prec}f}{}{:.{prec}f}{}{:.{prec}f}{}{:.{prec}f}'.format( minX, delim, maxX, delim, minY, delim, maxY, prec=precision) elif settings.bBoxFormat == 2: # x1 y1,x2 y2,x3 y3,x4 y4,x1 y1 - Polygon format outStr = '{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f}'.format( minX, minY, minX, maxY, maxX, maxY, maxX, minY, minX, minY, prec=precision) elif settings.bBoxFormat == 3: # x1,y1 x2,y2 x3,y3 x4,y4 x1,y1 - Polygon format outStr = '{:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f} {:.{prec}f},{:.{prec}f}'.format( minX, minY, minX, maxY, maxX, maxY, maxX, minY, minX, minY, prec=precision) elif settings.bBoxFormat == 4: # WKT Polygon outStr = extent.asWktPolygon() elif settings.bBoxFormat == 5: # bbox: [minX, minY, maxX, maxY] - MapProxy outStr = 'bbox: [{}, {}, {}, {}]'.format(minX, minY, maxX, maxY) elif settings.bBoxFormat == 6: # bbox: [minX, minY, maxX, maxY] - MapProxy outStr = 'bbox={},{},{},{}'.format(minX, minY, maxX, maxY) outStr = '{}{}{}'.format(prefix, outStr, suffix) clipboard = QApplication.clipboard() clipboard.setText(outStr) self.iface.messageBar().pushMessage( "", "'{}' copied to the clipboard".format(outStr), level=Qgis.Info, duration=4)
def processPoly(source, sink, feedback, maxseglen): layercrs = source.sourceCrs() if layercrs != epsg4326: transto4326 = QgsCoordinateTransform(layercrs, epsg4326, QgsProject.instance()) transfrom4326 = QgsCoordinateTransform(epsg4326, layercrs, QgsProject.instance()) total = 100.0 / source.featureCount() if source.featureCount() else 0 iterator = source.getFeatures() num_bad = 0 for cnt, feature in enumerate(iterator): if feedback.isCanceled(): break try: if not feature.geometry().isMultipart(): poly = feature.geometry().asPolygon() numpolygons = len(poly) if numpolygons < 1: continue ptset = [] # Iterate through all points in the polygon and if the distance # is greater than the maxseglen, then add additional points. for points in poly: numpoints = len(points) if numpoints < 2: continue # If the input is not 4326 we need to convert it to that and then back to the output CRS ptStart = QgsPointXY(points[0][0], points[0][1]) if layercrs != epsg4326: # Convert to 4326 ptStart = transto4326.transform(ptStart) pts = [ptStart] for x in range(1, numpoints): ptEnd = QgsPointXY(points[x][0], points[x][1]) if layercrs != epsg4326: # Convert to 4326 ptEnd = transto4326.transform(ptEnd) gline = geod.InverseLine(ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x()) # Check to see if the distance is greater than the maximum # segment length and if so lets add additional points. if gline.s13 > maxseglen: n = int(math.ceil(gline.s13 / maxseglen)) seglen = gline.s13 / n for i in range(1, n): s = seglen * i g = gline.Position( s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) pts.append(QgsPointXY(g['lon2'], g['lat2'])) pts.append(ptEnd) ptStart = ptEnd if layercrs != epsg4326: # Convert each point to the output CRS for x, pt in enumerate(pts): pts[x] = transfrom4326.transform(pt) ptset.append(pts) if len(ptset) > 0: featureout = QgsFeature() featureout.setGeometry(QgsGeometry.fromPolygonXY(ptset)) featureout.setAttributes(feature.attributes()) sink.addFeature(featureout) else: multipoly = feature.geometry().asMultiPolygon() multiset = [] for poly in multipoly: ptset = [] for points in poly: numpoints = len(points) if numpoints < 2: continue # If the input is not 4326 we need to convert it to that and then back to the output CRS ptStart = QgsPointXY(points[0][0], points[0][1]) if layercrs != epsg4326: # Convert to 4326 ptStart = transto4326.transform(ptStart) pts = [ptStart] for x in range(1, numpoints): ptEnd = QgsPointXY(points[x][0], points[x][1]) if layercrs != epsg4326: # Convert to 4326 ptEnd = transto4326.transform(ptEnd) gline = geod.InverseLine(ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x()) if gline.s13 > maxseglen: n = int(math.ceil(gline.s13 / maxseglen)) seglen = gline.s13 / n for i in range(1, n): s = seglen * i g = gline.Position( s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) pts.append(QgsPointXY( g['lon2'], g['lat2'])) pts.append(ptEnd) ptStart = ptEnd if layercrs != epsg4326: # Convert each point to the output CRS for x, pt in enumerate(pts): pts[x] = transfrom4326.transform(pt) ptset.append(pts) multiset.append(ptset) if len(multiset) > 0: featureout = QgsFeature() featureout.setGeometry( QgsGeometry.fromMultiPolygonXY(multiset)) featureout.setAttributes(feature.attributes()) sink.addFeature(featureout) except Exception: num_bad += 1 '''s = traceback.format_exc() feedback.pushInfo(s)''' feedback.setProgress(int(cnt * total)) return num_bad
def processLine(source, sink, feedback, discardVertices, maxseglen): layercrs = source.sourceCrs() if layercrs != epsg4326: transto4326 = QgsCoordinateTransform(layercrs, epsg4326, QgsProject.instance()) transfrom4326 = QgsCoordinateTransform(epsg4326, layercrs, QgsProject.instance()) total = 100.0 / source.featureCount() if source.featureCount() else 0 iterator = source.getFeatures() num_bad = 0 for cnt, feature in enumerate(iterator): if feedback.isCanceled(): break try: if feature.geometry().isMultipart(): seg = feature.geometry().asMultiPolyline() else: seg = [feature.geometry().asPolyline()] numseg = len(seg) if numseg < 1 or len(seg[0]) < 2: continue # Create a new Line Feature fline = QgsFeature() # If the input is not 4326 we need to convert it to that and then back to the output CRS if discardVertices: ptStart = QgsPointXY(seg[0][0][0], seg[0][0][1]) if layercrs != epsg4326: # Convert to 4326 ptStart = transto4326.transform(ptStart) pts = [ptStart] numpoints = len(seg[numseg - 1]) ptEnd = QgsPointXY(seg[numseg - 1][numpoints - 1][0], seg[numseg - 1][numpoints - 1][1]) if layercrs != epsg4326: # Convert to 4326 ptEnd = transto4326.transform(ptEnd) gline = geod.InverseLine(ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x()) if gline.s13 > maxseglen: n = int(math.ceil(gline.s13 / maxseglen)) seglen = gline.s13 / n for i in range(1, n): s = seglen * i g = gline.Position( s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) pts.append(QgsPointXY(g['lon2'], g['lat2'])) pts.append(ptEnd) if layercrs != epsg4326: # Convert each point back to the output CRS for x, pt in enumerate(pts): pts[x] = transfrom4326.transform(pt) fline.setGeometry(QgsGeometry.fromPolylineXY(pts)) else: if not feature.geometry().isMultipart(): line = seg[0] numpoints = len(line) ptStart = QgsPointXY(line[0][0], line[0][1]) if layercrs != epsg4326: # Convert to 4326 ptStart = transto4326.transform(ptStart) pts = [ptStart] for x in range(1, numpoints): ptEnd = QgsPointXY(line[x][0], line[x][1]) if layercrs != epsg4326: # Convert to 4326 ptEnd = transto4326.transform(ptEnd) gline = geod.InverseLine(ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x()) if gline.s13 > maxseglen: n = int(math.ceil(gline.s13 / maxseglen)) seglen = gline.s13 / n for i in range(1, n): s = seglen * i g = gline.Position( s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) pts.append(QgsPointXY(g['lon2'], g['lat2'])) pts.append(ptEnd) ptStart = ptEnd if layercrs != epsg4326: # Convert each point back to the output CRS for x, pt in enumerate(pts): pts[x] = transfrom4326.transform(pt) fline.setGeometry(QgsGeometry.fromPolylineXY(pts)) else: # MultiLineString outseg = [] for line in seg: numpoints = len(line) ptStart = QgsPointXY(line[0][0], line[0][1]) if layercrs != epsg4326: # Convert to 4326 ptStart = transto4326.transform(ptStart) pts = [ptStart] for x in range(1, numpoints): ptEnd = QgsPointXY(line[x][0], line[x][1]) if layercrs != epsg4326: # Convert to 4326 ptEnd = transto4326.transform(ptEnd) gline = geod.InverseLine(ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x()) if gline.s13 > maxseglen: n = int(math.ceil(gline.s13 / maxseglen)) seglen = gline.s13 / n for i in range(1, n): s = seglen * i g = gline.Position( s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) pts.append(QgsPointXY( g['lon2'], g['lat2'])) pts.append(ptEnd) ptStart = ptEnd if layercrs != epsg4326: # Convert each point back to the output CRS for x, pt in enumerate(pts): pts[x] = transfrom4326.transform(pt) outseg.append(pts) fline.setGeometry(QgsGeometry.fromMultiPolylineXY(outseg)) fline.setAttributes(feature.attributes()) sink.addFeature(fline) except Exception: num_bad += 1 feedback.setProgress(int(cnt * total)) return num_bad
def getWGSGeom(self, original_geom): crsSrc = self.canvas.mapSettings().destinationCrs() crsDest = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId) coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) wgsGeom = coordinateTransformer.transform(original_geom) return wgsGeom
def accept(self): try: distance = float(self.distLineEdit.text()) azimuth = float(self.azimuthLineEdit.text()) units = self.unitsComboBox.currentIndex( ) # 0 km, 1 m, 2 nm, 3 miles, 4 yards, 5 ft, 6 inches, 7 cm start = self.checkBox.isChecked() except: self.iface.messageBar().pushMessage( "", tr("Either distance or azimuth were invalid"), level=Qgis.Warning, duration=4) return layer = self.iface.activeLayer() if layer is None: self.iface.messageBar().pushMessage( "", tr("No point or line layer selected"), level=Qgis.Warning, duration=4) return measureFactor = conversionToMeters(units) distance = distance * measureFactor pt = self.pt destCRS = layer.crs() transform = QgsCoordinateTransform(epsg4326, destCRS, QgsProject.instance()) if layer.wkbType() == QgsWkbTypes.Point: g = geod.Direct(pt.y(), pt.x(), azimuth, distance, Geodesic.LATITUDE | Geodesic.LONGITUDE) if start: ptStart = transform.transform(self.pt.x(), self.pt.y()) feat = QgsFeature(layer.fields()) feat.setGeometry(QgsGeometry.fromPointXY(ptStart)) layer.addFeature(feat) pt = transform.transform(g['lon2'], g['lat2']) feat = QgsFeature(layer.fields()) feat.setGeometry(QgsGeometry.fromPointXY(pt)) layer.addFeature(feat) else: # It will either be a LineString or MultiLineString maxseglen = settings.maxSegLength * 1000.0 # Needs to be in meters maxSegments = settings.maxSegments l = geod.Line(pt.y(), pt.x(), azimuth) n = int(math.ceil(distance / maxseglen)) if n > maxSegments: n = maxSegments seglen = distance / n pts = [] for i in range(0, n + 1): s = seglen * i g = l.Position( s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL) ptc = transform.transform(g['lon2'], g['lat2']) pts.append(ptc) feat = QgsFeature(layer.fields()) if layer.wkbType() == QgsWkbTypes.LineString: feat.setGeometry(QgsGeometry.fromPolylineXY(pts)) else: feat.setGeometry(QgsGeometry.fromMultiPolylineXY([pts])) layer.addFeatures([feat]) layer.updateExtents() self.iface.mapCanvas().refresh() self.close()
def wgs84Center(self): if self.crs and self.baseExtent: wgs84 = QgsCoordinateReferenceSystem(4326) transform = QgsCoordinateTransform(self.crs, wgs84) return transform.transform(self.baseExtent.center()) return None
def do_operation(self): """ perform footprint load operation """ # input/output data checking already done during property set # load and verify popgrid_file = self.inputs[0].value pop_field = self.inputs[1].value popgrid_layername = 'zone_%s' % get_unique_filename() try: tmp_popgrid_layer = load_shapefile_verify(popgrid_file, popgrid_layername, [pop_field]) except AssertionError as err: raise OperatorError(str(err), self.__class__) logAPICall.log( 'tmp_fp_layer.crs().epsg() %s ' % tmp_popgrid_layer.crs().epsg(), logAPICall.DEBUG) if tmp_popgrid_layer.crs().epsg() != self._crs.epsg(): transform = QgsCoordinateTransform(tmp_popgrid_layer.crs(), self._crs) transform_required = True else: transform_required = False # output grid fields = { 0: QgsField(GID_FIELD_NAME, QVariant.Int), 1: QgsField(CNT_FIELD_NAME, QVariant.Double), } pop_idx = layer_field_index(tmp_popgrid_layer, pop_field) output_file = '%spop_grid_%s.shp' % (self._tmp_dir, get_unique_filename()) logAPICall.log('create outputfile %s ... ' % output_file, logAPICall.DEBUG) try: writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPoint, self._crs, "ESRI Shapefile") f = QgsFeature() gid = 0 for _f in layer_features(tmp_popgrid_layer): # NOTE: geom.transform does projection in place to underlying C object # 1. get geometry geom = _f.geometry() # 2. change project if required if transform_required: geom = transform.transform(geom) # 3. write to file gid += 1 f.setGeometry(geom) f.addAttribute(0, QVariant(gid)) f.addAttribute(1, _f.attributeMap()[pop_idx]) writer.addFeature(f) del writer, f except Exception as err: remove_shapefile(output_file) raise OperatorError("error creating footprint centroids: %s" % err, self.__class__) popgrid_layername = 'popgrid_%s' % get_unique_filename() popgrid_layer = load_shapefile(output_file, popgrid_layername) if not popgrid_layer: raise OperatorError( 'Error loading footprint centroid file' % (output_file), self.__class__) # clean up del tmp_popgrid_layer # store data in output self.outputs[0].value = popgrid_layer self.outputs[1].value = output_file
def clicked(self, pt, b): # if self.dlg.captureButton.isChecked(): '''Capture the coordinate when the mouse button has been released, format it, and copy it to dashboard''' # transform the coordinate to 4326 but display it in the original crs canvasCRS = self.canvas.mapSettings().destinationCrs() epsg4326 = QgsCoordinateReferenceSystem('EPSG:4326') transform = QgsCoordinateTransform( canvasCRS, epsg4326, QgsProject.instance()) pt4326 = transform.transform(pt.x(), pt.y()) lat = pt4326.y() lon = pt4326.x() self.getCredentials() # change dockwidget corrdinate with the original crs if self.dlg.captureButton.isChecked(): url = "https://revgeocode.search.hereapi.com/v1/revgeocode?at=" + \ str(lat) + "%2C" + str(lon) + "%2C10&limit=1&lang=en-US&apiKey=" + self.appId print(url) r = requests.get(url) try: self.dlg.fromAddress.setText( json.loads( r.text)["items"][0]["title"]) except BaseException: self.dlg.fromAddress.setText("no address found") print("something went wrong") self.dlg.FromLabel.setText( str("%.5f" % lat) + ',' + str("%.5f" % lon)) self.dlg.captureButton.setChecked(False) if self.dlg.captureButton_2.isChecked(): url = "https://revgeocode.search.hereapi.com/v1/revgeocode?at=" + \ str(lat) + "%2C" + str(lon) + "%2C10&limit=1&lang=en-US&apiKey=" + self.appId r = requests.get(url) try: self.dlg.toAddress.setText( json.loads( r.text)["items"][0]["title"]) except BaseException: self.dlg.toAddress.setText("no address found") print("something went wrong") self.dlg.ToLabel.setText( str("%.5f" % lat) + ',' + str("%.5f" % lon)) self.setWidget(self.dlg) self.iface.mapCanvas().setCursor(Qt.ArrowCursor) self.dlg.captureButton_2.setChecked(False) if self.dlg.captureButton_4.isChecked(): url = "https://revgeocode.search.hereapi.com/v1/revgeocode?at=" + \ str(lat) + "%2C" + str(lon) + "%2C10&limit=1&lang=en-US&apiKey=" + self.appId r = requests.get(url) try: self.dlg.placesAddress.setText(json.loads( r.text)["items"][0]["title"]) except BaseException: self.dlg.placesAddress.setText("no address found") print("something went wrong") self.dlg.placeLabel.setText( str("%.5f" % lat) + ',' + str("%.5f" % lon)) self.dlg.findPOISButton.setEnabled(True) self.setWidget(self.dlg) self.iface.mapCanvas().setCursor(Qt.ArrowCursor) self.dlg.captureButton_4.setChecked(False) if self.dlg.captureButton_3.isChecked(): url = "https://revgeocode.search.hereapi.com/v1/revgeocode?at=" + \ str(lat) + "%2C" + str(lon) + "%2C10&limit=1&lang=en-US&apiKey=" + self.appId r = requests.get(url) # print(r.text) try: self.dlg.IsoAddress.setText( json.loads( r.text)["items"][0]["title"]) except BaseException: self.dlg.IsoAddress.setText("no address found") print("something went wrong") self.dlg.IsoLabel.setText( str("%.5f" % lat) + ',' + str("%.5f" % lon)) self.dlg.calcIsoButton.setEnabled(True) self.setWidget(self.dlg) self.iface.mapCanvas().setCursor(Qt.ArrowCursor) self.dlg.captureButton_3.setChecked(False)
def reverseGeocode(self): layer = self.mMapLayerComboBox.currentLayer() if not layer: self.iface.messageBar().pushMessage( "", "No valid point vector layer to reverse geocode", level=QgsMessageBar.WARNING, duration=2) return self.numAddress = layer.featureCount() self.totalAddress = self.numAddress self.numErrors = 0 if self.numAddress > self.settings.maxAddress: self.iface.messageBar().pushMessage( "", "Maximum geocodes to process were exceeded. Please reduce the number and try again.", level=QgsMessageBar.WARNING, duration=4) return layername = self.layerLineEdit.text() self.pointLayer = QgsVectorLayer("point?crs=epsg:4326", layername, "memory") self.provider = self.pointLayer.dataProvider() self.provider.addAttributes( [QgsField("display_name", QVariant.String)]) self.pointLayer.updateFields() if self.showLabelCheckBox.checkState(): # Display labels label = QgsPalLayerSettings() label.readFromLayer(self.pointLayer) label.enabled = True label.fieldName = 'display_name' label.placement = QgsPalLayerSettings.AroundPoint label.setDataDefinedProperty(QgsPalLayerSettings.Size, True, True, '8', '') label.writeToLayer(self.pointLayer) layerCRS = layer.crs() epsg4326 = QgsCoordinateReferenceSystem("EPSG:4326") transform = QgsCoordinateTransform(layerCRS, epsg4326, QgsProject.instance()) iter = layer.getFeatures() self.geocodes = {} for feature in iter: # already know that this is a point vector layer pt = feature.geometry().asPoint() # make sure the coordinates are in EPSG:4326 pt = transform.transform(pt.x(), pt.y()) lat = str(pt.y()) lon = str(pt.x()) url = self.settings.reverseURL( ) + '?format=json&lat=' + lat + '&lon=' + lon + '&zoom=18&addressdetails=0' # print url qurl = QUrl(url) request = QNetworkRequest(qurl) request.setRawHeader( b"User-Agent", b"Mozilla/5.0 (Windows NT 6.1: WOW64; rv:52.0) Gecko/20100101 Firefox/52.0" ) request.setRawHeader(b"Connection", b"keep-alive") request.setRawHeader( b"Accept", b"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" ) reply = QgsNetworkAccessManager.instance().get(request) self.geocodes[reply] = pt reply.finished.connect(self.reverseGeoFinished)
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) sampled_raster = self.parameterAsRasterLayer(parameters, self.RASTERCOPY, context) columnPrefix = self.parameterAsString(parameters, self.COLUMN_PREFIX, context) if source is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT)) source_fields = source.fields() raster_fields = QgsFields() # append field to vector as columnPrefix_bandCount for b in range(sampled_raster.bandCount()): raster_fields.append( QgsField(columnPrefix + str('_{}'.format(b + 1)), QVariant.Double)) # combine all the vector fields out_fields = QgsProcessingUtils.combineFields(source_fields, raster_fields) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, out_fields, source.wkbType(), source.sourceCrs()) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) total = 100.0 / source.featureCount() if source.featureCount() else 0 features = source.getFeatures() # create the coordinates transformation context ct = QgsCoordinateTransform(source.sourceCrs(), sampled_raster.crs(), context.transformContext()) for n, i in enumerate(source.getFeatures()): attrs = i.attributes() if i.geometry().isMultipart( ) and i.geometry().constGet().partCount() > 1: sink.addFeature(i, QgsFeatureSink.FastInsert) feedback.setProgress(int(n * total)) feedback.reportError( self.tr( 'Impossible to sample data of multipart feature {}.'). format(i.id())) continue # get the feature geometry as point point = QgsPointXY() if i.geometry().isMultipart(): point = i.geometry().asMultiPoint()[0] else: point = i.geometry().asPoint() # reproject to raster crs try: point = ct.transform(point) except QgsCsException: for b in range(sampled_raster.bandCount()): attrs.append(None) i.setAttributes(attrs) sink.addFeature(i, QgsFeatureSink.FastInsert) feedback.setProgress(int(n * total)) feedback.reportError( self.tr( 'Could not reproject feature {} to raster CRS').format( i.id())) continue for b in range(sampled_raster.bandCount()): value, ok = sampled_raster.dataProvider().sample(point, b + 1) if ok: attrs.append(value) else: attrs.append(NULL) i.setAttributes(attrs) sink.addFeature(i, QgsFeatureSink.FastInsert) feedback.setProgress(int(n * total)) return {self.OUTPUT: dest_id}
class MoveSiteUI(QDialog): def __init__(self, iface, parent=None): super(MoveSiteUI, self).__init__() self.iface = iface self.parent = parent # 获取工程所在路径 self.project_dir = getProjectDir(self.iface) # 获取操作图层对象 self.sitelayer = getLayerByName(u'基站', self.iface) self.celllayer = getLayerByName(u'小区', self.iface) self.selectedSiteFeatures = self.sitelayer.selectedFeatures() self.allCellFeatures = self.celllayer.getFeatures() # 初始化鼠标点选事件 self.mapTool = MapTool(self.iface.mapCanvas()) self.mapTool.canvasClicked.connect(self.mouseClicked) self.iface.mapCanvas().setMapTool(self.mapTool) self.iface.mapCanvas().mapToolSet[QgsMapTool, QgsMapTool].connect( self.mapToolChanged) self.crsXform = QgsCoordinateTransform() self.crsXform.setDestCRS(QgsCoordinateReferenceSystem(4326)) self.pos = None '''self.cellutils = FeatureUtils(u'小区', self.iface) self.siteutils = FeatureUtils(u'基站', self.iface)''' self.initUI() # 初始化界面 def initUI(self): self.setGeometry(200, 200, 200, 100) self.setWindowFlags(Qt.WindowStaysOnTopHint) self.setWindowTitle(u'移动基站') title1 = QLabel(u'基站:') self.titleEdit1 = QLineEdit() self.titleEdit1.setReadOnly(True) lon_label = QLabel(u"经度:") self.lon_edit = QLineEdit() lat_label = QLabel(u"纬度:") self.lat_edit = QLineEdit() grid = QGridLayout() grid.setSpacing(10) grid.addWidget(title1, 1, 0) grid.addWidget(self.titleEdit1, 1, 1) grid.addWidget(lon_label, 2, 0) grid.addWidget(self.lon_edit, 2, 1) grid.addWidget(lat_label, 3, 0) grid.addWidget(self.lat_edit, 3, 1) ok = QPushButton(u'确定') self.connect(ok, SIGNAL('clicked()'), self.moveTo) cancel = QPushButton(u'取消') self.connect(cancel, SIGNAL('clicked()'), self.accept) btn_hbox = QHBoxLayout() btn_hbox.setSpacing(10) btn_hbox.addStretch(1) btn_hbox.addWidget(ok) btn_hbox.addWidget(cancel) btn_hbox.addStretch(1) vbox = QVBoxLayout() vbox.setSpacing(10) vbox.addLayout(grid) vbox.addStretch(1) vbox.addLayout(btn_hbox) self.setLayout(vbox) self.resize(270, 150) # 获取选中的基站信息并填入相应格中 self.oldcelllist = [] for f in self.selectedSiteFeatures: sitename = f[u'基站名'] id = f[u'基站ID'] operator = f[u'运营商'] bsc = f[u'RNC-BSC'] self.titleEdit1.setText(sitename) for i in self.allCellFeatures: cid = i[u'基站ID'] copetator = i[u'运营商'] cbsc = i[u'RNC-BSC'] if cid == id and copetator == operator and bsc == cbsc: # 找出与基站ID相同的小区 self.oldcelllist.append(i.id()) # 选中与基站相关联的小区 if len(self.oldcelllist) != 0: # 先取消原有选择 self.celllayer.selectAll() self.celllayer.invertSelection() self.celllayer.setSelectedFeatures(self.oldcelllist) self.selectedCellFeatures = self.celllayer.selectedFeatures() else: self.selectedCellFeatures = [] # 鼠标点击监听器 def mouseClicked(self, pos, button): if button == Qt.LeftButton: self.show() self.pos = pos self.geoPos = self.crsXform.transform(self.pos) self.x = unicode(self.geoPos.x()) self.y = unicode(self.geoPos.y()) self.lon_edit.setText(self.x) self.lat_edit.setText(self.y) @pyqtSlot(QgsMapTool, QgsMapTool) def mapToolChanged(self, mapToolNew, mapToolOld): if mapToolOld == self.mapTool and mapToolNew != self.mapTool: self.close() self.selectedCellFeatures = [] self.selectedSiteFeatures = [] self.sitelayer.selectAll() self.sitelayer.invertSelection() def moveTo(self): # 获取小区大小和长度设置 setting = getCellGraphicParam(self.iface) # 判断是否读取到参数设置 if not setting: QMessageBox.critical(self, u"错误", u"无法获取小区图形参数设置") self.accept() return oldsitelist = [] sitefeatures = [] cellfeatures = [] if len(self.selectedSiteFeatures) == 1: for f in self.selectedSiteFeatures: oldsitelist.append(f.id()) siteAttrs = f.attributes() del siteAttrs[0] siteAttrs[3] = self.lon_edit.text() siteAttrs[4] = self.lat_edit.text() self.titleEdit1.setText(unicode(siteAttrs[1])) siteFeature = createASiteFeature( QgsPoint(float(siteAttrs[3]), float(siteAttrs[4])), siteAttrs) sitefeatures.append(siteFeature) for c in self.selectedCellFeatures: cellAttrs = c.attributes() del cellAttrs[0] # 删除唯一标识符,创建新feature后会重新生成,避免重复 cellAttrs[8] = self.lon_edit.text() cellAttrs[9] = self.lat_edit.text() # 识别图形设置 operator = cellAttrs[18] if setting["type"] == 0: if operator == u'移动': szAngle = setting[u"移动"][0] szLength = setting[u"移动"][1] elif operator == u'联通': szAngle = setting[u"联通"][0] szLength = setting[u"联通"][1] elif operator == u'电信': szAngle = setting[u"电信"][0] szLength = setting[u"电信"][1] else: szAngle = setting[u"铁塔"][0] szLength = setting[u"铁塔"][1] else: # 自定义 system = cellAttrs[10] frequency = cellAttrs[12] # 获取默认设置 szAngle = setting[u"默认"][0] szLength = setting[u"默认"][1] # 获取分类 case_list = setting["case_list"] for (c_system, c_frequency, c_angle, c_length) in case_list: if c_system and (not c_frequency): if system == c_system: szAngle = c_angle szLength = c_length elif (not c_system) and c_frequency: if frequency == c_frequency: szAngle = c_angle szLength = c_length elif c_system and c_frequency: if (system == c_system) and (frequency == c_frequency): szAngle = c_angle szLength = c_length # 生成小区扇形geometry cellGeometry = createSector( QgsPoint(float(cellAttrs[8]), float(cellAttrs[9])), szLength, self.iface, True, cellAttrs[7], szAngle) cellFeature = createACellFeature(cellGeometry, cellAttrs) cellfeatures.append(cellFeature) else: QMessageBox.critical(self, u"提醒", u"需且仅需选择一个基站!") self.accept() return False button = QMessageBox.question(self, "Question", u"移动后将无法撤回,是否继续?", QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok) if button == QMessageBox.Ok: # 先删除旧features再往图层上添加新features delFeatures(self.sitelayer, oldsitelist) importFeaturesToLayer(self.sitelayer, sitefeatures) delFeatures(self.celllayer, self.oldcelllist) importFeaturesToLayer(self.celllayer, cellfeatures) self.iface.actionDraw().trigger() self.selectedSiteFeatures = [] self.selectedCellFeatures = [] self.sitelayer.selectAll() self.sitelayer.invertSelection() else: return False self.accept()
def exportRasterLayer(layer, safeLayerName, dataPath): name_ts = safeLayerName + unicode(int(time.time())) # We need to create a new file to export style piped_file = os.path.join(tempfile.gettempdir(), name_ts + '_piped.tif') piped_extent = layer.extent() piped_width = layer.height() piped_height = layer.width() piped_crs = layer.crs() piped_renderer = layer.renderer() piped_provider = layer.dataProvider() pipe = QgsRasterPipe() pipe.set(piped_provider.clone()) pipe.set(piped_renderer.clone()) file_writer = QgsRasterFileWriter(piped_file) file_writer.writeRaster(pipe, piped_width, piped_height, piped_extent, piped_crs) # Extent of the layer in EPSG:3857 crsSrc = layer.crs() crsDest = QgsCoordinateReferenceSystem(3857) xform = QgsCoordinateTransform(crsSrc, crsDest) extentRep = xform.transform(layer.extent()) extentRepNew = ','.join([ unicode(extentRep.xMinimum()), unicode(extentRep.xMaximum()), unicode(extentRep.yMinimum()), unicode(extentRep.yMaximum()) ]) # Reproject in 3857 piped_3857 = os.path.join(tempfile.gettempdir(), name_ts + '_piped_3857.tif') # Export layer as PNG out_raster = dataPath + '.png' qgis_version = QGis.QGIS_VERSION if int(qgis_version.split('.')[1]) < 15: processing.runalg("gdalogr:warpreproject", piped_file, layer.crs().authid(), "EPSG:3857", "", 0, 1, 0, -1, 75, 6, 1, False, 0, False, "", piped_3857) processing.runalg("gdalogr:translate", piped_3857, 100, True, "", 0, "", extentRepNew, False, 0, 0, 75, 6, 1, False, 0, False, "", out_raster) else: try: warpArgs = { "INPUT": piped_file, "SOURCE_SRS": layer.crs().authid(), "DEST_SRS": "EPSG:3857", "NO_DATA": "", "TR": 0, "METHOD": 2, "RAST_EXT": extentRepNew, "EXT_CRS": "EPSG:3857", "RTYPE": 0, "COMPRESS": 4, "JPEGCOMPRESSION": 75, "ZLEVEL": 6, "PREDICTOR": 1, "TILED": False, "BIGTIFF": 0, "TFW": False, "EXTRA": "", "OUTPUT": piped_3857 } procRtn = processing.runalg("gdalogr:warpreproject", warpArgs) # force exception on algorithm fail for val in procRtn: pass except: try: warpArgs = { "INPUT": piped_file, "SOURCE_SRS": layer.crs().authid(), "DEST_SRS": "EPSG:3857", "NO_DATA": "", "TR": 0, "METHOD": 2, "RAST_EXT": extentRepNew, "RTYPE": 0, "COMPRESS": 4, "JPEGCOMPRESSION": 75, "ZLEVEL": 6, "PREDICTOR": 1, "TILED": False, "BIGTIFF": 0, "TFW": False, "EXTRA": "", "OUTPUT": piped_3857 } procRtn = processing.runalg("gdalogr:warpreproject", warpArgs) # force exception on algorithm fail for val in procRtn: pass except: try: warpArgs = { "INPUT": piped_file, "SOURCE_SRS": layer.crs().authid(), "DEST_SRS": "EPSG:3857", "NO_DATA": "", "TR": 0, "METHOD": 2, "RTYPE": 0, "COMPRESS": 4, "JPEGCOMPRESSION": 75, "ZLEVEL": 6, "PREDICTOR": 1, "TILED": False, "BIGTIFF": 0, "TFW": False, "EXTRA": "", "OUTPUT": piped_3857 } procRtn = processing.runalg("gdalogr:warpreproject", warpArgs) for val in procRtn: pass except: shutil.copyfile(piped_file, piped_3857) try: processing.runalg("gdalogr:translate", piped_3857, 100, True, "", 0, "", extentRepNew, False, 5, 4, 75, 6, 1, False, 0, False, "", out_raster) except: shutil.copyfile(piped_3857, out_raster)
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.PrmInputLayer, context) shapetype = self.parameterAsInt(parameters, self.PrmShapeType, context) sidescol = self.parameterAsString(parameters, self.PrmNumberOfSidesField, context) anglecol = self.parameterAsString(parameters, self.PrmStartingAngleField, context) distcol = self.parameterAsString(parameters, self.PrmRadiusField, context) sides = self.parameterAsInt(parameters, self.PrmDefaultNumberOfSides, context) angle = self.parameterAsDouble(parameters, self.PrmDefaultStartingAngle, context) defaultDist = self.parameterAsInt(parameters, self.PrmDefaultRadius, context) unitOfDist = self.parameterAsInt(parameters, self.PrmUnitsOfMeasure, context) export_geom = self.parameterAsBool(parameters, self.PrmExportInputGeometry, context) measureFactor = conversionToMeters(unitOfDist) defaultDist *= measureFactor srcCRS = source.sourceCrs() fields = source.fields() if export_geom: names = fields.names() name_x, name_y = settings.getGeomNames(names) fields.append(QgsField(name_x, QVariant.Double)) fields.append(QgsField(name_y, QVariant.Double)) if shapetype == 0: (sink, dest_id) = self.parameterAsSink(parameters, self.PrmOutputLayer, context, fields, QgsWkbTypes.Polygon, srcCRS) else: (sink, dest_id) = self.parameterAsSink(parameters, self.PrmOutputLayer, context, fields, QgsWkbTypes.LineString, srcCRS) if srcCRS != epsg4326: geomTo4326 = QgsCoordinateTransform(srcCRS, epsg4326, QgsProject.instance()) toSinkCrs = QgsCoordinateTransform(epsg4326, srcCRS, QgsProject.instance()) featureCount = source.featureCount() total = 100.0 / featureCount if featureCount else 0 iterator = source.getFeatures() numbad = 0 for cnt, feature in enumerate(iterator): if feedback.isCanceled(): break try: pt = feature.geometry().asPoint() pt_orig_x = pt.x() pt_orig_y = pt.y() if srcCRS != epsg4326: pt = geomTo4326.transform(pt.x(), pt.y()) if sidescol: s = int(feature[sidescol]) else: s = sides if anglecol: startangle = float(feature[anglecol]) else: startangle = angle if distcol: d = float(feature[distcol]) * measureFactor else: d = defaultDist pts = [] i = s while i >= 0: a = (i * 360.0 / s) + startangle i -= 1 g = geod.Direct(pt.y(), pt.x(), a, d, Geodesic.LATITUDE | Geodesic.LONGITUDE) pts.append(QgsPointXY(g['lon2'], g['lat2'])) # If the Output crs is not 4326 transform the points to the proper crs if srcCRS != epsg4326: for x, ptout in enumerate(pts): pts[x] = toSinkCrs.transform(ptout) f = QgsFeature() if shapetype == 0: f.setGeometry(QgsGeometry.fromPolygonXY([pts])) else: f.setGeometry(QgsGeometry.fromPolylineXY(pts)) attr = feature.attributes() if export_geom: attr.append(pt_orig_x) attr.append(pt_orig_y) f.setAttributes(attr) sink.addFeature(f) except Exception: numbad += 1 if cnt % 100 == 0: feedback.setProgress(int(cnt * total)) if numbad > 0: feedback.pushInfo( tr("{} out of {} features had invalid parameters and were ignored." .format(numbad, featureCount))) return {self.PrmOutputLayer: dest_id}
class PositionDisplay(QWidget): ''' Widget to display the mouse position on the canvas in geographic coordinates (lat/lon) The display format can be altered. ''' __FORMATS = ('DD', 'DDM', 'DMDS') exportPosition = pyqtSignal(str) def __init__(self, iface, parent=None): '''Constructor :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface ''' super(PositionDisplay, self).__init__(parent) self.setObjectName('positionDisplay') layout = QHBoxLayout() layout.setContentsMargins(0, 0, 3, 0) self.button = QToolButton(self) self.button.setObjectName('toolButtonFormat') self.button.clicked.connect(self.switchCoordinateFormat) self.button.setAutoRaise(True) layout.addWidget(self.button) self.label = QLineEdit('--- ---') self.label.setReadOnly(True) self.label.setAlignment(Qt.AlignHCenter) self.label.setStyleSheet('font-weight: bold;') layout.addWidget(self.label) self.setLayout(layout) s = QSettings() self.format = s.value('PosiView/PositionDisplay/Format', defaultValue=1, type=int) self.button.setText(self.__FORMATS[self.format]) canvas = iface.mapCanvas() crsDest = QgsCoordinateReferenceSystem('EPSG:4326') crsSrc = canvas.mapSettings().destinationCrs() self.xform = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) canvas.xyCoordinates.connect(self.mouseMoved) canvas.destinationCrsChanged.connect(self.mapCrsHasChanged) self.canvas = canvas try: self.sep = cf.separator() + ' ' except AttributeError: self.sep = ', ' @pyqtSlot(name='on_toolButtonFormat_clicked') def switchCoordinateFormat(self): self.format = (self.format + 1) % 3 self.button.setText(self.tr(self.__FORMATS[self.format])) s = QSettings() s.setValue('PosiView/PositionDisplay/Format', self.format) @pyqtSlot() def mapCrsHasChanged(self): crsSrc = self.canvas.mapSettings().destinationCrs() self.xform.setSourceCrs(crsSrc) @pyqtSlot(QgsPointXY) def mouseMoved(self, point): pt = self.xform.transform(point) pos = self.posToStr(pt) self.label.setText(pos) self.exportPosition.emit(pos) def posToStr(self, pos): flg = cf.FlagDegreesUseStringSuffix if self.format == 1: f, pr = cf.FormatDegreesMinutes, 4 elif self.format == 2: f, pr = cf.FormatDegreesMinutesSeconds, 2 else: f, pr, flg = cf.FormatDecimalDegrees, 6, cf.FormatFlag(0) return self.sep.join( (cf.formatY(pos.y(), f, pr, flg), cf.formatX(pos.x(), f, pr, flg)))
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.PrmInputLayer, context) angle = self.parameterAsDouble(parameters, self.PrmTransformRotation, context) scale = self.parameterAsDouble(parameters, self.PrmTransformScale, context) azimuth = self.parameterAsDouble(parameters, self.PrmTransformAzimuth, context) distance = self.parameterAsDouble(parameters, self.PrmTransformDistance, context) units = self.parameterAsInt(parameters, self.PrmTransformUnits, context) to_meters = conversionToMeters(units) distance = distance * to_meters src_crs = source.sourceCrs() wkbtype = source.wkbType() (sink, dest_id) = self.parameterAsSink(parameters, self.PrmOutputLayer, context, source.fields(), wkbtype, src_crs) geom_to_4326 = QgsCoordinateTransform(src_crs, epsg4326, QgsProject.instance()) to_sink_crs = QgsCoordinateTransform(epsg4326, src_crs, QgsProject.instance()) geomtype = QgsWkbTypes.geometryType(wkbtype) featureCount = source.featureCount() total = 100.0 / featureCount if featureCount else 0 iterator = source.getFeatures() for cnt, feature in enumerate(iterator): if feedback.isCanceled(): break geom = feature.geometry() # Find the centroid of the vector shape. We will resize everything based on this centroid = geom.centroid().asPoint() centroid = geom_to_4326.transform(centroid.x(), centroid.y()) cy = centroid.y() cx = centroid.x() if distance != 0: g = geod.Direct(cy, cx, azimuth, distance, Geodesic.LATITUDE | Geodesic.LONGITUDE) new_centroid = QgsPoint(g['lon2'], g['lat2']) else: new_centroid = centroid # Find the x & y coordinates of the new centroid ncy = new_centroid.y() ncx = new_centroid.x() vertices = geom.vertices() for vcnt, vertex in enumerate(vertices): v = geom_to_4326.transform(vertex.x(), vertex.y()) l = geod.Inverse(cy, cx, v.y(), v.x()) vdist = l['s12'] vazi = l['azi1'] if scale != 1: vdist = vdist * scale if angle != 0: vazi += angle g = geod.Direct(ncy, ncx, vazi, vdist, Geodesic.LATITUDE | Geodesic.LONGITUDE) new_vertex = to_sink_crs.transform(g['lon2'], g['lat2']) geom.moveVertex(new_vertex.x(), new_vertex.y(), vcnt) feature.setGeometry(geom) sink.addFeature(feature) if cnt % 100 == 0: feedback.setProgress(int(cnt * total)) return {self.PrmOutputLayer: dest_id}
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.PrmInputLayer, context) shape_type = self.parameterAsInt(parameters, self.PrmShapeType, context) azimuth_mode = self.parameterAsInt(parameters, self.PrmAzimuthMode, context) start_angle_col = self.parameterAsString(parameters, self.PrmAzimuth1Field, context) end_angle_col = self.parameterAsString(parameters, self.PrmAzimuth2Field, context) inner_radius_col = self.parameterAsString(parameters, self.PrmInnerRadiusField, context) outer_radius_col = self.parameterAsString(parameters, self.PrmOuterRadiusField, context) start_angle = self.parameterAsDouble(parameters, self.PrmDefaultAzimuth1, context) end_angle = self.parameterAsDouble(parameters, self.PrmDefaultAzimuth2, context) inner_radius = self.parameterAsDouble(parameters, self.PrmInnerRadius, context) outer_radius = self.parameterAsDouble(parameters, self.PrmOuterRadius, context) segments = self.parameterAsInt(parameters, self.PrmDrawingSegments, context) units = self.parameterAsInt(parameters, self.PrmUnitsOfMeasure, context) export_geom = self.parameterAsBool(parameters, self.PrmExportInputGeometry, context) measure_factor = conversionToMeters(units) inner_radius *= measure_factor outer_radius *= measure_factor pt_spacing = 360.0 / segments src_crs = source.sourceCrs() fields = source.fields() if export_geom: names = fields.names() name_x, name_y = settings.getGeomNames(names) fields.append(QgsField(name_x, QVariant.Double)) fields.append(QgsField(name_y, QVariant.Double)) if shape_type == 0: (sink, dest_id) = self.parameterAsSink( parameters, self.PrmOutputLayer, context, fields, QgsWkbTypes.Polygon, src_crs) else: (sink, dest_id) = self.parameterAsSink( parameters, self.PrmOutputLayer, context, fields, QgsWkbTypes.LineString, src_crs) if src_crs != epsg4326: geom_to_4326 = QgsCoordinateTransform(src_crs, epsg4326, QgsProject.instance()) to_sink_crs = QgsCoordinateTransform(epsg4326, src_crs, QgsProject.instance()) feature_count = source.featureCount() total = 100.0 / feature_count if feature_count else 0 iterator = source.getFeatures() num_bad = 0 for cnt, feature in enumerate(iterator): if feedback.isCanceled(): break try: pts = [] pt = feature.geometry().asPoint() pt_orig_x = pt.x() pt_orig_y = pt.y() # make sure the coordinates are in EPSG:4326 if src_crs != epsg4326: pt = geom_to_4326.transform(pt.x(), pt.y()) if start_angle_col: sangle = float(feature[start_angle_col]) else: sangle = start_angle if end_angle_col: eangle = float(feature[end_angle_col]) else: eangle = end_angle if azimuth_mode == 1: width = abs(eangle) / 2.0 eangle = sangle + width sangle -= width if outer_radius_col: outer_dist = float(feature[outer_radius_col]) * measure_factor else: outer_dist = outer_radius if inner_radius_col: inner_dist = float(feature[inner_radius_col]) * measure_factor else: inner_dist = inner_radius sangle = sangle % 360 eangle = eangle % 360 if sangle == eangle: # This is not valid continue if sangle > eangle: # We are crossing the 0 boundary so lets just subtract # 360 from it. sangle -= 360.0 sanglesave = sangle while sangle < eangle: # Draw the outer arc g = geod.Direct(pt.y(), pt.x(), sangle, outer_dist, Geodesic.LATITUDE | Geodesic.LONGITUDE) pts.append(QgsPointXY(g['lon2'], g['lat2'])) sangle += pt_spacing # add this number of degrees to the angle g = geod.Direct(pt.y(), pt.x(), eangle, outer_dist, Geodesic.LATITUDE | Geodesic.LONGITUDE) pts.append(QgsPointXY(g['lon2'], g['lat2'])) if inner_dist == 0: # This will just be a pie wedge pts.append(pt) else: sangle = sanglesave while eangle > sangle: # Draw the inner arc g = geod.Direct(pt.y(), pt.x(), eangle, inner_dist, Geodesic.LATITUDE | Geodesic.LONGITUDE) pts.append(QgsPointXY(g['lon2'], g['lat2'])) eangle -= pt_spacing # subtract this number of degrees to the angle g = geod.Direct(pt.y(), pt.x(), sangle, inner_dist, Geodesic.LATITUDE | Geodesic.LONGITUDE) pts.append(QgsPointXY(g['lon2'], g['lat2'])) pts.append(pts[0]) makeIdlCrossingsPositive(pts) # If the Output crs is not 4326 transform the points to the proper crs if src_crs != epsg4326: for x, pt_out in enumerate(pts): pts[x] = to_sink_crs.transform(pt_out) f = QgsFeature() if shape_type == 0: f.setGeometry(QgsGeometry.fromPolygonXY([pts])) else: f.setGeometry(QgsGeometry.fromPolylineXY(pts)) attr = feature.attributes() if export_geom: attr.append(pt_orig_x) attr.append(pt_orig_y) f.setAttributes(attr) sink.addFeature(f) except Exception: num_bad += 1 feedback.setProgress(int(cnt * total)) if num_bad > 0: feedback.pushInfo( tr("{} out of {} features had invalid parameters and were ignored.".format(num_bad, feature_count))) return {self.PrmOutputLayer: dest_id}
def updateCoordinates(self, id, pt, crs): self.origPt = pt self.origCrs = crs projCRS = self.canvas.mapSettings().destinationCrs() customCRS = self.customProjectionSelectionWidget.crs() if crs == epsg4326: pt4326 = pt else: trans = QgsCoordinateTransform(crs, epsg4326, QgsProject.instance()) pt4326 = trans.transform(pt.x(), pt.y()) if id != 0: # WGS 84 if self.inputXYOrder == 0: # Y, X s = '{:.{prec}f}{}{:.{prec}f}'.format( pt4326.y(), settings.converterDelimiter, pt4326.x(), prec=settings.converter4326DDPrec) else: s = '{:.{prec}f}{}{:.{prec}f}'.format( pt4326.x(), settings.converterDelimiter, pt4326.y(), prec=settings.converter4326DDPrec) self.wgs84LineEdit.setText(s) if id != 1: # Project CRS if crs == projCRS: newpt = pt else: trans = QgsCoordinateTransform(crs, projCRS, QgsProject.instance()) newpt = trans.transform(pt.x(), pt.y()) if projCRS == epsg4326: precision = settings.converter4326DDPrec else: precision = settings.converterDDPrec if self.inputXYOrder == 0: # Y, X s = '{:.{prec}f}{}{:.{prec}f}'.format( newpt.y(), settings.converterDelimiter, newpt.x(), prec=precision) else: s = '{:.{prec}f}{}{:.{prec}f}'.format( newpt.x(), settings.converterDelimiter, newpt.y(), prec=precision) self.projLineEdit.setText(s) if id != 2: # Custom CRS if crs == customCRS: newpt = pt else: trans = QgsCoordinateTransform(crs, customCRS, QgsProject.instance()) newpt = trans.transform(pt.x(), pt.y()) if customCRS == epsg4326: precision = settings.converter4326DDPrec else: precision = settings.converterDDPrec if self.inputXYOrder == 0: # Y, X s = '{:.{prec}f}{}{:.{prec}f}'.format( newpt.y(), settings.converterDelimiter, newpt.x(), prec=precision) else: s = '{:.{prec}f}{}{:.{prec}f}'.format( newpt.x(), settings.converterDelimiter, newpt.y(), prec=precision) self.customLineEdit.setText(s) if id != 3: # D M' S" s = formatDmsString(pt4326.y(), pt4326.x(), 0, settings.converterDmsPrec, self.inputXYOrder, settings.converterDelimiter, settings.converterAddDmsSpace, settings.converterPadZeroes) self.dmsLineEdit.setText(s) if id != 4: # D M.MM' s = formatDmsString(pt4326.y(), pt4326.x(), 2, settings.converterDmmPrec, self.inputXYOrder, settings.converterDelimiter, settings.converterAddDmsSpace, settings.converterPadZeroes) self.dmLineEdit.setText(s) if id != 5: # DDMMSS s = formatDmsString(pt4326.y(), pt4326.x(), 1, settings.converterDmsPrec, self.inputXYOrder, settings.converterDdmmssDelimiter) self.ddmmssLineEdit.setText(s) if id != 6: # UTM s = latLon2UtmString(pt4326.y(), pt4326.x(), settings.converterUtmPrec) self.utmLineEdit.setText(s) if id != 7: # MGRS try: s = mgrs.toMgrs(pt4326.y(), pt4326.x()) except Exception: s = 'Invalid' self.mgrsLineEdit.setText(s) if id != 8: # Plus Codes try: s = olc.encode(pt4326.y(), pt4326.x(), settings.converterPlusCodeLength) except Exception: s = 'Invalid' self.plusLineEdit.setText(s) if id != 9: # GEOHASH try: s = geohash.encode(pt4326.y(), pt4326.x(), settings.converterGeohashPrecision) except Exception: s = 'Invalid' self.geohashLineEdit.setText(s) if id != 10: # Maidenhead try: s = maidenhead.toMaiden( pt4326.y(), pt4326.x(), precision=settings.converterMaidenheadPrecision) except Exception: s = 'Invalid' self.maidenheadLineEdit.setText(s)
class PositionDisplay(QWidget): ''' Widget to display the mouse position on the canvas in geographic coordinates (lat/lon) The display format can be altered. ''' __FORMATS = ('DD', 'DDM', 'DMDS') def __init__(self, iface, parent=None): '''Constructor :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface ''' super(PositionDisplay, self).__init__(parent) self.setObjectName('positionDisplay') layout = QHBoxLayout() layout.setContentsMargins(0, 0, 3, 0) self.button = QToolButton(self) self.button.setObjectName('toolButtonFormat') self.button.clicked.connect(self.switchCoordinateFormat) self.button.setAutoRaise(True) layout.addWidget(self.button) self.label = QLineEdit('--- ---') self.label.setReadOnly(True) self.label.setAlignment(Qt.AlignHCenter) self.label.setStyleSheet('font-weight: bold;') layout.addWidget(self.label) self.setLayout(layout) s = QSettings() self.format = s.value('PosiView/PositionDisplay/Format', defaultValue=1, type=int) self.button.setText(self.__FORMATS[self.format]) canvas = iface.mapCanvas() crsDest = QgsCoordinateReferenceSystem(4326) crsSrc = canvas.mapSettings().destinationCrs() self.xform = QgsCoordinateTransform(crsSrc, crsDest) canvas.xyCoordinates.connect(self.mouseMoved) canvas.destinationCrsChanged.connect(self.mapCrsHasChanged) self.canvas = canvas @pyqtSlot(name='on_toolButtonFormat_clicked') def switchCoordinateFormat(self): self.format = (self.format + 1) % 3 self.button.setText(self.tr(self.__FORMATS[self.format])) s = QSettings() s.setValue('PosiView/PositionDisplay/Format', self.format) @pyqtSlot() def mapCrsHasChanged(self): crsSrc = self.canvas.mapSettings().destinationCrs() self.xform.setSourceCrs(crsSrc) @pyqtSlot(QgsPoint) def mouseMoved(self, point): pt = self.xform.transform(point) self.label.setText(self.posToStr(pt)) def posToStr(self, pos): if self.format == 0: return '{:.6f}, {:.6f}'.format(pos.y(), pos.x()) if self.format == 1: return ', '.join(pos.toDegreesMinutes(4, True, True).rsplit(',')[::-1]) if self.format == 2: return ', '.join(pos.toDegreesMinutesSeconds(2, True, True).split(',')[::-1])
def add_layer_button_handler(self): geom_field = self.geometry_column_combo_box.currentText() geom_column = self.geometry_column_combo_box.currentText() elements_in_layer = Queue() upstream_taks_canceled = Queue() upstream_taks_canceled.put(False) self.file_queue = Queue() self.extent_query_job = Queue() for elm in self.base_query_elements + self.layer_import_elements: elm.setEnabled(False) if self.sender().objectName() == 'add_all_button': QgsMessageLog.logMessage('Pressed add all', 'BigQuery Layers', Qgis.Info) self.add_all_button.setText('Adding layer...') self.parent_task = LayerImportTask( 'BigQuery layer import', self.iface, self.file_queue, self.add_all_button, self.add_extents_button, self.base_query_elements, self.layer_import_elements, elements_in_layer, upstream_taks_canceled) # TASK 1: DOWNLOAD self.download_task = RetrieveQueryResultTask( 'Retrieve query result', self.iface, self.base_query_job, self.file_queue, elements_in_layer, upstream_taks_canceled) # TASK 2: Convert self.convert_task = ConvertToGeopackage('Convert to Geopackage', self.iface, geom_column, self.file_queue, upstream_taks_canceled) self.parent_task.addSubTask(self.download_task, [], QgsTask.ParentDependsOnSubTask) self.parent_task.addSubTask(self.convert_task, [self.download_task], QgsTask.ParentDependsOnSubTask) QgsApplication.taskManager().addTask(self.parent_task) elif self.sender().objectName() == 'add_extents_button': self.add_extents_button.setText('Adding layer...') extent = self.iface.mapCanvas().extent() # Reproject extents if project CRS is not EPSG:4326 project_crs = self.iface.mapCanvas().mapSettings().destinationCrs() if project_crs != QgsCoordinateReferenceSystem(4326): crcTarget = QgsCoordinateReferenceSystem(4326) transform = QgsCoordinateTransform(project_crs, crcTarget, QgsProject.instance()) extent = transform.transform(extent) self.parent_task = LayerImportTask( 'BigQuery layer import', self.iface, self.file_queue, self.add_all_button, self.add_extents_button, self.base_query_elements, self.layer_import_elements, elements_in_layer, upstream_taks_canceled) # TASK 1: Extents query self.extents_query_task = ExtentsQueryTask( 'Select window extents', self.iface, self.client, self.base_query_job, self.extent_query_job, extent.asWktPolygon(), geom_column, upstream_taks_canceled) # TASK 2: Retrive - from extent querty self.download_task = RetrieveQueryResultTask( 'Retrieve query result', self.iface, self.extent_query_job, self.file_queue, elements_in_layer, upstream_taks_canceled) # TASK 3: Convert self.convert_task = ConvertToGeopackage('Convert to Geopackage', self.iface, geom_column, self.file_queue, upstream_taks_canceled) self.parent_task.addSubTask(self.extents_query_task, [], QgsTask.ParentDependsOnSubTask) self.parent_task.addSubTask(self.download_task, [self.extents_query_task], QgsTask.ParentDependsOnSubTask) self.parent_task.addSubTask( self.convert_task, [self.extents_query_task, self.download_task], QgsTask.ParentDependsOnSubTask) QgsApplication.taskManager().addTask(self.parent_task)
def q2ge(self, back=True, player=False): """Przejście w Google Earth Pro do widoku mapy z QGIS'a.""" # print(f"[q2ge]") if not self.is_ge: self.get_handlers() canvas = iface.mapCanvas() crs_src = canvas.mapSettings().destinationCrs() # PL1992 crs_dest = QgsCoordinateReferenceSystem(4326) # WGS84 xform = QgsCoordinateTransform(crs_src, crs_dest, QgsProject.instance()) # Transformacja między układami if not self.extent or not back or player: # print("extent changed") self.loaded = False self.extent = iface.mapCanvas().extent() # Współrzędne rogów widoku mapy: x1 = self.extent.xMinimum() x2 = self.extent.xMaximum() y1 = self.extent.yMinimum() y2 = self.extent.yMaximum() # Wyznaczenie punktu centralnego: x = (x1 + x2) / 2 y = (y1 + y2) / 2 proj = QgsPointXY(x, y) # Punkt centralny w PL1992 # Transformacja punktu centralnego do WGS84: geo = xform.transform(QgsPointXY(proj.x(), proj.y())) # Współrzędne geograficzne punktu centralnego: lon = geo.x() lat = geo.y() # Ustalenie kąta obrotu mapy w GE: rot = -3.85 + (lon-14.11677234)*7.85/10.02872526 # Ustalenie wysokości kamery w GE: rng = canvas.scale() * (canvas.width()/100) * (0.022875 / self.screen_scale) TEMP_PATH = tempfile.gettempdir() # Ścieżka do folderu TEMP # Utworzenie pliku kml: kml = codecs.open(TEMP_PATH + '/moek.kml', 'w', encoding='utf-8') kml.write('<?xml version="1.0" encoding="UTF-8"?>\n') kml.write('<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">\n') kml.write(' <Document>\n') kml.write(' <LookAt>\n') k_txt = f' <longitude>{lon}</longitude>\n' kml.write(k_txt) k_txt = f' <latitude>{lat}</latitude>\n' kml.write(k_txt) kml.write(' <altitude>0</altitude>\n') k_txt = f' <heading>{rot}</heading>\n' kml.write(k_txt) kml.write(' <tilt>0</tilt>\n') k_txt = f' <range>{rng}</range>\n' kml.write(k_txt) kml.write(' <gx:altitudeMode>relativeToGround</gx:altitudeMode>\n') kml.write(' </LookAt>\n') kml.write(' </Document>\n') kml.write('</kml>\n') kml.close() # Włączenie dla QGIS'a funkcji always on top: if back and self.is_ge: # print(f"qgis on top: True") try: win32gui.SetWindowPos(self.q_hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_SHOWWINDOW) except: print(f"q_hwnd ({self.q_hwnd}) exception!") pass # Odpalenie pliku w Google Earth Pro: os.startfile(TEMP_PATH + '/moek.kml') if back and self.is_ge: QTimer.singleShot(1000, self.on_top_off)
def moveVertex(self, result): marker = result[1] snappingResult = result[0] QMessageBox.critical(self.iface.mainWindow(), "Move vertex error", "Move vertex error", QMessageBox.Ok) # The vertex that is found by the tool: vertexCoords = snappingResult.point( ) # vertexCoord are given in crs of the project vertexNr = snappingResult.vertexIndex() featureId = snappingResult.featureId() layer = snappingResult.layer() try: layerSrs = layer.srs() # find out the srs of the layer except AttributeError: # API version >1.8 layerSrs = layer.crs() # find out the srs of the layer # Give a dialog with the current coords and ask for the new ones (input, ok) = QInputDialog.getText( self.iface.mainWindow(), "Move Vertex Feature", "Enter New Coordinates as 'xcoord, ycoord'", QLineEdit.Normal, str(vertexCoords.x()) + "," + str(vertexCoords.y())) if not ok: # If we are aborting, we have to delete the marker self.canvas.scene().removeItem(marker) del marker return 0 # Find out which is the current crs of the project projectSrsEntry = QgsProject.instance().readEntry( "SpatialRefSys", "/ProjectCRSProj4String") projectSrs = QgsCoordinateReferenceSystem() projectSrs.createFromProj4(projectSrsEntry[0]) # Set up a coordinate transformation to transform the vertex coord into the srs of his layer transformer = QgsCoordinateTransform(projectSrs, layerSrs, QgsProject.instance()) # transformedPoint = transformer.transform(input.split(",")[0].toDouble()[0], # input.split(",")[1].toDouble()[0]) transformedPoint = transformer.transform(float(input.split(",")[0]), float(input.split(",")[1])) # If the transformation is successful, we move the vertex to his new place # else we inform the user that there is something wrong if (type(transformedPoint.x()).__name__ == 'double' and type(transformedPoint.y()).__name__ == 'double') or\ (type(transformedPoint.x()).__name__ == 'float' and type(transformedPoint.y()).__name__ == 'float'): # If the undo/redo stack is available, we use it if self.undoAvailable: layer.beginEditCommand("Moved Vertex") # Now we move the vertex to the given coordinates layer.moveVertex(transformedPoint.x(), transformedPoint.y(), featureId, vertexNr) # end of undo/redo stack (if available) if self.undoAvailable: layer.endEditCommand() else: QMessageBox.critical( self.iface.mainWindow(), "Error while transforming the vertex", "It's not possible to transform the coordinates you gave into the srs of this layer." ) # Now refresh the map canvas self.canvas.refresh() # At last we have to delete the marker self.canvas.scene().removeItem(marker) del marker
def qgis_composer_renderer(impact_report, component): """Default Map Report Renderer using QGIS Composer. Render using qgis composer for a given impact_report data and component context. :param impact_report: ImpactReport contains data about the report that is going to be generated. :type impact_report: safe.report.impact_report.ImpactReport :param component: Contains the component metadata and context for rendering the output. :type component: safe.report.report_metadata.QgisComposerComponentsMetadata :return: Whatever type of output the component should be. .. versionadded:: 4.0 """ context = component.context """:type: safe.report.extractors.composer.QGISComposerContext""" qgis_composition_context = impact_report.qgis_composition_context inasafe_context = impact_report.inasafe_context # load composition object composition = QgsComposition(qgis_composition_context.map_settings) # load template main_template_folder = impact_report.metadata.template_folder # we do this condition in case custom template was found if component.template.startswith('../qgis-composer-templates/'): template_path = os.path.join(main_template_folder, component.template) else: template_path = component.template with open(template_path) as template_file: template_content = template_file.read() document = QtXml.QDomDocument() document.setContent(template_content) load_status = composition.loadFromTemplate(document, context.substitution_map) if not load_status: raise TemplateLoadingError( tr('Error loading template: %s') % template_path) # replace image path for img in context.image_elements: item_id = img.get('id') path = img.get('path') image = composition_item(composition, item_id, QgsComposerPicture) """:type: qgis.core.QgsComposerPicture""" if image and path: image.setPicturePath(path) # replace html frame for html_el in context.html_frame_elements: item_id = html_el.get('id') mode = html_el.get('mode') composer_item = composition.getComposerItemById(item_id) try: html_element = composition.getComposerHtmlByItem(composer_item) except: pass """:type: qgis.core.QgsComposerHtml""" if html_element: if mode == 'text': text = html_el.get('text') text = text if text else '' html_element.setContentMode(QgsComposerHtml.ManualHtml) html_element.setHtml(text) html_element.loadHtml() elif mode == 'url': url = html_el.get('url') html_element.setContentMode(QgsComposerHtml.Url) qurl = QUrl.fromLocalFile(url) html_element.setUrl(qurl) original_crs = impact_report.impact_function.impact.crs() destination_crs = qgis_composition_context.map_settings.destinationCrs() coord_transform = QgsCoordinateTransform(original_crs, destination_crs) # resize map extent for map_el in context.map_elements: item_id = map_el.get('id') split_count = map_el.get('grid_split_count') layers = map_el.get('layers') map_extent_option = map_el.get('extent') composer_map = composition_item(composition, item_id, QgsComposerMap) """:type: qgis.core.QgsComposerMap""" if composer_map: composer_map.setKeepLayerSet(True) layer_set = [l.id() for l in layers if isinstance(l, QgsMapLayer)] composer_map.setLayerSet(layer_set) if map_extent_option and isinstance(map_extent_option, QgsRectangle): # use provided map extent extent = coord_transform.transform(map_extent_option) for l in [ layer for layer in layers if isinstance(layer, QgsMapLayer) ]: layer_extent = coord_transform.transform(l.extent()) if l.name() == map_overview['id']: map_overview_extent = layer_extent else: # if map extent not provided, try to calculate extent # from list of given layers. Combine it so all layers were # shown properly map_overview_extent = None extent = QgsRectangle() extent.setMinimal() for l in layers: # combine extent if different layer is provided. layer_extent = coord_transform.transform(l.extent()) extent.combineExtentWith(layer_extent) if l.name() == map_overview['id']: map_overview_extent = layer_extent width = extent.width() height = extent.height() longest_width = width if width > height else height half_length = longest_width / 2 margin = half_length / 5 center = extent.center() min_x = center.x() - half_length - margin max_x = center.x() + half_length + margin min_y = center.y() - half_length - margin max_y = center.y() + half_length + margin # noinspection PyCallingNonCallable square_extent = QgsRectangle(min_x, min_y, max_x, max_y) if component.key == 'population-infographic' and ( map_overview_extent): square_extent = map_overview_extent composer_map.zoomToExtent(square_extent) composer_map.renderModeUpdateCachedImage() actual_extent = composer_map.extent() # calculate intervals for grid x_interval = actual_extent.width() / split_count composer_map.grid().setIntervalX(x_interval) y_interval = actual_extent.height() / split_count composer_map.grid().setIntervalY(y_interval) # calculate legend element for leg_el in context.map_legends: item_id = leg_el.get('id') title = leg_el.get('title') layers = leg_el.get('layers') symbol_count = leg_el.get('symbol_count') column_count = leg_el.get('column_count') legend = composition_item(composition, item_id, QgsComposerLegend) """:type: qgis.core.QgsComposerLegend""" if legend: # set column count if column_count: legend.setColumnCount(column_count) elif symbol_count <= 7: legend.setColumnCount(1) else: legend.setColumnCount(symbol_count / 7 + 1) # set legend title if title is not None: legend.setTitle(title) # set legend root_group = legend.modelV2().rootGroup() for l in layers: # used for customizations tree_layer = root_group.addLayer(l) QgsLegendRenderer.setNodeLegendStyle( tree_layer, QgsComposerLegendStyle.Hidden) legend.synchronizeWithModel() # process to output # in case output folder not specified if impact_report.output_folder is None: impact_report.output_folder = mkdtemp(dir=temp_dir()) output_format = component.output_format component_output_path = impact_report.component_absolute_output_path( component.key) component_output = None doc_format = QgisComposerComponentsMetadata.OutputFormat.DOC_OUTPUT template_format = QgisComposerComponentsMetadata.OutputFormat.QPT if isinstance(output_format, list): component_output = [] for i in range(len(output_format)): each_format = output_format[i] each_path = component_output_path[i] if each_format in doc_format: result_path = create_qgis_pdf_output(impact_report, each_path, composition, each_format, component) component_output.append(result_path) elif each_format == template_format: result_path = create_qgis_template_output( each_path, composition) component_output.append(result_path) elif isinstance(output_format, dict): component_output = {} for key, each_format in output_format.iteritems(): each_path = component_output_path[key] if each_format in doc_format: result_path = create_qgis_pdf_output(impact_report, each_path, composition, each_format, component) component_output[key] = result_path elif each_format == template_format: result_path = create_qgis_template_output( each_path, composition) component_output[key] = result_path elif (output_format in QgisComposerComponentsMetadata.OutputFormat.SUPPORTED_OUTPUT): component_output = None if output_format in doc_format: result_path = create_qgis_pdf_output(impact_report, component_output_path, composition, output_format, component) component_output = result_path elif output_format == template_format: result_path = create_qgis_template_output(component_output_path, composition) component_output = result_path component.output = component_output return component.output
processing.run("qgis:serviceareafromlayer", params) if (sys.argv[3] == "fromPoint"): # Change projection from EPSG:4326 -> EPSG:3857 crsSrc = QgsCoordinateReferenceSystem("EPSG:4326") crsDest = QgsCoordinateReferenceSystem("EPSG:3857") transformContext = QgsProject.instance().transformContext() xform = QgsCoordinateTransform(crsSrc, crsDest, transformContext) # forward transformation: src -> dest intl = (sys.argv[2]).split(",") numX = float(intl[0]) numY = float(intl[1]) pt1 = xform.transform(QgsPointXY(numX, numY)) #longitude, lattitude params2 = { 'DEFAULT_DIRECTION': 2, 'DEFAULT_SPEED': 50, 'DIRECTION_FIELD': '', 'INCLUDE_BOUNDS': False, 'INPUT': '/usr/share/geoserver/data_dir/data/service_area/Road_Network.shp', 'OUTPUT_LINES': '/usr/share/geoserver/data_dir/data/service_area/Service_Area_Map.shp', 'SPEED_FIELD': '', 'START_POINT': str(pt1[0]) + ',' + str(pt1[1]) + ' [EPSG:3857]', 'STRATEGY': 0, 'TOLERANCE': 0, 'TRAVEL_COST2': sys.argv[1],
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.PrmInputLayer, context) shapetype = self.parameterAsInt(parameters, self.PrmShapeType, context) cuspscol = self.parameterAsString(parameters, self.PrmCuspsField, context) startanglecol = self.parameterAsString(parameters, self.PrmStartingAngleField, context) radiuscol = self.parameterAsString(parameters, self.PrmRadiusField, context) radius = self.parameterAsDouble(parameters, self.PrmRadius, context) startAngle = self.parameterAsDouble(parameters, self.PrmStartingAngle, context) cusps = self.parameterAsInt(parameters, self.PrmCusps, context) segments = self.parameterAsInt(parameters, self.PrmDrawingSegments, context) units = self.parameterAsInt(parameters, self.PrmUnitsOfMeasure, context) export_geom = self.parameterAsBool(parameters, self.PrmExportInputGeometry, context) measureFactor = conversionToMeters(units) radius *= measureFactor srcCRS = source.sourceCrs() fields = source.fields() if export_geom: names = fields.names() name_x, name_y = settings.getGeomNames(names) fields.append(QgsField(name_x, QVariant.Double)) fields.append(QgsField(name_y, QVariant.Double)) if shapetype == 0: (sink, dest_id) = self.parameterAsSink(parameters, self.PrmOutputLayer, context, fields, QgsWkbTypes.Polygon, srcCRS) else: (sink, dest_id) = self.parameterAsSink(parameters, self.PrmOutputLayer, context, fields, QgsWkbTypes.LineString, srcCRS) if srcCRS != epsg4326: geomTo4326 = QgsCoordinateTransform(srcCRS, epsg4326, QgsProject.instance()) toSinkCrs = QgsCoordinateTransform(epsg4326, srcCRS, QgsProject.instance()) featureCount = source.featureCount() total = 100.0 / featureCount if featureCount else 0 step = 360.0 / segments numbad = 0 iterator = source.getFeatures() for index, feature in enumerate(iterator): if feedback.isCanceled(): break try: if startanglecol: sangle = float(feature[startanglecol]) else: sangle = startAngle if cuspscol: cusps2 = int(feature[cuspscol]) else: cusps2 = cusps if radiuscol: radius2 = float(feature[radiuscol]) * measureFactor else: radius2 = radius r = radius2 / cusps2 except: numbad += 1 continue pts = [] pt = feature.geometry().asPoint() pt_orig_x = pt.x() pt_orig_y = pt.y() # make sure the coordinates are in EPSG:4326 if srcCRS != epsg4326: pt = geomTo4326.transform(pt.x(), pt.y()) angle = 0.0 while angle <= 360.0: a = math.radians(angle) x = r * (cusps2 - 1.0) * math.cos(a) + r * math.cos( (cusps2 - 1.0) * a) y = r * (cusps2 - 1.0) * math.sin(a) - r * math.sin( (cusps2 - 1.0) * a) a2 = math.degrees(math.atan2(y, x)) + sangle dist = math.sqrt(x * x + y * y) g = geod.Direct(pt.y(), pt.x(), a2, dist, Geodesic.LATITUDE | Geodesic.LONGITUDE) pts.append(QgsPointXY(g['lon2'], g['lat2'])) angle += step # If the Output crs is not 4326 transform the points to the proper crs if srcCRS != epsg4326: for x, ptout in enumerate(pts): pts[x] = toSinkCrs.transform(ptout) f = QgsFeature() if shapetype == 0: f.setGeometry(QgsGeometry.fromPolygonXY([pts])) else: f.setGeometry(QgsGeometry.fromPolylineXY(pts)) attr = feature.attributes() if export_geom: attr.append(pt_orig_x) attr.append(pt_orig_y) f.setAttributes(attr) sink.addFeature(f) if index % 100 == 0: feedback.setProgress(int(index * total)) if numbad > 0: feedback.pushInfo( tr("{} out of {} features had invalid parameters and were ignored." .format(numbad, featureCount))) return {self.PrmOutputLayer: dest_id}
def addPoint(self): text = self.lineEdit.text().strip() if text == "": return try: if (self.inputProjection == 0) or (text[0] == '{'): # If this is GeoJson it does not matter what inputProjection is if text[0] == '{': # This may be a GeoJSON point codec = QTextCodec.codecForName("UTF-8") fields = QgsJsonUtils.stringToFields(text, codec) fet = QgsJsonUtils.stringToFeatureList(text, fields, codec) if (len(fet) == 0) or not fet[0].isValid(): raise ValueError('Invalid Coordinates') geom = fet[0].geometry() if geom.isEmpty() or (geom.wkbType() != QgsWkbTypes.Point): raise ValueError('Invalid GeoJSON Geometry') pt = geom.asPoint() lat = pt.y() lon = pt.x() elif re.search(r'POINT\(', text) is not None: m = re.findall( r'POINT\(\s*([+-]?\d*\.?\d*)\s+([+-]?\d*\.?\d*)', text) if len(m) != 1: raise ValueError('Invalid Coordinates') lon = float(m[0][0]) lat = float(m[0][1]) else: lat, lon = parseDMSString(text, self.inputXYOrder) srcCrs = epsg4326 else: # Is either the project or custom CRS if re.search(r'POINT\(', text) is None: coords = re.split(r'[\s,;:]+', text, 1) if len(coords) < 2: raise ValueError('Invalid Coordinates') if self.inputXYOrder == 0: # Y, X Order lat = float(coords[0]) lon = float(coords[1]) else: lon = float(coords[0]) lat = float(coords[1]) else: m = re.findall( r'POINT\(\s*([+-]?\d*\.?\d*)\s+([+-]?\d*\.?\d*)', text) if len(m) != 1: raise ValueError('Invalid Coordinates') lon = float(m[0][0]) lat = float(m[0][1]) if self.inputProjection == 1: # Project CRS srcCrs = self.canvas.mapSettings().destinationCrs() else: srcCrs = QgsCoordinateReferenceSystem(self.inputCustomCRS) except Exception: # traceback.print_exc() self.iface.messageBar().pushMessage("", "Invalid Coordinate", level=Qgis.Warning, duration=2) return self.lineEdit.clear() if srcCrs != epsg4326: transform = QgsCoordinateTransform(srcCrs, epsg4326, QgsProject.instance()) # Transform the input coordinate projection to the layer CRS lon, lat = transform.transform(float(lon), float(lat)) pt = QgsPointXY(lon, lat) self.measureDialog.addPoint(pt, 1)
def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = QuickApiDialog() self.dlg.crs_input.setCrs( QgsCoordinateReferenceSystem('EPSG:4326')) project = QgsProject.instance() # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # First get all the values of the GUI items crs_input = self.dlg.crs_input.crs() crs_out = QgsCoordinateReferenceSystem( 'EPSG:4326') # we need this to be WGS84 for Nominatim lineedit_text = self.dlg.lineedit_xy.value() # Protect the free text field for coordinates from generic user failure try: lineedit_yx = [ float(coord.strip()) for coord in lineedit_text.split(',') ] except: QMessageBox.critical( self.iface.mainWindow(), 'QuickAPI error', "Did you really specify a coordinate in comma-separated Lat/Long?\nExiting..." ) return # Create a Point and transform if necessary point = QgsPointXY(*reversed(lineedit_yx)) if crs_input.authid() != 'EPSG:4326': xform = QgsCoordinateTransform(crs_input, crs_out, project) point_transform = xform.transform(point) point = point_transform # Set up the GET Request to Nominatim query = QUrlQuery() query.addQueryItem('lat', str(point.y())) query.addQueryItem('lon', str(point.x())) query.addQueryItem('format', 'json') url = QUrl('https://nominatim.openstreetmap.org/reverse') url.setQuery(query) request = QNetworkRequest(url) request.setHeader(QNetworkRequest.UserAgentHeader, '*****@*****.**') nam = QgsNetworkAccessManager() response: QgsNetworkReplyContent = nam.blockingGet(request) # Only process if HTTP status code is 200 status_code = response.attribute( QNetworkRequest.HttpStatusCodeAttribute) if status_code == 200: # Get the content of the response and process it response_json = json.loads(bytes(response.content())) if response_json.get('error'): QMessageBox.critical( self.iface.mainWindow(), "Quick API error", "The request was not processed succesfully!\n\n" "Message:\n" "{}".format(response_json['error'])) return x = float(response_json['lon']) y = float(response_json['lat']) address = response_json['display_name'] license = response_json['licence'] # Create the output memory layer layer_out = QgsVectorLayer( "Point?crs=EPSG:4326&field=address:string&field=license:string", "Nominatim Reverse Geocoding", "memory") # Create the output feature (only one here) point_out = QgsPointXY(x, y) feature = QgsFeature() feature.setGeometry(QgsGeometry.fromPointXY(point_out)) feature.setAttributes([address, license]) # Add feature to layer and layer to map layer_out.dataProvider().addFeature(feature) layer_out.updateExtents() project.addMapLayer(layer_out) # build bbox for auto-zoom feature bbox = [float(coord) for coord in response_json['boundingbox']] min_y, max_y, min_x, max_x = bbox bbox_geom = QgsGeometry.fromRect( QgsRectangle(min_x, min_y, max_x, max_y)) # Transform bbox if map canvas has a different CRS if project.crs().authid() != 'EPSG:4326': xform = QgsCoordinateTransform(crs_out, project.crs(), project) bbox_geom.transform(xform) self.iface.mapCanvas().zoomToFeatureExtent( QgsRectangle.fromWkt(bbox_geom.asWkt()))
def addSingleCoord(self): '''Add a coordinate from the coordinate text box.''' parts = [x.strip() for x in self.addLineEdit.text().split(',')] label = '' data = [] numFields = len(parts) try: if self.settings.multiZoomToProjIsMGRS(): '''Check to see if we have an MGRS coordinate for entry''' lat, lon = mgrs.toWgs(re.sub(r'\s+', '', parts[0])) if numFields >= 2: label = parts[1] if numFields >= 3: data = parts[2:] elif self.settings.multiZoomToProjIsPlusCodes(): coord = olc.decode(parts[0]) lat = coord.latitudeCenter lon = coord.longitudeCenter if numFields >= 2: label = parts[1] if numFields >= 3: data = parts[2:] elif numFields == 1: '''Perhaps the user forgot to add the comma separator. Check to see if there are two coordinates anyway.''' if self.settings.multiZoomToProjIsWgs84(): lat, lon = LatLon.parseDMSString(parts[0], self.settings.multiCoordOrder) else: parts = re.split(r'[\s;:]+', parts[0], 1) if len(parts) < 2: self.iface.messageBar().pushMessage("", "Invalid Coordinate.", level=Qgis.Warning, duration=3) return srcCrs = self.settings.multiZoomToCRS() transform = QgsCoordinateTransform(srcCrs, epsg4326, QgsProject.instance()) if self.settings.multiCoordOrder == self.settings.OrderYX: lon, lat = transform.transform(float(parts[1]), float(parts[0])) else: lon, lat = transform.transform(float(parts[0]), float(parts[1])) elif numFields >= 2: if self.settings.multiZoomToProjIsWgs84(): '''Combine the coordinates back together and use parseDMSString as it is more robust than parseDMSStringSingle.''' str = "{}, {}".format(parts[0], parts[1]) lat, lon = LatLon.parseDMSString(str, self.settings.multiCoordOrder) else: srcCrs = self.settings.multiZoomToCRS() transform = QgsCoordinateTransform(srcCrs, epsg4326, QgsProject.instance()) if self.settings.multiCoordOrder == self.settings.OrderYX: lon, lat = transform.transform(float(parts[1]), float(parts[0])) else: lon, lat = transform.transform(float(parts[0]), float(parts[1])) if numFields >= 3: label = parts[2] if numFields >= 4: data = parts[3:] else: self.iface.messageBar().pushMessage("", "Invalid Coordinate.", level=Qgis.Warning, duration=3) return except Exception: if self.addLineEdit.text(): self.iface.messageBar().pushMessage("", "Invalid Coordinate. Perhaps comma separators between fields were not used.", level=Qgis.Warning, duration=3) return newrow = self.addCoord(lat, lon, label, data) self.addLineEdit.clear() self.resultsTable.selectRow(newrow) self.itemClicked(newrow, 0)
def run(self): """Experimental impact function.""" # Get parameters from layer's keywords self.hazard_class_attribute = self.hazard.keyword('field') self.hazard_class_mapping = self.hazard.keyword('value_map') # There is no wet in the class mapping if self.wet not in self.hazard_class_mapping: raise ZeroImpactException(tr( 'There is no flooded area in the hazard layers, thus there ' 'is no affected building.')) self.exposure_class_attribute = self.exposure.keyword( 'structure_class_field') exposure_value_mapping = self.exposure.keyword('value_mapping') # Prepare Hazard Layer hazard_provider = self.hazard.layer.dataProvider() # Check affected field exists in the hazard layer affected_field_index = hazard_provider.fieldNameIndex( self.hazard_class_attribute) if affected_field_index == -1: message = tr( 'Field "%s" is not present in the attribute table of the ' 'hazard layer. Please change the Affected Field parameter in ' 'the IF Option.') % self.hazard_class_attribute raise GetDataError(message) srs = self.exposure.layer.crs().toWkt() exposure_provider = self.exposure.layer.dataProvider() exposure_fields = exposure_provider.fields() # Check self.exposure_class_attribute exists in exposure layer building_type_field_index = exposure_provider.fieldNameIndex( self.exposure_class_attribute) if building_type_field_index == -1: message = tr( 'Field "%s" is not present in the attribute table of ' 'the exposure layer. Please change the Building Type ' 'Field parameter in the IF Option.' ) % self.exposure_class_attribute raise GetDataError(message) # If target_field does not exist, add it: if exposure_fields.indexFromName(self.target_field) == -1: exposure_provider.addAttributes( [QgsField(self.target_field, QVariant.Int)]) target_field_index = exposure_provider.fieldNameIndex( self.target_field) exposure_fields = exposure_provider.fields() # Create layer to store the buildings from E and extent buildings_are_points = is_point_layer(self.exposure.layer) if buildings_are_points: building_layer = QgsVectorLayer( 'Point?crs=' + srs, 'impact_buildings', 'memory') else: building_layer = QgsVectorLayer( 'Polygon?crs=' + srs, 'impact_buildings', 'memory') building_provider = building_layer.dataProvider() # Set attributes building_provider.addAttributes(exposure_fields.toList()) building_layer.startEditing() building_layer.commitChanges() # Filter geometry and data using the requested extent requested_extent = QgsRectangle(*self.requested_extent) # This is a hack - we should be setting the extent CRS # in the IF base class via safe/engine/core.py:calculate_impact # for now we assume the extent is in 4326 because it # is set to that from geo_extent # See issue #1857 transform = QgsCoordinateTransform( self.requested_extent_crs, self.hazard.crs()) projected_extent = transform.transformBoundingBox(requested_extent) request = QgsFeatureRequest() request.setFilterRect(projected_extent) # Split building_layer by H and save as result: # 1) Filter from H inundated features # 2) Mark buildings as inundated (1) or not inundated (0) # make spatial index of affected polygons hazard_index = QgsSpatialIndex() hazard_geometries = {} # key = feature id, value = geometry has_hazard_objects = False for feature in self.hazard.layer.getFeatures(request): value = feature[affected_field_index] if value not in self.hazard_class_mapping[self.wet]: continue hazard_index.insertFeature(feature) hazard_geometries[feature.id()] = QgsGeometry(feature.geometry()) has_hazard_objects = True if not has_hazard_objects: message = tr( 'There are no objects in the hazard layer with %s ' 'value in %s. Please check your data or use another ' 'attribute.') % ( self.hazard_class_attribute, ', '.join(self.hazard_class_mapping[self.wet])) raise GetDataError(message) # Filter out just those EXPOSURE features in the analysis extents transform = QgsCoordinateTransform( self.requested_extent_crs, self.exposure.layer.crs()) projected_extent = transform.transformBoundingBox(requested_extent) request = QgsFeatureRequest() request.setFilterRect(projected_extent) # We will use this transform to project each exposure feature into # the CRS of the Hazard. transform = QgsCoordinateTransform( self.exposure.crs(), self.hazard.crs()) features = [] for feature in self.exposure.layer.getFeatures(request): # Make a deep copy as the geometry is passed by reference # If we don't do this, subsequent operations will affect the # original feature geometry as well as the copy TS building_geom = QgsGeometry(feature.geometry()) # Project the building geometry to hazard CRS building_bounds = transform.transform(building_geom.boundingBox()) affected = False # get tentative list of intersecting hazard features # only based on intersection of bounding boxes ids = hazard_index.intersects(building_bounds) for fid in ids: # run (slow) exact intersection test building_geom.transform(transform) if hazard_geometries[fid].intersects(building_geom): affected = True break new_feature = QgsFeature() # We write out the original feature geom, not the projected one new_feature.setGeometry(feature.geometry()) new_feature.setAttributes(feature.attributes()) new_feature[target_field_index] = 1 if affected else 0 features.append(new_feature) # every once in a while commit the created features # to the output layer if len(features) == 1000: (_, __) = building_provider.addFeatures(features) features = [] (_, __) = building_provider.addFeatures(features) building_layer.updateExtents() # Generate simple impact report hazard_classes = [tr('Flooded')] self.init_report_var(hazard_classes) buildings_data = building_layer.getFeatures() building_type_field_index = building_layer.fieldNameIndex( self.exposure_class_attribute) for building in buildings_data: record = building.attributes() usage = record[building_type_field_index] usage = main_type(usage, exposure_value_mapping) affected = False if record[target_field_index] == 1: affected = True self.classify_feature(hazard_classes[0], usage, affected) self.reorder_dictionaries() 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=self.target_field, style_classes=style_classes, style_type='categorizedSymbol') # Convert QgsVectorLayer to inasafe layer and return it. if building_layer.featureCount() < 1: raise ZeroImpactException(tr( 'No buildings were impacted by this flood.')) impact_data = self.generate_data() extra_keywords = { 'map_title': self.map_title(), 'legend_title': self.metadata().key('legend_title'), 'target_field': self.target_field, 'buildings_total': self.total_buildings, 'buildings_affected': self.total_affected_buildings } impact_layer_keywords = self.generate_impact_keywords(extra_keywords) impact_layer = Vector( data=building_layer, name=self.map_title(), keywords=impact_layer_keywords, style_info=style_info) impact_layer.impact_data = impact_data self._impact = impact_layer return impact_layer
def canvasPointXY(self, lat, lon): canvasCrs = self.canvas.mapSettings().destinationCrs() transform = QgsCoordinateTransform(epsg4326, canvasCrs, QgsProject.instance()) x, y = transform.transform(float(lon), float(lat)) pt = QgsPointXY(x, y) return pt