Пример #1
0
 def get_extents(self, element, ranges):
     extents = super(TilePlot, self).get_extents(element, ranges)
     if not self.overlaid:
         global_extent = (-20026376.39, -20048966.10, 20026376.39,
                          20048966.10)
         return util.max_extents([extents, global_extent])
     return extents
Пример #2
0
 def range(self, dim, data_range=True):
     didx = self.get_dimension_index(dim)
     if didx in [0, 1] and data_range:
         dim = self.get_dimension(dim)
         l, b, r, t = max_extents([geom.bounds for geom in self.data.geometries()])
         lower, upper = (b, t) if didx else (l, r)
         return dimension_range(lower, upper, dim)
     return super(Feature, self).range(dim, data_range)
Пример #3
0
 def range(self, dim, data_range=True, dimension_range=True):
     didx = self.get_dimension_index(dim)
     if didx in [0, 1] and data_range:
         dim = self.get_dimension(dim)
         l, b, r, t = util.max_extents([geom.bounds for geom in self.data.geometries()])
         lower, upper = (b, t) if didx else (l, r)
         if dimension_range:
             return util.dimension_range(lower, upper, dim.range, dim.soft_range)
         else:
             return lower, upper
     return super(Feature, self).range(dim, data_range, dimension_range)
Пример #4
0
    def _process_element(self, element):
        if element.crs == self.p.projection:
            return element
        elif not len(element):
            return element.clone(crs=self.p.projection)

        crs = element.crs
        cylindrical = isinstance(crs, ccrs._CylindricalProjection)
        proj = self.p.projection
        if isinstance(proj, ccrs.CRS) and not isinstance(proj, ccrs.Projection):
            raise ValueError('invalid transform:'
                             ' Spherical contouring is not supported - '
                             ' consider using PlateCarree/RotatedPole.')

        boundary = Polygon(crs.boundary)
        bounds = [round(b, 10) for b in boundary.bounds]
        xoffset = round((boundary.bounds[2]-boundary.bounds[0])/2.)
        if isinstance(element, Polygons):
            geoms = polygons_to_geom_dicts(element, skip_invalid=False)
        else:
            geoms = path_to_geom_dicts(element, skip_invalid=False)

        data_bounds = max_extents([g['geometry'].bounds for g in geoms])
        total_bounds = tuple(round(b, 10) for b in data_bounds)

        projected = []
        for path in geoms:
            geom = path['geometry']
            if (cylindrical and total_bounds[0] >= (bounds[0]+xoffset) and
                total_bounds[2] > (bounds[2]+xoffset//2)):
                # Offset if lon and not centered on 0 longitude
                # i.e. lon_min > 0 and lon_max > 270
                geom = shapely.affinity.translate(geom, xoff=-xoffset)
            geom_bounds = [round(b, 10) for b in geom.bounds]

            if boundary and (geom_bounds[0] < bounds[0] or
                             geom_bounds[2] > bounds[2]):
                try:
                    geom = boundary.intersection(geom)
                except:
                    pass

            # Ensure minimum area for polygons (precision issues cause errors)
            if isinstance(geom, Polygon) and geom.area < 1e-15:
                continue
            elif isinstance(geom, MultiPolygon):
                polys = [g for g in geom if g.area > 1e-15]
                if not polys:
                    continue
                geom = MultiPolygon(polys)
            elif (not geom or isinstance(geom, GeometryCollection)):
                continue

            proj_geom = proj.project_geometry(geom, element.crs)

            # Attempt to fix geometry without being noisy about it
            logger = logging.getLogger()
            try:
                prev = logger.level
                logger.setLevel(logging.ERROR)
                if not proj_geom.is_valid:
                    proj_geom = proj.project_geometry(geom.buffer(0), element.crs)
            except:
                continue
            finally:
                logger.setLevel(prev)
            data = dict(path, geometry=proj_geom)
            projected.append(data)

        if len(geoms) and len(projected) == 0:
            self.warning('While projecting a %s element from a %s coordinate '
                         'reference system (crs) to a %s projection none of '
                         'the projected paths were contained within the bounds '
                         'specified by the projection. Ensure you have specified '
                         'the correct coordinate system for your data.' %
                         (type(element).__name__, type(element.crs).__name__,
                          type(self.p.projection).__name__))

        # Try casting back to original types
        if element.interface is GeoPandasInterface:
            import geopandas as gpd
            projected = gpd.GeoDataFrame(projected, columns=element.data.columns)
        elif element.interface is MultiInterface:
            x, y = element.kdims
            item = element.data[0] if element.data else None
            if item is None or (isinstance(item, dict) and 'geometry' in item):
                return element.clone(projected, crs=self.p.projection)
            projected = [geom_dict_to_array_dict(p, [x.name, y.name]) for p in projected]
            if any('holes' in p for p in projected):
                pass
            elif pd and isinstance(item, pd.DataFrame):
                projected = [pd.DataFrame(p, columns=item.columns) for p in projected]
            elif isinstance(item, np.ndarray):
                projected = [np.column_stack([p[d.name] for d in element.dimensions()])
                             for p in projected]
        return element.clone(projected, crs=self.p.projection)