ogcopenapis 0.0.12 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/LICENSE +20 -20
  3. package/README.md +305 -72
  4. package/lib/OgcOpenApiCrsTools.d.ts +10 -9
  5. package/lib/OgcOpenApiCrsTools.d.ts.map +1 -0
  6. package/lib/OgcOpenApiCrsTools.js +40 -39
  7. package/lib/OgcOpenApiCrsTools.js.map +1 -0
  8. package/lib/OgcOpenApiFeatureStore.d.ts +94 -93
  9. package/lib/OgcOpenApiFeatureStore.d.ts.map +1 -0
  10. package/lib/OgcOpenApiFeatureStore.js +200 -244
  11. package/lib/OgcOpenApiFeatureStore.js.map +1 -0
  12. package/lib/OgcOpenApiFetchTools.d.ts +37 -30
  13. package/lib/OgcOpenApiFetchTools.d.ts.map +1 -0
  14. package/lib/OgcOpenApiFetchTools.js +68 -50
  15. package/lib/OgcOpenApiFetchTools.js.map +1 -0
  16. package/lib/OgcOpenApiGetCapabilities.d.ts +209 -112
  17. package/lib/OgcOpenApiGetCapabilities.d.ts.map +1 -0
  18. package/lib/OgcOpenApiGetCapabilities.js +424 -277
  19. package/lib/OgcOpenApiGetCapabilities.js.map +1 -0
  20. package/lib/OgcOpenApiMapsModel.d.ts +41 -36
  21. package/lib/OgcOpenApiMapsModel.d.ts.map +1 -0
  22. package/lib/OgcOpenApiMapsModel.js +88 -75
  23. package/lib/OgcOpenApiMapsModel.js.map +1 -0
  24. package/lib/OgcOpenApiMvtTools.d.ts +12 -0
  25. package/lib/OgcOpenApiMvtTools.d.ts.map +1 -0
  26. package/lib/OgcOpenApiMvtTools.js +100 -0
  27. package/lib/OgcOpenApiMvtTools.js.map +1 -0
  28. package/lib/OgcOpenApiStyleTools.d.ts +51 -0
  29. package/lib/OgcOpenApiStyleTools.d.ts.map +1 -0
  30. package/lib/OgcOpenApiStyleTools.js +155 -0
  31. package/lib/OgcOpenApiStyleTools.js.map +1 -0
  32. package/lib/OgcOpenApiTileMatrixTools.d.ts +41 -0
  33. package/lib/OgcOpenApiTileMatrixTools.d.ts.map +1 -0
  34. package/lib/OgcOpenApiTileMatrixTools.js +88 -0
  35. package/lib/OgcOpenApiTileMatrixTools.js.map +1 -0
  36. package/lib/OgcOpenApiTilesModel.d.ts +56 -31
  37. package/lib/OgcOpenApiTilesModel.d.ts.map +1 -0
  38. package/lib/OgcOpenApiTilesModel.js +167 -128
  39. package/lib/OgcOpenApiTilesModel.js.map +1 -0
  40. package/lib/OgcOpenApiVectorTilesModel.d.ts +39 -0
  41. package/lib/OgcOpenApiVectorTilesModel.d.ts.map +1 -0
  42. package/lib/OgcOpenApiVectorTilesModel.js +122 -0
  43. package/lib/OgcOpenApiVectorTilesModel.js.map +1 -0
  44. package/lib/OgcOpenApiWmtsTools.d.ts +30 -0
  45. package/lib/OgcOpenApiWmtsTools.d.ts.map +1 -0
  46. package/lib/OgcOpenApiWmtsTools.js +89 -0
  47. package/lib/OgcOpenApiWmtsTools.js.map +1 -0
  48. package/package.json +57 -27
  49. package/src/OgcOpenApiCrsTools.ts +40 -0
  50. package/src/OgcOpenApiFeatureStore.ts +296 -0
  51. package/src/OgcOpenApiFetchTools.ts +84 -0
  52. package/src/OgcOpenApiGetCapabilities.ts +641 -0
  53. package/src/OgcOpenApiMapsModel.ts +128 -0
  54. package/src/OgcOpenApiMvtTools.ts +104 -0
  55. package/src/OgcOpenApiStyleTools.ts +187 -0
  56. package/src/OgcOpenApiTileMatrixTools.ts +111 -0
  57. package/src/OgcOpenApiTilesModel.ts +214 -0
  58. package/src/OgcOpenApiVectorTilesModel.ts +141 -0
  59. package/src/OgcOpenApiWmtsTools.ts +114 -0
  60. package/lib/OgcOpenApiGetCollectionTiles.d.ts +0 -7
  61. package/lib/OgcOpenApiGetCollectionTiles.js +0 -7
