Skip to content

Commit 9f079b0

Browse files
committed
Report previous branch modifications for raster reprojection
1 parent 167663b commit 9f079b0

File tree

4 files changed

+123
-18
lines changed

4 files changed

+123
-18
lines changed

examples/reprojection.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version='1.0' encoding='UTF-8'?>
2+
<!DOCTYPE HTML>
3+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4+
<head>
5+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6+
<meta name="robots" content="index, all" />
7+
<title>Reprojection example</title>
8+
<link rel="stylesheet" href="../node_modules/ol/ol.css" type="text/css">
9+
</head>
10+
<body>
11+
<div id="map" style="width:600px;height:400px;"></div>
12+
<input id="enable" type="button" value="Enable/disable" />
13+
14+
<script src="inject_ol_cesium.js"></script>
15+
</body>
16+
</html>

examples/reprojection.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* @module examples.reprojection
3+
*/
4+
const exports = {};
5+
6+
import proj4 from 'proj4';
7+
import {register} from 'ol/proj/proj4';
8+
import {get as getProjection, transform} from 'ol/proj';
9+
import olTileWMS from 'ol/source/TileWMS';
10+
import olMap from 'ol/Map';
11+
import olLayerTile from 'ol/layer/Tile';
12+
import olView from 'ol/View';
13+
import OLCesium from 'olcs/OLCesium';
14+
import olSourceOSM from 'ol/source/OSM';
15+
16+
proj4.defs('EPSG:21781', '+proj=somerc +lat_0=46.95240555555556 ' +
17+
'+lon_0=7.439583333333333 +k_0=1 +x_0=600000 +y_0=200000 +ellps=bessel ' +
18+
'+towgs84=674.4,15.1,405.3,0,0,0,0 +units=m +no_defs');
19+
register(proj4);
20+
const proj21781 = getProjection('EPSG:21781');
21+
proj21781.setExtent([485071.54, 75346.36, 828515.78, 299941.84]);
22+
const source = new olTileWMS({
23+
attributions: ['&copy; ' +
24+
'<a href="http://www.geo.admin.ch/internet/geoportal/' +
25+
'en/home.html">' +
26+
'Pixelmap 1:1000000 / geo.admin.ch</a>'],
27+
crossOrigin: 'anonymous',
28+
params: {
29+
'LAYERS': 'ch.swisstopo.pixelkarte-farbe-pk1000.noscale',
30+
'FORMAT': 'image/jpeg'
31+
},
32+
url: 'http://wms.geo.admin.ch/',
33+
projection: 'EPSG:21781'
34+
});
35+
const ol2d = new olMap({
36+
layers: [
37+
new olLayerTile({source: new olSourceOSM()}),
38+
new olLayerTile({
39+
source
40+
})
41+
],
42+
target: 'map',
43+
view: new olView({
44+
projection: 'EPSG:4326',
45+
center: [6.56273, 46.51781],
46+
zoom: 6
47+
})
48+
});
49+
const ol3d = new OLCesium({map: ol2d});
50+
const scene = ol3d.getCesiumScene();
51+
const terrainProvider = new Cesium.CesiumTerrainProvider({
52+
url: '//assets.agi.com/stk-terrain/world'
53+
});
54+
scene.terrainProvider = terrainProvider;
55+
ol3d.setEnabled(true);
56+
57+
document.getElementById('enable').addEventListener('click', () => ol3d.setEnabled(!ol3d.getEnabled()));
58+
59+
export default exports;

src/olcs/core.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import olSourceTileWMS from 'ol/source/TileWMS.js';
1313
import {defaultImageLoadFunction} from 'ol/source/Image.js';
1414
import olcsCoreOLImageryProvider from './core/OLImageryProvider.js';
1515
import olcsUtil from './util.js';
16+
import {ENABLE_RASTER_REPROJECTION} from 'ol/reproj/common';
1617

1718

