Beispiel #1
0
def rnd_points_with_dist_from_points(otherPnt,
                                     rndPnt,
                                     NPnt,
                                     distFromOtherPnt,
                                     boundary,
                                     distRndTolerance=None):
    """
    Create NRandom Points with a distance of X from other Points
    """

    import os
    from glass.oss import get_filename
    from glass.cpu.arcg.anls.ovlay import erase
    from glass.anls.prox.bf import _buffer

    WORKSPACE = os.path.dirname(rndPnt)

    # Create Buffer
    bfShp = _buffer(otherPnt,
                    distFromOtherPnt,
                    os.path.join(
                        WORKSPACE,
                        "{}_buffer.shp".format(get_filename(otherPnt))),
                    dissolve="ALL",
                    api='arcpy')

    # Erase Boundary deleting areas where we want no points
    erased = erase(
        boundary, bfShp,
        os.path.join(WORKSPACE, "{}_erase.shp".format(get_filename(boundary))))

    # Create Random Points
    return rnd_points(rndPnt, NPnt, erased, distTolerance=distRndTolerance)
Beispiel #2
0
def range_score(raster, output, MAX=True, __template=None):
    """
    Calculate a Range Score of a Raster
    
    If Max, major values will be the major values in the normalized raster;
    Else, major values will be the minor values in the normalizes raster.
    """

    import os
    from glass.oss import get_filename
    from glass.cpu.arcg.lyr import rst_lyr
    from glass.prop.rst import rst_stats
    from glass.spanlst.algebra import rstcalc

    lyr = rst_lyr(raster)

    __max = rst_stats(lyr, api='arcpy')["MAX"]
    __min = rst_stats(lyr, api='arcpy')["MIN"]

    express = '({rst} - {_min}) / ({_max} - {_min})' if MAX else \
        '({_max} - {rst}) / ({_max} - {_min})'

    rstcalc(express.format(_min=str(__min),
                           _max=str(__max),
                           rst=get_filename(raster)),
            output,
            api='arcpy')

    return output
Beispiel #3
0
def maximum_score(raster, output, MAX=True, __template=None):
    """
    Calculate a Maximum Score of a Raster
    
    If Max, major values will be the major values in the normalized raster;
    Else, major values will be the minor values in the normalizes raster.
    """

    import os
    from glass.oss import get_filename
    from glass.cpu.arcg.lyr import rst_lyr
    from glass.prop.rst import rst_stats
    from glass.spanlst.algebra import rstcalc

    lyr = rst_lyr(raster)

    __max = rst_stats(lyr, api='arcpy')["MAX"]

    express = '{rst} / {_max}' if MAX else '1 - ({rst} / {_max})'

    rstcalc(express.format(rst=get_filename(raster), _max=str(__max)),
            output,
            template=__template,
            api='arcpy')

    return output
Beispiel #4
0
def generalize_obs_points_forFolder(FolderRst, refCell, outFolder):
    """
    Loop for generalize_obs_points
    """

    import arcpy
    import os
    from glass.oss import get_filename
    from glass.oss.ops import create_folder
    from glass.prop.rst import rst_distinct

    arcpy.env.workspace = FolderRst

    rasters = arcpy.ListRasters()

    wTmp = create_folder(os.path.join(outFolder, 'tmp'))

    for r in rasters:
        # Check if raster has data
        val = rst_distinct(r, gisApi='arcpy')
        if not len(val):
            continue

        # Generate observer points
        generalize_obs_points(r,
                              refCell,
                              os.path.join(outFolder,
                                           "{}.shp".format(get_filename(r))),
                              workspace=wTmp)

    return outFolder
Beispiel #5
0
def generalize_obs_points(rst, ref_cellsize, output, workspace=None):
    """
    We have one raster, each pixel is an observer point.
    If we have a raster with many pixels, viewshed will not run in a short time
    period. As result, we have to reduce the number of observer points.
    This script accomplish the above using a fishnet based approach
    """

    import os
    from glass.oss import get_filename
    from glass.oss.ops import create_folder
    from glass.cpu.arcg.anls.ovlay import erase
    from glass.prop.rst import get_cellsize
    from glass.cpu.arcg.mng.feat import feat_to_pnt
    from glass.cpu.arcg.mng.sample import fishnet
    from glass.to.shp import rst_to_polyg

    # 0 - Check cellsize, raster cellsize should be lower than refCellsize
    CELLSIZE = get_cellsize(rst, xy=True, bnd=None, gisApi='arcpy')

    if CELLSIZE >= ref_cellsize:
        raise ValueError(
            ("{} cellsize is not lower than ref_cellsize").format(rst))

    wTmp = workspace if workspace else create_folder(
        os.path.join(os.path.dirname(output), 'tmp'), overwrite=True)

    BASENAME = get_filename(rst)

    # Change cellsize to REF_CELLSIZE
    # 1) Create fishnet with REF_CELLSIZE
    fishNet = fishnet(os.path.join(wTmp, "fish_{}.shp".format(BASENAME)),
                      rst,
                      cellWidth=ref_cellsize,
                      cellHeight=ref_cellsize)

    # 2) Erase areas with NoData values
    # - Raster to shp
    cls_intPolygon = rst_to_polyg(rst,
                                  os.path.join(
                                      wTmp, 'clsint_{}.shp'.format(BASENAME)),
                                  gisApi='arcpy')

    # - Erase areas of the fishnet that agrees with nodata values in the raster
    tmpErase = erase(fishNet, cls_intPolygon,
                     os.path.join(wTmp, 'nozones_{}.shp'.format(BASENAME)))
    trueErase = erase(fishNet, tmpErase,
                      os.path.join(wTmp, 'fishint_{}.shp'.format(BASENAME)))

    # 3) Convert erased fishnet to points
    genObs = feat_to_pnt(trueErase, output, pnt_position="INSIDE")

    return genObs
