Beispiel #1
0
def feat_to_pnt(inShp, outPnt, epsg=None):
    """
    Get Centroid from each line in a PolyLine Feature Class
    """

    import os
    from osgeo import ogr
    from gasp.gt.prop.ff import drv_name
    from gasp.g.lyr.fld import copy_flds
    from gasp.gt.prop.feat import lst_fld

    # TODO: check if geometry is correct

    # Open data
    polyData = ogr.GetDriverByName(drv_name(outPnt)).Open(inShp)

    polyLyr = polyData.GetLayer()

    # Get SRS for the output
    if not epsg:
        from gasp.gt.prop.prj import get_shp_sref
        srs = get_shp_sref(polyLyr)

    else:
        from gasp.gt.prop.prj import get_sref_from_epsg
        srs = get_sref_from_epsg(epsg)

    # Create output
    pntData = ogr.GetDriverByName(drv_name(outPnt)).CreateDataSource(outPnt)

    pntLyr = pntData.CreateLayer(os.path.splitext(os.path.basename(outPnt))[0],
                                 srs,
                                 geom_type=ogr.wkbPoint)

    # Copy fields from input to output
    fields = lst_fld(polyLyr)
    copy_flds(polyLyr, pntLyr)

    pntLyrDefn = pntLyr.GetLayerDefn()
    for feat in polyLyr:
        geom = feat.GetGeometryRef()

        pnt = geom.Centroid()

        new_feat = ogr.Feature(pntLyrDefn)
        new_feat.SetGeometry(pnt)

        for fld in fields:
            new_feat.SetField(fld, feat.GetField(fld))

        pntLyr.CreateFeature(new_feat)

        new_feat.Destroy()

    del pntLyr
    del polyLyr
    pntData.Destroy()
    polyData.Destroy()

    return outPnt
Beispiel #2
0
def pnts_to_boundary(pntShp, outBound, distMeters):
    """
    Create a boundary from Point using a tolerance in meters
    """
    
    from osgeo            import ogr
    from gasp.pyt.oss     import fprop
    from gasp.gt.prop.ff  import drv_name
    from gasp.g.to        import new_pnt
    from gasp.gt.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
Beispiel #3
0
def sel_by_loc(shp, boundary_filter, filtered_output):
    """
    Filter a shp using the location of a boundary_filter shp
    
    For now the boundary must have only one feature
    
    Writes the filter on a new shp
    """

    import os
    from osgeo import ogr
    from gasp.gt.prop.ff import drv_name
    from gasp.gt.prop.feat import get_gtype
    from gasp.g.lyr.fld import copy_flds
    from gasp.gt.toshp import copy_feat
    from gasp.pyt.oss import fprop

    # Open main data
    dtSrc = ogr.GetDriverByName(drv_name(shp)).Open(shp, 0)
    lyr = dtSrc.GetLayer()

    # Get filter geom
    filter_shp = ogr.GetDriverByName(drv_name(boundary_filter)).Open(
        boundary_filter, 0)
    filter_lyr = filter_shp.GetLayer()

    c = 0
    for f in filter_lyr:
        if c:
            break
        geom = f.GetGeometryRef()
        c += 1

    filter_shp.Destroy()

    # Apply filter
    lyr.SetSpatialFilter(geom)

    # Copy filter objects to a new shape
    out = ogr.GetDriverByName(
        drv_name(filtered_output)).CreateDataSource(filtered_output)

    outLyr = out.CreateLayer(fprop(filtered_output, 'fn'),
                             geom_type=get_gtype(shp,
                                                 gisApi='ogr',
                                                 name=None,
                                                 py_cls=True))

    # Copy fields
    copy_flds(lyr, outLyr)

    copy_feat(lyr,
              outLyr,
              outDefn=outLyr.GetLayerDefn(),
              only_geom=False,
              gisApi='ogrlyr')
Beispiel #4
0
def get_cntr_bnd(shp, isFile=None):
    """
    Return centroid (OGR Point object) of a Boundary (layer with a single
    feature).
    """

    from osgeo import ogr
    from gasp.gt.prop.ff import drv_name

    if isFile:
        shp = ogr.GetDriverByName(drv_name(shp)).Open(shp, 0)

        lyr = shp.GetLayer()

        feat = lyr[0]
        geom = feat.GetGeometryRef()

    else:
        geom = shp

    centroid = geom.Centroid()

    cnt = ogr.CreateGeometryFromWkt(centroid.ExportToWkt())

    shp.Destroy()

    return cnt
Beispiel #5
0
def lst_fld(shp):
    """
    Return a list with every field name in a vectorial layer
    """

    from osgeo import ogr
    from gasp.gt.prop.ff import drv_name

    if type(shp) == ogr.Layer:
        lyr = shp
        c = 0

    else:
        data = ogr.GetDriverByName(drv_name(shp)).Open(shp, 0)

        lyr = data.GetLayer()
        c = 1

    defn = lyr.GetLayerDefn()

    fields = []
    for i in range(0, defn.GetFieldCount()):
        fdefn = defn.GetFieldDefn(i)
        fields.append(fdefn.name)

    if c:
        del lyr
        data.Destroy()

    return fields
