* @module OpenLayersMapPart
*/
-import Map from 'ol/Map.js';
-import View from 'ol/View.js';
-import OSM from 'ol/source/OSM.js';
+import { fromLonLat, getPointResolution } from 'ol/proj.js';
+
import TileLayer from 'ol/layer/Tile.js';
-import { fromLonLat, getPointResolution, transformExtent } from 'ol/proj.js';
-import VectorSource from 'ol/source/Vector.js';
-import Feature from 'ol/Feature.js';
-import { Point } from 'ol/geom.js';
-import VectorLayer from 'ol/layer/Vector.js';
-import GeoJSON from 'ol/format/GeoJSON.js';
-import GPX from 'ol/format/GPX.js';
+
+import OSM from 'ol/source/OSM.js';
+import { isEmpty } from 'ol/extent';
+
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 { OverviewMap, ScaleLine, defaults as defaultControls } from 'ol/control.js';
+import { easeOut } from 'ol/easing';
import * as SLDReader from '@nieuwlandgeo/sldreader';
import MapPart from './MapPart.js';
-
-import { bbox } from 'ol/loadingstrategy';
+import { transformToOlLonLatExtent } from './OpenLayersUtils.js';
/** OpenLayers implementation of MapPart. */
export default class OpenLayersMapPart extends MapPart {
/** The OpenLayers Map. */
#map;
+ /** The overview map */
+ #overviewMap;
+
/** Styled layer descriptor */
#sld;
+ /** The select interaction */
+ select;
+
/** 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({
// projection: 'EPSG:4326',
// }),
target: this.getMapName(),
});
+ this.#map.addInteraction(this.select);
//this.#map.getView().set('projection', 'EPSG:4326', true);
}
/* GEOGRAPHICAL METHODS */
- setZoom(zoom) {
- this.#map.getView().setZoom(zoom);
+ setCenter(lat, lon) {
+ this.#map.getView().setCenter(fromLonLat([lon, lat]));
}
- setCenter(lng, lat) {
- this.#map.getView().setCenter(fromLonLat([lng, lat]));
- }
-
- addPoint(lng, lat, style) {
- let vectorSource = new VectorSource({
- features: [new Feature({
- geometry: new Point(fromLonLat([lng, lat]))
- })]
- });
- this.#map.addLayer(new VectorLayer({
- source: vectorSource,
- style: style,
- }));
- }
-
- addUrlLayer(url, format, style, sld) {
- let featureFormat;
- if (format === 'GEOJSON') {
- featureFormat = new GeoJSON();
- }
- else if (format === 'GPX') {
- featureFormat = new GPX();
- } else {
- throw new Error("Unsupported format " + format);
- }
- const vectorSource = new VectorSource({
- url: url,
- format: featureFormat,
- });
- const vectorLayer = new VectorLayer({
- source: vectorSource,
- });
- if (sld) {
- this.#applySLD(vectorLayer, style);
- } else if (style !== null) {
- vectorLayer.setStyle(style);
- }
- this.#map.addLayer(vectorLayer);
- }
-
- addLayer(js) {
- const func = new Function(js);
- const layer = (func)();
- this.#map.addLayer(layer);
+ fit(extent, options) {
+ var transformed = transformToOlLonLatExtent(extent, this.#map.getView().getProjection());
+ this.#map.getView().fit(transformed, options);
}
+ /** Accessors */
getMap() {
return this.#map;
}
return true;
});
if (feature !== null)
- mapPart.callbacks['onFeatureSingleClick'](feature.get('path'));
+ mapPart.callbacks['onFeatureSingleClick'](feature.get('cr:path'));
});
}
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'));
}
});
}
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);
});
}
+ 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);
+ }
+ }
+ }
+
+ fitToLayer(layerName) {
+ // we cannot use 'this' in the function provided to OpenLayers
+ let mapPart = this;
+ const layer = this.getLayerByName(layerName);
+ const source = layer.getSource();
+ const extent = source.getExtent();
+ const options = {
+ duration: 1000,
+ padding: [20, 20, 20, 20],
+ easing: easeOut,
+ };
+ if (!isEmpty(extent))
+ this.#map.getView().fit(source.getExtent(), options);
+ source.on('featuresloadend', function(e) {
+ mapPart.getMap().getView().fit(source.getExtent(), options);
+ });
+ }
+
//
// HTML
//
return 'map';
}
+
//
// STATIC FOR EXTENSION
//
});
vectorLayer.setStyle(olStyleFunction);
}
-
- //
- // BBOX
- //
- applyBboxStrategy(layerName) {
- const layer = this.getLayerByName(layerName);
- const vectorSource = layer.getSource();
- const baseUrl = vectorSource.getUrl();
- if (typeof baseUrl === 'function')
- throw new Error('A strategy was already applied to layer ' + layerName);
-
- const loadFunction = function(extent, resolution, projection, success, failure) {
-
- const proj = projection.getCode();
- var bbox = transformExtent(extent, proj, 'EPSG:4326');
-
- const url = baseUrl + '&' +
- 'bbox=' + bbox.join(',') ;
-// 'bbox=' + extent.join(',') + ',' + proj;
- const xhr = new XMLHttpRequest();
- xhr.open('GET', url);
- const onError = function() {
- vectorSource.removeLoadedExtent(extent);
- failure();
- }
- xhr.onerror = onError;
- xhr.onload = function() {
- if (xhr.status == 200) {
- const features = vectorSource.getFormat().readFeatures(xhr.responseText);
- vectorSource.addFeatures(features);
- success(features);
- } else {
- onError();
- }
- }
- xhr.send();
- }
-
- vectorSource.setLoader(loadFunction);
- }
}