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
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)
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)
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)