X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=js%2Fsrc%2Fgeo%2FOpenLayersMapPart.js;h=6fedd7a2a382f9f6d8b77de9cbfae761a96b72cb;hb=6e13b9416a5fd1f5477eb7233f86d3eacbb88c55;hp=177ce33862919d750769ae9029e187d1467df6db;hpb=59da7271e876ca8a429beb86b67e7350eef1e1ca;p=gpl%2Fargeo-suite.git diff --git a/js/src/geo/OpenLayersMapPart.js b/js/src/geo/OpenLayersMapPart.js index 177ce33..6fedd7a 100644 --- a/js/src/geo/OpenLayersMapPart.js +++ b/js/src/geo/OpenLayersMapPart.js @@ -2,21 +2,27 @@ * @module OpenLayersMapPart */ -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, getPointResolution } from 'ol/proj.js'; -import VectorSource from 'ol/source/Vector.js'; import Feature from 'ol/Feature.js'; import { Point } from 'ol/geom.js'; +import { transformExtent } from 'ol/proj.js'; + import VectorLayer from 'ol/layer/Vector.js'; +import TileLayer from 'ol/layer/Tile.js'; + +import VectorSource from 'ol/source/Vector.js'; import GeoJSON from 'ol/format/GeoJSON.js'; import GPX from 'ol/format/GPX.js'; +import OSM from 'ol/source/OSM.js'; + import Select from 'ol/interaction/Select.js'; import Overlay from 'ol/Overlay.js'; import { Style, Icon } from 'ol/style.js'; +import Map from 'ol/Map.js'; +import View from 'ol/View.js'; +import { OverviewMap, ScaleLine, defaults as defaultControls } from 'ol/control.js'; + import * as SLDReader from '@nieuwlandgeo/sldreader'; import MapPart from './MapPart.js'; @@ -26,29 +32,49 @@ export default class OpenLayersMapPart extends MapPart { /** The OpenLayers Map. */ #map; + #overviewMap; + + select; + + /** Styled layer descriptor */ + #sld; + /** Externally added callback functions. */ callbacks = {}; /** Constructor taking the mapName as an argument. */ constructor(mapName) { super(mapName); + this.#overviewMap = new OverviewMap({ + layers: [ + new TileLayer({ + source: new OSM(), + }), + ], + }); + this.select = new Select(); this.#map = new Map({ + controls: defaultControls({ + attribution: false, + rotate: false, + }).extend([this.#overviewMap, new ScaleLine({ + bar: false, + steps: 2, + text: false, + minWidth: 150, + maxWidth: 200, + })]), layers: [ - // new TileLayer({ - // source: new SentinelCloudless(), - // }), -// new TileLayer({ -// source: new OSM(), -// opacity: 0.4, -// transition: 0, -// }), ], -// view: new View({ -// center: [0, 0], -// zoom: 2, -// }), + // view: new View({ + // projection: 'EPSG:4326', + // center: [0, 0], + // zoom: 2, + // }), target: this.getMapName(), }); + this.#map.addInteraction(this.select); + //this.#map.getView().set('projection', 'EPSG:4326', true); } /* GEOGRAPHICAL METHODS */ @@ -57,8 +83,13 @@ export default class OpenLayersMapPart extends MapPart { this.#map.getView().setZoom(zoom); } - setCenter(lng, lat) { - this.#map.getView().setCenter(fromLonLat([lng, lat])); + setCenter(lat, lon) { + this.#map.getView().setCenter(fromLonLat([lon, lat])); + } + + fit(extent, options) { + var transformed = transformExtent(extent, 'EPSG:4326', this.#map.getView().getProjection()); + this.#map.getView().fit(transformed, options); } addPoint(lng, lat, style) { @@ -108,6 +139,19 @@ export default class OpenLayersMapPart extends MapPart { return this.#map; } + getLayerByName(name) { + let layers = this.#map.getLayers(); + for (let i = 0; i < layers.getLength(); i++) { + let layer = layers.item(i); + let n = layer.get('name'); + if (n !== undefined) { + if (name === n) + return layer; + } + } + return undefined; + } + /* CALLBACKS */ enableFeatureSingleClick() { // we cannot use 'this' in the function provided to OpenLayers @@ -120,7 +164,7 @@ export default class OpenLayersMapPart extends MapPart { return true; }); if (feature !== null) - mapPart.callbacks['onFeatureSingleClick'](feature.get('path')); + mapPart.callbacks['onFeatureSingleClick'](feature.get('cr:path')); }); } @@ -132,7 +176,7 @@ export default class OpenLayersMapPart extends MapPart { select.on('select', function(e) { if (e.selected.length > 0) { let feature = e.selected[0]; - mapPart.callbacks['onFeatureSelected'](feature.get('path')); + mapPart.callbacks['onFeatureSelected'](feature.get('cr:path')); } }); } @@ -176,7 +220,7 @@ export default class OpenLayersMapPart extends MapPart { return; } const coordinate = e.coordinate; - const path = selected.get('path'); + const path = selected.get('cr:path'); if (path === null) return true; const res = mapPart.callbacks['onFeaturePopup'](path); @@ -196,6 +240,26 @@ export default class OpenLayersMapPart extends MapPart { return 'map'; } + selectFeatures(layerName, featureIds) { + // we cannot use 'this' in the function provided to OpenLayers + let mapPart = this; + this.select.getFeatures().clear(); + const layer = this.getLayerByName(layerName); + const source = layer.getSource(); + for (const featureId of featureIds) { + let feature = source.getFeatureById(featureId); + if (feature === null) { + source.on('featuresloadend', function(e) { + feature = source.getFeatureById(featureId); + if (feature !== null) + mapPart.select.getFeatures().push(feature); + }); + } else { + this.select.getFeatures().push(feature); + } + } + } + // // STATIC FOR EXTENSION // @@ -210,6 +274,40 @@ export default class OpenLayersMapPart extends MapPart { // // SLD STYLING // + + setSld(xml) { + this.#sld = SLDReader.Reader(xml); + } + + /** Get a FeatureTypeStyle (https://nieuwlandgeo.github.io/SLDReader/api.html#FeatureTypeStyle). */ + getFeatureTypeStyle(styledLayerName, styleName) { + const sldLayer = SLDReader.getLayer(this.#sld, styledLayerName); + const style = styleName === undefined ? SLDReader.getStyle(sldLayer) : SLDReader.getStyle(sldLayer, styleName); + // OpenLayers can only use one definition + const featureTypeStyle = style.featuretypestyles[0]; + return featureTypeStyle; + } + + applyStyle(layerName, styledLayerName, styleName) { + const layer = this.getLayerByName(layerName); + const featureTypeStyle = this.getFeatureTypeStyle(styledLayerName, styleName); + 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: () => { + layer.changed(); + }, + }); + layer.setStyle(olStyleFunction); + } + #applySLD(vectorLayer, text) { const sldObject = SLDReader.Reader(text); const sldLayer = SLDReader.getLayer(sldObject); @@ -232,4 +330,4 @@ export default class OpenLayersMapPart extends MapPart { }); vectorLayer.setStyle(olStyleFunction); } -} \ No newline at end of file +}