Source code for gpdvega.geodata

import altair as alt
import geopandas as gpd
import six
import json
import warnings
from toolz.curried import curry


def geopandas_to_dict(data):
    try:
        if ('geometry' != data.geometry.name) and ('geometry' in data.columns):
            warnings.warn(
                "Column name 'geometry' is reserved name for " +
                "GeoDataFrame. Column named 'geometry' should contain " +
                "actual displaying geometry or not be used. Data of column " +
                "will not be accessible from the chart description. "
            )
        if 'type' in data.columns:
            warnings.warn(
                "Column name 'type' is reserved name for GeoDataFrame. " +
                "Data of column 'type' will not be accessible from the " +
                "chart description."
            )
        if 'id' in data.columns:
            warnings.warn(
                "Column name 'id' is reserved name for GeoDataFrame for " +
                "index values. Data of column 'id' will not be accessible " +
                "from the chart description."
            )
        if data.crs:
            data = data.to_crs(epsg=4326)
        return [dict(
                    row,
                    type=feature['type'],
                    geometry=feature['geometry'],
                    id=feature['id']
                    ) for row, feature in zip(
                            data.drop(
                                data.geometry.name,
                                axis=1
                            ).to_dict('row'),
                            data.geometry.__geo_interface__['features']
                        )
                ]
    except AttributeError as err:
        if str(err).startswith('No geometry data set yet'):
            warnings.warn("GeoDataFrame has no geometry to display.")
            return data.to_dict('row')
        else:
            raise


[docs]@curry def gpd_to_values(data): """Replace a GeoDataFrame by a data model with values. For ``geopandas.GeoDataFrame`` columns values are stored as Foreign Members of GeoJSON feature objects. For all other types uses function :py:func:`altair.to_values`.""" if isinstance(data, gpd.GeoDataFrame): data = alt.utils.sanitize_dataframe(data) values = geopandas_to_dict(data) return {'values': json.dumps(values)} else: return alt.to_values(data)
[docs]@curry def gpd_to_json(data): """Write the data model to a .json file and return a url based data model. For ``geopandas.GeoDataFrame`` columns values are stored as Foreign Members of GeoJSON feature objects. For all other types uses function :py:func:`altair.to_json`.""" if isinstance(data, gpd.GeoDataFrame): data = alt.utils.sanitize_dataframe(data) values = geopandas_to_dict(data) return alt.to_json({'values': values}) else: return alt.to_json(data)
alt.data_transformers.register( 'gpd_to_values', lambda data: alt.pipe(data, alt.limit_rows, gpd_to_values) ) alt.data_transformers.register( 'gpd_to_json', lambda data: alt.pipe(data, alt.limit_rows, gpd_to_json) ) alt.data_transformers.enable('gpd_to_values')
[docs]def geojson_feature(data, feature='features', **kwargs): """A convenience function for extracting features from a geojson object or url Parameters ---------- data : anyOf(string, geojson.GeoJSON) string is interpreted as URL from which to load the data set. geojson.GeoJSON is interpreted as data set itself. feature : string The JSON property containing the GeoJSON object set to convert to a GeoJSON feature collection. For example ``features[0].geometry``. \**kwargs : additional keywords passed to JsonDataFormat """ if isinstance(data, six.string_types): return alt.UrlData( url=data, format=alt.JsonDataFormat( type='json', property=feature, **kwargs ) ) elif hasattr(data, '__geo_interface__'): if isinstance(data, gpd.GeoDataFrame): data = alt.utils.sanitize_dataframe(data) return alt.InlineData( values=data.__geo_interface__, format=alt.JsonDataFormat( type='json', property=feature, **kwargs ) ) else: warnings.warn("data of type {0} not recognized".format(type(data))) return data