Source code for GeoHealthCheck.plugins.probe.mapbox

from GeoHealthCheck.probe import Probe
import math
from pyproj import CRS, Transformer


[docs]class TileJSON(Probe): """ TileJSON """ NAME = 'TileJSON' DESCRIPTION = 'Request Mapbox TileJSON Service and ' + \ 'request each zoom level at center coordinates' RESOURCE_TYPE = 'Mapbox:TileJSON' REQUEST_METHOD = 'GET' CHECKS_AVAIL = { 'GeoHealthCheck.plugins.check.checks.HttpStatusNoError': { 'default': True }, } """Checks avail""" PARAM_DEFS = { 'lat_4326': { 'type': 'float', 'description': 'latitude in EPSG:4326', 'required': False }, 'lon_4326': { 'type': 'float', 'description': 'longitude in EPSG:4326', 'required': False }, }
[docs] def perform_request(self): url_base = self._resource.url # Remove trailing '/' if present if url_base.endswith('/'): url_base = url_base[0:-2] # Add .json to url if not present yet if url_base.endswith('.json'): json_url = url_base else: json_url = url_base + '.json' self.log('Requesting: %s url=%s' % (self.REQUEST_METHOD, json_url)) self.response = Probe.perform_get_request(self, json_url) self.run_checks() tile_info = self.response.json() lat, lon = self.get_latlon(tile_info) if not lat or not lon: # If none of the above are present, raise error err_message = 'No center coordinates given in tile.json.' + \ 'Please add lat/lon as probe parameters.' self.result.set(False, err_message) return # Convert bound coordinates to WebMercator transformer = Transformer.from_crs(CRS('EPSG:4326'), CRS('EPSG:3857'), always_xy=False) wm_coords = transformer.transform(lat, lon) # Circumference (2 * pi * Semi-major Axis) circ = 2 * math.pi * 6378137.0 # For calculating the relative tile index for zoom levels x_rel = (circ / 2 + wm_coords[0]) / circ y_rel = (circ / 2 - wm_coords[1]) / circ for tile_url in tile_info['tiles']: zoom_list = range(tile_info.get('minzoom', 0), tile_info.get('maxzoom', 22) + 1) for zoom in zoom_list: tile_count = 2 ** zoom zxy = { 'z': zoom, 'x': int(x_rel * tile_count), 'y': int(y_rel * tile_count), } # Determine the tile URL. zoom_url = tile_url.format(**zxy) self.log('Requesting zoom %s: url=%s' % (zoom, zoom_url)) self.response = Probe.perform_get_request(self, zoom_url) self.run_checks()
def get_latlon(self, tile_info): if ('lat_4326' in self._parameters and 'lon_4326' in self._parameters): if (self._parameters['lat_4326'] and self._parameters['lon_4326']): lat = self._parameters['lat_4326'] lon = self._parameters['lon_4326'] return lat, lon # If there are no user input parameters, take center from json if 'center' in tile_info: lat, lon = tile_info['center'][1], tile_info['center'][0] return lat, lon # If there is no center attribute in json, take bounds from json if 'bounds' in tile_info: lat = (tile_info['bounds'][1] + tile_info['bounds'][3]) / 2 lon = (tile_info['bounds'][0] + tile_info['bounds'][2]) / 2 return lat, lon return False, False