2020-09-09 20:02:35 +00:00
|
|
|
|
============================
|
|
|
|
|
Map Resources and Topography
|
|
|
|
|
============================
|
|
|
|
|
`Notebook <http://nbviewer.ipython.org/github/Unidata/python-awips/blob/master/examples/notebooks/Map_Resources_and_Topography.ipynb>`_
|
2021-09-01 18:40:35 +00:00
|
|
|
|
Python-AWIPS Tutorial Notebook
|
|
|
|
|
|
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
Objectives
|
|
|
|
|
==========
|
|
|
|
|
|
|
|
|
|
- Use python-awips to connect to an edex server
|
|
|
|
|
- Define data request object specifically for the maps database
|
|
|
|
|
- Manipulate request object for various different map resources
|
|
|
|
|
- Plot map resources in combination with one another for geographical
|
|
|
|
|
context
|
|
|
|
|
|
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
Table of Contents
|
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
|
|
| `1
|
|
|
|
|
Imports <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html#imports>`__\
|
|
|
|
|
| `2 Connect to
|
|
|
|
|
EDEX <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html#connect-to-edex>`__\
|
|
|
|
|
| `3 Function:
|
|
|
|
|
make_map() <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html#function-make-map>`__\
|
|
|
|
|
| `4 Create Initial Map From
|
|
|
|
|
CWA <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html#create-initial-map-from-cwa>`__\
|
|
|
|
|
| `5 Draw Merged
|
|
|
|
|
CWA <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html#draw-merged-cwa>`__\
|
|
|
|
|
| `6 Draw Interstates using Boundary
|
|
|
|
|
Filter <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html#draw-interstates-using-boundary-filter>`__\
|
|
|
|
|
| `7 Draw Nearby
|
|
|
|
|
Cities <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html#draw-nearby-cities>`__\
|
|
|
|
|
| `8 Draw Nearby
|
|
|
|
|
Lakes <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html#draw-nearby-lakes>`__\
|
|
|
|
|
| `9 Draw Major
|
|
|
|
|
Rivers <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html#draw-major-rivers>`__\
|
|
|
|
|
| `10 Draw
|
|
|
|
|
Topography <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html#draw-topography>`__\
|
|
|
|
|
| `11 See
|
|
|
|
|
Also <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html#see-also>`__\
|
|
|
|
|
| `11.1 Additional
|
|
|
|
|
Documentation <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html#additional-documentation>`__\
|
|
|
|
|
|
|
|
|
|
1 Imports
|
|
|
|
|
---------
|
|
|
|
|
|
|
|
|
|
The imports below are used throughout the notebook. Note the first
|
|
|
|
|
import is coming directly from python-awips and allows us to connect to
|
|
|
|
|
an EDEX server. The subsequent imports are for data manipulation and
|
|
|
|
|
visualization.
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
.. code:: ipython3
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
from awips.dataaccess import DataAccessLayer
|
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
import cartopy.crs as ccrs
|
|
|
|
|
import numpy.ma as ma
|
|
|
|
|
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
|
|
|
|
|
from cartopy.feature import ShapelyFeature,NaturalEarthFeature
|
|
|
|
|
from shapely.ops import cascaded_union
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
`Top <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html>`__
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
--------------
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
2 Connect to EDEX
|
|
|
|
|
-----------------
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
First we establish a connection to Unidata’s public EDEX server. With
|
|
|
|
|
that connection made, we can create a `new data request
|
|
|
|
|
object <http://unidata.github.io/python-awips/api/IDataRequest.html>`__
|
|
|
|
|
and set the data type to **maps**.
|
|
|
|
|
|
|
|
|
|
.. code:: ipython3
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
# Server, Data Request Type, and Database Table
|
|
|
|
|
DataAccessLayer.changeEDEXHost("edex-cloud.unidata.ucar.edu")
|
|
|
|
|
request = DataAccessLayer.newDataRequest('maps')
|
|
|
|
|
|
|
|
|
|
`Top <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html>`__
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
3 Function: make_map()
|
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
|
|
In many of our notebooks we end up plotting map images, and this logic
|
|
|
|
|
below is the same from those other notebooks. Typically, functions are
|
|
|
|
|
defined when they are called multiple times throughout a notebook. In
|
|
|
|
|
this case, we only use it in one code block cell, but because it is a
|
|
|
|
|
common function from several of our notebooks, it’s nice to keep the
|
|
|
|
|
logic neatly defined for consistency.
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
.. code:: ipython3
|
|
|
|
|
|
|
|
|
|
# Standard map plot
|
|
|
|
|
def make_map(bbox, projection=ccrs.PlateCarree()):
|
|
|
|
|
fig, ax = plt.subplots(figsize=(12,12),
|
|
|
|
|
subplot_kw=dict(projection=projection))
|
|
|
|
|
ax.set_extent(bbox)
|
|
|
|
|
ax.coastlines(resolution='50m')
|
|
|
|
|
gl = ax.gridlines(draw_labels=True)
|
|
|
|
|
gl.top_labels = gl.right_labels = False
|
|
|
|
|
gl.xformatter = LONGITUDE_FORMATTER
|
|
|
|
|
gl.yformatter = LATITUDE_FORMATTER
|
|
|
|
|
return fig, ax
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
`Top <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html>`__
|
|
|
|
|
|
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
4 Create Initial Map From CWA
|
|
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
|
|
The python-awips package provides access to the entire AWIPS Maps
|
|
|
|
|
Database for use in Python GIS applications. Map objects are returned as
|
|
|
|
|
Shapely geometries and can be easily plotted by many Python packages.
|
|
|
|
|
|
|
|
|
|
- Each map database table has a geometry field called ``the_geom``,
|
|
|
|
|
which can be used to spatially select map resources for any column of
|
|
|
|
|
type geometry.
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 19:06:40 +00:00
|
|
|
|
..
|
2021-09-01 18:40:35 +00:00
|
|
|
|
|
2021-09-01 19:06:40 +00:00
|
|
|
|
**Tip**: Note the geometry definition of ``the_geom`` for each data
|
|
|
|
|
type, which can be **Point**, **MultiPolygon**, or
|
|
|
|
|
**MultiLineString**.
|
2021-09-01 18:40:35 +00:00
|
|
|
|
|
|
|
|
|
Here we’ll be using Boulder (BOU) as our example for plotting the County
|
|
|
|
|
Warning Area (CWA). We’ll query our EDEX server to get all counties in
|
|
|
|
|
the CWA for BOU, and then plot those counties along withe the state
|
|
|
|
|
boundaries and lines of longitude and latitude. In order to get this
|
|
|
|
|
information from EDEX, we’ll need to set several characteristics on our
|
|
|
|
|
data request object. We will use
|
|
|
|
|
`request.setParameters() <http://unidata.github.io/python-awips/api/IDataRequest.html#awips.dataaccess.IDataRequest.setParameters>`__
|
|
|
|
|
to refine our query to EDEX.
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
.. code:: ipython3
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
# Specify the necessary identifiers for requesting the Boulder CWA
|
|
|
|
|
request.addIdentifier('table', 'mapdata.county')
|
2020-09-09 20:02:35 +00:00
|
|
|
|
# Define a WFO ID for location
|
|
|
|
|
# tie this ID to the mapdata.county column "cwa" for filtering
|
|
|
|
|
request.setLocationNames('BOU')
|
|
|
|
|
request.addIdentifier('cwa', 'BOU')
|
|
|
|
|
# enable location filtering (inLocation)
|
|
|
|
|
# locationField is tied to the above cwa definition (BOU)
|
|
|
|
|
request.addIdentifier('geomField', 'the_geom')
|
|
|
|
|
request.addIdentifier('inLocation', 'true')
|
|
|
|
|
request.addIdentifier('locationField', 'cwa')
|
|
|
|
|
|
|
|
|
|
# Get response and create dict of county geometries
|
2021-09-01 18:40:35 +00:00
|
|
|
|
response = DataAccessLayer.getGeometryData(request)
|
|
|
|
|
counties = []
|
2020-09-09 20:02:35 +00:00
|
|
|
|
for ob in response:
|
2021-09-01 18:40:35 +00:00
|
|
|
|
counties.append(ob.getGeometry())
|
2020-09-09 20:02:35 +00:00
|
|
|
|
print("Using " + str(len(counties)) + " county MultiPolygons")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# All WFO counties merged to a single Polygon
|
|
|
|
|
merged_counties = cascaded_union(counties)
|
|
|
|
|
envelope = merged_counties.buffer(2)
|
|
|
|
|
boundaries=[merged_counties]
|
|
|
|
|
|
|
|
|
|
# Get bounds of this merged Polygon to use as buffered map extent
|
|
|
|
|
bounds = merged_counties.bounds
|
|
|
|
|
bbox=[bounds[0]-1,bounds[2]+1,bounds[1]-1.5,bounds[3]+1.5]
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
# Create the map we'll use for the rest of this notebook based on the
|
|
|
|
|
# boundaries of the CWA
|
2020-09-09 20:02:35 +00:00
|
|
|
|
fig, ax = make_map(bbox=bbox)
|
2021-09-01 18:40:35 +00:00
|
|
|
|
|
2020-09-09 20:02:35 +00:00
|
|
|
|
# Plot political/state boundaries handled by Cartopy
|
|
|
|
|
political_boundaries = NaturalEarthFeature(category='cultural',
|
|
|
|
|
name='admin_0_boundary_lines_land',
|
|
|
|
|
scale='50m', facecolor='none')
|
|
|
|
|
states = NaturalEarthFeature(category='cultural',
|
|
|
|
|
name='admin_1_states_provinces_lines',
|
|
|
|
|
scale='50m', facecolor='none')
|
|
|
|
|
ax.add_feature(political_boundaries, linestyle='-', edgecolor='black')
|
|
|
|
|
ax.add_feature(states, linestyle='-', edgecolor='black',linewidth=2)
|
|
|
|
|
|
|
|
|
|
# Plot CWA counties
|
2021-09-01 18:40:35 +00:00
|
|
|
|
shape_feature = ShapelyFeature(counties,ccrs.PlateCarree(),
|
|
|
|
|
facecolor='none', linestyle="-",edgecolor='#86989B')
|
|
|
|
|
ax.add_feature(shape_feature)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. parsed-literal::
|
|
|
|
|
|
|
|
|
|
Using 22 county MultiPolygons
|
|
|
|
|
|
|
|
|
|
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. parsed-literal::
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
<cartopy.mpl.feature_artist.FeatureArtist at 0x11568f6d0>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
.. image:: Map_Resources_and_Topography_files/Map_Resources_and_Topography_13_2.png
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
`Top <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html>`__
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
--------------
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
5 Draw Merged CWA
|
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
|
|
In the previous section we created a merged polygon with the applicable
|
|
|
|
|
counties. Here, we draw this new shape on top of our existing map in a
|
|
|
|
|
burnt orange color.
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
.. code:: ipython3
|
|
|
|
|
|
|
|
|
|
# Plot CWA envelope
|
2021-09-01 18:40:35 +00:00
|
|
|
|
shape_feature = ShapelyFeature(boundaries,ccrs.PlateCarree(),
|
|
|
|
|
facecolor='none', linestyle="-",linewidth=3.,edgecolor='#cc5000')
|
|
|
|
|
ax.add_feature(shape_feature)
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
.. image:: Map_Resources_and_Topography_files/Map_Resources_and_Topography_16_0.png
|
|
|
|
|
|
|
|
|
|
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
`Top <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html>`__
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
--------------
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
6 Draw Interstates using Boundary Filter
|
|
|
|
|
----------------------------------------
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
Now, we’ll use the previously-defined
|
|
|
|
|
**envelope=merged_counties.buffer(2)** in a **newDataRequest()** to
|
|
|
|
|
request interstate geometries which fall inside the buffered boundary.
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
.. code:: ipython3
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
# Define the request for the interstate query
|
2020-09-09 20:02:35 +00:00
|
|
|
|
request = DataAccessLayer.newDataRequest('maps', envelope=envelope)
|
|
|
|
|
request.addIdentifier('table', 'mapdata.interstate')
|
|
|
|
|
request.addIdentifier('geomField', 'the_geom')
|
2021-09-01 18:40:35 +00:00
|
|
|
|
interstates = DataAccessLayer.getGeometryData(request)
|
2020-09-09 20:02:35 +00:00
|
|
|
|
print("Using " + str(len(interstates)) + " interstate MultiLineStrings")
|
|
|
|
|
|
|
|
|
|
# Plot interstates
|
|
|
|
|
for ob in interstates:
|
|
|
|
|
shape_feature = ShapelyFeature(ob.getGeometry(),ccrs.PlateCarree(),
|
|
|
|
|
facecolor='none', linestyle="-",edgecolor='orange')
|
|
|
|
|
ax.add_feature(shape_feature)
|
|
|
|
|
fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. parsed-literal::
|
|
|
|
|
|
|
|
|
|
Using 225 interstate MultiLineStrings
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
.. image:: Map_Resources_and_Topography_files/Map_Resources_and_Topography_19_1.png
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
`Top <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html>`__
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
--------------
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
7 Draw Nearby Cities
|
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
|
|
Request the city table based using the **envelope** attribute and filter
|
|
|
|
|
by population and progressive disclosure level.
|
|
|
|
|
|
2021-09-01 19:06:40 +00:00
|
|
|
|
**Warning**: The ``prog_disc`` field is not entirely understood and
|
|
|
|
|
values appear to change significantly depending on WFO site.
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
.. code:: ipython3
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
# Define the request for the city query
|
2020-09-09 20:02:35 +00:00
|
|
|
|
request = DataAccessLayer.newDataRequest('maps', envelope=envelope)
|
|
|
|
|
request.addIdentifier('table', 'mapdata.city')
|
|
|
|
|
request.addIdentifier('geomField', 'the_geom')
|
|
|
|
|
request.setParameters('name','population','prog_disc')
|
2021-09-01 18:40:35 +00:00
|
|
|
|
cities = DataAccessLayer.getGeometryData(request)
|
2020-09-09 20:02:35 +00:00
|
|
|
|
print("Queried " + str(len(cities)) + " total cities")
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
# Set aside two arrays - one for the geometry of the cities and one for their names
|
2020-09-09 20:02:35 +00:00
|
|
|
|
citylist = []
|
|
|
|
|
cityname = []
|
|
|
|
|
# For BOU, progressive disclosure values above 50 and pop above 5000 looks good
|
|
|
|
|
for ob in cities:
|
2021-09-01 18:40:35 +00:00
|
|
|
|
if ob.getString("population") != 'None':
|
|
|
|
|
if ob.getNumber("prog_disc") > 50 and int(ob.getString("population")) > 5000:
|
|
|
|
|
citylist.append(ob.getGeometry())
|
|
|
|
|
cityname.append(ob.getString("name"))
|
2020-09-09 20:02:35 +00:00
|
|
|
|
print("Plotting " + str(len(cityname)) + " cities")
|
|
|
|
|
|
|
|
|
|
# Plot city markers
|
|
|
|
|
ax.scatter([point.x for point in citylist],
|
|
|
|
|
[point.y for point in citylist],
|
|
|
|
|
transform=ccrs.PlateCarree(),marker="+",facecolor='black')
|
|
|
|
|
# Plot city names
|
|
|
|
|
for i, txt in enumerate(cityname):
|
|
|
|
|
ax.annotate(txt, (citylist[i].x,citylist[i].y),
|
|
|
|
|
xytext=(3,3), textcoords="offset points")
|
|
|
|
|
|
|
|
|
|
fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. parsed-literal::
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
Queried 1205 total cities
|
|
|
|
|
Plotting 58 cities
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
.. image:: Map_Resources_and_Topography_files/Map_Resources_and_Topography_22_1.png
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
`Top <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html>`__
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
--------------
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
8 Draw Nearby Lakes
|
|
|
|
|
-------------------
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
Again, use the **envelope** attribute to define a new data requst for
|
|
|
|
|
the nearby lakes.
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
.. code:: ipython3
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
# Define request for lakes
|
2020-09-09 20:02:35 +00:00
|
|
|
|
request = DataAccessLayer.newDataRequest('maps', envelope=envelope)
|
|
|
|
|
request.addIdentifier('table', 'mapdata.lake')
|
|
|
|
|
request.addIdentifier('geomField', 'the_geom')
|
|
|
|
|
|
|
|
|
|
# Get lake geometries
|
2021-09-01 18:40:35 +00:00
|
|
|
|
response = DataAccessLayer.getGeometryData(request)
|
|
|
|
|
print("Using " + str(len(response)) + " lake MultiPolygons")
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
# Plot lakes
|
2021-09-01 18:40:35 +00:00
|
|
|
|
shape_feature = ShapelyFeature([lake.getGeometry() for lake in response],ccrs.PlateCarree(),
|
|
|
|
|
facecolor='blue', linestyle="-",edgecolor='#20B2AA')
|
|
|
|
|
ax.add_feature(shape_feature)
|
2020-09-09 20:02:35 +00:00
|
|
|
|
fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. parsed-literal::
|
|
|
|
|
|
|
|
|
|
Using 208 lake MultiPolygons
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
.. image:: Map_Resources_and_Topography_files/Map_Resources_and_Topography_25_1.png
|
|
|
|
|
|
|
|
|
|
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
`Top <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html>`__
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
--------------
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
9 Draw Major Rivers
|
|
|
|
|
-------------------
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
.. code:: ipython3
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
# Define request for rivers
|
2020-09-09 20:02:35 +00:00
|
|
|
|
request = DataAccessLayer.newDataRequest('maps', envelope=envelope)
|
|
|
|
|
request.addIdentifier('table', 'mapdata.majorrivers')
|
|
|
|
|
request.addIdentifier('geomField', 'the_geom')
|
2021-09-01 18:40:35 +00:00
|
|
|
|
rivers = DataAccessLayer.getGeometryData(request)
|
2020-09-09 20:02:35 +00:00
|
|
|
|
print("Using " + str(len(rivers)) + " river MultiLineStrings")
|
|
|
|
|
|
|
|
|
|
# Plot rivers
|
2021-09-01 18:40:35 +00:00
|
|
|
|
shape_feature = ShapelyFeature([river.getGeometry() for river in rivers],ccrs.PlateCarree(),
|
|
|
|
|
facecolor='none', linestyle=":",edgecolor='#20B2AA')
|
|
|
|
|
ax.add_feature(shape_feature)
|
2020-09-09 20:02:35 +00:00
|
|
|
|
fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. parsed-literal::
|
|
|
|
|
|
|
|
|
|
Using 1400 river MultiLineStrings
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
.. image:: Map_Resources_and_Topography_files/Map_Resources_and_Topography_28_1.png
|
|
|
|
|
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
`Top <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html>`__
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
10 Draw Topography
|
|
|
|
|
------------------
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
|
|
|
|
Spatial envelopes are required for topo requests, which can become slow
|
|
|
|
|
to download and render for large (CONUS) maps.
|
|
|
|
|
|
|
|
|
|
.. code:: ipython3
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
# Define topography request
|
|
|
|
|
request = DataAccessLayer.newDataRequest("topo", envelope=envelope)
|
2020-09-09 20:02:35 +00:00
|
|
|
|
request.addIdentifier("group", "/")
|
|
|
|
|
request.addIdentifier("dataset", "full")
|
|
|
|
|
gridData = DataAccessLayer.getGridData(request)
|
|
|
|
|
print(gridData)
|
|
|
|
|
print("Number of grid records: " + str(len(gridData)))
|
|
|
|
|
print("Sample grid data shape:\n" + str(gridData[0].getRawData().shape) + "\n")
|
|
|
|
|
print("Sample grid data:\n" + str(gridData[0].getRawData()) + "\n")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. parsed-literal::
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
[<awips.dataaccess.PyGridData.PyGridData object at 0x115a20370>]
|
2020-09-09 20:02:35 +00:00
|
|
|
|
Number of grid records: 1
|
|
|
|
|
Sample grid data shape:
|
|
|
|
|
(778, 1058)
|
|
|
|
|
|
|
|
|
|
Sample grid data:
|
|
|
|
|
[[1694. 1693. 1688. ... 757. 761. 762.]
|
|
|
|
|
[1701. 1701. 1701. ... 758. 760. 762.]
|
|
|
|
|
[1703. 1703. 1703. ... 760. 761. 762.]
|
|
|
|
|
...
|
|
|
|
|
[1767. 1741. 1706. ... 769. 762. 768.]
|
|
|
|
|
[1767. 1746. 1716. ... 775. 765. 761.]
|
|
|
|
|
[1781. 1753. 1730. ... 766. 762. 759.]]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. code:: ipython3
|
|
|
|
|
|
|
|
|
|
grid=gridData[0]
|
|
|
|
|
topo=ma.masked_invalid(grid.getRawData())
|
|
|
|
|
lons, lats = grid.getLatLonCoords()
|
|
|
|
|
print(topo.min()) # minimum elevation in our domain (meters)
|
|
|
|
|
print(topo.max()) # maximum elevation in our domain (meters)
|
|
|
|
|
|
|
|
|
|
# Plot topography
|
|
|
|
|
cs = ax.contourf(lons, lats, topo, 80, cmap=plt.get_cmap('terrain'),alpha=0.1, extend='both')
|
|
|
|
|
cbar = fig.colorbar(cs, shrink=0.5, orientation='horizontal')
|
|
|
|
|
cbar.set_label("topography height in meters")
|
|
|
|
|
|
|
|
|
|
fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. parsed-literal::
|
|
|
|
|
|
|
|
|
|
623.0
|
|
|
|
|
4328.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
.. image:: Map_Resources_and_Topography_files/Map_Resources_and_Topography_32_1.png
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`Top <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html>`__
|
|
|
|
|
|
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
11 See Also
|
|
|
|
|
-----------
|
|
|
|
|
|
|
|
|
|
11.1 Additional Documentation
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
- This notebook requires: **python-awips, numpy, matplotplib, cartopy,
|
|
|
|
|
shapely**
|
|
|
|
|
- Use datatype **maps** and **addIdentifier(‘table’, <postgres maps
|
|
|
|
|
schema>)** to define the map table:
|
|
|
|
|
DataAccessLayer.changeEDEXHost(“edex-cloud.unidata.ucar.edu”) request
|
|
|
|
|
= DataAccessLayer.newDataRequest(‘maps’)
|
|
|
|
|
request.addIdentifier(‘table’, ‘mapdata.county’)
|
|
|
|
|
- Use **request.setLocationNames()** and **request.addIdentifier()** to
|
|
|
|
|
spatially filter a map resource. In the example below, WFO ID **BOU**
|
|
|
|
|
(Boulder, Colorado) is used to query counties within the BOU county
|
|
|
|
|
watch area (CWA)
|
|
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
|
|
request.addIdentifier('geomField', 'the_geom')
|
|
|
|
|
request.addIdentifier('inLocation', 'true')
|
|
|
|
|
request.addIdentifier('locationField', 'cwa')
|
|
|
|
|
request.setLocationNames('BOU')
|
|
|
|
|
request.addIdentifier('cwa', 'BOU')
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 19:06:40 +00:00
|
|
|
|
See the `Maps Database Reference
|
|
|
|
|
Page <http://unidata.github.io/awips2/python/maps-database/#mapdatacw>`__
|
|
|
|
|
for available database tables, column names, and types.
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
`Top <https://unidata.github.io/python-awips/examples/generated/Map_Resources_and_Topography.html>`__
|
2020-09-09 20:02:35 +00:00
|
|
|
|
|
2021-09-01 18:40:35 +00:00
|
|
|
|
--------------
|