diff --git a/examples/reprojection.html b/examples/reprojection.html
new file mode 100644
index 000000000..ce62651c6
--- /dev/null
+++ b/examples/reprojection.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+ Reprojection example
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/reprojection.js b/examples/reprojection.js
new file mode 100755
index 000000000..0df0a2503
--- /dev/null
+++ b/examples/reprojection.js
@@ -0,0 +1,59 @@
+/**
+ * @module examples.reprojection
+ */
+const exports = {};
+
+import proj4 from 'proj4';
+import {register} from 'ol/proj/proj4';
+import {get as getProjection} from 'ol/proj';
+import olTileWMS from 'ol/source/TileWMS';
+import olMap from 'ol/Map';
+import olLayerTile from 'ol/layer/Tile';
+import olView from 'ol/View';
+import OLCesium from 'olcs/OLCesium';
+import olSourceOSM from 'ol/source/OSM';
+
+proj4.defs('EPSG:21781', '+proj=somerc +lat_0=46.95240555555556 ' +
+ '+lon_0=7.439583333333333 +k_0=1 +x_0=600000 +y_0=200000 +ellps=bessel ' +
+ '+towgs84=674.4,15.1,405.3,0,0,0,0 +units=m +no_defs');
+register(proj4);
+const proj21781 = getProjection('EPSG:21781');
+proj21781.setExtent([485071.54, 75346.36, 828515.78, 299941.84]);
+const source = new olTileWMS({
+ attributions: ['© ' +
+ '' +
+ 'Pixelmap 1:1000000 / geo.admin.ch'],
+ crossOrigin: 'anonymous',
+ params: {
+ 'LAYERS': 'ch.swisstopo.pixelkarte-farbe-pk1000.noscale',
+ 'FORMAT': 'image/jpeg'
+ },
+ url: 'http://wms.geo.admin.ch/',
+ projection: 'EPSG:21781'
+});
+const ol2d = new olMap({
+ layers: [
+ new olLayerTile({source: new olSourceOSM()}),
+ new olLayerTile({
+ source
+ })
+ ],
+ target: 'map',
+ view: new olView({
+ projection: 'EPSG:4326',
+ center: [6.56273, 46.51781],
+ zoom: 6
+ })
+});
+const ol3d = new OLCesium({map: ol2d});
+const scene = ol3d.getCesiumScene();
+const terrainProvider = new Cesium.CesiumTerrainProvider({
+ url: '//assets.agi.com/stk-terrain/world'
+});
+scene.terrainProvider = terrainProvider;
+ol3d.setEnabled(true);
+
+document.getElementById('enable').addEventListener('click', () => ol3d.setEnabled(!ol3d.getEnabled()));
+
+export default exports;
diff --git a/src/olcs/core.js b/src/olcs/core.js
index 60c28c126..b9b399ccb 100644
--- a/src/olcs/core.js
+++ b/src/olcs/core.js
@@ -13,6 +13,7 @@ import olSourceTileWMS from 'ol/source/TileWMS.js';
import {defaultImageLoadFunction} from 'ol/source/Image.js';
import olcsCoreOLImageryProvider from './core/OLImageryProvider.js';
import olcsUtil from './util.js';
+import {ENABLE_RASTER_REPROJECTION} from 'ol/reproj/common';
/**
@@ -395,7 +396,7 @@ exports.tileLayerToImageryLayer = function(olMap, olLayer, viewProj) {
projection = viewProj;
}
- if (exports.isCesiumProjection(projection)) {
+ if (exports.isCesiumProjection(projection) || ENABLE_RASTER_REPROJECTION) {
provider = new olcsCoreOLImageryProvider(olMap, source, viewProj);
}
// Projection not supported by Cesium
diff --git a/src/olcs/core/OLImageryProvider.js b/src/olcs/core/OLImageryProvider.js
index 06bfa01dd..9cc988ff8 100644
--- a/src/olcs/core/OLImageryProvider.js
+++ b/src/olcs/core/OLImageryProvider.js
@@ -3,6 +3,9 @@
*/
import {get as getProjection} from 'ol/proj.js';
import olcsUtil from '../util.js';
+import {ENABLE_RASTER_REPROJECTION} from 'ol/reproj/common';
+import olTileState from 'ol/TileState';
+import {listen, unlistenByKey} from 'ol/events';
class OLImageryProvider /* should not extend Cesium.ImageryProvider */ {
/**
@@ -96,6 +99,9 @@ class OLImageryProvider /* should not extend Cesium.ImageryProvider */ {
this.tilingScheme_ = new Cesium.GeographicTilingScheme();
} else if (this.projection_ == getProjection('EPSG:3857')) {
this.tilingScheme_ = new Cesium.WebMercatorTilingScheme();
+ } else if (ENABLE_RASTER_REPROJECTION) {
+ this.tilingScheme_ = new Cesium.GeographicTilingScheme();
+ this.projection_ = getProjection('EPSG:4326');
} else {
return;
}
@@ -138,24 +144,47 @@ class OLImageryProvider /* should not extend Cesium.ImageryProvider */ {
* @override
*/
requestImage(x, y, level) {
- const tileUrlFunction = this.source_.getTileUrlFunction();
- if (tileUrlFunction && this.projection_) {
-
- // Perform mapping of Cesium tile coordinates to OpenLayers tile coordinates:
- // 1) Cesium zoom level 0 is OpenLayers zoom level 1 for EPSG:4326
- const z_ = this.tilingScheme_ instanceof Cesium.GeographicTilingScheme ? level + 1 : level;
- // 2) OpenLayers tile coordinates increase from bottom to top
- const y_ = -y - 1;
-
- let url = tileUrlFunction.call(this.source_,
- [z_, x, y_], 1, this.projection_);
- if (this.proxy_) {
- url = this.proxy_.getURL(url);
- }
- return url ? Cesium.ImageryProvider.loadImage(this, url) : this.emptyCanvas_;
+ // Perform mapping of Cesium tile coordinates to ol3 tile coordinates:
+ // 1) Cesium zoom level 0 is OpenLayers zoom level 1 for EPSG:4326
+ const z_ = this.tilingScheme_ instanceof Cesium.GeographicTilingScheme ? level + 1 : level;
+ // 2) OpenLayers tile coordinates increase from bottom to top
+ const y_ = -y - 1;
+
+ const tilegrid = this.source_.getTileGridForProjection(this.projection_);
+ if (z_ < tilegrid.getMinZoom() || z_ > tilegrid.getMaxZoom()) {
+ return Promise.resolve(this.emptyCanvas_); // no data
+ }
+
+ const tile = this.source_.getTile(z_, x, y_, 1, this.projection_);
+
+ tile.load();
+
+ // not yet loaded!
+ // const image = tile.getImage();
+ // if (!image || !image.src) {
+ // return this.emptyCanvas_; // no data
+ // }
+
+
+ const state = tile.getState();
+ if (state === olTileState.LOADED || state === olTileState.EMPTY) {
+ return Promise.resolve(tile.getImage()) || undefined;
+ } else if (state === olTileState.ERROR) {
+ return undefined; // let Cesium continue retrieving later
} else {
- // return empty canvas to stop Cesium from retrying later
- return this.emptyCanvas_;
+ const promise = new Promise((resolve, reject) => {
+ const unlisten = listen(tile, 'change', (evt) => {
+ const state = tile.getState();
+ if (state === olTileState.LOADED || state === olTileState.EMPTY) {
+ resolve(tile.getImage() || undefined);
+ unlistenByKey(unlisten);
+ } else if (state === olTileState.ERROR) {
+ resolve(undefined); // let Cesium continue retrieving later
+ unlistenByKey(unlisten);
+ }
+ });
+ });
+ return promise;
}
}
}