Esempio n. 1
0
def del_topoerror_shps(conParam, shps, epsg, outfolder):
    """
    Remove topological errors from Feature Class data using PostGIS
    """
    
    import os
    from gasp             import goToList
    from gasp.sql.mng.fld import cols_name
    from gasp.sql.mng.qw  import ntbl_by_query
    from gasp.to.sql      import shp_to_psql
    from gasp.to.shp      import psql_to_shp
    
    shps = goToList(shps)
    
    TABLES = shp_to_psql(conParam, shps, epsg, api="shp2pgsql")
    
    NTABLE = [ntbl_by_query(
        conParam, "nt_{}".format(t),
        "SELECT {cols}, ST_MakeValid({tbl}.geom) AS geom FROM {tbl}".format(
            cols = ", ".join(["{}.{}".format(TABLES[t], x) for x in cols_name(
                conParam, TABLES[t], sanitizeSpecialWords=None
            ) if x != 'geom']),
            tbl=TABLES[t]
        ), api='psql'
    ) for t in range(len(TABLES))]
    
    for t in range(len(NTABLE)):
        psql_to_shp(
            conParam, NTABLE[t],
            os.path.join(outfolder, TABLES[t]), tableIsQuery=None,
            api='pgsql2shp', geom_col="geom"
        )
Esempio n. 2
0
def sgbd_get_feat_not_within(dbcon, inTbl, inGeom, withinTbl, withinGeom, outTbl,
                             inTblCols=None, outTblIsFile=None,
                             apiToUse='OGR_SPATIALITE'):
    """
    Get features not Within with any of the features in withinTbl
    
    apiToUse options:
    * OGR_SPATIALITE;
    * POSTGIS.
    """
    
    from gasp import goToList
    
    Q = (
        "SELECT {selCols} FROM {tbl} AS in_tbl WHERE ("
        "in_tbl.{in_geom} NOT IN ("
            "SELECT inin_tbl.{in_geom} FROM {wi_tbl} AS wi_tbl "
            "INNER JOIN {tbl} AS inin_tbl ON "
            "ST_Within(wi_tbl.{wi_geom}, inin_tbl.{in_geom})"
        "))"
    ).format(
        selCols = "*" if not inTblCols else ", ".join(goToList(inTblCols)),
        tbl     = inTbl,
        in_geom = inGeom,
        wi_tbl  = withinTbl,
        wi_geom = withinGeom
    )
    
    if apiToUse == "OGR_SPATIALITE":
        if outTblIsFile:
            from gasp.anls.exct import sel_by_attr
            
            sel_by_attr(dbcon, Q, outTbl, api_gis='ogr')
        
        else:
            from gasp.sql.mng.qw import ntbl_by_query
            
            ntbl_by_query(dbcon, outTbl, Q, api='ogr2ogr')
    
    elif apiToUse == "POSTGIS":
        if outTblIsFile:
            from gasp.to.shp import psql_to_shp
            
            psql_to_shp(
                dbcon, Q, outTbl, api='pgsql2shp',
                geom_col=None, tableIsQuery=True
            )
        
        else:
            from gasp.sql.mng.qw import ntbl_by_query
            
            ntbl_by_query(dbcon, outTbl, Q, api='psql')
    
    else:
        raise ValueError((
            "API {} is not available. OGR_SPATIALITE and POSTGIS "
            "are the only valid options"
        ))
    
    return outTbl
