def test_set_vector_file_wrong_fail(self): """Test set_vector_file with wrong centroids""" shp_file = shapereader.natural_earth(resolution='110m', category='cultural', name='populated_places_simple') centr = Centroids() inten = centr.set_vector_file(shp_file, ['pop_min', 'pop_max']) self.assertEqual(CRS.from_user_input(centr.geometry.crs), CRS.from_epsg(u_coord.NE_EPSG)) self.assertEqual(centr.geometry.size, centr.lat.size) self.assertEqual(CRS.from_user_input(centr.geometry.crs), CRS.from_epsg(u_coord.NE_EPSG)) self.assertAlmostEqual(centr.lon[0], 12.453386544971766) self.assertAlmostEqual(centr.lon[-1], 114.18306345846304) self.assertAlmostEqual(centr.lat[0], 41.903282179960115) self.assertAlmostEqual(centr.lat[-1], 22.30692675357551) self.assertEqual(inten.shape, (2, 243)) # population min self.assertEqual(inten[0, 0], 832) self.assertEqual(inten[0, -1], 4551579) # population max self.assertEqual(inten[1, 0], 832) self.assertEqual(inten[1, -1], 7206000) shp_file = shapereader.natural_earth(resolution='10m', category='cultural', name='populated_places_simple') with self.assertRaises(ValueError): centr.set_vector_file(shp_file, ['pop_min', 'pop_max'])
def _set_single(self, crs: CRS): """ Assign the provided pyproj crs object to the object attribute representing either the vertical crs or the horizontal crs. If the object contains a new vertical crs and contains the remarks for the regions, the regions are also extracted and assigned to the associated object attribute. Parameters ---------- crs : pyproj.crs.CRS The new crs. Returns ------- None. """ new_vert = False if crs_is_compound(crs): self.ccrs = crs self._hori = crs.sub_crs_list[0] self._vert = crs.sub_crs_list[1] new_vert = True elif crs.is_geocentric: raise ValueError( 'Geocentric cooridinate systems are not supported.') elif len(crs.axis_info) > 2: # assuming 3D crs if not compound but axis length is > 2. Break into compound crs. if crs.to_epsg() == NAD83_3D: # if 3d nad83, go to 2d nad83 self._hori = CRS.from_epsg(NAD83_2D) elif crs.to_epsg() == ITRF2008_3D: # 3d wgs84/itrf2008, go to 2d self._hori = CRS.from_epsg(ITRF2008_2D) elif crs.to_epsg() == ITRF2014_3D: # 3d itrf2014, go to 2d self._hori = CRS.from_epsg(ITRF2014_2D) else: raise NotImplementedError( f'A 3D coordinate system was provided that is not yet implemented: {crs.to_epsg()}' ) self._vert = VerticalPipelineCRS( datum_data=self.datum_data, vert_datum_name=f'{self._hori.name}_ellipse').to_crs() new_vert = True elif crs.is_vertical: self._vert = crs new_vert = True else: self._hori = crs if new_vert: # get the regions from the wkt if available tmp_vert = VerticalPipelineCRS(datum_data=self.datum_data) tmp_vert.from_wkt(self._vert.to_wkt()) if len(tmp_vert.regions) > 0: self._regions = tmp_vert.regions
def pyproj_crs_to_osgeo(proj_crs: Union[CRS, int]): """ Convert from the pyproj CRS object to osgeo SpatialReference See https://pyproj4.github.io/pyproj/stable/crs_compatibility.html Parameters ---------- proj_crs pyproj CRS or an integer epsg code Returns ------- SpatialReference converted SpatialReference """ if isinstance(proj_crs, int): proj_crs = CRS.from_epsg(proj_crs) osr_crs = SpatialReference() if osgeo.version_info.major < 3: osr_crs.ImportFromWkt(proj_crs.to_wkt(WktVersion.WKT1_GDAL)) else: osr_crs.ImportFromWkt(proj_crs.to_wkt()) return osr_crs
def test_to_crs_user_input(self): pcrs = PCRS.from_epsg(4326) rcrs = RCRS.from_epsg(4326) # are they the default? self.assertTrue( pcrs == PCRS.from_user_input(to_crs_user_input(DEF_CRS))) self.assertEqual(rcrs, RCRS.from_user_input(to_crs_user_input(DEF_CRS))) # can they be understood from the provider? for arg in ['epsg:4326', b'epsg:4326', DEF_CRS, 4326]: self.assertEqual(pcrs, PCRS.from_user_input(to_crs_user_input(arg))) self.assertEqual(rcrs, RCRS.from_user_input(to_crs_user_input(arg))) # can they be misunderstood from the provider? for arg in [{ 'init': 'epsg:4326', 'no_defs': True }, b'{"init": "epsg:4326", "no_defs": True}']: self.assertFalse( pcrs == PCRS.from_user_input(to_crs_user_input(arg))) self.assertEqual(rcrs, RCRS.from_user_input(to_crs_user_input(arg))) # are they noticed? for arg in [4326.0, [4326]]: with self.assertRaises(ValueError): to_crs_user_input(arg) with self.assertRaises(SyntaxError): to_crs_user_input('{init: epsg:4326, no_defs: True}')
def __init__(self, code): crs = _CRS.from_epsg(code) if not crs.is_projected: raise ValueError('EPSG code does not define a projection') if not crs.area_of_use: raise ValueError("Area of use not defined.") self.epsg_code = code super().__init__(crs.to_wkt())
def _handler(self, request, response): shape_url = request.inputs["shape"][0].file projected_crs = request.inputs["projected_crs"][0].data extensions = [".gml", ".shp", ".gpkg", ".geojson", ".json"] vector_file = single_file_check( archive_sniffer(shape_url, working_dir=self.workdir, extensions=extensions)) shape_crs = crs_sniffer(vector_file) try: projection = CRS.from_epsg(projected_crs) if projection.is_geographic: msg = ( f"Desired CRS {projection.to_epsg()} is geographic. " "Areal analysis values will be in decimal-degree units.") LOGGER.warning(msg) except Exception as e: msg = f"{e}: Failed to parse CRS definition. Exiting." LOGGER.error(msg) raise Exception(msg) # TODO: It would be good to one day refactor this to make use of RavenPy utils and gis utilities properties = list() try: for i, layer_name in enumerate(fiona.listlayers(vector_file)): with fiona.open(vector_file, "r", crs=shape_crs, layer=i) as src: for feature in src: geom = shape(feature["geometry"]) multipolygon_check(geom) transformed = geom_transform(geom, source_crs=shape_crs, target_crs=projection) prop = {"id": feature["id"]} prop.update(feature["properties"]) prop.update(geom_prop(transformed)) # Recompute the centroid location using the original projection prop["centroid"] = geom_prop(geom)["centroid"] properties.append(prop) except Exception as e: msg = f"{e}: Failed to extract features from shape {vector_file}." LOGGER.error(msg) raise Exception(msg) response.outputs["properties"].data = json.dumps(properties) return response
def from_epsg(epsg): """Converts from an EPSG code to a workflow CRS. Parameters ---------- epsg : int An EPSG code. (see `https://epsg.io`_) Returns ------- out : crs-type Equivalent workflow CRS. """ return CRS.from_epsg(epsg)
def test_read_vector_pass(self): """Test one columns data""" shp_file = shapereader.natural_earth(resolution='110m', category='cultural', name='populated_places_simple') lat, lon, geometry, intensity = read_vector(shp_file, ['pop_min', 'pop_max']) self.assertEqual(PCRS.from_user_input(geometry.crs), PCRS.from_epsg(NE_EPSG)) self.assertEqual(geometry.size, lat.size) self.assertAlmostEqual(lon[0], 12.453386544971766) self.assertAlmostEqual(lon[-1], 114.18306345846304) self.assertAlmostEqual(lat[0], 41.903282179960115) self.assertAlmostEqual(lat[-1], 22.30692675357551) self.assertEqual(intensity.shape, (2, 243)) # population min self.assertEqual(intensity[0, 0], 832) self.assertEqual(intensity[0, -1], 4551579) # population max self.assertEqual(intensity[1, 0], 832) self.assertEqual(intensity[1, -1], 7206000)
def from_fiona(crs): """Converts a fiona CRS to the workflow CRS standard. Parameters ---------- crs : fiona-crs-dict Input fiona CRS, which is a dictionary containing an EPSG code. Returns ------- out : crs-type Equivalent workflow CRS. """ # if 'datum' in crs and crs['datum'] == 'WGS84' and 'epsg' not in crs and 'ellps' not in crs: # logging.warning('Old-style datum WGS84, moving to ellipse') # crs['ellps'] = crs.pop('datum') if 'init' in crs and crs['init'].startswith('epsg:'): epsg, code = crs['init'].split(':') return CRS.from_epsg(code) else: return CRS.from_dict(crs)
def reproject_raster(input_raster_name, reprojection, blocksize=None, reprojected_raster_name=None): if blocksize is not None: if isinstance(blocksize, int): pass elif isinstance(blocksize, str): blocksize = int(blocksize) elif isinstance(blocksize, float): blocksize = int(blocksize) else: raise TypeError("Pass integer for blocksize") else: blocksize = 256 assert input_raster_name.endswith('.tif'), "input raster needs to be a tif" reprojection = rasterio.crs.CRS.from_string(reprojection) with rasterio.open(input_raster_name) as src: # Check projection if src.crs.to_string() != reprojection: if src.crs.to_string().startswith('EPSG'): epsg = src.crs.to_epsg() proj_crs = CRS.from_epsg(epsg) rio_crs = rasterio.crs.CRS.from_user_input( proj_crs).to_string() else: rio_crs = src.crs.to_string() print(f"{input_raster_name} not projected") print(f"Reprojecting from {rio_crs} to {reprojection}") transform, width, height = calculate_default_transform( src.crs, reprojection, src.width, src.height, *src.bounds) kwargs = src.meta.copy() kwargs.update({ 'crs': reprojection, 'transform': transform, 'width': width, 'height': height, 'compress': 'lzw' }) if reprojected_raster_name is None: reprojected_raster_name = input_raster_name assert reprojected_raster_name.endswith( '.tif'), "output raster needs to be a tif" with rasterio.open(reprojected_raster_name, 'w', **kwargs, tiled=True, blockxsize=blocksize, blockysize=blocksize, BIGTIFF='YES') as dst: reproject(source=rasterio.band(src, 1), destination=rasterio.band(dst, 1), src_transform=src.transform, src_crs=rio_crs, dst_transform=transform, dst_crs=reprojection.to_string(), resampling=Resampling.nearest) del dst del src
def processAlgorithm(self, parameters, context, feedback): # inputs rasters = self.parameterAsLayerList(parameters, self.RASTERLIST, context) if rasters is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.RASTERLIST)) reamostragem = self.parameterAsEnum(parameters, self.RESAMPLING, context) reamostragem = ['nearest', 'bilinear', 'bicubic'][reamostragem] sobrep = self.parameterAsEnum(parameters, self.OVERLAP, context) muda_res = self.parameterAsBool(parameters, self.CHANGERESOLUTION, context) resolucao = self.parameterAsDouble(parameters, self.RESOLUTION, context) valor_nulo = self.parameterAsDouble(parameters, self.NULLVALUE, context) moldura = self.parameterAsDouble(parameters, self.CLIP, context) if moldura: vlayer = self.parameterAsVectorLayer(parameters, self.FRAME, context) if vlayer is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.FRAME)) # output Output = self.parameterAsFileOutput(parameters, self.MOSAIC, context) Carregar = self.parameterAsBool(parameters, self.OPEN, context) lista = [] for raster_lyr in rasters: lista += [raster_lyr.dataProvider().dataSourceUri()] if len(lista) < 1: raise QgsProcessingException( self.tr('At least one raster must be selected!', 'Pelo menos um raster deve ser selecionado!')) if len(lista) == 1: sobrep = 0 # apenas um raster (sem sobreposicao) # Gerar geometria para cada raster geoms = [] SRC = [] n_bands = [] GDT = [] nulos = [] XRES, YRES = [], [] for item in lista: image = gdal.Open(item) SRC += [QgsCoordinateReferenceSystem(image.GetProjection())] # wkt ulx, xres, xskew, uly, yskew, yres = image.GetGeoTransform() cols = image.RasterXSize rows = image.RasterYSize n_bands += [image.RasterCount] GDT += [image.GetRasterBand(1).DataType] nulos += [image.GetRasterBand(1).GetNoDataValue()] XRES += [xres] YRES += [yres] image = None # Close image # Creating BBox coord = [[ QgsPointXY(ulx, uly), QgsPointXY(ulx + cols * xres, uly), QgsPointXY(ulx + cols * xres, uly + rows * yres), QgsPointXY(ulx, uly + rows * yres), QgsPointXY(ulx, uly) ]] geom = QgsGeometry.fromPolygonXY(coord) geoms += [geom] ## Validar dados de entrada # Mesmo numero de bandas if not n_bands.count(n_bands[0]) == len(n_bands): raise QgsProcessingException( self.tr('The images must have the same number of bands!', 'As imagens devem ter o mesmo número de bandas!')) # Mesmo SRC if not SRC.count(SRC[0]) == len(SRC): raise QgsProcessingException( self.tr('The images must have the same CRS!', 'As imagens devem ter o mesmo SRC!')) # Mesmo GDT if not GDT.count(GDT[0]) == len(GDT): raise QgsProcessingException( self.tr('The images must have the same data type!', 'As imagens devem ter o tipo de dado!')) # Mesmo valor nulo if not nulos.count(nulos[0]) == len(nulos): raise QgsProcessingException( self.tr( 'The images must have the same definied null value!', 'As imagens devem ter o mesmo valor para definir pixel nulo!' )) # Dados para o raster de saída prj = SRC[0].toWkt() n_bands = n_bands[0] GDT = GDT[0] xres = np.mean(XRES) yres = np.mean(YRES) NULO = valor_nulo if valor_nulo == -1: valor_nulo = nulos[0] if nulos[0] is not None else 0 if moldura: # Pegar extensão X e Y da moldura # SRC da moldura deve ser o mesmo dos raster if vlayer.sourceCrs() != QgsCoordinateReferenceSystem(prj): raise QgsProcessingException( self.tr( "The frame's CRS must be iqual to the rasters' CRS!", 'O SRC da moldura deve ser igual ao SRC dos rasters!')) for feat in vlayer.getFeatures(): moldura_geom = feat.geometry() break moldura_rect = moldura_geom.boundingBox() y_min = moldura_rect.yMinimum() y_max = moldura_rect.yMaximum() x_min = moldura_rect.xMinimum() x_max = moldura_rect.xMaximum() else: # Mesclar geometrias e obter a extensão new_geom = QgsGeometry() new_geom = new_geom.unaryUnion(geoms) extensao = new_geom.boundingBox() # Coodenadas máxima e mínima da extensão y_min = extensao.yMinimum() y_max = extensao.yMaximum() x_min = extensao.xMinimum() x_max = extensao.xMaximum() # Transformar resolucao de metros para graus, se o SRC for Geográfico src_qgis = QgsCoordinateReferenceSystem(prj) if src_qgis.isGeographic(): EPSG = int(src_qgis.authid().split(':')[-1]) proj_crs = CRS.from_epsg(EPSG) a = proj_crs.ellipsoid.semi_major_metre f = 1 / proj_crs.ellipsoid.inverse_flattening e2 = f * (2 - f) N = a / np.sqrt(1 - e2 * (np.sin( (y_min + y_max) / 2))**2) # Raio de curvatura 1º vertical M = a * (1 - e2) / (1 - e2 * (np.sin((y_min + y_max) / 2))**2)**( 3 / 2.) # Raio de curvatura meridiana R = np.sqrt(M * N) # Raio médio de Gauss theta = resolucao / R resolucao = np.degrees(theta) # Radianos para graus # Definir n_col, n_lin e resolucao if moldura: if muda_res: n_lin = round((y_max - y_min) / abs(resolucao)) n_col = round((x_max - x_min) / abs(resolucao)) else: n_lin = round((y_max - y_min) / abs(yres)) n_col = round((x_max - x_min) / abs(xres)) xres = (x_max - x_min) / n_col yres = -(y_max - y_min) / n_lin else: if muda_res: n_lin = round((y_max - y_min) / abs(resolucao)) n_col = round((x_max - x_min) / abs(resolucao)) xres = resolucao yres = -resolucao else: n_lin = round((y_max - y_min) / abs(yres)) n_col = round((x_max - x_min) / abs(xres)) xres = (x_max - x_min) / n_col yres = -(y_max - y_min) / n_lin feedback.pushInfo( self.tr('Resolution: ', 'Resolução: ') + str(n_lin) + 'x' + str(n_col)) # Geotransform do Mosaico ulx = x_min uly = y_max xskew, yskew = 0, 0 geotransform = [ulx, xres, xskew, uly, yskew, yres] origem = (ulx, uly) resol_X = abs(xres) resol_Y = abs(yres) # Numeração das Imagens valores = list(range(1, len(lista) + 1)) # Definição de áreas de varredura feedback.pushInfo( self.tr('Defining mosaic filling areas...', 'Definindo áreas de preenchimento do mosaico...')) # Gerar combinações dos Rasters if sobrep != 0: combs = [] feedback.pushInfo( self.tr('Creating combinations...', 'Gerando combinações...')) for k in range(1, 5): combs += list(combinations(valores, k)) if feedback.isCanceled(): break # Armazenar geometrias exclusivas de cada combinação classes = {} feedback.pushInfo( self.tr('Indentifying combinations...', 'Identificando combinações...')) Percent = 100.0 / (len(combs)) current = 0 for comb in combs: if len(comb) == 1: geom1 = geoms[comb[0] - 1] lista_outras = [] for geom in geoms: if geom1 != geom: lista_outras += [geom] outras = QgsGeometry() outras = outras.unaryUnion(lista_outras) diferença = geom1.difference(outras) if not diferença.isEmpty(): classes[comb] = {'geom': diferença} elif len(comb) < len(valores): intersecao = geoms[comb[0] - 1] sentinela = True for ind in comb[1:]: geom = geoms[ind - 1] if geom.intersects(intersecao): intersecao = intersecao.intersection(geom) else: sentinela = False continue lista_outras = [] for valor in valores: if valor not in comb: lista_outras += [geoms[valor - 1]] outras = QgsGeometry() outras = outras.unaryUnion(lista_outras) if sentinela: diferença = intersecao.difference(outras) if not diferença.isEmpty(): classes[comb] = {'geom': diferença} else: intersecao = geoms[comb[0] - 1] sentinela = True for ind in comb[1:]: geom = geoms[ind - 1] if geom.intersects(intersecao): intersecao = intersecao.intersection(geom) else: sentinela = False continue if sentinela: classes[comb] = {'geom': intersecao} if feedback.isCanceled(): break current += 1 feedback.setProgress(int(current * Percent)) else: # Gerar geometrias por área sem cálculo de sobreposição ("first") combs = np.array(valores)[:, np.newaxis] classes = {} acumulado = geoms[combs[0][0] - 1] classes[(1, )] = {'geom': acumulado} for k in range(1, len(combs)): comb = combs[k] geom = geoms[comb[0] - 1] diferenca = geom.difference(acumulado) classes[(comb[0], )] = {'geom': diferenca} acumulado = acumulado.combine(geom) if feedback.isCanceled(): break # Gerar lista com os valores classificados Percent = 100.0 / (len(classes)) current = 0 for classe in classes: feedback.pushInfo( (self.tr('Classifying class {}...', 'Classificando classe {}...')).format(str(classe))) geom = classes[classe]['geom'] if moldura: geom = geom.intersection(moldura_geom) if geom.type() == 2: if geom.isMultipart(): coords = geom.asMultiPolygon()[0][0] else: coords = geom.asPolygon()[0] else: del classes[classe] continue caminho = [] for ponto in coords: linha = (origem[1] - ponto.y()) / resol_Y coluna = (ponto.x() - origem[0]) / resol_X caminho += [(linha, coluna)] p = path.Path(caminho) box = geom.boundingBox() uly = box.yMaximum() lry = box.yMinimum() ulx = box.xMinimum() lrx = box.xMaximum() # Limites de Varredura row_ini = int(round((origem[1] - uly) / resol_Y - 0.5)) - 1 row_fim = int(round((origem[1] - lry) / resol_Y - 0.5)) + 1 col_ini = int(round((ulx - origem[0]) / resol_X - 0.5)) - 1 col_fim = int(round((lrx - origem[0]) / resol_X - 0.5)) + 1 lin, col = np.meshgrid(np.arange(row_ini, row_fim), np.arange(col_ini, col_fim)) LIN = lin.flatten()[:, np.newaxis] + 0.5 # centro do pixel COL = col.flatten()[:, np.newaxis] + 0.5 pixels_center = np.hstack((LIN, COL)) # Verificando pixels dentro de poligono flags = p.contains_points(pixels_center) pixels_x = LIN.flatten() * flags pixels_y = COL.flatten() * flags pixels_x = (pixels_x[pixels_x > 0] - 0.5).astype('int')[:, np.newaxis] pixels_y = (pixels_y[pixels_y > 0] - 0.5).astype('int')[:, np.newaxis] pixels = np.hstack((pixels_x, pixels_y)) classes[classe]['pixels'] = pixels current += 1 feedback.setProgress(int(current * Percent)) # Criar Raster Driver = gdal.GetDriverByName('GTiff').Create(Output, n_col, n_lin, n_bands, GDT) Driver.SetGeoTransform(geotransform) Driver.SetProjection(prj) # Mosaicar por banda Percent = 100.0 / (n_lin * n_col * n_bands) current = 0 for k in range(n_bands): feedback.pushInfo( (self.tr('Creating band {}...', 'Criando banda {}...')).format(str(k + 1))) # Criar Array do mosaico tipo = gdal_array.GDALTypeCodeToNumericTypeCode(GDT) inteiro = True if GDT in (gdal.GDT_Byte, gdal.GDT_UInt16, gdal.GDT_Int16, gdal.GDT_UInt32, gdal.GDT_Int32) else False banda = np.ones( (n_lin, n_col), dtype=tipo) * (int(valor_nulo) if inteiro else valor_nulo) imgs = {} # Para cada classe abrir banda da(s) imagem(ns) for classe in classes: # Deixando somente imagens a serem utilizadas for item in valores: if (item not in classe) and (item in imgs): del imgs[item] # Preenchendo dados da imagem no dicionário for img in classe: if img not in imgs or len(lista) == 1: img_path = lista[img - 1] image = gdal.Open(img_path) ulx, xres, xskew, uly, yskew, yres = image.GetGeoTransform( ) img_origem = (ulx, uly) img_resol_X = abs(xres) img_resol_Y = abs(yres) img_band = image.GetRasterBand(k + 1).ReadAsArray() imgs[img] = { 'band': img_band, 'xres': img_resol_X, 'yres': img_resol_Y, 'origem': img_origem } image = None if sobrep == 0: # Se for "primeiro", interpolar apenas da primeira img da comb, caso contrário img = classe[0] # Para cada pixel da classe for px in classes[classe]['pixels']: lin, col = px X = origem[0] + resol_X * (col + 0.5) Y = origem[1] - resol_Y * (lin + 0.5) Interpolado = self.Interpolar(X, Y, imgs[img]['band'], imgs[img]['origem'], imgs[img]['xres'], imgs[img]['yres'], reamostragem, valor_nulo) if Interpolado != valor_nulo: banda[lin][col] = round( Interpolado) if inteiro else Interpolado if feedback.isCanceled(): break current += 1 feedback.setProgress(int(current * Percent)) else: # Para cada pixel da classe interpolar o valor da banda de cada img for px in classes[classe]['pixels']: lin, col = px X = origem[0] + resol_X * (col + 0.5) Y = origem[1] - resol_Y * (lin + 0.5) interp_values = [] for img in imgs: Interpolado = self.Interpolar( X, Y, imgs[img]['band'], imgs[img]['origem'], imgs[img]['xres'], imgs[img]['yres'], reamostragem, valor_nulo) if Interpolado != valor_nulo: interp_values += [Interpolado] # Calcular o valor agregado (0:first, 1:average, 2:median, 3:min, 4:max) e inserir na banda (se byte, arredondar) if interp_values: if sobrep == 1: result = np.mean(interp_values) elif sobrep == 2: result = np.median(interp_values) elif sobrep == 3: result = np.min(interp_values) elif sobrep == 4: result = np.max(interp_values) banda[lin][col] = round( result) if inteiro else result if feedback.isCanceled(): break current += 1 feedback.setProgress(int(current * Percent)) # Salvar banda outband = Driver.GetRasterBand(k + 1) feedback.pushInfo( self.tr('Writing Band {}...'.format(k + 1), 'Escrevendo Banda {}...'.format(k + 1))) outband.WriteArray(banda) if NULO != -1: outband.SetNoDataValue(valor_nulo) # Salvar e Fechar Raster Driver.FlushCache() # Escrever no disco Driver = None # Salvar e fechar feedback.pushInfo( self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!')) feedback.pushInfo('Leandro França - Eng Cart') self.CAMINHO = Output self.CARREGAR = Carregar return {self.MOSAIC: Output}
def processAlgorithm(self, parameters, context, feedback): linhas = self.parameterAsVectorLayer(parameters, self.LINES, context) if linhas is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.LINES)) tipo = self.parameterAsEnum(parameters, self.TYPE, context) Distancia = self.parameterAsDouble(parameters, self.DISTANCE, context) if Distancia is None or Distancia < 0: raise QgsProcessingException( self.tr('The input distance must be grater than 0!', 'A distância de entrada deve ser maior que 0!')) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, linhas.fields(), linhas.wkbType(), linhas.sourceCrs()) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) # Camada de entrada SRC = linhas.sourceCrs() fields = linhas.fields() extensao = linhas.sourceExtent() y_max = extensao.yMaximum() y_min = extensao.yMinimum() # Transformar distancia para graus, se o SRC for Geográfico if SRC.isGeographic(): EPSG = int(SRC.authid().split(':')[-1]) proj_crs = CRS.from_epsg(EPSG) a = proj_crs.ellipsoid.semi_major_metre f = 1 / proj_crs.ellipsoid.inverse_flattening e2 = f * (2 - f) N = a / np.sqrt(1 - e2 * (np.sin( (y_min + y_max) / 2))**2) # Raio de curvatura 1º vertical M = a * (1 - e2) / (1 - e2 * (np.sin((y_min + y_max) / 2))**2)**( 3 / 2.) # Raio de curvatura meridiana R = np.sqrt(M * N) # Raio médio de Gauss theta = Distancia / R Distancia = np.degrees(theta) # Radianos para graus # Varrer linhas Percent = 100.0 / linhas.featureCount() if linhas.featureCount( ) > 0 else 0 for index, feat in enumerate(linhas.getFeatures()): geom = feat.geometry() att = feat.attributes() if geom: if geom.isMultipart(): lines = geom.asMultiPolyline() for line in lines: P1 = line[0] P2 = line[1] Pn = line[-1] Pn_1 = line[-2] P_ini = QgsGeometry.fromPointXY(P1) P_fim = QgsGeometry.fromPointXY(Pn) if tipo == 0 or tipo == 2: vetor = array(P1) - array(P2) P = array(P1) + vetor / norm(vetor) * Distancia P1 = QgsPointXY(P[0], P[1]) if tipo == 0 or tipo == 1: vetor = array(Pn) - array(Pn_1) P = array(Pn) + vetor / norm(vetor) * Distancia Pn = QgsPointXY(P[0], P[1]) if tipo == 0: line = [P1] + line[1:-1] + [Pn] elif tipo == 1: line = line[0:-1] + [Pn] elif tipo == 2: line = [P1] + line[1:] new_geom = QgsGeometry.fromPolylineXY(line) feature = QgsFeature(fields) feature.setAttributes(att) feature.setGeometry(new_geom) sink.addFeature(feature, QgsFeatureSink.FastInsert) else: line = geom.asPolyline() P1 = line[0] P2 = line[1] Pn = line[-1] Pn_1 = line[-2] P_ini = QgsGeometry.fromPointXY(P1) P_fim = QgsGeometry.fromPointXY(Pn) if tipo == 0 or tipo == 2: vetor = array(P1) - array(P2) P = array(P1) + vetor / norm(vetor) * Distancia P1 = QgsPointXY(P[0], P[1]) if tipo == 0 or tipo == 1: vetor = array(Pn) - array(Pn_1) P = array(Pn) + vetor / norm(vetor) * Distancia Pn = QgsPointXY(P[0], P[1]) if tipo == 0: line = [P1] + line[1:-1] + [Pn] elif tipo == 1: line = line[0:-1] + [Pn] elif tipo == 2: line = [P1] + line[1:] new_geom = QgsGeometry.fromPolylineXY(line) feature = QgsFeature(fields) feature.setAttributes(att) feature.setGeometry(new_geom) sink.addFeature(feature, QgsFeatureSink.FastInsert) if feedback.isCanceled(): break feedback.setProgress(int((index + 1) * Percent)) feedback.pushInfo( self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!')) feedback.pushInfo( self.tr('Leandro Franca - Cartographic Engineer', 'Leandro França - Eng Cart')) return {self.OUTPUT: dest_id}
def test_properties_from_json_dict(property_name, init_class): prop = getattr(CRS.from_epsg(26915), property_name) assert init_class.from_json_dict(prop.to_json_dict()) == prop
from pathlib import Path from statistics import mode import rasterio as rio import xarray as xr from pyproj.crs import CRS from rasterio.enums import ColorInterp from rasterio.merge import merge from rasterio.warp import calculate_default_transform, reproject, Resampling UTM_CRS = { '16': CRS.from_epsg(32616), # UTM 16N WGS84 # Eureka '15': CRS.from_epsg(32615), # UTM 15N WGS84 # West of Eureka '08': CRS.from_epsg(32608), # UTM 8N WGS84 # TVC '29': CRS.from_epsg(32629), # UTM 29N WGS84 # Ireland '30': CRS.from_epsg(32630) # UTM 30N WGS84 # Ireland } SAMPLE_METHODS = { 'nearest': Resampling.nearest, 'cubic': Resampling.cubic, 'average': Resampling.average, 'cubic-spline': Resampling.cubic_spline, 'gauss': Resampling.gauss, 'mode': Resampling.mode, 'lanczos': Resampling.lanczos } def acceptable_cloud_coverage(hdf_file, threshold=30): '''
def set_crs(self, new_crs: Union[str, int, tuple], regions: [str] = None): """ Set the object vertical and / or horizontal crs using either an epsg code or wkt. Regions are also optionally set with a list of VDatum region strings. Parameters ---------- new_crs : Union[str, int, tuple] A wkt string or a vyperdatum vertical datum definition string or an epsg code may be provided either on its own or as a tuple pair. While the order (horizontal or vertical) does not matter, if they contain information for the same frame (horizontal or vertical) the second will overwrite the first. Once the provided object datums are set, the object compound attribute is set if the horizontal, verical, and region information is available. regions : [str], optional A list of VDatum region strings. These values will overwrite the values contained in the vertical WKT if they exist. The default is None. Raises ------ ValueError If a tuple of length greater than two is provided or if the provided value(s) are not a string or an integer. Returns ------- None. """ # check the input type if type(new_crs) == tuple: if len(new_crs) > 2: len_crs = len(new_crs) raise ValueError( f'The provided crs {new_crs} is {len_crs} in length but should have a length of two.' ) else: new_crs = (new_crs, ) # create pyproj crs based on the input type for entry in new_crs: if type(entry) == str: crs_str = entry if entry.lower() in datum_definition: if entry == 'ellipse' and self._hori: entry = f'{self._hori.name}_ellipse' tmp_crs = VerticalPipelineCRS(datum_data=self.datum_data, vert_datum_name=entry) crs_str = tmp_crs.to_wkt() crs = CRS.from_wkt(crs_str) self._set_single(crs) elif type(entry) == int: crs = CRS.from_epsg(entry) self._set_single(crs) else: raise ValueError( f'The crs description type {entry} is not recognized.') if regions: self._regions = regions self._update_and_build_compound()
import os from typing import Union from pyproj.crs import CRS, CompoundCRS, VerticalCRS as pyproj_VerticalCRS import pyproj.datadir from vyperdatum.pipeline import get_regional_pipeline, datum_definition from vyperdatum.__version__ import __version__ NAD83_2D = 6318 NAD83_3D = 6319 ITRF2008_2D = 8999 ITRF2008_3D = 7911 ITRF2014_2D = 9000 ITRF2014_3D = 7912 frame_lookup = { CRS.from_epsg(NAD83_2D).name: 'NAD83', CRS.from_epsg(NAD83_3D).name: 'NAD83', CRS.from_epsg(ITRF2008_2D).name: 'ITRF2008', CRS.from_epsg(ITRF2008_3D).name: 'ITRF2008', CRS.from_epsg(ITRF2014_2D).name: 'ITRF2014', CRS.from_epsg(ITRF2014_3D).name: 'ITRF2014' } geoid_frame_lookup = { r'core\geoid12b\g2012bu0.gtx': CRS.from_epsg(NAD83_2D).name, r'core\geoid12b\g2012bp0.gtx': CRS.from_epsg(NAD83_2D).name, r'core\xgeoid16b\ak.gtx': CRS.from_epsg(ITRF2008_2D).name, r'core\xgeoid16b\conus.gtx': CRS.from_epsg(ITRF2008_2D).name, r'core\xgeoid16b\hi.gtx': CRS.from_epsg(ITRF2008_2D).name, r'core\xgeoid16b\prvi.gtx': CRS.from_epsg(ITRF2008_2D).name, r'core\xgeoid17b\AK_17B.gtx': CRS.from_epsg(ITRF2008_2D).name,