Skip to content

Commit

Permalink
api
Browse files Browse the repository at this point in the history
  • Loading branch information
jahow committed Feb 1, 2024
1 parent d384c92 commit d676b11
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 116 deletions.
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,17 @@ The following standards are partially implemented:

- WMS - _Web Map Service_
- WFS - _Web Feature Service_
- WMTS - _Web Map Tile Service_
- OGC API (Records and Features)

Why no WMTS support? Because [OpenLayers](https://www.github.com/openlayers/openlayers) has an incredibly thorough and well-tested WMTS capabilities parser and you should just use it.
Reimplementing it in **ogc-client** currently does not bring any significant value.

## Why use it?

1. **ogc-client** will abstract the service version so you don't have to worry about it
2. **ogc-client** will handle XML so you only have to deal with native Javascript objects
3. **ogc-client** will hide the complexity of OGC standards behind straightforward APIs
4. **ogc-client** will run heavy tasks in a worker to avoid blocking the main thread
5. **ogc-client** will keep a persistent cache of operations to minimize requests and processing
6. **ogc-client** will handle errors in a graceful way and extract relevant messages for you
7. **ogc-client** will tell you if a service is not usable for [CORS-related issues](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
6. **ogc-client** will tell you if a service is not usable for [CORS-related issues](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)

## Instructions

Expand Down Expand Up @@ -59,7 +56,7 @@ To start it locally, clone the repository and run the following commands:
```bash
$ cd app
$ npm install
$ npm run serve
$ npm start
```

The app is based on [Vue.js](https://vuejs.org/) and will showcase most features implemented in the library.
Expand Down
121 changes: 78 additions & 43 deletions app/src/Docs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@

<ul>
<li>
Support for <a href="https://www.ogc.org/standards/wfs">WFS</a> and
<a href="https://www.ogc.org/standards/wms">WMS</a> protocols
Support for <a href="https://www.ogc.org/standards/wfs">WFS</a>,
<a href="https://www.ogc.org/standards/wms">WMS</a>,
<a href="https://www.ogc.org/standards/wmts">WMTS</a> and
<a href="https://ogcapi.ogc.org/">OGC API</a> protocols
</li>
<li>Elaborate cache system to minimize network requests</li>
<li>
Expand Down Expand Up @@ -47,13 +49,13 @@
<p>
<CodeBlock lang="js">
<pre>
import { WfsEndpoint } from '@camptocamp/ogc-client';
import { WfsEndpoint } from '@camptocamp/ogc-client';

new WfsEndpoint("https://my.server.org/ows")
.isReady()
.then(
(endpoint) => console.log(endpoint.getFeatureTypes())
)
new WfsEndpoint("https://my.server.org/ows")
.isReady()
.then(
(endpoint) => console.log(endpoint.getFeatureTypes())
)
</pre
>
</CodeBlock>
Expand Down Expand Up @@ -126,23 +128,12 @@

<ul>
<li>
No <a href="https://www.ogc.org/standards/wmts">WMTS</a> parsing:
alternatives already exist, such as the OpenLayers
<a
href="https://openlayers.org/en/latest/apidoc/module-ol_format_WMTSCapabilities-WMTSCapabilities.html"
>WMTS Capabilities</a
>
class (<a
href="https://openlayers.org/en/latest/examples/wmts-capabilities.html"
>example</a
>)
</li>
<li>
No GML geometry parsing: again,
No GML geometry parsing: the
<a
href="https://openlayers.org/en/latest/apidoc/module-ol_format_GML32-GML32.html"
>alternatives do exist</a
>OpenLayers GML parser</a
>
offers extensive support of the GML format
</li>
</ul>

Expand All @@ -153,13 +144,13 @@
<p>
<CodeBlock lang="js">
<pre>
import { WmsEndpoint } from '@camptocamp/ogc-client';
import { WmsEndpoint } from '@camptocamp/ogc-client';

async function readExtent() {
const endpoint = await new WmsEndpoint('https://my.server.org/ows').isReady();
const layer = endpoint.getLayerByName();
const extent = layer.boundingBoxes['EPSG:4326'];
}</pre
async function readExtent() {
const endpoint = await new WmsEndpoint('https://my.server.org/ows').isReady();
const layer = endpoint.getLayerByName();
const extent = layer.boundingBoxes['EPSG:4326'];
}</pre
>
</CodeBlock>
</p>
Expand All @@ -169,15 +160,15 @@
<p>
<CodeBlock lang="js">
<pre>
import { WfsEndpoint } from '@camptocamp/ogc-client';

async function getFeatureUrl() {
const endpoint = await new WfsEndpoint('https://my.server.org/ows').isReady();
const url = endpoint.getFeatureUrl('my:featureType', {
asJson: true,
maxFeature: 1000
});
}</pre
import { WfsEndpoint } from '@camptocamp/ogc-client';

async function getFeatureUrl() {
const endpoint = await new WfsEndpoint('https://my.server.org/ows').isReady();
const url = endpoint.getFeatureUrl('my:featureType', {
asJson: true,
maxFeature: 1000
});
}</pre
>
</CodeBlock>
</p>
Expand All @@ -187,13 +178,57 @@
<p>
<CodeBlock lang="js">
<pre>
import { OgcApiEndpoint } from '@camptocamp/ogc-client';
import { OgcApiEndpoint } from '@camptocamp/ogc-client';

async function getFirstTenRecords() {
const endpoint = await new OgcApiEndpoint('https://my.server.org/main')
const firstCollection = (await endpoint.recordCollections)[0];
return endpoint.getCollectionItems(firstCollection, 10, 0);
}</pre
>
</CodeBlock>
</p>

<h5>
Add a WMTS layer to an
<a href="https://openlayers.org/">OpenLayers</a> map
</h5>

async function getFirstTenRecords() {
const endpoint = await new OgcApiEndpoint('https://my.server.org/main')
const firstCollection = (await endpoint.recordCollections)[0];
return endpoint.getCollectionItems(firstCollection, 10, 0);
}</pre
<p>
<CodeBlock lang="js">
<pre>
import TileLayer from 'ol/layer/Tile';
import WMTS from 'ol/source/WMTS';
import { WmtsEndpoint } from '@camptocamp/ogc-client';

// create the OpenLayers map
// ...

async function addWmtsLayer() {
const endpoint = await new WmtsEndpoint('https://my.server.org/wmts').isReady();
const layer = endpoint.getLayers()[0];
const matrixSet = layer.matrixSets[0];
const tileGrid = await endpoint.getOpenLayersTileGrid(
layer.name,
matrixSet.identifier
);
const resourceUrl = layer.resourceUrls[0];
const dimensions = endpoint.getDefaultDimensions(layer.name);
const layer = new TileLayer({
source: new WMTS({
layer: layer.name,
style: layer.defaultStyle,
matrixSet: matrixSet.identifier,
format: resourceUrl.format,
url: resourceUrl.url,
requestEncoding: resourceUrl.encoding,
tileGrid,
projection: matrixSet.crs,
dimensions,
}),
});
openLayersMap.addLayer(layer);
}</pre
>
</CodeBlock>
</p>
Expand Down
2 changes: 2 additions & 0 deletions app/src/api-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export function formatTypeToString(typeObj) {
switch (typeObj.type || typeObj) {
case 'Array':
return `${subType}[]`;
case 'Record':
return `Record<string, ${subType}>`;
case 'Response':
return `[Response](https://developer.mozilla.org/en-US/docs/Web/API/Response)`;
case 'Promise':
Expand Down
62 changes: 46 additions & 16 deletions app/src/components/wmts/WmtsLayerInfo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,39 @@ import TileLayer from 'ol/layer/Tile';
import WMTS from 'ol/source/WMTS';
import proj4 from 'proj4';
import { register } from 'ol/proj/proj4';
import WmtsEndpoint from '../../../../src/wmts/endpoint';
// this is necessary for tile reprojection to work
register(proj4);
async function addWmtsLayer(olMap) {
const endpoint = await new WmtsEndpoint(
'https://basemap.at/wmts/1.0.0/WMTSCapabilities.xml'
).isReady();
const layer = endpoint.getLayers()[0];
const matrixSetLink = layer.matrixSets[0];
const tileGrid = await endpoint.getOpenLayersTileGrid(
layer.name,
matrixSetLink.identifier
);
const resourceUrl = layer.resourceUrls[0];
const dimensions = endpoint.getDefaultDimensions(layer.name);
const olLayer = new TileLayer({
source: new WMTS({
layer: layer.name,
style: layer.defaultStyle,
matrixSet: matrixSetLink.identifier,
format: resourceUrl.format,
url: resourceUrl.url,
requestEncoding: resourceUrl.encoding,
tileGrid,
projection: matrixSetLink.crs,
dimensions,
}),
});
olMap.addLayer(olLayer);
}
export default {
name: 'WmtsLayerInfo',
components: { InfoList },
Expand Down Expand Up @@ -95,22 +124,23 @@ export default {
} else {
this.olMap.getLayers().pop();
}
const resourceUrl = this.layer.resourceUrls[0];
const dimensions = this.endpoint.getDefaultDimensions(this.layer.name);
const layer = new TileLayer({
source: new WMTS({
layer: this.layer.name,
style: this.selectedStyle,
matrixSet: matrixSetLink.identifier,
format: resourceUrl.format,
url: resourceUrl.url,
requestEncoding: resourceUrl.encoding,
tileGrid,
projection: matrixSetLink.crs,
dimensions,
}),
});
this.olMap.addLayer(layer);
// const resourceUrl = this.layer.resourceUrls[0];
// const dimensions = this.endpoint.getDefaultDimensions(this.layer.name);
// const layer = new TileLayer({
// source: new WMTS({
// layer: this.layer.name,
// style: this.selectedStyle,
// matrixSet: matrixSetLink.identifier,
// format: resourceUrl.format,
// url: resourceUrl.url,
// requestEncoding: resourceUrl.encoding,
// tileGrid,
// projection: matrixSetLink.crs,
// dimensions,
// }),
// });
// this.olMap.addLayer(layer);
addWmtsLayer(this.olMap);
},
},
},
Expand Down
87 changes: 87 additions & 0 deletions app/src/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,93 @@ available layers, bounding boxes etc. Layer name is case sensitive.`,
},
],
},
{
name: 'WmtsEndpoint',
type: 'Class',
constructor: {
params: [{ name: 'url', type: 'string' }],
description: `Creates a new WMTS endpoint; wait for the \`isReady()\` promise before using the endpoint methods.`,
},
methods: [
{
name: 'isReady',
description: `Resolves when the endpoint is ready to use. Returns the same endpoint object for convenience.`,
params: [],
return: { type: 'Promise', subType: 'WmtsEndpoint' },
},
{
name: 'getServiceInfo',
description: `Returns the service info.`,
params: [],
return: { type: 'WmtsEndpointInfo' },
},
{
name: 'getLayers',
description: `Returns the layers advertised in the endpoint.`,
params: [],
return: { type: 'Array', subType: 'WmtsLayer' },
},
{
name: 'getMatrixSets',
description: `Returns the matrix sets available for that endpoint. Each matrix set contains a list of tile matrices
as well as a supported CRS.`,
params: [],
return: { type: 'Array', subType: 'WmtsMatrixSet' },
},
{
name: 'getLayerByName',
description: `Returns a layer object based on its name.`,
params: [{ name: 'name', type: 'string' }],
return: { type: 'WmtsLayer' },
},
{
name: 'getMatrixSetByIdentifier',
description: `Returns a matrix set object based on its identifier.`,
params: [{ name: 'identifier', type: 'string' }],
return: { type: 'WmtsMatrixSet' },
},
{
name: 'getLayerResourceUrl',
description: `Returns a layer resource info. If no type hint is specified, the first resource will be returned. A resource
info contains a URL as well as an image format and a request encoding (KVP or REST).`,
params: [
{ name: 'layerName', type: 'string' },
{ name: 'formatHint', type: 'MimeType', optional: true },
],
return: { type: 'LayerResourceUrl' },
},
{
name: 'getTileUrl',
description: `Generates a tile URL for a layer and a set of parameters.`,
params: [
{ name: 'layerName', type: 'string' },
{ name: 'styleName', type: 'string' },
{ name: 'matrixSetName', type: 'string' },
{ name: 'tileMatrix', type: 'string' },
{ name: 'tileRow', type: 'number' },
{ name: 'tileCol', type: 'number' },
{ name: 'outputFormat', type: 'MimeType' },
],
return: { type: 'string' },
},
{
name: 'getDefaultDimensions',
description: `Return an object with all defined dimensions for the layer, as well as their default values.`,
params: [{ name: 'layerName', type: 'string' }],
return: { type: 'Record', subType: 'LayerDimensionValue' },
},
{
name: 'getOpenLayersTileGrid',
description: `Creates a \`WMTSTileGrid\` instance from the [\`ol\` package](https://www.npmjs.com/package/ol), for a given layer. Optionally, a matrix set
can be provided. Will return \`null\` if the \`ol\` package is not present (as it is considered an optional peer dependency).`,
params: [
{ name: 'layerName', type: 'string' },
{ name: 'matrixSetIdentifier', type: 'string', optional: true },
],
return: { type: 'WMTSTileGrid' },
},
],
},
{
name: 'useCache',
type: 'Function',
Expand Down
Loading

0 comments on commit d676b11

Please sign in to comment.