I'm new to GIS. Trying to use Finnish population data on 1km tiles available here: http://www.stat.fi/org/avoindata/paikkatietoaineistot_en.html

The WFS service is here: http://geo.stat.fi/geoserver/vaestoruutu/wfs

I'm using owslib to access the service:

from owslib.wfs import WebFeatureService
url = 'http://geo.stat.fi/geoserver/tilastointialueet/wfs'
wfs20 = WebFeatureService(url=url, version='2.0.0')
response = wfs20.getfeature(typename='tilastointialueet:hila1km')

First of all this response is huge, but I don't know how to ask for a smaller response. I don't understand how to get this response to a geopandas dataframe. I've tried:

out = open('data.gml', 'wb')
out.write(bytes(response.read(), 'UTF-8'))
import geopandas
tiles = geopandas.read_file('data.gml')

but get the error CPLE_OpenFailedError: b'Unable to open EPSG support file gcs.csv. Try setting the GDAL_DATA environment variable to point to the directory containing EPSG csv files.' I think that the correct EPSG should be 3067, but I don't know how to specify this when reading the file.

How to get this data to a geopandas dataframe?

  • 2
    The data contains the coordinate system code but problem is as the error message tries to tell that geopandas is not properly configured and it does not know where it could find necessary support files. Set environment for GDAL_DATA.
    – user30184
    Commented Oct 20, 2018 at 7:01

1 Answer 1


OWSLib is good for reading the details and capabilities of specific WFS. For reading the data, I would use request module to first parse the URL with parameters, and then you can read the data directly from that URL using gpd.read_file().

Read WFS capabilities and metadata:

from owslib.wfs import WebFeatureService

# URL for WFS backend
url = "http://geo.stat.fi/geoserver/vaestoruutu/wfs"

# Initialize
wfs = WebFeatureService(url=url)

# Service provider 

# Get WFS version

# Available methods
print([operation.name for operation in wfs.operations])

# Available data layers

# Print all metadata of all layers
for layer, meta in wfs.items():

Read the data into GeoDataFrame:

import geopandas as gpd
from requests import Request
from owslib.wfs import WebFeatureService

# URL for WFS backend
url = "http://geo.stat.fi/geoserver/vaestoruutu/wfs"

# Initialize
wfs = WebFeatureService(url=url)

# Fetch the last available layer (as an example) --> 'vaestoruutu:vaki2021_5km'
layer_name = list(wfs.contents)[-1]

# Specify the parameters for fetching the data
# Count: specificies amount of rows to return (e.g. 10000 or 100)
# startIndex: specifies at which offset to start returning rows
params = dict(service='WFS', version="2.0.0", request='GetFeature',
      typeName=layer_name, outputFormat='json', count=100, startIndex=0)

# Parse the URL with parameters
wfs_request_url = Request('GET', url, params=params).prepare().url

# Read data from URL
data = gpd.read_file(wfs_request_url)
  • 1
    In the version 0.4 .0 supports direct [reading from the GeoJSON Web link][1] : import geopandas as gpd url = "geo.stat.fi/geoserver/vaestoruutu/…" [1]: geopandas.org/io.html
    – SamTux
    Commented Nov 15, 2018 at 16:33
  • Cool! Thanks for pointing out. Will update the answer accordingly.
    – htenkanen
    Commented Nov 16, 2018 at 18:07
  • seems like there is a limitation on the number of rows, how can we avoid it ?
    – Basile
    Commented Jun 12, 2020 at 13:03
  • @Balise: Add pagination in the params with (count=100, startIndex=0) to avoid requesting too many rows. Suggested this as edit in the answer :)
    – Davma
    Commented Jan 5, 2023 at 23:19
  • Thanks a lot for this useful and detailed answer!
    – raphael
    Commented Jul 17, 2023 at 17:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.