def intersecting_geometries(self, extent): """ Returns an iterator of shapely geometries for the GSHHS dataset that intersect with the given extent. """ if self._scale == 'auto': scale = self._scale_from_extent(extent) else: scale = self._scale[0] if extent is not None: extent_geom = shapely.geometry.box(extent[0], extent[2], extent[1], extent[3]) for level in self._levels: geoms = GSHHSFeature._geometries_cache.get((scale, level)) if geoms is None: # Load GSHHS geometries from appropriate shape file. # TODO selective load based on bbox of each geom in file. path = shapereader.gshhs(scale, level) geoms = tuple(shapereader.Reader(path).geometries()) GSHHSFeature._geometries_cache[(scale, level)] = geoms for geom in geoms: if extent is None or extent_geom.intersects(geom): yield geom
def plot_map(fig=None, coast='med', figsize=(10, 10), ll_lim=None, cp=None): crs = ccrs.PlateCarree() # if fig is None: fig = plt.figure(figsize=figsize) else: fig.clf() if ll_lim is None: if cp is not None: ll_lim = cp.lon_lim + cp.lat_lim else: ll_lim = _ll_lim_default ax = fig.add_subplot(111, projection=crs) ax.set_extent(ll_lim, crs=crs) gl = ax.gridlines(crs=crs, draw_labels=True, linewidth=2, color='k', alpha=0.5, linestyle='--') gl.xlabels_top = False # if coast in ['10m', '50m', '110m']: ax.coastlines(resolution=coast, color='k') elif coast in ['auto', 'coarse', 'low', 'intermediate', 'high', 'full']: shpfile = shapereader.gshhs('h') shp = shapereader.Reader(shpfile) ax.add_geometries(shp.geometries(), crs, edgecolor='black', facecolor='none') elif coast == 'med': # conda install -c conda-forge gdal # ogr2ogr -f "ESRI Shapefile" med_coast.shp /Users/aponte/.local/share/cartopy/shapefiles/gshhs/h/GSHHS_h_L1.shp -clipsrc 5 42. 7 44. shp = shapereader.Reader( os.getenv('HOME') + '/data/OSM/med/med_coast.shp') for record, geometry in zip(shp.records(), shp.geometries()): ax.add_geometries([geometry], crs, facecolor='None', edgecolor='black') elif coast == 'med_high': # conda install -c conda-forge gdal # ogr2ogr -f "ESRI Shapefile" med_high_coast.shp ../coastlines/lines.shp -clipsrc 6 7 42.5 43.5 shp = shapereader.Reader( os.getenv('HOME') + '/data/OSM/med/med_high_coast.shp') for record, geometry in zip(shp.records(), shp.geometries()): ax.add_geometries([geometry], crs, facecolor='None', edgecolor='black') return [fig, ax, crs]
def add_coastlines(latlon_extent, ax): """ new method for adding coastlines, to replace the cartopy builtin method. This is dependent on the GSHHS data, "h"igh resolution shapefiles. We rely on the cartopy shapereader to manage the GSHHS datafiles. Copies the method created by Rob Nelson for the OCO3 quicklook imagery. inputs: latlon_extent: W,S,E,N of the bounding box in a 4-element arraylike. ax: the axis to use for drawing coastlines. """ shp1 = shapereader.Reader(shapereader.gshhs('h', 1)) shp2 = shapereader.Reader(shapereader.gshhs('h', 2)) shp3 = shapereader.Reader(shapereader.gshhs('h', 3)) coastlines_all = [[geoms1 for geoms1 in shp1.geometries()], [geoms2 for geoms2 in shp2.geometries()], [geoms3 for geoms3 in shp3.geometries()]] coastlines = [item for sublist in coastlines_all for item in sublist] # STRtree is used to efficiently discard most of the coastline data, # which is a global dataset. In effect, this loop identifies the # small subset of coastline data that resides in the latlon box. W, S, E, N = latlon_extent plotting_box = sgeom.Polygon([[W, S], [E, S], [E, N], [W, N], [W, S]]) tree = STRtree([plotting_box]) coasts_in_box = [] for i in range(len(coastlines)): if tree.query(coastlines[i]): coasts_in_box.append(coastlines[i]) ax.add_geometries(coasts_in_box, ccrs.PlateCarree(), facecolor='None', edgecolor='k')
def intersecting_geometries(self, extent): if self._scale == 'auto': scale = self._scale_from_extent(extent) else: scale = self._scale[0] if extent is not None: extent_geom = sgeom.box(extent[0], extent[2], extent[1], extent[3]) for level in self._levels: geoms = GSHHSFeature._geometries_cache.get((scale, level)) if geoms is None: # Load GSHHS geometries from appropriate shape file. # TODO selective load based on bbox of each geom in file. path = shapereader.gshhs(scale, level) geoms = tuple(shapereader.Reader(path).geometries()) GSHHSFeature._geometries_cache[(scale, level)] = geoms for geom in geoms: if extent is None or extent_geom.intersects(geom): yield geom
def _make_basemap(config, maxdist): g = Geod(ellps='WGS84') hypo = config.hypo maxdiagonal = maxdist * (2**0.5) * 1.10 lonmax, latmax, _ = g.fwd(hypo.longitude, hypo.latitude, 45, maxdiagonal * 1000.) lonmin = 2 * hypo.longitude - lonmax latmin = 2 * hypo.latitude - latmax tile_dir = 'maptiles' stamen_terrain = CachedTiler(cimgt.Stamen('terrain-background'), tile_dir) # Create a GeoAxes figsize = (7.5, 7.5) fig = plt.figure(figsize=figsize, dpi=200) ax = fig.add_subplot(111, projection=stamen_terrain.crs) # Add event information as a title textstr = 'evid: {} \nlon: {:.3f} lat: {:.3f} depth: {:.1f} km' textstr = textstr.format(hypo.evid, hypo.longitude, hypo.latitude, hypo.depth) try: textstr += ' time: {}'.format( hypo.origin_time.format_iris_web_service()) except AttributeError: pass ax.text(0., 1.15, textstr, fontsize=10, ha='left', va='top', linespacing=1.5, transform=ax.transAxes) trans = ccrs.Geodetic() ax.set_extent([lonmin, lonmax, latmin, latmax], crs=trans) if config.plot_map_tiles_zoom_level: tile_zoom_level = config.plot_map_tiles_zoom_level else: if maxdiagonal <= 100: tile_zoom_level = 12 else: tile_zoom_level = 8 logger.info('Map zoom level autoset to: {}'.format(tile_zoom_level)) # Add the image twice, so that the CachedTiler has time to cache # (avoids white tiles on map) ax.add_image(stamen_terrain, tile_zoom_level) ax.add_image(stamen_terrain, tile_zoom_level) ax.gridlines(draw_labels=True, color='#777777', linestyle='--') # add coastlines from GSHHS res_map = { 'full': 'f', 'high': 'h', 'intermediate': 'i', 'low': 'l', 'crude': 'c' } inv_res_map = {v: k for k, v in res_map.items()} if config.plot_coastline_resolution: coastline_resolution = res_map[config.plot_coastline_resolution] else: if maxdiagonal <= 100: coastline_resolution = 'h' else: coastline_resolution = 'i' logger.info('Coastline resolution autoset to: {}'.format( inv_res_map[coastline_resolution])) shpfile = shpreader.gshhs(coastline_resolution) shp = shpreader.Reader(shpfile) with warnings.catch_warnings(): # silent a warning on: # "Shapefile shape has invalid polygon: no exterior rings found" warnings.simplefilter('ignore') ax.add_geometries(shp.geometries(), ccrs.PlateCarree(), edgecolor='black', facecolor='none') ax.add_feature(cfeature.BORDERS, edgecolor='black', facecolor='none') circle_texts = _plot_circles(ax, hypo.longitude, hypo.latitude, maxdist, 5) _plot_hypo(ax, hypo) return ax, circle_texts