Exemplo n.º 1
0
def pnts_to_boundary(pntShp, outBound, distMeters):
    """
    Create a boundary from Point using a tolerance in meters
    """

    from osgeo import ogr
    from glass.pys.oss import fprop
    from glass.g.prop import drv_name
    from glass.g.gobj import new_pnt
    from glass.g.prop.prj import get_shp_sref

    SRS = get_shp_sref(pntShp)

    shp = ogr.GetDriverByName(drv_name(pntShp)).Open(pntShp)
    lyr = shp.GetLayer()

    outShp = ogr.GetDriverByName(drv_name(outBound)).CreateDataSource(outBound)
    outLyr = outShp.CreateLayer(fprop(outBound, 'fn', forceLower=True),
                                SRS,
                                geom_type=ogr.wkbPolygon)

    outDefn = outLyr.GetLayerDefn()

    for feat in lyr:
        __feat = ogr.Feature(outDefn)
        ring = ogr.Geometry(ogr.wkbLinearRing)

        geom = feat.GetGeometryRef()
        X, Y = geom.GetX(), geom.GetY()

        boundary_points = [
            new_pnt(X - distMeters, Y + distMeters),  # Topleft
            new_pnt(X + distMeters, Y + distMeters),  # TopRight
            new_pnt(X + distMeters, Y - distMeters),  # Lower Right
            new_pnt(X - distMeters, Y - distMeters),  # Lower Left
            new_pnt(X - distMeters, Y + distMeters)
        ]

        for pnt in boundary_points:
            ring.AddPoint(pnt.GetX(), pnt.GetY())

        polygon = ogr.Geometry(ogr.wkbPolygon)
        polygon.AddGeometry(ring)

        __feat.SetGeometry(polygon)

        outLyr.CreateFeature(__feat)

        feat.Destroy()

        __feat = None
        ring = None
        polygon = None

    shp.Destroy()
    outShp.Destroy()

    return outBound
Exemplo n.º 2
0
def get_ext(inFile, outEpsg=None):
    """
    Get Extent of any GIS Data
    
    return None if inFile is not a GIS File
    """

    from glass.g.prop import check_isRaster, check_isShp

    if check_isRaster(inFile):
        from glass.g.prop.rst import rst_ext

        extent = rst_ext(inFile)

    else:
        if check_isShp(inFile):
            from glass.g.prop.feat import get_ext as gext

            extent = gext(inFile)

        else:
            return None

    if outEpsg:
        from glass.g.prop.prj import get_epsg

        fileEpsg = get_epsg(inFile)

        if not fileEpsg:
            raise ValueError('cannot get EPSG of input file')

        if fileEpsg != outEpsg:
            from glass.g.gobj import new_pnt
            from glass.g.prj.obj import prj_ogrgeom

            bt_left = prj_ogrgeom(new_pnt(extent[0], extent[2]),
                                  fileEpsg,
                                  outEpsg,
                                  api='ogr' if outEpsg != 4326 else 'shapely')
            top_right = prj_ogrgeom(
                new_pnt(extent[1], extent[3]),
                fileEpsg,
                outEpsg,
                api='ogr' if outEpsg != 4326 else 'shapely')

            left, bottom = bt_left.GetX(), bt_left.GetY()
            right, top = top_right.GetX(), top_right.GetY()

            extent = [left, right, bottom, top]

    return extent
Exemplo n.º 3
0
def xy_to_buffer(x, y, radius):
    """
    XY Coordinates to Buffer Geometry
    """

    from glass.g.gobj import new_pnt

    pnt = new_pnt(x, y)

    return pnt.Buffer(int(round(float(radius), 0)))
Exemplo n.º 4
0
def get_random_point(minX, maxX, minY, maxY):
    """
    Create a Single Random Point
    """

    import random
    from glass.g.gobj import new_pnt

    x = minX + (random.random() * (maxX - minX))
    y = minY + (random.random() * (maxY - minY))

    pnt = new_pnt(x, y)

    return pnt
