X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.app.geo.js%2Fsrc%2Forg.argeo.app.geo.js%2FOpenLayersMapPart.js;h=13597fa8cfe8c61c06c4545e704e069a89d847ec;hb=10ada90446095744f4ed73798936de9d0ed415bd;hp=b2d09115f94309e890f5d31936f0b3f857d9c65a;hpb=21433ef7b049abb44bbd3c815b6724a15912accf;p=gpl%2Fargeo-suite.git 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..13597fa 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,9 +3,10 @@ */ 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'; +import { fromLonLat, getPointResolution } from 'ol/proj.js'; import VectorSource from 'ol/source/Vector.js'; import Feature from 'ol/Feature.js'; import { Point } from 'ol/geom.js'; @@ -14,6 +15,9 @@ 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 * as SLDReader from '@nieuwlandgeo/sldreader'; import MapPart from './MapPart.js'; import { SentinelCloudless } from './OpenLayerTileSources.js'; @@ -22,23 +26,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,22 +64,38 @@ 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) { - let vectorSource; + addUrlLayer(url, format, style, sld) { + let featureFormat; if (format === 'GEOJSON') { - vectorSource = new VectorSource({ url: url, format: new GeoJSON() }) + featureFormat = new GeoJSON(); } else if (format === 'GPX') { - vectorSource = new VectorSource({ url: url, format: new GPX() }) + featureFormat = new GPX(); + } else { + throw new Error("Unsupported format " + format); } - this.#map.addLayer(new VectorLayer({ + const vectorSource = new VectorSource({ + url: url, + format: featureFormat, + }); + const vectorLayer = new VectorLayer({ source: vectorSource, - })); + }); + if (sld) { + this.#applySLD(vectorLayer, style); + } else { + vectorLayer.setStyle(style); + } + this.#map.addLayer(vectorLayer); } + /* CALLBACKS */ enableFeatureSingleClick() { // we cannot use 'this' in the function provided to OpenLayers @@ -143,6 +165,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 +176,50 @@ 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); + } + + // + // SLD STYLING + // + #applySLD(vectorLayer, text) { + const sldObject = SLDReader.Reader(text); + const sldLayer = SLDReader.getLayer(sldObject); + const style = SLDReader.getStyle(sldLayer); + const featureTypeStyle = style.featuretypestyles[0]; + + const viewProjection = this.#map.getView().getProjection(); + const olStyleFunction = SLDReader.createOlStyleFunction(featureTypeStyle, { + // Use the convertResolution option to calculate a more accurate resolution. + convertResolution: viewResolution => { + const viewCenter = this.#map.getView().getCenter(); + return getPointResolution(viewProjection, viewResolution, viewCenter); + }, + // If you use point icons with an ExternalGraphic, you have to use imageLoadCallback + // to update the vector layer when an image finishes loading. + // If you do not do this, the image will only be visible after next layer pan/zoom. + imageLoadedCallback: () => { + vectorLayer.changed(); + }, + }); + vectorLayer.setStyle(olStyleFunction); + } + + }