]>
git.argeo.org Git - gpl/argeo-suite.git/blob - org.argeo.app.geo.js/src/org.argeo.app.geo.js/OpenLayersMapPart.js
1 /** OpenLayers-based implementation.
2 * @module OpenLayersMapPart
5 import Map
from 'ol/Map.js';
6 import View
from 'ol/View.js';
7 import OSM
from 'ol/source/OSM.js';
8 import TileLayer
from 'ol/layer/Tile.js';
9 import { fromLonLat
, getPointResolution
} from 'ol/proj.js';
10 import VectorSource
from 'ol/source/Vector.js';
11 import Feature
from 'ol/Feature.js';
12 import { Point
} from 'ol/geom.js';
13 import VectorLayer
from 'ol/layer/Vector.js';
14 import GeoJSON
from 'ol/format/GeoJSON.js';
15 import GPX
from 'ol/format/GPX.js';
16 import Select
from 'ol/interaction/Select.js';
17 import Overlay
from 'ol/Overlay.js';
18 import { Style
, Icon
} from 'ol/style.js';
20 import * as SLDReader
from '@nieuwlandgeo/sldreader';
22 import MapPart
from './MapPart.js';
23 import { SentinelCloudless
} from './OpenLayerTileSources.js';
25 /** OpenLayers implementation of MapPart. */
26 export default class OpenLayersMapPart
extends MapPart
{
27 /** The OpenLayers Map. */
30 /** Externally added callback functions. */
33 /** Constructor taking the mapName as an argument. */
34 constructor(mapName
) {
39 // source: new SentinelCloudless(),
47 target
: this.getMapName(),
51 /* GEOGRAPHICAL METHODS */
54 this.#map
.getView().setZoom(zoom
);
58 this.#map
.getView().setCenter(fromLonLat([lng
, lat
]));
61 addPoint(lng
, lat
, style
) {
62 let vectorSource
= new VectorSource({
63 features
: [new Feature({
64 geometry
: new Point(fromLonLat([lng
, lat
]))
67 this.#map
.addLayer(new VectorLayer({
73 addUrlLayer(url
, format
, style
, sld
) {
75 if (format
=== 'GEOJSON') {
76 featureFormat
= new GeoJSON();
78 else if (format
=== 'GPX') {
79 featureFormat
= new GPX();
81 throw new Error("Unsupported format " + format
);
83 const vectorSource
= new VectorSource({
85 format
: featureFormat
,
87 const vectorLayer
= new VectorLayer({
91 this.#applySLD(vectorLayer
, style
);
93 vectorLayer
.setStyle(style
);
95 this.#map
.addLayer(vectorLayer
);
100 enableFeatureSingleClick() {
101 // we cannot use 'this' in the function provided to OpenLayers
103 this.#map
.on('singleclick', function(e
) {
105 // we chose the first one
106 e
.map
.forEachFeatureAtPixel(e
.pixel
, function(f
) {
110 if (feature
!== null)
111 mapPart
.callbacks
['onFeatureSingleClick'](feature
.get('path'));
115 enableFeatureSelected() {
116 // we cannot use 'this' in the function provided to OpenLayers
118 var select
= new Select();
119 this.#map
.addInteraction(select
);
120 select
.on('select', function(e
) {
121 if (e
.selected
.length
> 0) {
122 let feature
= e
.selected
[0];
123 mapPart
.callbacks
['onFeatureSelected'](feature
.get('path'));
128 enableFeaturePopup() {
129 // we cannot use 'this' in the function provided to OpenLayers
132 * Elements that make up the popup.
134 const container
= document
.getElementById('popup');
135 const content
= document
.getElementById('popup-content');
136 const closer
= document
.getElementById('popup-closer');
139 * Create an overlay to anchor the popup to the map.
141 const overlay
= new Overlay({
148 this.#map
.addOverlay(overlay
);
151 this.#map
.on('pointermove', function(e
) {
152 if (selected
!== null) {
153 selected
.setStyle(undefined);
157 e
.map
.forEachFeatureAtPixel(e
.pixel
, function(f
) {
162 if (selected
== null) {
163 overlay
.setPosition(undefined);
166 const coordinate
= e
.coordinate
;
167 const path
= selected
.get('path');
170 const res
= mapPart
.callbacks
['onFeaturePopup'](path
);
172 content
.innerHTML
= res
;
173 overlay
.setPosition(coordinate
);
175 overlay
.setPosition(undefined);
183 getMapDivCssClass() {
188 // STATIC FOR EXTENSION
190 static newStyle(args
) {
191 return new Style(args
);
194 static newIcon(args
) {
195 return new Icon(args
);
201 #applySLD(vectorLayer
, text
) {
202 const sldObject
= SLDReader
.Reader(text
);
203 const sldLayer
= SLDReader
.getLayer(sldObject
);
204 const style
= SLDReader
.getStyle(sldLayer
);
205 const featureTypeStyle
= style
.featuretypestyles
[0];
207 const viewProjection
= this.#map
.getView().getProjection();
208 const olStyleFunction
= SLDReader
.createOlStyleFunction(featureTypeStyle
, {
209 // Use the convertResolution option to calculate a more accurate resolution.
210 convertResolution
: viewResolution
=> {
211 const viewCenter
= this.#map
.getView().getCenter();
212 return getPointResolution(viewProjection
, viewResolution
, viewCenter
);
214 // If you use point icons with an ExternalGraphic, you have to use imageLoadCallback
215 // to update the vector layer when an image finishes loading.
216 // If you do not do this, the image will only be visible after next layer pan/zoom.
217 imageLoadedCallback
: () => {
218 vectorLayer
.changed();
221 vectorLayer
.setStyle(olStyleFunction
);