def write(self, theRasterName): print(theRasterName) path = "%s/%s" % (self.testDataDir, theRasterName) rasterLayer = QgsRasterLayer(path, "test") if not rasterLayer.isValid(): return False provider = rasterLayer.dataProvider() tmpFile = QTemporaryFile() tmpFile.open() # fileName is no avialable until open tmpName = tmpFile.fileName() tmpFile.close() # do not remove when class is destroyed so that we can read # the file and see difference tmpFile.setAutoRemove(False) fileWriter = QgsRasterFileWriter(tmpName) pipe = QgsRasterPipe() if not pipe.set(provider.clone()): print("Cannot set pipe provider") return False projector = QgsRasterProjector() projector.setCrs(provider.crs(), provider.crs()) if not pipe.insert(2, projector): print("Cannot set pipe projector") return False fileWriter.writeRaster(pipe, provider.xSize(), provider.ySize(), provider.extent(), provider.crs()) checker = QgsRasterChecker() ok = checker.runTest("gdal", tmpName, "gdal", path) self.report += checker.report() # All OK, we can delete the file tmpFile.setAutoRemove(ok) return ok
def testExportToGpkgWithExtraExtent(self): tmpName = tempfile.mktemp(suffix='.gpkg') source = QgsRasterLayer( os.path.join(self.testDataDir, 'raster', 'band3_byte_noct_epsg4326.tif'), 'my', 'gdal') self.assertTrue(source.isValid()) provider = source.dataProvider() fw = QgsRasterFileWriter(tmpName) fw.setOutputFormat('gpkg') pipe = QgsRasterPipe() self.assertTrue(pipe.set(provider.clone())) self.assertEqual( fw.writeRaster(pipe, provider.xSize() + 4, provider.ySize() + 4, QgsRectangle(-3 - 2, -4 - 2, 7 + 2, 6 + 2), provider.crs()), 0) del fw # Check that the test geopackage contains the raster layer and compare rlayer = QgsRasterLayer(tmpName) self.assertTrue(rlayer.isValid()) out_provider = rlayer.dataProvider() for i in range(3): src_data = provider.block(i + 1, provider.extent(), source.width(), source.height()) out_data = out_provider.block(i + 1, provider.extent(), source.width(), source.height()) self.assertEqual(src_data.data(), out_data.data()) out_data = out_provider.block(1, QgsRectangle(7, -4, 7 + 2, 6), 2, 8) # band3_byte_noct_epsg4326 nodata is 255 self.assertEqual(out_data.data().data(), b'\xff' * 2 * 8) del out_provider del rlayer # remove result file os.unlink(tmpName)
def testImportIntoGpkg(self): # init target file test_gpkg = tempfile.mktemp(suffix='.gpkg', dir=self.testDataDir) gdal.GetDriverByName('GPKG').Create(test_gpkg, 1, 1, 1) source = QgsRasterLayer( os.path.join(self.testDataDir, 'raster', 'band3_byte_noct_epsg4326.tif'), 'my', 'gdal') self.assertTrue(source.isValid()) provider = source.dataProvider() fw = QgsRasterFileWriter(test_gpkg) fw.setOutputFormat('gpkg') fw.setCreateOptions( ['RASTER_TABLE=imported_table', 'APPEND_SUBDATASET=YES']) pipe = QgsRasterPipe() self.assertTrue(pipe.set(provider.clone())) projector = QgsRasterProjector() projector.setCrs(provider.crs(), provider.crs()) self.assertTrue(pipe.set(projector)) self.assertEqual( fw.writeRaster(pipe, provider.xSize(), provider.ySize(), provider.extent(), provider.crs()), 0) # Check that the test geopackage contains the raster layer and compare rlayer = QgsRasterLayer('GPKG:%s:imported_table' % test_gpkg) self.assertTrue(rlayer.isValid()) out_provider = rlayer.dataProvider() for i in range(3): src_data = provider.block(i + 1, provider.extent(), source.width(), source.height()) out_data = out_provider.block(i + 1, out_provider.extent(), rlayer.width(), rlayer.height()) self.assertEqual(src_data.data(), out_data.data()) # remove result file os.unlink(test_gpkg)
def _testGeneratePyramids(self, pyramidFormat): tmpName = tempfile.mktemp(suffix='.tif') source = QgsRasterLayer(os.path.join(self.testDataDir, 'raster', 'byte.tif'), 'my', 'gdal') self.assertTrue(source.isValid()) provider = source.dataProvider() fw = QgsRasterFileWriter(tmpName) fw.setBuildPyramidsFlag(QgsRaster.PyramidsFlagYes) fw.setPyramidsFormat(pyramidFormat) fw.setPyramidsList([2]) pipe = QgsRasterPipe() self.assertTrue(pipe.set(provider.clone())) projector = QgsRasterProjector() projector.setCrs(provider.crs(), provider.crs()) self.assertTrue(pipe.set(projector)) self.assertEqual(fw.writeRaster(pipe, provider.xSize(), provider.ySize(), provider.extent(), provider.crs()), 0) del fw ds = gdal.Open(tmpName) self.assertEqual(ds.RasterCount, 1) self.assertEqual(ds.GetRasterBand(1).Checksum(), 4672) self.assertEqual(ds.GetRasterBand(1).GetOverviewCount(), 1) fl = ds.GetFileList() if pyramidFormat == QgsRaster.PyramidsGTiff: self.assertEqual(len(fl), 2, fl) self.assertIn('.ovr', fl[1]) elif pyramidFormat == QgsRaster.PyramidsInternal: self.assertEqual(len(fl), 1, fl) elif pyramidFormat == QgsRaster.PyramidsErdas: self.assertEqual(len(fl), 2, fl) self.assertIn('.aux', fl[1]) os.unlink(tmpName)
def read_from_qgis_native(self, qgis_layer): """Read raster data from qgis layer QgsRasterLayer. A stub is used now: save all data in a file, then call safe.read_from_file Raises: * TypeError if qgis is not avialable * IOError if can't store temporary file * GetDataError if can't create copy of qgis_layer's dataProvider """ if not qgis_imported: # FIXME (DK): this branch isn't covered by test msg = ('Used data is QgsRasterLayer instance, ' 'but QGIS is not available.') raise TypeError(msg) base_name = unique_filename() file_name = base_name + '.tif' file_writer = QgsRasterFileWriter(file_name) pipe = QgsRasterPipe() provider = qgis_layer.dataProvider() if not pipe.set(provider.clone()): msg = "Cannot set pipe provider" raise GetDataError(msg) file_writer.writeRaster( pipe, provider.xSize(), provider.ySize(), provider.extent(), provider.crs()) # Write keywords if any write_keywords(self.keywords, base_name + '.keywords') self.read_from_file(file_name)
def testFail(self): """test error 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("/this/is/invalid/file.tif") writer = QgsRasterFileWriter(tmp) task = QgsRasterFileWriterTask(writer, pipe, 100, 100, raster_layer.extent(), raster_layer.crs(), QgsCoordinateTransformContext()) 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.assertFalse(self.success) self.assertTrue(self.fail)
def create_rgb(self, raster_layer, output): '''Render and write RGB file Parameters ---------- raster_layer : QgsRasterLayer input raster layer with singleband pseudocolor output : str output file path Returns ------- error : boolean 0/1 - no error/error result : str or None output or error msg if error == 1 ''' # get raster_layer properties extent = raster_layer.extent() width, height = raster_layer.width(), raster_layer.height() renderer = raster_layer.renderer() provider = raster_layer.dataProvider() crs_raster = raster_layer.crs() # create pipe for export pipe = QgsRasterPipe() pipe.set(provider.clone()) pipe.set(renderer.clone()) # create FileWriter and write file fwriter = QgsRasterFileWriter(output) error = fwriter.writeRaster(pipe, width, height, extent, crs_raster) if error != fwriter.NoError: return 1, 'RGB file could not be rendered!' return 0, output
def clip_raster(raster, n_cols, n_rows, output_extent): """Clip raster to specified extent, width and height. Note there is similar utility in safe_qgis.utilities.clipper, but it uses gdal whereas this one uses native QGIS. :param raster: Raster :type raster: QgsRasterLayer :param n_cols: Desired width in pixels of new raster :type n_cols: Int :param n_rows: Desired height in pixels of new raster :type n_rows: Int :param output_extent: Extent of the clipped region :type output_extent: QgsRectangle :returns: Clipped region of the raster :rtype: QgsRasterLayer """ provider = raster.dataProvider() pipe = QgsRasterPipe() pipe.set(provider.clone()) base_name = unique_filename() file_name = base_name + '.tif' file_writer = QgsRasterFileWriter(file_name) file_writer.writeRaster( pipe, n_cols, n_rows, output_extent, raster.crs()) return QgsRasterLayer(file_name, 'clipped_raster')
def testWriteAsRawGS7BG(self): ''' Test that despite writing a Byte raster, we correctly handle GS7BG creating a Float64 ''' tmpName = tempfile.mktemp(suffix='.grd') source = QgsRasterLayer(os.path.join(self.testDataDir, 'raster', 'byte.tif'), 'my', 'gdal') self.assertTrue(source.isValid()) provider = source.dataProvider() fw = QgsRasterFileWriter(tmpName) fw.setOutputFormat('GS7BG') pipe = QgsRasterPipe() self.assertTrue(pipe.set(provider.clone())) self.assertEqual(fw.writeRaster(pipe, provider.xSize(), provider.ySize(), provider.extent(), provider.crs()), QgsRasterFileWriter.NoError) del fw ds = gdal.Open(tmpName) self.assertEqual(ds.RasterCount, 1) self.assertEqual(ds.GetRasterBand(1).Checksum(), 4672) ds = None os.unlink(tmpName)
def write_raster(raster_layer, raster_writer, write_path): """Write raster to specified file and update the layer's data source.""" dp = raster_layer.dataProvider() pipe = QgsRasterPipe() if not pipe.set(dp.clone()): raise PackagingError( f"Couldn't set raster pipe projector for layer {write_path}") projector = QgsRasterProjector() projector.setCrs(raster_layer.crs(), raster_layer.crs()) if not pipe.insert(2, projector): raise PackagingError( f"Couldn't set raster pipe provider for layer {write_path}") res = raster_writer.writeRaster(pipe, dp.xSize(), dp.ySize(), dp.extent(), raster_layer.crs()) if not res == QgsRasterFileWriter.NoError: raise PackagingError( f"Couldn't save raster {write_path} - write error: {res}") provider_opts = QgsDataProvider.ProviderOptions() provider_opts.layerName = raster_layer.name() raster_layer.setDataSource(write_path, raster_layer.name(), "gdal", provider_opts)
def exportRasterLayer(self, layer, destinationFile, options=None): outputFormat = self.settings[ 'rasterFormat'] if 'rasterFormat' in self.settings else 'GTiff' if os.path.splitext(destinationFile)[1] == '': formats = QgsRasterFileWriter.extensionsForFormat(outputFormat) if len(formats) > 0: destinationFile = '{}.{}'.format(destinationFile, formats[0]) provider = layer.dataProvider() cols = provider.xSize() rows = provider.ySize() if not provider.capabilities() & QgsRasterDataProvider.Size: k = float(provider.extent().width()) / float( provider.extent().height()) cols = RASTER_SIZE * k rows = RASTER_SIZE pipe = QgsRasterPipe() if not pipe.set(provider.clone()): QgsMessageLog.logMessage( self. tr('Failed to export layer "{layer}": Cannot set pipe provider.' ).format(layer=layer.name()), 'QConsolidate', Qgis.Warning) return False, None nodata = {} for i in range(1, provider.bandCount() + 1): if provider.sourceHasNoDataValue(i): value = provider.sourceNoDataValue(i) nodata[i] = QgsRasterRange(value, value) nuller = QgsRasterNuller() for band, value in nodata.items(): nuller.setNoData(band, [value]) if not pipe.insert(1, nuller): QgsMessageLog.logMessage( self.tr( 'Failed to export layer "{layer}": Cannot set pipe nuller.' ).format(layer=layer.name()), 'QConsolidate', Qgis.Warning) return False, None writer = QgsRasterFileWriter(destinationFile) writer.setOutputFormat(outputFormat) if options is not None: writer.setCreateOptions(options) success = True error = writer.writeRaster(pipe, cols, rows, provider.extent(), provider.crs()) if error != QgsRasterFileWriter.NoError: QgsMessageLog.logMessage( self.tr('Failed to export layer "{layer}": {message}.').format( layer=layer.name(), message=error), 'QConsolidate', Qgis.Warning) success = False return success, destinationFile
def styleRaster(filename): # Create outfile name outfile = "".join(filename.strip().split('.raw')) # Open layer from filename rasterfile = filename.strip().split('/')[-1] rasterlayer = rasterfile.split('.')[0] rlayer = QgsRasterLayer(filename, rasterlayer, 'gdal') # Check if layer is valid if rlayer.isValid() is True: # Get layer data provider provider = rlayer.dataProvider() # Calculate histrogram provider.initHistogram(QgsRasterHistogram(), 1, 100) hist = provider.histogram(1) # Get histograms stats nbins = hist.binCount minv = hist.minimum maxv = hist.maximum # Create histogram array, bin array, and histogram index hista = np.array(hist.histogramVector) bins = np.arange(minv, maxv, (maxv - minv) / nbins) index = np.where(hista > 5) # Get bottom and top color values from bin values bottomcolor = bins[index[0][0]] topcolor = bins[index[0][-1]] # Calculate range value between the bottom and top color values if bottomcolor < 0: vrange = topcolor + bottomcolor else: vrange = topcolor - bottomcolor # Calculate values for bottom middle, and top middle color values if rasterlayer == 'maxele': bottommiddle = vrange * 0.3333 topmiddle = vrange * 0.6667 else: bottommiddle = vrange * 0.375 topmiddle = vrange * 0.75 # Create list of color values valueList = [bottomcolor, bottommiddle, topmiddle, topcolor] # Create color dictionary if rasterlayer == 'maxele': colDic = { 'bottomcolor': '#0000ff', 'bottommiddle': '#00ffff', 'topmiddle': '#ffff00', 'topcolor': '#ff0000' } else: colDic = { 'bottomcolor': '#000000', 'bottommiddle': '#ff0000', 'topmiddle': '#ffff00', 'topcolor': '#ffffff' } # Create color ramp function and add colors fnc = QgsColorRampShader() fnc.setColorRampType(QgsColorRampShader.Interpolated) lst = [QgsColorRampShader.ColorRampItem(valueList[0], QColor(colDic['bottomcolor'])),\ QgsColorRampShader.ColorRampItem(valueList[1], QColor(colDic['bottommiddle'])), \ QgsColorRampShader.ColorRampItem(valueList[2], QColor(colDic['topmiddle'])), \ QgsColorRampShader.ColorRampItem(valueList[3], QColor(colDic['topcolor']))] fnc.setColorRampItemList(lst) # Create raster shader and add color ramp function shader = QgsRasterShader() shader.setRasterShaderFunction(fnc) # Create color render and set opacity renderer = QgsSingleBandPseudoColorRenderer(provider, 1, shader) renderer.setOpacity(0.75) # Get output format output_format = QgsRasterFileWriter.driverForExtension( os.path.splitext(outfile)[1]) # Open output file for writing rfw = QgsRasterFileWriter(outfile) rfw.setOutputProviderKey('gdal') rfw.setOutputFormat(output_format) # Add EPSG 4326 to layer crs crs = QgsCoordinateReferenceSystem() crs.createFromSrid(4326) # Create Raster pipe and set provider and renderer pipe = QgsRasterPipe() pipe.set(provider.clone()) pipe.set(renderer.clone()) # Get transform context transform_context = QgsProject.instance().transformContext() # Write to file rfw.writeRaster(pipe, provider.xSize(), provider.ySize(), provider.extent(), crs, transform_context) logger.info( 'Conveted data in ' + rasterfile + ' from float64 to 8bit, added color palette and saved to tiff (' + outfile.split('/')[-1] + ') file') if not rlayer.isValid(): raise Exception('Invalid raster') return (valueList)
def exportRaster(layer, count, layersFolder, feedback): feedback.showFeedback("Exporting %s to PNG..." % layer.name()) name_ts = (safeName(layer.name()) + unicode(count) + 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 = os.path.join(layersFolder, safeName(layer.name()) + unicode(count) + ".png") qgis_version = QGis.QGIS_VERSION old_stdout = sys.stdout sys.stdout = mystdout = StringIO() try: processing.runalg("gdalogr:warpreproject") except: pass sys.stdout = old_stdout params = { "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 } warpArgs = {} lines = mystdout.getvalue() for count, line in enumerate(lines.split("\n\t")): if count != 0 and line != " ": try: k = line.split(" ")[0] warpArgs[k] = params[k] except: pass 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: procRtn = processing.runalg("gdalogr:warpreproject", warpArgs) 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 Color(self, file_in, calcType=None): """ Color the Inbound file (Essentially the File we JUST exported) and display it to screen) :param file_in: The file that was just exported :type file_in: FileImport :return: TO SCREEN Rendered Image :rtype: None """ k = self.iface.addRasterLayer(file_in.filePath, file_in.baseName) stats = k.dataProvider().bandStatistics(1, QgsRasterBandStats.All, k.extent(), 0) minimum = stats.minimumValue maximum = stats.maximumValue self.com.log("Color func: [Min val: {0} | Max val: {1}".format( str(minimum), str(maximum)), level=0) ramp_shader = QgsColorRampShader() ramp_shader.setColorRampType(QgsColorRampShader.INTERPOLATED) if calcType is None: color_list = [ QgsColorRampShader.ColorRampItem(minimum, QColor(255, 0, 0)), QgsColorRampShader.ColorRampItem(0, QColor(255, 207, 74, 255)), QgsColorRampShader.ColorRampItem(maximum, QColor(0, 255, 0)) ] elif calcType == "EVI": color_list = [ QgsColorRampShader.ColorRampItem(-2, QColor(255, 0, 0)), QgsColorRampShader.ColorRampItem(0, QColor(255, 207, 74, 255)), QgsColorRampShader.ColorRampItem(2, QColor(0, 255, 0)) ] else: color_list = [ QgsColorRampShader.ColorRampItem(minimum, QColor(255, 0, 0)), QgsColorRampShader.ColorRampItem(0, QColor(255, 207, 74, 255)), QgsColorRampShader.ColorRampItem(maximum, QColor(0, 255, 0)) ] ramp_shader.setColorRampItemList(color_list) shader = QgsRasterShader() shader.setRasterShaderFunction(ramp_shader) renderer = QgsSingleBandPseudoColorRenderer(k.dataProvider(), 1, shader) k.setRenderer(renderer) """ Export colored image to file """ export_path = file_in.filePath + ".colored.tif" file_writer = QgsRasterFileWriter(export_path) pipe = QgsRasterPipe() provide = k.dataProvider() # Pipe Setter if not pipe.set(provide.clone()): self.com.error(Bold="PipeProviderError:", String="Cannot set pipe provider", level=1, duration=3) self.com.log( "mainPlug - Color: Pipe provider error on line 473, Continuing...", level=1) self.com.log(str(pipe.renderer()), level=0) pipe.set(renderer.clone()) file_writer.writeRaster(pipe, provide.xSize(), provide.ySize(), provide.extent(), provide.crs())
pcolor = [] pcolor.append(QgsColorRampShader.ColorRampItem(1, QColor("#d2ca97"))) pcolor.append(QgsColorRampShader.ColorRampItem(2, QColor("#f7f7f7"))) pcolor.append(QgsColorRampShader.ColorRampItem(3, QColor("#a1d99b"))) pcolor.append(QgsColorRampShader.ColorRampItem(4, QColor("#41ab5d"))) pcolor.append(QgsColorRampShader.ColorRampItem(5, QColor("#006d2c"))) pcolor.append(QgsColorRampShader.ColorRampItem(6, QColor("#00441b"))) renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 1, QgsPalettedRasterRenderer.colorTableToClassData(pcolor)) layer.setRenderer(renderer) extent = layer.extent() width, height = layer.width(), layer.height() renderer = layer.renderer() provider = layer.dataProvider() crs = layer.crs().toWkt() pipe = QgsRasterPipe() pipe.set(provider.clone()) pipe.set(renderer.clone()) file_writer = QgsRasterFileWriter("C:/temp/naip/classified_res.tif") file_writer.writeRaster(pipe, width, height, extent, layer.crs()) print("Done!")
def response_geotiff_mode(self, request): """ Export raster as geotiff i.e: 192.168.1.137:8006/raster/api/geotiff/qdjango/190/sfondo_clip_c60533a4_743e_4734_9b95_514ac765ec4e/ 192.168.1.137:8006/raster/api/geotiff/qdjango/190/europa_dem_8f0a9c30_5b96_4661_b747_8ce4f2679d6b/?map_extent=10.515901325263899%2C43.875701513907146%2C10.55669628723769%2C43.92294901234999 :param request: Http Django request object :return: http response with attached file """ #if not self.layer.download: # return HttpResponseForbidden() tmp_dir = tempfile.TemporaryDirectory() filename = f"{self.metadata_layer.qgis_layer.name()}.tif" file_path = os.path.join(tmp_dir.name, filename) writer = QgsRasterFileWriter(file_path) provider = self.metadata_layer.qgis_layer.dataProvider() renderer = self.metadata_layer.qgis_layer.renderer() # Check for Url Params if request.query_params.get('map_extent'): me = request.query_params.get('map_extent').split(',') orig_extent =provider.extent() extent = QgsRectangle(float(me[0]), float(me[1]), float(me[2]), float(me[3])) # If crs layer is not equal to project crs if self.reproject: ct = QgsCoordinateTransform( QgsCoordinateReferenceSystem(f'EPSG:{self.layer.project.group.srid.srid}'), self.metadata_layer.qgis_layer.crs(), QgsCoordinateTransformContext() ) extent = ct.transform(extent) # Calc columns and rows cols = int((extent.xMaximum() - extent.xMinimum()) / (orig_extent.xMaximum() - orig_extent.xMinimum()) * provider.xSize()) rows = int((extent.yMaximum() - extent.yMinimum()) / (orig_extent.yMaximum() - orig_extent.yMinimum()) * provider.ySize()) # For cols or rows lower than 0, we have to recalculate extent to guarantee minimal raster cell if cols < 1: cols = 1 new_wide_x_extent = (orig_extent.xMaximum() - orig_extent.xMinimum()) / provider.xSize() off = (new_wide_x_extent - (extent.xMaximum() - extent.xMinimum())) / 2 extent.setXMinimum(extent.xMinimum() - off) extent.setXMaximum(extent.xMaximum() + off) if rows < 1: rows = 1 new_wide_y_extent = (orig_extent.yMaximum() - orig_extent.yMinimum()) / provider.ySize() off = (new_wide_y_extent - (extent.yMaximum() - extent.yMinimum())) / 2 extent.setYMinimum(extent.yMinimum() - off) extent.setYMaximum(extent.yMaximum() + off) else: extent = provider.extent() cols = provider.xSize() rows = provider.ySize() pipe = QgsRasterPipe() pipe.set(provider.clone()) pipe.set(renderer.clone()) error_code = writer.writeRaster( pipe, cols, rows, extent, self.metadata_layer.qgis_layer.crs(), self.metadata_layer.qgis_layer.transformContext() ) if error_code != QgsRasterFileWriter.NoError: tmp_dir.cleanup() raise APIException(f"An error occoured on create raster file for export") # Grab ZIP file from in-memory, make response with correct MIME-type response = HttpResponse( open(file_path, 'rb').read(), content_type='image/tif') response['Content-Disposition'] = f'attachment; filename={filename}' response.set_cookie('fileDownload', 'true') return response
def exportLayers(iface, layers, folder, precision, optimize, popupField, json, restrictToExtent, extent, feedback): canvas = iface.mapCanvas() epsg4326 = QgsCoordinateReferenceSystem("EPSG:4326") layersFolder = os.path.join(folder, "layers") QDir().mkpath(layersFolder) for count, (layer, encode2json, popup) in enumerate(zip(layers, json, popupField)): if (layer.type() == layer.VectorLayer and (layer.providerType() != "WFS" or encode2json)): feedback.showFeedback("Exporting %s to JSON..." % layer.name()) cleanLayer = writeTmpLayer(layer, popup, restrictToExtent, iface, extent) fields = layer.pendingFields() for field in fields: exportImages(layer, field.name(), layersFolder + "/tmp.tmp") if is25d(layer, canvas, restrictToExtent, extent): provider = cleanLayer.dataProvider() provider.addAttributes([ QgsField("height", QVariant.Double), QgsField("wallColor", QVariant.String), QgsField("roofColor", QVariant.String) ]) cleanLayer.updateFields() fields = cleanLayer.pendingFields() renderer = layer.rendererV2() renderContext = QgsRenderContext.fromMapSettings( canvas.mapSettings()) feats = layer.getFeatures() context = QgsExpressionContext() context.appendScope( QgsExpressionContextUtils.layerScope(layer)) expression = QgsExpression('eval(@qgis_25d_height)') heightField = fields.indexFromName("height") wallField = fields.indexFromName("wallColor") roofField = fields.indexFromName("roofColor") renderer.startRender(renderContext, fields) cleanLayer.startEditing() for feat in feats: context.setFeature(feat) height = expression.evaluate(context) if isinstance(renderer, QgsCategorizedSymbolRendererV2): classAttribute = renderer.classAttribute() attrValue = feat.attribute(classAttribute) catIndex = renderer.categoryIndexForValue(attrValue) categories = renderer.categories() symbol = categories[catIndex].symbol() elif isinstance(renderer, QgsGraduatedSymbolRendererV2): classAttribute = renderer.classAttribute() attrValue = feat.attribute(classAttribute) ranges = renderer.ranges() for range in ranges: if (attrValue >= range.lowerValue() and attrValue <= range.upperValue()): symbol = range.symbol().clone() else: symbol = renderer.symbolForFeature2( feat, renderContext) sl1 = symbol.symbolLayer(1) sl2 = symbol.symbolLayer(2) wallColor = sl1.subSymbol().color().name() roofColor = sl2.subSymbol().color().name() provider.changeAttributeValues({ feat.id() + 1: { heightField: height, wallField: wallColor, roofField: roofColor } }) cleanLayer.commitChanges() renderer.stopRender(renderContext) sln = safeName(cleanLayer.name()) + unicode(count) tmpPath = os.path.join(layersFolder, sln + ".json") path = os.path.join(layersFolder, sln + ".js") options = [] if precision != "maintain": options.append("COORDINATE_PRECISION=" + unicode(precision)) QgsVectorFileWriter.writeAsVectorFormat(cleanLayer, tmpPath, "utf-8", epsg4326, 'GeoJson', 0, layerOptions=options) with open(path, "w") as f: f.write("var %s = " % ("geojson_" + sln)) with open(tmpPath, "r") as f2: for line in f2: if optimize: line = line.strip("\n\t ") line = removeSpaces(line) f.write(line) os.remove(tmpPath) elif (layer.type() == layer.RasterLayer and layer.providerType() != "wms"): feedback.showFeedback("Exporting %s to PNG..." % layer.name()) name_ts = (safeName(layer.name()) + unicode(count) + 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 = os.path.join( layersFolder, safeName(layer.name()) + unicode(count) + ".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) # force exception on algorithm fail 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) feedback.completeStep()
def exportRaster(layer, count, layersFolder, feedback, iface, matchCRS): feedback.showFeedback("Exporting %s to PNG..." % layer.name()) name_ts = (safeName(layer.name()) + unicode(count) + 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_height, -1, piped_extent, piped_crs) # Export layer as PNG out_raster = os.path.join(layersFolder, safeName(layer.name()) + "_" + unicode(count) + ".png") projectCRS = iface.mapCanvas().mapSettings().destinationCrs() if not (matchCRS and layer.crs() == projectCRS): # Extent of the layer in EPSG:3857 crsSrc = layer.crs() crsDest = QgsCoordinateReferenceSystem(3857) try: xform = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) except: xform = QgsCoordinateTransform(crsSrc, crsDest) extentRep = xform.transformBoundingBox(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') qgis_version = Qgis.QGIS_VERSION old_stdout = sys.stdout sys.stdout = mystdout = StringIO() try: processing.algorithmHelp("gdal:warpreproject") except: pass sys.stdout = old_stdout params = { "INPUT": piped_file, "SOURCE_CRS": layer.crs().authid(), "TARGET_CRS": "EPSG:3857", "NODATA": 0, "TARGET_RESOLUTION": 0, "RESAMPLING": 2, "TARGET_EXTENT": extentRepNew, "EXT_CRS": "EPSG:3857", "TARGET_EXTENT_CRS": "EPSG:3857", "DATA_TYPE": 0, "COMPRESS": 4, "JPEGCOMPRESSION": 75, "ZLEVEL": 6, "PREDICTOR": 1, "TILED": False, "BIGTIFF": 0, "TFW": False, "MULTITHREADING": False, "COPY_SUBDATASETS": False, "EXTRA": "", "OUTPUT": piped_3857 } warpArgs = {} lines = mystdout.getvalue() for count, line in enumerate(lines.split("\n")): if count != 0 and ":" in line: try: k = line.split(":")[0] warpArgs[k] = params[k] except: pass try: processing.run("gdal:warpreproject", warpArgs) except: shutil.copyfile(piped_file, piped_3857) try: processing.run("gdal:translate", {"INPUT": piped_3857, "OUTSIZE": 100, "OUTSIZE_PERC": True, "NODATA": 0, "EXPAND": 0, "TARGET_CRS": "", "PROJWIN": extentRepNew, "SDS": False, "DATA_TYPE": 0, "COMPRESS": 4, "JPEGCOMPRESSION": 75, "ZLEVEL": 6, "PREDICTOR": 1, "TILED": False, "BIGTIFF": 0, "TFW": False, "COPY_SUBDATASETS": False, "OPTIONS": "", "OUTPUT": out_raster}) except: shutil.copyfile(piped_3857, out_raster) else: srcExtent = ','.join([unicode(piped_extent.xMinimum()), unicode(piped_extent.xMaximum()), unicode(piped_extent.yMinimum()), unicode(piped_extent.yMaximum())]) processing.run("gdal:translate", {"INPUT": piped_file, "OUTSIZE": 100, "OUTSIZE_PERC": True, "NODATA": 0, "EXPAND": 0, "TARGET_CRS": "", "PROJWIN": srcExtent, "SDS": False, "DATA_TYPE": 0, "COMPRESS": 4, "JPEGCOMPRESSION": 75, "ZLEVEL": 6, "PREDICTOR": 1, "TILED": False, "BIGTIFF": 0, "TFW": False, "COPY_SUBDATASETS": False, "OPTIONS": "", "OUTPUT": out_raster})
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)