I am trying to use the Dutch BGT Api via https://api.pdok.nl/lv/bgt/download/v1_0/ui/ with the following code:
# Native
import requests
from requests.structures import CaseInsensitiveDict
import json
import time
from zipfile import ZipFile
from io import BytesIO
# Third Party
import pandas as pd
import geopandas as gpd
# %% Function to request the download link through the BGT API
def request_bgt_download_url(base_url, featurelist, fileformat, geofilter):
api_url = F"{base_url}/lv/bgt/download/v1_0/delta/custom"
# Headers
headers = CaseInsensitiveDict()
headers["accept"] = "application/json"
headers["Content-Type"] = "application/json"
features = json.dumps(featurelist)
data = f'{{"featuretypes": {features}, "format": "{fileformat}", "geofilter": "{geofilter}"}}'
# Request
response = requests.post(api_url, headers=headers, data=data)
return response.json()['_links']['status']['href']
# %% Get the download zip URL from the download url requested with: request_bgt_download_url
def request_bgt_zip_url(base_url, download_url):
api_url = F"{base_url}{download_url}"
response = requests.get(api_url)
print(response.json())
while response.json()['status'] != 'COMPLETED':
response = requests.get(api_url)
print(response.json()['progress'])
time.sleep(1)
print(response.json())
return response.json()['_links']['download']['href']
# %% Main
base_url = "https://api.pdok.nl"
featurelist = ["bak","begroeidterreindeel","bord","buurt","functioneelgebied",
"gebouwinstallatie","installatie","kast","kunstwerkdeel",
"mast","onbegroeidterreindeel","ondersteunendwaterdeel",
"ondersteunendwegdeel","ongeclassificeerdobject","openbareruimte",
"openbareruimtelabel","overbruggingsdeel","overigbouwwerk","overigescheiding",
"paal","pand","plaatsbepalingspunt","put","scheiding","sensor","spoor",
"stadsdeel","straatmeubilair","tunneldeel","vegetatieobject","waterdeel",
"waterinrichtingselement","waterschap","wegdeel","weginrichtingselement",
"wijk"]
fileformat = "citygml"
geofilter = 'POLYGON((211417.92 475752.4800000001,212390.64000000004 475896.12,212916.48000000004 475818.84,212879.52000000005 475360.2,212950.08000000002 475203.12,212839.2 475065.36,212819.04 474981.36,212819.04 474877.2,212772 474857.04,212792.16 474769.68,212832.48 474705.84,212889.6 474695.76,213010.56000000003 474685.68,213044.16 474611.76,213030.72 474450.48,212637.6 474423.6,212708.16 473956.56,211122.24000000002 473849.04,210453.6 473896.08,210315.84000000003 473970,211417.92 475752.4800000001))'
# Get the ZIP URL
download_url = request_bgt_download_url(base_url, featurelist, fileformat, geofilter)
zip_url = request_bgt_zip_url(base_url, download_url)
# Request the ZIP URL and unpack it in python
zip_response = requests.get(f"{base_url}{zip_url}")
zipfile = ZipFile(BytesIO(zip_response.content))
files = [zipfile.open(file_name) for file_name in zipfile.namelist()]
# Read the xml files with Geopandas
gdf = gpd.read_file(files[4])
The problem is that I get an error with certain XML files, because of the CurvePolygons present in the XML:
Traceback (most recent call last):
File "<ipython-input-71-beceeaf42900>", line 1, in <module>
gdf = gpd.read_file(files[4])
File "C:\ProgramData\Anaconda3\envs\gis\lib\site-packages\geopandas\io\file.py", line 197, in _read_file
columns = list(features.schema["properties"])
File "C:\ProgramData\Anaconda3\envs\gis\lib\site-packages\fiona\collection.py", line 200, in schema
self._schema = self.session.get_schema()
File "fiona/ogrext.pyx", line 661, in fiona.ogrext.Session.get_schema
File "fiona/_geometry.pyx", line 80, in fiona._geometry.normalize_geometry_type_code
UnsupportedGeometryTypeError: 10
TypeError 10 refers to (https://github.com/Toblerity/Fiona/blob/master/fiona/_geometry.pyx):
# Unsupported types.
#8: 'CircularString',
#9: 'CompoundCurve',
#10: 'CurvePolygon',
#11: 'MultiCurve',
#12: 'MultiSurface',
#13: 'Curve',
#14: 'Surface',
#15: 'PolyhedralSurface',
#16: 'TIN',
#17: 'Triangle'
Is there a way to read the CurvePolygons fom the XML files and make them into normal Polygons so they will fit into a Geopandas GeoDataFrame?
from osgeo import gdal; gdal.VectorTranslate(inputfile, outputfile, options='-nlt CONVERT_TO_LINEAR')
, if you want to try it.