In [14]:
# we'll be using these services
import owslib.wms
import owslib.wcs
import owslib.wfs
from io import BytesIO, StringIO
import os
import json
import shapely.geometry

In [15]:
import matplotlib.style
matplotlib.style.use('ggplot')
import matplotlib.pyplot as plt
%matplotlib inline

Web Maps


In [16]:
# this is the dataset of dutch altimetry
url = 'http://geodata.nationaalgeoregister.nl/ahn2/wms'

In [17]:
# we're using WMS for rendered maps
wms = owslib.wms.WebMapService(url)

In [18]:
# let's see what the server offers.
wms.contents


Out[18]:
{'ahn2_05m_int': <owslib.wms.ContentMetadata at 0x75a07b8>,
 'ahn2_05m_non': <owslib.wms.ContentMetadata at 0x75a0278>,
 'ahn2_05m_ruw': <owslib.wms.ContentMetadata at 0x75a0748>,
 'ahn2_5m': <owslib.wms.ContentMetadata at 0x75a07f0>,
 'ahn2_bladindex': <owslib.wms.ContentMetadata at 0x75a0898>}

In [19]:
# let's zoom in on delft
(top,left, bottom, right) = (52.0144342,4.3053329,51.984102,4.3947685)
# define a bounding box
bbox = (left, bottom, right, top) 
# and get a map
f = wms.getmap('ahn2_05m_ruw', bbox=bbox, size=(256, 256))

In [20]:
# oops, we missed some inputs
import logging
logging.warn(f.read())


WARNING:root:b'<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE ServiceExceptionReport SYSTEM "http://geodata.nationaalgeoregister.nl/schemas/wms/1.1.1/WMS_exception_1_1_1.dtd"> <ServiceExceptionReport version="1.1.1" >   <ServiceException code="InvalidSRS">\n      Error occurred decoding the espg code None\nNo authority was defined for code &quot;NONE&quot;. Did you forget &quot;AUTHORITY:NUMBER&quot;?\n</ServiceException></ServiceExceptionReport>'

In [21]:
# let's specify some more details, 
# We want WGS84 and we want a bigger map
f = wms.getmap(['ahn2_5m'], srs='EPSG:4326', bbox=bbox, size=(1024, 1024), format='image/png', transparent=True)

In [22]:
# convert binary data to IO stream
f_io = BytesIO(f.read())
img = plt.imread(f_io)

In [23]:
plt.subplots(figsize=(13,8))
plt.imshow(img)


Out[23]:
<matplotlib.image.AxesImage at 0x7437e10>

In [44]:
# let's find out some more details about the server
print(wms.getServiceXML().decode('ascii'))