Beispiel #6
0
def rst_val_to_points(pnt, rst):
    """
    Extract, for a given point dataset, the value of a cell with the same location
    
    Returns a dict:
    
    d = {
        fid: value,
        ...
    }
    """

    from osgeo import ogr, gdal
    from gasp.gt.prop.ff import drv_name

    values_by_point = {}
    shp = ogr.GetDriverByName(drv_name(pnt)).Open(pnt, 0)
    lyr = shp.GetLayer()

    img = gdal.Open(rst)
    geo_transform = img.GetGeoTransform()
    band = img.GetRasterBand(1)

    for feat in lyr:
        geom = feat.GetGeometryRef()
        mx, my = geom.GetX(), geom.GetY()
        px = int((mx - geo_transform[0]) / geo_transform[1])
        py = int((my - geo_transform[3]) / geo_transform[5])

        val_pix = band.ReadAsArray(px, py, 1, 1)

        values_by_point[int(feat.GetFID())] = float(val_pix[0][0])

    return values_by_point
Beispiel #7
0
def area_to_dic(shp):
    """
    Return the following output:
    
    dic = {
        id_feat: area,
        ...,
        id_feat: area
    }
    """

    from osgeo import ogr
    from gasp.gt.prop.ff import drv_name

    o = ogr.GetDriverByName(drv_name(shp)).Open(shp, 0)
    l = o.GetLayer()
    d = {}
    c = 0
    for feat in l:
        g = feat.GetGeometryRef()
        area = g.GetArea()
        d[c] = area
        c += 1
    del l
    o.Destroy()
    return d
Beispiel #8
0
def geom_by_idx(inShp, idx):
    """
    Get Geometry by index in file
    """

    from osgeo import ogr
    from gasp.gt.prop.ff import drv_name

    src = ogr.GetDriverByName(drv_name(inShp)).Open(inShp)
    lyr = src.GetLayer()

    c = 0
    geom = None
    for f in lyr:
        if idx == c:
            geom = f.GetGeometryRef()

        else:
            c += 1

    if not geom:
        raise ValueError("inShp has not idx")

    _geom = geom.ExportToWkt()

    del lyr
    src.Destroy()

    return _geom
Beispiel #9
0
def ogr_list_fields_defn(shp):
    """
    Return a dict with the field name as key and the field definition as value
    
    Field defn is the same of saying name + type
    """
    
    if type(shp) == ogr.Layer:
        lyr = shp
        c   = 0
    
    else:
        data = ogr.GetDriverByName(
            drv_name(shp)).Open(shp, 0) 
        lyr = data.GetLayer()
        c   = 1
    
    defn = lyr.GetLayerDefn()
    
    fields = {}
    for i in range(0, defn.GetFieldCount()):
        fdefn = defn.GetFieldDefn(i)
        fieldType = fdefn.GetFieldTypeName(fdefn.GetType())
        
        fields[fdefn.name] = {fdefn.GetType(): fieldType}
    
    if c:
        del lyr
        data.Destroy()
    
    return fields
Beispiel #10
0
def get_shp_sref(shp):
    """
    Get Spatial Reference Object from Feature Class/Lyr
    """

    from osgeo import ogr
    from gasp.gt.prop.ff import drv_name

    if type(shp) == ogr.Layer:
        lyr = shp

        c = 0

    else:
        data = ogr.GetDriverByName(drv_name(shp)).Open(shp)

        lyr = data.GetLayer()
        c = 1

    spref = lyr.GetSpatialRef()

    if c:
        del lyr
        data.Destroy()

    return spref
Beispiel #11
0
def obj_to_rst(inArray, outRst, template, noData=None, geotrans=None):
    """
    Send Array to Raster
    
    API Available:
    * gdal;
    """

    gisApi = 'gdal'

    if gisApi == 'gdal':
        from osgeo import gdal, osr, gdal_array
        from gasp.gt.prop.ff import drv_name
        from gasp.gt.prop.rst import compress_option

        if type(template).__name__ == 'Dataset':
            img_template = template
        else:
            img_template = gdal.Open(template)

        geo_transform = img_template.GetGeoTransform() if not geotrans else \
            geotrans
        rows, cols = inArray.shape
        drv_n = drv_name(outRst)
        driver = gdal.GetDriverByName(drv_n)

        c_opt = compress_option(drv_n)
        if c_opt:
            out = driver.Create(outRst,
                                cols,
                                rows,
                                1,
                                gdal_array.NumericTypeCodeToGDALTypeCode(
                                    inArray.dtype),
                                options=[c_opt])
        else:
            out = driver.Create(
                outRst, cols, rows, 1,
                gdal_array.NumericTypeCodeToGDALTypeCode(inArray.dtype))
        out.SetGeoTransform(geo_transform)
        outBand = out.GetRasterBand(1)

        if noData:
            outBand.SetNoDataValue(noData)

        outBand.WriteArray(inArray)

        proj = osr.SpatialReference(wkt=img_template.GetProjection())

        if proj:
            out.SetProjection(img_template.GetProjection())

        outBand.FlushCache()

    else:
        raise ValueError('The api {} is not available'.format(gisApi))

    return outRst
