Пример #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.prop.ff import drv_name
    from gasp.mng.fld import ogr_copy_fields
    from gasp.mng.fld 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.prop.prj import get_shp_sref
        srs = get_shp_sref(polyLyr)

    else:
        from gasp.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)
    ogr_copy_fields(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
Пример #2
0
def ogr_select_by_location(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.prop.ff import drv_name
    from gasp.prop.feat import get_geom_type
    from gasp.mng.gen import copy_feat
    from gasp.mng.fld import ogr_copy_fields

    # 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(os.path.splitext(
        os.path.basename(filtered_output))[0],
                             geom_type=get_geom_type(shp,
                                                     gisApi='ogr',
                                                     name=None,
                                                     py_cls=True))

    # Copy fields
    ogr_copy_fields(lyr, outLyr)

    copy_feat(lyr,
              outLyr,
              outDefn=outLyr.GetLayerDefn(),
              only_geom=False,
              gisApi='ogrlyr')
Пример #3
0
def get_shp_sref(shp):
    """
    Get Spatial Reference Object from Feature Class/Lyr
    """

    from osgeo import ogr
    from gasp.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
Пример #4
0
    def dist_to_nodes(pnt_shp, cstSurface, string, w):
        nodes = ogr.GetDriverByName(drv_name(pnt_shp)).Open(pnt_shp, 0)

        nodesLyr = nodes.GetLayer()

        c = 0
        dicNodes = {}
        for pnt in nodesLyr:
            geom = pnt.GetGeometryRef()
            point = geom.ExportToWkb()
            OGR_CreateNewShape(
                OGR_GetDriverName(pnt_shp),
                os.path.join(w, '{pnt}_{o}.shp'.format(pnt=string, o=str(c))),
                ogr.wkbPoint, [point])
            FT_TF_GRASS(
                os.path.join(w, '{pnt}_{o}.shp'.format(pnt=string, o=str(c))),
                '{pnt}_{o}'.format(pnt=string, o=str(c)), 'None')
            GRASS_CostDistance(cstSurface, '{pnt}_{o}'.format(pnt=string,
                                                              o=str(c)),
                               'cst_{pnt}_{a}'.format(pnt=string, a=str(c)))
            dicNodes['{pnt}_{o}'.format(pnt=string, o=str(c))] = [
                os.path.join(w, '{pnt}_{o}.shp'.format(pnt=string, o=str(c))),
                'cst_{pnt}_{a}'.format(pnt=string, a=str(c))
            ]
            c += 1
        return dicNodes
Пример #5
0
def add_fields(table, fields):
    """
    Receive a feature class and a dict with the field name and type
    and add the fields in the feature class
    
    TODO: Check if fields is a dict
    """

    import os

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

    else:
        if os.path.exists(table) and os.path.isfile(table):
            # Open table in edition mode
            __table = ogr.GetDriverByName(drv_name(table)).Open(table, 1)

            # Get Layer
            lyr = __table.GetLayer()
            c = 1

        else:
            raise ValueError('File path does not exist')

    for fld in fields:
        lyr.CreateField(ogr.FieldDefn(fld, fields[fld]))

    if c:
        del lyr
        __table.Destroy()
    else:
        return lyr
Пример #6
0
def get_centroid_boundary(shp, isFile=None):
    """
    Return centroid (OGR Point object) of a Boundary (layer with a single
    feature).
    """
    
    from osgeo        import ogr
    from gasp.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
Пример #7
0
def lst_fld(shp):
    """
    Return a list with every field name in a vectorial layer
    """

    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
Пример #8
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
    from gasp.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
Пример #9
0
def get_geom_by_index(inShp, idx):
    """
    Get Geometry by index in file
    """

    from osgeo import ogr
    from gasp.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
Пример #10
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
Пример #11
0
def area_to_dic(shp):
    """
    Return the following output:
    
    dic = {
        id_feat: area,
        ...,
        id_feat: area
    }
    """
    
    from osgeo        import ogr
    from gasp.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
Пример #12
0
def sel_by_attr(inShp, sql, outShp, geomType="area", lyrN=1, api_gis='ogr'):
    """
    Select vectorial file and export to new file
    
    If api_gis == 'grass' or 'pygrass', sql is not a query but the where clause
    
    API's Available:
    * ogr;
    * grass;
    * pygrass
    """

    if api_gis == 'ogr':
        from gasp import exec_cmd
        from gasp.prop.ff import drv_name

        out_driver = drv_name(outShp)

        cmd = 'ogr2ogr -f "{drv}" {o} {i} -dialect sqlite -sql "{s}"'.format(
            o=outShp, i=inShp, s=sql, drv=out_driver)

        # Execute command
        outcmd = exec_cmd(cmd)

    elif api_gis == 'pygrass':
        """
        v.extract via pygrass
        """

        from grass.pygrass.modules import Module

        m = Module("v.extract",
                   input=inShp,
                   type=geomType,
                   layer=lyrN,
                   where=sql,
                   output=outShp,
                   overwrite=True,
                   run_=False,
                   quiet=True)

        m()

    elif api_gis == 'grass':
        """
        v.extract via command shell
        """

        from gasp import exec_cmd

        rcmd = exec_cmd(
            ("v.extract input={} type={} layer={} where={} "
             "output={} --overwrite --quiet").format(inShp, geomType,
                                                     str(lyrN), sql, outShp))

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

    return outShp