Exemplo n.º 5
0
def getBufferParam(inArea, inAreaSRS, outSRS=4326):
    """
    Get Buffer X, Y Center and radius in any SRS (radius in meteres).
    
    Check the type of the 'inArea' Object and return the interest values.
    
    inArea could be a file, dict, list or tuple
    """

    import os
    from osgeo import ogr
    from glass.g.gobj import new_pnt
    from glass.g.prj.obj import prj_ogrgeom

    TYPE = type(inArea)

    if TYPE == str:
        # Assuming that inArea is a file

        # Check if exists
        if os.path.exists(inArea):
            if os.path.isfile(inArea):
                from glass.g.tbl.filter import geom_by_idx

                # Get Geometry object
                BUFFER_GEOM = geom_by_idx(inArea, 0)

                # To outSRS
                if int(inAreaSRS) != outSRS:
                    BUFFER_GEOM = prj_ogrgeom(
                        ogr.CreateGeometryFromWkt(BUFFER_GEOM), inAreaSRS,
                        outSRS).ExportToWkt()

                # Get x_center, y_center and radius
                xyr = bf_prop(BUFFER_GEOM, outSRS, isFile=None)
                x_center, y_center, dist = str(xyr['X']), str(xyr['Y']), str(
                    xyr['R'])

            else:
                raise ValueError('The given path exists but it is not a file')

        else:
            raise ValueError('The given path doesn\'t exist')

    elif TYPE == dict:
        X = 'x' if 'x' in inArea else 'X' if 'X' in inArea else \
            'lng' if 'lng' in inArea else None

        Y = 'y' if 'x' in inArea else 'Y' if 'Y' in inArea else \
            'lat' if 'lat' in inArea else None

        R = 'r' if 'r' in inArea else 'R' if 'R' in inArea else \
            'rad' if 'rad' in inArea else 'RADIUS' if 'RADIUS' in inArea \
            else 'radius' if 'radius' in inArea else None

        if not X or not Y or not R:
            raise ValueError(
                ('The keys used to identify the buffer properties '
                 'are not valid! '
                 'Please choose one of the following keys groups: '
                 'x, y, r; '
                 'X, Y, R; '
                 'lat, lng, rad'))

        else:
            x_center, y_center, dist = (str(inArea[X]), str(inArea[Y]),
                                        str(inArea[R]))

            if inAreaSRS != outSRS:
                pnt_wgs = prj_ogrgeom(new_pnt(x_center, y_center), inAreaSRS,
                                      outSRS)

                x_center, y_center = (pnt_wgs.GetX(), pnt_wgs.GetY())

    elif TYPE == list or TYPE == tuple:
        x_center, y_center, dist = inArea

        if inAreaSRS != outSRS:
            pnt_wgs = prj_ogrgeom(new_pnt(x_center, y_center), inAreaSRS,
                                  outSRS)

            x_center, y_center = (pnt_wgs.GetX(), pnt_wgs.GetY())

    else:
        raise ValueError(
            ('Please give a valid path to a shapefile or a tuple, dict or '
             'list with the x, y and radius values'))

    return x_center, y_center, dist
