def load(fileName, name=None, crs=None, style=None, isRaster=False): """ Loads a layer/table into the current project, given its file. .. deprecated:: 3.0 Do not use, will be removed in QGIS 4.0 """ from warnings import warn warn("processing.load is deprecated and will be removed in QGIS 4.0", DeprecationWarning) if fileName is None: return prjSetting = None settings = QgsSettings() if crs is not None: prjSetting = settings.value('/Projections/defaultBehavior') settings.setValue('/Projections/defaultBehavior', '') if name is None: name = os.path.split(fileName)[1] if isRaster: qgslayer = QgsRasterLayer(fileName, name) if qgslayer.isValid(): if crs is not None and qgslayer.crs() is None: qgslayer.setCrs(crs, False) if style is None: style = ProcessingConfig.getSetting(ProcessingConfig.RASTER_STYLE) qgslayer.loadNamedStyle(style) QgsProject.instance().addMapLayers([qgslayer]) else: if prjSetting: settings.setValue('/Projections/defaultBehavior', prjSetting) raise RuntimeError(QCoreApplication.translate('dataobject', 'Could not load layer: {0}\nCheck the processing framework log to look for errors.').format( fileName)) else: qgslayer = QgsVectorLayer(fileName, name, 'ogr') if qgslayer.isValid(): if crs is not None and qgslayer.crs() is None: qgslayer.setCrs(crs, False) if style is None: if qgslayer.geometryType() == QgsWkbTypes.PointGeometry: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POINT_STYLE) elif qgslayer.geometryType() == QgsWkbTypes.LineGeometry: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POLYGON_STYLE) qgslayer.loadNamedStyle(style) QgsProject.instance().addMapLayers([qgslayer]) if prjSetting: settings.setValue('/Projections/defaultBehavior', prjSetting) return qgslayer
def load(fileName, name=None, crs=None, style=None, isRaster=False): """Loads a layer/table into the current project, given its file. """ if fileName is None: return prjSetting = None settings = QSettings() if crs is not None: prjSetting = settings.value('/Projections/defaultBehaviour') settings.setValue('/Projections/defaultBehaviour', '') if name is None: name = os.path.split(fileName)[1] if isRaster: qgslayer = QgsRasterLayer(fileName, name) if qgslayer.isValid(): if crs is not None and qgslayer.crs() is None: qgslayer.setCrs(crs, False) if style is None: style = ProcessingConfig.getSetting(ProcessingConfig.RASTER_STYLE) qgslayer.loadNamedStyle(style) QgsMapLayerRegistry.instance().addMapLayers([qgslayer]) iface.legendInterface().refreshLayerSymbology(qgslayer) else: if prjSetting: settings.setValue('/Projections/defaultBehaviour', prjSetting) raise RuntimeError('Could not load layer: ' + unicode(fileName) + '\nCheck the processing framework log to look for errors') else: qgslayer = QgsVectorLayer(fileName, name, 'ogr') if qgslayer.isValid(): if crs is not None and qgslayer.crs() is None: qgslayer.setCrs(crs, False) if style is None: if qgslayer.geometryType() == QGis.Point: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POINT_STYLE) elif qgslayer.geometryType() == QGis.Line: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POLYGON_STYLE) qgslayer.loadNamedStyle(style) QgsMapLayerRegistry.instance().addMapLayers([qgslayer]) if prjSetting: settings.setValue('/Projections/defaultBehaviour', prjSetting) return qgslayer
def clip_layers(first_layer_path, second_layer_path): """Clip and resample layers with the reference to the first layer. :param first_layer_path: Path to the first layer path. :type first_layer_path: str :param second_layer_path: Path to the second layer path. :type second_layer_path: str :return: Path to the clipped datasets (clipped 1st layer, clipped 2nd layer). :rtype: tuple(str, str) :raise FileNotFoundError """ base_name, _ = os.path.splitext(first_layer_path) # noinspection PyCallingNonCallable first_layer = QgsRasterLayer(first_layer_path, base_name) base_name, _ = os.path.splitext(second_layer_path) # noinspection PyCallingNonCallable second_layer = QgsRasterLayer(second_layer_path, base_name) # Get the firs_layer extents as an array in EPSG:4326 first_layer_geo_extent = extent_to_geoarray( first_layer.extent(), first_layer.crs()) first_layer_geo_cell_size, _ = get_wgs84_resolution(first_layer) second_layer_geo_cell_size, _ = get_wgs84_resolution(second_layer) if first_layer_geo_cell_size < second_layer_geo_cell_size: cell_size = first_layer_geo_cell_size else: cell_size = second_layer_geo_cell_size clipped_first_layer = clip_layer( layer=first_layer, extent=first_layer_geo_extent, cell_size=cell_size) clipped_second_layer = clip_layer( layer=second_layer, extent=first_layer_geo_extent, cell_size=cell_size) return clipped_first_layer, clipped_second_layer
def test_projection(self): """QGIS properly parses a wkt string""" crs = QgsCoordinateReferenceSystem() wkt = ( 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",' 'SPHEROID["WGS_1984",6378137.0,298.257223563]],' 'PRIMEM["Greenwich",0.0],UNIT["Degree",' '0.0174532925199433]]') crs.createFromWkt(wkt) auth_id = crs.authid() expected_auth_id = 'EPSG:4326' self.assertEqual(auth_id, expected_auth_id) # now test for a loaded layer path = os.path.join(os.path.dirname(__file__), 'tenbytenraster.asc') title = 'TestRaster' layer = QgsRasterLayer(path, title) auth_id = layer.crs().authid() self.assertEqual(auth_id, expected_auth_id)
def testProjInterpretation(self): """Test that QGIS properly parses a proj4 string. see https://github.com/AIFDR/inasafe/issues/349 """ myCrs = QgsCoordinateReferenceSystem() myProj4 = ('GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",' 'SPHEROID["WGS_1984",6378137.0,298.257223563]],' 'PRIMEM["Greenwich",0.0],UNIT["Degree",' '0.0174532925199433]]') myCrs.createFromWkt(myProj4) myAuthId = myCrs.authid() myExpectedAuthId = 'EPSG:4326' self.assertEqual(myAuthId, myExpectedAuthId) # now test for a loaded layer myPath = os.path.join(EXPDATA, 'glp10ag.asc') myTitle = 'people' myLayer = QgsRasterLayer(myPath, myTitle) myAuthId = myLayer.crs().authid() self.assertEqual(myAuthId, myExpectedAuthId)
def test_proj_interpretation(self): """Test that QGIS properly parses a proj4 string. see https://github.com/AIFDR/inasafe/issues/349 """ # noinspection PyCallingNonCallable crs = QgsCoordinateReferenceSystem() proj4 = ( 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",' 'SPHEROID["WGS_1984",6378137.0,298.257223563]],' 'PRIMEM["Greenwich",0.0],UNIT["Degree",' '0.0174532925199433]]') crs.createFromWkt(proj4) auth_id = crs.authid() expected_auth_id = 'EPSG:4326' self.assertEqual(auth_id, expected_auth_id) # now test for a loaded layer path = standard_data_path('hazard', 'jakarta_flood_design.tif') title = 'Jakarta Flood' # noinspection PyCallingNonCallable layer = QgsRasterLayer(path, title) auth_id = layer.crs().authid() self.assertEqual(auth_id, expected_auth_id)
def testLayerRemovalBeforeRun(self): """test behavior when layer is removed before task begins""" path = os.path.join(unitTestDataPath(), 'raster', 'with_color_table.tif') raster_layer = QgsRasterLayer(path, "test") self.assertTrue(raster_layer.isValid()) pipe = QgsRasterPipe() self.assertTrue(pipe.set(raster_layer.dataProvider().clone())) tmp = create_temp_filename('remove_layer.tif') writer = QgsRasterFileWriter(tmp) task = QgsRasterFileWriterTask(writer, pipe, 100, 100, raster_layer.extent(), raster_layer.crs()) task.writeComplete.connect(self.onSuccess) task.errorOccurred.connect(self.onFail) # remove layer raster_layer = None QgsApplication.taskManager().addTask(task) while not self.success and not self.fail: QCoreApplication.processEvents() # in this case will still get a positive result - since the pipe is cloned before the task # begins the task is no longer dependent on the original layer self.assertTrue(self.success) self.assertFalse(self.fail) self.assertTrue(os.path.exists(tmp))
def testSuccess(self): """test successfully writing a layer""" path = os.path.join(unitTestDataPath(), 'raster', 'with_color_table.tif') raster_layer = QgsRasterLayer(path, "test") self.assertTrue(raster_layer.isValid()) pipe = QgsRasterPipe() self.assertTrue(pipe.set(raster_layer.dataProvider().clone())) tmp = create_temp_filename('success.tif') writer = QgsRasterFileWriter(tmp) task = QgsRasterFileWriterTask(writer, pipe, 100, 100, raster_layer.extent(), raster_layer.crs()) task.writeComplete.connect(self.onSuccess) task.errorOccurred.connect(self.onFail) QgsApplication.taskManager().addTask(task) while not self.success and not self.fail: QCoreApplication.processEvents() self.assertTrue(self.success) self.assertFalse(self.fail) self.assertTrue(os.path.exists(tmp))
def load(fileName, name=None, crs=None, style=None, isRaster=False): """ Loads a layer/table into the current project, given its file. .. deprecated:: 3.0 Do not use, will be removed in QGIS 4.0 """ from warnings import warn warn("processing.load is deprecated and will be removed in QGIS 4.0", DeprecationWarning) if fileName is None: return prjSetting = None settings = QgsSettings() if crs is not None: prjSetting = settings.value('/Projections/defaultBehavior') settings.setValue('/Projections/defaultBehavior', '') if name is None: name = os.path.split(fileName)[1] if isRaster: qgslayer = QgsRasterLayer(fileName, name) if qgslayer.isValid(): if crs is not None and qgslayer.crs() is None: qgslayer.setCrs(crs, False) if style is None: style = ProcessingConfig.getSetting( ProcessingConfig.RASTER_STYLE) qgslayer.loadNamedStyle(style) QgsProject.instance().addMapLayers([qgslayer]) else: if prjSetting: settings.setValue('/Projections/defaultBehavior', prjSetting) raise RuntimeError( QCoreApplication.translate( 'dataobject', 'Could not load layer: {0}\nCheck the processing framework log to look for errors.' ).format(fileName)) else: qgslayer = QgsVectorLayer(fileName, name, 'ogr') if qgslayer.isValid(): if crs is not None and qgslayer.crs() is None: qgslayer.setCrs(crs, False) if style is None: if qgslayer.geometryType() == QgsWkbTypes.PointGeometry: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_POINT_STYLE) elif qgslayer.geometryType() == QgsWkbTypes.LineGeometry: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_POLYGON_STYLE) qgslayer.loadNamedStyle(style) QgsProject.instance().addMapLayers([qgslayer]) if prjSetting: settings.setValue('/Projections/defaultBehavior', prjSetting) return qgslayer
def select_HDF5_file(self): """Run method that performs all the real work""" # show the dialog #self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # close the dialog self.dlg.close() # See if OK was pressed if result: #### to open windows browser and search for HDF5 files only: myfileNames = QFileDialog.getOpenFileNames(self.dlg, self.tr("HDF5 File Selector"), "", self.tr("HDF5 (*.hdf5 *.h5)")) #### to loop through all selected HDF5 files, just handling one for now for i in myfileNames: #### bind the HDF5 file myfile = QgsRasterLayer(i) #### to deal with multiple datasets within file if (len(myfile.subLayers()) > 1): #### to open dataset with desired data and name it Reflectance #mydset = QgsRasterLayer(myfile.subLayers()[0], 'Reflectance') fileName = myfile.subLayers()[0] fileInfo = QFileInfo(fileName) baseName = fileInfo.baseName() mydset = QgsRasterLayer(fileName, baseName) ##################################### Trials of setting proper extent begin here print 'Extent before: ' print mydset.extent().toString() ########################## test almost worked ### loaded layer in right place but without data #rect = QgsRectangle(326380.0,4103390.0-2853,326380.0+1332,4103390.0) #mydset.setExtent(rect) #################################### ######################## test almost worked ### loaded layer in right place but without data #size = QSizeF(1,1) #point = QPointF(326380.0, 4103390.0) #rect = QRectF(point, size) #rect = QgsRectangle(rect) #mydset.setExtent(rect) ################################### ########################## did not change extent #rect = QgsRectangle(326380.0,4103390.0-2853,326380.0+1332,4103390.0) #context = QgsRenderContext() #context.setExtent(rect) #mydset.draw(context) #################################### #################################### did not change extent #size = QSizeF(1,1) #point = QPointF(326380.0, 4103390.0) #rect = QRectF(point, size) #rect = QgsRectangle(rect) #context = QgsRenderContext() #context.setExtent(rect) #mydset.draw(context) ##################################### ###################################### did not change extent #rect = QgsRectangle(326380.0,4103390.0-2853,326380.0+1332,4103390.0) #context = QgsRenderContext() #context.setExtent(rect) #print 'Context extent: ' #print context.extent().toString() #this printed correct extent #mydset.createMapRenderer(context) ####################################### ######################## test almost worked ### loaded layer in right place but without data #rect = QgsRectangle(326380.0,4103390.0-2853,326380.0+1332,4103390.0) #provider = mydset.dataProvider().clone() #mydset.setExtent(rect) #provider.reloadData() ###################################### ######################################## # did not change extent, loaded data #rect = QgsRectangle(326380.0,4103390.0-2853,326380.0+1332,4103390.0) #context = QgsRenderContext() #context.setExtent(rect) #renderer = mydset.createMapRenderer(context) #renderer.render() ######################################### ########################################### # did not change extent, loaded data #rect = QgsRectangle(326380.0,4103390.0-2853,326380.0+1332,4103390.0) #mydset.dataProvider().block(52, rect, 1332, 2853) ########################################## ############################################# # did not change extent, loaded data #rect = QgsRectangle(326380.0,4103390.0-2853,326380.0+1332,4103390.0) #mydset.dataProvider().block(426, rect, 1332, 2853) ############################################### ################################################# # changed extent but overwrote to no data #rect = QgsRectangle(326380.0,4103390.0-2853,326380.0+1332,4103390.0) #mydset.setExtent(rect) #mydset.dataProvider().reload() #################################################### #################################################### # changed extent but overwrote to no data #rect = QgsRectangle(326380.0,4103390.0-2853,326380.0+1332,4103390.0) #mydset.setExtent(rect) #mydset.dataProvider().block(52, rect, 1332, 2853) #mydset.dataProvider().reload() ##################################################### ############################################# # not setting new cloned data provider correctly # method wants QString object but gets meaningless string #rect = QgsRectangle(326380.0,4103390.0-2853,326380.0+1332,4103390.0) #provider = mydset.dataProvider() #print 'Provider: ' #print provider #clone = provider.clone() #print 'Provider clone: ' #print clone #clone.block(1, rect, 1332, 2853) #mydset.setDataProvider(str(clone)) #print 'New provider: ' #print mydset.dataProvider() ############################################## ######## printing result of extent changes print 'Extent after: ' print mydset.extent().toString() ################################### ####################################### Trials of setting proper extent end here #### to set proper Coordinate Reference System (crs) info crs = mydset.crs() crs.createFromId(32611) mydset.setCrs(crs) ### this was josh's recommendation #mycrs = QgsCoordinateReferenceSystem(32611) #self.iface.mapCanvas().mapRenderer().setDestinationCrs(mycrs) #### to set raster bands to load as RGB mydset.renderer().setGreenBand(34) mydset.renderer().setRedBand(52) mydset.renderer().setBlueBand(18) ####### Tristan changes #myrenderer = mydset.renderer() #print 'Renderer Type: ' #print mydset.renderer().type() # print 'Renderer block before: ' #print myrenderer.block(426, rect, 1, 1) #myrenderer.block(426, rect, 1, 1) #print 'Renderer block after: ' #print myrenderer.block() not enough arguments #if hasattr(mydset, "setCacheImage"): #mydset.setCacheImage(None) #mydset.triggerRepaint() #mydset.dataProvider().reloadData() #mydset.triggerRepaint() #self.iface.legendInterface().refreshLayerSymbology(mydset) #mydset.reload() #mydset.reloadData() #mydset.triggerRepaint() #mydset.draw() #print 'Extent: ' #print mydset.extent().toString() # ident = rlayer.dataProvider().identify(QgsPoint(15.30, 40.98), \ # QgsRaster.IdentifyFormatValue) # if ident.isValid(): # print ident.results() ####### End Tristan changes #### to add selected dataset/raster to map canvas QgsMapLayerRegistry.instance().addMapLayer(mydset) #canvas=QgsMapCanvas() #canvas.show() #canvas.setExtent(mydset.extent()) #canvas.setLayerSet([QgsMapCanvasLayer(mydset)]) ####################################### Script for getting all raster values # takes 11 minutes to run on (426,1332,2583) #list = [] #for x in range(mydset.width()): #x_coord = x #print 'Doing ' +str(x) + 'x right now...' #for y in range(mydset.height()): #y_coord = y #ident = mydset.dataProvider().identify(QgsPoint(x_coord, y_coord), \ #QgsRaster.IdentifyFormatValue) #list.append(ident.results().values()) #print 'Length of list is: ' #print len(list) #print 'Length of list[0] is: ' #print len(list[0]) ############################################ #if ident.isValid(): #print ident.results()
class BBOXDialog(QDialog, FORM_CLASS): def __init__(self, inp_sparql, triplestoreconf, endpointIndex): super(QDialog, self).__init__() self.setupUi(self) self.inp_sparql = inp_sparql self.triplestoreconf = triplestoreconf self.endpointIndex = endpointIndex self.vl = QgsVectorLayer("Point", "temporary_points", "memory") self.map_canvas = QgsMapCanvas(self) self.layerExtentOrBBOX = False self.map_canvas.setMinimumSize(500, 475) uri = "url=http://a.tile.openstreetmap.org/{z}/{x}/{y}.png&zmin=0&type=xyz" self.mts_layer = QgsRasterLayer(uri, 'OSM', 'wms') if not self.mts_layer.isValid(): print("Layer failed to load!") self.rect_tool = RectangleMapTool(self.map_canvas) self.map_canvas.setMapTool(self.rect_tool) self.map_canvas.setExtent(self.mts_layer.extent()) self.map_canvas.setLayers([self.vl, self.mts_layer]) self.map_canvas.setCurrentLayer(self.mts_layer) #chooseLayerLabel=QLabel("Choose Layer Extent:",self) #chooseLayerLabel.move(0,480) #self.chooseBBOXLayer=QComboBox(self) #self.chooseBBOXLayer.move(150,475) #b2 = QPushButton("Apply Layer Extent",self) #b2.move(10,500) self.b2.clicked.connect(self.setBBOXExtentQuery) layers = QgsProject.instance().layerTreeRoot().children() for layer in layers: self.chooseBBOXLayer.addItem(layer.name()) #b1 = QPushButton("Apply BBOX",self) #b1.move(400,500) self.b1.clicked.connect(self.setBBOXInQuery) def setBBOXExtentQuery(self): self.mts_layer = QgsProject.instance().layerTreeRoot().children()[ self.chooseBBOXLayer.currentIndex()].layer() self.layerExtentOrBBOX = True self.setBBOXInQuery() def setBBOXInQuery(self): if self.layerExtentOrBBOX: xMax = self.mts_layer.extent().xMaximum() xMin = self.mts_layer.extent().xMinimum() yMin = self.mts_layer.extent().yMinimum() yMax = self.mts_layer.extent().yMaximum() pointt1 = QgsGeometry.fromPointXY(QgsPointXY(xMax, yMin)) pointt2 = QgsGeometry.fromPointXY(QgsPointXY(xMin, yMin)) pointt3 = QgsGeometry.fromPointXY(QgsPointXY(xMin, yMax)) pointt4 = QgsGeometry.fromPointXY(QgsPointXY(xMax, yMax)) sourceCrs = QgsCoordinateReferenceSystem( self.mts_layer.sourceCrs()) else: pointt1 = QgsGeometry.fromWkt(self.rect_tool.point1.asWkt()) pointt2 = QgsGeometry.fromWkt(self.rect_tool.point2.asWkt()) pointt3 = QgsGeometry.fromWkt(self.rect_tool.point3.asWkt()) pointt4 = QgsGeometry.fromWkt(self.rect_tool.point4.asWkt()) sourceCrs = QgsCoordinateReferenceSystem(self.mts_layer.crs()) destCrs = QgsCoordinateReferenceSystem(4326) tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance()) pointt1.transform(tr) pointt2.transform(tr) pointt3.transform(tr) pointt4.transform(tr) polygon = QgsGeometry.fromPolylineXY([ pointt1.asPoint(), pointt2.asPoint(), pointt3.asPoint(), pointt4.asPoint() ]) center = polygon.centroid() #distance = QgsDistanceArea() #distance.setSourceCrs(destCrs) #distance.setEllipsoidalMode(True) #distance.setEllipsoid('WGS84') widthm = 100 #distance.measureLine(pointt1, pointt2) self.curbbox = [] self.curbbox.append(pointt1) self.curbbox.append(pointt2) self.curbbox.append(pointt3) self.curbbox.append(pointt4) self.close() curquery = self.inp_sparql.toPlainText() if "bboxquery" in self.triplestoreconf[ self.endpointIndex] and self.triplestoreconf[ self.endpointIndex]["bboxquery"]["type"] == "minmax": curquery = curquery[0:curquery.rfind('}')] + self.triplestoreconf[ self.endpointIndex]["bboxquery"]["query"].replace( "%%minPoint%%", pointt2.asWkt()).replace( "%%maxPoint%%", pointt4.asWkt()) + curquery[curquery.rfind('}') + 1:] elif "bboxquery" in self.triplestoreconf[ self.endpointIndex] and self.triplestoreconf[ self. endpointIndex]["bboxquery"]["type"] == "pointdistance": curquery = curquery[0:curquery.rfind('}')] + self.triplestoreconf[ self.endpointIndex]["bboxquery"]["query"].replace( "%%lat%%", str(center.asPoint().y())).replace( "%%lon%%", str(center.asPoint().x())).replace( "%%distance%%", str(widthm / 1000)) + curquery[curquery.rfind('}') + 1:] self.inp_sparql.setPlainText(curquery)
class OptimizerQGisCase(unittest.TestCase): def setUp(self): """Set the input layers and the output directory """ input_v_layer_path = '.\\test_data\\line_4_road_design.shp' self.input_v_layer = QgsVectorLayer(input_v_layer_path, 'input_path', 'ogr') input_dtm_path = '.\\test_data\\dtm_h242_25830_5_metros_clip.tif' self.input_dtm = QgsRasterLayer(input_dtm_path, 'dtm_5m') exclusion_areas_path = \ '.\\test_data\\excluded_areas\\exclusion_areas_file.shp' self.exclusion_areas_layer = QgsVectorLayer(exclusion_areas_path, 'exclusion_areas', 'ogr') self.empty_layer = QgsVectorLayer( 'Line?crs={}'.format(self.input_dtm.crs().toWkt()), "Vacia", 'memory') self.outputfolder = 'C:\\ForestRoadDesigner\\pruebas' QgsProject.instance().addMapLayer(self.input_v_layer) QgsProject.instance().addMapLayer(self.input_dtm) QgsProject.instance().addMapLayer(self.exclusion_areas_layer) def test_coords_and_indexes(self): """Test conversion between coordinates and indexes """ waypoints_coords_list = af.waypoints_list(self.input_v_layer) wpts_index_array, ds_geotransform = af.coord_to_index( self.input_dtm, waypoints_coords_list) q_coords = af.index_to_coord(ds_geotransform, wpts_index_array) np.testing.assert_allclose(np.array(waypoints_coords_list), q_coords) def test_bounds_check(self): """Test if input data (layers) are in dtm extension limits """ self.assertTrue( inputs_checker.check_bounds(self.input_dtm, self.input_v_layer)) self.assertFalse( inputs_checker.check_bounds(self.input_v_layer, self.input_dtm)) def testVectorLayer(self): """ """ v_layer_feat = self.input_v_layer.getFeatures() points_coords_list = [] for elem in v_layer_feat: geom = elem.geometry() point = geom.asPoint() points_coords_list.append([point.x(), point.y()]) self.assertNotEqual(len(points_coords_list), 0) def test_raster_2_array(self): """Testing raster 2 array function """ dtm_array = af.raster_2_array(self.input_dtm) self.assertEqual(dtm_array.shape, (136, 176)) def testBestPathFinder(self): """Test full process to obtain layers (points and Lines layers) """ import tempfile outputFolder = tempfile.mkdtemp("frd") polylineThreshold = 5 parameters = { "min_slope_pct": 0, "max_slope_pct": 10, "semi_size": 2, "penalty_factor_xy": 40, "penalty_factor_z": 40 } finder = oq.BestPathFinder(self.input_dtm, self.exclusion_areas_layer) finder.set_parameters(parameters) finder.set_output_folder(outputFolder) raw_layer = finder.create_raw_output_layer() simplified_layer = finder.create_simplified_output_layer( polylineThreshold) for point_index in af.waypoints_list(self.input_v_layer): finder.add_segment_to(point_index) self.assertEqual(raw_layer.dataProvider().featureCount(), 179) self.assertTrue(simplified_layer.isValid()) def test_checkAttrsValues(self): """Test for layers attributes """ import tempfile outputFolder = tempfile.mkdtemp("frd") polylineThreshold = 0 parameters = { "min_slope_pct": 0.5, "max_slope_pct": 10, "semi_size": 2, "penalty_factor_xy": 40, "penalty_factor_z": 40 } # finder = oq.BestPathFinder(self.input_dtm, self.exclusion_areas_layer) finder = oq.BestPathFinder(self.input_dtm) finder.set_parameters(parameters) finder.set_output_folder(outputFolder) _ = finder.create_raw_output_layer() simplified_layer = finder.create_simplified_output_layer( polylineThreshold) height_prof, slope_profile, _ = viewers.height_profile( finder.dtm["array"], finder.optimizer.waypoints_index(), finder.parameters["max_slope_pct"] / 100.0, finder.converter.pixel_width) self.assertEqual( len(slope_profile) - 1, simplified_layer.dataProvider().featureCount()) feats = simplified_layer.dataProvider().getFeatures() for row_id, vals in enumerate(zip(feats, slope_profile[1:])): f, s = vals for att_id, a in enumerate(f.attributes()): with self.assertRaises(AttributeError): a.isNull() self.assertAlmostEqual(s * 100.0, f.attribute("slope_p")) self.assertTrue( abs(f.attribute("slope_p")) <= parameters["max_slope_pct"]) self.assertTrue( abs(f.attribute("slope_p")) >= parameters["min_slope_pct"]) def test_empty_waypoints(self): """Test for empty layer """ import tempfile outputFolder = tempfile.mkdtemp("frd") parameters = { "min_slope_pct": 0, "max_slope_pct": 10, "semi_size": 2, "penalty_factor_xy": 40, "penalty_factor_z": 40 } finder = oq.BestPathFinder(self.input_dtm, self.exclusion_areas_layer) finder.set_parameters(parameters) finder.set_output_folder(outputFolder) finder.create_raw_output_layer() simp_layer = finder.create_simplified_output_layer(5) self.assertEqual(simp_layer.featureCount(), 0) def testExclusionUtility(self): """Test if exclusion utility is working """ import tempfile from qgis.core import Qgis outputFolder = tempfile.mkdtemp("frd") parameters = { "min_slope_pct": 0, "max_slope_pct": 10, "semi_size": 2, "penalty_factor_xy": 40, "penalty_factor_z": 40 } finder = oq.BestPathFinder(self.input_dtm, self.exclusion_areas_layer) finder.set_parameters(parameters) finder.set_output_folder(outputFolder) raw_layer = finder.create_raw_output_layer() for point_index in af.waypoints_list(self.input_v_layer): finder.add_segment_to(point_index) raw_layer = finder.create_raw_output_layer() self.assertTrue(raw_layer) provider = raw_layer.dataProvider().getFeatures() puntos_geom = [] for elem in provider: geom2 = elem.geometry() if geom2.wkbType() == Qgis.WKBPoint: puntos_geom.append(geom2) exc_provider = self.exclusion_areas_layer.dataProvider().getFeatures() exc_geoms = [] for elem in exc_provider: geom1 = elem.geometry() exc_geoms.append(geom1) contenido = [] for elem_exc in self.exclusion_areas_layer.dataProvider().getFeatures( ): for elem in raw_layer.dataProvider().getFeatures(): geom2 = elem.geometry() geom1 = elem_exc.geometry() if geom1.contains(geom2): contenido.append(geom2) self.assertEqual(contenido, []) def tearDown(self): QgsProject.instance().removeMapLayer(self.input_v_layer) QgsProject.instance().removeMapLayer(self.input_dtm) QgsProject.instance().removeMapLayer(self.exclusion_areas_layer)
def layerSubsetSave(rasterLayer: QgsRasterLayer, domainLayer: QgsVectorLayer, subsetName: str) -> None: """Description: Processes a raster image into a vector polygon ocean/land mask. Make sure to save the shapefile, as it will be deleted otherwise! Input: QgsRasterLayer rasterLayer - layer that contains the raster image to process QgsVectorLayer domainLayer - layer that contains a polygon specifying the bounds of the raster image to process string name - output file name. Output: QgsRasterLayer, QgsVectorLayer - objects referencing the new mask layers """ # Get basic file name information on geotiff, raster image, masked raster subset image, and masked vector subset shp file fileSource = rasterLayer.source() fileInfo = QFileInfo(fileSource) fileName = fileInfo.baseName() savePaths = getSavePaths(fileSource, domainLayer, 'tif') subsetPath = savePaths + '/' + subsetName + '.tif' # Load geotiff and get domain layer/bounding box of area to mask geotiff = gdal.Open(fileSource) feature = domainLayer.getFeature(0) domain = feature.geometry().boundingBox() prj = geotiff.GetProjection() srs = osr.SpatialReference(wkt=prj) if srs.GetAttrValue("PROJCS|AUTHORITY", 1) is not None: epsgCode = srs.GetAttrValue("PROJCS|AUTHORITY", 1) elif srs.GetAttrValue("AUTHORITY", 1) is not None: epsgCode = srs.GetAttrValue("AUTHORITY", 1) else: epsgCode = str(32621) rasterCRS = "EPSG:" + epsgCode crs = rasterLayer.crs() crs.createFromId(int(epsgCode)) rasterLayer.setCrs(crs) rasterLayer.triggerRepaint() #rasterCRS = rasterLayer.crs().authid() domainCRS = domainLayer.crs().authid() bounds = geotiffWorldToPixelCoords(geotiff, domain, rasterCRS, domainCRS) band = geotiff.GetRasterBand(1) img_full = band.ReadAsArray(0, 0, geotiff.RasterXSize, geotiff.RasterYSize) img = img_full[int(round(bounds.yMinimum())):int(round(bounds.yMaximum())), int(round(bounds.xMinimum())):int(round(bounds.xMaximum()))] print('bounds', bounds.yMinimum(), bounds.yMaximum(), bounds.xMinimum(), bounds.xMaximum()) print('img.shape', img.shape, 'img_full.shape', img_full.shape) print("img min/max/mean:", img.min(), img.max(), np.mean(img, axis=(0, 1))) img = (img.astype(np.float32) / img.max() * 65535).astype(np.uint16) print("after img min/max/mean:", img.min(), img.max(), np.mean(img, axis=(0, 1))) # print('Save subset:', subsetPath, resolve('landsat_raw/' + domainLayer.name() + '/' + subsetName + '.png')) if not DRY_RUN: arrayToRaster(img, geotiff, bounds, subsetPath) imsave( resolve('landsat_raw/' + domainLayer.name() + '/' + subsetName + '.png'), img) # imsave(resolve('small/' + domainLayer.name() + '/' + subsetName + '.png'), img) # imsave(os.path.join(r'D:\Daniel\Documents\Github\CALFIN Repo\reprocessing\images_1024', domainLayer.name(), subsetName + '.png'), img) try: #Gather BQA info fileSourceBQA = fileSource[:-7] + '_BQA.TIF' #Save BQA subset geotiffBQA = gdal.Open(fileSourceBQA) imgBQA = geotiffBQA.GetRasterBand(1) imgBQA = imgBQA.ReadAsArray(0, 0, geotiffBQA.RasterXSize, geotiffBQA.RasterYSize).astype(np.uint16) imgBQA = imgBQA[ int(round(bounds.yMinimum())):int(round(bounds.yMaximum())), int(round(bounds.xMinimum())):int(round(bounds.xMaximum()))] # print('Save BQA subset:', subsetPathBQA, resolve('landsat_raw/' + domainLayer.name() + '/' + subsetName + '_bqa.png')) if not DRY_RUN: # arrayToRaster(imgBQA, geotiffBQA, bounds, subsetPathBQA) # print(fileSourceBQA, geotiffBQA.RasterXSize, geotiffBQA.RasterYSize) # print(int(round(bounds.yMinimum())), int(round(bounds.yMaximum())), int(round(bounds.xMinimum())), int(round(bounds.xMaximum()))) # imsave(resolve('landsat_raw/' + domainLayer.name() + '/' + subsetName + '_bqa.png'), imgBQA) pass #Gather MTL info fileSourceMTL = fileSource[:-7] + '_MTL.txt' #Save MTL subset if not DRY_RUN: image_feats = [''] * 6 with open(fileSourceMTL, 'r') as image_feats_source_file: lines = image_feats_source_file.readlines() for line in lines: if 'SUN_AZIMUTH =' in line: image_feats[0] = line.strip() elif 'SUN_ELEVATION =' in line: image_feats[1] = line.strip() elif 'CLOUD_COVER ' in line: image_feats[2] = line.strip() elif 'CLOUD_COVER_LAND ' in line: image_feats[3] = line.strip() elif 'DATE_ACQUIRED =' in line: image_feats[4] = line.strip() elif 'GRID_CELL_SIZE_REFLECTIVE =' in line: image_feats[5] = line.strip() savePath = resolve('landsat_raw/' + domainLayer.name() + '/' + subsetName + '_mtl.txt') with open(savePath, 'w') as image_feats_dest_file: for line in image_feats: image_feats_dest_file.write(str(line) + '\n') except: print('No BQA/MTL found for:', subsetName) return img.shape
def domainInRaster(rasterLayer: QgsRasterLayer, domainLayer: QgsVectorLayer) -> bool: """Returns bool if domain is within bounds of geotiff in rasterLayer :param rasterLayer: QgsRasterLayer :param domainLayer: QgsVectorLayer """ # Get basic file name information on geotiff, raster image, masked raster subset image, and masked vector subset shp file fileSource = rasterLayer.source() # Load geotiff and get domain layer/bounding box of area to mask geotiff = gdal.Open(fileSource) feature = domainLayer.getFeature(0) domain = feature.geometry().boundingBox() prj = geotiff.GetProjection() srs = osr.SpatialReference(wkt=prj) if srs.GetAttrValue("PROJCS|AUTHORITY", 1) is not None: epsgCode = srs.GetAttrValue("PROJCS|AUTHORITY", 1) elif srs.GetAttrValue("AUTHORITY", 1) is not None: epsgCode = srs.GetAttrValue("AUTHORITY", 1) else: epsgCode = str(32621) rasterCRS = "EPSG:" + epsgCode crs = rasterLayer.crs() crs.createFromId(int(epsgCode)) domainCRS = domainLayer.crs().authid() bounds = geotiffWorldToPixelCoords(geotiff, domain, rasterCRS, domainCRS) #Gather BQA info fileSourceBQA = fileSource[:-7] + '_BQA.TIF' #Save BQA subset geotiffBQA = gdal.Open(fileSourceBQA) minX = int(round(bounds.yMinimum())) maxX = int(round(bounds.yMaximum())) minY = int(round(bounds.xMinimum())) maxY = int(round(bounds.xMaximum())) if minX < 0 or maxX > geotiff.RasterXSize or maxX > geotiffBQA.RasterXSize or minY < 0 or maxY > geotiff.RasterYSize or maxY > geotiffBQA.RasterYSize: return False else: #Check image is above Nodata percentage threshold band = geotiff.GetRasterBand(1) # Get raster statistics stats = band.GetStatistics(True, True) min_value, max_value = stats[0], stats[1] img_full = band.ReadAsArray(0, 0, geotiff.RasterXSize, geotiff.RasterYSize) img = img_full[ int(round(bounds.yMinimum())):int(round(bounds.yMaximum())), int(round(bounds.xMinimum())):int(round(bounds.xMaximum()))] if img.shape[0] == 0 or img.shape[1] == 0: geotiff = None geotiffBQA = None print('Skipping: not in domain') return False noDataValue = 0.0 # print(min_value, max_value, img.shape) noDataValueThreshold = noDataValue + (max_value - min_value) * 0.006 noDataCount = np.sum(img < noDataValue + noDataValueThreshold) percentNoData = noDataCount / img.size # print('percentNoData', percentNoData, 'noDataCount', noDataCount, 'noDataValueThreshold', noDataValueThreshold) if percentNoData > nodata_threshold: geotiff = None geotiffBQA = None print('Skipping: Nodata percentage above threshold:', percentNoData, ' > ', nodata_threshold) return False #Check image is above cloud percentage threshold bandBQA = geotiffBQA.GetRasterBand(1) imgBQA = bandBQA.ReadAsArray(minX, minY, maxX - minX, maxY - minY).astype(np.uint16) print('warning: check cloud mask parameters for MSS! (year < 1985)') masked = imgBQA & maskClouds cloudCount = np.sum(masked) percentCloud = cloudCount / 8.0 / imgBQA.size if percentCloud > cloud_threshold: geotiff = None geotiffBQA = None print('Skipping: Cloud percentage above threshold:', percentCloud, ' > ', cloud_threshold) return False geotiff = None geotiffBQA = None return True