package/CHANGELOG.md ADDED
@@ -0,0 +1,63 @@
1
+ # Changelog
2
+
3
+ All notable changes to ogcopenapis are in this file. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ Each pull request adds its changes under Unreleased. A release renames Unreleased to its version and date.
8
+
9
+ ## [Unreleased]
10
+
11
+ ## [1.0.1] - 2026-10-27
12
+
13
+ ### Fixed
14
+ - The Features example of the README keeps the feature ids of the server, `new GeoJsonCodec({generateIDs: false})`.
15
+ `generateIDs: true` replaced them with ids of its own on every query: `get(id)` of the store then requested ids that
16
+ do not exist, and LuciadRIA re-added every feature on every query. The library is unchanged, the application passes
17
+ the codec.
18
+
19
+ ## [1.0.0] - 2026-10-27
20
+
21
+ ### Changed
22
+ - **BREAKING:** requires LuciadRIA 2026.1 or higher, as a peer dependency: the application installs its single copy,
23
+ the package never bundles it.
24
+ - **BREAKING:** the package is native ES modules (`"type": "module"`) with an `exports` map. Import components as
25
+ `ogcopenapis/OgcOpenApiFeatureStore`, the paths of 0.0.12 with `lib/` still work. TypeScript projects need
26
+ `moduleResolution` `bundler`, `node16` or `nodenext` for the paths without `lib/`.
27
+ - OgcOpenApiTilesModel uses LuciadRIA's WMTS support: create it with `createFromTileSet`, which handles tile matrix
28
+ sets that are not quad-trees and `tileMatrixSetLimits`.
29
+ - OgcOpenApiFeatureStore extends LuciadRIA's `Store`. Its requests always settle, and it supports `abortSignal`.
30
+ - `fetchTileSetsInFull` leaves out tile matrix sets whose definition cannot be read, instead of failing, and rejects
31
+ only when none can be read.
32
+ - OgcOpenApiMapsModel keeps the `f` value of the map link, such as `f=png`, and encodes its query.
33
+ - Tile matrix set definitions are requested by their link as the server gives it, with an `Accept: application/json`
34
+ header.
35
+
36
+ ### Added
37
+ - Vector tiles (Mapbox Vector Tiles): OgcOpenApiVectorTilesModel, on LuciadRIA's MapboxVectorTileSetModel. It reads
38
+ the layers from a few tiles when a tileset does not list them (`discoverLayers`).
39
+ - OGC API Styles in the Mapbox GL encoding: OgcOpenApiStyleTools, with a stylesheet or a style per tile matrix set
40
+ (`pickStylesheet`, `getStylesForTileMatrixSet`) and a generated default style (`createDefaultStyle`).
41
+ - The tilesets of a collection, only the tile matrix sets it is tiled in: `fetchCollectionTileSets`, matched to the
42
+ tile matrix sets of the server by URI (`matchTileMatrixSet`, `fetchTileMatrixSetOfTileSet`).
43
+ - The tilesets of the dataset, all collections in each tile: `hasDatasetTileSets`, `fetchDatasetTileSets`, and
44
+ `fetchCollectionTileSet` with collection `null`.
45
+ - A tile matrix set included in a tileset is used as is.
46
+ - A demo, test servers with recorded, live and browser tests, and a check of the package as published.
47
+
48
+ ### Deprecated
49
+ - The constructor `new OgcOpenApiTilesModel(options)`: it supports quad-tree tile matrix sets only.
50
+
51
+ ### Fixed
52
+ - Relative links are resolved against the URL of their document, instead of the host of the server.
53
+ - Tile matrix set URIs match regardless of `http`/`https`, the case of the host and a trailing slash.
54
+ - `orderedAxes` `Y, X` (EPSG:3035) is northing first: `pointOfOrigin` is read in that order.
55
+ - `fromURL` without options no longer hangs.
56
+
57
+ ## 0.0.12 and earlier
58
+
59
+ See the [git history](https://github.com/felipecarrillo100/ogcopenapis/commits/main).
60
+
61
+ [Unreleased]: https://github.com/felipecarrillo100/ogcopenapis/compare/v1.0.1...HEAD
62
+ [1.0.1]: https://github.com/felipecarrillo100/ogcopenapis/compare/v1.0.0...v1.0.1
63
+ [1.0.0]: https://github.com/felipecarrillo100/ogcopenapis/releases/tag/v1.0.0
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2019 felipecarrillo100
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1
+ MIT License
2
+
3
+ Copyright (c) 2019 felipecarrillo100
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
package/README.md CHANGED
@@ -1,72 +1,305 @@
1
- # OGC OPEN API's prototype for LuciadRIA
2
-
3
- ## Description
4
- The ogcopenapis package provides OGC API functionalities to LuciadRIA Application.
5
-
6
- Implements
7
- * __Open API Features__
8
- * __Open API Tiles__
9
- * __Open API Maps__
10
-
11
- The Main Components are:
12
-
13
- * __OgcOpenApiFeatureStore__: a ready to use LuciadRIA Feature store capable to retrieve features from an OGC API Feature Service
14
- * __OgcOpenApiMapsModel__: a ready to use model capable to retrieve images from from an OGC API Maps Service
15
- * __OgcOpenApiTilesModel__: a ready to use model capable to retrieve tiles from an OGC API Tiles Service
16
- * __OgcOpenApiGetCapabilities__: a helper to retrieve the capabilities of a server such as available Collections and available Formats
17
-
18
-
19
-
20
- ## To build
21
- This is the source code that produces a library delivered as a npm package.
22
- To build the source code use the npm scripts:
23
- ```
24
- npm install
25
- npm run build
26
- ```
27
- Then you can publish the package to npm or other repository
28
-
29
- ## To test
30
- Some test have been added that runs using nodejs using Jest. No browser test is available at the moment.
31
- The test uses isomorphic-fetch to provide fetch in node testing with jest.
32
- ```
33
- npm run test
34
- ```
35
- Test use the sever-side implementations of OGC Open API from "https://demo.pygeoapi.io/master/" and "https://maps.gnosis.earth/ogcapi/"
36
- The servers are reliable and stable, but take in t account that changes at the server may brake some tests of this client.
37
-
38
- ## To use in your project
39
-
40
- Simply import the NPM package into your project
41
-
42
- ```
43
- npm install ogcopenapis
44
- ```
45
-
46
- If you require the GetCapabilities functionality then import:
47
- ```typescript
48
- import {
49
- CollectionLinkType, OgcOpenApiCapabilitiesCollection,
50
- OgcOpenApiCapabilitiesCollectionServiceLinkType,
51
- OgcOpenApiGetCapabilities
52
- } from "ogcopenapis/lib/OgcOpenApiGetCapabilities";
53
- ```
54
- For Open Api Feature you can use the OgcOpenApiFeatureStore, this implements a store that can be used with LuciadRIA FeatureModel and FeatureLayer
55
- ```typescript
56
- import {
57
- OgcOpenApiFeatureStore
58
- } from "ogcopenapis/lib/OgcOpenApiFeatureStore";
59
- ```
60
-
61
- For Maps and Tiles use OgcOpenApiMapsModel and OgcOpenApiTilesModel:
62
- ```typescript
63
- import {OgcOpenApiMapsModel} from "ogcopenapis/lib/OgcOpenApiMapsModel";
64
- import {OgcOpenApiTilesModel} from "ogcopenapis/lib/OgcOpenApiTilesModel";
65
- ```
66
- Both models extend from UrlTileSetModel so you can use them in combination with RasterTileSetLayer.
67
- Look at the LuciadRIA documentation if you need further information on using RasterTileSetLayer.
68
-
69
-
70
- ## Requirements
71
- * LuciadRIA 2020.0 or higher (place it on a local npm repository for instance verdaccio )
72
- * A ES6 or Typescript capable transpiler.
1
+ # OGC API for LuciadRIA
2
+
3
+ ## Description
4
+ The ogcopenapis package provides OGC API functionalities to LuciadRIA applications.
5
+
6
+ Implements
7
+ * __OGC API - Features__
8
+ * __OGC API - Maps__
9
+ * __OGC API - Tiles__, map (raster) tiles and vector tiles, of collections and of the dataset
10
+ * __OGC API - Styles__, for vector tiles
11
+
12
+ The Main Components are:
13
+
14
+ * __OgcOpenApiGetCapabilities__: a helper to retrieve the capabilities of a server such as available collections, available formats, tilesets and tile matrix sets
15
+ * __OgcOpenApiFeatureStore__: a ready to use LuciadRIA store that retrieves features from an OGC API Features service
16
+ * __OgcOpenApiMapsModel__: a ready to use model that retrieves images from an OGC API Maps service
17
+ * __OgcOpenApiTilesModel__: a ready to use model that retrieves map tiles from an OGC API Tiles service
18
+ * __OgcOpenApiVectorTilesModel__: a ready to use model that retrieves vector tiles (Mapbox Vector Tiles) from an OGC API Tiles service
19
+ * __OgcOpenApiStyleTools__: a helper to retrieve OGC API Styles as Mapbox GL styles, or to generate a default style
20
+
21
+ And the helpers they share:
22
+
23
+ * __OgcOpenApiTileMatrixTools__: maps an OGC TileMatrixSet onto a LuciadRIA tile structure, shared by both tiles models
24
+ * __OgcOpenApiWmtsTools__: describes an OGC API tileset as a WMTS layer, for LuciadRIA's WMTS support
25
+ * __OgcOpenApiMvtTools__: reads the layers in a Mapbox Vector Tile
26
+ * __OgcOpenApiCrsTools__: converts OGC CRS URIs to LuciadRIA reference identifiers, `http://www.opengis.net/def/crs/EPSG/0/3857` to `EPSG:3857`
27
+ * __OgcOpenApiFetchTools__: the requests of all components, with URL completion and the proxify option
28
+
29
+ ## To build
30
+ This is the source code that produces a library delivered as a npm package of native ES modules, in the `lib` folder,
31
+ with type declarations and source maps. To build the source code use the npm scripts:
32
+ ```
33
+ npm install
34
+ npm run build
35
+ ```
36
+ `build` runs `build:lib`, which compiles with `tsc` (TypeScript 5, `module: NodeNext`, target ES2020): one module per
37
+ source file, with the `.js` extensions that native ES modules need. LuciadRIA is never bundled: it is a peer dependency,
38
+ and every `@luciad/ria/...` import stays an import of the application's single copy.
39
+
40
+ Then you can publish the package to npm or other repository. `npm publish` first runs the tests and the package check.
41
+
42
+ ## To test
43
+ The tests run in Node.js using Vitest, with jsdom as environment.
44
+
45
+ The default tests run offline, on fixtures in `src/fixtures` and `test/fixtures/servers`, with a mocked `fetch`:
46
+ ```
47
+ npm run test
48
+ ```
49
+
50
+ The servers the tests use are listed in `test/servers.ts`, with an example of each kind of data they serve (features, maps,
51
+ map tiles, vector tiles of a collection and of the dataset, and styles): pygeoapi (https://demo.pygeoapi.io/master/), ldproxy
52
+ (https://demo.ldproxy.net/), CubeWerx (https://test.cubewerx.com/cubewerx/cubeserv/demo/ogcapi/) and PDOK (https://api.pdok.nl/).
53
+ `npm run test` replays their recorded responses in `test/fixtures/servers`, and the live tests (`*.live.test.ts`) check that
54
+ the servers still answer as recorded:
55
+ ```
56
+ npm run test:live
57
+ ```
58
+ The servers are reliable and stable, but take into account that changes at a server may break some of these tests.
59
+ When a server changed, record its responses again:
60
+ ```
61
+ npm run test:record
62
+ ```
63
+ GNOSIS (https://maps.gnosis.earth/ogcapi/) is in the list but not tested: its `/collections` response is 9 MB, and its tiles need a login.
64
+
65
+ The package check builds and packs the package, and checks it as published: only `lib/`, the sources of its source
66
+ maps, README, CHANGELOG, LICENSE and package.json are in it, nothing of LuciadRIA; `lib/` imports only its own modules and
67
+ `@luciad/ria`; [publint](https://publint.dev) and [Are the Types Wrong](https://arethetypeswrong.github.io) find no
68
+ problems; and every module loads through the package exports, installed in a `node_modules` folder, by Node's own
69
+ ES module loader, as in the tests of an application:
70
+ ```
71
+ npm run test:package
72
+ ```
73
+
74
+ The browser tests run the demo in Chrome: for each test server and each kind of data, they add a layer and check that the
75
+ map paints it, without failed requests or page errors. They need the LuciadRIA license in `demo/license` (see
76
+ [demo/README.md](demo/README.md)) and Google Chrome, or another Chrome set with `CHROME_PATH`. `HEADED=1` shows the browser,
77
+ and screenshots are saved in `test/browser/screenshots`.
78
+ ```
79
+ npm run test:browser
80
+ ```
81
+ Layers that are not painted yet are marked with `knownIssue` in `test/servers.ts`, the browser tests expect them to fail.
82
+
83
+ ## Demo
84
+ The `demo` folder contains a minimal page to open Features, Maps, Tiles and Vector Tiles collections, and the tiles of a
85
+ dataset, in a LuciadRIA map. It needs a LuciadRIA development license in `demo/license/luciadria_development.txt`, see
86
+ [demo/README.md](demo/README.md).
87
+ ```
88
+ npm run demo
89
+ ```
90
+
91
+ ## To use in your project
92
+
93
+ Simply import the NPM package into your project, with LuciadRIA, its peer dependency:
94
+
95
+ ```
96
+ npm install ogcopenapis @luciad/ria
97
+ ```
98
+
99
+ The package is native ES modules. Import each component by its name, `ogcopenapis/OgcOpenApiFeatureStore` for
100
+ instance. The paths of version 0.0.12, `ogcopenapis/lib/OgcOpenApiFeatureStore`, still work.
101
+
102
+ ### Capabilities
103
+ `fromURL` reads the landing page of a server and its collections, optionally only those with links of one type:
104
+ ```typescript
105
+ import {CollectionLinkType, OgcOpenApiGetCapabilities} from "ogcopenapis/OgcOpenApiGetCapabilities";
106
+
107
+ const capabilities = await OgcOpenApiGetCapabilities.fromURL("https://demo.pygeoapi.io/master/", {filterCollectionsByLinkType: CollectionLinkType.Items});
108
+ const collection = capabilities.collections.find(c => c.id === "lakes");
109
+ ```
110
+ Links that are relative are resolved against the document that has them.
111
+
112
+ All components accept `credentials` and `requestHeaders` for their requests, and `proxify`, a function that rewrites each
113
+ request, for instance to send it through a proxy:
114
+ ```typescript
115
+ const proxify = (url: string, fetchOptions: RequestInit) => ({url: "https://proxy.example.com/?url=" + encodeURIComponent(url), fetchOptions});
116
+ const capabilities = await OgcOpenApiGetCapabilities.fromURL(serverUrl, {proxify});
117
+ ```
118
+
119
+ ### Features
120
+ OgcOpenApiFeatureStore implements a LuciadRIA store, to use with FeatureModel and FeatureLayer:
121
+ ```typescript
122
+ import {FeatureModel} from "@luciad/ria/model/feature/FeatureModel.js";
123
+ import {FeatureLayer} from "@luciad/ria/view/feature/FeatureLayer.js";
124
+ import {LoadSpatially} from "@luciad/ria/view/feature/loadingstrategy/LoadSpatially.js";
125
+ import {GeoJsonCodec} from "@luciad/ria/model/codec/GeoJsonCodec.js";
126
+ import {getReference} from "@luciad/ria/reference/ReferenceProvider.js";
127
+ import {OgcOpenApiFeatureStore} from "ogcopenapis/OgcOpenApiFeatureStore";
128
+
129
+ const items = OgcOpenApiGetCapabilities.filterCollectionLinks(collection.links, CollectionLinkType.Items);
130
+ const store = new OgcOpenApiFeatureStore({
131
+ dataUrl: items.find(l => l.type === "application/geo+json").href,
132
+ outputFormat: "application/geo+json",
133
+ codec: new GeoJsonCodec({generateIDs: false}),
134
+ crs: "http://www.opengis.net/def/crs/OGC/1.3/CRS84",
135
+ extent: collection.extent,
136
+ useCrs84Bounds: true,
137
+ });
138
+ const model = new FeatureModel(store, {reference: getReference("CRS:84")});
139
+ map.layerTree.addChild(new FeatureLayer(model, {label: collection.title, loadingStrategy: new LoadSpatially()}));
140
+ ```
141
+ The store requests the features in view, a query does not follow the `next` links of a response yet (no paging).
142
+
143
+ Keep the ids of the server: `generateIDs: false`. Each feature of an OGC API Features collection has an id, `get(id)` of
144
+ the store requests `items/{id}` with it, and LuciadRIA updates only the features that changed when the ids stay the same
145
+ between queries. `generateIDs: true` replaces them with ids of its own on every query.
146
+
147
+ ### Maps and map tiles
148
+ For maps and map tiles use OgcOpenApiMapsModel and OgcOpenApiTilesModel. OgcOpenApiMapsModel extends WMSTileSetModel
149
+ and OgcOpenApiTilesModel extends WMTSTileSetModel, so you use them in combination with RasterTileSetLayer.
150
+
151
+ OgcOpenApiMapsModel requests the map as tiles. The map link carries the `f` value the server accepts, such as `f=png`:
152
+ ```typescript
153
+ import {RasterTileSetLayer} from "@luciad/ria/view/tileset/RasterTileSetLayer.js";
154
+ import {OgcOpenApiMapsModel} from "ogcopenapis/OgcOpenApiMapsModel";
155
+
156
+ const mapLinks = OgcOpenApiGetCapabilities.filterCollectionLinks(collection.links, CollectionLinkType.Map);
157
+ const mapsModel = new OgcOpenApiMapsModel({
158
+ crs: "http://www.opengis.net/def/crs/EPSG/0/3857",
159
+ baseURL: (mapLinks.find(l => l.type === "image/png") || mapLinks[0]).href,
160
+ collection: collection.id,
161
+ });
162
+ map.layerTree.addChild(new RasterTileSetLayer(mapsModel, {label: collection.title}));
163
+ ```
164
+
165
+ Create OgcOpenApiTilesModel with `createFromTileSet`. It describes the tileset to LuciadRIA's WMTS support, which handles
166
+ tile matrix sets that are quad-trees and tile matrix sets that are not (such as GlobalCRS84Scale), and it does not request
167
+ tiles outside the `tileMatrixSetLimits`. The tilesets and tile matrix sets are found as for vector tiles, below:
168
+ ```typescript
169
+ import {OgcOpenApiTilesModel} from "ogcopenapis/OgcOpenApiTilesModel";
170
+
171
+ const tileSet = await OgcOpenApiGetCapabilities.fetchCollectionTileSet(capabilities, collection, tileSetInfo, {}, CollectionLinkType.Tiles);
172
+ const model = await OgcOpenApiTilesModel.createFromTileSet({
173
+ tileMatrix,
174
+ baseURL: tileSet.links.find(l => l.type === "image/png").href,
175
+ collection: collection.id,
176
+ tileMatrixSetLimits: tileSet.tileMatrixSetLimits,
177
+ extent: collection.extent.spatial.bbox[0],
178
+ });
179
+ map.layerTree.addChild(new RasterTileSetLayer(model, {label: collection.title}));
180
+ ```
181
+ The constructor `new OgcOpenApiTilesModel(options)` still works, but is deprecated: it supports quad-tree tile matrix sets only.
182
+ Look at the LuciadRIA documentation if you need further information on using RasterTileSetLayer.
183
+
184
+ ### Vector tiles
185
+ For vector tiles use OgcOpenApiVectorTilesModel. It extends LuciadRIA's MapboxVectorTileSetModel, so you use it in combination with
186
+ MapboxVectorTileSetLayer and a MapboxStyle:
187
+ ```typescript
188
+ import {MapboxVectorTileSetLayer} from "@luciad/ria/view/mapbox/MapboxVectorTileSetLayer.js";
189
+ import {MapboxStyle} from "@luciad/ria/view/mapbox/MapboxStyle.js";
190
+ import {CollectionLinkType, OgcOpenApiGetCapabilities} from "ogcopenapis/OgcOpenApiGetCapabilities";
191
+ import {OgcOpenApiVectorTilesModel} from "ogcopenapis/OgcOpenApiVectorTilesModel";
192
+ import {OgcOpenApiStyleTools} from "ogcopenapis/OgcOpenApiStyleTools";
193
+
194
+ const capabilities = await OgcOpenApiGetCapabilities.fromURL("https://demo.ldproxy.net/daraa/", {filterCollectionsByLinkType: CollectionLinkType.VectorTiles});
195
+ const collection = capabilities.collections.find(c => c.id === "TransportationGroundCrv");
196
+
197
+ // The tilesets of the collection: the tile matrix sets it is tiled in, which can be fewer than the ones of the server.
198
+ // Servers give tile matrix sets their own ids (CubeWerx calls WebMercatorQuad smerc), they are matched by URI.
199
+ // fetchTileSetsInFull leaves out definitions that cannot be read, it rejects only when none can
200
+ const tileMatrixSets = await OgcOpenApiGetCapabilities.fetchTileSetsInFull(capabilities);
201
+ const tileSets = await OgcOpenApiGetCapabilities.fetchCollectionTileSets(capabilities, collection, CollectionLinkType.VectorTiles);
202
+ const webMercator = tileSets.find(t => /WebMercatorQuad\/?$/.test(t.tileMatrixSetURI));
203
+ const tileMatrix = await OgcOpenApiGetCapabilities.fetchTileMatrixSetOfTileSet(capabilities, webMercator, tileMatrixSets);
204
+ const tileSet = await OgcOpenApiGetCapabilities.fetchCollectionTileSet(capabilities, collection, webMercator, {}, CollectionLinkType.VectorTiles);
205
+
206
+ const model = new OgcOpenApiVectorTilesModel({
207
+ tileMatrix,
208
+ baseURL: tileSet.links.find(l => l.type === "application/vnd.mapbox-vector-tile").href,
209
+ collection: collection.id,
210
+ tileMatrixSetLimits: tileSet.tileMatrixSetLimits,
211
+ });
212
+
213
+ // A style of the server (OGC API Styles), or a default style when the server has none.
214
+ // The default style needs the layers in the tiles: from the tileset, or read from a few tiles when the tileset does not list them
215
+ const styles = await OgcOpenApiStyleTools.fetchStyles(capabilities, collection);
216
+ const layers = tileSet.layers.length > 0 ? tileSet.layers : await model.discoverLayers({extent: collection.extent.spatial.bbox[0]});
217
+ const styleJson = styles.length > 0 ?
218
+ await OgcOpenApiStyleTools.fetchMapboxStyle(capabilities, OgcOpenApiStyleTools.pickStylesheet(styles[0], tileMatrix.id)) :
219
+ OgcOpenApiStyleTools.createDefaultStyle(layers);
220
+
221
+ map.layerTree.addChild(new MapboxVectorTileSetLayer(model, {label: collection.title, style: MapboxStyle.createFromObject(styleJson)}));
222
+ ```
223
+
224
+ ### Tiles of the dataset
225
+ Some servers tile the dataset as a whole, with all its collections in each tile, and some only the dataset (PDOK).
226
+ The tilesets and styles of the dataset are linked from the landing page:
227
+
228
+ ```typescript
229
+ if (OgcOpenApiGetCapabilities.hasDatasetTileSets(capabilities, CollectionLinkType.VectorTiles)) {
230
+ const datasetTileSets = await OgcOpenApiGetCapabilities.fetchDatasetTileSets(capabilities, CollectionLinkType.VectorTiles);
231
+ const tileMatrix = await OgcOpenApiGetCapabilities.fetchTileMatrixSetOfTileSet(capabilities, datasetTileSets[0], tileMatrixSets);
232
+ // null instead of a collection: the tileset of the dataset
233
+ const tileSet = await OgcOpenApiGetCapabilities.fetchCollectionTileSet(capabilities, null, datasetTileSets[0], {}, CollectionLinkType.VectorTiles);
234
+ // The styles of the dataset, only those for the tile matrix set in use
235
+ const datasetStyles = OgcOpenApiStyleTools.getStylesForTileMatrixSet(
236
+ await OgcOpenApiStyleTools.fetchStyles(capabilities, null), tileMatrix.id, [tileMatrix.id /* and the ids of the other tilesets */]);
237
+ }
238
+ ```
239
+ A tileset of the dataset can have a `boundingBox`, where its data is. A collection has its `extent` instead.
240
+
241
+ ### Styles
242
+ * LuciadRIA reads the Mapbox GL encoding of OGC API Styles only, not SLD or other encodings.
243
+ * A server can publish a stylesheet per tile matrix set, because zoom levels depend on it. `pickStylesheet` picks the one for the tile matrix set in use.
244
+ * A server can also publish a style per tile matrix set, named after it (PDOK: `bgt_standaardvisualisatie__netherlandsrdnewquad`).
245
+ `getStylesForTileMatrixSet` leaves out the styles named after another tile matrix set.
246
+ * `fetchMapboxStyle` removes properties without a value (`"filter" : ,`), so that styles that are not valid JSON can still be used.
247
+ * `createDefaultStyle` paints points, lines and surfaces by the `geometryDimension` of the layers, without labels.
248
+ * Not all servers list the layers of a tileset (CubeWerx, pygeoapi and PDOK do not), and the names of the layers in the tiles
249
+ differ per server: ldproxy and CubeWerx name the layer of a collection after it, pygeoapi after its source data.
250
+ `discoverLayers` of the vector tiles model reads them from a few tiles where the data is.
251
+
252
+ ### References
253
+ LuciadRIA reprojects tiles and features to the reference of the map, but it knows only some EPSG references by default.
254
+ LuciadRIA 2026.1.1 does not know the references of five of the tile matrix sets of the OGC standard (UTM31WGS84Quad EPSG:32631,
255
+ UPSArcticWGS84Quad EPSG:5041, UPSAntarcticWGS84Quad EPSG:5042, EuropeanETRS89_LAEAQuad EPSG:3035 and CanadianNAD83_LCC EPSG:3978),
256
+ nor of PDOK's NetherlandsRDNewQuad (EPSG:28992). The library does not register references itself: register the ones your
257
+ servers use before creating a model, as the demo does in [demo/src/references.ts](demo/src/references.ts):
258
+
259
+ ```typescript
260
+ import {addReference, parseWellKnownText} from "@luciad/ria/reference/ReferenceProvider.js";
261
+
262
+ addReference(parseWellKnownText('PROJCS["RD",GEOGCS["Amersfoort", ...]]'), "EPSG:28992");
263
+ ```
264
+
265
+ Applications that load references on demand, such as MapEvolution with `requireReference` and `retryOnUnknownReference`,
266
+ need nothing more. When a reference is unknown, the models throw LuciadRIA's own `UnknownIdentifierError` with its
267
+ identifier (`EPSG:3035`), so the reference can be loaded and the model created again:
268
+ ```typescript
269
+ import {OgcOpenApiCrsTools} from "ogcopenapis/OgcOpenApiCrsTools";
270
+
271
+ // Before listing tile matrix sets: load their references, so that none is left out because its reference is not loaded yet
272
+ await Promise.all(tileMatrixSets.map(t => requireReference(OgcOpenApiCrsTools.getReferenceName(t.crs)).catch(() => undefined)));
273
+ // When creating a model: a tile matrix set fetched later can bring another reference
274
+ const model = await retryOnUnknownReference(() => OgcOpenApiTilesModel.createFromTileSet(options));
275
+ // The vector tiles model is created synchronously, an async wrapper lets the same retry apply
276
+ const vectorModel = await retryOnUnknownReference(async () => new OgcOpenApiVectorTilesModel(vectorOptions));
277
+ ```
278
+ `getReferenceName` turns `http://www.opengis.net/def/crs/EPSG/0/28992` into `EPSG:28992`, the identifier to load.
279
+ It does not convert the `https://` form of those URIs, nor a CRS given as an object (`{uri}` or `{wkt}`, allowed by
280
+ OGC 2D Tile Matrix Set 2.0): none of the test servers uses them in a tile matrix set.
281
+
282
+ The axis order of a reference matters for raster tiles: EPSG:3035 is northing first. Its WKT should declare that with
283
+ `AXIS["Northing",NORTH],AXIS["Easting",EAST]`, as the EPSG definitions in LuciadRIA's sample data (`epsg_coord_ref.txt`,
284
+ which MapEvolution uses) do. The WKT of epsg.io that the demo uses has no `AXIS`, which is enough for vector tiles only.
285
+
286
+ ### Notes
287
+ * Map tiles support any tile matrix set of LuciadRIA's WMTS support. Vector tiles support only tile matrix sets that
288
+ LuciadRIA can address as a quad-tree, LuciadRIA's vector tile structure is a quad-tree.
289
+ * Tile matrix sets with a bottomLeft corner of origin are not in WMTS 1.0, `createFromTileSet` supports them as quad-trees only.
290
+ * `variableMatrixWidths` (coalesced tile matrices) is not supported.
291
+ * A tileset can include its tile matrix set instead of linking it, `fetchTileMatrixSetOfTileSet` uses it then.
292
+ * Levels that are not in the `tileMatrixSetLimits` of a tileset have no tiles. PDOK tiles BGT at one level only,
293
+ RD level 12: nothing shows until the map is zoomed in to about 1 m per pixel, and LuciadRIA over-zooms beyond it.
294
+ * LuciadRIA 2026.1.1 paints nothing for a vector tiles model with `minLevel > 0`. OgcOpenApiVectorTilesModel therefore starts at
295
+ level 0, and does not request tiles outside the `tileMatrixSetLimits` of the tileset.
296
+ * LuciadRIA 2026.1.1 does not paint Mapbox `circle` layers. The default style draws points as a text symbol for that reason.
297
+
298
+ ## Changes
299
+ See [CHANGELOG.md](CHANGELOG.md) for the changes of each version.
300
+
301
+ ## Requirements
302
+ * LuciadRIA 2026.1 or higher, a peer dependency that the application installs (place it on a local npm repository,
303
+ for instance verdaccio)
304
+ * A bundler or runtime for ES modules and ES2020, such as Vite or webpack. TypeScript projects need
305
+ `moduleResolution` `bundler`, `node16` or `nodenext`, which read the `exports` of the package.
@@ -1,9 +1,10 @@
1
- declare class OgcOpenApiCrsTools {
2
- /**
3
- *
4
- * @param uriOrName
5
- * @private
6
- */
7
- static getReferenceName(uriOrNameI: string): any;
8
- }
9
- export { OgcOpenApiCrsTools };
1
+ declare class OgcOpenApiCrsTools {
2
+ /**
3
+ *
4
+ * @param uriOrName
5
+ * @private
6
+ */
7
+ static getReferenceName(uriOrNameI: string): any;
8
+ }
9
+ export { OgcOpenApiCrsTools };
10
+ //# sourceMappingURL=OgcOpenApiCrsTools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OgcOpenApiCrsTools.d.ts","sourceRoot":"","sources":["../src/OgcOpenApiCrsTools.ts"],"names":[],"mappings":"AAAA,cAAM,kBAAkB;IACpB;;;;OAIG;WACW,gBAAgB,CAAC,UAAU,EAAE,MAAM;CA+BpD;AAED,OAAO,EAAE,kBAAkB,EAAC,CAAA"}
@@ -1,39 +1,40 @@
1
- class OgcOpenApiCrsTools {
2
- /**
3
- *
4
- * @param uriOrName
5
- * @private
6
- */
7
- static getReferenceName(uriOrNameI) {
8
- let uriOrName;
9
- if (typeof uriOrNameI === "undefined") {
10
- uriOrName = "http://www.opengis.net/def/crs/OGC/1.3/CRS84";
11
- }
12
- else {
13
- uriOrName = uriOrNameI.replace(/[<>]/g, '');
14
- }
15
- if (!uriOrName.startsWith('http')) {
16
- return uriOrName;
17
- }
18
- const prefix = 'http://www.opengis.net/def/crs/';
19
- if (uriOrName.startsWith(prefix)) {
20
- const cleanCRS = uriOrName.substr(prefix.length);
21
- const parts = cleanCRS.split('/');
22
- if (parts.length === 3) {
23
- const name = parts[0];
24
- const version = parts[1];
25
- const code = parts[2];
26
- switch (name) {
27
- case 'EPSG':
28
- return name + ':' + code;
29
- break;
30
- case 'OGC':
31
- return 'CRS' + ':' + code.substr('CRS'.length);
32
- break;
33
- }
34
- }
35
- }
36
- return uriOrName;
37
- }
38
- }
39
- export { OgcOpenApiCrsTools };
1
+ class OgcOpenApiCrsTools {
2
+ /**
3
+ *
4
+ * @param uriOrName
5
+ * @private
6
+ */
7
+ static getReferenceName(uriOrNameI) {
8
+ let uriOrName;
9
+ if (typeof uriOrNameI === "undefined") {
10
+ uriOrName = "http://www.opengis.net/def/crs/OGC/1.3/CRS84";
11
+ }
12
+ else {
13
+ uriOrName = uriOrNameI.replace(/[<>]/g, '');
14
+ }
15
+ if (!uriOrName.startsWith('http')) {
16
+ return uriOrName;
17
+ }
18
+ const prefix = 'http://www.opengis.net/def/crs/';
19
+ if (uriOrName.startsWith(prefix)) {
20
+ const cleanCRS = uriOrName.substr(prefix.length);
21
+ const parts = cleanCRS.split('/');
22
+ if (parts.length === 3) {
23
+ const name = parts[0];
24
+ const version = parts[1];
25
+ const code = parts[2];
26
+ switch (name) {
27
+ case 'EPSG':
28
+ return name + ':' + code;
29
+ break;
30
+ case 'OGC':
31
+ return 'CRS' + ':' + code.substr('CRS'.length);
32
+ break;
33
+ }
34
+ }
35
+ }
36
+ return uriOrName;
37
+ }
38
+ }
39
+ export { OgcOpenApiCrsTools };
40
+ //# sourceMappingURL=OgcOpenApiCrsTools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OgcOpenApiCrsTools.js","sourceRoot":"","sources":["../src/OgcOpenApiCrsTools.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB;IACpB;;;;OAIG;IACI,MAAM,CAAC,gBAAgB,CAAC,UAAkB;QAC7C,IAAI,SAAS,CAAC;QACd,IAAI,OAAO,UAAU,KAAK,WAAW,EAAE,CAAC;YACpC,SAAS,GAAG,8CAA8C,CAAA;QAC9D,CAAC;aAAM,CAAC;YACJ,SAAS,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAChD,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAChC,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,MAAM,MAAM,GAAG,iCAAiC,CAAC;QACjD,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACzB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,QAAQ,IAAI,EAAE,CAAC;oBACX,KAAK,MAAM;wBACP,OAAO,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC;wBACzB,MAAM;oBACV,KAAK,KAAK;wBACN,OAAO,KAAK,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;wBAC/C,MAAM;gBACd,CAAC;YACL,CAAC;QACL,CAAC;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;CACJ;AAED,OAAO,EAAE,kBAAkB,EAAC,CAAA"}