コード例 #1
0
 def select(cls, dataset, selection_mask=None, **selection):
     if cls.geom_dims(dataset):
         data = cls.shape_mask(dataset, selection)
     else:
         data = dataset.data
     if selection_mask is None:
         selection_mask = cls.select_mask(dataset, selection)
     empty = not selection_mask.sum()
     dimensions = dataset.dimensions()
     if empty:
         return {
             d.name: np.array([], dtype=cls.dtype(dataset, d))
             for d in dimensions
         }
     indexed = cls.indexed(dataset, selection)
     new_data = {}
     for k, v in data.items():
         if k not in dimensions or isscalar(v):
             new_data[k] = v
         else:
             new_data[k] = v[selection_mask]
     if indexed and len(list(new_data.values())[0]) == 1 and len(
             dataset.vdims) == 1:
         value = new_data[dataset.vdims[0].name]
         return value if isscalar(value) else value[0]
     return new_data
コード例 #2
0
    def init(cls, eltype, data, kdims, vdims):
        odict_types = (OrderedDict, cyODict)
        if kdims is None:
            kdims = eltype.kdims
        if vdims is None:
            vdims = eltype.vdims

        dimensions = [dimension_name(d) for d in kdims + vdims]
        if isinstance(data, geom_types):
            data = {'geometry': data}

        if not cls.applies(data):
            raise ValueError(
                "GeomDictInterface only handles dictionary types "
                "containing a 'geometry' key and shapely geometry "
                "value.")

        unpacked = []
        for d, vals in data.items():
            if isinstance(d, tuple):
                vals = np.asarray(vals)
                if vals.shape == (0, ):
                    for sd in d:
                        unpacked.append((sd, np.array([], dtype=vals.dtype)))
                elif not vals.ndim == 2 and vals.shape[1] == len(d):
                    raise ValueError("Values for %s dimensions did not have "
                                     "the expected shape.")
                else:
                    for i, sd in enumerate(d):
                        unpacked.append((sd, vals[:, i]))
            elif d not in dimensions:
                unpacked.append((d, vals))
            else:
                if not isscalar(vals):
                    vals = np.asarray(vals)
                    if not vals.ndim == 1 and d in dimensions:
                        raise ValueError(
                            'DictInterface expects data for each column to be flat.'
                        )
                unpacked.append((d, vals))

        if not cls.expanded(
            [vs
             for d, vs in unpacked if d in dimensions and not isscalar(vs)]):
            raise ValueError(
                'DictInterface expects data to be of uniform shape.')
        if isinstance(data, odict_types):
            data.update(unpacked)
        else:
            data = OrderedDict(unpacked)

        return data, {'kdims': kdims, 'vdims': vdims}, {}
コード例 #3
0
def geom_from_dict(geom, xdim, ydim, single_type, multi_type):
    from shapely.geometry import (Point, LineString, Polygon, MultiPoint,
                                  MultiPolygon, MultiLineString)
    if (xdim, ydim) in geom:
        xs, ys = np.asarray(geom.pop((xdim, ydim))).T
    elif xdim in geom and ydim in geom:
        xs, ys = geom.pop(xdim), geom.pop(ydim)
    else:
        raise ValueError('Could not find geometry dimensions')

    xscalar, yscalar = isscalar(xs), isscalar(ys)
    if xscalar and yscalar:
        xs, ys = np.array([xs]), np.array([ys])
    elif xscalar:
        xs = np.full_like(ys, xs)
    elif yscalar:
        ys = np.full_like(xs, ys)
    geom_array = np.column_stack([xs, ys])
    splits = np.where(np.isnan(
        geom_array[:, :2].astype('float')).sum(axis=1))[0]
    if len(splits):
        split_geoms = [
            g[:-1] if i == (len(splits) - 1) else g
            for i, g in enumerate(np.split(geom_array, splits + 1))
        ]
    else:
        split_geoms = [geom_array]
    split_holes = geom.pop('holes', None)
    if split_holes is not None and len(split_holes) != len(split_geoms):
        raise DataError('Polygons with holes containing multi-geometries '
                        'must declare a list of holes for each geometry.')

    if single_type is Point:
        if len(splits) > 1 or any(len(g) > 1 for g in split_geoms):
            geom = MultiPoint(np.concatenate(split_geoms))
        else:
            geom = Point(*split_geoms[0])
    elif len(splits):
        if multi_type is MultiPolygon:
            if split_holes is None:
                split_holes = [[]] * len(split_geoms)
            geom = MultiPolygon(list(zip(split_geoms, split_holes)))
        else:
            geom = MultiLineString(split_geoms)
    elif single_type is Polygon:
        if split_holes is None or not len(split_holes):
            split_holes = [None]
        geom = Polygon(split_geoms[0], split_holes[0])
    else:
        geom = LineString(split_geoms[0])
    return geom