<WMT_MS_Capabilities xmlns:xlink="http://www.w3.org/1999/xlink" updateSequence="1913" version="1.1.1">
  <Service>
    <Name>OGC:WMS</Name>
    <Title>Actueel Hoogtebestand Nederland 2</Title>
    <Abstract>Actueel Hoogtebestand Nederland 2</Abstract>
    <KeywordList>
      <Keyword>WMS</Keyword>
      <Keyword>PDOK</Keyword>
      <Keyword>infoMapAccessService</Keyword>
    </KeywordList>
    <OnlineResource xlink:href="http://geodata.nationaalgeoregister.nl/" xlink:type="simple" />
    <ContactInformation>
      <ContactPersonPrimary>
        <ContactPerson>KlantContactCenter PDOK</ContactPerson>
        <ContactOrganization>PDOK</ContactOrganization>
      </ContactPersonPrimary>
      <ContactPosition>pointOfContact</ContactPosition>
      <ContactAddress>
        <AddressType>Work</AddressType>
        <Address />
        <City>Apeldoorn</City>
        <StateOrProvince />
        <PostCode />
        <Country>Nederland</Country>
      </ContactAddress>
      <ContactVoiceTelephone />
      <ContactFacsimileTelephone />
      <ContactElectronicMailAddress>BeheerPDOK@kadaster.nl</ContactElectronicMailAddress>
    </ContactInformation>
    <Fees>no conditions apply</Fees>
    <AccessConstraints>none</AccessConstraints>
  </Service>
  <Capability>
    <Request>
      <GetCapabilities>
        <Format>application/vnd.ogc.wms_xml</Format>
        <DCPType>
          <HTTP>
            <Get>
              <OnlineResource xlink:href="http://geodata.nationaalgeoregister.nl/ahn2/wms?SERVICE=WMS&amp;" xlink:type="simple" />
            </Get>
            <Post>
              <OnlineResource xlink:href="http://geodata.nationaalgeoregister.nl/ahn2/wms?SERVICE=WMS&amp;" xlink:type="simple" />
            </Post>
          </HTTP>
        </DCPType>
      </GetCapabilities>
      <GetMap>
        <Format>image/png</Format>
        <Format>application/atom xml</Format>
        <Format>application/atom+xml</Format>
        <Format>application/openlayers</Format>
        <Format>application/pdf</Format>
        <Format>application/rss xml</Format>
        <Format>application/rss+xml</Format>
        <Format>application/vnd.google-earth.kml</Format>
        <Format>application/vnd.google-earth.kml xml</Format>
        <Format>application/vnd.google-earth.kml+xml</Format>
        <Format>application/vnd.google-earth.kml+xml;mode=networklink</Format>
        <Format>application/vnd.google-earth.kmz</Format>
        <Format>application/vnd.google-earth.kmz xml</Format>
        <Format>application/vnd.google-earth.kmz+xml</Format>
        <Format>application/vnd.google-earth.kmz;mode=networklink</Format>
        <Format>atom</Format>
        <Format>image/geotiff</Format>
        <Format>image/geotiff8</Format>
        <Format>image/gif</Format>
        <Format>image/gif;subtype=animated</Format>
        <Format>image/jpeg</Format>
        <Format>image/png8</Format>
        <Format>image/png; mode=8bit</Format>
        <Format>image/svg</Format>
        <Format>image/svg xml</Format>
        <Format>image/svg+xml</Format>
        <Format>image/tiff</Format>
        <Format>image/tiff8</Format>
        <Format>kml</Format>
        <Format>kmz</Format>
        <Format>openlayers</Format>
        <Format>rss</Format>
        <Format>text/html; subtype=openlayers</Format>
        <DCPType>
          <HTTP>
            <Get>
              <OnlineResource xlink:href="http://geodata.nationaalgeoregister.nl/ahn2/wms?SERVICE=WMS&amp;" xlink:type="simple" />
            </Get>
          </HTTP>
        </DCPType>
      </GetMap>
      <GetFeatureInfo>
        <Format>text/plain</Format>
        <Format>application/vnd.ogc.gml</Format>
        <Format>text/xml</Format>
        <Format>application/vnd.ogc.gml/3.1.1</Format>
        <Format>text/xml; subtype=gml/3.1.1</Format>
        <Format>text/html</Format>
        <Format>application/json</Format>
        <DCPType>
          <HTTP>
            <Get>
              <OnlineResource xlink:href="http://geodata.nationaalgeoregister.nl/ahn2/wms?SERVICE=WMS&amp;" xlink:type="simple" />
            </Get>
            <Post>
              <OnlineResource xlink:href="http://geodata.nationaalgeoregister.nl/ahn2/wms?SERVICE=WMS&amp;" xlink:type="simple" />
            </Post>
          </HTTP>
        </DCPType>
      </GetFeatureInfo>
      <DescribeLayer>
        <Format>application/vnd.ogc.wms_xml</Format>
        <DCPType>
          <HTTP>
            <Get>
              <OnlineResource xlink:href="http://geodata.nationaalgeoregister.nl/ahn2/wms?SERVICE=WMS&amp;" xlink:type="simple" />
            </Get>
          </HTTP>
        </DCPType>
      </DescribeLayer>
      <GetLegendGraphic>
        <Format>image/png</Format>
        <Format>image/jpeg</Format>
        <Format>image/gif</Format>
        <DCPType>
          <HTTP>
            <Get>
              <OnlineResource xlink:href="http://geodata.nationaalgeoregister.nl/ahn2/wms?SERVICE=WMS&amp;" xlink:type="simple" />
            </Get>
          </HTTP>
        </DCPType>
      </GetLegendGraphic>
      <GetStyles>
        <Format>application/vnd.ogc.sld+xml</Format>
        <DCPType>
          <HTTP>
            <Get>
              <OnlineResource xlink:href="http://geodata.nationaalgeoregister.nl/ahn2/wms?SERVICE=WMS&amp;" xlink:type="simple" />
            </Get>
          </HTTP>
        </DCPType>
      </GetStyles>
    </Request>
    <Exception>
      <Format>application/vnd.ogc.se_xml</Format>
      <Format>application/vnd.ogc.se_inimage</Format>
      <Format>application/vnd.ogc.se_blank</Format>
    </Exception>
    <VendorSpecificCapabilities />
    <UserDefinedSymbolization RemoteWFS="1" SupportSLD="1" UserLayer="1" UserStyle="1" />
    <Layer>
      <Title>Actueel Hoogtebestand Nederland 2</Title>
      <Abstract>Actueel Hoogtebestand Nederland 2</Abstract>
      
      <SRS>EPSG:25831</SRS>
      <SRS>EPSG:25832</SRS>
      <SRS>EPSG:28992</SRS>
      <SRS>EPSG:3034</SRS>
      <SRS>EPSG:3035</SRS>
      <SRS>EPSG:3857</SRS>
      <SRS>EPSG:4258</SRS>
      <SRS>EPSG:4326</SRS>
      <LatLonBoundingBox maxx="7.273799656562079" maxy="53.55490608251144" minx="3.2012587672031283" miny="50.72814376700224" />
      <BoundingBox SRS="EPSG:4326" maxx="7.273799656562079" maxy="53.55490608251144" minx="3.2012587672031283" miny="50.72814376700224" />
      <BoundingBox SRS="EPSG:4258" maxx="7.273799656562079" maxy="53.554906083412476" minx="3.2012587672031287" miny="50.72814376792637" />
      <BoundingBox SRS="EPSG:3035" maxx="4140353.143005944" maxy="3404140.7447055597" minx="3841738.116121487" miny="3072084.1427382175" />
      <BoundingBox SRS="EPSG:3034" maxx="3825376.919705849" maxy="2987211.013175145" minx="3537116.0663671913" miny="2666783.5833347915" />
      <BoundingBox SRS="EPSG:3857" maxx="809715.6739007788" maxy="7086307.463431749" minx="356362.495862555" miny="6573345.657901575" />
      <BoundingBox SRS="EPSG:28992" maxx="288131.22740307095" maxy="620944.4704319139" minx="587.7038058960752" miny="304228.85162430233" />
      <BoundingBox SRS="EPSG:25831" maxx="801584.3681230601" maxy="5942500.858425828" minx="513332.737091332" miny="5619613.469290287" />
      <BoundingBox SRS="EPSG:25832" maxx="385649.8643967738" maxy="5949654.589106056" minx="90870.66306016548" miny="5621015.098761116" />
      <AuthorityURL name="PDOK">
        <OnlineResource xlink:href="http://www.pdok.nl" />
      </AuthorityURL>
      <Layer opaque="0" queryable="1">
        <Name>ahn2_05m_int</Name>
        <Title>ahn2_0.5m_geinterpoleerd</Title>
        <Abstract />
        <KeywordList>
          <Keyword>WCS</Keyword>
          <Keyword>ImageMosaic</Keyword>
          <Keyword>ahn2_05m_int</Keyword>
          <Keyword>infoMapAccessService</Keyword>
        </KeywordList>
        <SRS>EPSG:28992</SRS>
        
        <LatLonBoundingBox maxx="7.257742689700455" maxy="53.53246277298016" minx="3.247598752084866" miny="50.728891615388974" />
        <BoundingBox SRS="EPSG:28992" maxx="279000.0" maxy="616250.0" minx="13000.0" miny="306250.0" />
        <BoundingBox SRS="EPSG:4326" maxx="7.256670702817714" maxy="53.53226914232056" minx="3.246545004046175" miny="50.72869738465634" />
        <BoundingBox SRS="EPSG:4258" maxx="7.256670702817714" maxy="53.53226914322182" minx="3.246545004046175" miny="50.72869738558046" />
        <BoundingBox SRS="EPSG:3035" maxx="4139060.8896294045" maxy="3399253.612019572" minx="3854022.6612462844" miny="3072958.0190181057" />
        <BoundingBox SRS="EPSG:3034" maxx="3824132.2923488356" maxy="2982493.1329725673" minx="3548986.4721450764" miny="2667624.2324392176" />
        <BoundingBox SRS="EPSG:3857" maxx="807808.8874921346" maxy="7082066.659439815" minx="361403.7366878665" miny="6573443.017669047" />
        <BoundingBox SRS="EPSG:25831" maxx="792368.7222270598" maxy="5938314.292717852" minx="516348.7956727453" miny="5619723.1291915905" />
        <BoundingBox SRS="EPSG:25832" maxx="384414.39765056974" maxy="5944794.755039554" minx="103196.4798537966" miny="5621761.058799986" />
        <MetadataURL type="TC211">
          <Format>text/plain</Format>
          <OnlineResource xlink:href="http://www.nationaalgeoregister.nl/geonetwork/srv/dut/xml.metadata.get?uuid=b9dd8575-3c1c-41f4-add5-c4f5f2b67181" xlink:type="simple" />
        </MetadataURL>
        <Style>
          <Name>ahn2_05m_detail</Name>
          <Title>ahn2_05m</Title>
          <Abstract>Style for AHN_2 (m)</Abstract>
          <LegendURL height="20" width="20">
            <Format>image/png</Format>
            <OnlineResource xlink:href="http://geodata.nationaalgeoregister.nl/ahn2/wms?request=GetLegendGraphic&amp;format=image%2Fpng&amp;width=20&amp;height=20&amp;layer=ahn2_05m_int" xlink:type="simple" />
          </LegendURL>
        </Style>
        <ScaleHint max="20000.0" min="0.0" />
      </Layer>
      <Layer opaque="0" queryable="1">
        <Name>ahn2_05m_non</Name>
        <Title>ahn2_0.5m_niet_geinterpoleerd</Title>
        <Abstra