Exemplo n.º 6
0
def ogr_buffer(geom, radius, out_file, srs=None):
    """
    For each geometry in the input, this method create a buffer and store it
    in a vetorial file
    
    Accepts files or lists with geom objects as inputs
    """

    import os
    from osgeo import ogr
    from glass.g.prj import def_prj
    from glass.g.prop import drv_name
    from glass.g.prop.prj import get_sref_from_epsg
    from glass.g.gp.prox.bfing.obj import draw_buffer

    # Create output
    buffer_shp = ogr.GetDriverByName(
        drv_name(out_file)).CreateDataSource(out_file)

    buffer_lyr = buffer_shp.CreateLayer(
        os.path.splitext(os.path.basename(out_file))[0],
        get_sref_from_epsg(srs) if srs else None,
        geom_type=ogr.wkbPolygon)

    featDefn = buffer_lyr.GetLayerDefn()

    if type(geom) == list:
        for g in geom:
            feat = ogr.Feature(featDefn)
            feat.SetGeometry(draw_buffer(g, radius))

            buffer_lyr.CreateFeature(feat)

            feat = None

        buffer_shp.Destroy()

    elif type(geom) == dict:
        if 'x' in geom and 'y' in geom:
            X = 'x'
            Y = 'y'
        elif 'X' in geom and 'Y' in geom:
            X = 'X'
            Y = 'Y'
        else:
            raise ValueError(('Your geom dict has invalid keys. '
                              'Please use one of the following combinations: '
                              'x, y; '
                              'X, Y'))

        from glass.g.gobj import new_pnt

        feat = ogr.Feature(featDefn)
        g = new_pnt(geom[X], geom[Y])
        feat.SetGeometry(draw_buffer(g, radius))

        buffer_lyr.CreateFeature(feat)

        feat = None

        buffer_shp.Destroy()

        if srs:
            def_prj(out_file, epsg=srs)

    elif type(geom) == str:
        # Check if the input is a file
        if os.path.exists(geom):
            inShp = ogr.GetDriverByName(drv_name(geom)).Open(geom, 0)

            lyr = inShp.GetLayer()
            for f in lyr:
                g = f.GetGeometryRef()

                feat = ogr.Feature(featDefn)
                feat.SetGeometry(draw_buffer(g, radius))

                buffer_lyr.CreateFeature(feat)

                feat = None

            buffer_shp.Destroy()
            inShp.Destroy()

            if srs:
                def_prj(out_file, epsg=srs)
            else:
                def_prj(out_file, template=geom)

        else:
            raise ValueError('The given path does not exist')

    else:
        raise ValueError('Your geom input is not valid')

    return out_file
Exemplo n.º 7
0
def ext_to_rst(topLeft,
               btRight,
               outRst,
               cellsize=None,
               epsg=None,
               outEpsg=None,
               invalidResultAsNull=None,
               rstvalue=None):
    """
    Extent to Raster
    """

    import numpy
    from osgeo import gdal
    from glass.g.prop import drv_name

    left, top = topLeft
    right, bottom = btRight

    cellsize = 10 if not cellsize else cellsize

    if outEpsg and epsg and outEpsg != epsg:
        from glass.g.gobj import new_pnt
        from glass.g.gobj import create_polygon
        from glass.g.prj.obj import prj_ogrgeom

        extGeom = prj_ogrgeom(
            create_polygon([
                new_pnt(left, top),
                new_pnt(right, top),
                new_pnt(right, bottom),
                new_pnt(left, bottom),
                new_pnt(left, top)
            ]), epsg, outEpsg)

        epsg = outEpsg

        left, right, bottom, top = extGeom.GetEnvelope()

    # Get row and cols number
    rows = (float(top) - float(bottom)) / cellsize
    cols = (float(right) - float(left)) / cellsize

    rows = int(rows) if rows == int(rows) else int(rows) + 1
    cols = int(cols) if cols == int(cols) else int(cols) + 1

    if not invalidResultAsNull:
        if not rstvalue:
            NEW_RST_ARRAY = numpy.zeros((rows, cols))

        else:
            NEW_RST_ARRAY = numpy.full((rows, cols), rstvalue)
    else:
        try:
            if not rstvalue:
                NEW_RST_ARRAY = numpy.zeros((rows, cols))

            else:
                NEW_RST_ARRAY = numpy.full((rows, cols), rstvalue)
        except:
            return None

    # Create new Raster
    img = gdal.GetDriverByName(drv_name(outRst)).Create(
        outRst, cols, rows, 1, gdal.GDT_Byte)

    img.SetGeoTransform((left, cellsize, 0, top, 0, -cellsize))

    band = img.GetRasterBand(1)

    band.WriteArray(NEW_RST_ARRAY)

    if epsg:
        from osgeo import osr

        rstSrs = osr.SpatialReference()
        rstSrs.ImportFromEPSG(epsg)
        img.SetProjection(rstSrs.ExportToWkt())

    band.FlushCache()

    return outRst