Beispiel #12
0
def statistics_by_line_feat(lines, raster, statistic, new_field):
    """
    Estimates raster statistic per line on a linear feature class
    
    statistic = statistic type (e.g. max, min, mean, sum)
    
    This method has an important problem - depends on the
    number of vertex of each features
    
    TODO: convert lines to raster and use the raster to get the statistics
    of each line
    """

    from osgeo import ogr, gdal
    from gasp.gt.prop.ff import drv_name
    from gasp.gt.sample import pnt_val_on_rst

    # Open feature class
    shp = ogr.GetDriverByName(drv_name(lines)).Open(lines, 1)
    lyr = shp.GetLayer()
    # Create new field
    lyr.CreateField(ogr.FieldDefn(new_field, ogr.OFTReal))

    # Open Raster
    img = gdal.Open(raster)
    geo_transform = img.GetGeoTransform()
    band = img.GetRasterBand(1)

    # For feature in layer
    for feat in lyr:
        rst_values = []
        # For point in line
        lnh = feat.GetGeometryRef()
        num_pnt = lnh.GetPointCount()
        for pnt in range(num_pnt):
            x, y, z = lnh.GetPoint(pnt)
            cell = pnt_val_on_rst(x, y, band, geo_transform)
            if not cell:
                continue
            else:
                rst_values.append(cell)

        if len(rst_values):
            if statistic == 'minimum':
                value = min(rst_values)
            elif statistic == 'maximum':
                value = max(rst_values)
            elif statistic == 'mean':
                value = sum(rst_values) / len(rst_values)
            elif statistic == 'sum':
                value = sum(rst_values)

        else:
            continue

        feat.SetField(new_field, value)
        lyr.SetFeature(feat)
Beispiel #13
0
def get_attr_values_in_location(inShp, attr, geomFilter=None, shpFilter=None):
    """
    Get attributes of the features of inShp that intersects with geomFilter
    or shpFilter
    """

    from osgeo import ogr
    from gasp.gt.prop.ff import drv_name

    if not geomFilter and not shpFilter:
        raise ValueError(
            'A geom object or a path to a sho file should be given')

    if shpFilter:
        # For now the shpFilter must have only one feature
        filter_shp = ogr.GetDriverByName(drv_name(shpFilter)).Open(
            shpFilter, 0)

        filter_lyr = filter_shp.GetLayer()
        c = 0
        for f in filter_lyr:
            if c:
                break

            geom = f.GetGeometryRef()
            c += 1

        filter_shp.Destroy()

    else:
        geom = geomFilter

    # Open Main data
    dtSrc = ogr.GetDriverByName(drv_name(inShp)).Open(inShp, 0)
    lyr = dtSrc.GetLayer()

    lyr.SetSpatialFilter(geom)

    # Get attribute values
    ATTRIBUTE_VAL = [feat.GetField(attr) for feat in lyr]

    dtSrc.Destroy()

    return ATTRIBUTE_VAL
Beispiel #14
0
def clip(inFeat, clipFeat, outFeat, api_gis="grass", clip_by_region=None):
    """
    Clip Analysis
    
    api_gis Options:
    * grass
    * pygrass
    * ogr2ogr
    """

    if api_gis == "pygrass":
        from grass.pygrass.modules import Module

        if not clip_by_region:
            vclip = Module("v.clip",
                           input=inFeat,
                           clip=clipFeat,
                           output=outFeat,
                           overwrite=True,
                           run_=False,
                           quiet=True)
        else:
            vclip = Module("v.clip",
                           input=inFeat,
                           output=outFeat,
                           overwrite=True,
                           flags='r',
                           run_=False,
                           quiet=True)

        vclip()

    elif api_gis == "grass":
        from gasp import exec_cmd

        rcmd = exec_cmd(
            "v.clip input={}{} output={} {}--overwrite --quiet".format(
                inFeat, " clip={}".format(clipFeat) if clipFeat else "",
                outFeat, "-r " if not clipFeat else ""))

    elif api_gis == 'ogr2ogr':
        from gasp import exec_cmd
        from gasp.pyt.oss import fprop
        from gasp.gt.prop.ff import drv_name

        rcmd = exec_cmd(
            ("ogr2ogr -f \"{}\" {} {} -clipsrc {} -clipsrclayer {}").format(
                drv_name(outFeat), outFeat, inFeat, clipFeat,
                fprop(clipFeat, 'fn')))

    else:
        raise ValueError("{} is not available!".format(api_gis))

    return outFeat