コード例 #4
0
 def isscalar(cls, dataset, dim, per_geom=False):
     """
     Tests if dimension is scalar in each subpath.
     """
     dim = dataset.get_dimension(dim)
     geom_dims = cls.geom_dims(dataset)
     if dim in geom_dims:
         return False
     elif per_geom:
         return all(isscalar(v) or len(list(unique_array(v))) == 1
                    for v in dataset.data[dim.name])
     dim = dataset.get_dimension(dim)
     return len(dataset.data[dim.name].unique()) == 1
コード例 #5
0
    def iloc(cls, dataset, index):
        from shapely.geometry import MultiPoint
        rows, cols = index

        data = dict(dataset.data)
        geom = data['geometry']

        if isinstance(geom, MultiPoint):
            if isscalar(rows) or isinstance(rows, slice):
                geom = geom[rows]
            elif isinstance(rows, (set, list)):
                geom = MultiPoint([geom[r] for r in rows])
        data['geometry'] = geom
        return data
コード例 #6
0
ファイル: geopandas.py プロジェクト: RichardScottOZ/geoviews
def from_multi(eltype, data, kdims, vdims):
    """Converts list formats into geopandas.GeoDataFrame.

    Args:
        eltype: Element type to convert
        data: The original data
        kdims: The declared key dimensions
        vdims: The declared value dimensions

    Returns:
        A GeoDataFrame containing the data in the list based format.
    """

    from geopandas import GeoDataFrame

    new_data = []
    types = []
    xname, yname = (kd.name for kd in kdims[:2])
    for d in data:
        types.append(type(d))
        if isinstance(d, dict):
            d = {k: v if isscalar(v) else np.asarray(v) for k, v in d.items()}
            new_data.append(d)
            continue
        new_el = eltype(d, kdims, vdims)
        if new_el.interface is GeoPandasInterface:
            types[-1] = GeoDataFrame
            new_data.append(new_el.data)
            continue
        new_dict = {}
        for d in new_el.dimensions():
            if d in (xname, yname):
                scalar = False
            else:
                scalar = new_el.interface.isscalar(new_el, d)
            vals = new_el.dimension_values(d, not scalar)
            new_dict[d.name] = vals[0] if scalar else vals
        new_data.append(new_dict)
    if len(set(types)) > 1:
        raise DataError('Mixed types not supported')
    if new_data and types[0] is GeoDataFrame:
        data = pd.concat(new_data)
    else:
        columns = [d.name for d in kdims + vdims if d not in (xname, yname)]
        geom = GeoPandasInterface.geom_type(eltype)
        if not len(data):
            return GeoDataFrame([], columns=['geometry'] + columns)
        data = to_geopandas(new_data, xname, yname, columns, geom)
    return data
