Exemplo n.º 1
0
    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'])
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
    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}')
Exemplo n.º 5
0
    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())
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
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
Exemplo n.º 11
0
    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}
Exemplo n.º 12
0
    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}
Exemplo n.º 13
0
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
Exemplo n.º 14
0
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):
    '''
Exemplo n.º 15
0
    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()
Exemplo n.º 16
0
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,