Beispiel #15
0
def gpkgrst_to_rst(gpkg, tbl, outrst):
    """
    Convert Raster in GeoPackage to single file
    """

    from gasp import exec_cmd
    from gasp.gt.prop.ff import drv_name

    rcmd = exec_cmd("gdal_translate -of {} {} {} -b 1 -oo TABLE={}".format(
        drv_name(outrst), gpkg, outrst, tbl))

    return outrst
Beispiel #16
0
def rst_to_rst(inRst, outRst):
    """
    Convert a raster file to another raster format
    """

    from gasp import exec_cmd
    from gasp.gt.prop.ff import drv_name

    outDrv = drv_name(outRst)
    cmd = 'gdal_translate -of {drv} {_in} {_out}'.format(drv=outDrv,
                                                         _in=inRst,
                                                         _out=outRst)

    cmdout = exec_cmd(cmd)

    return outRst
Beispiel #17
0
def shpext_to_boundshp(inShp, outShp, epsg=None):
    """
    Read one feature class extent and create a boundary with that
    extent
    
    The outFile could be a Feature Class or one Raster Dataset
    """
    
    import os
    from osgeo           import ogr
    from gasp.gt.prop.ff import drv_name
    from gasp.pyt.oss    import fprop
    from gasp.g.to       import new_pnt
    from gasp.g.to       import shpext_to_boundary
    
    # Get SRS for the output
    if not epsg:
        from gasp.gt.prop.prj import get_shp_sref
        
        srs = get_shp_sref(inShp)
    
    else:
        from gasp.gt.prop.prj import get_sref_from_epsg
        
        srs= get_sref_from_epsg(epsg)
    
    # Write new file
    shp = ogr.GetDriverByName(
        drv_name(outShp)).CreateDataSource(outShp)
    
    lyr = shp.CreateLayer(
        fprop(outShp, 'fn', forceLower=True),
        srs, geom_type=ogr.wkbPolygon
    )
    
    outDefn = lyr.GetLayerDefn()
    
    feat = ogr.Feature(outDefn)
    polygon = shpext_to_boundary(inShp)
    
    feat.SetGeometry(polygon)
    lyr.CreateFeature(feat)
    
    feat.Destroy()
    shp.Destroy()
    
    return outShp
Beispiel #18
0
def dic_buffer_array_to_shp(arrayBf, outShp, epsg, fields=None):
    """
    Array with dict with buffer proprieties to Feature Class
    """

    import os
    from osgeo import ogr
    from gasp.gt.prop.ff import drv_name
    from gasp.gt.prop.prj import get_sref_from_epsg

    # Get SRS for output
    srs = get_sref_from_epsg(epsg)

    # Create output DataSource and Layer
    outData = ogr.GetDriverByName(drv_name(outShp)).CreateDataSource(outShp)

    lyr = outData.CreateLayer(os.path.splitext(os.path.basename(outShp))[0],
                              srs,
                              geom_type=ogr.wkbPolygon)

    # Create fields
    if fields:
        from gasp.g.lyr.fld import fields_to_lyr

        fields_to_lyr(lyr, fields)

    lyrDefn = lyr.GetLayerDefn()
    for _buffer in arrayBf:
        newFeat = ogr.Feature(lyrDefn)

        geom = coord_to_buffer(_buffer["X"], _buffer["Y"], _buffer["RADIUS"])

        newFeat.SetGeometry(geom)

        for field in fields:
            if field in _buffer.keys():
                newFeat.SetField(field, _buffer[field])

        lyr.CreateFeature(newFeat)

        newFeat.Destroy()

    del lyrDefn
    outData.Destroy()

    return outShp
Beispiel #19
0
def feat_count(shp, gisApi='pandas', work=None, loc=None):
    """
    Count the number of features in a feature class
    
    API'S Available:
    * gdal;
    * arcpy;
    * pygrass;
    * pandas;
    """

    if gisApi == 'ogr':
        from osgeo import ogr
        from gasp.gt.prop.ff import drv_name

        data = ogr.GetDriverByName(drv_name(shp)).Open(shp, 0)
        lyr = data.GetLayer()
        fcnt = int(lyr.GetFeatureCount())
        data.Destroy()

    elif gisApi == 'grass':
        if not work or not loc:
            raise ValueError(
                ("If gisApi=='grass', work and loc must be defined!"))

        import os
        from gasp.sql.i import row_num

        db = os.path.join(work, loc, 'PERMANENT', 'sqlite', 'sqlite.db')

        fcnt = row_num(db, shp, api='sqlite')

    elif gisApi == 'pandas':
        from gasp.gt.fmshp import shp_to_obj

        gdf = shp_to_obj(shp)

        fcnt = int(gdf.shape[0])

        del gdf

    else:
        raise ValueError('The api {} is not available'.format(gisApi))

    return fcnt