コード例 #7
0
ファイル: geopandas.py プロジェクト: RichardScottOZ/geoviews
    def iloc(cls, dataset, index):
        from geopandas import GeoSeries
        from shapely.geometry import MultiPoint
        rows, cols = index
        geom_dims = cls.geom_dims(dataset)
        geom_col = cls.geo_column(dataset.data)
        scalar = False
        columns = list(dataset.data.columns)
        if isinstance(cols, slice):
            cols = [d.name for d in dataset.dimensions()][cols]
        elif np.isscalar(cols):
            scalar = np.isscalar(rows)
            cols = [dataset.get_dimension(cols).name]
        else:
            cols = [dataset.get_dimension(d).name for d in index[1]]
        if not all(d in cols for d in geom_dims):
            raise DataError(
                "Cannot index a dimension which is part of the "
                "geometry column of a spatialpandas DataFrame.", cls)
        cols = list(
            unique_iterator([
                columns.index(geom_col) if c in geom_dims else columns.index(c)
                for c in cols
            ]))

        geom_type = dataset.data[geom_col].geom_type.iloc[0]
        if geom_type != 'MultiPoint':
            if scalar:
                return dataset.data.iloc[rows[0], cols[0]]
            elif isscalar(rows):
                rows = [rows]
            return dataset.data.iloc[rows, cols]

        geoms = dataset.data[geom_col]
        count = 0
        new_geoms, indexes = [], []
        for i, geom in enumerate(geoms):
            length = len(geom)
            if np.isscalar(rows):
                if count <= rows < (count + length):
                    new_geoms.append(geom[rows - count])
                    indexes.append(i)
                    break
            elif isinstance(rows, slice):
                if rows.start is not None and rows.start > (count + length):
                    continue
                elif rows.stop is not None and rows.stop < count:
                    break
                start = None if rows.start is None else max(
                    rows.start - count, 0)
                stop = None if rows.stop is None else min(
                    rows.stop - count, length)
                if rows.step is not None:
                    dataset.param.warning(
                        ".iloc step slicing currently not supported for"
                        "the multi-tabular data format.")
                indexes.append(i)
                new_geoms.append(geom[start:stop])
            elif isinstance(rows, (list, set)):
                sub_rows = [(r - count) for r in rows
                            if count <= r < (count + length)]
                if not sub_rows:
                    continue
                indexes.append(i)
                new_geoms.append(MultiPoint([geom[r] for r in sub_rows]))
            count += length

        new = dataset.data.iloc[indexes].copy()
        new[geom_col] = GeoSeries(new_geoms)
        return new
コード例 #8
0
 def dimension_type(cls, dataset, dim):
     name = dataset.get_dimension(dim, strict=True).name
     if name in cls.geom_dims(dataset):
         return float
     values = dataset.data[name]
     return type(values) if isscalar(values) else values.dtype.type
コード例 #9
0
    def init(cls, eltype, data, kdims, vdims):
        odict_types = (OrderedDict, cyODict)
        if kdims is None:
            kdims = eltype.kdims
        if vdims is None:
            vdims = eltype.vdims

        dimensions = [dimension_name(d) for d in kdims + vdims]
        if isinstance(data, geom_types):
            data = {'geometry': data}
        elif not isinstance(data, dict) or 'geometry' not in data:
            xdim, ydim = kdims[:2]
            from shapely.geometry import (Point, LineString, Polygon,
                                          MultiPoint, MultiPolygon,
                                          MultiLineString, LinearRing)
            data = to_geom_dict(eltype, data, kdims, vdims, GeomDictInterface)
            geom = data.get('geom_type') or MultiInterface.geom_type(eltype)
            poly = 'holes' in data or geom == 'Polygon'
            if poly:
                single_type, multi_type = Polygon, MultiPolygon
            elif geom == 'Line':
                single_type, multi_type = LineString, MultiLineString
            elif geom == 'Ring':
                single_type, multi_type = LinearRing, MultiPolygon
            else:
                single_type, multi_type = Point, MultiPoint
            data['geometry'] = geom_from_dict(data, xdim.name, ydim.name,
                                              single_type, multi_type)

        if not cls.applies(data):
            raise ValueError(
                "GeomDictInterface only handles dictionary types "
                "containing a 'geometry' key and shapely geometry "
                "value.")

        unpacked = []
        for d, vals in data.items():
            if isinstance(d, tuple):
                vals = np.asarray(vals)
                if vals.shape == (0, ):
                    for sd in d:
                        unpacked.append((sd, np.array([], dtype=vals.dtype)))
                elif not vals.ndim == 2 and vals.shape[1] == len(d):
                    raise ValueError("Values for %s dimensions did not have "
                                     "the expected shape.")
                else:
                    for i, sd in enumerate(d):
                        unpacked.append((sd, vals[:, i]))
            elif d not in dimensions:
                unpacked.append((d, vals))
            else:
                if not isscalar(vals):
                    vals = np.asarray(vals)
                    if not vals.ndim == 1 and d in dimensions:
                        raise ValueError(
                            'DictInterface expects data for each column to be flat.'
                        )
                unpacked.append((d, vals))

        if not cls.expanded(
            [vs
             for d, vs in unpacked if d in dimensions and not isscalar(vs)]):
            raise ValueError(
                'DictInterface expects data to be of uniform shape.')
        if isinstance(data, odict_types):
            data.update(unpacked)
        else:
            data = OrderedDict(unpacked)

        return data, {'kdims': kdims, 'vdims': vdims}, {}