1819
/**
@@ -395,7 +396,7 @@ exports.tileLayerToImageryLayer = function(olMap, olLayer, viewProj) {
395396
projection = viewProj;
396397
}
397398

398-
if (exports.isCesiumProjection(projection)) {
399+
if (exports.isCesiumProjection(projection) || ENABLE_RASTER_REPROJECTION) {
399400
provider = new olcsCoreOLImageryProvider(olMap, source, viewProj);
400401
}
401402
// Projection not supported by Cesium

src/olcs/core/OLImageryProvider.js

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
*/
44
import {get as getProjection} from 'ol/proj.js';
55
import olcsUtil from '../util.js';
6+
import {ENABLE_RASTER_REPROJECTION} from 'ol/reproj/common';
7+
import olTileState from 'ol/TileState';
8+
import {listen, unlistenByKey} from 'ol/events';
69

710
class OLImageryProvider /* should not extend Cesium.ImageryProvider */ {
811
/**
@@ -96,6 +99,9 @@ class OLImageryProvider /* should not extend Cesium.ImageryProvider */ {
9699
this.tilingScheme_ = new Cesium.GeographicTilingScheme();
97100
} else if (this.projection_ == getProjection('EPSG:3857')) {
98101
this.tilingScheme_ = new Cesium.WebMercatorTilingScheme();
102+
} else if (ENABLE_RASTER_REPROJECTION) {
103+
this.tilingScheme_ = new Cesium.GeographicTilingScheme();
104+
this.projection_ = getProjection('EPSG:4326');
99105
} else {
100106
return;
101107
}
@@ -138,24 +144,47 @@ class OLImageryProvider /* should not extend Cesium.ImageryProvider */ {
138144
* @override
139145
*/
140146
requestImage(x, y, level) {
141-
const tileUrlFunction = this.source_.getTileUrlFunction();
142-
if (tileUrlFunction && this.projection_) {
143-
144-
// Perform mapping of Cesium tile coordinates to OpenLayers tile coordinates:
145-
// 1) Cesium zoom level 0 is OpenLayers zoom level 1 for EPSG:4326
146-
const z_ = this.tilingScheme_ instanceof Cesium.GeographicTilingScheme ? level + 1 : level;
147-
// 2) OpenLayers tile coordinates increase from bottom to top
148-
const y_ = -y - 1;
149-
150-
let url = tileUrlFunction.call(this.source_,
151-
[z_, x, y_], 1, this.projection_);
152-
if (this.proxy_) {
153-
url = this.proxy_.getURL(url);
154-
}
155-
return url ? Cesium.ImageryProvider.loadImage(this, url) : this.emptyCanvas_;
147+
// Perform mapping of Cesium tile coordinates to ol3 tile coordinates:
148+
// 1) Cesium zoom level 0 is OpenLayers zoom level 1 for EPSG:4326
149+
const z_ = this.tilingScheme_ instanceof Cesium.GeographicTilingScheme ? level + 1 : level;
150+
// 2) OpenLayers tile coordinates increase from bottom to top
151+
const y_ = -y - 1;
152+
153+
const tilegrid = this.source_.getTileGridForProjection(this.projection_);
154+
if (z_ < tilegrid.getMinZoom() || z_ > tilegrid.getMaxZoom()) {
155+
return Promise.resolve(this.emptyCanvas_); // no data
156+
}
157+
158+
const tile = this.source_.getTile(z_, x, y_, 1, this.projection_);
159+
160+
tile.load();
161+
162+
// not yet loaded!
163+
// const image = tile.getImage();
164+
// if (!image || !image.src) {
165+
// return this.emptyCanvas_; // no data
166+
// }
167+
168+
169+
const state = tile.getState();
170+
if (state === olTileState.LOADED || state === olTileState.EMPTY) {
171+
return Promise.resolve(tile.getImage()) || undefined;
172+
} else if (state === olTileState.ERROR) {
173+
return undefined; // let Cesium continue retrieving later
156174
} else {
157-
// return empty canvas to stop Cesium from retrying later
158-
return this.emptyCanvas_;
175+
const promise = new Promise((resolve, reject) => {
176+
const unlisten = listen(tile, 'change', (evt) => {
177+
const state = tile.getState();
178+
if (state === olTileState.LOADED || state === olTileState.EMPTY) {
179+
resolve(tile.getImage() || undefined);
180+
unlistenByKey(unlisten);
181+
} else if (state === olTileState.ERROR) {
182+
resolve(undefined); // let Cesium continue retrieving later
183+
unlistenByKey(unlisten);
184+
}
185+
});
186+
});
187+
return promise;
159188
}
160189
}
161190
}

0 commit comments

Comments
 (0)