Beispiel #20
0
def clip_rst(raster, clipShp, outRst, nodataValue=None, api='gdal'):
    """
    Clip Raster using GDAL WARP
    """

    if api == 'gdal':
        from gasp import exec_cmd
        from gasp.gt.prop.ff import drv_name

        outcmd = exec_cmd(
            ("gdalwarp {ndata}-cutline {clipshp} -crop_to_cutline "
             "-of {ext} {inraster} -overwrite {outrst}").format(
                 clipshp=clipShp,
                 inraster=raster,
                 outrst=outRst,
                 ext=drv_name(outRst),
                 ndata="-dstnodata {} ".format(str(nodataValue))
                 if nodataValue else ""))

    elif api == 'pygrass':
        from grass.pygrass.modules import Module

        m = Module('r.clip',
                   input=raster,
                   output=outRst,
                   overwrite=True,
                   run_=False,
                   quiet=True)

        m()

    elif api == 'grass':
        from gasp import exec_cmd

        rcmd = exec_cmd('r.clip input={} output={} --overwrite --quiet'.format(
            raster, outRst))

    else:
        raise ValueError('API {} is not available'.format(api))

    return outRst
Beispiel #21
0
def rst_val_to_points2(pntShp, listRasters):
    """
    Pick raster value for each point in pntShp
    """

    from osgeo import ogr
    from gasp.pyt import obj_to_lst
    from gasp.gt.prop.ff import drv_name

    listRasters = obj_to_lst(listRasters)

    shp = ogr.GetDriverByName(drv_name(pntShp)).Open(pnt, 0)

    lyr = shp.GetLayer()

    pntDict = {}
    for feat in lyr:
        geom = feat.GetGeometryRef()

        x, y = geom.GetX(), geom.GetY()

        l = []
        for rst in listRasters:
            img = gdal.Open(rst)
            geo_transform = img.GetGeoTransform()
            band = img.GetRasterBand(1)

            px = int((x - geo_transform[0]) / geo_transform[1])
            py = int((y - geo_transform[3]) / geo_transform[5])
            value = band.ReadAsArray(px, py, 1, 1)

            l.append(list(value)[0])

            del img, geo_transform, band, px, py

        pntDict[feat.GetFID()] = l

    shp.Destroy()

    return pntDict
Beispiel #22
0
def comp_bnds(rsts, outRst):
    """
    Composite Bands
    """

    from osgeo import gdal, gdal_array
    from gasp.gt.fmrst import rst_to_array
    from gasp.gt.prop.ff import drv_name
    from gasp.gt.prop.rst import get_nodata
    from gasp.gt.prop.prj import get_rst_epsg, epsg_to_wkt

    # Get Arrays
    _as = [rst_to_array(r) for r in rsts]

    # Get nodata values
    nds = [get_nodata(r) for r in rsts]

    # Assume that first raster is the template
    img_temp = gdal.Open(rsts[0])
    geo_tran = img_temp.GetGeoTransform()
    band = img_temp.GetRasterBand(1)
    dataType = gdal_array.NumericTypeCodeToGDALTypeCode(_as[0].dtype)
    rows, cols = _as[0].shape
    epsg = get_rst_epsg(rsts[0])

    # Create Output
    drv = gdal.GetDriverByName(drv_name(outRst))
    out = drv.Create(outRst, cols, rows, len(_as), dataType)
    out.SetGeoTransform(geo_tran)
    out.SetProjection(epsg_to_wkt(epsg))

    # Write all bands
    for i in range(len(_as)):
        outBand = out.GetRasterBand(i + 1)
        outBand.SetNoDataValue(nds[i])
        outBand.WriteArray(_as[i])

        outBand.FlushCache()

    return outRst
Beispiel #23
0
def shp_to_shp(inShp, outShp, gisApi='ogr', supportForSpatialLite=None):
    """
    Convert a vectorial file to another with other file format
    
    API's Available:
    * ogr;
    
    When using gisApi='ogr' - Set supportForSpatialLite to True if outShp is
    a sqlite db and if you want SpatialLite support for that database.
    """
    
    import os
    
    if gisApi == 'ogr':
        from gasp            import exec_cmd
        from gasp.gt.prop.ff import drv_name
        
        out_driver = drv_name(outShp)
    
        if out_driver == 'SQLite' and supportForSpatialLite:
            splite = ' -dsco "SPATIALITE=YES"'
        else:
            splite = ''
    
        cmd = 'ogr2ogr -f "{drv}" {out} {_in}{lite}'.format(
            drv=out_driver, out=outShp, _in=inShp,
            lite=splite
        )
    
        # Run command
        cmdout = exec_cmd(cmd)
    
    else:
        raise ValueError('Sorry, API {} is not available'.format(gisApi))
    
    return outShp