In [27]:
# let's zoom out
(top,left, bottom, right) = (53.8,3,50.5,7.1)
bbox = (left, bottom, right, top) 
f = wms.getmap(['ahn2_5m'], srs='EPSG:4326', bbox=bbox, size=(1024, 1024), format='image/png', transparent=True)
f_io = BytesIO(f.read())
img = plt.imread(f_io)
plt.imshow(img)


Out[27]:
<matplotlib.image.AxesImage at 0x7759860>

In [28]:
(top,left, bottom, right) = (52.05,4.30,51.95,4.40)
bbox = (left, bottom, right, top) 

f = wms.getmap(['ahn2_5m'], srs='EPSG:4326', bbox=bbox, size=(1024, 1024), format='application/vnd.google-earth.kml', transparent=True)
open('file.kml', 'w').write(f.read().decode('ascii'))

os.system('file.kml')


Out[28]:
1

Web coverage


In [29]:
url='http://geodata.nationaalgeoregister.nl/ahn2/wcs'
wcs = owslib.wcs.WebCoverageService(url=url, 
                                    version="1.0.0") # version is actually 1.1.1, 1.2.0 
meta = wcs.contents['ahn2:ahn2_5m']
bbox = meta.boundingBoxWGS84

In [30]:
# How do we get this to work?
f = wcs.getCoverage(identifier='ahn2:ahn2_5m',
                bbox=bbox, 
                format='GeoTIFF',
                crs='EPSG:28992', 
                version="1.0.0",
                resx=5, resy=5)