Beispiel #6
0
def TIN_nodata_interpolation(inRst,
                             boundary,
                             prj,
                             cellsize,
                             outRst,
                             workspace=None,
                             template=None):
    """
    Preenche os valores NoData de uma imagem raster usando um TIN
    """

    import os
    from glass.oss import get_filename
    from glass.cpu.arcg.lyr import rst_lyr
    from glass.cpu.arcg.lyr import feat_lyr
    from glass.cpu.to.shp.arcg import rst_to_pnt
    from glass.cpu.arcg._3D.mng.tin import create_tin
    from glass.cpu.to.rst.arcg import tin_to_raster

    workspace = workspace if workspace else \
        os.path.dirname(outRst)

    # Convert Input Raster to a Point Feature Class
    rstLyr = rst_lyr(inRst)
    pntRst = rst_to_pnt(
        rstLyr, os.path.join(workspace,
                             get_filename(inRstinRst) + '.shp'))

    # Create TIN
    pntrstLyr = feat_lyr(pntRst)
    lmtLyr = feat_lyr(boundary)

    tinInputs = ('{bound} <None> Soft_Clip <None>;'
                 '{rst_pnt} GRID_CODE Mass_Points <None>')

    tinOutput = os.path.join(workspace, 'tin_' + get_filename(inRst))

    create_tin(tinOutput, prj, tinInputs)

    return tin_to_raster(tinOutput, cellsize, outRst, template=template)
Beispiel #7
0
def rnd_points(rndPntShp, NPoints, whereShp, distTolerance=None):
    """
    Create NRandom Points inside some area
    and save the result in one file
    """

    import os
    from glass.oss import get_filename

    distT = "" if not distTolerance else "{} Meters".format(distTolerance)

    arcpy.CreateRandomPoints_management(os.path.dirname(rndPntShp),
                                        get_filename(rndPntShp), whereShp, "",
                                        NPoints, distT, "POINT", "0")

    return rndPntShp
