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 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 #3
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 #4
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 #5
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 #6
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 #7
0
def eachfeat_to_newshp(inShp, outFolder, epsg=None, idCol=None):
    """
    Export each feature in inShp to a new/single File
    """
    
    import os; from osgeo  import ogr
    from gasp.gt.prop.ff   import drv_name
    from gasp.gt.prop.feat import get_gtype, lst_fld
    from gasp.g.lyr.fld    import copy_flds
    from gasp.pyt.oss      import fprop
    
    inDt = ogr.GetDriverByName(
        drv_name(inShp)).Open(inShp)
    
    lyr = inDt.GetLayer()
    
    # Get SRS for the output
    if not epsg:
        from gasp.gt.prop.prj import get_shp_sref
        srs = get_shp_sref(lyr)
    
    else:
        from gasp.gt.prop.prj import get_sref_from_epsg
        srs = get_sref_from_epsg(epsg)
    
    # Get fields name
    fields = lst_fld(lyr)
    
    # Get Geometry type
    geomCls = get_gtype(inShp, gisApi='ogr', name=None, py_cls=True)
    
    # Read features and create a new file for each feature
    RESULT_SHP = []
    for feat in lyr:
        # Create output
        ff = fprop(inShp, ['fn', 'ff'])
        newShp = os.path.join(outFolder, "{}_{}{}".format(
            ff['filename'],
            str(feat.GetFID()) if not idCol else str(feat.GetField(idCol)),
            ff['fileformat']
        ))
        
        newData = ogr.GetDriverByName(
            drv_name(newShp)).CreateDataSource(newShp)
        
        newLyr = newData.CreateLayer(
            fprop(newShp, 'fn'), srs, geom_type=geomCls
        )
        
        # Copy fields from input to output
        copy_flds(lyr, newLyr)
        
        newLyrDefn = newLyr.GetLayerDefn()
        
        # Create new feature
        newFeat = ogr.Feature(newLyrDefn)
        
        # Copy geometry
        geom = feat.GetGeometryRef()
        newFeat.SetGeometry(geom)
        
        # Set fields attributes
        for fld in fields:
            newFeat.SetField(fld, feat.GetField(fld))
        
        # Save feature
        newLyr.CreateFeature(newFeat)
        
        newFeat.Destroy()
        
        del newLyr
        newData.Destroy()
        RESULT_SHP.append(newShp)
    
    return RESULT_SHP
Beispiel #8
0
def polylines_from_points(points,
                          polylines,
                          POLYLINE_COLUMN,
                          ORDER_FIELD=None,
                          epsg=None):
    """
    Create a Polyline Table from a Point Table
    
    A given Point Table:
    FID | POLYLINE_ID | ORDER_FIELD
     0  |    P1       |      1
     1  |    P1       |      2
     2  |    P1       |      3
     3  |    P1       |      4
     4  |    P2       |      1
     5  |    P2       |      2
     6  |    P2       |      3
     7  |    P2       |      4
     
    Will be converted into a new Polyline Table:
    FID | POLYLINE_ID
     0  |    P1
     1  |    P2
     
    In the Point Table, the POLYLINE_ID field identifies the Polyline of that point,
    the ORDER FIELD specifies the position (first point, second point, etc.)
    of the point in the polyline.
    
    If no ORDER field is specified, the points will be assigned to polylines
    by reading order.
    """

    import os
    from osgeo import ogr
    from gasp.gt.prop.ff import drv_name
    from gasp.gt.prj import def_prj
    from gasp.gt.prop.fld import ogr_list_fields_defn
    from gasp.g.lyr.fld import fields_to_lyr

    # TODO: check if geometry is correct

    # List all points
    pntSrc = ogr.GetDriverByName(drv_name(points)).Open(points)
    pntLyr = pntSrc.GetLayer()

    lPnt = {}
    cnt = 0
    for feat in pntLyr:
        # Get Point Geom
        geom = feat.GetGeometryRef()
        # Polyline identification
        polyline = feat.GetField(POLYLINE_COLUMN)
        # Get position in the polyline
        order = feat.GetField(ORDER_FIELD) if ORDER_FIELD else cnt

        # Store data
        if polyline not in lPnt.keys():
            lPnt[polyline] = {order: (geom.GetX(), geom.GetY())}

        else:
            lPnt[polyline][order] = (geom.GetX(), geom.GetY())

        cnt += 1

    # Write output
    lineSrc = ogr.GetDriverByName(
        drv_name(polylines)).CreateDataSource(polylines)

    if not epsg:
        from gasp.gt.prop.prj import get_shp_sref
        srs = get_shp_sref(points)

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

    lineLyr = lineSrc.CreateLayer(os.path.splitext(
        os.path.basename(polylines))[0],
                                  srs,
                                  geom_type=ogr.wkbLineString)

    # Create polyline id field
    fields_types = ogr_list_fields_defn(pntLyr)
    fields_to_lyr(
        lineLyr,
        {POLYLINE_COLUMN: list(fields_types[POLYLINE_COLUMN].keys())[0]})

    polLnhDefns = lineLyr.GetLayerDefn()
    # Write lines
    for polyline in lPnt:
        new_feature = ogr.Feature(polLnhDefns)

        lnh = ogr.Geometry(ogr.wkbLineString)

        pnt_order = list(lPnt[polyline].keys())
        pnt_order.sort()

        for p in pnt_order:
            lnh.AddPoint(lPnt[polyline][p][0], lPnt[polyline][p][1])

        new_feature.SetField(POLYLINE_COLUMN, polyline)
        new_feature.SetGeometry(lnh)

        lineLyr.CreateFeature(new_feature)

        new_feature = None

    pntSrc.Destroy()
    lineSrc.Destroy()

    return polylines
Beispiel #9
0
def polyline_to_points(inShp, outShp, attr=None, epsg=None):
    """
    Polyline vertex to Points
    
    TODO: See if works with Polygons
    """

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

    # Open Input
    polyData = ogr.GetDriverByName(drv_name(inShp)).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(outShp)).CreateDataSource(outShp)

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

    # Copy fields from input to output
    if attr:
        if attr == 'ALL':
            attr = None
        else:
            attr = [attr] if type(attr) != list else attr

        copy_flds(polyLyr, pntLyr, __filter=attr)

    # Polyline Vertex to Point Feature Class
    pntLyrDefn = pntLyr.GetLayerDefn()
    for feat in polyLyr:
        geom = feat.GetGeometryRef()

        # Get point count
        nrPnt = geom.GetPointCount()

        # Add point to a new feature
        for p in range(nrPnt):
            x, y, z = geom.GetPoint(p)

            new_point = ogr.Geometry(ogr.wkbPoint)
            new_point.AddPoint(x, y)

            new_feature = ogr.Feature(pntLyrDefn)
            new_feature.SetGeometry(new_point)

            if attr:
                for at in attr:
                    new_feature.SetField(at, feat.GetField(at))

            pntLyr.CreateFeature(new_feature)

            new_feature.Destroy()

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

    return outShp