f.read()[1:1000]


Out[30]:
b'?xml version="1.0" encoding="UTF-8"?><ServiceExceptionReport version="1.2.0" >   <ServiceException>\n      java.lang.IllegalArgumentException: Illegal value for argument &quot;resolutions&quot;.\nIllegal value for argument &quot;resolutions&quot;.\n</ServiceException></ServiceExceptionReport>'

Web Feature Service


In [31]:
url = 'http://geodata.nationaalgeoregister.nl/ahn2/wfs'
wfs = owslib.wfs.WebFeatureService(url, version="2.0.0")
# only one layer
wfs.contents
print(wfs)


<owslib.feature.wfs200.WebFeatureService_2_0_0 object at 0x000000000767FEB8>

In [32]:
layer = wfs.contents['ahn2:ahn2_bladindex']
layer = list(wfs.contents.values())[0]

In [39]:
# let's read the features
f = wfs.getfeature(typename=[layer.id], outputFormat="json")

data = json.loads(f.read().decode('ascii'))

shapes = []
for feature in data['features']:
    shapes.append(shapely.geometry.asShape(feature['geometry'])[0])

In [40]:
import numpy as np
for shape in shapes:
    xy = np.array(shape.exterior.coords)
    plt.plot(xy[:,0], xy[:,1], 'k-')



In [41]:
data['features'][0]


Out[41]:
{'geometry': {'coordinates': [[[[200000, 618750],
     [205000, 618750],
     [205000, 612500],
     [200000, 612500],
     [200000, 618750]]]],
  'type': 'MultiPolygon'},
 'geometry_name': 'geom',
 'id': 'ahn2_bladindex.1',
 'properties': {'bladnr': '02ez1',
  'cellsize': '5',
  'datum': '2008-02-14Z',
  'geom_valid': True,
  'lo_x': '200000',
  'lo_y': '612500',
  'max_datum': '2008-03-04Z',
  'min_datum': '2008-02-14Z',
  'update': '2009-05-27Z'},
 'type': 'Feature'}

In [21]:
# Challenge
# read point cloud from http://geodata.nationaalgeoregister.nl/ahn2/atom/ahn2_uitgefilterd.xml

In [21]: