Last active
August 28, 2015 09:53
-
-
Save pksorensen/8ee1afd8253ba8f30b48 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
}); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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