Beispiel #24
0
def get_ext(shp):
    """
    Return extent of a Vectorial file
    
    Return a tuple object with the follow order:
    (left, right, bottom, top)
    
    API'S Available:
    * ogr;
    """

    gisApi = 'ogr'

    if gisApi == 'ogr':
        from osgeo import ogr
        from gasp.gt.prop.ff import drv_name

        dt = ogr.GetDriverByName(drv_name(shp)).Open(shp, 0)
        lyr = dt.GetLayer()
        extent = lyr.GetExtent()

        dt.Destroy()

    return list(extent)
Beispiel #25
0
def coords_to_boundshp(topLeft, lowerRight, epsg, outshp,
                       outEpsg=None):
    """
    Top Left and Lower Right to Boundary
    """
    
    import os; from osgeo import ogr
    from gasp.gt.prop.ff  import drv_name
    from gasp.gt.prop.prj import get_sref_from_epsg
    from gasp.pyt.oss     import fprop
    from gasp.g.to        import coords_to_boundary

    # Get boundary geometry
    polygon = coords_to_boundary(topLeft, lowerRight, epsg, outEpsg=outEpsg)
    
    # Create outShapefile if a path is given
    shp = ogr.GetDriverByName(
        drv_name(outshp)).CreateDataSource(outshp)
    
    SRS_OBJ = get_sref_from_epsg(epsg) if not outEpsg else \
        get_sref_from_epsg(outEpsg)
    lyr = shp.CreateLayer(fprop(
        outshp, 'fn'), SRS_OBJ, geom_type=ogr.wkbPolygon
    )
    
    outDefn = lyr.GetLayerDefn()
    
    feat = ogr.Feature(outDefn)
    
    feat.SetGeometry(polygon)
    lyr.CreateFeature(feat)
    
    feat.Destroy()
    shp.Destroy()
    
    return outshp
Beispiel #26
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 gasp.gt.prj import def_prj
    from gasp.gt.prop.ff import drv_name
    from gasp.gt.prop.prj import get_sref_from_epsg
    from gasp.g.gop.prox 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 gasp.g.to 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
Beispiel #27
0
def rsts_to_mosaic(inRasterS, o, api="grass", fformat='.tif'):
    """
    Create Mosaic of Raster
    """

    if api == 'pygrass':
        """
        The GRASS program r.patch allows the user to build a new raster map the size
        and resolution of the current region by assigning known data values from
        input raster maps to the cells in this region. This is done by filling in
        "no data" cells, those that do not yet contain data, contain NULL data, or,
        optionally contain 0 data, with the data from the first input map.
        Once this is done the remaining holes are filled in by the next input map,
        and so on. This program is useful for making a composite raster map layer
        from two or more adjacent map layers, for filling in "holes" in a raster map
        layer's data (e.g., in digital elevation data), or for updating an older map
        layer with more recent data. The current geographic region definition and
        mask settings are respected.
        The first name listed in the string input=name,name,name, ... is the name of
        the first map whose data values will be used to fill in "no data" cells in
        the current region. The second through last input name maps will be used,
        in order, to supply data values for for the remaining "no data" cells.
        """

        from grass.pygrass.modules import Module
    
        m = Module(
            "r.patch", input=inRasterS, output=o,
            overwrite=True, run_=False, quiet=True
        )
    
        m()
    
    elif api == 'grass':
        from gasp import exec_cmd
        
        rcmd = exec_cmd("r.patch input={} output={} --overwrite --quiet".format(
            ",".join(inRasterS), o
        ))
    
    elif api == 'rasterio':
        import os;           import rasterio
        from rasterio.merge  import merge
        from gasp.gt.prop.ff import drv_name

        if type(inRasterS) != list:
            from gasp.pyt.oss import lst_ff

            rsts = lst_ff(inRasterS, file_format=fformat)
        else: rsts = inRasterS

        srcs = [rasterio.open(r) for r in rsts]

        mosaic, out_trans = merge(srcs)

        out_meta = srcs[0].meta.copy()

        out_meta.update({
            "driver"    : drv_name(o),
            "height"    : mosaic.shape[1],
            "width"     : mosaic.shape[2],
            "transform" : out_trans,
            "compress"  : 'lzw'
        })

        with rasterio.open(o, "w", **out_meta) as dest:
            dest.write(mosaic)
    
    else:
        raise ValueError('api {} is not available'.format(api))
    
    return o
