Skip to content

Instantly share code, notes, and snippets.

@pksorensen
Last active August 28, 2015 09:53
Show Gist options
  • Save pksorensen/8ee1afd8253ba8f30b48 to your computer and use it in GitHub Desktop.
Save pksorensen/8ee1afd8253ba8f30b48 to your computer and use it in GitHub Desktop.
var viewer = new Cesium.Viewer('cesiumContainer', {
baseLayerPicker : false
});
var imageryLayers = viewer.imageryLayers;
require(["https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.10/proj4-src.js"],function(proj4){
proj4.defs("EPSG:25832", "+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs");
var cache={};var cache1={};
var Proj4WebMapProjection = (function () {
function Proj4WebMapProjection(ellipsoid, code) {
if (ellipsoid === void 0) { ellipsoid = Cesium.Ellipsoid.WGS84; }
if (code === void 0) { code = "EPSG:25832"; }
this.ellipsoid = ellipsoid;
this._proj = proj4(code);
}
Proj4WebMapProjection.prototype.project = function (cartographic, result) {
var epgscustom = this._proj.forward([Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)]);
if (!Cesium.defined(result)) {
return new Cesium.Cartesian3(epgscustom[0], epgscustom[1], cartographic.height);
}
result.x = epgscustom[0];
result.y = epgscustom[1];
result.z = cartographic.height;
return result;
};
Proj4WebMapProjection.prototype.unproject = function (cartesian, result) {
var wgs84 = this._proj.inverse([cartesian.x, cartesian.y, cartesian.z]);
if (!Cesium.defined(result)) {
return new Cesium.Cartographic(Cesium.Math.toRadians(wgs84[0]), Cesium.Math.toRadians(wgs84[1]), cartesian.z);
}
result.longitude = Cesium.Math.toRadians(wgs84[0]);
result.latitude = Cesium.Math.toRadians(wgs84[1]);
result.height = cartesian.z;
return result;
};
return Proj4WebMapProjection;
})();
var Epsg25832TilingSchema = (function () {
function Epsg25832TilingSchema(options) {
if (options === void 0) { options = {}; }
this._numberOfLevelZeroTilesX = 1;
this._numberOfLevelZeroTilesY = 1;
this._rectangleSouthwestInMeters = new Cesium.Cartesian2;
this._rectangleNortheastInMeters = new Cesium.Cartesian2;
this.skipfirst2 = 2; //Have to skip those two to ignore the guard in ImageProvider.
this.ellipsoid = Cesium.defaultValue(options.ellipsoid, Cesium.Ellipsoid.WGS84);
this._numberOfLevelZeroTilesX = Cesium.defaultValue(options.numberOfLevelZeroTilesX, 1);
this._numberOfLevelZeroTilesY = Cesium.defaultValue(options.numberOfLevelZeroTilesY, 1);
this.projection = new Proj4WebMapProjection(this.ellipsoid);
if (Cesium.defined(options.rectangleSouthwestInMeters) &&
Cesium.defined(options.rectangleNortheastInMeters)) {
this._rectangleSouthwestInMeters = options.rectangleSouthwestInMeters;
this._rectangleNortheastInMeters = options.rectangleNortheastInMeters;
}
else {
throw new Cesium.DeveloperError("The rectangle should be given for the extend, and it should be fitted to the tile extent");
}
var southwest = this.projection.unproject(this._rectangleSouthwestInMeters);
var northeast = this.projection.unproject(this._rectangleNortheastInMeters);
this.rectangle = new Cesium.Rectangle(southwest.longitude, southwest.latitude, northeast.longitude, northeast.latitude);
}
Epsg25832TilingSchema.prototype.getNumberOfXTilesAtLevel = function (level) {
return this._numberOfLevelZeroTilesX << level;
};
Epsg25832TilingSchema.prototype.getNumberOfYTilesAtLevel = function (level) {
return this._numberOfLevelZeroTilesY << level;
};
Epsg25832TilingSchema.prototype.rectangleToNativeRectangle = function (rectangle, result) {
console.log(["rectangleToNativeRectangle", rectangle]);
var southwest = this.projection.project(Cesium.Rectangle.southwest(rectangle));
var northeast = this.projection.project(Cesium.Rectangle.northeast(rectangle));
if (!Cesium.defined(result)) {
return new Cesium.Rectangle(southwest.x, southwest.y, northeast.x, northeast.y);
}
result.west = southwest.x;
result.south = southwest.y;
result.east = northeast.x;
result.north = northeast.y;
return result;
};
Epsg25832TilingSchema.prototype.tileXYToNativeRectangle = function (x, y, level, result) {
var xTiles = this.getNumberOfXTilesAtLevel(level);
var yTiles = this.getNumberOfYTilesAtLevel(level);
var xTileWidth = (this._rectangleNortheastInMeters.x - this._rectangleSouthwestInMeters.x) / xTiles;
var west = this._rectangleSouthwestInMeters.x + x * xTileWidth;
var east = this._rectangleSouthwestInMeters.x + (x + 1) * xTileWidth;
var yTileHeight = (this._rectangleNortheastInMeters.y - this._rectangleSouthwestInMeters.y) / yTiles;
var north = this._rectangleNortheastInMeters.y - y * yTileHeight;
var south = this._rectangleNortheastInMeters.y - (y + 1) * yTileHeight;
cache1[x.toString() + y.toString() + level.toString()] = { tw: xTileWidth, th: yTileHeight, west: west, east: east, north: north, south: south };
console.log(["tileXYToNativeRectangle", x, y, level, xTiles, yTiles, xTileWidth, yTileHeight, west, east, north, south]);
if (!Cesium.defined(result)) {
return new Cesium.Rectangle(west, south, east, north);
}
result.west = west;
result.south = south;
result.east = east;
result.north = north;
return result;
};
Epsg25832TilingSchema.prototype.tileXYToRectangle = function (x, y, level, result) {
var key = x.toString() + y.toString() + level.toString();
if (cache[key]) {
return cache[key];
}
var nativeRectangle = this.tileXYToNativeRectangle(x, y, level, result);
var southwest = this.projection.unproject(new Cesium.Cartesian3(nativeRectangle.west, nativeRectangle.south, 0));
var northeast = this.projection.unproject(new Cesium.Cartesian3(nativeRectangle.east, nativeRectangle.north, 0));
console.log(["tileXYToRectangle", x, y, level, Cesium.Math.toDegrees(southwest.longitude), Cesium.Math.toDegrees(southwest.latitude), Cesium.Math.toDegrees(northeast.longitude), Cesium.Math.toDegrees(northeast.latitude)]);
nativeRectangle.west = southwest.longitude;
nativeRectangle.south = southwest.latitude;
nativeRectangle.east = northeast.longitude;
nativeRectangle.north = northeast.latitude;
cache[key] = nativeRectangle;
return nativeRectangle;
};
Epsg25832TilingSchema.prototype.positionToTileXY = function (position, level, result) {
if (this.skipfirst2 && this.skipfirst2-- > 0){
return new Cesium.Cartesian2(0, 0);
}
if (!Cesium.Rectangle.contains(this.rectangle, position)) {
// outside the bounds of the tiling scheme
return undefined;
}
console.log(["positionToTileXY", this.rectangle, Cesium.Math.toDegrees(position.longitude), Cesium.Math.toDegrees(position.latitude), level]);
var xTiles = this.getNumberOfXTilesAtLevel(level);
var yTiles = this.getNumberOfYTilesAtLevel(level);
var overallWidth = this._rectangleNortheastInMeters.x - this._rectangleSouthwestInMeters.x;
var xTileWidth = overallWidth / xTiles;
var overallHeight = this._rectangleNortheastInMeters.y - this._rectangleSouthwestInMeters.y;
var yTileHeight = overallHeight / yTiles;
var webMercatorPosition = this.projection.project(position);
var distanceFromWest = webMercatorPosition.x - this._rectangleSouthwestInMeters.x;
var distanceFromNorth = this._rectangleNortheastInMeters.y - webMercatorPosition.y;
var xTileCoordinate = distanceFromWest / xTileWidth | 0;
if (xTileCoordinate >= xTiles) {
xTileCoordinate = xTiles - 1;
}
var yTileCoordinate = distanceFromNorth / yTileHeight | 0;
if (yTileCoordinate >= yTiles) {
yTileCoordinate = yTiles - 1;
}
if (!Cesium.defined(result)) {
return new Cesium.Cartesian2(xTileCoordinate, yTileCoordinate);
}
result.x = xTileCoordinate;
result.y = yTileCoordinate;
return result;
};
return Epsg25832TilingSchema;
})();
addAdditionalLayerOption(
'Grid',
new Cesium.GridImageryProvider({tilingScheme : new Epsg25832TilingSchema(
{
rectangleSouthwestInMeters: new Cesium.Cartesian2(120000, 5661139.2),
rectangleNortheastInMeters: new Cesium.Cartesian2(1378291.2, 6500000),
numberOfLevelZeroTilesX: 3,
numberOfLevelZeroTilesY:2
})
}), 1.0, false);
addAdditionalLayerOption(
'Tile Coordinates',
new Cesium.TileCoordinatesImageryProvider({tilingScheme : new Epsg25832TilingSchema(
{
rectangleSouthwestInMeters: new Cesium.Cartesian2(120000, 5661139.2),
rectangleNortheastInMeters: new Cesium.Cartesian2(1378291.2, 6500000),
numberOfLevelZeroTilesX: 3,
numberOfLevelZeroTilesY:2
})
}), 1.0, false);
updateLayerList();
});
var viewModel = {
layers : [],
baseLayers : [],
upLayer : null,
downLayer : null,
selectedLayer : null,
isSelectableLayer : function(layer) {
return baseLayers.indexOf(layer) >= 0;
},
raise : function(layer, index) {
imageryLayers.raise(layer);
viewModel.upLayer = layer;
viewModel.downLayer = viewModel.layers[Math.max(0, index - 1)];
updateLayerList();
window.setTimeout(function() { viewModel.upLayer = viewModel.downLayer = null; }, 10);
},
lower : function(layer, index) {
imageryLayers.lower(layer);
viewModel.upLayer = viewModel.layers[Math.min(viewModel.layers.length - 1, index + 1)];
viewModel.downLayer = layer;
updateLayerList();
window.setTimeout(function() { viewModel.upLayer = viewModel.downLayer = null; }, 10);
},
canRaise : function(layerIndex) {
return layerIndex > 0;
},
canLower : function(layerIndex) {
return layerIndex >= 0 && layerIndex < imageryLayers.length - 1;
}
};
Cesium.knockout.track(viewModel);
var baseLayers = viewModel.baseLayers;
function setupLayers() {
// Create all the base layers that this example will support.
// These base layers aren't really special. It's possible to have multiple of them
// enabled at once, just like the other layers, but it doesn't make much sense because
// all of these layers cover the entire globe and are opaque.
}
function addBaseLayerOption(name, imageryProvider) {
var layer;
if (typeof imageryProvider === 'undefined') {
layer = imageryLayers.get(0);
viewModel.selectedLayer = layer;
} else {
layer = new Cesium.ImageryLayer(imageryProvider);
}
layer.name = name;
baseLayers.push(layer);
}
function addAdditionalLayerOption(name, imageryProvider, alpha, show) {
var layer = imageryLayers.addImageryProvider(imageryProvider);
layer.alpha = Cesium.defaultValue(alpha, 0.5);
layer.show = Cesium.defaultValue(show, true);
layer.name = name;
Cesium.knockout.track(layer, ['alpha', 'show', 'name']);
}
function updateLayerList() {
var numLayers = imageryLayers.length;
viewModel.layers.splice(0, viewModel.layers.length);
for (var i = numLayers - 1; i >= 0; --i) {
viewModel.layers.push(imageryLayers.get(i));
}
}
setupLayers();
updateLayerList();
//Bind the viewModel to the DOM elements of the UI that call for it.
var toolbar = document.getElementById('toolbar');
Cesium.knockout.applyBindings(viewModel, toolbar);
Cesium.knockout.getObservable(viewModel, 'selectedLayer').subscribe(function(baseLayer) {
// Handle changes to the drop-down base layer selector.
var activeLayerIndex = 0;
var numLayers = viewModel.layers.length;
for (var i = 0; i < numLayers; ++i) {
if (viewModel.isSelectableLayer(viewModel.layers[i])) {
activeLayerIndex = i;
break;
}
}
var activeLayer = viewModel.layers[activeLayerIndex];
var show = activeLayer.show;
var alpha = activeLayer.alpha;
imageryLayers.remove(activeLayer, false);
imageryLayers.add(baseLayer, numLayers - activeLayerIndex - 1);
baseLayer.show = show;
baseLayer.alpha = alpha;
updateLayerList();
});
<style>
@import url(../templates/bucket.css);
#toolbar {
background: rgba(42, 42, 42, 0.8);
padding: 4px;
border-radius: 4px;
}
#toolbar input {
vertical-align: middle;
padding-top: 2px;
padding-bottom: 2px;
}
#toolbar table tr {
transform: translateY(0);
transition: transform 0.4s ease-out;
}
#toolbar table tr.up {
transform: translateY(33px);
transition: none;
}
#toolbar table tr.down {
transform: translateY(-33px);
transition: none;
}
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<div id="toolbar">
<table><tbody data-bind="foreach: layers">
<tr data-bind="css: { up: $parent.upLayer === $data, down: $parent.downLayer === $data }">
<td><input type="checkbox" data-bind="checked: show"></td>
<td>
<span data-bind="text: name, visible: !$parent.isSelectableLayer($data)"></span>
<select data-bind="visible: $parent.isSelectableLayer($data), options: $parent.baseLayers, optionsText: 'name', value: $parent.selectedLayer"></select>
</td>
<td>
<input type="range" min="0" max="1" step="0.01" data-bind="value: alpha, valueUpdate: 'input'">
</td>
<td><button type="button" class="cesium-button" data-bind="click: function() { $parent.raise($data, $index()); }, visible: $parent.canRaise($index())">▲</button></td>
<td><button type="button" class="cesium-button" data-bind="click: function() { $parent.lower($data, $index()); }, visible: $parent.canLower($index())">▼</button></td>
</tr>
</tbody></table>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment