This repository has been archived by the owner on Jul 24, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
wfs_api.py
139 lines (114 loc) · 5.63 KB
/
wfs_api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
from itertools import count
import requests
from geojson import Feature, FeatureCollection, LineString
import os_paw.project_paths as paths
from os_paw.api_utils import (convert_features_to_geojson,
get_feature_geometry_type, validate_api_key,
validate_bbox, validate_output_format,
validate_request_params, validate_srs,
validate_type_name)
from os_paw.products import wfs_products
class WFS_API:
"""Wrapper for the Ordnance Survey Web Feature Survey API.
To generate your own key, please create an account at
https://osdatahub.os.uk/
To see some examples of what can be done with Ordnance Survey data, refer to
https://labs.os.uk/public/os-data-hub-tutorials/
"""
_SERVICE = 'wfs'
_WFS_ENDPOINT = r'https://api.os.uk/features/v1/wfs'
_VERSION = '2.0.0'
_MAX_FEATURES_PER_REQUEST = 100
_PREMIUM_PRODUCTS = wfs_products['Premium']
_OPEN_PRODUCTS = wfs_products['Open']
_ALL_PRODUCTS = _PREMIUM_PRODUCTS | _OPEN_PRODUCTS
def __init__(self, api_key):
self.__api_key = api_key
@property
def api_key(self):
return self.__api_key
@api_key.setter
def api_key(self, new_api_key):
validate_api_key(new_api_key)
self.__api_key = new_api_key
def get_all_features_within_bbox(self, type_name, bbox,
allow_premium=False,
srs='EPSG:4326',
output_format='geojson',
max_feature_count=1000):
request_params = self._create_request_params(type_name=type_name,
bbox=bbox,
allow_premium=allow_premium,
output_format=output_format,
srs=srs,
start_index=0)
index_count = count(1, self._MAX_FEATURES_PER_REQUEST)
all_features = []
features = True
while features and request_params['startIndex'] < max_feature_count:
response = requests.get(self._WFS_ENDPOINT, params=request_params)
payload = response.json()
features = payload['features']
all_features.extend(features)
request_params['startIndex'] = next(index_count)
if all_features:
# Assumes all features in collection will be of the same type
geometry_type = get_feature_geometry_type(all_features[0]).lower()
if geometry_type == 'linestring':
all_features = convert_features_to_geojson(all_features)
elif geometry_type not in {'point', 'polygon'}:
raise Exception(f'Currently unable to handle {geometry_type}s.')
return FeatureCollection(all_features, crs=srs)
def _create_request_params(self, allow_premium, type_name, bbox,
output_format, srs='EPSG:4326', start_index=0):
validate_request_params(api_service=self._SERVICE,
type_name=type_name,
bbox=bbox,
allow_premium=allow_premium,
srs=srs,
output_format=output_format)
request_params = {
'key': self.api_key,
'service': self._SERVICE,
'version': self._VERSION,
'startIndex': start_index,
'request': 'GetFeature',
'typeNames': type_name,
'outputFormat': output_format,
'srsName': srs,
'bbox': bbox,
'count': self._MAX_FEATURES_PER_REQUEST
}
return request_params
if __name__ == '__main__':
import configparser
config = configparser.ConfigParser()
config.read(paths.config_path)
keys = config['KEYS']
API_KEY = keys['API_KEY']
WGS84_SRS = 'EPSG:4326'
BNG_SRS = 'EPSG:27700'
wfs_api = WFS_API(api_key=API_KEY)
wgs_bbox = '51.0162, 0.9160, 51.1388, 0.9877'
# LINESTRINGS
wgs_payload = wfs_api.get_all_features_within_bbox(type_name='Zoomstack_RoadsRegional',
bbox=wgs_bbox,
srs=WGS84_SRS)
# # POLYGONS
# wgs_payload = wfs_api.get_all_features_within_bbox(type_name='Zoomstack_Greenspace',
# bbox=wgs_bbox)
# POINTS
# wgs_payload = wfs_api.get_all_features_within_bbox(type_name='Zoomstack_Names',
# bbox=wgs_bbox)
# # PREMIUM
# wgs_payload = wfs_api.get_all_features_within_bbox(type_name='Highways_RoadLink',
# bbox=wgs_bbox,
# allow_premium=True,
# srs=WGS84_SRS)
print(len(wgs_payload['features']))
# bng_bbox = '605621, 139199, 607621, 141199'
# bng_bbox = '605621, 139199, 605622, 139200'
# bng_payload = wfs_api.get_all_features_within_bbox(type_name='Zoomstack_RoadsRegional',
# bbox=bng_bbox,
# srs=BNG_SRS)
# print(len(bng_payload['features']))