Exemplo n.º 8
0
def download_by_boundary(input_boundary, folder_out, osm_name, epsg,
                         GetUrl=True, db_name=None, geomCol=None,
                         justOneFeature=None):
    """
    Download data from OSM using a bounding box
    """
    
    import os
    from osgeo         import ogr
    from glass.pys.web import get_file
    from glass.pys.oss import os_name
    
    OS_NAME = os_name()
    
    EXTENTS = []
    
    if db_name and geomCol:
        """
        Assuming input_boundary is a PostgreSQL Table
        """
        
        from glass.pys        import obj_to_lst
        from glass.g.prop.gql import tbl_ext
        
        for t in obj_to_lst(input_boundary):
            EXTENTS.append(tbl_ext(db_name, t, geomCol))
    
    else:
        if type(input_boundary) == dict:
            if 'top' in input_boundary and 'bottom' in input_boundary \
                and 'left' in input_boundary and 'right' in input_boundary:
                
                EXTENTS.append([
                    input_boundary['left'],input_boundary['right'],
                    input_boundary['bottom'], input_boundary['top']
                ])
        
            else:
                raise ValueError((
                    'input_boundary is a dict but the keys are not correct. '
                    'Please use left, right, top and bottom as keys'
                ))
    
        elif type(input_boundary) == list:
            if len(input_boundary) == 4:
                EXTENTS.append(input_boundary)
        
            else:
                raise ValueError((
                    'input boundary is a list with more than 4 objects. '
                    'The list should be like: '
                    'l = [left, right, bottom, top]'
                ))
    
        elif type(input_boundary) == ogr.Geometry:
            EXTENTS.append(input_boundary.GetEnvelope())
    
        else:
            # Assuming input boundary is a file
        
            #Check if file exists
            if not os.path.exists(input_boundary):
                raise ValueError((
                    "Sorry, but the file {} does not exist inside the folder {}!"
                ).format(
                    os.path.basename(input_boundary),
                    os.path.dirname(input_boundary)
                ))
        
            # Check if is a raster
            from glass.g.prop import check_isRaster
            isRst = check_isRaster(input_boundary)
        
            # Get EPSG
            if not epsg:
                from glass.g.prop.prj import get_epsg
            
                epsg = get_epsg(input_boundary)
        
            if isRst:
                from glass.g.prop.rst import rst_ext
            
                # Get raster extent
                EXTENTS.append(rst_ext(input_boundary))
        
            else:
                from glass.g.prop import drv_name
                
                # Todo: check if it is shape
                
                # Open Dataset
                inSrc = ogr.GetDriverByName(drv_name(
                    input_boundary)).Open(input_boundary)
                
                lyr = inSrc.GetLayer()
                
                i = 1
                for feat in lyr:
                    geom = feat.GetGeometryRef()
                    
                    featext = geom.GetEnvelope()
                    
                    EXTENTS.append(featext)
                    
                    if justOneFeature:
                        break
    
    if epsg != 4326:
        from glass.g.gobj import new_pnt
        from glass.g.prj.obj  import prj_ogrgeom
        
        for i in range(len(EXTENTS)):
            bottom_left = prj_ogrgeom(new_pnt(
                EXTENTS[i][0], EXTENTS[i][2]), epsg, 4326)
        
            top_right   = prj_ogrgeom(new_pnt(
                EXTENTS[i][1], EXTENTS[i][3]), epsg, 4326)
        
            left , bottom = bottom_left.GetX(), bottom_left.GetY()
            right, top    = top_right.GetX()  , top_right.GetY()
            
            EXTENTS[i] = [left, right, bottom, top]
    
    #url = "https://overpass-api.de/api/map?bbox={}"
    url = "https://lz4.overpass-api.de/api/interpreter?bbox={}"
    
    RESULTS = []
    for e in range(len(EXTENTS)):
        bbox_str = ','.join([str(p) for p in EXTENTS[e]])
        
        if GetUrl:
            RESULTS.append(url.format(bbox_str))
            continue
        
        if len(EXTENTS) == 1:
            outOsm = os.path.join(folder_out, osm_name + '.xml')
        else:
            outOsm = os.path.join(folder_out, "{}_{}.xml".format(osm_name, str(e)))
        
        osm_file = get_file(
            url.format(bbox_str), outOsm,
            useWget=None if OS_NAME == 'Windows' else None
        )
        
        RESULTS.append(osm_file)
    
    return RESULTS[0] if len(RESULTS) == 1 else RESULTS
