|
| 1 | +<!doctype html> |
| 2 | +<html lang="en"> |
| 3 | + <head> |
| 4 | + <meta charset="utf-8"> |
| 5 | + <meta name="viewport" content="width=device-width,initial-scale=1"> |
| 6 | + <title>custom-projection.html</title> |
| 7 | + <script type="module" src="../dist/mapml-viewer.js"></script> |
| 8 | + <!-- |
| 9 | + To define a custom projection, the user needs to supply a projection definition |
| 10 | + in a json template literal, per the customProjectionDefinition variable below. |
| 11 | + |
| 12 | + It is anticipated that the format of the custom projection definition, |
| 13 | + will be something based on a future json-based schema that is agreed to |
| 14 | + as a web standard itself. There is an initiative underway to develop |
| 15 | + such a format in the OGC CRS standards working group (R. Lott, pers. comm. |
| 16 | + Jan 2021). |
| 17 | + |
| 18 | + The custiom projection definition is then passed to the browser |
| 19 | + "GeoReferencing API", which in the code below is 'polyfilled' by the |
| 20 | + mapml-viewer.defineCustomProjection method. In the native version of this |
| 21 | + API, we envisage an actual global window object member method, probably |
| 22 | + not a method on the actual element (map or whatever, [which implies that |
| 23 | + the result is scoped to the element instance, which is not the intention |
| 24 | + here]). The reason we've implemented defineCustomProjection on the |
| 25 | + mapml-viewer polyfill element is so that it has access to the module-level |
| 26 | + "M" variable which is available across all instances of the element, |
| 27 | + i.e. global to the module code at least. |
| 28 | + |
| 29 | + In the native implementation, we imagine that window.defineCustomProjection |
| 30 | + will define the projection globally, so that map elements,(in this case |
| 31 | + represented by the polyfill mapml-viewer, but natively tbd) will be able |
| 32 | + to use the projection attribute with the custom projection definition |
| 33 | + "projection" member value (which will be returned by the defineCustomProjection |
| 34 | + method if successful). In the polyfill below, because of the module-scoped |
| 35 | + M variable, we were forced to not use the projection attribute, but to pass |
| 36 | + the projection value to the element via the mapml-viewer.projection property, |
| 37 | + a small inconvenience. |
| 38 | + --> |
| 39 | + <script type="module"> |
| 40 | + let customProjectionDefinition = ` |
| 41 | + { |
| 42 | + "projection": "BNG", |
| 43 | + "proj4string" : "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.999601 +x_0=400000 +y_0=-100000 +ellps=airy +towgs84=446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894 +datum=OSGB36 +units=m +no_defs", |
| 44 | + "code" : "EPSG:27700", |
| 45 | + "origin" : [-238375,1376256], |
| 46 | + "resolutions" : [896,448,224,112,56,28,14,7,3.5,1.75,0.875,0.4375,0.21875,0.109375], |
| 47 | + "bounds" : [[-238375,0],[900000,1376256]], |
| 48 | + "tilesize" : 256 |
| 49 | + }`; |
| 50 | + let map = document.querySelector("mapml-viewer"); |
| 51 | + let cProjection = map.defineCustomProjection(customProjectionDefinition); |
| 52 | + map.projection = cProjection; |
| 53 | + </script> |
| 54 | + <style> |
| 55 | + html, |
| 56 | + body { |
| 57 | + height: 100%; |
| 58 | + } |
| 59 | + * { |
| 60 | + margin: 0; |
| 61 | + padding: 0; |
| 62 | + } |
| 63 | + |
| 64 | + /* Specifying the `:defined` selector is recommended to style the map |
| 65 | + element, such that styles don't apply when fallback content is in use |
| 66 | + (e.g. when scripting is disabled or when custom/built-in elements isn't |
| 67 | + supported in the browser). */ |
| 68 | + mapml-viewer:defined { |
| 69 | + /* Responsive map. */ |
| 70 | + max-width: 100%; |
| 71 | + |
| 72 | + /* Full viewport. */ |
| 73 | + width: 100%; |
| 74 | + height: 100%; |
| 75 | + |
| 76 | + /* Remove default (native-like) border. */ |
| 77 | + /* border: none; */ |
| 78 | + } |
| 79 | + |
| 80 | + /* Pre-style to avoid FOUC of inline layer- and fallback content. */ |
| 81 | + mapml-viewer:not(:defined) > * { |
| 82 | + display: none; |
| 83 | + } |
| 84 | + /* Ensure inline layer content is hidden if custom/built-in elements isn't |
| 85 | + supported, or if javascript is disabled. This needs to be defined separately |
| 86 | + from the above, because the `:not(:defined)` selector invalidates the entire |
| 87 | + declaration in browsers that do not support it. */ |
| 88 | + layer- { |
| 89 | + display: none; |
| 90 | + } |
| 91 | + </style> |
| 92 | + <noscript> |
| 93 | + <style> |
| 94 | + /* Ensure fallback content (children of the map element) is displayed if |
| 95 | + custom/built-in elements is supported but javascript is disabled. */ |
| 96 | + mapml-viewer:not(:defined) > :not(layer-) { |
| 97 | + display: initial; |
| 98 | + } |
| 99 | + </style> |
| 100 | + </noscript> |
| 101 | + </head> |
| 102 | + <body> |
| 103 | + <!-- when using --> |
| 104 | + <mapml-viewer zoom="4" lat="51.507222" lon="-0.1275" controls> |
| 105 | + <layer- label="OS Roads tile map in BNG custom projection" checked> |
| 106 | + <meta name="projection" content="BNG"> |
| 107 | + <extent units="BNG"> |
| 108 | + <input name="z" type="zoom" min="0" max="9"/> |
| 109 | + <input name="y" type="location" units="tilematrix" axis="row" /> |
| 110 | + <input name="x" type="location" units="tilematrix" axis="column"/> |
| 111 | + <link rel="tile" tref="https://api.os.uk/maps/raster/v1/wmts?key=TtPU7xWvj7AmV6uePZRYWFXuKVHzRTq7&tileMatrixSet=EPSG:27700&version=1.0.0&style=default&layer=Road_27700&service=WMTS&request=GetTile&tileCol={x}&tileRow={y}&tileMatrix={z}"> |
| 112 | + </extent> |
| 113 | + </layer-> |
| 114 | + <!-- if these layers work, they are located near Glasgow, and demonstrate |
| 115 | + the intention that a custom projection should be unremarkable and work |
| 116 | + like its standard-defined counterparts. --> |
| 117 | + <layer- label="BNG Geology WMS as TILES on top of OS Roads map"> |
| 118 | + <meta name="projection" content="BNG"> |
| 119 | + <extent units="BNG"> |
| 120 | + <input name="z" type="zoom" min="0" max="9"/> |
| 121 | + <input name="y" type="location" units="tilematrix" axis="row" /> |
| 122 | + <input name="x" type="location" units="tilematrix" axis="column"/> |
| 123 | + <link rel="tile" tref="https://api.os.uk/maps/raster/v1/wmts?key=TtPU7xWvj7AmV6uePZRYWFXuKVHzRTq7&tileMatrixSet=EPSG:27700&version=1.0.0&style=default&layer=Road_27700&service=WMTS&request=GetTile&tileCol={x}&tileRow={y}&tileMatrix={z}"> |
| 124 | + <input name="xmin" type="location" units="tilematrix" position="top-left" axis="easting" min="240755" max="261199" /> |
| 125 | + <input name="ymin" type="location" units="tilematrix" position="bottom-left" axis="northing" min="628735" max="658452" /> |
| 126 | + <input name="xmax" type="location" units="tilematrix" position="top-right" axis="easting" min="240755" max="261199" /> |
| 127 | + <input name="ymax" type="location" units="tilematrix" position="top-left" axis="northing" min="628735" max="658452" /> |
| 128 | + <input name="ixmin" type="location" units="pcrs" position="top-left" axis="easting" min="240755" max="261199" /> |
| 129 | + <input name="iymin" type="location" units="pcrs" position="bottom-left" axis="northing" min="628735" max="658452" /> |
| 130 | + <input name="ixmax" type="location" units="pcrs" position="top-right" axis="easting" min="240755" max="261199" /> |
| 131 | + <input name="iymax" type="location" units="pcrs" position="top-left" axis="northing" min="628735" max="658452" /> |
| 132 | + <link rel="tile" tref="https://map.bgs.ac.uk/arcgis/services/BGS_Detailed_Geology/MapServer/WMSServer?version=1.3.0&request=GetMap&layers=BGS.50k.Superficial.deposits&STYLES=default&format=image/png&crs=epsg:27700&BBOX={xmin},{ymin},{xmax},{ymax}&WIDTH=256&HEIGHT=256&z={z}"> |
| 133 | +<!-- <link rel="tile" tref="http://ogc.bgs.ac.uk/cgi-bin/BGS_1GE_Geology/wms?version=1.3.0&request=GetMap&layers=GBR_Kilmarnock_BGS_50k_ShrinkSwell&format=image/png&crs=epsg:27700&BBOX={xmin},{ymin},{xmax},{ymax}&WIDTH=256&HEIGHT=256&z={z}">--> |
| 134 | + <input name="i" type="location" units="map" axis="i"> |
| 135 | + <input name="j" type="location" units="map" axis="j"> |
| 136 | + <input name="wd" type="width"/> |
| 137 | + <input name="hg" type="height"/> |
| 138 | + <link rel="query" tref="https://map.bgs.ac.uk/arcgis/services/BGS_Detailed_Geology/MapServer/WMSServer?version=1.3.0&request=GetFeatureInfo&i={i}&j={j}&radius=0&query_layers=BGS.50k.Superficial.deposits&info_format=text/html&layers=BGS.50k.Superficial.deposits&STYLES=default&format=image/png&crs=epsg:27700&BBOX={ixmin},{iymin},{ixmax},{iymax}&WIDTH={wd}&HEIGHT={hg}&z={z}"> |
| 139 | + |
| 140 | + </extent> |
| 141 | + |
| 142 | + </layer-> |
| 143 | + <layer- label="BNG WMS" > |
| 144 | + <meta name="projection" content="BNG"> |
| 145 | + <meta name="extent" content="xmin=54224.000100,ymin=5192.999900,xmax=655627.000000,ymax=1220319.000000"> |
| 146 | + <extent units="BNG"> |
| 147 | + <input name="xmin" type="location" rel="map" position="top-left" axis="easting" units="pcrs" min="240755" max="261199" /> |
| 148 | + <input name="ymin" type="location" rel="map" position="bottom-left" axis="northing" units="pcrs" min="628735" max="658452" /> |
| 149 | + <input name="xmax" type="location" rel="map" position="top-right" axis="easting" units="pcrs" min="240755" max="261199" /> |
| 150 | + <input name="ymax" type="location" rel="map" position="top-left" axis="northing" units="pcrs" min="628735" max="658452" /> |
| 151 | + <input name="w" type="width" min="1" max="10000" /> |
| 152 | + <input name="h" type="height" min="1" max="10000" /> |
| 153 | + <link rel="image" tref="http://ogc.bgs.ac.uk/cgi-bin/BGS_1GE_Geology/wms?version=1.3.0&request=GetMap&layers=GBR_Kilmarnock_BGS_50k_ShrinkSwell&format=image/png&crs=epsg:27700&BBOX={xmin},{ymin},{xmax},{ymax}&WIDTH={w}&HEIGHT={h}"> |
| 154 | + </extent> |
| 155 | + </layer-> |
| 156 | + </mapml-viewer> |
| 157 | + </body> |
| 158 | +</html> |
0 commit comments