Esempio n. 3
0
File: prox.py Progetto: zonakre/gasp
def st_buffer(conParam,
              inTbl,
              bfDist,
              geomCol,
              outTbl,
              bufferField="geometry",
              whrClause=None,
              dissolve=None,
              cols_select=None,
              outTblIsFile=None):
    """
    Using Buffer on PostGIS Data
    """

    from gasp import goToList

    dissolve = goToList(dissolve) if dissolve != "ALL" else "ALL"

    SEL_COLS = "" if not cols_select else ", ".join(goToList(cols_select))
    DISS_COLS = "" if not dissolve or dissolve == "ALL" else ", ".join(
        dissolve)
    GRP_BY = "" if not dissolve else "{}, {}".format(SEL_COLS, DISS_COLS) if \
        SEL_COLS != "" and DISS_COLS != "" else SEL_COLS \
        if SEL_COLS != "" else DISS_COLS if DISS_COLS != "" else ""

    Q = (
        "SELECT{sel}{spFunc}{geom}, {_dist}{endFunc} AS {bf} "
        "FROM {t}{whr}{grpBy}"
    ).format(
        sel = " " if not cols_select else " {}, ".format(SEL_COLS),
        spFunc="ST_Buffer(" if not dissolve else \
            "ST_UnaryUnion(ST_Collect(ST_Buffer(",
        geom=geomCol, _dist=bfDist,
        endFunc=")" if not dissolve else ")))",
        t=inTbl,
        grpBy=" GROUP BY {}".format(GRP_BY) if GRP_BY != "" else "",
        whr="" if not whrClause else " WHERE {}".format(whrClause),
        bf=bufferField
    )

    if not outTblIsFile:
        from gasp.sql.mng.qw import ntbl_by_query

        outTbl = ntbl_by_query(conParam, outTbl, Q, api='psql')
    else:
        from gasp.to.shp import psql_to_shp

        psql_to_shp(conParam,
                    Q,
                    outTbl,
                    api='pgsql2shp',
                    geom_col=bufferField,
                    tableIsQuery=True)

    return outTbl
Esempio n. 4
0
def st_dissolve(db,
                table,
                geomColumn,
                outTable,
                whrClause=None,
                diss_cols=None,
                outTblIsFile=None,
                api='sqlite'):
    """
    Dissolve a Polygon table
    """

    from gasp import goToList

    diss_cols = goToList(diss_cols) if diss_cols else None
    geomcol = "geometry" if api == 'sqlite' else 'geom'

    sql = ("SELECT{selCols} ST_UnaryUnion(ST_Collect({geom})) AS {gout} "
           "FROM {tbl}{whr}{grpBy}").format(
               selCols=""
               if not diss_cols else " {},".format(", ".join(diss_cols)),
               geom=geomColumn,
               tbl=table,
               whr="" if not whrClause else " WHERE {}".format(whrClause),
               grpBy="" if not diss_cols else " GROUP BY {}".format(
                   ", ".join(diss_cols)),
               gout=geomcol)

    if outTblIsFile:
        if api == 'sqlite':
            from gasp.anls.exct import sel_by_attr

            sel_by_attr(db, sql, outTable, api_gis='ogr')

        elif api == 'psql':
            from gasp.to.shp import psql_to_shp

            psql_to_shp(db,
                        table,
                        outTable,
                        api='pgsql2shp',
                        geom_col=geomColumn,
                        tableIsQuery=True)

    else:
        from gasp.sql.mng.qw import ntbl_by_query

        ntbl_by_query(db,
                      outTable,
                      sql,
                      api='ogr2ogr' if api == 'sqlite' else 'psql')

    return outTable
Esempio n. 5
0
    def fix_geometry(shp):
        # Send data to PostgreSQL
        nt = shp_to_psql(conPARAM, shp, SRS_CODE, api='shp2pgsql')

        # Fix data
        corr_tbl = fix_geom(conPARAM,
                            nt,
                            "geom",
                            "corr_{}".format(nt),
                            colsSelect=['gid', __SHAPES_TO_COMPARE[shp]])

        # Check if we have multiple geometries
        geomN = check_geomtype_in_table(conPARAM, corr_tbl)

        if geomN > 1:
            corr_tbl = select_main_geom_type(conPARAM, corr_tbl,
                                             "corr2_{}".format(nt))

        # Export data again
        newShp = psql_to_shp(conPARAM,
                             corr_tbl,
                             os.path.join(OUT_FOLDER, corr_tbl + '.shp'),
                             api='pgsql2shp',
                             geom_col='geom')

        return newShp