Exemplo n.º 9
0
Arquivo: rst.py Projeto: jasp382/glass
def adjust_ext_to_snap(outExt, snapRst):
    """
    Adjust extent for a output raster to snap with other raster
    """

    from glass.g.prop import check_isShp, check_isRaster
    from glass.g.prop.rst import rst_ext, get_cellsize
    from glass.g.gobj import new_pnt, create_polygon

    # Check if outExt is a raster or not
    isRst = check_isRaster(outExt)

    if isRst:
        shpAExt = rst_ext(outExt)

    else:
        isShp = check_isShp(outExt)

        if isShp:
            from glass.g.prop.feat import get_ext

            shpAExt = get_ext(outExt)

        else:
            raise ValueError(
                ("outExt value should be a path to a SHP or to a Raster file"))

    # Check if snapRst is a raster
    isRst = check_isRaster(snapRst)

    if not isRst:
        raise ValueError(("snapRst should be a path to a raster file"))

    # Get snapRst Extent
    snapRstExt = rst_ext(snapRst)

    # Get cellsize
    csize = get_cellsize(snapRst)

    # Find extent point of outExt inside the two extents
    # This will be used as pseudo origin

    snapRstPnt = [
        new_pnt(snapRstExt[0], snapRstExt[3]),
        new_pnt(snapRstExt[1], snapRstExt[3]),
        new_pnt(snapRstExt[1], snapRstExt[2]),
        new_pnt(snapRstExt[0], snapRstExt[2]),
        new_pnt(snapRstExt[0], snapRstExt[3]),
    ]

    poly_snap_rst = create_polygon(snapRstPnt)

    outExtPnt = {
        'top_left': new_pnt(shpAExt[0], shpAExt[3]),
        'top_right': new_pnt(shpAExt[1], shpAExt[3]),
        'bottom_right': new_pnt(shpAExt[1], shpAExt[2]),
        'bottom_left': new_pnt(shpAExt[0], shpAExt[2])
    }

    out_rst_pseudo = {}
    for pnt in outExtPnt:
        out_rst_pseudo[pnt] = outExtPnt[pnt].Intersects(poly_snap_rst)

    pseudoOrigin = outExtPnt['top_left'] if out_rst_pseudo['top_left'] else \
        outExtPnt['bottom_left'] if out_rst_pseudo['bottom_left'] else \
        outExtPnt['top_right'] if out_rst_pseudo['top_right'] else \
        outExtPnt['bottom_right'] if out_rst_pseudo['bottom_right'] else None

    if not pseudoOrigin:
        raise ValueError(('Extents doesn\'t have overlapping areas'))

    pseudoOriginName = 'top_left' if out_rst_pseudo['top_left'] else \
        'bottom_left' if out_rst_pseudo['bottom_left'] else \
        'top_right' if out_rst_pseudo['top_right'] else \
        'bottom_right' if out_rst_pseudo['bottom_right'] else None

    # Get out Raster Shape
    n_col = int((shpAExt[1] - shpAExt[0]) / csize)
    n_row = int((shpAExt[3] - shpAExt[2]) / csize)

    # Get Output Raster real origin/top left
    yName, xName = pseudoOriginName.split('_')

    if xName == 'left':
        # Obtain left of output Raster
        left_out_rst = snapRstExt[0] + (csize * int(
            (shpAExt[0] - snapRstExt[0]) / csize))

    else:
        # obtain right of output Raster
        right_out_rst = snapRstExt[1] - (csize * int(
            (snapRstExt[1] - shpAExt[1]) / csize))

        # Use right to obtain left coordinate
        left_out_rst = right_out_rst - (n_col * csize)

    if yName == 'top':
        # Obtain top of output Raster
        top_out_rst = snapRstExt[3] - (csize * int(
            (snapRstExt[3] - shpAExt[3]) / csize))

    else:
        # obtain bottom of output raster
        bot_out_rst = snapRstExt[2] + (csize * int(
            (shpAExt[2] - snapRstExt[2]) / csize))

        # use bottom to find the top of the output raster
        top_out_rst = bot_out_rst + (n_row * csize)

    return left_out_rst, top_out_rst, n_row, n_col, csize