@masterportal/masterportalapi 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +15 -0
- package/.eslintignore +6 -0
- package/.eslintrc +184 -0
- package/.husky/pre-push +4 -0
- package/CHANGELOG.md +217 -0
- package/License.txt +21 -0
- package/README.md +24 -0
- package/babel.config.json +6 -0
- package/example/README.md +7 -0
- package/example/config/localGeoJSON.js +956 -0
- package/example/config/portal.json +35 -0
- package/example/config/services.json +79 -0
- package/example/index.html +27 -0
- package/example/index.js +210 -0
- package/example/style.scss +59 -0
- package/jest.config.js +18 -0
- package/jest.setup.js +5 -0
- package/jsdoc.json +15 -0
- package/package.json +62 -0
- package/public/marker.svg +1 -0
- package/public/stringMarker.js +5 -0
- package/src/crs.js +122 -0
- package/src/defaults.js +38 -0
- package/src/index.js +30 -0
- package/src/layer/geojson/index.js +109 -0
- package/src/layer/geojson/style.js +61 -0
- package/src/layer/lib.js +32 -0
- package/src/layer/oaf.js +207 -0
- package/src/layer/terrain.js +72 -0
- package/src/layer/tileset.js +71 -0
- package/src/layer/vector.js +48 -0
- package/src/layer/vectorBase.js +39 -0
- package/src/layer/wfs.js +218 -0
- package/src/layer/wms.js +185 -0
- package/src/lib/coordsToPairs.js +15 -0
- package/src/lib/getInitialLayers.js +22 -0
- package/src/lib/load3DScript.js +22 -0
- package/src/lib/oafUtil.js +22 -0
- package/src/lib/setBackgroundImage.js +23 -0
- package/src/lib/wfsUtil.js +75 -0
- package/src/lib/zoomTo.js +40 -0
- package/src/maps/api.js +5 -0
- package/src/maps/map.js +35 -0
- package/src/maps/mapView.js +54 -0
- package/src/maps/ol/olMap.js +124 -0
- package/src/maps/olcs/3dUtils/fixedOverlaySynchronizer.js +39 -0
- package/src/maps/olcs/3dUtils/wmsRasterSynchronizer.js +348 -0
- package/src/maps/olcs/olcsMap.js +212 -0
- package/src/rawLayerList.js +88 -0
- package/src/searchAddress/gazetteerUrl.js +22 -0
- package/src/searchAddress/index.js +13 -0
- package/src/searchAddress/parse.js +196 -0
- package/src/searchAddress/search.js +184 -0
- package/src/searchAddress/searchGazetteer.js +52 -0
- package/src/searchAddress/showGeographicIdentifier.js +20 -0
- package/src/searchAddress/types.js +17 -0
- package/test/.eslintrc +7 -0
- package/test/crs.test.js +109 -0
- package/test/layer/geojson/index.test.js +133 -0
- package/test/layer/geojson/style.test.js +46 -0
- package/test/layer/lib.test.js +83 -0
- package/test/layer/oaf.test.js +245 -0
- package/test/layer/resources/oafFeatures.js +105 -0
- package/test/layer/resources/wfsFeatures.js +26 -0
- package/test/layer/resources/wfsFilter.js +17 -0
- package/test/layer/terrain.test.js +106 -0
- package/test/layer/tileset.test.js +116 -0
- package/test/layer/vector.test.js +76 -0
- package/test/layer/vectorBase.test.js +48 -0
- package/test/layer/wfs.test.js +388 -0
- package/test/layer/wms.test.js +256 -0
- package/test/lib/coordsToPairs.test.js +9 -0
- package/test/lib/getInitialLayers.test.js +28 -0
- package/test/lib/oafUtil.test.js +24 -0
- package/test/lib/setBackgroundImage.test.js +49 -0
- package/test/lib/wfsUtil.test.js +28 -0
- package/test/lib/zoomTo.test.js +74 -0
- package/test/map.test.js +258 -0
- package/test/mapView.test.js +59 -0
- package/test/rawLayerList.test.js +48 -0
- package/test/searchAddress/gazetteerSearchResults/address.js +175 -0
- package/test/searchAddress/gazetteerSearchResults/district.js +71 -0
- package/test/searchAddress/gazetteerSearchResults/houseNumber.js +32 -0
- package/test/searchAddress/gazetteerSearchResults/index.js +19 -0
- package/test/searchAddress/gazetteerSearchResults/parcel.js +44 -0
- package/test/searchAddress/gazetteerSearchResults/street.js +46 -0
- package/test/searchAddress/gazetteerSearchResults/streetKey.js +51 -0
- package/test/searchAddress/gazetteerUrl.test.js +22 -0
- package/test/searchAddress/parse.test.js +110 -0
- package/test/searchAddress/search.test.js +150 -0
- package/test/searchAddress/searchGazetteer.test.js +58 -0
- package/test/searchAddress/showGeographicIdentifier.test.js +22 -0
package/src/maps/map.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as olMap from "./ol/olMap.js";
|
|
2
|
+
import * as olcsMap from "./olcs/olcsMap.js";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
/**
|
|
6
|
+
* Creates a map and adds it to the mapCollection. Depending on param 'mapMode' a 2D or a 3D map is created. Default ist 2D.
|
|
7
|
+
* @param {object} [config] - configuration object - falls back to defaults if none given
|
|
8
|
+
* @param {string} [config.target="map"] - div id to render map to
|
|
9
|
+
* @param {string} [config.namedProjections] - projections to create the map
|
|
10
|
+
* @param {string} [config.backgroundImage] - background image for map; "" to use none
|
|
11
|
+
* @param {string} [config.epsg] - CRS to use
|
|
12
|
+
* @param {number[]} [config.extent] - extent to use
|
|
13
|
+
* @param {Array.<{resolution: number, scale: number, zoomLevel: number}>} [config.options] - zoom level definition
|
|
14
|
+
* @param {Array.<string[]>} [config.options] - each sub-array has two values: projection name, and projection description
|
|
15
|
+
* @param {number} [config.startResolution] - initial resolution
|
|
16
|
+
* @param {number[]} [config.startCenter] - initial position
|
|
17
|
+
* @param {(string|object)} [config.layerConf] - services registry or URL thereof
|
|
18
|
+
* @param {string} [config.gazetteerUrl] - url of gazetteer to use in searchAddress
|
|
19
|
+
* @param {String} [mapMode = "2D"] The map mode. '2D' to create a 2D-map and '3D' to create a 3D-map.
|
|
20
|
+
* @param {object} [settings={}] - settings object
|
|
21
|
+
* @param {object} [settings.mapParams] - additional parameter object that is spread into the ol.Map constructor object
|
|
22
|
+
* @param {function} [settings.callback] - optional callback for layer list loading
|
|
23
|
+
* @returns {module:ol/PluggableMap~PluggableMap} The map.
|
|
24
|
+
*/
|
|
25
|
+
createMap: function (config, mapMode = "2D", settings = {}) {
|
|
26
|
+
const createMapFunctions = {
|
|
27
|
+
"2D": olMap.createMap,
|
|
28
|
+
"3D": olcsMap.createMap
|
|
29
|
+
},
|
|
30
|
+
map = createMapFunctions[mapMode](config, settings);
|
|
31
|
+
|
|
32
|
+
return map;
|
|
33
|
+
},
|
|
34
|
+
olcsMap
|
|
35
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {View} from "ol";
|
|
2
|
+
import defaults from "../defaults";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Sets the startResolution or the startZoomlevel, depending on the configuration.
|
|
6
|
+
* Where the resolution is preferred.
|
|
7
|
+
* The value to use is set and the other is undefined.
|
|
8
|
+
* @param {object} config - configuration object
|
|
9
|
+
* @param {object} [mergedConfig=defaults] - configuration from object merged with default configuration
|
|
10
|
+
* @returns {object} object that contains startZoomLevel and startResolution
|
|
11
|
+
*/
|
|
12
|
+
export function chooseZoomOrResolution (config = {}, mergedConfig = defaults) {
|
|
13
|
+
const zoomResolution = {
|
|
14
|
+
startZoomLevel: undefined,
|
|
15
|
+
startResolution: undefined
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
if (Object.prototype.hasOwnProperty.call(config, "startZoomLevel") && !Object.prototype.hasOwnProperty.call(config, "startResolution")) {
|
|
19
|
+
zoomResolution.startZoomLevel = mergedConfig.startZoomLevel;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
zoomResolution.startResolution = mergedConfig.startResolution;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return zoomResolution;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates a View from config.
|
|
30
|
+
* @param {object} config - configuration object
|
|
31
|
+
* @param {string} [config.epsg="EPSG:25832"] - CRS to use
|
|
32
|
+
* @param {number[]} [config.extent=[510000.0, 5850000.0, 625000.4, 6000000.0]] - extent to use
|
|
33
|
+
* @param {Array.<string[]>} [config.options=[{resolution: 66.14579761460263, scale: 250000, zoomLevel: 0},{resolution: 26.458319045841044, scale: 100000, zoomLevel: 1},{resolution: 15.874991427504629, scale: 60000, zoomLevel: 2},{resolution: 10.583327618336419, scale: 40000, zoomLevel: 3},{resolution: 5.2916638091682096, scale: 20000, zoomLevel: 4},{resolution: 2.6458319045841048, scale: 10000, zoomLevel: 5},{resolution: 1.3229159522920524, scale: 5000, zoomLevel: 6},{resolution: 0.6614579761460262, scale: 2500, zoomLevel: 7},{resolution: 0.2645831904584105, scale: 1000, zoomLevel: 8},{resolution: 0.13229159522920521, scale: 500, zoomLevel: 9}]] - each sub-array has two values: projection name, and projection description
|
|
34
|
+
* @param {number} [config.startResolution=15.874991427504629] - initial resolution
|
|
35
|
+
* @param {number[]} [config.startCenter=[565874, 5934140]] - initial position
|
|
36
|
+
* @returns {ol.View} view with start values from config
|
|
37
|
+
*/
|
|
38
|
+
export function createMapView (config) {
|
|
39
|
+
const mergedConfig = Object.assign({}, defaults, config),
|
|
40
|
+
zoomResolution = chooseZoomOrResolution(config, mergedConfig);
|
|
41
|
+
|
|
42
|
+
return new View({
|
|
43
|
+
projection: mergedConfig.epsg,
|
|
44
|
+
center: mergedConfig.startCenter,
|
|
45
|
+
extent: mergedConfig.extent,
|
|
46
|
+
zoom: zoomResolution.startZoomLevel,
|
|
47
|
+
options: mergedConfig.options,
|
|
48
|
+
resolution: zoomResolution.startResolution,
|
|
49
|
+
resolutions: mergedConfig.options.map(entry => entry.resolution),
|
|
50
|
+
constrainResolution: true,
|
|
51
|
+
constrainOnlyCenter: true,
|
|
52
|
+
backgroundImage: mergedConfig.backgroundImage
|
|
53
|
+
});
|
|
54
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {Map, PluggableMap} from "ol";
|
|
2
|
+
import {defaults as olDefaultInteractions} from "ol/interaction.js";
|
|
3
|
+
import setBackgroundImage from "../../lib/setBackgroundImage";
|
|
4
|
+
import getInitialLayers from "../../lib/getInitialLayers";
|
|
5
|
+
import defaults from "../../defaults";
|
|
6
|
+
import * as wms from "../../layer/wms";
|
|
7
|
+
import * as geojson from "../../layer/geojson";
|
|
8
|
+
import * as wfs from "../../layer/wfs";
|
|
9
|
+
import * as vectorBase from "../../layer/vectorBase";
|
|
10
|
+
import * as oaf from "../../layer/oaf";
|
|
11
|
+
import {createMapView} from "../../maps/mapView";
|
|
12
|
+
import {initializeLayerList, getLayerWhere} from "../../rawLayerList";
|
|
13
|
+
import {registerProjections} from "../../crs";
|
|
14
|
+
import {setGazetteerUrl} from "../../searchAddress";
|
|
15
|
+
|
|
16
|
+
let mapIdCounter = 0;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* lookup for layer constructors
|
|
20
|
+
* @ignore
|
|
21
|
+
*/
|
|
22
|
+
const layerBuilderMap = {
|
|
23
|
+
wms,
|
|
24
|
+
wfs,
|
|
25
|
+
geojson,
|
|
26
|
+
vectorBase,
|
|
27
|
+
oaf
|
|
28
|
+
},
|
|
29
|
+
originalAddLayer = PluggableMap.prototype.addLayer;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Adds a layer to the map, or adds a layer to the map by id.
|
|
33
|
+
* This id is looked up within the array of all known services.
|
|
34
|
+
*
|
|
35
|
+
* Make sure services have been loaded with a callback on createMap
|
|
36
|
+
* if you request the services from the internet.
|
|
37
|
+
*
|
|
38
|
+
* This function is available on all ol/Map instances.
|
|
39
|
+
* @param {(string|ol/Layer)} layerOrId - if of layer to add to map
|
|
40
|
+
* @param {object} [params] - optional parameter object
|
|
41
|
+
* @param {boolean} [params.visibility=true] - whether added layer is initially visible
|
|
42
|
+
* @param {Number} [params.transparency=0] - how visible the layer is initially
|
|
43
|
+
* @returns {?ol.Layer} added layer
|
|
44
|
+
*/
|
|
45
|
+
function addLayer (layerOrId, params = {visibility: true, transparency: 0}) {
|
|
46
|
+
var layer, layerBuilder;
|
|
47
|
+
|
|
48
|
+
// if parameter is id, create and add layer with masterportalAPI mechanisms
|
|
49
|
+
if (typeof layerOrId === "string") {
|
|
50
|
+
const rawLayer = getLayerWhere({id: layerOrId});
|
|
51
|
+
|
|
52
|
+
if (!rawLayer) {
|
|
53
|
+
console.error("Layer with id '" + layerOrId + "' not found. No layer added to map.");
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
layerBuilder = layerBuilderMap[rawLayer.typ.toLowerCase()];
|
|
57
|
+
if (!layerBuilder) {
|
|
58
|
+
console.error("Layer with id '" + layerOrId + "' has unknown type '" + rawLayer.typ + "'. No layer added to map.");
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
layer = layerBuilder.createLayer(rawLayer, {}, {map: this});
|
|
62
|
+
layer.setVisible(typeof params.visibility === "boolean" ? params.visibility : true);
|
|
63
|
+
layer.setOpacity(typeof params.transparency === "number" ? (100 - params.transparency) / 100 : 1);
|
|
64
|
+
originalAddLayer.call(this, layer);
|
|
65
|
+
return layer;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// else use original function
|
|
69
|
+
return originalAddLayer.call(this, layerOrId);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
PluggableMap.prototype.addLayer = addLayer;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Creates an openlayers map according to configuration. Does not set many default values itself, but uses function that do.
|
|
76
|
+
* Check the called functions for default values, or [the defaults file]{@link ./defaults.js}.
|
|
77
|
+
* @param {object} [config] - configuration object - falls back to defaults if none given
|
|
78
|
+
* @param {string} [config.target="map"] - div id to render map to
|
|
79
|
+
* @param {string} [config.namedProjections] - projections to create the map
|
|
80
|
+
* @param {string} [config.backgroundImage] - background image for map; "" to use none
|
|
81
|
+
* @param {string} [config.epsg] - CRS to use
|
|
82
|
+
* @param {number[]} [config.extent] - extent to use
|
|
83
|
+
* @param {Array.<{resolution: number, scale: number, zoomLevel: number}>} [config.options] - zoom level definition
|
|
84
|
+
* @param {Array.<string[]>} [config.options] - each sub-array has two values: projection name, and projection description
|
|
85
|
+
* @param {number} [config.startResolution] - initial resolution
|
|
86
|
+
* @param {number[]} [config.startCenter] - initial position
|
|
87
|
+
* @param {(string|object)} [config.layerConf] - services registry or URL thereof
|
|
88
|
+
* @param {string} [config.gazetteerUrl] - url of gazetteer to use in searchAddress
|
|
89
|
+
* @param {object} [settings={}] - setings object
|
|
90
|
+
* @param {object} [settings.mapParams] - additional parameter object that is spread into the ol.Map constructor object
|
|
91
|
+
* @param {function} [settings.callback] - optional callback for layer list loading
|
|
92
|
+
* @param {String} [mapMode = "2D"] The map mode. '2D' to craete a 2D-map and '3D' to create a 3D-map.
|
|
93
|
+
* @returns {object} map object from ol
|
|
94
|
+
*/
|
|
95
|
+
export function createMap (config = defaults, {mapParams, callback} = {}) {
|
|
96
|
+
registerProjections(config.namedProjections);
|
|
97
|
+
setBackgroundImage(config);
|
|
98
|
+
setGazetteerUrl(config.gazetteerUrl);
|
|
99
|
+
const map = new Map(Object.assign({
|
|
100
|
+
target: config.target || defaults.target,
|
|
101
|
+
interactions: olDefaultInteractions({altShiftDragRotate: false, pinchRotate: false}),
|
|
102
|
+
controls: [],
|
|
103
|
+
view: createMapView(config)
|
|
104
|
+
}, mapParams));
|
|
105
|
+
|
|
106
|
+
map.set("mapMode", "2D");
|
|
107
|
+
map.set("id", `map2D_${mapIdCounter++}`);
|
|
108
|
+
|
|
109
|
+
// extend callback to load configured initial layers
|
|
110
|
+
initializeLayerList(config.layerConf, (param, error) => {
|
|
111
|
+
getInitialLayers(config)
|
|
112
|
+
.forEach(layer => {
|
|
113
|
+
map.addLayer(layer.id, layer);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
if (typeof callback === "function") {
|
|
117
|
+
return callback(param, error);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return null;
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return map;
|
|
124
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import OverlaySynchronizer from "olcs/OverlaySynchronizer.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a FixedOverlaySynchronizer.
|
|
5
|
+
*/
|
|
6
|
+
class FixedOverlaySynchronizer extends OverlaySynchronizer {
|
|
7
|
+
/* eslint-disable no-useless-constructor */
|
|
8
|
+
/**
|
|
9
|
+
* This object takes care of one-directional synchronization of
|
|
10
|
+
* Openlayers WMS raster layers to the given Cesium globe. This Synchronizer
|
|
11
|
+
* assumes that the given WMS supports EPSG Code 4326 (WGS84)
|
|
12
|
+
* @param {!ol.Map} map -
|
|
13
|
+
* @param {!Cesium.Scene} scene -
|
|
14
|
+
* @constructor
|
|
15
|
+
* @extends {olcs.AbstractSynchronizer.<Cesium.ImageryLayer>}
|
|
16
|
+
* @api
|
|
17
|
+
* @struct
|
|
18
|
+
*/
|
|
19
|
+
constructor (map, scene) {
|
|
20
|
+
super(map, scene);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @api
|
|
25
|
+
* @returns {void}
|
|
26
|
+
*/
|
|
27
|
+
addOverlays () {
|
|
28
|
+
/* eslint no-underscore-dangle: ["error", { "allow": ["overlays_"] }]*/
|
|
29
|
+
this.overlays_.forEach((overlay) => {
|
|
30
|
+
if (overlay.getId() !== undefined) {
|
|
31
|
+
this.addOverlay(overlay);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default FixedOverlaySynchronizer;
|
|
38
|
+
|
|
39
|
+
/* eslint-enable no-useless-constructor */
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module olcs.WMSRasterSynchronizer
|
|
3
|
+
*/
|
|
4
|
+
import olLayerGroup from "ol/layer/Group.js";
|
|
5
|
+
import {getUid} from "olcs/util.js";
|
|
6
|
+
import TileWMS from "ol/source/TileWMS.js";
|
|
7
|
+
import olcsAbstractSynchronizer from "olcs/AbstractSynchronizer.js";
|
|
8
|
+
import olcsCore from "olcs/core.js";
|
|
9
|
+
import {Tile, Image as ImageLayer} from "ol/layer.js";
|
|
10
|
+
import {stableSort} from "ol/array.js";
|
|
11
|
+
import {getBottomLeft, getBottomRight, getTopRight, getTopLeft} from "ol/extent.js";
|
|
12
|
+
import {transformExtent} from "ol/proj.js";
|
|
13
|
+
import StaticImageSource from "ol/source/ImageStatic";
|
|
14
|
+
import proj4 from "proj4";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Represents a WMSRasterSynchronizer.
|
|
18
|
+
*/
|
|
19
|
+
class WMSRasterSynchronizer extends olcsAbstractSynchronizer {
|
|
20
|
+
/**
|
|
21
|
+
* This object takes care of one-directional synchronization of
|
|
22
|
+
* Openlayers WMS raster layers to the given Cesium globe. This Synchronizer
|
|
23
|
+
* assumes that the given WMS supports EPSG Code 4326 (WGS84)
|
|
24
|
+
* @param {!ol.Map} map -
|
|
25
|
+
* @param {!Cesium.Scene} scene -
|
|
26
|
+
* @constructor
|
|
27
|
+
* @extends {olcs.AbstractSynchronizer.<Cesium.ImageryLayer>}
|
|
28
|
+
* @api
|
|
29
|
+
* @struct
|
|
30
|
+
*/
|
|
31
|
+
constructor (map, scene) {
|
|
32
|
+
super(map, scene);
|
|
33
|
+
/**
|
|
34
|
+
* @type {!Cesium.ImageryLayerCollection}
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
this.cesiumLayers = scene.imageryLayers;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @type {!Cesium.ImageryLayerCollection}
|
|
41
|
+
* @private
|
|
42
|
+
*/
|
|
43
|
+
/* eslint-disable no-undef */
|
|
44
|
+
this.ourLayers = new Cesium.ImageryLayerCollection();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @inheritDoc
|
|
50
|
+
*/
|
|
51
|
+
addCesiumObject (object) {
|
|
52
|
+
this.cesiumLayers.add(object);
|
|
53
|
+
this.ourLayers.add(object);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @inheritDoc
|
|
59
|
+
*/
|
|
60
|
+
destroyCesiumObject (object) {
|
|
61
|
+
object.destroy();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @inheritDoc
|
|
67
|
+
*/
|
|
68
|
+
removeSingleCesiumObject (object, destroy) {
|
|
69
|
+
this.cesiumLayers.remove(object, destroy);
|
|
70
|
+
this.ourLayers.remove(object, false);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @inheritDoc
|
|
76
|
+
*/
|
|
77
|
+
removeAllCesiumObjects (destroy) {
|
|
78
|
+
for (let i = 0; i < this.ourLayers.length; ++i) {
|
|
79
|
+
this.cesiumLayers.remove(this.ourLayers.get(i), destroy);
|
|
80
|
+
}
|
|
81
|
+
this.ourLayers.removeAll(false);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Creates an array of Cesium.ImageryLayer.
|
|
87
|
+
* May be overriden by child classes to implement custom behavior.
|
|
88
|
+
* The default implementation handles tiled imageries in EPSG:4326 or
|
|
89
|
+
* EPSG:3859.
|
|
90
|
+
* @param {!ol.layer.Base} olLayer -
|
|
91
|
+
* @param {?ol.proj.Projection} viewProj Projection of the view.
|
|
92
|
+
* @return {?Array.<!Cesium.ImageryLayer>} array or null if not possible
|
|
93
|
+
* (or supported)
|
|
94
|
+
* @protected
|
|
95
|
+
*/
|
|
96
|
+
convertLayerToCesiumImageries (olLayer, viewProj) {
|
|
97
|
+
let layerOptions = {
|
|
98
|
+
"show": false
|
|
99
|
+
},
|
|
100
|
+
source = {},
|
|
101
|
+
cesiumLayer = {},
|
|
102
|
+
provider = null;
|
|
103
|
+
|
|
104
|
+
if (!(olLayer instanceof Tile) && !(olLayer instanceof ImageLayer)) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
source = olLayer.getSource();
|
|
109
|
+
|
|
110
|
+
if (source instanceof TileWMS) {
|
|
111
|
+
const params = source.getParams(),
|
|
112
|
+
options = {
|
|
113
|
+
"url": source.getUrls()[0],
|
|
114
|
+
"parameters": params,
|
|
115
|
+
"layers": params.LAYERS,
|
|
116
|
+
"show": false
|
|
117
|
+
},
|
|
118
|
+
tileGrid = source.getTileGrid();
|
|
119
|
+
|
|
120
|
+
if (tileGrid) {
|
|
121
|
+
const ext = olLayer.getExtent();
|
|
122
|
+
|
|
123
|
+
if (ext && viewProj) {
|
|
124
|
+
options.rectangle = olcsCore.extentToRectangle(ext, viewProj);
|
|
125
|
+
const minMax = this.getMinMaxLevelFromTileGrid(tileGrid, ext, viewProj);
|
|
126
|
+
|
|
127
|
+
options.tileWidth = tileGrid.getTileSize(0)[0];
|
|
128
|
+
options.tileHeight = tileGrid.getTileSize(0)[1];
|
|
129
|
+
options.minimumLevel = minMax[0];
|
|
130
|
+
options.maximumLevel = minMax[1];
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/* eslint-disable no-undef */
|
|
134
|
+
provider = new Cesium.WebMapServiceImageryProvider(options);
|
|
135
|
+
}
|
|
136
|
+
else if (source instanceof StaticImageSource) {
|
|
137
|
+
const extent = source.getImageExtent(),
|
|
138
|
+
options = {
|
|
139
|
+
"url": source.getUrl(),
|
|
140
|
+
"show": false
|
|
141
|
+
},
|
|
142
|
+
bottomLeftCorner = proj4("EPSG:25832", "EPSG:4326", getBottomLeft(extent)),
|
|
143
|
+
topRightCorner = proj4("EPSG:25832", "EPSG:4326", getTopRight(extent));
|
|
144
|
+
|
|
145
|
+
/* eslint-disable no-undef */
|
|
146
|
+
options.rectangle = Cesium.Rectangle.fromDegrees(bottomLeftCorner[0], bottomLeftCorner[1], topRightCorner[0], topRightCorner[1]);
|
|
147
|
+
/* eslint-disable no-undef */
|
|
148
|
+
provider = new Cesium.SingleTileImageryProvider(options);
|
|
149
|
+
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
console.warn("Sources other than TileImage are currently not supported.");
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// the provider is always non-null if we got this far
|
|
157
|
+
layerOptions = {
|
|
158
|
+
"show": false
|
|
159
|
+
};
|
|
160
|
+
/* eslint-disable no-undef */
|
|
161
|
+
cesiumLayer = new Cesium.ImageryLayer(provider, layerOptions);
|
|
162
|
+
|
|
163
|
+
return cesiumLayer ? [cesiumLayer] : null;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
*
|
|
168
|
+
* @param {ol.Extent} extent -
|
|
169
|
+
* @param {ol.ProjectionLike} projection -
|
|
170
|
+
* @return {Array.<Cesium.Cartographic>} -
|
|
171
|
+
* @private
|
|
172
|
+
*/
|
|
173
|
+
getExtentPoints (extent, projection) {
|
|
174
|
+
const wgs84Extent = transformExtent(extent, projection, "EPSG:4326"),
|
|
175
|
+
olCoords = [
|
|
176
|
+
getBottomLeft(wgs84Extent),
|
|
177
|
+
getBottomRight(wgs84Extent),
|
|
178
|
+
getTopRight(wgs84Extent),
|
|
179
|
+
getTopLeft(wgs84Extent)
|
|
180
|
+
];
|
|
181
|
+
|
|
182
|
+
/* eslint-disable no-undef */
|
|
183
|
+
return olCoords.map(coord => Cesium.Cartographic.fromDegrees(coord[0], coord[1]));
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
*
|
|
187
|
+
* @param {ol.tilegrid.TileGrid} tilegrid -
|
|
188
|
+
* @param {ol.Extent} extent -
|
|
189
|
+
* @param {ol.ProjectionLike} projection -
|
|
190
|
+
* @return {Array.<Number>} -
|
|
191
|
+
*/
|
|
192
|
+
getMinMaxLevelFromTileGrid (tilegrid, extent, projection) {
|
|
193
|
+
const olCoords = [
|
|
194
|
+
getBottomLeft(extent),
|
|
195
|
+
getBottomRight(extent),
|
|
196
|
+
getTopRight(extent),
|
|
197
|
+
getTopLeft(extent)
|
|
198
|
+
],
|
|
199
|
+
resolution = tilegrid.getResolutions().slice(-1).pop(),
|
|
200
|
+
tileCoordsLocal = olCoords.map(position => tilegrid.getTileCoordForCoordAndResolution(position, resolution)),
|
|
201
|
+
distanceLocalX = Math.abs(tileCoordsLocal[0][1] - tileCoordsLocal[1][1]),
|
|
202
|
+
distanceLocalY = Math.abs(tileCoordsLocal[0][2] - tileCoordsLocal[3][2]),
|
|
203
|
+
extentCoords = this.getExtentPoints(extent, projection),
|
|
204
|
+
/* eslint-disable no-undef */
|
|
205
|
+
tilingScheme = new Cesium.GeographicTilingScheme({});
|
|
206
|
+
let minLevel = 0,
|
|
207
|
+
maxLevel = 20;
|
|
208
|
+
|
|
209
|
+
while (minLevel < maxLevel) {
|
|
210
|
+
/* eslint-disable no-loop-func */
|
|
211
|
+
|
|
212
|
+
const tileCoords = extentCoords.map(position => tilingScheme.positionToTileXY(position, minLevel)),
|
|
213
|
+
distances = [];
|
|
214
|
+
/* eslint-enable no-loop-func */
|
|
215
|
+
|
|
216
|
+
distances.push(Math.abs(tileCoords[0].x - tileCoords[1].x));
|
|
217
|
+
distances.push(Math.abs(tileCoords[0].y - tileCoords[3].y));
|
|
218
|
+
if (distances[0] > 1 || distances[1] > 1) {
|
|
219
|
+
minLevel--;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
minLevel++;
|
|
223
|
+
}
|
|
224
|
+
while (maxLevel > minLevel) {
|
|
225
|
+
/* eslint-disable no-loop-func */
|
|
226
|
+
|
|
227
|
+
const tileCoords = extentCoords.map(position => tilingScheme.positionToTileXY(position, maxLevel)),
|
|
228
|
+
distances = [];
|
|
229
|
+
/* eslint-enable no-loop-func */
|
|
230
|
+
|
|
231
|
+
distances.push(Math.abs(tileCoords[0].x - tileCoords[1].x));
|
|
232
|
+
distances.push(Math.abs(tileCoords[0].y - tileCoords[3].y));
|
|
233
|
+
if (distances[0] < distanceLocalX || distances[1] < distanceLocalY) {
|
|
234
|
+
maxLevel++;
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
maxLevel--;
|
|
238
|
+
}
|
|
239
|
+
return [minLevel, maxLevel];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* @inheritDoc
|
|
244
|
+
*/
|
|
245
|
+
createSingleLayerCounterparts (olLayerWithParents) {
|
|
246
|
+
const olLayer = olLayerWithParents.layer,
|
|
247
|
+
uid = getUid(olLayer).toString(),
|
|
248
|
+
viewProj = this.view.getProjection(),
|
|
249
|
+
cesiumObjects = this.convertLayerToCesiumImageries(olLayer, viewProj);
|
|
250
|
+
|
|
251
|
+
if (cesiumObjects) {
|
|
252
|
+
const listenKeyArray = [];
|
|
253
|
+
|
|
254
|
+
[olLayerWithParents.layer].concat(olLayerWithParents.parents).forEach((olLayerItem) => {
|
|
255
|
+
listenKeyArray.push(olLayerItem.on(["change:opacity", "change:visible"], () => {
|
|
256
|
+
// the compiler does not seem to be able to infer this
|
|
257
|
+
/* eslint-disable no-console */
|
|
258
|
+
|
|
259
|
+
console.assert(cesiumObjects);
|
|
260
|
+
/* eslint-enable no-console */
|
|
261
|
+
for (let i = 0; i < cesiumObjects.length; ++i) {
|
|
262
|
+
olcsCore.updateCesiumLayerProperties(olLayerWithParents, cesiumObjects[i]);
|
|
263
|
+
}
|
|
264
|
+
}));
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
for (let i = 0; i < cesiumObjects.length; ++i) {
|
|
268
|
+
olcsCore.updateCesiumLayerProperties(olLayerWithParents, cesiumObjects[i]);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// there is no way to modify Cesium layer extent,
|
|
272
|
+
// we have to recreate when OpenLayers layer extent changes:
|
|
273
|
+
listenKeyArray.push(olLayer.on("change:extent", function () {
|
|
274
|
+
for (let i = 0; i < cesiumObjects.length; ++i) {
|
|
275
|
+
this.cesiumLayers.remove(cesiumObjects[i], true); // destroy
|
|
276
|
+
this.ourLayers.remove(cesiumObjects[i], false);
|
|
277
|
+
}
|
|
278
|
+
delete this.layerMap[getUid(olLayer)]; // invalidate the map entry
|
|
279
|
+
this.synchronize();
|
|
280
|
+
}, this));
|
|
281
|
+
|
|
282
|
+
listenKeyArray.push(olLayer.on("change", function () {
|
|
283
|
+
// when the source changes, re-add the layer to force update
|
|
284
|
+
for (let i = 0; i < cesiumObjects.length; ++i) {
|
|
285
|
+
const position = this.cesiumLayers.indexOf(cesiumObjects[i]);
|
|
286
|
+
|
|
287
|
+
if (position >= 0) {
|
|
288
|
+
this.cesiumLayers.remove(cesiumObjects[i], false);
|
|
289
|
+
this.cesiumLayers.add(cesiumObjects[i], position);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}.bind(this)));
|
|
293
|
+
|
|
294
|
+
this.olLayerListenKeys[uid].push(...listenKeyArray);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return Array.isArray(cesiumObjects) ? cesiumObjects : null;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Order counterparts using the same algorithm as the Openlayers renderer:
|
|
302
|
+
* z-index then original sequence order.
|
|
303
|
+
* @override
|
|
304
|
+
* @protected
|
|
305
|
+
*/
|
|
306
|
+
orderLayers () {
|
|
307
|
+
const layers = [],
|
|
308
|
+
zIndices = {},
|
|
309
|
+
queue = [this.mapLayerGroup];
|
|
310
|
+
|
|
311
|
+
while (queue.length > 0) {
|
|
312
|
+
const olLayer = queue.splice(0, 1)[0];
|
|
313
|
+
|
|
314
|
+
layers.push(olLayer);
|
|
315
|
+
zIndices[getUid(olLayer)] = olLayer.getZIndex();
|
|
316
|
+
|
|
317
|
+
if (olLayer instanceof olLayerGroup) {
|
|
318
|
+
const sublayers = olLayer.getLayers();
|
|
319
|
+
|
|
320
|
+
if (sublayers) {
|
|
321
|
+
// Prepend queue with sublayers in order
|
|
322
|
+
queue.unshift(...sublayers.getArray());
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
stableSort(layers, (layer1, layer2) => zIndices[getUid(layer1)] - zIndices[getUid(layer2)]);
|
|
328
|
+
|
|
329
|
+
layers.forEach(function (olLayer) {
|
|
330
|
+
const olLayerId = getUid(olLayer).toString(),
|
|
331
|
+
cesiumObjects = this.layerMap[olLayerId];
|
|
332
|
+
|
|
333
|
+
if (cesiumObjects) {
|
|
334
|
+
cesiumObjects.forEach(this.raiseToTop, this);
|
|
335
|
+
}
|
|
336
|
+
}, this);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* @param {Cesium.ImageryLayer} counterpart -
|
|
341
|
+
* @returns {void}
|
|
342
|
+
*/
|
|
343
|
+
raiseToTop (counterpart) {
|
|
344
|
+
this.cesiumLayers.raiseToTop(counterpart);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
export default WMSRasterSynchronizer;
|