@geospatial-sdk/openlayers 0.0.5-dev.53 → 0.0.5-dev.55

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.
@@ -1 +1 @@
1
- {"version":3,"file":"create-map.d.ts","sourceRoot":"","sources":["../../lib/map/create-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,eAAe,EACf,cAAc,EAEf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,GAAG,MAAM,WAAW,CAAC;AAC5B,OAAO,IAAI,MAAM,YAAY,CAAC;AAC9B,OAAO,KAAK,MAAM,mBAAmB,CAAC;AAsCtC,wBAAsB,WAAW,CAAC,UAAU,EAAE,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,CAyN7E;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,eAAe,EAC3B,aAAa,EAAE,MAAM,EACrB,kBAAkB,EAAE,eAAe,QAgBpC;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAkC3E;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,UAAU,EACnB,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAC5B,OAAO,CAAC,GAAG,CAAC,CAKd;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,GAAG,CAAC,CASd"}
1
+ {"version":3,"file":"create-map.d.ts","sourceRoot":"","sources":["../../lib/map/create-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,eAAe,EACf,cAAc,EAEf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,GAAG,MAAM,WAAW,CAAC;AAC5B,OAAO,IAAI,MAAM,YAAY,CAAC;AAC9B,OAAO,KAAK,MAAM,mBAAmB,CAAC;AA8CtC,wBAAsB,WAAW,CAAC,UAAU,EAAE,eAAe,GAAG,OAAO,CAAC,KAAK,CAAC,CAmO7E;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,eAAe,EAC3B,aAAa,EAAE,MAAM,EACrB,kBAAkB,EAAE,eAAe,QAgBpC;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAkC3E;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,UAAU,EACnB,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAC5B,OAAO,CAAC,GAAG,CAAC,CAKd;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,GAAG,CAAC,CASd"}
@@ -18,8 +18,15 @@ import { OgcApiEndpoint, WfsEndpoint, WmtsEndpoint, } from "@camptocamp/ogc-clie
18
18
  import { MapboxVectorLayer } from "ol-mapbox-style";
19
19
  import { handleEndpointError, tileLoadErrorCatchFunction, } from "./handle-errors.js";
20
20
  import VectorTile from "ol/source/VectorTile.js";
21
+ import GeoTIFF from "ol/source/GeoTIFF.js";
22
+ import WebGLTileLayer from "ol/layer/WebGLTile.js";
23
+ import proj4 from "proj4";
24
+ import { register } from "ol/proj/proj4.js";
21
25
  import { canDoIncrementalUpdate, updateLayerProperties, } from "./layer-update.js";
22
26
  import { initHoverLayer } from "./feature-hover.js";
27
+ // Register proj4 with OpenLayers so that arbitrary EPSG codes
28
+ // (e.g., UTM zones from GeoTIFF metadata) can be reprojected to the map projection
29
+ register(proj4);
23
30
  const GEOJSON = new GeoJSON();
24
31
  const WFS_MAX_FEATURES = 10000;
25
32
  export async function createLayer(layerModel) {
@@ -211,6 +218,16 @@ export async function createLayer(layerModel) {
211
218
  }
212
219
  break;
213
220
  }
221
+ case "geotiff": {
222
+ const geoTiffSource = new GeoTIFF({
223
+ sources: [{ url: layerModel.url }],
224
+ convertToRGB: "auto",
225
+ });
226
+ layer = new WebGLTileLayer({
227
+ source: geoTiffSource,
228
+ });
229
+ break;
230
+ }
214
231
  default:
215
232
  throw new Error(`Unrecognized layer type: ${JSON.stringify(layerModel)}`);
216
233
  }
@@ -1,5 +1,5 @@
1
- import type OlMap from "ol/Map.js";
2
1
  import VectorLayer from "ol/layer/Vector.js";
2
+ import type OlMap from "ol/Map.js";
3
3
  import VectorSource from "ol/source/Vector.js";
4
4
  export declare function initHoverLayer(map: OlMap): void;
5
5
  export declare function getHoverLayer(map: OlMap): VectorLayer<VectorSource>;
@@ -1 +1 @@
1
- {"version":3,"file":"feature-hover.d.ts","sourceRoot":"","sources":["../../lib/map/feature-hover.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,WAAW,CAAC;AACnC,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAC7C,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAe/C,wBAAgB,cAAc,CAAC,GAAG,EAAE,KAAK,QAoGxC;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,KAAK,GAAG,WAAW,CAAC,YAAY,CAAC,CAEnE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,KAAK,QAMzC"}
1
+ {"version":3,"file":"feature-hover.d.ts","sourceRoot":"","sources":["../../lib/map/feature-hover.ts"],"names":[],"mappings":"AAQA,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,KAAK,MAAM,WAAW,CAAC;AAEnC,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAO/C,wBAAgB,cAAc,CAAC,GAAG,EAAE,KAAK,QAoGxC;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,KAAK,GAAG,WAAW,CAAC,YAAY,CAAC,CAEnE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,KAAK,QAMzC"}
@@ -1,9 +1,9 @@
1
- import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
2
- import VectorLayer from "ol/layer/Vector.js";
3
- import VectorSource from "ol/source/Vector.js";
4
1
  import { defaultHighlightStyle, FeaturesHoverEventType, } from "@geospatial-sdk/core";
5
2
  import OlFeature from "ol/Feature.js";
3
+ import VectorLayer from "ol/layer/Vector.js";
6
4
  import { unByKey } from "ol/Observable.js";
5
+ import VectorSource from "ol/source/Vector.js";
6
+ import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
7
7
  import { readFeaturesAtPixel } from "./get-features.js";
8
8
  const hoverLayerKey = `${GEOSPATIAL_SDK_PREFIX}hover-layer`;
9
9
  const unsubscribeKey = `${GEOSPATIAL_SDK_PREFIX}hover-unsub`;
@@ -19,15 +19,15 @@ export function initHoverLayer(map) {
19
19
  }),
20
20
  style: defaultHighlightStyle,
21
21
  properties: {
22
- [`${GEOSPATIAL_SDK_PREFIX}enable-hover`]: false,
23
- [`${GEOSPATIAL_SDK_PREFIX}disable-click`]: true,
22
+ [`${GEOSPATIAL_SDK_PREFIX}hoverable`]: false,
23
+ [`${GEOSPATIAL_SDK_PREFIX}clickable`]: false,
24
24
  },
25
25
  });
