def change_project_projection(self): # Change to wgs84 to activate the changes in origin self.qgis_instance.setCrs(WGS84) proj_string = self.projection.value.proj_str(self.origin) crs = QgsCoordinateReferenceSystem() crs.createFromProj(proj_string) self.qgis_instance.setCrs(crs)
def add_to_layout(self, layout, background_color=QColor(255, 255, 255, 0), size=80): """ Inspired by https://opensourceoptions.com/blog/pyqgis-create-and-print-a-map-layout-with-python/ """ layers = [layer.layer() for layer in self.group.findLayers()] # create map item in the layout map = QgsLayoutItemMap(layout) map.setRect(20, 20, 20, 20) # set the map extent ms = QgsMapSettings() ms.setLayers(layers) # set layers to be mapped crs = QgsCoordinateReferenceSystem() crs.createFromProj(self.projection.value.proj_str(self.origin)) map.setCrs(crs) map.setFollowVisibilityPreset(True) map.setFollowVisibilityPresetName(Globe.THEME_NAME) rect = QgsRectangle(ms.fullExtent()) ms.setExtent(rect) map.setExtent(rect) map.setBackgroundColor(background_color) layout.addLayoutItem(map) map.attemptMove(QgsLayoutPoint(5, 20, QgsUnitTypes.LayoutMillimeters)) map.attemptResize( QgsLayoutSize(size, size, QgsUnitTypes.LayoutMillimeters))
def testCrsConversion(self): self.assertFalse( GdalUtils.gdal_crs_string(QgsCoordinateReferenceSystem())) self.assertEqual( GdalUtils.gdal_crs_string( QgsCoordinateReferenceSystem('EPSG:3111')), 'EPSG:3111') self.assertEqual( GdalUtils.gdal_crs_string( QgsCoordinateReferenceSystem('POSTGIS:3111')), 'EPSG:3111') self.assertEqual( GdalUtils.gdal_crs_string( QgsCoordinateReferenceSystem( 'proj4: +proj=utm +zone=36 +south +a=6378249.145 +b=6356514.966398753 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs' )), 'EPSG:20936') crs = QgsCoordinateReferenceSystem() crs.createFromProj( '+proj=utm +zone=36 +south +a=600000 +b=70000 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs' ) self.assertTrue(crs.isValid()) self.assertEqual( GdalUtils.gdal_crs_string(crs), '+proj=utm +zone=36 +south +a=600000 +b=70000 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs' ) # check that newlines are stripped crs = QgsCoordinateReferenceSystem() crs.createFromProj( '+proj=utm +zone=36 +south\n +a=600000 +b=70000 \r\n +towgs84=-143,-90,-294,0,0,0,0 +units=m\n+no_defs' ) self.assertTrue(crs.isValid()) self.assertEqual( GdalUtils.gdal_crs_string(crs), '+proj=utm +zone=36 +south +a=600000 +b=70000 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs' )
def testCrsConversion(self): self.assertFalse( GdalUtils.gdal_crs_string(QgsCoordinateReferenceSystem())) self.assertEqual( GdalUtils.gdal_crs_string( QgsCoordinateReferenceSystem('EPSG:3111')), 'EPSG:3111') self.assertEqual( GdalUtils.gdal_crs_string( QgsCoordinateReferenceSystem('POSTGIS:3111')), 'EPSG:3111') self.assertEqual( GdalUtils.gdal_crs_string( QgsCoordinateReferenceSystem( 'proj4: +proj=utm +zone=36 +south +a=6378249.145 +b=6356514.966398753 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs' )), 'EPSG:20936') crs = QgsCoordinateReferenceSystem() crs.createFromProj( '+proj=utm +zone=36 +south +a=600000 +b=70000 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs' ) self.assertTrue(crs.isValid()) # proj 6, WKT should be used self.assertEqual( GdalUtils.gdal_crs_string(crs)[:40], 'BOUNDCRS[SOURCECRS[PROJCRS["unknown",BAS') self.assertEqual( GdalUtils.gdal_crs_string( QgsCoordinateReferenceSystem('ESRI:102003')), 'ESRI:102003')
def get_destination_crs(self): crs = self.layer.crs() srs = osr.SpatialReference() srs.ImportFromProj4(crs.toProj()) a = srs.GetSemiMajor() b = srs.GetSemiMinor() proj4 = "+proj=latlong +a={} +b={}".format(a, b) destination = QgsCoordinateReferenceSystem() destination.createFromProj(proj4) return destination
def updateRaster(self): if self.mcboRasterLayer.currentLayer() is None: return layer = self.mcboRasterLayer.currentLayer() provider = layer.dataProvider() if provider.sourceHasNoDataValue(1): self.lneNoDataVal.setText(str(provider.sourceNoDataValue(1))) elif len(provider.userNoDataValues(1)) > 0: self.lneNoDataVal.setText(str(provider.userNoDataValues(1)[0].min())) else: self.lneNoDataVal.clear() # add a band list to the drop down box bandCount = self.mcboRasterLayer.currentLayer().bandCount() band_list = ['Band {: >2}'.format(i) for i in range(1, bandCount + 1)] self.cboBand.setMaxCount(bandCount + 1) self.cboBand.clear() self.cboBand.addItems(sorted(band_list)) #set default coordinate system rast_crs = layer.crs() if rast_crs.authid()== '': # Convert from the older style strings rast_crs = QgsCoordinateReferenceSystem() if not rast_crs.createFromProj(layer.crs().toWkt()): rast_crs = layer.crs() rast_crs = get_UTM_Coordinate_System(layer.extent().xMinimum(), layer.extent().yMinimum(), rast_crs.authid()) self.mCRSoutput.setCrs(rast_crs)
def on_mcboLineLayer_layerChanged(self): # set default coordinate system layer = self.mcboLineLayer.currentLayer() if layer is None: return line_crs = layer.crs() if line_crs.authid() == '': # Convert from the older style strings line_crs = QgsCoordinateReferenceSystem() if not line_crs.createFromProj(layer.crs().toWkt()): line_crs = layer.crs() line_crs = get_UTM_Coordinate_System(layer.extent().xMinimum(), layer.extent().yMinimum(), line_crs.authid()) self.mCRSoutput.setCrs(line_crs)
def updateRaster(self): """Update form elements based on raster metadata elements""" if self.mcboRasterLayer.currentLayer() is None: return rast_layer = self.mcboRasterLayer.currentLayer() provider = rast_layer.dataProvider() if provider.sourceHasNoDataValue(1): self.lneNoDataVal.setText(str(provider.sourceNoDataValue(1))) elif len(provider.userNoDataValues(1)) > 0: self.lneNoDataVal.setText(str(provider.userNoDataValues(1)[0].min())) else: self.lneNoDataVal.setText('0') # add a band list to the drop down box bandCount = self.mcboRasterLayer.currentLayer().bandCount() band_list = ['Band {: >2}'.format(i) for i in range(1, bandCount + 1)] for obj in [self.cboBandRed, self.cboBandGreen, self.cboBandIR, self.cboBandRedEdge, self.cboBandNonVine]: obj.setMaxCount(bandCount + 1) obj.clear() obj.addItems([u''] + sorted(band_list)) # clear the coordinate system self.mCRSoutput.setCrs(QgsCoordinateReferenceSystem()) # set default coordinate system rast_crs = rast_layer.crs() if rast_crs.authid() == '': # Convert from the older style strings rast_crs = QgsCoordinateReferenceSystem() if not rast_crs.createFromProj(rast_layer.crs().toWkt()): rast_crs = rast_layer.crs() else: self.mcboRasterLayer.currentLayer().setCrs(rast_crs) rast_crs = get_UTM_Coordinate_System(rast_layer.extent().xMinimum(), rast_layer.extent().yMinimum(), rast_crs.authid()) self.mCRSoutput.setCrs(rast_crs)
def build_layer_table(layer_list=None, only_raster_boundingbox=True): """Build a table of layer properties. Can be used in conjunction with selecting layers to exclude from mapcomboboxes Layer_list: default None if None then it will build the table from all layers in the QGIS project otherwise it will use the list. only_raster_boundingbox: default False create a bounding box from the raster data ie removing nodata from polygon. This will slow it down if large numbers of rasters are present. """ dest_crs = QgsProject.instance().crs() gdf_layers = gpd.GeoDataFrame(columns=[ 'layer', 'layer_name', 'layer_id', 'layer_type', 'source', 'format', 'epsg', 'crs_name', 'is_projected', 'extent', 'provider', 'geometry' ], geometry='geometry', crs=dest_crs.authid()) # pd.DataFrame() if layer_list is None or len(layer_list) == 0: layermap = QgsProject.instance().mapLayers().values() else: layermap = layer_list new_rows = [] for layer in layermap: if layer.type() not in [ QgsMapLayer.VectorLayer, QgsMapLayer.RasterLayer ]: continue if layer.providerType() not in ['ogr', 'gdal', 'delimitedtext']: continue if layer.type() == QgsMapLayer.VectorLayer: format = layer.dataProvider().storageType() else: format = None if layer.crs().isValid() and layer.crs().authid() == '': # Try and convert older style coordinates systems # were correctly definied in QGIS 2 as GDA94 / MGA zone 54 # but get interpreted in QGIS 3 as Unknown CRS: BOUNDCRS[SOURCECRS[PROJCRS["GDA94 / MGA zone 54",..... layer_crs = QgsCoordinateReferenceSystem() if not layer_crs.createFromProj(layer.crs().toWkt()): #print('Could not match a coordinate system for {}'.format(layer.id())) layer_crs = layer.crs() # could apply to the layer, but what if it's wrong.... #layer.setCrs(layer_crs) else: layer_crs = layer.crs() # project the bounding box extents to be the same as the qgis project. if layer_crs.authid() != dest_crs.authid(): transform = QgsCoordinateTransform(layer_crs, dest_crs, QgsProject.instance()) prj_ext = transform.transformBoundingBox(layer.extent()) else: prj_ext = layer.extent() row_dict = { 'layer': layer, 'layer_name': layer.name(), 'layer_id': layer.id(), 'layer_type': layerTypes[layer.type()], 'format': format, 'source': get_layer_source(layer), 'epsg': layer_crs.authid(), 'crs_name': layer_crs.description(), 'is_projected': not layer_crs.isGeographic(), 'provider': layer.providerType(), 'geometry': wkt.loads(prj_ext.asWktPolygon()) } # 'extent': prj_ext.asWktPolygon(), if layer.type() == QgsMapLayer.RasterLayer: pixel_size = get_pixel_size(layer) if not only_raster_boundingbox: with rasterio.open(get_layer_source(layer)) as src: msk = src.dataset_mask() # 0 = nodata 255=valid rast_shapes = rasterio.features.shapes( np.ma.masked_equal(np.where(msk > 0, 1, 0), 0), transform=src.transform) try: results = ({ 'properties': { 'raster_val': v }, 'geometry': s } for i, (s, v) in enumerate(rast_shapes)) geoms = list(results) gpd_rPoly = gpd.GeoDataFrame.from_features( geoms, crs=layer.crs().authid()) dest_crs.authid().replace('epgs:', '') gpd_rPoly.to_crs(dest_crs.authid().replace('epgs:', ''), inplace=True) row_dict.update({'geometry': gpd_rPoly.unary_union}) del gpd_rPoly, results, msk, rast_shapes except: pass row_dict.update({ 'bandcount': layer.bandCount(), 'datatype': dataTypes[layer.dataProvider().dataType(1)], 'pixel_size': pixel_size[0], 'pixel_text': '{} {}'.format(*pixel_size), }) new_rows.append(row_dict) # gdf_layers = gpd.GeoDataFrame(new_rows, geometry='extent') if len(new_rows) == 0: return gdf_layers # for pandas 0.23.4 add sort=False to prevent row and column orders to change. try: gdf_layers = gdf_layers.append(new_rows, ignore_index=True, sort=False) except: gdf_layers = gdf_layers.append(new_rows, ignore_index=True) #df_layers.set_geometry('geometry') return gdf_layers