{ "cells": [ { "cell_type": "markdown", "id": "8bcfb831-8f42-4b48-9f87-e99e3ea40874", "metadata": {}, "source": [ "# Introduction to Web Feature Service (WFS)\n", "\n", "The Web Feature Service (WFS) is a standard created by the Open Geospatial Consortium (OGC) for creating, modifying and exchanging geospatial data in vector format. A WFS encodes and transfers information in Geography Markup Language (GML) which is a subset of XML. The current version of WFS is 2.0.0, but there are also earlier versions 1.1.0 and 1.0.0 which are also still in use. Although there are some differences between the versions, the syntax between versions often remains the same.\n", "\n" ] }, { "cell_type": "markdown", "id": "59fdb10a-56b0-4138-9ff0-00b807d9107c", "metadata": {}, "source": [ "## Where to find WFS providers?\n", "\n", "\n", "### Global coverage\n", "- [Spatineo Directory](https://directory.spatineo.com/):\n", " - Very useful service to explore WFS providers in different countries. \n", " - You can easily find the WFS endpoint address for each provider.\n", " - Includes information about the stability and quality of the service. \n", "\n", "### European coverage\n", "\n", "- [Inspire Geoportal](https://inspire-geoportal.ec.europa.eu/index.html)\n", " - You can easily explore the Inspire providers.\n", " - Not possible to find WFS endpoint URLs ..(??)\n", "\n", "### Finnish coverage\n", "\n", "- [Avoindata.fi](https://www.avoindata.fi/en)\n", "- [Helsinki Region Infoshare](https://hri.fi/data/en_GB/group/59b85a25-5cf1-4eb8-a0b7-92ffe34efdad?res_format=WFS)\n", "\n", "### Estonian coverage\n", "\n", "- [Estonian Open Data portal](https://avaandmed.eesti.ee/)\n", "\n", "\n" ] }, { "cell_type": "markdown", "id": "ede0ddf5-80ac-412d-a10e-b7264b3695e2", "metadata": {}, "source": [ "## Retreaving data via WFS to geopandas\n", "\n", "To work with OGC APIs in Python, there is a library called [**OWSLib**](https://geopython.github.io/OWSLib/index.html) which works with standards such as [WFS](https://geopython.github.io/OWSLib/usage.html#wfs), [WMS](https://geopython.github.io/OWSLib/usage.html#wms) etc. It supports all (or at least majority) of the functionalities specified in the OGC standards. \n", "\n", "To make things a bit easier to work, there is also an experimental library called `geostream` which is built on top of OWSLib. The [geostream](https://github.com/geostream-org/geostream) library directly converts the data into geopandas GeoDataFrames and overall makes it a bit easier to work with WFS APIs. The library is in the early days of development and still experimental by nature. In the following we will see how it works:" ] }, { "cell_type": "code", "execution_count": 1, "id": "6d676554-09c8-4955-9829-aa28a9444fb2", "metadata": {}, "outputs": [], "source": [ "from geostream import WFS\n", "import geopandas as gpd" ] }, { "cell_type": "code", "execution_count": 2, "id": "301956aa-0bb3-44d2-8618-0dc6b2172d15", "metadata": {}, "outputs": [], "source": [ "endpoint = \"https://inspire.geoportaal.ee/geoserver/TN_teeregister/wfs\"\n", "api = WFS(endpoint)" ] }, { "cell_type": "code", "execution_count": 3, "id": "48c6f167-c030-4793-ac13-69346af9bdd2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Sisaldab Eesti teeregistri teid.'" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Via .wfs object we can access all the functionalities provided by OWSLib, such as seeing the abstract description for the WFS\n", "api.wfs.identification.abstract" ] }, { "cell_type": "code", "execution_count": 4, "id": "04173cfd-9e9f-4bc9-8318-31b62001f59a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['TN_teeregister:TN.RoadTransportNetwork.RoadLink_eteed',\n", " 'TN_teeregister:TN.RoadTransportNetwork.FunctionalRoadClass',\n", " 'TN_teeregister:TN.RoadTransportNetwork.NumberOfLanes',\n", " 'TN_teeregister:TN.RoadTransportNetwork.Road',\n", " 'TN_teeregister:TN.RoadTransportNetwork.RoadSurfaceCategory',\n", " 'TN_teeregister:TN.RoadTransportNetwork.Roadwidth',\n", " 'TN_teeregister:TN.RoadTransportNetwork.RoadLink']" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "layers = api.get_layers()\n", "layers" ] }, { "cell_type": "code", "execution_count": 5, "id": "0f2c272a-af28-4578-bd02-4b11afae58f3", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'crsOptions': [urn:ogc:def:crs:EPSG::3301],\n", " 'boundingBox': (23.41994981394858,\n", " 57.55461990262201,\n", " 28.208216378676774,\n", " 59.478274255322894,\n", " urn:ogc:def:crs:EPSG::3301),\n", " 'boundingBoxWGS84': (20.776261739109742,\n", " 6.571349317973539,\n", " 20.776291969635007,\n", " 6.571363185346309),\n", " 'title': 'Eesti teeregister (E-teed)',\n", " 'id': 'TN_teeregister:TN.RoadTransportNetwork.RoadLink_eteed',\n", " 'crs_code': 3301,\n", " 'abstract': 'Sisaldab Eesti teeregister rahvusvahelisi teid.',\n", " 'keywords': [None],\n", " 'styles': None}" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "api.get_layer_info(layers[0])" ] }, { "cell_type": "code", "execution_count": 6, "id": "e50ac94b-7139-4048-8313-1cb5335c27c2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'TN_teeregister:TN.RoadTransportNetwork.Road'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Pick one of the layers\n", "layer_id = layers[3]\n", "layer_id" ] }, { "cell_type": "markdown", "id": "f2b461c5-13b1-43ab-9b85-507c58570509", "metadata": {}, "source": [ "### Extract data from specific area based on a bounding box\n", "\n", "WFS supports limiting the data request based on bounding box. The `geostream` library provides some useful functionalities to extract geographic extent Polygons for any part of the world based on OpenStreetMap. In the following, we will use the tool to download the boundaries for Tallinn using the `.get_gdf_from_place()` method which returns the boundaries as an output:" ] }, { "cell_type": "code", "execution_count": 7, "id": "8750bb36-bfcd-4ec3-a453-5ac9c710386c", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/hentenka/.conda/envs/mamba/envs/python-gis-book/lib/python3.9/site-packages/osmnx/geocoder.py:110: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n", " gdf = gdf.append(_geocode_query_to_gdf(q, wr, by_osmid))\n" ] }, { "data": { "text/html": [ "
| \n", " | id | \n", "gml_id | \n", "gml_metadataproperty_xlink_href | \n", "gml_metadataproperty_xlink_title | \n", "gml_original_coordinate_system | \n", "gml_parent_property | \n", "gml_description | \n", "inspireid_identifier_localid | \n", "inspireid_identifier_namespace | \n", "beginlifespanversion | \n", "nationalroadcode | \n", "geographicalname_geographicalname_language | \n", "geographicalname_geographicalname_spelling_spellingofname_text | \n", "xml_ns_uri | \n", "geometry | \n", "
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | \n", "TN.RoadTransportNetwork.Road.tee_6206830 | \n", "tee_6206830 | \n", "https://metadata.geoportaal.ee/geonetwork/srv/... | \n", "Eesti teeregister | \n", "http://www.opengis.net/def/crs/EPSG/0/3301 | \n", "featureMember | \n", "Last update:2023-01-23 | \n", "tee_6206830 | \n", "ee.transpordiamet.tn.teeregister-teed | \n", "2020-11-09 | \n", "1980663 | \n", "est | \n", "Salu põik | \n", "http://inspire.ec.europa.eu/schemas/tn-ro/4.0 | \n", "LINESTRING (531689.240 6588344.611, 531731.610... | \n", "
| 1 | \n", "TN.RoadTransportNetwork.Road.tee_6865295 | \n", "tee_6865295 | \n", "https://metadata.geoportaal.ee/geonetwork/srv/... | \n", "Eesti teeregister | \n", "http://www.opengis.net/def/crs/EPSG/0/3301 | \n", "featureMember | \n", "Last update:2023-01-23 | \n", "tee_6865295 | \n", "ee.transpordiamet.tn.teeregister-teed | \n", "2020-12-18 | \n", "2451893 | \n", "est | \n", "Kopra tee | \n", "http://inspire.ec.europa.eu/schemas/tn-ro/4.0 | \n", "LINESTRING (551561.940 6591713.542, 551547.010... | \n", "
| 2 | \n", "TN.RoadTransportNetwork.Road.tee_40351 | \n", "tee_40351 | \n", "https://metadata.geoportaal.ee/geonetwork/srv/... | \n", "Eesti teeregister | \n", "http://www.opengis.net/def/crs/EPSG/0/3301 | \n", "featureMember | \n", "Last update:2023-01-23 | \n", "tee_40351 | \n", "ee.transpordiamet.tn.teeregister-teed | \n", "2021-09-24 | \n", "7841203 | \n", "est | \n", "Laagna tee | \n", "http://inspire.ec.europa.eu/schemas/tn-ro/4.0 | \n", "LINESTRING (544279.138 6588124.715, 544282.156... | \n", "
| 3 | \n", "TN.RoadTransportNetwork.Road.tee_7001773 | \n", "tee_7001773 | \n", "https://metadata.geoportaal.ee/geonetwork/srv/... | \n", "Eesti teeregister | \n", "http://www.opengis.net/def/crs/EPSG/0/3301 | \n", "featureMember | \n", "Last update:2023-01-23 | \n", "tee_7001773 | \n", "ee.transpordiamet.tn.teeregister-teed | \n", "2021-03-18 | \n", "1982736 | \n", "est | \n", "Künka tee | \n", "http://inspire.ec.europa.eu/schemas/tn-ro/4.0 | \n", "LINESTRING (533661.199 6588468.106, 533633.977... | \n", "
| 4 | \n", "TN.RoadTransportNetwork.Road.tee_6416 | \n", "tee_6416 | \n", "https://metadata.geoportaal.ee/geonetwork/srv/... | \n", "Eesti teeregister | \n", "http://www.opengis.net/def/crs/EPSG/0/3301 | \n", "featureMember | \n", "Last update:2023-01-23 | \n", "tee_6416 | \n", "ee.transpordiamet.tn.teeregister-teed | \n", "2021-09-28 | \n", "7844298 | \n", "est | \n", "Mustamäe - Tee 26 | \n", "http://inspire.ec.europa.eu/schemas/tn-ro/4.0 | \n", "LINESTRING (537908.806 6585656.426, 537989.845... | \n", "