Beispiel #8
0
def generate_obs_points_for_large_viewshed(INTEREST_RASTER,
                                           DEM,
                                           REF_CELLS,
                                           ID_CELLS,
                                           OUT_FOLDER,
                                           SNAP_RASTER,
                                           SRS_EPSG,
                                           OBS_PNT_TOLERANCE,
                                           PRODUCE_DEM=None,
                                           PRODUCE_FROM_INDEX=None):
    """
    Imagine-se que se pretende gerar um raster com a visibilidade
    a um conjunto de entidades geográficas identificadas num ficheiro raster
    com o valor 1 (Interest Raster) e que a informação diz respeito a uma
    extensão considerável, como por exemplo, a extensão de um país.
    
    Como é fácil de perceber, isto não pode ser feito executando a ferramenta
    viewshed uma única vez, consequência do elevado volume de dados.
    
    A melhor forma de resolver o problema é segmentar os dados em vários
    ficheiros, tendo como referência uma Feature Classe constituida por features
    que constituem parcelas mais pequenas da área total a ser
    trabalhada - adiante, estas parcelas serão designadas apenas por Células.
    
    A ferramenta viewshed poderá depois ser executada de modo parcelar,
    uma vez para cada conjunto de ficheiros.
    
    Este método segmenta/divide os dados originais em partes, permitindo que a
    viewshed possa ser executada também por partes. Esta divisão seguirá
    as seguintes regras:
    
    * Para cada célula, o DEM deve ser extraído para uma área cuja extensão
    seja igual à extensão da Célula + 10 Km de tolerância;
    
    * Cada célula do Interest Raster será considerada como um ponto de
    observação. Havendo muitos pixéis no Interest Raster, deverá ser definida
    uma tolerância em metros, que definirá a distância mínima entre cada ponto
    de observação. Se esta distância for superior ao cellsize do Interest Raster,
    haverão menos pontos de observação do que células do Interest Raster,
    o que reduzirá significativamente a carga do cálculo da viewshed.
    Claro, esta tolerância deverá ser definida com critério, garantindo que
    os resultados são válidos.
    
    
    Este script tem duas formas de execução:
    * com PRODUCE_DEM = None, será feito o pre_processamento;
    * com PRODUCE_DEM = True, os rasters com as bacias de visibilidade
    serão criados, tendo por base os ficheiros criados no pre-processamento.
    """

    import os
    from threading import Thread
    from glass.cpu.arcg.mng.rst.proc import clip_raster_each_feat_class
    from glass.cpu.arcg.spanlst.rcls import rcls_folderRaster
    from glass.cpu.arcg.spanlst.surf import viewshed
    from glass.fm import tbl_to_obj
    from glass.oss import get_filename
    from glass.oss.ops import create_folder
    from glass.anls.exct import split_shp_by_attr
    from glass.mng.ext import df_buffer_extent
    from glass.mng.fld.df import col_distinct

    # Create workspaces to store data
    C_CELLS_FLD = os.path.join(OUT_FOLDER, 'cells')
    RST_TMP = os.path.join(OUT_FOLDER, 'mask_tmp')
    RST_FLD = os.path.join(OUT_FOLDER, 'mask_rst')
    B_CELLS_FLD = os.path.join(OUT_FOLDER, 'bf_cells')
    OBS_FLD = os.path.join(OUT_FOLDER, 'obs_pnt')
    DEM_RST = os.path.join(OUT_FOLDER, get_filename(DEM))

    THRD_MAPS = {
        "INT_RST": {
            "CELLS_FLD":
            create_folder(C_CELLS_FLD, overwrite=None)
            if not os.path.exists(C_CELLS_FLD) else C_CELLS_FLD,
            "RST_TMP":
            create_folder(RST_TMP, overwrite=None)
            if not os.path.exists(RST_TMP) else RST_TMP,
            "RST_FLD":
            create_folder(RST_FLD, overwrite=None)
            if not os.path.exists(RST_FLD) else RST_FLD,
            "OBS_FLD":
            create_folder(OBS_FLD, overwrite=None)
            if not os.path.exists(OBS_FLD) else OBS_FLD
        },
        "DEM": {
            "RST_FLD":
            create_folder(DEM_RST, overwrite=True)
            if not os.path.exists(DEM_RST) else DEM_RST,
            "CELLS_FLD":
            create_folder(B_CELLS_FLD, overwrite=None)
            if not os.path.exists(B_CELLS_FLD) else B_CELLS_FLD,
        }
    }

    if not PRODUCE_DEM:
        """
        Split data into parts
        """
        """
        Split Cells
        """
        def split_cells(f, bf, of):
            if bf == "DEM":
                _f = df_buffer_extent(f, SRS_EPSG, 10000,
                                      os.path.join(OUT_FOLDER, 'bf_cells.shp'))

            else:
                _f = f

            split_shp_by_attr(_f, ID_CELLS, of["CELLS_FLD"], _format='.shp')

        thrds = [
            Thread(name="split-{}".format(k),
                   target=split_cells,
                   args=(REF_CELLS, k, THRD_MAPS[k])) for k in THRD_MAPS
        ]

        for t in thrds:
            t.start()

        for t in thrds:
            t.join()
        """
        Clip INTEREST RASTER for all cells in CELLS_FLD and BF_CELLS_FLD
        """

        for key, val in THRD_MAPS.items():
            inrst = DEM if key == "DEM" else INTEREST_RASTER

            clip_raster_each_feat_class(
                inrst,
                val["CELLS_FLD"],
                val["RST_FLD"] if key == "DEM" else val["RST_TMP"],
                snap=SNAP_RASTER,
                clipGeometry=True)
        """
        Reclassify Rasters of interest:
    
        - For each cell, create a Raster with presence of class and other with
        ausence of class
        """

        rcls_folderRaster(THRD_MAPS["INT_RST"]["RST_TMP"], {
            0: 'NoData',
            1: 1
        }, THRD_MAPS["INT_RST"]["RST_FLD"])
        """
        Create Observer points for each raster
        """
        generalize_obs_points_forFolder(THRD_MAPS["INT_RST"]["RST_FLD"],
                                        OBS_PNT_TOLERANCE,
                                        THRD_MAPS["INT_RST"]["OBS_FLD"])

    else:
        """
        Generate Viewsheds
        """

        cellsDf = tbl_to_obj(REF_CELLS)

        LST_CELLS = col_distinct(cellsDf, ID_CELLS)

        OBS_REF_NAME = get_filename(REF_CELLS)

        __LST_CELLS = LST_CELLS if not PRODUCE_FROM_INDEX else LST_CELLS[:
                                                                         PRODUCE_FROM_INDEX]

        for cell_id in LST_CELLS:
            OUT_RST = os.path.join(OUT_FOLDER,
                                   "vis_{}.tif".format(str(cell_id)))

            if os.path.exists(OUT_RST):
                continue

            DEM_RST = os.path.join(
                THRD_MAPS["DEM"]["RST_FLD"],
                "bf_cells_{}.tif".format(str(cell_id)),
            )

            OBS_SHP = os.path.join(
                THRD_MAPS["INT_RST"]["OBS_FLD"],
                "{}_{}.shp".format(OBS_REF_NAME, str(int(cell_id))))

            if not os.path.join(OBS_SHP):
                continue

            viewshed(DEM_RST,
                     OBS_SHP,
                     OUT_RST,
                     snapRaster=DEM_RST,
                     extRaster=DEM_RST)