def test_ExpressionFieldEllipsoidAreaCalculation(self): #create a temporary layer temp_layer = QgsVectorLayer("Polygon?crs=epsg:3111&field=pk:int", "vl", "memory") self.assertTrue(temp_layer.isValid()) f1 = QgsFeature(temp_layer.dataProvider().fields(), 1) f1.setAttribute("pk", 1) f1.setGeometry(QgsGeometry.fromPolygon([[QgsPoint(2484588, 2425722), QgsPoint(2482767, 2398853), QgsPoint(2520109, 2397715), QgsPoint(2520792, 2425494), QgsPoint(2484588, 2425722)]])) temp_layer.dataProvider().addFeatures([f1]) # set project CRS and ellipsoid srs = QgsCoordinateReferenceSystem(3111, QgsCoordinateReferenceSystem.EpsgCrsId) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSID", srs.srsid()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCrs", srs.authid()) QgsProject.instance().writeEntry("Measure", "/Ellipsoid", "WGS84") QgsProject.instance().writeEntry("Measurement", "/AreaUnits", QgsUnitTypes.encodeUnit(QgsUnitTypes.SquareMeters)) idx = temp_layer.addExpressionField('$area', QgsField('area', QVariant.Double)) # NOQA # check value f = temp_layer.getFeatures().next() expected = 1009089817.0 self.assertAlmostEqual(f['area'], expected, delta=1.0) # change project area unit, check calculation respects unit QgsProject.instance().writeEntry("Measurement", "/AreaUnits", QgsUnitTypes.encodeUnit(QgsUnitTypes.SquareMiles)) f = temp_layer.getFeatures().next() expected = 389.6117565069 self.assertAlmostEqual(f['area'], expected, 3)
def processCommand(alg): # Creates a new location with the CRS crsParam = alg.getParameterFromName('crs') crsId = int(crsParam.value[5:]) #QgsMessageLog.logMessage('crs = {}'.format(crs), 'DEBUG', QgsMessageLog.INFO) crs = QgsCoordinateReferenceSystem() crs.createFromId(crsId, QgsCoordinateReferenceSystem.EpsgCrsId) command = "g.proj proj4=\"{}\" location=TARGET".format(crs.toProj4()) alg.commands.append(command) alg.parameters.remove(crsParam) # Regroup rasters rasters = alg.getParameterFromName('rasters') rastersList = rasters.value.split(';') alg.parameters.remove(rasters) # Insert a i.group command group = getParameterFromString("ParameterString|group|group of rasters|None|False|False") group.value = alg.getTempFilename() alg.addParameter(group) command = 'i.group group={} input={}'.format( group.value, ','.join([alg.exportedLayers[f] for f in rastersList]) ) alg.commands.append(command) # Handle POINT File gcp = alg.getParameterFromName('gcp') extFileName = gcp.value destPath = path.join(Grass7Utils.grassMapsetFolder(), 'PERMANENT', 'group', group.value, 'POINTS') copyFile(alg, extFileName, destPath) alg.parameters.remove(gcp) # Add a target destination for our group command = "i.target group={} location=TARGET mapset=PERMANENT".format(group.value) alg.commands.append(command) # remove output output = alg.getOutputFromName('output') alg.removeOutputFromName('output') # Add an extension #extension = getParameterFromString("ParameterString|extension|Output raster map(s) suffix|None|False|False") #extension.value = "rectified" #alg.addParameter(extension) # modify parameters values alg.processCommand() # Re-add input rasters alg.addParameter(rasters) alg.addParameter(gcp) alg.addParameter(crs) # Re-add output alg.addOutput(output)
def __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 test_ExpressionFieldEllipsoidLengthCalculation(self): #create a temporary layer temp_layer = QgsVectorLayer("LineString?crs=epsg:3111&field=pk:int", "vl", "memory") self.assertTrue(temp_layer.isValid()) f1 = QgsFeature(temp_layer.dataProvider().fields(), 1) f1.setAttribute("pk", 1) f1.setGeometry(QgsGeometry.fromPolyline([QgsPoint(2484588, 2425722), QgsPoint(2482767, 2398853)])) temp_layer.dataProvider().addFeatures([f1]) # set project CRS and ellipsoid srs = QgsCoordinateReferenceSystem(3111, QgsCoordinateReferenceSystem.EpsgCrsId) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSID", srs.srsid()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCrs", srs.authid()) QgsProject.instance().writeEntry("Measure", "/Ellipsoid", "WGS84") QgsProject.instance().writeEntry("Measurement", "/DistanceUnits", QgsUnitTypes.encodeUnit(QGis.Meters)) idx = temp_layer.addExpressionField('$length', QgsField('length', QVariant.Double)) # NOQA # check value f = next(temp_layer.getFeatures()) expected = 26932.156 self.assertAlmostEqual(f['length'], expected, 3) # change project length unit, check calculation respects unit QgsProject.instance().writeEntry("Measurement", "/DistanceUnits", QgsUnitTypes.encodeUnit(QGis.Feet)) f = next(temp_layer.getFeatures()) expected = 88360.0918635 self.assertAlmostEqual(f['length'], expected, 3)
def set_domain_to_extent(self, crs: QgsCoordinateReferenceSystem, extent: QgsRectangle) -> None: resolution = self.resolution.value() bbox = rect_to_bbox(extent) extent_crs = CRS(crs.toProj4()) domain_crs = self.create_domain_crs() domain_srs = domain_crs.srs domain_bbox = domain_crs.transform_bbox(bbox, domain_srs) # TODO disallow creation of bounding box outside projection range (e.g. for lat-lon 360-180) xmin, xmax, ymin, ymax = domain_bbox.minx, domain_bbox.maxx, domain_bbox.miny, domain_bbox.maxy center_x = xmin + (xmax - xmin) / 2 center_y = ymin + (ymax - ymin) / 2 center_lonlat = domain_crs.to_lonlat(Coordinate2D(center_x, center_y)) self.center_lat.set_value(center_lonlat.lat) self.center_lon.set_value(center_lonlat.lon) self.resolution.set_value(resolution) cols = ceil((xmax - xmin) / resolution) rows = ceil((ymax - ymin) / resolution) self.cols.set_value(cols) self.rows.set_value(rows) self.on_change_any_field(zoom_out=True)
def test_ExpressionFieldEllipsoidAreaCalculation(self): #create a temporary layer temp_layer = QgsVectorLayer("Polygon?crs=epsg:3111&field=pk:int", "vl", "memory") self.assertTrue(temp_layer.isValid()) f1 = QgsFeature(temp_layer.dataProvider().fields(), 1) f1.setAttribute("pk", 1) f1.setGeometry(QgsGeometry.fromPolygon([[QgsPoint(2484588, 2425722), QgsPoint(2482767, 2398853), QgsPoint(2520109, 2397715), QgsPoint(2520792, 2425494), QgsPoint(2484588, 2425722)]])) temp_layer.dataProvider().addFeatures([f1]) # set project CRS and ellipsoid srs = QgsCoordinateReferenceSystem(3111, QgsCoordinateReferenceSystem.EpsgCrsId) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSID", srs.srsid()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCrs", srs.authid()) QgsProject.instance().writeEntry("Measure", "/Ellipsoid", "WGS84") QgsProject.instance().writeEntry("Measurement", "/AreaUnits", QgsUnitTypes.encodeUnit(QgsUnitTypes.SquareMeters)) idx = temp_layer.addExpressionField('$area', QgsField('area', QVariant.Double)) # NOQA # check value f = next(temp_layer.getFeatures()) expected = 1009089817.0 self.assertAlmostEqual(f['area'], expected, delta=1.0) # change project area unit, check calculation respects unit QgsProject.instance().writeEntry("Measurement", "/AreaUnits", QgsUnitTypes.encodeUnit(QgsUnitTypes.SquareMiles)) f = next(temp_layer.getFeatures()) expected = 389.6117565069 self.assertAlmostEqual(f['area'], expected, 3)
def processCommand(alg): # Creates a new location with the CRS crsParam = alg.getParameterFromName('crs') crsId = int(crsParam.value[5:]) # QgsMessageLog.logMessage('crs = {}'.format(crs), 'DEBUG', QgsMessageLog.INFO) crs = QgsCoordinateReferenceSystem() crs.createFromId(crsId, QgsCoordinateReferenceSystem.EpsgCrsId) command = "g.proj proj4=\"{}\" location=TARGET".format(crs.toProj4()) alg.commands.append(command) alg.parameters.remove(crsParam) # Regroup rasters rasters = alg.getParameterFromName('rasters') rastersList = rasters.value.split(';') alg.parameters.remove(rasters) # Insert a i.group command group = getParameterFromString("ParameterString|group|group of rasters|None|False|False") group.value = alg.getTempFilename() alg.addParameter(group) command = 'i.group group={} input={}'.format( group.value, ','.join([alg.exportedLayers[f] for f in rastersList]) ) alg.commands.append(command) # Handle POINT File gcp = alg.getParameterFromName('gcp') extFileName = gcp.value destPath = path.join(Grass7Utils.grassMapsetFolder(), 'PERMANENT', 'group', group.value, 'POINTS') copyFile(alg, extFileName, destPath) alg.parameters.remove(gcp) # Add a target destination for our group command = "i.target group={} location=TARGET mapset=PERMANENT".format(group.value) alg.commands.append(command) # remove output output = alg.getOutputFromName('output') alg.removeOutputFromName('output') # Add an extension #extension = getParameterFromString("ParameterString|extension|Output raster map(s) suffix|None|False|False") #extension.value = "rectified" #alg.addParameter(extension) # modify parameters values alg.processCommand() # Re-add input rasters alg.addParameter(rasters) alg.addParameter(gcp) alg.addParameter(crs) # Re-add output alg.addOutput(output)
def set_point(self, variable: str, point: QgsPointXY, crs: QgsCoordinateReferenceSystem) -> list: """ Produces R code that creates a variable from point input. :param variable: string. Name of the variable. :param point: QgsPointXY. Point to extract x and y coordinates from. :param crs: QgsCoordinateReferenceSystem. Coordinate reference system for the point. :return: string. R code that constructs the point. """ commands = [] if self.use_sf: commands.append('point_crs <- st_crs(\'{}\')'.format(crs.toWkt())) commands.append( '{0} <- st_sfc(st_point(c({1},{2})), crs = point_crs)'.format( variable, point.x(), point.y())) else: commands.append('xy_df <- cbind(c({}), c({}))'.format( point.x(), point.y())) commands.append('point_crs <- CRS(\'{}\')'.format(crs.toProj4())) commands.append( '{} <- SpatialPoints(xy_df, proj4string = point_crs)'.format( variable)) return commands
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 test_ExpressionFieldEllipsoidLengthCalculation(self): #create a temporary layer temp_layer = QgsVectorLayer("LineString?crs=epsg:3111&field=pk:int", "vl", "memory") self.assertTrue(temp_layer.isValid()) f1 = QgsFeature(temp_layer.dataProvider().fields(), 1) f1.setAttribute("pk", 1) f1.setGeometry(QgsGeometry.fromPolyline([QgsPoint(2484588, 2425722), QgsPoint(2482767, 2398853)])) temp_layer.dataProvider().addFeatures([f1]) # set project CRS and ellipsoid srs = QgsCoordinateReferenceSystem(3111, QgsCoordinateReferenceSystem.EpsgCrsId) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSID", srs.srsid()) QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCrs", srs.authid()) QgsProject.instance().writeEntry("Measure", "/Ellipsoid", "WGS84") QgsProject.instance().writeEntry("Measurement", "/DistanceUnits", QgsUnitTypes.encodeUnit(QGis.Meters)) idx = temp_layer.addExpressionField('$length', QgsField('length', QVariant.Double)) # NOQA # check value f = temp_layer.getFeatures().next() expected = 26932.156 self.assertAlmostEqual(f['length'], expected, 3) # change project length unit, check calculation respects unit QgsProject.instance().writeEntry("Measurement", "/DistanceUnits", QgsUnitTypes.encodeUnit(QGis.Feet)) f = temp_layer.getFeatures().next() expected = 88360.0918635 self.assertAlmostEqual(f['length'], expected, 3)
def gdal_crs_string(crs: QgsCoordinateReferenceSystem) -> str: """ Converts a QgsCoordinateReferenceSystem to a string understandable by GDAL :param crs: crs to convert :return: gdal friendly string """ if crs.authid().upper().startswith('EPSG:'): return crs.authid() # fallback to proj4 string return crs.toProj4()
def gdal_crs_string(crs: QgsCoordinateReferenceSystem) -> str: """ Converts a QgsCoordinateReferenceSystem to a string understandable by GDAL :param crs: crs to convert :return: gdal friendly string """ if crs.authid().upper().startswith('EPSG:'): return crs.authid() # fallback to proj4 string return crs.toProj4()
def browseCRS(self): selector = QgsGenericProjectionSelector() selector.setSelectedAuthId(self.crs) if selector.exec_(): authId = selector.selectedAuthId() if authId.upper().startswith("EPSG:"): self.crs = authId else: proj = QgsCoordinateReferenceSystem() proj.createFromSrsId(selector.selectedCrsId()) self.crs = proj.toProj4() self.updateText()
def browseCRS(self): selector = QgsGenericProjectionSelector() selector.setSelectedAuthId(self.crs) if selector.exec_(): authId = selector.selectedAuthId() if authId.upper().startswith("EPSG:"): self.crs = authId else: proj = QgsCoordinateReferenceSystem() proj.createFromSrsId(selector.selectedCrsId()) self.crs = proj.toProj4() self.updateText()
def post(self, request, **kwargs): # Check for content type accept only 'application/json' if request.content_type != 'application/json': return APIException( "Interface OWS accept only 'application/json request'") post_data = json.loads(request.body) # Required url = post_data.get('url') if not url: raise APIException("'url' parameter must be provided.") service = post_data.get('service') if not service: raise APIException("'service' parameter must be provided.") service = service.lower() if service not in self._service_available.keys(): raise APIException(f"Service '{service}' is not available.") # Not required: version = post_data.get('version', '1.3.0') ows = self._service_available[service](url, version=version) # Identification # ----------------------------------- self.results.results.update({ 'title': ows.identification.title, 'abstract': ows.identification.abstract }) # Map formats # ----------------------------------- self.results.results.update( {'map_formats': ows.getOperationByName('GetMap').formatOptions}) # Info formats # ----------------------------------- self.results.results.update({ 'info_formats': ows.getOperationByName('GetFeatureInfo').formatOptions }) # Layers # ----------------------------------- available_layers = list(ows.contents) # add styles for every layer layers = [] for al in available_layers: # Build crs crss = [] for srid in ows[al].crsOptions: crs = QgsCoordinateReferenceSystem(srid) if crs.postgisSrid() == 3003: proj4 = settings.PROJ4_EPSG_3003 else: proj4 = crs.toProj4() crss.append({ 'epsg': crs.postgisSrid(), 'proj4': proj4, 'geographic': crs.isGeographic(), 'axisinverted': crs.hasAxisInverted() }) layers.append({ 'name': al, 'title': ows[al].title, 'abstract': ows[al].abstract, 'crss': crss, 'styles': ows[al].styles, 'parent': ows[al].parent.id if ows[al].parent else None }) self.results.results.update({'layers': layers}) return Response(self.results.results)
def to_representation(self, instance): ret = super(LayerSerializer, self).to_representation(instance) qgs_maplayer = self.qgs_project.mapLayers()[instance.qgs_layer_id] # add attributes/fields ret['fields'] = self.get_attributes(instance) # add infoformat and infourl ret['infoformat'] = '' ret['infourl'] = '' #lidname = instance.qgs_layer_id if instance.project.wms_use_layer_ids else instance.name # add bbox if instance.geometrytype != QGIS_LAYER_TYPE_NO_GEOM: if instance.extent: ret['bbox'] = instance.extent_rect else: # get from QgsMapLayer instance extent = qgs_maplayer.extent() ret['bbox'] = {} ret['bbox']['minx'] = extent.xMinimum() ret['bbox']['miny'] = extent.yMinimum() ret['bbox']['maxx'] = extent.xMaximum() ret['bbox']['maxy'] = extent.yMaximum() # add capabilities ret['capabilities'] = get_capabilities4layer(qgs_maplayer) # add styles # FIXME: restore in the future for styles map management #ret['styles'] = self.qgis_projectsettings_wms.layers[lidname]['styles'] ret['source'] = {'type': instance.layer_type} # add options for wms layer if instance.layer_type in [ Layer.TYPES.wms, Layer.TYPES.arcgismapserver ]: if instance.layer_type == Layer.TYPES.wms: datasource_wms = QueryDict(instance.datasource) else: datasource_wms = datasourcearcgis2dict(instance.datasource) if ('username' not in ret['source'] or 'password' not in ret['source']) and 'type=xyz' \ not in instance.datasource: # rebuild the dict for paramenters repeat n times i.e. 'layers' and 'styles' if isinstance(datasource_wms, QueryDict): for p in datasource_wms.lists(): if p[0] in ('layers', 'styles'): ret['source'].update({p[0]: ','.join(p[1])}) else: ret['source'].update({p[0]: datasource_wms[p[0]]}) else: ret['source'].update(datasource_wms) ret['source']['external'] = instance.external if instance.external and instance.layer_type == Layer.TYPES.wms: try: wms = WebMapService(ret['source']['url'], version='1.3.0') format_options = wms.getOperationByName( 'GetFeatureInfo').formatOptions if format_options: # Filter format by supported by G3W-CLIENT formats = list( set(format_options).intersection( set(settings.EXTERNAL_WMS_INFOFORMATS_SUPPORTED ))) if formats: ret['infoformat'] = formats[0] ret['infoformats'] = formats except Exception as e: logger.debug( f'WMS layer GetFeatureInfo formats available: {e}') # replace crs property if is not none with dict structure if ret['crs']: crs = QgsCoordinateReferenceSystem(f'EPSG:{ret["crs"]}') # Patch for Proj4 > 4.9.3 version if ret["crs"] == 3003: proj4 = "+proj=tmerc +lat_0=0 +lon_0=9 +k=0.9996 +x_0=1500000 +y_0=0 +ellps=intl " \ "+towgs84=-104.1,-49.1,-9.9,0.971,-2.917,0.714,-11.68 +units=m +no_defs" else: proj4 = crs.toProj4() ret['crs'] = { 'epsg': crs.postgisSrid(), 'proj4': proj4, 'geographic': crs.isGeographic(), 'axisinverted': crs.hasAxisInverted() } # add metadata ret['metadata'] = self.get_metadata(instance, qgs_maplayer) # eval editor_form_structure if ret['editor_form_structure']: ret['editor_form_structure'] = eval(instance.editor_form_structure) # add ows ret['ows'] = self.get_ows(instance) # For temporal properties if instance.temporal_properties: ret['qtimeseries'] = json.loads(instance.temporal_properties) if ret['qtimeseries'] and ret['qtimeseries'][ 'mode'] == 'FeatureDateTimeInstantFromField': # Add start_date end end_date: findex = qgs_maplayer.dataProvider().fieldNameIndex( ret['qtimeseries']['field']) ret['qtimeseries']['start_date'] = qgs_maplayer.minimumValue( findex) ret['qtimeseries']['end_date'] = qgs_maplayer.maximumValue( findex) if isinstance(ret['qtimeseries']['start_date'], QDate) or isinstance( ret['qtimeseries']['start_date'], QDateTime): if not hasattr(QDate, 'isoformat'): QDate.isoformat = lambda d: d.toString(Qt.ISODate) if not hasattr(QDateTime, 'isoformat'): QDateTime.isoformat = lambda d: d.toString( Qt.ISODateWithMs) ret['qtimeseries']['start_date'] = ret['qtimeseries'][ 'start_date'].isoformat() ret['qtimeseries']['end_date'] = ret['qtimeseries'][ 'end_date'].isoformat() return ret
def to_representation(self, instance): ret = super(LayerSerializer, self).to_representation(instance) qgs_maplayer = self.qgs_project.mapLayers()[instance.qgs_layer_id] group = instance.project.group # add attributes/fields ret['fields'] = self.get_attributes(instance) # add infoformat and infourl ret['infoformat'] = '' ret['infourl'] = '' lidname = instance.qgs_layer_id if instance.project.wms_use_layer_ids else instance.name # add bbox if instance.geometrytype != QGIS_LAYER_TYPE_NO_GEOM: if instance.extent: ret['bbox'] = instance.extent_rect else: # get from QgsMapLayer instance extent = qgs_maplayer.extent() ret['bbox'] = {} ret['bbox']['minx'] = extent.xMinimum() ret['bbox']['miny'] = extent.yMinimum() ret['bbox']['maxx'] = extent.xMaximum() ret['bbox']['maxy'] = extent.yMaximum() # add capabilities ret['capabilities'] = get_capabilities4layer(qgs_maplayer) # add styles # FIXME: restore in the future for styles map management #ret['styles'] = self.qgis_projectsettings_wms.layers[lidname]['styles'] ret['source'] = {'type': instance.layer_type} # add options for wms layer if instance.layer_type in [ Layer.TYPES.wms, Layer.TYPES.arcgismapserver ]: if instance.layer_type == Layer.TYPES.wms: datasourceWMS = QueryDict(instance.datasource) else: datasourceWMS = datasourcearcgis2dict(instance.datasource) if ('username' not in ret['source'] or 'password' not in ret['source']) and 'type=xyz' \ not in instance.datasource: # rebuild the dict for paramenters repeat n times i.e. 'layers' and 'styles' if isinstance(datasourceWMS, QueryDict): for p in datasourceWMS.lists(): if p[0] in ('layers', 'styles'): ret['source'].update({p[0]: ','.join(p[1])}) else: ret['source'].update({p[0]: datasourceWMS[p[0]]}) else: ret['source'].update(datasourceWMS) ret['source']['external'] = instance.external # replace crs property if is not none with dict structure if ret['crs']: crs = QgsCoordinateReferenceSystem(f'EPSG:{ret["crs"]}') ret['crs'] = { 'epsg': crs.postgisSrid(), 'proj4': crs.toProj4(), 'geographic': crs.isGeographic(), 'axisinverted': crs.hasAxisInverted() } # add metadata ret['metadata'] = self.get_metadata(instance, qgs_maplayer) # eval editor_form_structure if ret['editor_form_structure']: ret['editor_form_structure'] = eval(instance.editor_form_structure) # add ows ret['ows'] = self.get_ows(instance) return ret
def to_representation(self, instance): ret = super(GroupSerializer, self).to_representation(instance) # add header_logo # before check macrogroups and groups number also if is equal to 1 use it try: macrogroup = instance.macrogroups.get(use_logo_client=True) ret['header_logo_img'] = macrogroup.logo_img.name except: ret['header_logo_img'] = instance.header_logo_img.name try: macrogroup = instance.macrogroups.get(use_title_client=True) ret['name'] = macrogroup.title except: # change groupData name with title for i18n app ret['name'] = instance.title # add crs: crs = QgsCoordinateReferenceSystem(f'EPSG:{self.instance.srid.srid}') # Patch for Proj4 > 4.9.3 version if self.instance.srid.srid == 3003: proj4 = settings.PROJ4_EPSG_3003 else: proj4 = crs.toProj4() ret['crs'] = { 'epsg': crs.postgisSrid(), 'proj4': proj4, 'geographic': crs.isGeographic(), 'axisinverted': crs.hasAxisInverted() } # map controls ret['mapcontrols'] = [ mapcontrol.name for mapcontrol in instance.mapcontrols.all() ] # add projects to group ret['projects'] = [] self.projects = {} anonymous_user = get_user_model().get_anonymous() for g3wProjectApp in settings.G3WADMIN_PROJECT_APPS: Project = apps.get_app_config(g3wProjectApp).get_model('project') projects = get_objects_for_user(self.request.user, '{}.view_project'.format(g3wProjectApp), Project) \ .filter(group=instance) projects_anonymous = get_objects_for_user( anonymous_user, '{}.view_project'.format(g3wProjectApp), Project).filter(group=instance) projects = list(set(projects) | set(projects_anonymous)) for project in projects: self.projects[g3wProjectApp + '-' + str(project.id)] = project if project.pk == int( self.projectId) and g3wProjectApp == self.projectType: self.project = project # project thumbnail project_thumb = project.thumbnail.name if bool(project.thumbnail.name) \ else '{}client/images/FakeProjectThumb.png'.format(settings.STATIC_URL) # Get project url if project.url_alias: url = reverse('group-project-map-alias', args=[project.url_alias])[1:] else: url = reverse( 'group-project-map', args=[project.group.slug, g3wProjectApp, project.pk])[1:] ret['projects'].append({ 'id': project.id, 'title': project.title, 'description': project.description, 'thumbnail': project_thumb, 'type': g3wProjectApp, 'gid': "{}:{}".format(g3wProjectApp, project.id), 'modified': project.modified.timestamp() if hasattr( project, 'modified') else 0, 'url': url }) # baselayers ret['baselayers'] = [] baselayers = instance.baselayers.all().order_by('order') for baselayer in baselayers: ret['baselayers'].append(BaseLayerSerializer(baselayer).data) # add vendorkeys if it is set into settings if settings.VENDOR_KEYS: ret['vendorkeys'] = settings.VENDOR_KEYS # add initproject and overviewproject ret['initproject'] = "{}:{}".format(self.projectType, self.projectId) # add overviewproject is present overviewproject = instance.project_panoramic.all() if overviewproject: overviewproject = overviewproject[0] ret['overviewproject'] = { 'id': int(overviewproject.project_id), 'type': overviewproject.project_type, 'gid': "{}:{}".format(overviewproject.project_type, overviewproject.project_id) } else: ret['overviewproject'] = None ret['plugins'] = {} # Plugins/Module data # Data from plugins can be instance of dict or list # - dict results are used only for update 'plugins' API return data # - list results are more verbose and action on 'plugins' API section is declared, ie: # { # 'mode': 'delete', # 'data': [<list_plugins_section_to_remove>] # }, # { # 'mode': 'update', # 'data': { # '<lugins_name>: { # ... # } # } # } plugins = initconfig_plugin_start.send(sender=self, project=self.projectId, projectType=self.projectType) for data_plugin in plugins: if data_plugin[1] and isinstance(data_plugin[1], dict): ret['plugins'] = copy(ret['plugins']) ret['plugins'].update(data_plugin[1]) elif data_plugin[1] and isinstance(data_plugin[1], list): for dp in data_plugin[1]: if dp['mode'] == 'delete': ret['plugins'] = copy(ret['plugins']) for k in dp['data']: try: ret['plugins'].pop(k) except: pass elif dp['mode'] == 'update': ret['plugins'] = copy(ret['plugins']) ret['plugins'].update(dp['data']) # powerd_by ret['powered_by'] = settings.G3WSUITE_POWERD_BY # header customs links header_custom_links = getattr(settings, 'G3W_CLIENT_HEADER_CUSTOM_LINKS', None) ret['header_custom_links'] = [] if header_custom_links: # check for possible callback for head_link in header_custom_links: if callable(head_link): ret['header_custom_links'].append(head_link(self.request)) else: ret['header_custom_links'].append(head_link) # custom layout ret['layout'] = {} # add legend settings if set to layout layout_legend = getattr(settings, 'G3W_CLIENT_LEGEND', None) if layout_legend: ret['layout']['legend'] = layout_legend # Check if G3W_CLIENT_LEGEND['layertitle'] set it tu false if self.project.legend_position == 'toc': if layout_legend: ret['layout']['legend']['layertitle'] = False else: ret['layout']['legend'] = {'layertitle': False} # add legend settings if set to layout layout_right_panel = getattr(settings, 'G3W_CLIENT_RIGHT_PANEL', None) if layout_right_panel: ret['layout']['rightpanel'] = layout_right_panel return ret
def _crud_baselayer(self, form): """ CRUD base layer """ if form.cleaned_data['as_base_layer']: # Create/update base layer if self.base_layer: # update self.base_layer.title = form.cleaned_data['base_layer_title'] self.base_layer.description = form.cleaned_data['base_layer_desc'] property = eval(self.base_layer.property) property['attributions'] = form.cleaned_data['base_layer_attr'] self.base_layer.property = property self.base_layer.save() else: # create # create OL config data # i.e.: # { # "crs": { # "epsg": 32632, # "proj4": '+proj=utm +zone=32 +datum=WGS84 +units=m +no_defs', # "geographic": False, # "axisinverted": False # }, # "url": "https://dev.g3wsuite.it/caching/api/qdjango30/{z}/{x}/{y}.png", # "servertype": "TMS", # "attributions": "Ortofoto Piemonte AGEA 2015" # } crs = QgsCoordinateReferenceSystem(f'EPSG:{self.layer.project.group.srid.srid}') property = { "crs": { "epsg": self.layer.project.group.srid.srid, "proj4": crs.toProj4(), "geographic": crs.isGeographic(), "axisinverted": crs.hasAxisInverted() }, "url": f"/caching/api/{self.layer._meta.app_label}{self.layer.pk}/"+"{z}/{x}/{y}.png", "servertype": "TMS", "attributions": form.cleaned_data['base_layer_attr'] } kwargs = { 'name': f'bl_from_cached_layer_{self.layer.pk}', 'title': form.cleaned_data['base_layer_title'], 'description': form.cleaned_data['base_layer_desc'], 'property': property } self.base_layer = BaseLayer(**kwargs) self.base_layer.save() # update caching layer config record self.activated.baselayer_id = self.base_layer.pk self.activated.save() else: # Delete base layer if self.base_layer and self.base_layer.pk: self.base_layer.delete() if self.activated.baselayer_id: self.activated.baselayer_id = None self.activated.save()
from qgis.core import QgsCoordinateReferenceSystem from osgeo import osr if __name__ == '__console__': print("-----------------------------------------------\n\n") # PostGIS SRID 4326 is allocated for WGS84 # If not specified otherwise in second parameter, PostGIS SRID is used by default. crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.PostgisCrsId) print("Valid: ", crs.isValid()) print("QGIS CRS ID:", crs.srsid()) print("EPSG ID:", crs.authid()) print("Description:", crs.description()) print("Projection Acronym:", crs.projectionAcronym()) print("Ellipsoid Acronym:", crs.ellipsoidAcronym()) print("Proj4 String:", crs.toProj4()) # check whether it's geographic or projected coordinate system print("Is geographic:", crs.geographicFlag()) # check type of map units in this CRS (values defined in QGis::units enum) print("Map units:", crs.mapUnits()) print("-----------------------------------------------\n\n") wkt = '''GEOGCS["WGS84", DATUM["WGS84", SPHEROID["WGS84", 6378137.0, 298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295], AXIS["Longitude", EAST], AXIS["Latitude", NORTH]]''' crs = QgsCoordinateReferenceSystem(wkt) print("Valid: ", crs.isValid()) print("QGIS CRS ID:", crs.srsid()) print("EPSG ID:", crs.authid()) print("Description:", crs.description())
def qgsadapt(projectTemplate, qkanDB, epsg, projectFile, setPathToTemplateDir=True, dbtyp=u'SpatiaLite'): '''Lädt eine (Vorlage-) Projektdatei (*.qgs) und adaptiert diese auf eine QKan-Datenbank an. Anschließend wird dieses Projekt geladen. Voraussetzungen: keine :projectTemplate: Vorlage-Projektdatei :type database: String :qkanDB: Ziel-Datenbank, auf die die Projektdatei angepasst werden soll :type qkanDB: String :projectFile: Zu Erzeugende Projektdatei :type projectFile: String :setPathToTemplateDir: Option, ob das Suchverzeichnis auf das Template-Verzeichnis gesetzt werden soll. :type setPathToTemplateDir: Boolean :dbtyp: Typ der Datenbank (SpatiaLite, PostGIS) :type dbtyp: String :returns: void ''' # ------------------------------------------------------------------------------ # Datenbankverbindungen dbQK = DBConnection( dbname=qkanDB, epsg=epsg) # Datenbankobjekt der QKan-Datenbank zum Schreiben if dbQK is None: fehlermeldung( u"Fehler in qgsadapt", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( qkanDB)) iface.messageBar().pushMessage(u"Fehler in qgsadapt", u'QKan-Datenbank {:s} wurde nicht gefunden!\nAbbruch!'.format( \ qkanDB), level=QgsMessageBar.CRITICAL) return None # -------------------------------------------------------------------------- # Zoom-Bereich für die Projektdatei vorbereiten sql = u'''SELECT min(xsch) AS xmin, max(xsch) AS xmax, min(ysch) AS ymin, max(ysch) AS ymax FROM schaechte''' try: dbQK.sql(sql) except BaseException as e: fehlermeldung('SQL-Fehler', str(e)) fehlermeldung("Fehler in qgsadapt", u"\nFehler in sql_zoom: \n" + sql + '\n\n') daten = dbQK.fetchone() try: zoomxmin, zoomxmax, zoomymin, zoomymax = daten except BaseException as e: fehlermeldung('SQL-Fehler', str(e)) fehlermeldung("Fehler in qgsadapt", u"\nFehler in sql_zoom; daten= " + str(daten) + '\n') # -------------------------------------------------------------------------- # Projektionssystem für die Projektdatei vorbereiten sql = """SELECT srid FROM geom_cols_ref_sys WHERE Lower(f_table_name) = Lower('schaechte') AND Lower(f_geometry_column) = Lower('geom')""" if not dbQK.sql(sql, 'importkanaldaten_dyna (37)'): return None srid = dbQK.fetchone()[0] try: crs = QgsCoordinateReferenceSystem( srid, QgsCoordinateReferenceSystem.EpsgCrsId) srsid = crs.srsid() proj4text = crs.toProj4() description = crs.description() projectionacronym = crs.projectionAcronym() if 'ellipsoidacronym' in dir(crs): ellipsoidacronym = crs.ellipsoidacronym() else: ellipsoidacronym = None except BaseException as e: srid, srsid, proj4text, description, projectionacronym, ellipsoidacronym = \ 'dummy', 'dummy', 'dummy', 'dummy', 'dummy', 'dummy' fehlermeldung('\nFehler in "daten"', str(e)) fehlermeldung("Fehler in qgsadapt", u"\nFehler bei der Ermittlung der srid: \n" + str(daten)) # -------------------------------------------------------------------------- # Datenbankverbindungen schliessen del dbQK # -------------------------------------------------------------------------- # Projektdatei schreiben, falls ausgewählt if projectFile is None or projectFile == u'': fehlermeldung(u'Bedienerfehler!', u'Es wurde keine Projektdatei ausgewählt') return False if setPathToTemplateDir: templatepath = os.path.join(pluginDirectory('qkan'), u"database/templates") projectpath = os.path.dirname(projectFile) if os.path.dirname(qkanDB) == projectpath: datasource = qkanDB.replace(os.path.dirname(qkanDB), u'.') else: datasource = qkanDB # Liste der Geotabellen aus QKan, um andere Tabellen von der Bearbeitung auszuschliessen # Liste steht in 3 Modulen: tools.k_tools, importdyna.import_from_dyna, importhe.import_from_he tabliste = [ u'einleit', u'einzugsgebiete', u'flaechen', u'haltungen', u'linkfl', u'linksw', u'pumpen', u'schaechte', u'teilgebiete', u'tezg', u'wehre' ] # Liste der QKan-Formulare, um individuell erstellte Formulare von der Bearbeitung auszuschliessen formsliste = [ 'qkan_abflussparameter.ui', 'qkan_anbindungageb.ui', 'qkan_anbindungeinleit.ui', 'qkan_anbindungflaechen.ui', 'qkan_auslaesse.ui', 'qkan_auslasstypen.ui', 'qkan_aussengebiete.ui', 'qkan_bodenklassen.ui', 'qkan_einleit.ui', 'qkan_einzugsgebiete.ui', 'qkan_entwaesserungsarten.ui', 'qkan_flaechen.ui', 'qkan_haltungen.ui', 'qkan_profildaten.ui', 'qkan_profile.ui', 'qkan_pumpen.ui', 'qkan_pumpentypen.ui', 'qkan_schaechte.ui', 'qkan_simulationsstatus.ui', 'qkan_speicher.ui', 'qkan_speicherkennlinien.ui', 'qkan_swref.ui', 'qkan_teilgebiete.ui', 'qkan_tezg.ui', 'qkan_wehre.ui' ] # Lesen der Projektdatei ------------------------------------------------------------------ qgsxml = ET.parse(projectTemplate) root = qgsxml.getroot() # Projektionssystem anpassen -------------------------------------------------------------- for tag_maplayer in root.findall(u".//projectlayers/maplayer"): tag_datasource = tag_maplayer.find(u"./datasource") tex = tag_datasource.text # Nur QKan-Tabellen bearbeiten if tex[tex.index(u'table="') + 7:].split(u'" ')[0] in tabliste: # <extend> löschen for tag_extent in tag_maplayer.findall(u"./extent"): tag_maplayer.remove(tag_extent) for tag_spatialrefsys in tag_maplayer.findall( u"./srs/spatialrefsys"): tag_spatialrefsys.clear() elem = ET.SubElement(tag_spatialrefsys, u'proj4') elem.text = proj4text elem = ET.SubElement(tag_spatialrefsys, u'srsid') elem.text = u'{}'.format(srsid) elem = ET.SubElement(tag_spatialrefsys, u'srid') elem.text = u'{}'.format(srid) elem = ET.SubElement(tag_spatialrefsys, u'authid') elem.text = u'EPSG: {}'.format(srid) elem = ET.SubElement(tag_spatialrefsys, u'description') elem.text = description elem = ET.SubElement(tag_spatialrefsys, u'projectionacronym') elem.text = projectionacronym if ellipsoidacronym is not None: elem = ET.SubElement(tag_spatialrefsys, u'ellipsoidacronym') elem.text = ellipsoidacronym # Pfad zu Formularen auf plugin-Verzeichnis setzen ----------------------------------------- formspath = os.path.join(pluginDirectory('qkan'), u"forms") for tag_maplayer in root.findall(u".//projectlayers/maplayer"): tag_editform = tag_maplayer.find(u"./editform") dateiname = os.path.basename(tag_editform.text) if dateiname in formsliste: # Nur QKan-Tabellen bearbeiten tag_editform.text = os.path.join(formspath, dateiname) # Zoom für Kartenfenster einstellen ------------------------------------------------------- for tag_extent in root.findall(u".//mapcanvas/extent"): elem = tag_extent.find(u"./xmin") elem.text = u'{:.3f}'.format(zoomxmin) elem = tag_extent.find(u"./ymin") elem.text = u'{:.3f}'.format(zoomymin) elem = tag_extent.find(u"./xmax") elem.text = u'{:.3f}'.format(zoomxmax) elem = tag_extent.find(u"./ymax") elem.text = u'{:.3f}'.format(zoomymax) # Projektionssystem anpassen -------------------------------------------------------------- for tag_spatialrefsys in root.findall( u".//mapcanvas/destinationsrs/spatialrefsys"): tag_spatialrefsys.clear() elem = ET.SubElement(tag_spatialrefsys, u'proj4') elem.text = proj4text elem = ET.SubElement(tag_spatialrefsys, u'srid') elem.text = u'{}'.format(srid) elem = ET.SubElement(tag_spatialrefsys, u'authid') elem.text = u'EPSG: {}'.format(srid) elem = ET.SubElement(tag_spatialrefsys, u'description') elem.text = description elem = ET.SubElement(tag_spatialrefsys, u'projectionacronym') elem.text = projectionacronym if ellipsoidacronym is not None: elem = ET.SubElement(tag_spatialrefsys, u'ellipsoidacronym') elem.text = ellipsoidacronym # Pfad zur QKan-Datenbank anpassen for tag_datasource in root.findall( u".//projectlayers/maplayer/datasource"): text = tag_datasource.text tag_datasource.text = u"dbname='" + datasource + u"' " + text[ text.find(u'table='):] qgsxml.write(projectFile) # writing modified project file logger.debug(u'Projektdatei: {}'.format(projectFile)) # logger.debug(u'encoded string: {}'.format(tex)) # ------------------------------------------------------------------------------ # Abschluss: Ggfs. Protokoll schreiben und Datenbankverbindungen schliessen iface.mainWindow().statusBar().clearMessage() iface.messageBar().pushMessage( "Information", "Projektdatei ist angepasst und muss neu geladen werden!", level=QgsMessageBar.INFO)
def to_representation(self, instance): ret = super(GroupSerializer, self).to_representation(instance) # add header_logo # before check macrogroups and groups number also if is equal to 1 use it try: macrogroup = instance.macrogroups.get(use_logo_client=True) ret['header_logo_img'] = macrogroup.logo_img.name except: ret['header_logo_img'] = instance.header_logo_img.name try: macrogroup = instance.macrogroups.get(use_title_client=True) ret['name'] = macrogroup.title except: # change groupData name with title for i18n app ret['name'] = instance.title # add crs: crs = QgsCoordinateReferenceSystem(f'EPSG:{self.instance.srid.srid}') ret['crs'] = { 'epsg': crs.postgisSrid(), 'proj4': crs.toProj4(), 'geographic': crs.isGeographic(), 'axisinverted': crs.hasAxisInverted() } # map controls ret['mapcontrols'] = [ mapcontrol.name for mapcontrol in instance.mapcontrols.all() ] # add projects to group ret['projects'] = [] self.projects = {} anonymous_user = get_user_model().get_anonymous() for g3wProjectApp in settings.G3WADMIN_PROJECT_APPS: Project = apps.get_app_config(g3wProjectApp).get_model('project') projects = get_objects_for_user(self.request.user, '{}.view_project'.format(g3wProjectApp), Project) \ .filter(group=instance) projects_anonymous = get_objects_for_user( anonymous_user, '{}.view_project'.format(g3wProjectApp), Project).filter(group=instance) projects = list(set(projects) | set(projects_anonymous)) print(projects) for project in projects: self.projects[g3wProjectApp + '-' + str(project.id)] = project if project.pk == int( self.projectId) and g3wProjectApp == self.projectType: self.project = project # project thumbnail project_thumb = project.thumbnail.name if bool(project.thumbnail.name) \ else '{}client/images/FakeProjectThumb.png'.format(settings.STATIC_URL) ret['projects'].append({ 'id': project.id, 'title': project.title, 'description': project.description, 'thumbnail': project_thumb, 'type': g3wProjectApp, 'gid': "{}:{}".format(g3wProjectApp, project.id), 'modified': project.modified.timestamp() if hasattr( project, 'modified') else 0 }) # baselayers ret['baselayers'] = [] baselayers = instance.baselayers.all().order_by('order') for baselayer in baselayers: ret['baselayers'].append(BaseLayerSerializer(baselayer).data) # add vendorkeys if it is set into settings if settings.VENDOR_KEYS: ret['vendorkeys'] = settings.VENDOR_KEYS # add initproject and overviewproject ret['initproject'] = "{}:{}".format(self.projectType, self.projectId) # add overviewproject is present overviewproject = instance.project_panoramic.all() if overviewproject: overviewproject = overviewproject[0] ret['overviewproject'] = { 'id': int(overviewproject.project_id), 'type': overviewproject.project_type, 'gid': "{}:{}".format(overviewproject.project_type, overviewproject.project_id) } else: ret['overviewproject'] = None ret['plugins'] = {} # plugins/module data dataPlugins = initconfig_plugin_start.send( sender=self, project=self.projectId, projectType=self.projectType) for dataPlugin in dataPlugins: if dataPlugin[1]: ret['plugins'] = copy(ret['plugins']) ret['plugins'].update(dataPlugin[1]) # powerd_by ret['powered_by'] = settings.G3WSUITE_POWERD_BY # header customs links header_custom_links = getattr(settings, 'G3W_CLIENT_HEADER_CUSTOM_LINKS', None) ret['header_custom_links'] = [] if header_custom_links: # check for possible callback for head_link in header_custom_links: if callable(head_link): ret['header_custom_links'].append(head_link(self.request)) else: ret['header_custom_links'].append(head_link) # custom layout ret['layout'] = {} # add legend settings if set to layout layout_legend = getattr(settings, 'G3W_CLIENT_LEGEND', None) if layout_legend: ret['layout']['legend'] = layout_legend # Check if G3W_CLIENT_LEGEND['layertitle'] set it tu false if self.project.legend_position == 'toc': if layout_legend: ret['layout']['legend']['layertitle'] = False else: ret['layout']['legend'] = {'layertitle': False} # add legend settings if set to layout layout_right_panel = getattr(settings, 'G3W_CLIENT_RIGHT_PANEL', None) if layout_right_panel: ret['layout']['rightpanel'] = layout_right_panel return ret