Esempio n. 6
0
def check_autofc_overlap(checkShp, epsg, conParam, outOverlaps):
    """
    Check if the features of one Feature Class overlaps each other
    """
    
    import os
    
    from gasp.sql.mng.db import create_db
    from gasp.sql.mng.qw import ntbl_by_query
    from gasp.to.sql     import shp_to_psql_tbl
    from gasp.to.shp     import psql_to_shp
    
    create_db(conParam, conParam["DB"])
    conParam["DATABASE"] = conParam["DB"]
    
    # Send data to postgresql
    table = shp_to_psql(conParam, checkShp, epsg, api="pandas")
    
    # Produce result
    q = (
        "SELECT foo.* FROM ("
            "SELECT * FROM {t}"
        ") AS foo, ("
            "SELECT cat AS relcat, geom AS tst_geom FROM {t}"
        ") AS foo2 "
        "WHERE ("
            "ST_Overlaps(geom, tst_geom) IS TRUE OR "
            "ST_Equals(geom, tst_geom) IS TRUE OR "
            "ST_Contains(geom, tst_geom) IS TRUE"
        ") AND cat <> relcat"
    ).format(t=table)
    
    resultTable = os.path.splitext(os.path.basename(outOverlaps))[0]
    ntbl_by_query(conParam, resultTable, q, api='psql')
    
    psql_to_shp(conParam, resultTable, outOverlaps, api='pandas', epsg=epsg)
    
    return outOverlaps
Esempio n. 7
0
def v_break_at_points(workspace, loc, lineShp, pntShp, conParam, srs, out_correct,
            out_tocorrect):
    """
    Break lines at points - Based on GRASS GIS v.edit
    
    Use PostGIS to sanitize the result
    
    TODO: Confirm utility
    """
    
    import os
    from gasp.session    import run_grass
    from gasp.sql.mng.db import create_db
    from gasp.to.sql     import shp_to_psql
    from gasp.to.shp     import psql_to_shp
    from gasp.sql.mng.qw import ntbl_by_query
    from gasp.oss        import get_filename
    
    tmpFiles = os.path.join(workspace, loc)
    
    gbase = run_grass(workspace, location=loc, srs=srs)
    
    import grass.script       as grass
    import grass.script.setup as gsetup
    
    gsetup.init(gbase, workspace, loc, 'PERMANENT')
    
    from gasp.to.shp.grs import shp_to_grs, grs_to_shp
    
    grsLine = shp_to_grs(
        lineShp, get_filename(lineShp, forceLower=True)
    )
    
    vedit_break(grsLine, pntShp, geomType='line')
    
    LINES = grass_converter(
        grsLine, os.path.join(tmpFiles, grsLine + '_v1.shp'), 'line')
    
    # Sanitize output of v.edit.break using PostGIS
    create_db(conParam, conParam["DB"], overwrite=True)
    conParam["DATABASE"] = conParam["DB"]
    
    LINES_TABLE = shp_to_psql(
        conParam, LINES, srs,
        pgTable=get_filename(LINES, forceLower=True), api="shp2pgsql"
    )
    
    # Delete old/original lines and stay only with the breaked one
    Q = (
        "SELECT {t}.*, foo.cat_count FROM {t} INNER JOIN ("
            "SELECT cat, COUNT(cat) AS cat_count, "
            "MAX(ST_Length(geom)) AS max_len "
            "FROM {t} GROUP BY cat"
        ") AS foo ON {t}.cat = foo.cat "
        "WHERE foo.cat_count = 1 OR foo.cat_count = 2 OR ("
            "foo.cat_count = 3 AND ST_Length({t}.geom) <= foo.max_len)"
    ).format(t=LINES_TABLE)
    
    CORR_LINES = ntbl_by_query(
        conParam, "{}_corrected".format(LINES_TABLE), Q, api='psql'
    )
    
    # TODO: Delete Rows that have exactly the same geometry
    
    # Highlight problems that the user must solve case by case
    Q = (
        "SELECT {t}.*, foo.cat_count FROM {t} INNER JOIN ("
            "SELECT cat, COUNT(cat) AS cat_count FROM {t} GROUP BY cat"
        ") AS foo ON {t}.cat = foo.cat "
        "WHERE foo.cat_count > 3"
    ).format(t=LINES_TABLE)
    
    ERROR_LINES = ntbl_by_query(
        conParam, "{}_not_corr".format(LINES_TABLE), Q, api='psql'
    )
    
    psql_to_shp(
        conParam,  CORR_LINES, out_correct,
        api="pgsql2shp", geom_col="geom"
    )
    
    psql_to_shp(
        conParam, ERROR_LINES, out_tocorrect,
        api="pgsql2shp", geom_col="geom"
    )
