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=8206d4fd76ea0d1190d9b1d62616be2fe996925b;hb=0d531e23f44e4cc66d8a8f9837e05ad5d7fd4f20;hp=6eff99f2ff58d8fe3635474bdc2a0e0628585fff;hpb=69adaa7b31078cb30043b073dada14dee1a9e75d;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 6eff99f..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'; @@ -13,6 +14,8 @@ import VectorLayer from 'ol/layer/Vector.js'; 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'; @@ -21,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(), }); } @@ -57,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() }) @@ -70,6 +78,7 @@ export default class OpenLayersMapPart extends MapPart { } this.#map.addLayer(new VectorLayer({ source: vectorSource, + style: style, })); } @@ -79,9 +88,10 @@ export default class OpenLayersMapPart extends MapPart { let mapPart = this; this.#map.on('singleclick', function(e) { let feature = null; - // we chose only one + // we chose the first one e.map.forEachFeatureAtPixel(e.pixel, function(f) { feature = f; + return true; }); if (feature !== null) mapPart.callbacks['onFeatureSingleClick'](feature.get('path')); @@ -100,4 +110,76 @@ export default class OpenLayersMapPart extends MapPart { } }); } + + enableFeaturePopup() { + // we cannot use 'this' in the function provided to OpenLayers + let mapPart = this; + /** + * Elements that make up the popup. + */ + const container = document.getElementById('popup'); + const content = document.getElementById('popup-content'); + const closer = document.getElementById('popup-closer'); + + /** + * Create an overlay to anchor the popup to the map. + */ + const overlay = new Overlay({ + element: container, + autoPan: false, + autoPanAnimation: { + duration: 250, + }, + }); + this.#map.addOverlay(overlay); + + let selected = null; + this.#map.on('pointermove', function(e) { + if (selected !== null) { + selected.setStyle(undefined); + selected = null; + } + + e.map.forEachFeatureAtPixel(e.pixel, function(f) { + selected = f; + return true; + }); + + if (selected == null) { + overlay.setPosition(undefined); + return; + } + 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; + overlay.setPosition(coordinate); + } else { + overlay.setPosition(undefined); + } + }); + } + + // + // HTML + // + getMapDivCssClass() { + return 'map'; + } + + // + // STATIC FOR EXTENSION + // + static newStyle(args){ + return new Style(args); + } + + static newIcon(args){ + return new Icon(args); + } + + }