Web Map Tile Service
Der OGC-Standard Web Map Tile Service (WMTS) ist eine von mehreren Konventionen um Rasterkarten als (potenziell vor-berechnete & vor-gerenderte) Kachelsammlung anzubieten.
Inhaltsverzeichnis
XYZ → WMTS
Hat man bereits einen nach XYZ-Konvention im Web verfügbaren Kachel-Satz, so lässt sich aus diesem ein (RESTful) WTMS machen, in dem man eine passende (statische) ServiceMetadata-XML-Datei WMTSCapabilities.xml
serviert.
XML-Schema-Validierung für WMTSCapabilities.xml
Siehe auch diese StackOverflow-Antwort bzgl. "XML Schema (XSD) validation tool".
Mit xmllint
(libxml)
(CLI-Tool das bei libxml mitinstalliert wird, und somit auf Linux & Mac meist bereits vorhanden ist.)
xmllint --noout --schema http://www.opengis.net/wmts/1.0 WMTSCapabilities.xml
oder
xmllint --noout --schema http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd WMTSCapabilities.xml
(Falls das Schema lokal vorhanden ist, kann auch der Pfad zur Schema-Datei angegeben werden. Umgekehrt kann die XML-Datei auch als URL angegeben werden, um eine online verfügbare Version zu validieren.)
Mit xsd-validator
(Kleines Java-Programm, das den Standard-XML-Parser der JRE (normalerweise Xerces) verwendet.)
git clone https://github.com/amouat/xsd-validator.git wget http://www.opengis.net/wmts/1.0 --output-document=wmts.xsd wget http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd ./xsd-validator/xsdv.sh wmts.xsd WMTSCapabilities.xml
oder einfach
git clone https://github.com/amouat/xsd-validator.git wget http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd ./xsd-validator/xsdv.sh wmtsGetCapabilities_response.xsd WMTSCapabilities.xml
(xsd-validator
kann nur mit lokalen Schema-Dateien umgehen, daher laden wir diese(s) hier mit wget
selbst herunter. Auch die XML-Datei muss lokal vorliegen.)
TileMatrixSet
Für einen Kachel-Satz nach OSM- & Google Maps-Konvention kann das "Well-known scale set" "GoogleMapsCompatible" (urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible
) aus Annex E.4 des Standards verwendet werden.
Scale Denominator
In Tabelle E.4 "Definition of Well-known scale set GoogleMapsCompatible" im Standard sind die Werte des "Scale Denominator" bereits für die Zoom-Levels 0–18 angegeben. Diese lassen sich aber auch wie folgt berechnen:
Herleitung
In Abschnitt 6.1 "Tile matrix set – the geometry of the tiled space" des Standards erhalten wir (unten auf Seite 8) u.A. folgende beiden Formeln:
pixelSpan = scaleDenominator × 0.28e-3 / metersPerUnit(crs)
tileSpanX = tileWidth × pixelSpan
Daraus folgt
tileSpanX = tileWidth × scaleDenominator × 0.28e-3 / metersPerUnit(crs)
und daraus durch auflösen nach scaleDenominator
scaleDenominator = tileSpanX × metersPerUnit(crs) / (tileWidth × 0.28e-3)
Die Kachel-Kantenlänge in Pixel tileWidth
ist bei OSM & Google immer 256.
Das CRS WebMercator verwendet (pseudo-)Metrische Koordinaten, daher ist metersPerUnit(crs)
hierfür 1.
Bei Zoomlevel Z
wird die Welt zwischen 85.06°S and 85.06°N (und von 180°W bis 180°O) auf 2^Z × 2^Z
Kacheln abgebildet. Entlang des Äquators hat man also 2^Z
Kachel-Kanten. Laut Annex E.4 stimmen die "Scale Denominator"-Werte nur in Äquatornähe, also können wir das verwenden. Der Äquator-Radius (im EPSG-Eintrag "Semi-Major Axis (a)" genannt) ist der von WGS 84 und beträgt 6'378'137 m. Mit Tau
(a.k.a. 2 Pi
) multipliziert ergibt dies die Äquatorlänge. Damit ist
tileSpanX = Äquatorlänge / (2^Z) = 6378137 × Tau / (2^Z)
Damit ergibt sich
scaleDenominator = (6378137 × Tau / (2^Z)) / (256 × 0.28e-3)
oder umgeformt die
Berechnungsformel
scaleDenominator = 6378137 × Tau / (256 × (2^Z) × 0.28e-3)
Berechnung für Zoomlevels 0–18 in Python 3.6:
from math import tau equator_length = 6378137 * tau {i : equator_length / (256 * 2**i * 0.28e-3) for i in range(19)}
{0: 559082264.0287178, 1: 279541132.0143589, 2: 139770566.00717944, 3: 69885283.00358972, 4: 34942641.50179486, 5: 17471320.75089743, 6: 8735660.375448715, 7: 4367830.1877243575, 8: 2183915.0938621787, 9: 1091957.5469310894, 10: 545978.7734655447, 11: 272989.38673277234, 12: 136494.69336638617, 13: 68247.34668319309, 14: 34123.67334159654, 15: 17061.83667079827, 16: 8530.918335399136, 17: 4265.459167699568, 18: 2132.729583849784}
Pixel Size (m)
Die im Annex E.4 angegebenen (obwohl im XML wohl nicht anzugebenden) Pixel-Grössen in Metern ergeben sich, wenn man aus obiger Formel den mysteriösen 0.28 mm/px-Faktor weglässt:
pixelSize = 6378137 × Tau / (256 × (2^Z))
Berechnung für Zoomlevels 0–18 in Python 3.6:
from math import tau equator_length = 6378137 * tau {i : equator_length / (256 * 2**i) for i in range(19)}
{0: 156543.03392804097, 1: 78271.51696402048, 2: 39135.75848201024, 3: 19567.87924100512, 4: 9783.93962050256, 5: 4891.96981025128, 6: 2445.98490512564, 7: 1222.99245256282, 8: 611.49622628141, 9: 305.748113140705, 10: 152.8740565703525, 11: 76.43702828517625, 12: 38.21851414258813, 13: 19.109257071294063, 14: 9.554628535647032, 15: 4.777314267823516, 16: 2.388657133911758, 17: 1.194328566955879, 18: 0.5971642834779395}