Esempio n. 8
0
def sgbd_get_feat_within(conParam, inTbl, inGeom, withinTbl, withinGeom, outTbl,
                         inTblCols=None, withinCols=None, outTblIsFile=None,
                         apiToUse='OGR_SPATIALITE'):
    """
    Get Features within other Geometries in withinTbl
    e.g. Intersect points with Polygons
    
    apiToUse options:
    * OGR_SPATIALITE;
    * POSTGIS.
    """
    
    from gasp import goToList
    
    if not inTblCols and not withinCols:
        colSelect = "intbl.*, witbl.*"
    else:
        if inTblCols and not withinCols:
            colSelect = ", ".join([
                "intbl.{}".format(c) for c in goToList(inTblCols)
            ])
        
        elif not inTblCols and withinCols:
            colSelect = ", ".join([
                "witbl.{}".format(c) for c in goToList(withinCols)
            ])
        
        else:
            colSelect = "{}, {}".format(
                ", ".join(["intbl.{}".format(c) for c in goToList(inTblCols)]),
                ", ".join(["witbl.{}".format(c) for c in goToList(withinCols)])
            )
    
    Q = (
        "SELECT {selcols} FROM {in_tbl} AS intbl "
        "INNER JOIN {within_tbl} AS witbl ON "
        "ST_Within(intbl.{in_geom}, witbl.{wi_geom})"
    ).format(
        selcols=colSelect, in_tbl=inTbl, within_tbl=withinTbl,
        in_geom=inGeom, wi_geom=withinGeom
    )
    
    if apiToUse == "OGR_SPATIALITE":
        if outTblIsFile:
            from gasp.anls.exct import sel_by_attr
            
            sel_by_attr(conParam, Q, outTbl, api_gis='ogr')
        
        else:
            from gasp.sql.mng.qw import ntbl_by_query
            
            ntbl_by_query(conParam, outTbl, Q, api='ogr2ogr')
    
    elif apiToUse == 'POSTGIS':
        if outTblIsFile:
            from gasp.to.shp import psql_to_shp
            
            psql_to_shp(
                conParam, Q, outTbl, api="pgsql2shp",
                geom_col=None, tableIsQuery=True)
        
        else:
            from gasp.sql.mng.qw import ntbl_by_query
            
            ntbl_by_query(conParam, outTbl, Q, api='psql')
    
    else:
        raise ValueError((
            "API {} is not available. OGR_SPATIALITE and POSTGIS "
            "are the only valid options"
        ))
    
    return outTbl