Пример #13
0
def shpext_to_boundary(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 gasp.oss import get_filename
    from gasp.to.geom import create_point
    from gasp.prop.ext import get_extent

    extent = get_extent(inShp, gisApi='ogr')

    # Create points of the new boundary based on the extent
    boundary_points = [
        create_point(extent[0], extent[3], api='ogr'),
        create_point(extent[1], extent[3], api='ogr'),
        create_point(extent[1], extent[2], api='ogr'),
        create_point(extent[0], extent[2], api='ogr'),
        create_point(extent[0], extent[3], api='ogr')
    ]

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

    else:
        from gasp.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(get_filename(outShp, forceLower=True),
                          srs,
                          geom_type=ogr.wkbPolygon)

    outDefn = lyr.GetLayerDefn()

    feat = ogr.Feature(outDefn)
    ring = ogr.Geometry(ogr.wkbLinearRing)

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

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

    feat.SetGeometry(polygon)
    lyr.CreateFeature(feat)

    feat.Destroy()
    shp.Destroy()

    return outShp
Пример #14
0
def array_to_raster(inArray,
                    outRst,
                    template,
                    epsg,
                    data_type,
                    noData=None,
                    gisApi='gdal'):
    """
    Send Array to Raster
    
    API Available:
    * gdal;
    * arcpy
    """

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

        img_template = gdal.Open(template)
        geo_transform = img_template.GetGeoTransform()
        rows, cols = inArray.shape
        driver = gdal.GetDriverByName(drv_name(outRst))
        out = driver.Create(outRst, cols, rows, 1, data_type)
        out.SetGeoTransform(geo_transform)
        outBand = out.GetRasterBand(1)

        if noData:
            outBand.SetNoDataValue(noData)

        outBand.WriteArray(inArray)

        if epsg:
            from gasp.prop.prj import epsg_to_wkt
            srs = epsg_to_wkt(epsg)
            out.SetProjection(srs)

        outBand.FlushCache()

    elif gisApi == 'arcpy':
        import arcpy

        xmin = arcpy.GetRasterProperties_management(template, "LEFT")
        cellx = arcpy.GetRasterProperties_management(template, "CELLSIZEX")
        celly = arcpy.GetRasterProperties_management(template, "CELLSIZEY")

        new_rst = arcpy.NumPyArrayToRaster(array,
                                           float(str(xmin).replace(',', '.')),
                                           float(str(cellx).replace(",", ".")),
                                           float(str(celly).replace(",", ".")))

        new_rst.save(outRst)

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

    return outRst
Пример #15
0
def get_attr_values_by_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.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
Пример #16
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
    """

    from osgeo import ogr, gdal
    from gasp.prop.ff import drv_name
    from gasp.cpu.gdl.sampling import gdal_point_value_on_raster

    # 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 = gdal_point_value_on_raster(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)
Пример #17
0
def shply_array_to_shp(arrayLike,
                       outfile,
                       geomType,
                       epsg=None,
                       fields=None,
                       crsObj=None):
    """
    Convert a array with Shapely geometric data into a file
    with geometry (GML, ESRI Shapefile or others).
    
    Example of an array_like object:
    data = [
        {col_1: value, col_2: value, geom: geomObj},
        {col_1: value, col_2: value, geom: geomObj},
    ]
    """

    import os
    from gasp.prop.ff import drv_name
    from gasp.prop.prj import get_sref_from_epsg

    # Create output file
    shp = ogr.GetDriverByName(drv_name(outfile)).CreateDataSource(outfile)

    lyr = shp.CreateLayer(
        os.path.splitext(os.path.basename(outfile))[0],
        get_sref_from_epsg(epsg) if epsg else crsObj if crsObj else \
            None, geom_type=geomType
    )

    # Create fields of output file
    # TODO: Automatic mapping of filters types needs further testing
    if fields:
        for f in fields:
            lyr.CreateField(ogr.FieldDefn(f, fields[f]))

    # Add features
    defn = lyr.GetLayerDefn()
    for feat in arrayLike:
        newFeat = ogr.Feature(defn)

        newFeat.SetGeometry(ogr.CreateGeometryFromWkb(feat['GEOM'].wkb))

        if len(fields):
            for f in fields:
                newFeat.SetField(f, feat[f])

        lyr.CreateFeature(newFeat)

        newFeat = None

    shp.Destroy()

    return outfile
Пример #18
0
def composite_bnds(rsts, outRst, epsg=None, gisAPI='gdal'):
    """
    Composite Bands
    
    API's Available:
    * gdal;
    """
    
    if gisAPI == 'gdal':
        """
        Using GDAL
        """
        
        from osgeo         import gdal
        from gasp.fm.rst   import rst_to_array
        from gasp.prop.ff  import drv_name
        from gasp.prop.rst import rst_dataType, get_nodata
        
        # Get Arrays
        _as = [rst_to_array(r) for r in rsts]
        
        # Get nodata values
        nds = [get_nodata(r, gisApi='gdal') for r in rsts]
        
        # Open template and get some metadata
        img_temp = gdal.Open(rsts[0])
        geo_tran = img_temp.GetGeoTransform()
        band     = img_temp.GetRasterBand(1)
        dataType = rst_dataType(band)
        rows, cols = _as[0].shape
        
        # Create Output
        drv = gdal.GetDriverByName(drv_name(outRst))
        out = drv.Create(outRst, cols, rows, len(_as), dataType)
        out.SetGeoTransform(geo_tran)
        
        if epsg:
            from gasp.prop.prj import epsg_to_wkt
            srs = epsg_to_wkt(epsg)
            out.SetProjection(srs)
        
        # Write all bands
        for i in range(len(_as)):
            outBand = out.GetRasterBand(i + 1)
            
            outBand.SetNoDataValue(nds[i])
            outBand.WriteArray(_as[i])
            
            outBand.FlushCache()
    
    else:
        raise ValueError('The api {} is not available'.format(gisAPI))
    
    return outRst
Пример #19
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;
    * arcpy;
    
    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.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)

    elif gisApi == 'arcpy':
        """
        Feature Class to Feature Class using ArcGIS
        """

        import arcpy

        arcpy.FeatureClassToFeatureClass_conversion(inShp,
                                                    os.path.dirname(outShp),
                                                    os.path.basename(outShp),
                                                    "", "", "")

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

    return outShp
Пример #20
0
def merge_feat(shps, outShp, api="ogr2ogr"):
    """
    Get all features in several Shapefiles and save them in one file
    """
    
    if api == "ogr2ogr":
        from gasp         import exec_cmd
        from gasp.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.fm     import tbl_to_obj
        from gasp.to.shp import df_to_shp
        
        if type(shps) != list:
            raise ValueError('shps should be a list with paths for Feature Classes')
        
        dfs = [tbl_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)
    
    else:
        raise ValueError(
            "{} API is not available"
        )
    
    return outShp
Пример #21
0
def osmosis_extract(boundary, osmdata, wepsg, output):
    """
    Extract OSM Data from a xml file with osmosis
    
    The extraction is done using the extent of a boundary
    """

    import os
    from osgeo import ogr
    from gasp import exec_cmd
    from gasp.prop.ff import drv_name
    from gasp.mng.prj import project_geom

    # Assuming that boundary has only one feature
    # Get Geometry
    dtSrc = ogr.GetDriverByName(drv_name(boundary)).Open(boundary)
    lyr = dtSrc.GetLayer()

    for feat in lyr:
        geom = feat.GetGeometryRef()
        break

    # Convert boundary to WGS84 -EPSG 4326
    geom_wgs = project_geom(geom, int(wepsg), 4326,
                            api='ogr') if int(wepsg) != 4326 else geom

    # Get boundary extent
    left, right, bottom, top = geom_wgs.GetEnvelope()

    # Osmosis shell comand
    osmExt = os.path.splitext(osmdata)[1]
    osm_f = 'enableDateParsing=no' if osmExt == '.xml' or osmExt == '.osm' else ''

    cmd = ('osmosis --read-{_f} {p} file={_in} --bounding-box top={t} left={l}'
           ' bottom={b} right={r} --write-{outext} file={_out}').format(
               _f='xml' if osmExt == '.xml' or osmExt == '.osm' else 'pbf',
               p=osm_f,
               _in=osmdata,
               t=str(top),
               l=str(left),
               b=str(bottom),
               r=str(right),
               _out=output,
               outext=os.path.splitext(output)[1][1:])

    # Execute command
    outcmd = exec_cmd(cmd)

    return output
Пример #22
0
def rst_to_rst(inRst, outRst):
    """
    Convert a raster file to another raster format
    """
    
    from gasp         import exec_cmd
    from gasp.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
Пример #23
0
Файл: bf.py Проект: zonakre/gasp
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.prop.ff import drv_name
    from gasp.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.mng.fld import add_fields

        add_fields(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
Пример #24
0
def feat_count(shp, gisApi='pandas'):
    """
    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.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 == 'arcpy':
        import arcpy
        
        fcnt = int(arcpy.GetCount_management(lyr).getOutput(0))
    
    elif gisApi == 'pygrass':
        from grass.pygrass.vector import VectorTopo
        
        open_shp = VectorTopo(shp)
        open_shp.open(mode='r')
        fcnt = open_shp.num_primitive_of(geom)
    
    elif gisApi == 'pandas':
        from gasp.fm import tbl_to_obj
        
        gdf = tbl_to_obj(shp)
        
        fcnt = int(gdf.shape[0])
        
        del gdf
    
    else:
        raise ValueError('The api {} is not available'.format(gisApi))
    
    return fcnt
Пример #25
0
def clip_rst(raster, clipShp, outRst, nodataValue=None):
    """
    Clip Raster using GDAL WARP
    """
    
    from gasp         import exec_cmd
    from gasp.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 ""
    ))
    
    return outRst
