Skip to content

Commit

Permalink
feat!: extract advanced layers & sources into separate bundle (#515)
Browse files Browse the repository at this point in the history
* feat: extract advanced layers & sources into separate bundle

* chore(docs): add information about plugin

* chore(lint): update linter rules

* chore(docs): improve eror message

* chore(docs): update layers and sources description
  • Loading branch information
silvester-pari authored Dec 13, 2023
1 parent 3eafdbf commit 2ad7893
Show file tree
Hide file tree
Showing 14 changed files with 174 additions and 50 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"plugins": ["cypress", "@typescript-eslint"],
"root": true,
"rules": {
"@typescript-eslint/ban-ts-comment": "warn"
"@typescript-eslint/ban-ts-comment": "warn",
"@typescript-eslint/no-explicit-any": "warn"
}
}
14 changes: 3 additions & 11 deletions elements/map/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,11 @@ import "@eox/map"
<eox-map></eox-map>
```

// TODO: add documentation
Please refer to the [map docs](https://eox-a.github.io/EOxElements/?path=/docs/elements-eox-map--docs) for more details.

## Contribute
## Development

```
npm watch
(on root) npm run cypress
(on root) npm run format
npm version <new version>
npm run build
npm publish (requires OTP)
```
For a development setup, please check the [root-level readme](../../README.md).

## Changelog

Expand Down
32 changes: 32 additions & 0 deletions elements/map/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,38 @@ import {
import { buffer } from "ol/extent";
import "./src/compare";

/**
* The `eox-map` is a wrapper for the library [OpenLayers](https://openlayers.org/) with additional features and helper functions.
*
* Basic usage:
*
* ```
* import "@eox/map"
*
* <eox-map [...]></eox-map>
* ```
*
* Some basic layers, sources and formats are included in the default bundle, for advanced usage it is
* required to import the `advanced-layers-and-sources` plugin.
*
* Included in the base bundle:
* - Formats: `GeoJSON`, `MVT`
* - Layers: `Group`, `Image`, `Tile`, `Vector`, `VectorTile`
* - Sources: `ImageWMS`, `OSM`, `Tile`, `TileWMS`, `Vector`, `VectorTile`, `WMTS`, `XYZ`
*
* In order to use the rest of the layers and sources provided by OpenLayers, import the plugin as well:
*
* ```
* import "@eox/map/dist/eox-map-advanced-layers-and-sources.js"
* import "@eox/map/dist/eox-map.js"
*
* <eox-map [...]></eox-map>
* ```
* Included in the advanced plugin bundle:
* - Layers: All OpenLayers layer types, plus [STAC](https://github.com/m-mohr/ol-stac)
* - Sources: All OpenLayers source types
* - Reprojection through [proj4](https://github.com/proj4js/proj4js)
*/
@customElement("eox-map")
export class EOxMap extends LitElement {
/**
Expand Down
1 change: 1 addition & 0 deletions elements/map/map.stories.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { html } from "lit";
import "./src/plugins/advancedLayersAndSources/index";
import "./main";

export default {
Expand Down
4 changes: 2 additions & 2 deletions elements/map/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
],
"main": "./dist/eox-map.js",
"scripts": {
"build": "tsc && vite build",
"watch": "tsc && vite build --watch",
"build": "tsc && vite build --config vite.config.advancedLayersAndSources.ts && vite build --config vite.config.ts",
"watch": "tsc && vite build --config vite.config.advancedLayersAndSources.ts && vite build --config vite.config.ts --watch",
"format": "prettier --write .",
"lint": "eslint --ext .js,.ts .",
"lint:fix": "eslint --ext .js,.ts . --fix"
Expand Down
127 changes: 91 additions & 36 deletions elements/map/src/generate.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
import * as olLayers from "ol/layer";
import * as olSources from "ol/source";
import * as olFormats from "ol/format";
import STAC from "ol-stac";
import { GeoJSON, MVT } from "ol/format";

import {
Group,
Image,
Tile as TileLayer,
Vector as VectorLayer,
VectorTile as VectorTileLayer,
} from "ol/layer";

import {
ImageWMS,
OSM,
Tile as TileSource,
TileWMS,
Vector as VectorSource,
VectorTile as VectorTileSource,
WMTS,
XYZ,
} from "ol/source";

import { FlatStyleLike } from "ol/style/flat";
import { Collection } from "ol";
import { createXYZ } from "ol/tilegrid";
Expand All @@ -13,17 +30,8 @@ import {
SelectOptions,
addSelect,
} from "./select";
import { register } from "ol/proj/proj4.js";
import proj4 from "proj4";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";

register(proj4); // required to support source reprojection

const availableLayers = {
...olLayers,
STAC,
};
import type Layer from "ol/layer/Base";

export type layerType =
| "Group"
Expand Down Expand Up @@ -58,8 +66,43 @@ export type sourceType =
| "WMTS"
| "XYZ";

const basicOlFormats = {
GeoJSON,
MVT,
};

const basicOlLayers = {
Group,
Image,
Tile: TileLayer,
Vector: VectorLayer,
VectorTile: VectorTileLayer,
};

const basicOlSources = {
ImageWMS,
OSM,
Tile: TileSource,
TileWMS,
Vector: VectorSource,
VectorTile: VectorTileSource,
WMTS,
XYZ,
};

const availableFormats = {
...basicOlFormats,
...window.eoxMapAdvancedOlFormats,
};

const availableLayers = {
...basicOlLayers,
...window.eoxMapAdvancedOlLayers,
};

const availableSources = {
...olSources,
...basicOlSources,
...window.eoxMapAdvancedOlSources,
};

export type EOxInteraction = {
Expand Down Expand Up @@ -90,22 +133,34 @@ export type EoxLayer = {
* @param {EOxMap} EOxMap
* @param {EoxLayer} layer
* @param {boolean=} createInteractions
* @returns {olLayers.Layer}
* @returns {Layer}
*/
export function createLayer(
EOxMap: EOxMap,
layer: EoxLayer,
createInteractions: boolean = true
): olLayers.Layer {
): Layer {
layer = JSON.parse(JSON.stringify(layer));

const newLayer = availableLayers[layer.type];
const newSource = availableSources[layer.source?.type];
if (!newLayer) {
throw new Error(`Layer type ${layer.type} not supported!`);
if (!window.eoxMapAdvancedOlLayers) {
throw new Error(
`Layer type ${layer.type} not created! Forgot to import advanced layers & sources plugin from @eox/map/dist/eox-map-advanced-layers-and-sources.js?`
);
} else {
throw new Error(`Layer type ${layer.type} not supported!`);
}
}
if (layer.source && !newSource) {
throw new Error(`Source type ${layer.source.type} not supported!`);
if (!window.eoxMapAdvancedOlSources) {
throw new Error(
`Source type ${layer.source.type} not created! Forgot to import advanced layers & sources plugin from @eox/map/dist/eox-map-advanced-layers-and-sources.js?`
);
} else {
throw new Error(`Source type ${layer.source.type} not supported!`);
}
}

//@ts-ignore
Expand All @@ -118,7 +173,7 @@ export function createLayer(
// @ts-ignore
...(layer.source.format && {
// @ts-ignore
format: new olFormats[layer.source.format](),
format: new availableFormats[layer.source.format](),
}),
// @ts-ignore
...(layer.source.tileGrid && {
Expand Down Expand Up @@ -186,13 +241,13 @@ function addInteraction(
/**
* updates an existing layer
* @param {EoxLayer} newLayerDefinition
* @param {olLayers.Layer} existingLayer
* @param {Layer} existingLayer
* @returns {existingLayer}
*/
export function updateLayer(
EOxMap: EOxMap,
newLayerDefinition: EoxLayer,
existingLayer: olLayers.Layer
existingLayer: Layer
) {
const existingJsonDefintion = existingLayer.get(
"_jsonDefinition"
Expand All @@ -214,7 +269,9 @@ export function updateLayer(
JSON.stringify(newLayerDefinition.source) !==
JSON.stringify(existingJsonDefintion.source)
) {
existingLayer.setSource(newLayer.getSource());
(existingLayer as any as VectorLayer<VectorSource>).setSource(
(newLayer as any as VectorLayer<VectorSource>).getSource()
);
}

if (
Expand Down Expand Up @@ -296,7 +353,7 @@ export function updateLayer(
// remove all layers from the group that do not exist in the new layer definition
//@ts-ignore
const layerCollection = existingLayer.getLayers();
layerCollection.forEach((l: olLayers.Layer) => {
layerCollection.forEach((l: Layer) => {
if (!newLayerIds.includes(l.get("id"))) {
layerCollection.remove(l);
}
Expand All @@ -308,7 +365,7 @@ export function updateLayer(
if (
layerCollection
.getArray()
.map((l: olLayers.Layer) => l.get("id"))
.map((l: Layer) => l.get("id"))
.includes(newLayerId)
) {
// layer already existed
Expand All @@ -325,15 +382,13 @@ export function updateLayer(
});

// after all layers were added/updated/deleted, rearrange them in the correct order
layerCollection
.getArray()
.sort((layerA: olLayers.Layer, layerB: olLayers.Layer) => {
return (
// change this order? the reverse order, because we want the topmost layer to be on top
newLayerIds.indexOf(layerA.get("id")) -
newLayerIds.indexOf(layerB.get("id"))
);
});
layerCollection.getArray().sort((layerA: Layer, layerB: Layer) => {
return (
// change this order? the reverse order, because we want the topmost layer to be on top
newLayerIds.indexOf(layerA.get("id")) -
newLayerIds.indexOf(layerB.get("id"))
);
});
layerCollection.changed();
}
setSyncListeners(existingLayer, newLayerDefinition);
Expand All @@ -349,10 +404,10 @@ export const generateLayers = (EOxMap: EOxMap, layerArray: Array<EoxLayer>) => {

/**
* set listeners to keep state of layer in sync with input json
* @param {olLayers.Layer} olLayer
* @param {Layer} olLayer
* @param {EoxLayer} eoxLayer
*/
function setSyncListeners(olLayer: olLayers.Layer, eoxLayer: EoxLayer) {
function setSyncListeners(olLayer: Layer, eoxLayer: EoxLayer) {
olLayer.on("change:opacity", () => {
eoxLayer.opacity = olLayer.getOpacity();
});
Expand Down
3 changes: 3 additions & 0 deletions elements/map/src/plugins/advancedLayersAndSources/formats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as olFormats from "ol/format";

window.eoxMapAdvancedOlFormats = olFormats;
3 changes: 3 additions & 0 deletions elements/map/src/plugins/advancedLayersAndSources/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import "./formats";
import "./layers";
import "./sources";
11 changes: 11 additions & 0 deletions elements/map/src/plugins/advancedLayersAndSources/layers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as olLayers from "ol/layer";
import STAC from "ol-stac";
import { register } from "ol/proj/proj4.js";
import proj4 from "proj4";

register(proj4); // required to support source reprojection

window.eoxMapAdvancedOlLayers = {
...olLayers,
STAC,
};
3 changes: 3 additions & 0 deletions elements/map/src/plugins/advancedLayersAndSources/sources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as olSources from "ol/source";

window.eoxMapAdvancedOlSources = olSources;
1 change: 1 addition & 0 deletions elements/map/test/stacLayer.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { html } from "lit";
import "../src/plugins/advancedLayersAndSources/index";
import "../main";
import stacLayerJson from "./stacLayer.json";

Expand Down
8 changes: 8 additions & 0 deletions elements/map/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ declare global {

declare module "*.css";
declare module "vite";

declare global {
interface Window {
eoxMapAdvancedOlFormats: any;
eoxMapAdvancedOlLayers: any;
eoxMapAdvancedOlSources: any;
}
}
13 changes: 13 additions & 0 deletions elements/map/vite.config.advancedLayersAndSources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineConfig } from "vite";

// https://vitejs.dev/config/
export default defineConfig({
build: {
lib: {
entry: "./src/plugins/advancedLayersAndSources/index.ts",
name: "eox-map-advanced-layers-and-sources",
// the proper extensions will be added
fileName: "eox-map-advanced-layers-and-sources",
},
},
});
1 change: 1 addition & 0 deletions elements/map/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { defineConfig } from "vite";
// https://vitejs.dev/config/
export default defineConfig({
build: {
emptyOutDir: false,
lib: {
entry: "./main.ts",
name: "eox-map",
Expand Down

0 comments on commit 2ad7893

Please sign in to comment.