Esempio n. 9
0
def get_unused_data_on_lulcp(
    pbf,
    pgsql_data,
    out_work,
    nomenclature,
    dicPostgre={
        'HOST': 'localhost',
        'USER': '******',
        'DATABASE': 'osm',
        'TEMPLATE': 'template_postgis',
        'PASSWORD': '******',
        'PORT': '5432'
    }):
    """
    Return data not used in osm2lulc procedure
    """

    import os
    from gasp.sql import run_sql_file
    from gasp.sql.mng.db import create_db
    from gasp.fm.sql import query_to_df
    from gasp.sql.mng.fld import cols_name
    from gasp.sql.k import create_pk
    from gasp.to.shp import psql_to_shp
    from gasp.to.psql import osm_to_pgsql
    # TODO: replace postgis
    from gasp.postgis.analysis import new_geom_table

    # ################ #
    # Global Variables #
    # ################ #
    # Name of the tables with osmdata after the import with osm2pgsql
    OsmData = {
        'polygon': 'planet_osm_polygon',
        'line': 'planet_osm_line',
        'point': 'planet_osm_point'
    }

    IrrelevantCols = [
        'addr:housename', 'addr:housenumber', 'addr:interpolation',
        'generator:source', 'tower:type'
    ]

    if nomenclature == 'URBAN_ATLAS':
        tbl_relation = 'rel_osm_ua'
        id_osm = 'osm_id'
    elif nomenclature == 'CORINE_LAND_COVER':
        tbl_relation = 'rel_osm_clc'
        id_osm = 'osm_id'
    elif nomenclature == 'GLOB_LAND_30':
        tbl_relation = 'rel_osm_global'
        id_osm = 'id_osm'

    # ################ #
    # Auxiliar Methods #
    # ################ #
    def get_where_string(dic, operator, table):
        l = []
        for fid in dic:
            if dic[fid][0] == '' or dic[fid][1] == '' or dic[fid][0] == 'sidewalk'\
               or dic[fid][0] == 'cycleway' or dic[fid][0] == 'busway'\
               or dic[fid][0] == 'enity' or dic[fid][0] == 'healthcare':
                continue
            l.append("{t}.{col}{o}'{val}'".format(col=dic[fid][0],
                                                  o=operator,
                                                  val=dic[fid][1],
                                                  t=table))
        return " OR ".join(l)

    create_db(dicPostgre, dicPostgre['DATABASE'])
    run_sql_file(dicPostgre, dicPostgre['DATABASE'], pgsql_data)
    run_osm2pgsql(pbf, dicPostgre['DATABASE'], dicPostgre['HOST'],
                  dicPostgre['USER'])
    # 1. Obtain data used on OSM2LULC procedure
    # 1.1 Get key and value for osm features
    id_related_with = [
        x[0]
        for x in query_to_df(dicPostgre,
                             "SELECT {fid} FROM {t}".format(t=tbl_relation,
                                                            fid=id_osm),
                             db_api='psql')[id_osm].tolist()
    ]
    key_value = {
        x[0]: [x[1], x[2]]
        for x in query_to_df(
            dicPostgre,
            "SELECT id, key, value FROM osm_features WHERE {s}".format(
                s=' OR '.join(
                    ['id={y}'.format(y=str(x)) for x in id_related_with])),
            db_api='psql').values.tolist()
    }
    # 1.2 Extract data with this combinations of keys and values
    for tbl in OsmData:
        # Create new primary key
        create_pk(dicPostgre, OsmData[tbl], 'pk_fid')
        cols = cols_name(dicPostgre, OsmData[tbl])
        cols_clean = []
        for i in cols:
            if i not in IrrelevantCols:
                if i == 'natural':
                    cols_clean.append("{t}.{col}".format(t=OsmData[tbl],
                                                         col=i))
                else:
                    cols_clean.append(i)
        whr = get_where_string(key_value, "=", OsmData[tbl])
        new_geom_table(dicPostgre,
                       cols_clean,
                       OsmData[tbl],
                       whr,
                       'used{t}'.format(t=OsmData[tbl]),
                       pk=False)
        export = psql_to_shp(
            dicPostgre,
            'used{t}'.format(t=OsmData[tbl]),
            os.path.join(out_work, 'used{t}.shp'.format(t=OsmData[tbl])),
            api="pgsql2shp",
            geom_col='way')
    # 2. Obtain data not used on OSM2LULC procedure
    for tbl in OsmData:
        new_geom_table(dicPostgre, ['*'],
                       OsmData[tbl],
                       "{t}.pk_fid NOT IN (SELECT pk_fid FROM used{t})".format(
                           t=OsmData[tbl]),
                       'unused{t}'.format(t=OsmData[tbl]),
                       pk=False)
        export = psql_to_shp(dicPostgre,
                             'unused{t}'.format(t=OsmData[tbl]),
                             os.path.join(
                                 out_work,
                                 'unused{t}.shp'.format(t=OsmData[tbl])),
                             api="pgsql2shp",
                             geom_col='way')