Пример #26
0
def rst_val_to_points2(pntShp, listRasters):
    """
    Pick raster value for each point in pntShp
    """
    
    from osgeo        import ogr
    from gasp         import goToList
    from gasp.prop.ff import drv_name
    
    listRasters = goToList(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
Пример #27
0
def get_extent(shp, gisApi='ogr'):
    """
    Return extent of a Vectorial file
    
    Return a tuple object with the follow order:
    (left, right, bottom, top)
    
    API'S Available:
    * ogr;
    * arcpy;
    """

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

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

        dt.Destroy()

        EXT = [Decimal(x) for x in extent]

    elif gisApi == 'arcpy':
        import arcpy

        descObj = arcpy.Describe(shp)

        EXT = [
            descObj.extent.XMin, descObj.extent.XMax, descObj.extent.YMin,
            descObj.extent.YMax
        ]

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

    return EXT
Пример #28
0
Файл: bf.py Проект: zonakre/gasp
def get_buffer_radius(bfShp, isFile=None):
    """
    Return the radius of a buffer boundary in meters.
    
    The layer must be only one feature
    """

    from osgeo import ogr

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

        bfLyr = bfShp.GetLayer()

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

    else:
        geom = ogr.CreateGeometryFromWkt(bfShp)

    center = geom.Centroid()
    c = 0
    for pnt in geom:
        if c == 1:
            break
        pnt_aux = pnt
        c += 1

    x_center, y_center = (center.GetX(), center.GetY())
    x_aux, y_aux = (pnt_aux.GetX(), pnt_aux.GetY())

    dist = ((pnt_aux.GetX() - x_center)**2 +
            (pnt_aux.GetY() - y_center)**2)**0.5

    del center
    if isFile:
        bfShp.Destroy()

    return round(dist, 0)
Пример #29
0
def coords_to_boundary(topLeft, lowerRight, epsg, outshp):
    """
    Top Left and Lower Right to Boundary
    """

    import os
    from gasp.oss import get_filename
    from gasp.prop.prj import get_sref_from_epsg

    boundary_points = [(topLeft[0], topLeft[1]), (lowerRight[0], topLeft[1]),
                       (lowerRight[0], lowerRight[1]),
                       (topLeft[0], lowerRight[1]), (topLeft[0], topLeft[1])]

    shp = ogr.GetDriverByName(drv_name(outshp)).CreateDataSource(outshp)

    lyr = shp.CreateLayer(get_filename(outshp),
                          get_sref_from_epsg(epsg),
                          geom_type=ogr.wkbPolygon)

    outDefn = lyr.GetLayerDefn()

    feat = ogr.Feature(outDefn)
    ring = ogr.Geometry(ogr.wkbLinearRing)

    for pnt in boundary_points:
        ring.AddPoint(pnt[0], pnt[1])

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

    feat.SetGeometry(polygon)
    lyr.CreateFeature(feat)

    feat.Destroy()
    shp.Destroy()

    return outshp
Пример #30
0
Файл: bf.py Проект: zonakre/gasp
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
    """

    from osgeo import ogr
    from gasp.mng.prj import ogr_def_proj
    from gasp.prop.ff import drv_name
    from gasp.prop.prj import get_sref_from_epsg

    # 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.to.geom import create_point
        feat = ogr.Feature(featDefn)
        g = create_point(geom[X], geom[Y], api='ogr')
        feat.SetGeometry(draw_buffer(g, radius))

        buffer_lyr.CreateFeature(feat)

        feat = None

        buffer_shp.Destroy()

        if srs:
            ogr_def_proj(out_file, epsg=srs)

    elif type(geom) == str or type(geom) == unicode:
        # 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:
                ogr_def_proj(out_file, epsg=srs)
            else:
                ogr_def_proj(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