├── .github ├── remark.yaml └── workflows │ ├── publish.yaml │ └── test.yaml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── examples ├── collection.json └── item.json ├── json-schema └── schema.json ├── package.json └── wms.md /.github/remark.yaml: -------------------------------------------------------------------------------- 1 | plugins: 2 | # Check links 3 | - validate-links 4 | # Apply some recommended defaults for consistency 5 | - remark-preset-lint-consistent 6 | - remark-preset-lint-recommended 7 | - lint-no-html 8 | # General formatting 9 | - - remark-lint-emphasis-marker 10 | - '*' 11 | - remark-lint-hard-break-spaces 12 | - remark-lint-blockquote-indentation 13 | - remark-lint-no-consecutive-blank-lines 14 | - - remark-lint-maximum-line-length 15 | - 150 16 | # Code 17 | - remark-lint-fenced-code-flag 18 | - remark-lint-fenced-code-marker 19 | - remark-lint-no-shell-dollars 20 | - - remark-lint-code-block-style 21 | - 'fenced' 22 | # Headings 23 | - remark-lint-heading-increment 24 | - remark-lint-no-multiple-toplevel-headings 25 | - remark-lint-no-heading-punctuation 26 | - - remark-lint-maximum-heading-length 27 | - 70 28 | - - remark-lint-heading-style 29 | - atx 30 | - - remark-lint-no-shortcut-reference-link 31 | - false 32 | # Lists 33 | - remark-lint-list-item-bullet-indent 34 | - remark-lint-ordered-list-marker-style 35 | - remark-lint-ordered-list-marker-value 36 | - remark-lint-checkbox-character-style 37 | - - remark-lint-unordered-list-marker-style 38 | - '-' 39 | - - remark-lint-list-item-indent 40 | - space 41 | # Tables 42 | - remark-lint-table-pipes 43 | - remark-lint-no-literal-urls 44 | -------------------------------------------------------------------------------- /.github/workflows/publish.yaml: -------------------------------------------------------------------------------- 1 | name: Publish JSON Schema 2 | on: 3 | release: 4 | types: [published] 5 | jobs: 6 | deploy: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Inject env variables 10 | uses: rlespinasse/github-slug-action@v3.x 11 | - uses: actions/checkout@v2 12 | - name: deploy JSON Schema for version ${{ env.GITHUB_REF_SLUG }} 13 | uses: peaceiris/actions-gh-pages@v3 14 | with: 15 | github_token: ${{ secrets.GITHUB_TOKEN }} 16 | publish_dir: json-schema 17 | destination_dir: ${{ env.GITHUB_REF_SLUG }} 18 | -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: Check Markdown and Examples 2 | on: [push, pull_request] 3 | jobs: 4 | deploy: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/setup-node@v2 8 | with: 9 | node-version: 'lts/*' 10 | - uses: actions/checkout@v2 11 | - run: | 12 | npm install 13 | npm test 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS files 2 | .DS_Store 3 | Thumbs.db 4 | 5 | # Editors 6 | /.idea/ 7 | /.vscode/ 8 | 9 | # Node / npm 10 | .npm 11 | /node_modules/ 12 | /package-lock.json 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | 9 | ### Added 10 | 11 | - PMTiles 12 | - New property `wms:transparent` for WMS 13 | 14 | ### Changed 15 | 16 | - The `type` for WMS and WMTS links should be set to the image media type that the client should request for tiles. 17 | - WMS supports only v1.3.0 of the specification 18 | 19 | ### Deprecated 20 | 21 | ### Removed 22 | 23 | ### Fixed 24 | 25 | - WMS: Clarified the behavior of `wms:layers` and `wms:styles` 26 | 27 | ## [1.2.0] 28 | 29 | ### Added 30 | 31 | - PMTiles 32 | 33 | ## [1.1.0] 34 | 35 | ### Added 36 | 37 | - OGC WMS (Basic WMS only) 38 | - 3D Tiles 39 | 40 | ### Changed 41 | 42 | - The JSON schema for `wmts:layer` is less ambiguous and a bit more strict 43 | 44 | ## [1.0.0] 45 | 46 | - Initial release for TileJSON, WMTS and XYZ. 47 | 48 | [Unreleased]: 49 | [1.2.0]: 50 | [1.1.0]: 51 | [1.0.0]: 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Web Map Links Extension Specification 2 | 3 | - **Title:** Web Map Links 4 | - **Identifier:** 5 | - **Field Name Prefix:** none, but each relation type has potentially a distinct prefix for additional data (e.g. `wmts` and `xyz`) 6 | - **Scope:** Item, Catalog, Collection 7 | - **Extension [Maturity Classification](https://github.com/radiantearth/stac-spec/tree/master/extensions/README.md#extension-maturity):** Proposal 8 | - **Owner**: @m-mohr 9 | 10 | This document explains the Web Map Links Extension to the 11 | [SpatioTemporal Asset Catalog](https://github.com/radiantearth/stac-spec) (STAC) specification. 12 | It allows to provide links to web map services for visualization purposes. 13 | 14 | The following services are supported: 15 | - [3D Tiles](#3d-tiles) 16 | - [OGC WMS](#ogc-wms) 17 | - [OGC WMTS](#ogc-wmts) 18 | - [PMTiles](#pmtiles) 19 | - [TileJSON](#tilejson) 20 | - [XYZ](#xyz) 21 | 22 | Important resources in this extension: 23 | - Examples: 24 | - [Item example](examples/item.json): Shows the basic usage of the extension in a STAC Item 25 | - [Collection example](examples/collection.json): Shows the basic usage of the extension in a STAC Collection 26 | - [JSON Schema](json-schema/schema.json) 27 | - [Changelog](./CHANGELOG.md) 28 | 29 | ## Link Object Fields 30 | 31 | This extension only extends the [Link Object](https://github.com/radiantearth/stac-spec/tree/master/item-spec/item-spec.md#link-object) 32 | used in all STAC entities (Catalogs, Collections, Items). It requires specific relation types to be set for the `rel` field in the 33 | Link Object. 34 | 35 | An attribution field is not defined as part of this extension, but it is RECOMMENDED to provide an attribution 36 | in via the `attribution` field as defined the [Attribtion Extension](https://github.com/stac-extensions/attribution). 37 | 38 | ### 3D Tiles 39 | 40 | Links to a [3D Tiles](https://docs.ogc.org/cs/18-053r2/18-053r2.html) implementation (versions 1.x). 41 | 42 | | Field Name | Type | Description | 43 | | --------------- | -------------------- | ----------- | 44 | | rel | string | **REQUIRED**. Must be set to `3d-tiles`. | 45 | | href | string | **REQUIRED**. Link to a tileset. | 46 | | type | string | Recommended to be set to `application/json`. | 47 | 48 | ### OGC WMS 49 | 50 | Links to a [OGC Web Map Service](https://www.ogc.org/standards/wms) (WMS) implementation (versions 1.3.0). 51 | Only (tiled) "Basic WMS" is supported at this time. 52 | 53 | | Field Name | Type | Description | 54 | | --------------- | -------------------- | ----------- | 55 | | rel | string | **REQUIRED**. Must be set to `wms`. | 56 | | href | string | **REQUIRED**. Link to the WMS, without any WMS specific query parameters. | 57 | | type | string | The media type to be used for the tile requests, e.g. `image/png` or `image/jpeg`. | 58 | | wms:layers | \[string] | **REQUIRED**. The layers to show on the map by default. Can't be empty. | 59 | | wms:styles | \[string] | The styles to show on the map by default. If not provided or empty, an empty string will be used for the query parameter. | 60 | | wms:dimensions | Map\ | Any additional dimension parameters to add to the request as query parameters (e.g. the dimensions `TIME` or `ELEVATION`). | 61 | | wms:transparent | boolean | Sets whether the layers should be rendered transparent or not. Default: `false` | 62 | 63 | If you provide multiple array elements in `wms:layers` (e.g. `["layerA", "layerB"]`), 64 | each should occur in a separate layer in the mapping library so that requests for the layers are sent. 65 | If you want to send multiple layers in a single request, provide them as a string with comma-separated values: `["layerA,layerB"]`. 66 | `wms:layers` and `wms:styles` work in parallel, so the first style in the array will be used for the first layer, etc. 67 | 68 | - [More details on the mapping between WMS query parameters and the STAC fields](./wms.md) 69 | 70 | ### OGC WMTS 71 | 72 | Links to a [OGC Web Map Tile Service](https://www.ogc.org/standards/wmts) (WMTS) implementation (versions 1.x). 73 | 74 | | Field Name | Type | Description | 75 | | --------------- | -------------------- | ----------- | 76 | | rel | string | **REQUIRED**. Must be set to `wmts`. | 77 | | href | string | **REQUIRED**. Link to the WMTS, without any WMTS specific query parameters. | 78 | | type | string | The media type to be used for the tile requests, e.g. `image/png` or `image/jpeg`. | 79 | | href:servers | \[string] | See [href:servers](#hrefservers) below for details. | 80 | | wmts:layer | string\|\[string] | **REQUIRED**. The layers to show on the map by default, either a list of layer names or a single layer name. | 81 | | wmts:dimensions | Map\ | Any additional dimension parameters to add to the request as key-value-pairs, usually added as query parameters. | 82 | 83 | If you provide multiple array elements in `wmts:layer` (e.g. `["layerA", "layerB"]`), 84 | each should occur in a separate layer in the mapping library so that individual requests for the layers are sent. 85 | 86 | #### href 87 | 88 | For WMTS, the `href` is pointing to the URL of the Capabilities document, but without the query parameters for the Capabilities request. 89 | So if your Capabilities can be requested from `https://example.com/geoserver/service/wmts?service=wmts&request=GetCapabilities` 90 | you'd provide `https://example.com/geoserver/service/wmts` as `href`. 91 | 92 | The `href` can contain an optional server placeholder `{s}`. If `{s}` is used, the field [`href:servers`](#hrefservers) MUST be provided. 93 | 94 | ### PMTiles 95 | 96 | Links to a [PMTiles](https://github.com/protomaps/PMTiles/blob/main/spec/v3/spec.md) file (versions 3.x). 97 | 98 | | Field Name | Type | Description | 99 | | --------------- | -------------------- | ----------- | 100 | | rel | string | **REQUIRED**. Must be set to `pmtiles`. | 101 | | href | string | **REQUIRED**. Link to a PMTiles file (usually ends with `.pmtiles`). | 102 | | type | string | Recommended to be set to `application/vnd.pmtiles`. | 103 | | pmtiles:layers | \[string] | For vector tiles, the layers to show on the map by default. If not provided, it's up to the discretion of the implementation to choose a layer from the `vector_layers` in the PMTiles metadata. | 104 | 105 | The [Tile Type](https://github.com/protomaps/PMTiles/blob/main/spec/v3/spec.md#tile-type-tt) of the 106 | PMTiles data source can be read from the first 127 bytes of the the binary header. 107 | 108 | It is typical to assume a tile size of 256x256 display (CSS) pixels for raster tiles and 512x512 display pixels for vector tiles. 109 | Tile sizes are not guaranteed to be uniform across an entire archive. 110 | 111 | ### XYZ 112 | 113 | Links to a XYZ, also known as slippy map. 114 | 115 | | Field Name | Type | Description | 116 | | ------------ | --------- | ----------- | 117 | | rel | string | **REQUIRED**. Must be set to `xyz`. | 118 | | href | string | **REQUIRED**. Link to the XYZ as a templated URI. | 119 | | type | string | Recommended to be set to the image file type the XYZ returns by default, usually `image/png` or `image/jpeg`. | 120 | | href:servers | \[string] | See [href:servers](#hrefservers) below for details. | 121 | 122 | #### href 123 | 124 | For XYZ, the `href` is a templated URI. 125 | It MUST include the following placeholders: `{x}`, `{y}` and `{z}` and MAY include a placeholder for the server: `{s}`. 126 | If `{s}` is used, the field [`href:servers`](#hrefservers) MUST be provided. 127 | All other parameters should be [hard-coded](https://github.com/stac-extensions/web-map-links/issues/2) with specific values, 128 | e.g. the `{r}` parameter in Leaflet could be replaced by `2x`. 129 | 130 | ### TileJSON 131 | 132 | Links to a [TileJSON](https://github.com/mapbox/tilejson-spec) document. 133 | 134 | | Field Name | Type | Description | 135 | | ---------- | ------ | ----------- | 136 | | rel | string | **REQUIRED**. Must be set to `tilejson`. | 137 | | href | string | **REQUIRED**. Link to the valid TileJSON document. | 138 | | type | string | Recommended to be set to `application/json`. | 139 | 140 | ### General 141 | 142 | The following field applies to multiple types of web mapping services: 143 | 144 | | Field Name | Type | Description | 145 | | ------------ | --------- | ----------- | 146 | | href:servers | \[string] | A list of replacement values for `{s}` in `href`s. | 147 | 148 | #### href:servers 149 | 150 | This field is used to specify a set of URLs for a web mapping library so that requests can be sent to multiple servers, 151 | which can avoid request limits in web browsers. 152 | 153 | The field is used across multiple types of web mapping services and applies currently to XYZ and WMTS. 154 | 155 | It is **REQUIRED** if `{s}` is used in the `href` and then a list of at least 2 allowed values for the placeholder `{s}` must be provided. 156 | If you only have a single value don't provide `href:servers` and instead hard-code the value into the href. 157 | 158 | The implementations can expand the given values into multiple URLs. 159 | For example, if you provide `https://{s}/example` as `href` and `href:servers` is `["a.com", "b.eu"]` 160 | you can expand that to `["https://a.com/example", "https://b.eu/example"]`. 161 | 162 | ## Contributing 163 | 164 | All contributions are subject to the 165 | [STAC Specification Code of Conduct](https://github.com/radiantearth/stac-spec/blob/master/CODE_OF_CONDUCT.md). 166 | For contributions, please follow the 167 | [STAC specification contributing guide](https://github.com/radiantearth/stac-spec/blob/master/CONTRIBUTING.md) Instructions 168 | for running tests are copied here for convenience. 169 | 170 | ### Running tests 171 | 172 | The same checks that run as checks on PR's are part of the repository and can be run locally to verify that changes are valid. 173 | To run tests locally, you'll need `npm`, which is a standard part of any [node.js installation](https://nodejs.org/en/download/). 174 | 175 | First you'll need to install everything with npm once. Just navigate to the root of this repository and on 176 | your command line run: 177 | ```bash 178 | npm install 179 | ``` 180 | 181 | Then to check markdown formatting and test the examples against the JSON schema, you can run: 182 | ```bash 183 | npm test 184 | ``` 185 | 186 | This will spit out the same texts that you see online, and you can then go and fix your markdown or examples. 187 | 188 | If the tests reveal formatting problems with the examples, you can fix them with: 189 | ```bash 190 | npm run format-examples 191 | ``` 192 | -------------------------------------------------------------------------------- /examples/collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "stac_version": "1.0.0", 3 | "stac_extensions": [ 4 | "https://stac-extensions.github.io/web-map-links/v1.2.0/schema.json" 5 | ], 6 | "type": "Collection", 7 | "id": "collection", 8 | "title": "A title", 9 | "description": "A description", 10 | "license": "Apache-2.0", 11 | "extent": { 12 | "spatial": { 13 | "bbox": [ 14 | [ 15 | 172.9, 16 | 1.3, 17 | 173, 18 | 1.4 19 | ] 20 | ] 21 | }, 22 | "temporal": { 23 | "interval": [ 24 | [ 25 | "2015-06-23T00:00:00Z", 26 | null 27 | ] 28 | ] 29 | } 30 | }, 31 | "attribution": "© 2022 The Example Corp.", 32 | "links": [ 33 | { 34 | "href": "https://example.com/examples/collection.json", 35 | "rel": "self" 36 | }, 37 | { 38 | "href": "https://example.com/examples/item.json", 39 | "rel": "item" 40 | }, 41 | { 42 | "href": "https://maps.example.com/wmts", 43 | "rel": "wmts", 44 | "type": "image/png", 45 | "title": "RGB composite visualized through a WMTS", 46 | "wmts:layer": "rgb", 47 | "wmts:dimensions": { 48 | "time": "2022-01-01" 49 | } 50 | }, 51 | { 52 | "href": "https://maps.example.com/wms", 53 | "rel": "wms", 54 | "type": "image/png", 55 | "title": "RGB composite visualized through a WMS", 56 | "wms:layers": [ 57 | "rgb" 58 | ], 59 | "wms:styles": [ 60 | "default" 61 | ], 62 | "wms:dimensions": { 63 | "ELEVATION": "0", 64 | "TIME": "2022-01-01" 65 | } 66 | }, 67 | { 68 | "href": "https://{s}.maps.example.com/xyz/{z}/{x}/{y}.png", 69 | "rel": "xyz", 70 | "type": "image/png", 71 | "title": "RGB composite visualized through a XYZ", 72 | "href:servers": [ 73 | "a", 74 | "b", 75 | "c" 76 | ] 77 | }, 78 | { 79 | "href": "https://maps.example.com/collection/tilejson.json", 80 | "rel": "tilejson", 81 | "title": "TileJSON", 82 | "type": "application/json" 83 | }, 84 | { 85 | "href": "https://storage.googleapis.com/open-cogs/planet-stac/cocabamba-peru/3d-geofox.ai/3DTiles/tileset.json", 86 | "rel": "3d-tiles", 87 | "title": "3D Tiles", 88 | "type": "application/json" 89 | }, 90 | { 91 | "href": "https://maps.example.com/item/example.pmtiles", 92 | "rel": "pmtiles", 93 | "title": "PMTiles", 94 | "type": "application/vnd.pmtiles", 95 | "pmtiles:layers": [ 96 | "streets" 97 | ] 98 | } 99 | ] 100 | } -------------------------------------------------------------------------------- /examples/item.json: -------------------------------------------------------------------------------- 1 | { 2 | "stac_version": "1.0.0", 3 | "stac_extensions": [ 4 | "https://stac-extensions.github.io/web-map-links/v1.2.0/schema.json" 5 | ], 6 | "type": "Feature", 7 | "id": "item", 8 | "bbox": [ 9 | 172.9, 10 | 1.3, 11 | 173, 12 | 1.4 13 | ], 14 | "geometry": { 15 | "type": "Polygon", 16 | "coordinates": [ 17 | [ 18 | [ 19 | 172.9, 20 | 1.3 21 | ], 22 | [ 23 | 173, 24 | 1.3 25 | ], 26 | [ 27 | 173, 28 | 1.4 29 | ], 30 | [ 31 | 172.9, 32 | 1.4 33 | ], 34 | [ 35 | 172.9, 36 | 1.3 37 | ] 38 | ] 39 | ] 40 | }, 41 | "properties": { 42 | "datetime": "2020-12-11T22:38:32Z" 43 | }, 44 | "attribution": "© 2022 The Example Corp.", 45 | "links": [ 46 | { 47 | "href": "https://example.com/examples/item.json", 48 | "rel": "self" 49 | }, 50 | { 51 | "href": "https://maps.example.com/wmts", 52 | "rel": "wmts", 53 | "type": "image/png", 54 | "title": "RGB composite visualized through a WMTS", 55 | "wmts:layer": [ 56 | "streets", 57 | "satellite" 58 | ] 59 | }, 60 | { 61 | "href": "https://maps.example.com/wms", 62 | "rel": "wms", 63 | "type": "image/png", 64 | "title": "RGB composite visualized through a WMS", 65 | "wms:layers": [ 66 | "rgb" 67 | ], 68 | "wms:transparent": true 69 | }, 70 | { 71 | "href": "https://maps.example.com/xyz/{z}/{x}/{y}.jpg", 72 | "rel": "xyz", 73 | "type": "image/jpeg", 74 | "title": "RGB composite visualized through a XYZ" 75 | }, 76 | { 77 | "href": "https://maps.example.com/item/tilejson.json", 78 | "rel": "tilejson", 79 | "title": "TileJSON", 80 | "type": "application/json" 81 | }, 82 | { 83 | "href": "https://storage.googleapis.com/open-cogs/planet-stac/cocabamba-peru/3d-geofox.ai/3DTiles/tileset.json", 84 | "rel": "3d-tiles", 85 | "title": "3D Tiles", 86 | "type": "application/json" 87 | }, 88 | { 89 | "href": "https://maps.example.com/item/example.pmtiles", 90 | "rel": "pmtiles", 91 | "title": "PMTiles", 92 | "type": "application/vnd.pmtiles", 93 | "pmtiles:layers": [ 94 | "streets" 95 | ] 96 | } 97 | ], 98 | "assets": {} 99 | } -------------------------------------------------------------------------------- /json-schema/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://stac-extensions.github.io/web-map-links/v1.2.0/schema.json#", 4 | "title": "Web Map Links Extension", 5 | "description": "STAC Web Map Links Extension for STAC Items, STAC Catalogs and STAC Collections.", 6 | "type": "object", 7 | "required": [ 8 | "stac_extensions", 9 | "type", 10 | "links" 11 | ], 12 | "properties": { 13 | "stac_extensions": { 14 | "type": "array", 15 | "contains": { 16 | "const": "https://stac-extensions.github.io/web-map-links/v1.2.0/schema.json" 17 | } 18 | }, 19 | "type": { 20 | "type": "string", 21 | "enum": [ 22 | "Catalog", 23 | "Collection", 24 | "Feature" 25 | ] 26 | }, 27 | "links": { 28 | "type": "array", 29 | "contains": { 30 | "type": "object", 31 | "required": [ 32 | "rel" 33 | ], 34 | "properties": { 35 | "rel": { 36 | "enum": [ 37 | "xyz", 38 | "wms", 39 | "wmts", 40 | "tilejson", 41 | "pmtiles", 42 | "3d-tiles" 43 | ] 44 | } 45 | } 46 | }, 47 | "items": { 48 | "type": "object", 49 | "allOf": [ 50 | { 51 | "$comment": "Defines XYZ links", 52 | "if": { 53 | "properties": { 54 | "rel": { 55 | "const": "xyz" 56 | } 57 | } 58 | }, 59 | "then": { 60 | "$ref": "#/definitions/servers" 61 | } 62 | }, 63 | { 64 | "$comment": "Defines WMTS links", 65 | "if": { 66 | "properties": { 67 | "rel": { 68 | "const": "wmts" 69 | } 70 | } 71 | }, 72 | "then": { 73 | "required": [ 74 | "wmts:layer" 75 | ], 76 | "properties": { 77 | "wmts:layer": { 78 | "oneOf": [ 79 | { 80 | "type": "string", 81 | "minLength": 1 82 | }, 83 | { 84 | "type": "array", 85 | "minItems": 1, 86 | "items": { 87 | "type": "string", 88 | "minLength": 1 89 | } 90 | } 91 | ] 92 | }, 93 | "wmts:dimensions": { 94 | "type": "object", 95 | "additionalProperties": { 96 | "type": "string" 97 | } 98 | } 99 | }, 100 | "allOf": [ 101 | { 102 | "$ref": "#/definitions/servers" 103 | } 104 | ] 105 | } 106 | }, 107 | { 108 | "$comment": "Defines WMS links", 109 | "if": { 110 | "properties": { 111 | "rel": { 112 | "const": "wms" 113 | } 114 | } 115 | }, 116 | "then": { 117 | "required": [ 118 | "wms:layers" 119 | ], 120 | "properties": { 121 | "wms:layers": { 122 | "type": "array", 123 | "minItems": 1, 124 | "items": { 125 | "type": "string", 126 | "minLength": 1 127 | } 128 | }, 129 | "wms:styles": { 130 | "type": "array", 131 | "items": { 132 | "type": "string", 133 | "minLength": 1 134 | } 135 | }, 136 | "wms:dimensions": { 137 | "type": "object", 138 | "additionalProperties": { 139 | "type": "string" 140 | } 141 | }, 142 | "wms:transparent": { 143 | "type": "boolean" 144 | } 145 | } 146 | } 147 | }, 148 | { 149 | "$comment": "Defines PMTiles links", 150 | "if": { 151 | "properties": { 152 | "rel": { 153 | "const": "pmtiles" 154 | } 155 | } 156 | }, 157 | "then": { 158 | "properties": { 159 | "pmtiles:layers": { 160 | "type": "array", 161 | "items": { 162 | "type": "string", 163 | "minLength": 1 164 | } 165 | } 166 | } 167 | } 168 | } 169 | ] 170 | } 171 | } 172 | }, 173 | "definitions": { 174 | "servers": { 175 | "if": { 176 | "required": [ 177 | "href" 178 | ], 179 | "properties": { 180 | "href": { 181 | "pattern": "\\{s\\}" 182 | } 183 | } 184 | }, 185 | "then": { 186 | "required": [ 187 | "href:servers" 188 | ], 189 | "properties": { 190 | "href:servers": { 191 | "type": "array", 192 | "minItems": 2, 193 | "items": { 194 | "type": "string" 195 | } 196 | } 197 | } 198 | }, 199 | "else": { 200 | "properties": { 201 | "href:servers": { 202 | "not": {} 203 | } 204 | } 205 | } 206 | } 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stac-extensions", 3 | "version": "1.2.0", 4 | "scripts": { 5 | "test": "npm run check-markdown && npm run check-examples", 6 | "check-markdown": "remark . -f -r .github/remark.yaml", 7 | "check-examples": "stac-node-validator . --lint --verbose --schemaMap https://stac-extensions.github.io/web-map-links/v1.2.0/schema.json=./json-schema/schema.json", 8 | "format-examples": "stac-node-validator . --format --schemaMap https://stac-extensions.github.io/web-map-links/v1.2.0/schema.json=./json-schema/schema.json" 9 | }, 10 | "dependencies": { 11 | "remark-cli": "^8.0.0", 12 | "remark-lint": "^7.0.0", 13 | "remark-lint-no-html": "^2.0.0", 14 | "remark-preset-lint-consistent": "^3.0.0", 15 | "remark-preset-lint-markdown-style-guide": "^3.0.0", 16 | "remark-preset-lint-recommended": "^4.0.0", 17 | "remark-validate-links": "^10.0.0", 18 | "stac-node-validator": "^1.0.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /wms.md: -------------------------------------------------------------------------------- 1 | # OGC WMS 2 | 3 | ## Mapping between STAC and the WMS GetMap parameters 4 | 5 | | Request Parameter | Mandatory | Description | Mapping / Implementation guide | 6 | | --------------------------- | --------- | ------------------------------------------------------------ | ------------------------------------------------------------ | 7 | | VERSION=1.3.0 | Yes | Request version. | Always `1.3.0` - We assume everyone supports 1.3.0 today. | 8 | | REQUEST=GetMap | Yes | Request name. | Always `GetMap`. | 9 | | LAYERS=layer_list | Yes | Comma-separated list of one or more map layers. | via `wms:layers`, one layer in the mapping library per array element | 10 | | STYLES=style_list | Yes | Comma-separated list of one rendering style per requested layer. | via `wms:styles`, 1:1 mapping to `wms:layers` | 11 | | CRS=namespace:identifier | Yes | Coordinate reference system. | determined by mapping library, usually EPSG:3857 | 12 | | BBOX=minx,miny,maxx,maxy | Yes | Bounding box corners (lower left, upper right) in CRS units. | determined by mapping library | 13 | | WIDTH=output_width | Yes | Width in pixels of map picture. | determined by mapping library | 14 | | HEIGHT=output_height | Yes | Height in pixels of map picture. | determined by mapping library | 15 | | FORMAT=output_format | Yes | Output format of map. | via `type` | 16 | | TRANSPARENT=TRUE\|FALSE | No | Background transparency of map (default=FALSE). | via `wms:transparent` | 17 | | BGCOLOR=color_value | No | Hexadecimal red-green-blue colour value for the background color (default=0xFFFFFF). | not supported, some libraries may support setting it via `wms:dimensions` | 18 | | EXCEPTIONS=exception_format | No | The format in which exceptions are to be reported by the WMS (default=XML). | determined by mapping library | 19 | | TIME=time | No | Time value of layer desired. | via `wms:dimensions` | 20 | | ELEVATION=elevation | No | Elevation of layer desired. | via `wms:dimensions` | 21 | | Other sample dimension(s) | No | Value of other dimensions as appropriate. | via `wms:dimensions` | 22 | 23 | Columns 1-3 are coming from the [OGC WMS specification, version 1.3.0](https://portal.ogc.org/files/?artifact_id=14416), chapter 7.3.2. 24 | --------------------------------------------------------------------------------