Beispiel #28
0
def proj(inShp, outShp, outEPSG, inEPSG=None,
        gisApi='ogr', sql=None, db_name=None):
    """
    Project Geodata using GIS
    
    API's Available:
    * ogr;
    * ogr2ogr;
    * pandas;
    * ogr2ogr_SQLITE;
    * psql;
    """
    import os
    
    if gisApi == 'ogr':
        """
        Using ogr Python API
        """
        
        if not inEPSG:
            raise ValueError(
                'To use ogr API, you should specify the EPSG Code of the'
                ' input data using inEPSG parameter'
            )
        
        from osgeo             import ogr
        from gasp.g.lyr.fld    import copy_flds
        from gasp.gt.prop.feat import get_gtype
        from gasp.gt.prop.ff   import drv_name
        from gasp.gt.prop.prj  import get_sref_from_epsg, get_trans_param
        from gasp.pyt.oss      import fprop
        
        def copyShp(out, outDefn, lyr_in, trans):
            for f in lyr_in:
                g = f.GetGeometryRef()
                g.Transform(trans)
                new = ogr.Feature(outDefn)
                new.SetGeometry(g)
                for i in range(0, outDefn.GetFieldCount()):
                    new.SetField(outDefn.GetFieldDefn(i).GetNameRef(), f.GetField(i))
                out.CreateFeature(new)
                new.Destroy()
                f.Destroy()
        
        # ####### #
        # Project #
        # ####### #
        transP = get_trans_param(inEPSG, outEPSG)
        
        inData = ogr.GetDriverByName(
            drv_name(inShp)).Open(inShp, 0)
        
        inLyr = inData.GetLayer()
        out = ogr.GetDriverByName(
            drv_name(outShp)).CreateDataSource(outShp)
        
        outlyr = out.CreateLayer(
            fprop(outShp, 'fn'), get_sref_from_epsg(outEPSG),
            geom_type=get_gtype(
                inShp, name=None, py_cls=True, gisApi='ogr'
            )
        )
        
        # Copy fields to the output
        copy_flds(inLyr, outlyr)
        # Copy/transform features from the input to the output
        outlyrDefn = outlyr.GetLayerDefn()
        copyShp(outlyr, outlyrDefn, inLyr, transP)
        
        inData.Destroy()
        out.Destroy()
    
    elif gisApi == 'ogr2ogr':
        """
        Transform SRS of any OGR Compilant Data. Save the transformed data
        in a new file
        """

        if not inEPSG:
            from gasp.gt.prop.prj import get_epsg_shp
            inEPSG = get_epsg_shp(inShp)
        
        if not inEPSG:
            raise ValueError('To use ogr2ogr, you must specify inEPSG')
        
        from gasp            import exec_cmd
        from gasp.gt.prop.ff import drv_name
        
        cmd = (
            'ogr2ogr -f "{}" {} {}{} -s_srs EPSG:{} -t_srs EPSG:{}'
        ).format(
            drv_name(outShp), outShp, inShp,
            '' if not sql else ' -dialect sqlite -sql "{}"'.format(sql),
            str(inEPSG), str(outEPSG)
        )
        
        outcmd = exec_cmd(cmd)
    
    elif gisApi == 'ogr2ogr_SQLITE':
        """
        Transform SRS of a SQLITE DB table. Save the transformed data in a
        new table
        """
        
        from gasp import exec_cmd
        
        if not inEPSG:
            raise ValueError((
                'With ogr2ogr_SQLITE, the definition of inEPSG is '
                'demandatory.'
            ))
        
        # TODO: Verify if database is sqlite
        
        db, tbl = inShp['DB'], inShp['TABLE']
        sql = 'SELECT * FROM {}'.format(tbl) if not sql else sql
        
        outcmd = exec_cmd((
            'ogr2ogr -update -append -f "SQLite" {db} -nln "{nt}" '
            '-dialect sqlite -sql "{_sql}" -s_srs EPSG:{inepsg} '
            '-t_srs EPSG:{outepsg} {db}'
        ).format(
            db=db, nt=outShp, _sql=sql, inepsg=str(inEPSG),
            outepsg=str(outEPSG)
        ))
    
    elif gisApi == 'pandas':
        # Test if input Shp is GeoDataframe
        from gasp.gt.fmshp import shp_to_obj
        from gasp.gt.toshp import df_to_shp

        df = shp_to_obj(inShp)
        
        # Project df
        newDf = df.to_crs({'init' : 'epsg:{}'.format(str(outEPSG))})
        
        # Save as file 
            
        return df_to_shp(df, outShp)
    
    elif gisApi == 'psql':
        from gasp.sql.db      import create_db
        from gasp.pyt.oss     import fprop
        from gasp.gql.to      import shp_to_psql
        from gasp.gt.toshp.db import dbtbl_to_shp
        from gasp.gql.prj     import sql_proj

        # Create Database
        if not db_name:
            db_name = create_db(fprop(
                outShp, 'fn', forceLower=True), api='psql'
            )
        
        else:
            from gasp.sql.i import db_exists

            isDb = db_exists(db_name)

            if not isDb:
                create_db(db_name, api='psql')

        # Import Data
        inTbl = shp_to_psql(db_name, inShp, api='shp2pgsql', encoding="LATIN1")

        # Transform
        oTbl = sql_proj(
            db_name, inTbl, fprop(outShp, 'fn', forceLower=True),
            outEPSG, geomCol='geom', newGeom='geom'
        )

        # Export
        outShp = dbtbl_to_shp(
            db_name, oTbl, 'geom', outShp, api='psql', epsg=outEPSG
        )
    
    else:
        raise ValueError('Sorry, API {} is not available'.format(gisApi))
    
    return outShp
