From 187dcc18d0f09b834774b74b32244113d6aa3daf Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sat, 2 Sep 2023 12:20:17 +0200 Subject: [PATCH] Customisable map styling --- .../src/org.argeo.app.geo.js/MapPart.js | 46 +++++++++++++++ .../org.argeo.app.geo.js/OpenLayersMapPart.js | 48 ++++++++++++--- .../src/org.argeo.app.geo.js/index.html | 7 --- .../src/org/argeo/app/geo/ux/MapPart.java | 3 +- .../internal/geo/http/GeoJsonHttpHandler.java | 58 +++++++++++++++---- .../org/argeo/app/geo/swt/MapUiProvider.java | 4 +- .../org/argeo/app/geo/swt/SwtJSMapPart.java | 52 +++++++++++------ 7 files changed, 169 insertions(+), 49 deletions(-) diff --git a/org.argeo.app.geo.js/src/org.argeo.app.geo.js/MapPart.js b/org.argeo.app.geo.js/src/org.argeo.app.geo.js/MapPart.js index ef19f58..6635b08 100644 --- a/org.argeo.app.geo.js/src/org.argeo.app.geo.js/MapPart.js +++ b/org.argeo.app.geo.js/src/org.argeo.app.geo.js/MapPart.js @@ -5,6 +5,18 @@ /** Abstract base class for displaying a map. */ export default class MapPart { + /** The name of the map, will also be the name of the variable */ + #mapName; + + constructor(mapName) { + this.#mapName = mapName; + this.createMapDiv(this.#mapName); + } + + // + // ABSTRACT METHODS + // + /** Zoom the map to the given value. */ setZoom(zoom) { throw new Error("Abstract method"); @@ -23,4 +35,38 @@ export default class MapPart { addUrlLayer(url, format) { throw new Error("Abstract method"); } + + // + // EXTENSIONS + // + loadMapModule(url) { + var script = document.createElement("script"); + script.src = url; + document.head.appendChild(script); + // import(url) + // .then(module => { }) + // .catch((error) => 'An error occurred while loading the component'); + } + + // + // AcCESSORS + // + getMapName() { + return this.#mapName; + } + + // + // HTML + // + createMapDiv(id) { + var mapDiv = document.createElement('div'); + mapDiv.id = id; + mapDiv.className = this.getMapDivCssClass(); + mapDiv.style.cssText = 'width: 100%; height: 100vh;'; + document.body.appendChild(mapDiv); + } + + getMapDivCssClass() { + throw new Error("Abstract method"); + } } diff --git a/org.argeo.app.geo.js/src/org.argeo.app.geo.js/OpenLayersMapPart.js b/org.argeo.app.geo.js/src/org.argeo.app.geo.js/OpenLayersMapPart.js index b2d0911..8206d4f 100644 --- a/org.argeo.app.geo.js/src/org.argeo.app.geo.js/OpenLayersMapPart.js +++ b/org.argeo.app.geo.js/src/org.argeo.app.geo.js/OpenLayersMapPart.js @@ -3,6 +3,7 @@ */ import Map from 'ol/Map.js'; +import View from 'ol/View.js'; import OSM from 'ol/source/OSM.js'; import TileLayer from 'ol/layer/Tile.js'; import { fromLonLat } from 'ol/proj.js'; @@ -14,6 +15,7 @@ import GeoJSON from 'ol/format/GeoJSON.js'; import GPX from 'ol/format/GPX.js'; import Select from 'ol/interaction/Select.js'; import Overlay from 'ol/Overlay.js'; +import { Style, Icon } from 'ol/style.js'; import MapPart from './MapPart.js'; import { SentinelCloudless } from './OpenLayerTileSources.js'; @@ -22,23 +24,25 @@ import { SentinelCloudless } from './OpenLayerTileSources.js'; export default class OpenLayersMapPart extends MapPart { /** The OpenLayers Map. */ #map; + + /** Externally added callback functions. */ callbacks = {}; - // Constructor - constructor() { - super(); + /** Constructor taking the mapName as an argument. */ + constructor(mapName) { + super(mapName); this.#map = new Map({ layers: [ - new TileLayer({ - source: new SentinelCloudless(), - }), + // new TileLayer({ + // source: new SentinelCloudless(), + // }), new TileLayer({ source: new OSM(), opacity: 0.4, transition: 0, }), ], - target: 'map', + target: this.getMapName(), }); } @@ -58,10 +62,13 @@ export default class OpenLayersMapPart extends MapPart { geometry: new Point(fromLonLat([lng, lat])) })] }); - this.#map.addLayer(new VectorLayer({ source: vectorSource })); + this.#map.addLayer(new VectorLayer({ + source: vectorSource, + style: style, + })); } - addUrlLayer(url, format) { + addUrlLayer(url, format, style) { let vectorSource; if (format === 'GEOJSON') { vectorSource = new VectorSource({ url: url, format: new GeoJSON() }) @@ -71,6 +78,7 @@ export default class OpenLayersMapPart extends MapPart { } this.#map.addLayer(new VectorLayer({ source: vectorSource, + style: style, })); } @@ -143,6 +151,8 @@ export default class OpenLayersMapPart extends MapPart { } const coordinate = e.coordinate; const path = selected.get('path'); + if (path === null) + return true; const res = mapPart.callbacks['onFeaturePopup'](path); if (res != null) { content.innerHTML = res; @@ -152,4 +162,24 @@ export default class OpenLayersMapPart extends MapPart { } }); } + + // + // HTML + // + getMapDivCssClass() { + return 'map'; + } + + // + // STATIC FOR EXTENSION + // + static newStyle(args){ + return new Style(args); + } + + static newIcon(args){ + return new Icon(args); + } + + } diff --git a/org.argeo.app.geo.js/src/org.argeo.app.geo.js/index.html b/org.argeo.app.geo.js/src/org.argeo.app.geo.js/index.html index 12fa0a1..bafe7fe 100644 --- a/org.argeo.app.geo.js/src/org.argeo.app.geo.js/index.html +++ b/org.argeo.app.geo.js/src/org.argeo.app.geo.js/index.html @@ -4,11 +4,6 @@