26
26
  map.set(hoverLayerKey, hoverLayer);
27
27
  hoverLayer.setMap(map);
28
28
  // store original cursor style in order to change it later
29
29
  const originalCursorStyle = map.getTargetElement()?.style.cursor ?? "";
30
- const layerFilter = (layer) => layer.get(`${GEOSPATIAL_SDK_PREFIX}enable-hover`);
30
+ const layerFilter = (layer) => layer.get(`${GEOSPATIAL_SDK_PREFIX}hoverable`);
31
31
  const unKey = map.on("pointermove", async (event) => {
32
32
  // skip hit detection if the view is moving as it can have an impact on performance
33
33
  if (map.getView().getInteracting() || map.getView().getAnimating()) {
@@ -1 +1 @@
1
- {"version":3,"file":"layer-update.d.ts","sourceRoot":"","sources":["../../lib/map/layer-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAKhE,OAAO,KAAK,MAAM,mBAAmB,CAAC;AAsBtC;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAIT;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,KAAK,EACd,kBAAkB,CAAC,EAAE,eAAe,QAuDrC"}
1
+ {"version":3,"file":"layer-update.d.ts","sourceRoot":"","sources":["../../lib/map/layer-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAKhE,OAAO,KAAK,MAAM,mBAAmB,CAAC;AAsBtC;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAIT;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,KAAK,EACd,kBAAkB,CAAC,EAAE,eAAe,QAiDrC"}
@@ -7,8 +7,8 @@ const UPDATABLE_PROPERTIES = [
7
7
  "attributions",
8
8
  "extras",
9
9
  "version",
10
- "enableHover",
11
- "disableClick",
10
+ "hoverable",
11
+ "clickable",
12
12
  "style",
13
13
  "hoverStyle",
14
14
  // TODO (when available) "zIndex"
@@ -60,14 +60,14 @@ export function updateLayerProperties(layerModel, olLayer, previousLayerModel) {
60
60
  if (shouldApplyProperty("label")) {
61
61
  olLayer.set("label", layerModel.label);
62
62
  }
63
- if (shouldApplyProperty("enableHover")) {
64
- olLayer.set(`${GEOSPATIAL_SDK_PREFIX}enable-hover`, layerModel.enableHover);
63
+ if (shouldApplyProperty("hoverable")) {
64
+ olLayer.set(`${GEOSPATIAL_SDK_PREFIX}hoverable`, layerModel.hoverable);
65
65
  }
66
66
  if (shouldApplyProperty("hoverStyle")) {
67
67
  olLayer.set(`${GEOSPATIAL_SDK_PREFIX}hover-style`, layerModel.hoverStyle);
68
68
  }
69
- if (shouldApplyProperty("disableClick")) {
70
- olLayer.set(`${GEOSPATIAL_SDK_PREFIX}disable-click`, layerModel.disableClick);
69
+ if (shouldApplyProperty("clickable")) {
70
+ olLayer.set(`${GEOSPATIAL_SDK_PREFIX}clickable`, layerModel.clickable);
71
71
  }
72
72
  if (shouldApplyProperty("style") &&
73
73
  "setStyle" in olLayer) {
@@ -6,8 +6,8 @@ import { readFeaturesAtPixel } from "./get-features.js";
6
6
  function registerFeatureClickEvent(map) {
7
7
  if (map.get(FeaturesClickEventType))
8
8
  return;
9
- // Filter to only query layers with enableSelection
10
- const layerFilter = (layer) => !layer.get(`${GEOSPATIAL_SDK_PREFIX}disable-click`);
9
+ // Filter to only query clickable layers
10
+ const layerFilter = (layer) => layer.get(`${GEOSPATIAL_SDK_PREFIX}clickable`) !== false;
11
11
  map.on("click", async (event) => {
12
12
  const featuresByLayer = await readFeaturesAtPixel(map, event, layerFilter);
13
13
  const features = Array.from(featuresByLayer.values()).flat();
@@ -1,15 +1,13 @@
1
- import { FeatureCollection } from "geojson";
2
- import TileLayer from "ol/layer/Tile.js";
3
- import VectorLayer from "ol/layer/Vector.js";
4
- import Map from "ol/Map.js";
5
- import TileWMS from "ol/source/TileWMS.js";
6
- import VectorSource from "ol/source/Vector.js";
7
- import XYZ from "ol/source/XYZ.js";
8
- import View from "ol/View.js";
9
- import GeoJSON from "ol/format/GeoJSON.js";
1
+ import {
2
+ MapContext,
3
+ MapContextLayer,
4
+ MapContextLayerGeojson,
5
+ MapContextLayerWms,
6
+ } from "@geospatial-sdk/core";
10
7
  import {
11
8
  MAP_CTX_EXTENT_FIXTURE,
12
9
  MAP_CTX_FIXTURE,
10
+ MAP_CTX_LAYER_GEOTIFF_FIXTURE,
13
11
  MAP_CTX_LAYER_GEOJSON_FIXTURE,
14
12
  MAP_CTX_LAYER_GEOJSON_REMOTE_FIXTURE,
15
13
  MAP_CTX_LAYER_MAPBLIBRE_STYLE_FIXTURE,
@@ -20,31 +18,36 @@ import {
20
18
  MAP_CTX_LAYER_WMTS_FIXTURE,
21
19
  MAP_CTX_LAYER_XYZ_FIXTURE,
22
20
  } from "@geospatial-sdk/core/fixtures/map-context.fixtures.js";
23
- import {
24
- MapContext,
25
- MapContextLayer,
26
- MapContextLayerGeojson,
27
- MapContextLayerWms,
28
- } from "@geospatial-sdk/core";
21
+ import { FeatureCollection } from "geojson";
22
+ import { MapboxVectorLayer } from "ol-mapbox-style";
23
+ import { FeatureUrlFunction } from "ol/featureloader.js";
24
+ import GeoJSON from "ol/format/GeoJSON.js";
25
+ import ImageTile from "ol/ImageTile.js";
29
26
  import Layer from "ol/layer/Layer.js";
27
+ import TileLayer from "ol/layer/Tile.js";
28
+ import VectorLayer from "ol/layer/Vector.js";
29
+ import VectorTileLayer from "ol/layer/VectorTile.js";
30
+ import WebGLTileLayer from "ol/layer/WebGLTile.js";
31
+ import Map from "ol/Map.js";
32
+ import { VectorTile } from "ol/source.js";
33
+ import GeoTIFF from "ol/source/GeoTIFF.js";
34
+ import TileWMS from "ol/source/TileWMS.js";
35
+ import VectorSource from "ol/source/Vector.js";
36
+ import WMTS from "ol/source/WMTS.js";
37
+ import XYZ from "ol/source/XYZ.js";
38
+ import TileState from "ol/TileState.js";
39
+ import View from "ol/View.js";
40
+ import { beforeEach } from "vitest";
30
41
  import {
31
42
  createLayer,
32
43
  createMapFromContext,
33
44
  createView,
34
45
  resetMapFromContext,
35
46
  } from "./create-map.js";
36
- import WMTS from "ol/source/WMTS.js";
37
- import { VectorTile } from "ol/source.js";
38
- import { MapboxVectorLayer } from "ol-mapbox-style";
39
47
  import {
40
48
  handleEndpointError,
41
49
  tileLoadErrorCatchFunction,
42
50
  } from "./handle-errors.js";
43
- import ImageTile from "ol/ImageTile.js";
44
- import TileState from "ol/TileState.js";
45
- import VectorTileLayer from "ol/layer/VectorTile.js";
46
- import { FeatureUrlFunction } from "ol/featureloader.js";
47
- import { beforeEach } from "vitest";
48
51
 
49
52
  vi.mock("./handle-errors", async (importOriginal) => {
50
53
  const actual =
@@ -432,6 +435,26 @@ describe("MapContextService", () => {
432
435
  expect(layer.get("label")).toBeUndefined();
433
436
  });
434
437
  });
438
+
439
+ describe("GeoTIFF", () => {
440
+ beforeEach(async () => {
441
+ layerModel = MAP_CTX_LAYER_GEOTIFF_FIXTURE;
442
+ layer = await createLayer(layerModel);
443
+ });
444
+ it("create a WebGLTile layer", () => {
445
+ expect(layer).toBeTruthy();
446
+ expect(layer).toBeInstanceOf(WebGLTileLayer);
447
+ });
448
+ it("set correct layer properties", () => {
449
+ expect(layer.getVisible()).toBe(true);
450
+ expect(layer.getOpacity()).toBe(1);
451
+ expect(layer.get("label")).toBeUndefined();
452
+ });
453
+ it("create a GeoTIFF source", () => {
454
+ const source = layer.getSource();
455
+ expect(source).toBeInstanceOf(GeoTIFF);
456
+ });
457
+ });
435
458
  });
436
459
 
437
460
  describe("#createView", () => {
@@ -36,12 +36,20 @@ import {
36
36
  tileLoadErrorCatchFunction,
37
37
  } from "./handle-errors.js";
38
38
  import VectorTile from "ol/source/VectorTile.js";
39
+ import GeoTIFF from "ol/source/GeoTIFF.js";
40
+ import WebGLTileLayer from "ol/layer/WebGLTile.js";
41
+ import proj4 from "proj4";
42
+ import { register } from "ol/proj/proj4.js";
39
43
  import {
40
44
  canDoIncrementalUpdate,
41
45
  updateLayerProperties,
42
46
  } from "./layer-update.js";
43
47
  import { initHoverLayer } from "./feature-hover.js";
44
48
 
49
+ // Register proj4 with OpenLayers so that arbitrary EPSG codes
50
+ // (e.g., UTM zones from GeoTIFF metadata) can be reprojected to the map projection
51
+ register(proj4);
52
+
45
53
  const GEOJSON = new GeoJSON();
46
54
  const WFS_MAX_FEATURES = 10000;
47
55
 
@@ -252,6 +260,16 @@ export async function createLayer(layerModel: MapContextLayer): Promise<Layer> {
252
260
  }
253
261
  break;
254
262
  }
263
+ case "geotiff": {
264
+ const geoTiffSource = new GeoTIFF({
265
+ sources: [{ url: layerModel.url }],
266
+ convertToRGB: "auto",
267
+ });
268
+ layer = new WebGLTileLayer({
269
+ source: geoTiffSource,
270
+ });
271
+ break;
272
+ }
255
273
  default:
256
274
  throw new Error(`Unrecognized layer type: ${JSON.stringify(layerModel)}`);
257
275
  }
@@ -1,16 +1,16 @@
1
- import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
2
- import type OlMap from "ol/Map.js";
3
- import VectorLayer from "ol/layer/Vector.js";
4
- import VectorSource from "ol/source/Vector.js";
5
1
  import {
6
2
  defaultHighlightStyle,
7
3
  FeaturesHoverEventType,
8
4
  } from "@geospatial-sdk/core";
9
- import type BaseEvent from "ol/events/Event.js";
10
5
  import { MapBrowserEvent } from "ol";
6
+ import type BaseEvent from "ol/events/Event.js";
11
7
  import OlFeature from "ol/Feature.js";
12
8
  import type BaseLayer from "ol/layer/Base.js";
9
+ import VectorLayer from "ol/layer/Vector.js";
10
+ import type OlMap from "ol/Map.js";
13
11
  import { unByKey } from "ol/Observable.js";
12
+ import VectorSource from "ol/source/Vector.js";
13
+ import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
14
14
  import { readFeaturesAtPixel } from "./get-features.js";
15
15
 
16
16
  const hoverLayerKey = `${GEOSPATIAL_SDK_PREFIX}hover-layer`;
@@ -29,8 +29,8 @@ export function initHoverLayer(map: OlMap) {
29
29
  }),
30
30
  style: defaultHighlightStyle,
31
31
  properties: {
32
- [`${GEOSPATIAL_SDK_PREFIX}enable-hover`]: false,
33
- [`${GEOSPATIAL_SDK_PREFIX}disable-click`]: true,
32
+ [`${GEOSPATIAL_SDK_PREFIX}hoverable`]: false,
33
+ [`${GEOSPATIAL_SDK_PREFIX}clickable`]: false,
34
34
  },
35
35
  });
36
36
  map.set(hoverLayerKey, hoverLayer);
@@ -40,7 +40,7 @@ export function initHoverLayer(map: OlMap) {
40
40
  const originalCursorStyle = map.getTargetElement()?.style.cursor ?? "";
41
41
 
42
42
  const layerFilter = (layer: BaseLayer) =>
43
- layer.get(`${GEOSPATIAL_SDK_PREFIX}enable-hover`);
43
+ layer.get(`${GEOSPATIAL_SDK_PREFIX}hoverable`);
44
44
 
45
45
  const unKey = map.on(
46
46
  "pointermove",
@@ -125,8 +125,8 @@ describe("Layer update utils", () => {
125
125
  style: {
126
126
  "circle-fill-color": "blue",
127
127
  },
128
- enableHover: true,
129
- disableClick: true,
128
+ hoverable: true,
129
+ clickable: false,
130
130
  };
131
131
  const prevLayerModel = SAMPLE_LAYER3;
132
132
  updateLayerProperties(layerModel, olLayer, prevLayerModel);
@@ -134,12 +134,12 @@ describe("Layer update utils", () => {
134
134
  layerModel.style,
135
135
  );
136
136
  expect(olLayer.set).toHaveBeenCalledWith(
137
- "--geospatial-sdk-enable-hover",
137
+ "--geospatial-sdk-hoverable",
138
138
  true,
139
139
  );
140
140
  expect(olLayer.set).toHaveBeenCalledWith(
141
- "--geospatial-sdk-disable-click",
142
- true,
141
+ "--geospatial-sdk-clickable",
142
+ false,
143
143
  );
144
144
  });
145
145
  });
@@ -4,9 +4,9 @@ import {
4
4
  MapContextLayerVector,
5
5
  } from "@geospatial-sdk/core/lib/model/map-context.js";
6
6
  import Layer from "ol/layer/Layer.js";
7
- import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
8
7
  import VectorLayer from "ol/layer/Vector.js";
9
8
  import type VectorSource from "ol/source/Vector.js";
9
+ import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
10
10
 
11
11
  const UPDATABLE_PROPERTIES: (
12
12
  | keyof MapContextBaseLayer
@@ -18,8 +18,8 @@ const UPDATABLE_PROPERTIES: (
18
18
  "attributions",
19
19
  "extras",
20
20
  "version",
21
- "enableHover",
22
- "disableClick",
21
+ "hoverable",
22
+ "clickable",
23
23
  "style",
24
24
  "hoverStyle",
25
25
  // TODO (when available) "zIndex"
@@ -82,11 +82,8 @@ export function updateLayerProperties(
82
82
  if (shouldApplyProperty("label")) {
83
83
  olLayer.set("label", layerModel.label);
84
84
  }
85
- if (shouldApplyProperty("enableHover" as keyof MapContextLayer)) {
86
- olLayer.set(
87
- `${GEOSPATIAL_SDK_PREFIX}enable-hover`,
88
- (layerModel as MapContextLayerVector).enableHover,
89
- );
85
+ if (shouldApplyProperty("hoverable")) {
86
+ olLayer.set(`${GEOSPATIAL_SDK_PREFIX}hoverable`, layerModel.hoverable);
90
87
  }
91
88
  if (shouldApplyProperty("hoverStyle" as keyof MapContextLayer)) {
92
89
  olLayer.set(
@@ -94,11 +91,8 @@ export function updateLayerProperties(
94
91
  (layerModel as MapContextLayerVector).hoverStyle,
95
92
  );
96
93
  }
97
- if (shouldApplyProperty("disableClick" as keyof MapContextLayer)) {
98
- olLayer.set(
99
- `${GEOSPATIAL_SDK_PREFIX}disable-click`,
100
- layerModel.disableClick,
101
- );
94
+ if (shouldApplyProperty("clickable" as keyof MapContextLayer)) {
95
+ olLayer.set(`${GEOSPATIAL_SDK_PREFIX}clickable`, layerModel.clickable);
102
96
  }
103
97
  if (
104
98
  shouldApplyProperty("style" as keyof MapContextLayer) &&
@@ -19,9 +19,9 @@ import { readFeaturesAtPixel } from "./get-features.js";
19
19
  function registerFeatureClickEvent(map: Map) {
20
20
  if (map.get(FeaturesClickEventType)) return;
21
21
 
22
- // Filter to only query layers with enableSelection
22
+ // Filter to only query clickable layers
23
23
  const layerFilter = (layer: BaseLayer) =>
24
- !layer.get(`${GEOSPATIAL_SDK_PREFIX}disable-click`);
24
+ layer.get(`${GEOSPATIAL_SDK_PREFIX}clickable`) !== false;
25
25
 
26
26
  map.on("click", async (event: any) => {
27
27
  const featuresByLayer = await readFeaturesAtPixel(map, event, layerFilter);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geospatial-sdk/openlayers",
3
- "version": "0.0.5-dev.53+85f2d77",
3
+ "version": "0.0.5-dev.55+475f057",
4
4
  "description": "OpenLayers-related utilities",
5
5
  "keywords": [
6
6
  "ol",
@@ -37,10 +37,9 @@
37
37
  "ol": ">9.x"
38
38
  },
39
39
  "dependencies": {
40
- "@geospatial-sdk/core": "^0.0.5-dev.53+85f2d77",
41
- "chroma-js": "^2.4.2",
40
+ "@geospatial-sdk/core": "^0.0.5-dev.55+475f057",
42
41
  "lodash.throttle": "^4.1.1",
43
42
  "ol-mapbox-style": "12.4.0"
44
43
  },
45
- "gitHead": "85f2d770cbe0bf97a4c2c5e0650fe7712f3396c8"
44
+ "gitHead": "475f057bccd243497d84db212b50812633e7398b"
46
45
  }
@@ -1,8 +0,0 @@
1
- import type OlMap from "ol/Map.js";
2
- import VectorLayer from "ol/layer/Vector.js";
3
- import VectorSource from "ol/source/Vector.js";
4
- export declare function initSelectionLayer(map: OlMap): void;
5
- export declare function getSelectionLayer(map: OlMap): VectorLayer<VectorSource>;
6
- export declare function clearSelectionLayer(map: OlMap): void;
7
- export declare function clearSelection(map: OlMap): void;
8
- //# sourceMappingURL=feature-selection.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"feature-selection.d.ts","sourceRoot":"","sources":["../../lib/map/feature-selection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,WAAW,CAAC;AACnC,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAC7C,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAU/C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,KAAK,QAqE5C;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,KAAK,GAAG,WAAW,CAAC,YAAY,CAAC,CAEvE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,KAAK,QAM7C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,KAAK,QAQxC"}
@@ -1,76 +0,0 @@
1
- import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
2
- import VectorLayer from "ol/layer/Vector.js";
3
- import VectorSource from "ol/source/Vector.js";
4
- import { defaultHighlightStyle } from "@geospatial-sdk/core";
5
- import OlFeature from "ol/Feature.js";
6
- import { unByKey } from "ol/Observable.js";
7
- const selectionLayerKey = `${GEOSPATIAL_SDK_PREFIX}selection-layer`;
8
- const unsubscribeKey = `${GEOSPATIAL_SDK_PREFIX}selection-unsub`;
9
- export function initSelectionLayer(map) {
10
- if (map.get(selectionLayerKey)) {
11
- clearSelectionLayer(map);
12
- }
13
- // create layer & add on top of everything else
14
- const selectionLayer = new VectorLayer({
15
- source: new VectorSource({
16
- features: [],
17
- useSpatialIndex: false,
18
- }),
19
- style: defaultHighlightStyle,
20
- });
21
- map.set(selectionLayerKey, selectionLayer);
22
- selectionLayer.setMap(map);
23
- const layerFilter = (layer) => layer !== selectionLayer &&
24
- layer.get(`${GEOSPATIAL_SDK_PREFIX}enable-selection`);
25
- const unKey = map.on("click", async (event) => {
26
- const selectedSource = selectionLayer.getSource();
27
- selectedSource.clear(true);
28
- // Check if there's a feature at the clicked pixel
29
- const hasFeature = map.hasFeatureAtPixel(event.pixel, {
30
- layerFilter,
31
- });
32
- if (!hasFeature) {
33
- return;
34
- }
35
- // Find the selected feature and its source layer
36
- const selectedFeatureResult = [];
37
- map.forEachFeatureAtPixel(event.pixel, (feature, layer) => {
38
- if (feature instanceof OlFeature) {
39
- selectedFeatureResult.push({ feature, layer });
40
- return true;
41
- }
42
- }, {
43
- layerFilter,
44
- });
45
- if (selectedFeatureResult.length === 0) {
46
- return;
47
- }
48
- const { feature: firstFeature, layer: sourceLayer } = selectedFeatureResult[0];
49
- // Get the selectedStyle from the source layer, fallback to defaultHighlightStyle
50
- const selectedStyle = sourceLayer.get(`${GEOSPATIAL_SDK_PREFIX}selected-style`) ??
51
- defaultHighlightStyle;
52
- // Apply the selected style to the layer (FlatStyleLike works on layers, not features)
53
- selectionLayer.setStyle(selectedStyle);
54
- selectedSource.addFeature(firstFeature);
55
- });
56
- map.set(unsubscribeKey, unKey);
57
- }
58
- export function getSelectionLayer(map) {
59
- return map.get(selectionLayerKey);
60
- }
61
- export function clearSelectionLayer(map) {
62
- const selectionLayer = getSelectionLayer(map);
63
- selectionLayer.setMap(null);
64
- selectionLayer.dispose();
65
- map.set(selectionLayerKey, null);
66
- unByKey(map.get(unsubscribeKey));
67
- }
68
- export function clearSelection(map) {
69
- const selectionLayer = getSelectionLayer(map);
70
- if (selectionLayer) {
71
- const source = selectionLayer.getSource();
72
- if (source) {
73
- source.clear(true);
74
- }
75
- }
76
- }
@@ -1,4 +0,0 @@
1
- import Map from "ol/Map.js";
2
- import { MapEventsByType } from "@geospatial-sdk/core";
3
- export declare function listen<T extends keyof MapEventsByType>(map: Map, eventType: T, callback: (event: MapEventsByType[T]) => void): void;
4
- //# sourceMappingURL=listen.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"listen.d.ts","sourceRoot":"","sources":["../../lib/map/listen.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,WAAW,CAAC;AAG5B,OAAO,EAKL,eAAe,EAShB,MAAM,sBAAsB,CAAC;AA6B9B,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,eAAe,EACpD,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,CAAC,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,QA+E9C"}
@@ -1,83 +0,0 @@
1
- import { toLonLat } from "ol/proj.js";
2
- import { FeaturesClickEventType, FeaturesHoverEventType, MapClickEventType, MapExtentChangeEventType, MapLayerStateChangeEventType, MapStateChangeEventType, MapViewStateChangeEventType, SourceLoadErrorType, } from "@geospatial-sdk/core";
3
- import { GEOSPATIAL_SDK_PREFIX } from "./constants.js";
4
- import { registerFeatureClickEvent, registerFeatureHoverEvent, registerMapViewStateChangeEvent, } from "./register-events.js";
5
- function addEventListener(map, eventType, callback) {
6
- map.on(`${GEOSPATIAL_SDK_PREFIX}${eventType}`, ({ target: _target, ...event }) =>
7
- // we're excluding the `target` property and renaming the `type` here
8
- callback({
9
- ...event,
10
- type: eventType,
11
- }));
12
- }
13
- export function listen(map, eventType, callback) {
14
- switch (eventType) {
15
- case FeaturesClickEventType:
16
- registerFeatureClickEvent(map);
17
- addEventListener(map, eventType, callback);
18
- break;
19
- case FeaturesHoverEventType:
20
- registerFeatureHoverEvent(map);
21
- addEventListener(map, eventType, callback);
22
- break;
23
- case MapClickEventType:
24
- map.on("click", (event) => {
25
- const coordinate = toLonLat(event.coordinate, map.getView().getProjection());
26
- callback({
27
- type: MapClickEventType,
28
- coordinate,
29
- });
30
- });
31
- break;
32
- case MapViewStateChangeEventType:
33
- registerMapViewStateChangeEvent(map);
34
- addEventListener(map, eventType, callback);
35
- break;
36
- case MapLayerStateChangeEventType:
37
- // TODO: registerMapLayerStateChangeEvent(map);
38
- addEventListener(map, eventType, callback);
39
- break;
40
- case MapStateChangeEventType:
41
- // TODO: registerMapStateChangeEvent(map);
42
- addEventListener(map, eventType, callback);
43
- break;
44
- /**
45
- * DEPRECATED
46
- */
47
- case MapExtentChangeEventType:
48
- registerMapViewStateChangeEvent(map);
49
- map.on(`${GEOSPATIAL_SDK_PREFIX}${MapViewStateChangeEventType}`, (event) => callback({
50
- type: MapExtentChangeEventType,
51
- extent: event.viewState.extent,
52
- }));
53
- break;
54
- case SourceLoadErrorType: {
55
- const errorCallback = (event) => {
56
- callback(event);
57
- };
58
- //attach event listener to all existing layers
59
- map.getLayers().forEach((layer) => {
60
- if (layer) {
61
- layer.on(SourceLoadErrorType, errorCallback);
62
- }
63
- });
64
- //attach event listener when layer is added
65
- map.getLayers().on("add", (event) => {
66
- const layer = event.element;
67
- if (layer) {
68
- layer.on(SourceLoadErrorType, errorCallback);
69
- }
70
- });
71
- //remove event listener when layer is removed
72
- map.getLayers().on("remove", (event) => {
73
- const layer = event.element;
74
- if (layer) {
75
- layer.un(SourceLoadErrorType, errorCallback);
76
- }
77
- });
78
- break;
79
- }
80
- default:
81
- throw new Error(`Unrecognized event type: ${eventType}`);
82
- }
83
- }
@@ -1,8 +0,0 @@
1
- import Map from "ol/Map.js";
2
- import { ResolvedMapViewState } from "@geospatial-sdk/core";
3
- /**
4
- * Reads the current view state of the map.
5
- * @param map
6
- */
7
- export declare function readMapViewState(map: Map): ResolvedMapViewState;
8
- //# sourceMappingURL=resolved-map-state.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolved-map-state.d.ts","sourceRoot":"","sources":["../../lib/map/resolved-map-state.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,WAAW,CAAC;AAE5B,OAAO,EAAU,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAIpE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,oBAAoB,CAgB/D"}
@@ -1,27 +0,0 @@
1
- import { transform as transformCoordinate, transformExtent } from "ol/proj.js";
2
- /**
3
- * This magic value is generally used across OGC services as a reasonable approximation for most displays
4
- */
5
- const PIXEL_SIZE_MM = 0.28;
6
- /**
7
- * Reads the current view state of the map.
8
- * @param map
9
- */
10
- export function readMapViewState(map) {
11
- const view = map.getView();
12
- const projection = view.getProjection();
13
- const extent = transformExtent(view.calculateExtent(), projection, "EPSG:4326");
14
- const center = transformCoordinate(view.getCenter() ?? [0, 0], projection, "EPSG:4326");
15
- const resolution = view.getResolution() ?? 1;
16
- const metersPerUnit = projection.getMetersPerUnit() ?? 1;
17
- const scaleDenominator = metersPerUnit * resolution * (1000 / PIXEL_SIZE_MM);
18
- const bearing = view.getRotation() * (180 / Math.PI) + 90; // by default, bearing is North
19
- return {
20
- center,
21
- extent,
22
- resolution,
23
- scaleDenominator,
24
- bearing,
25
- };
26
- }
27
- export function processLayerEvent(map, layer) { }
@@ -1,16 +0,0 @@
1
- import { Style } from "ol/style.js";
2
- import { StyleFunction } from "ol/style/Style.js";
3
- export interface CreateStyleOptions {
4
- color: string;
5
- isFocused?: boolean;
6
- }
7
- export interface StyleByGeometryType {
8
- line: Style | Style[];
9
- polygon: Style | Style[];
10
- point: Style | Style[];
11
- }
12
- export declare function createGeometryStyles(options: CreateStyleOptions): StyleByGeometryType;
13
- export declare function createStyleFunction(styleByGeometryType: StyleByGeometryType): StyleFunction;
14
- export declare const defaultStyle: StyleFunction;
15
- export declare const defaultHighlightStyle: StyleFunction;
16
- //# sourceMappingURL=styles.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../lib/map/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAIlD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;IACtB,OAAO,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;IACzB,KAAK,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;CACxB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,kBAAkB,GAC1B,mBAAmB,CA4CrB;AAED,wBAAgB,mBAAmB,CACjC,mBAAmB,EAAE,mBAAmB,GACvC,aAAa,CAmBf;AAMD,eAAO,MAAM,YAAY,eAIxB,CAAC;AAEF,eAAO,MAAM,qBAAqB,eAKjC,CAAC"}
@@ -1,77 +0,0 @@
1
- import { Circle, Fill, Stroke, Style } from "ol/style.js";
2
- import chroma from "chroma-js";
3
- export function createGeometryStyles(options) {
4
- const { color, isFocused } = options;
5
- const zIndex = isFocused ? 10 : undefined;
6
- return {
7
- polygon: new Style({
8
- fill: new Fill({
9
- color: computeTransparentFillColor(color),
10
- }),
11
- stroke: new Stroke({
12
- color: "white",
13
- width: 2,
14
- }),
15
- zIndex,
16
- }),
17
- point: new Style({
18
- image: new Circle({
19
- fill: new Fill({
20
- color,
21
- }),
22
- stroke: new Stroke({
23
- color: "white",
24
- width: isFocused ? 3 : 2,
25
- }),
26
- radius: isFocused ? 8 : 7,
27
- }),
28
- zIndex,
29
- }),
30
- line: [
31
- new Style({
32
- stroke: new Stroke({
33
- color: "white",
34
- width: isFocused ? 8 : 6,
35
- }),
36
- zIndex,
37
- }),
38
- new Style({
39
- stroke: new Stroke({
40
- color,
41
- width: isFocused ? 3 : 2,
42
- }),
43
- zIndex,
44
- }),
45
- ],
46
- };
47
- }
48
- export function createStyleFunction(styleByGeometryType) {
49
- return (feature) => {
50
- const geometryType = feature?.getGeometry()?.getType();
51
- switch (geometryType) {
52
- case "LinearRing":
53
- case "LineString":
54
- case "MultiLineString":
55
- return styleByGeometryType.line;
56
- case "Point":
57
- case "MultiPoint":
58
- return styleByGeometryType.point;
59
- case "Circle":
60
- case "Polygon":
61
- case "MultiPolygon":
62
- return styleByGeometryType.polygon;
63
- default:
64
- return styleByGeometryType.point;
65
- }
66
- };
67
- }
68
- function computeTransparentFillColor(color, alpha = 0.25) {
69
- return chroma(color).alpha(alpha).css();
70
- }
71
- export const defaultStyle = createStyleFunction(createGeometryStyles({
72
- color: "blue",
73
- }));
74
- export const defaultHighlightStyle = createStyleFunction(createGeometryStyles({
75
- color: "red",
76
- isFocused: true,
77
- }));
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=resolved-map-state.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolved-map-state.d.ts","sourceRoot":"","sources":["../../lib/resolved-state/resolved-map-state.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- export {};