Beispiel #29
0
def rst_to_polyg(inRst, outShp, rstColumn=None, gisApi='gdal', epsg=None):
    """
    Raster to Polygon Shapefile
    
    Api's Available:
    * gdal;
    * qgis;
    * pygrass;
    * grass;
    """

    if gisApi == 'gdal':
        if not epsg:
            raise ValueError(
                ('Using GDAL, you must specify the EPSG CODE of the '
                 'Spatial Reference System of input raster.'))

        import os
        from osgeo import gdal, ogr, osr
        from gasp.gt.prop.ff import drv_name
        from gasp.pyt.oss import fprop

        src = gdal.Open(inRst)
        bnd = src.GetRasterBand(1)

        output = ogr.GetDriverByName(drv_name(ouShp)).CreateDataSource(outShp)

        srs = osr.SpatialReference()
        srs.ImportFromEPSG(epsg)

        lyr = output.CreateLayer(fprop(outShp, 'fn', forceLower=True), srs)

        lyr.CreateField(ogr.FieldDefn('VALUE', ogr.OFTInteger))
        gdal.Polygonize(bnd, None, lyr, 0, [], callback=None)

        output.Destroy()

    elif gisApi == 'qgis':
        import processing

        processing.runalg("gdalogr:polygonize", inRst, "value", outShp)

    elif gisApi == 'pygrass':
        from grass.pygrass.modules import Module

        rstField = "value" if not rstColumn else rstColumn

        rtop = Module("r.to.vect",
                      input=inRst,
                      output=outShp,
                      type="area",
                      column=rstField,
                      overwrite=True,
                      run_=False,
                      quiet=True)
        rtop()

    elif gisApi == 'grass':
        from gasp import exec_cmd

        rstField = "value" if not rstColumn else rstColumn

        rcmd = exec_cmd(("r.to.vect input={} output={} type=area column={} "
                         "--overwrite --quiet").format(inRst, outShp,
                                                       rstField))

    else:
        raise ValueError('Sorry, API {} is not available'.format(gisApi))

    return outShp
Beispiel #30
0
def shps_to_shp(shps, outShp, api="ogr2ogr", fformat='.shp', dbname=None):
    """
    Get all features in several Shapefiles and save them in one file

    api options:
    * ogr2ogr;
    * psql;
    * pandas;
    * psql;
    """

    import os

    if type(shps) != list:
        # Check if is dir
        if os.path.isdir(shps):
            from gasp.pyt.oss import lst_ff
            # List shps in dir
            shps = lst_ff(shps, file_format=fformat)

        else:
            raise ValueError((
                'shps should be a list with paths for Feature Classes or a path to '
                'folder with Feature Classes'))

    if api == "ogr2ogr":
        from gasp import exec_cmd
        from gasp.gt.prop.ff import drv_name

        out_drv = drv_name(outShp)

        # Create output and copy some features of one layer (first in shps)
        cmdout = exec_cmd('ogr2ogr -f "{}" {} {}'.format(
            out_drv, outShp, shps[0]))

        # Append remaining layers
        lcmd = [
            exec_cmd('ogr2ogr -f "{}" -update -append {} {}'.format(
                out_drv, outShp, shps[i])) for i in range(1, len(shps))
        ]

    elif api == 'pandas':
        """
        Merge SHP using pandas
        """

        from gasp.gt.fmshp import shp_to_obj
        from gasp.gt.toshp import df_to_shp

        if type(shps) != list:
            raise ValueError(
                'shps should be a list with paths for Feature Classes')

        dfs = [shp_to_obj(shp) for shp in shps]

        result = dfs[0]

        for df in dfs[1:]:
            result = result.append(df, ignore_index=True, sort=True)

        df_to_shp(result, outShp)

    elif api == 'psql':
        import os
        from gasp.sql.tbl import tbls_to_tbl, del_tables
        from gasp.gql.to import shp_to_psql

        if not dbname:
            from gasp.sql.db import create_db

            create_db(dbname, api='psql')

        pg_tbls = shp_to_psql(dbname, shps, api="shp2pgsql")

        if os.path.isfile(outShp):
            from gasp.pyt.oss import fprop
            outbl = fprop(outShp, 'fn')

        else:
            outbl = outShp

        tbls_to_tbl(dbname, pg_tbls, outbl)

        if outbl != outShp:
            from gasp.gt.toshp.db import dbtbl_to_shp

            dbtbl_to_shp(dbname,
                         outbl,
                         'geom',
                         outShp,
                         inDB='psql',
                         api="pgsql2shp")

        del_tables(dbname, pg_tbls)

    elif api == 'grass':
        from gasp import exec_cmd

        rcmd = exec_cmd(
            ("v.patch input={} output={} --overwrite --quiet").format(
                ",".join(shps), outShp))

    else:
        raise ValueError("{} API is not available")

    return outShp