Esempio n. 1
0
def query_layer(aoi, layer_id=10):
    """
    Return the features of the given layer that intersect with the given area of interest.

    Parameters
    ----------
    aoi : str
        A WKT string specifying the area of interest.
    layer_id
        ID number of the layer.

    Returns
    -------
    geopandas.GeoDataFrame
    """
    params = [('in', 'objects'), ('layer_id', str(layer_id)),
              ('operation', 'fw')]
    data = [('requestArea', aoi.upper()), ('srs', 'EPSG:3301')]
    r = session.post('http://register.metsad.ee/avalik/flashconf.php',
                     params=params,
                     data=data)
    r.raise_for_status()
    if 'Error' in r.text:
        raise RuntimeError('Server raised an error: ' + r.text[:1000])

    crs = {'init': 'epsg:3301'}
    if ">0 objects<" in r.text:
        return gpd.GeoDataFrame(crs=crs)
    features = xmltodict.parse(r.text)['objects']['obj']
    if not isinstance(features, list):
        features = [features]
    df = pd.DataFrame(features).set_index('@id')
    df.index.name = 'id'
    if '@label' in list(df):
        df = df.drop('@label', axis=1)
    if 'url' in list(df):
        df.loc[df['url'].notnull(), 'url'] = df['url'].dropna().map(unquote)

    geometries = []
    for wkt in df['wkt']:
        if wkt.startswith('GEOMETRYCOLLECTION'):
            # GeometryCollection type seems to be more of a bug in the dataset
            # With erroneous LineString objects appearing inside it.
            # It's better to convert it to a MultiPolygon.
            wkt = (re.sub(r'LINESTRING\s*\(([^)]+\))(?:,\s*)?', '',
                          wkt).replace('POLYGON',
                                       '').replace('GEOMETRYCOLLECTION',
                                                   'MULTIPOLYGON'))
        try:
            geometries.append(shapely.wkt.loads(wkt))
        except:
            # A workaround for cases like
            # IllegalArgumentException: Points of LinearRing do not form a closed linestring
            # that Shapely refuses to handle.
            geometries.append(
                shapely.geometry.geo.shape(pygeoif.geometry.from_wkt(wkt)))
    df = df.drop('wkt', axis=1)
    gdf = gpd.GeoDataFrame(df, crs=crs, geometry=geometries)
    return gdf
Esempio n. 2
0
def appendrow(row, rows, chatty, sections=()):
    if row.code == 'F':  # row.coords is a multiFaultSource
        row.coords.create_inverted_index(sections)
        row.coords = [row.coords.polygon.coords]
    row.wkt = wkt = to_wkt(row.geom, row.coords)
    if wkt.startswith('POINT'):
        rows[row.code + '1'].append(row)
    elif wkt.startswith('LINESTRING'):
        rows[row.code + '2'].append(row)
    elif wkt.startswith('POLYGON'):
        rows[row.code + '3'].append(row)
    elif wkt.startswith('MULTIPOINT'):
        rows[row.code + '4'].append(row)
    elif wkt.startswith('MULTILINESTRING'):
        rows[row.code + '5'].append(row)
    elif wkt.startswith('MULTIPOLYGON'):
        rows[row.code + '6'].append(row)
    if chatty:
        print('=' * 79)
        for col in row.__class__.__annotations__:
            print(col, getattr(row, col))
        try:
            shapely.wkt.loads(wkt)  # sanity check
        except Exception as exc:
            raise exc.__class__(wkt)
Esempio n. 3
0
def appendrow(row, rows, chatty):
    wkt = to_wkt(row.geom, row.coords)
    if wkt.startswith('POINT'):
        rows[row.code + '1'].append(row)
    elif wkt.startswith('LINESTRING'):
        rows[row.code + '2'].append(row)
    elif wkt.startswith('POLYGON'):
        rows[row.code + '3'].append(row)
    elif wkt.startswith('MULTIPOINT'):
        rows[row.code + '4'].append(row)
    elif wkt.startswith('MULTILINESTRING'):
        rows[row.code + '5'].append(row)
    elif wkt.startswith('MULTIPOLYGON'):
        rows[row.code + '6'].append(row)
    if chatty:
        print('=' * 79)
        for col in row._fields:
            print(col, getattr(row, col))
        try:
            shapely.wkt.loads(wkt)  # sanity check
        except Exception as exc:
            raise exc.__class__(wkt)