Merge branch 'master' of github.com:openlayers/ol3 into vector
This commit is contained in:
40
src/imageurlfunction.js
Normal file
40
src/imageurlfunction.js
Normal file
@@ -0,0 +1,40 @@
|
||||
goog.provide('ol.ImageUrlFunction');
|
||||
goog.provide('ol.ImageUrlFunctionType');
|
||||
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Size');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {function(ol.Extent, ol.Size): (string|undefined)}
|
||||
*/
|
||||
ol.ImageUrlFunctionType;
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} baseUrl Base URL (may have query data).
|
||||
* @return {ol.ImageUrlFunctionType} Image URL function.
|
||||
*/
|
||||
ol.ImageUrlFunction.createBboxParam = function(baseUrl) {
|
||||
return function(extent, size) {
|
||||
// FIXME Projection dependant axis order.
|
||||
var bboxValue = [
|
||||
extent.minX, extent.minY, extent.maxX, extent.maxY
|
||||
].join(',');
|
||||
return goog.uri.utils.appendParams(baseUrl,
|
||||
'BBOX', bboxValue,
|
||||
'HEIGHT', size.height,
|
||||
'WIDTH', size.width);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {ol.Size} size Size.
|
||||
* @return {string|undefined} Image URL.
|
||||
*/
|
||||
ol.ImageUrlFunction.nullImageUrlFunction =
|
||||
function(extent, size) {
|
||||
return undefined;
|
||||
};
|
||||
@@ -92,10 +92,29 @@
|
||||
@exportObjectLiteralProperty ol.source.DebugTileSourceOptions.projection ol.Projection|undefined
|
||||
@exportObjectLiteralProperty ol.source.DebugTileSourceOptions.tileGrid ol.tilegrid.TileGrid|undefined
|
||||
|
||||
@exportObjectLiteral ol.source.SingleImageWMSOptions
|
||||
@exportObjectLiteralProperty ol.source.SingleImageWMSOptions.attributions Array.<ol.Attribution>|undefined
|
||||
@exportObjectLiteralProperty ol.source.SingleImageWMSOptions.crossOrigin null|string|undefined
|
||||
@exportObjectLiteralProperty ol.source.SingleImageWMSOptions.extent ol.Extent|undefined
|
||||
@exportObjectLiteralProperty ol.source.SingleImageWMSOptions.params Object.<string,*>
|
||||
@exportObjectLiteralProperty ol.source.SingleImageWMSOptions.projection ol.Projection|undefined
|
||||
@exportObjectLiteralProperty ol.source.SingleImageWMSOptions.resolutions Array.<number>|undefined
|
||||
@exportObjectLiteralProperty ol.source.SingleImageWMSOptions.url string|undefined
|
||||
@exportObjectLiteralProperty ol.source.SingleImageWMSOptions.version string|undefined
|
||||
|
||||
@exportObjectLiteral ol.source.StamenOptions
|
||||
@exportObjectLiteralProperty ol.source.StamenOptions.flavor string|undefined
|
||||
@exportObjectLiteralProperty ol.source.StamenOptions.provider string
|
||||
|
||||
@exportObjectLiteral ol.source.StaticImageOptions
|
||||
@exportObjectLiteralProperty ol.source.StaticImageOptions.attributions Array.<ol.Attribution>|undefined
|
||||
@exportObjectLiteralProperty ol.source.StaticImageOptions.crossOrigin null|string|undefined
|
||||
@exportObjectLiteralProperty ol.source.StaticImageOptions.extent ol.Extent|undefined
|
||||
@exportObjectLiteralProperty ol.source.StaticImageOptions.imageExtent ol.Extent|undefined
|
||||
@exportObjectLiteralProperty ol.source.StaticImageOptions.imageSize ol.Size|undefined
|
||||
@exportObjectLiteralProperty ol.source.StaticImageOptions.projection ol.Projection|undefined
|
||||
@exportObjectLiteralProperty ol.source.StaticImageOptions.url string|undefined
|
||||
|
||||
@exportObjectLiteral ol.source.TiledWMSOptions
|
||||
@exportObjectLiteralProperty ol.source.TiledWMSOptions.attributions Array.<ol.Attribution>|undefined
|
||||
@exportObjectLiteralProperty ol.source.TiledWMSOptions.params Object
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// FIXME handle date line wrap
|
||||
// FIXME does not handle image sources
|
||||
|
||||
goog.provide('ol.control.Attribution');
|
||||
|
||||
|
||||
170
src/ol/ellipsoid.js
Normal file
170
src/ol/ellipsoid.js
Normal file
@@ -0,0 +1,170 @@
|
||||
goog.provide('ol.Ellipsoid');
|
||||
|
||||
goog.require('goog.math');
|
||||
goog.require('ol.Coordinate');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {number} a Major radius.
|
||||
* @param {number} flattening Flattening.
|
||||
*/
|
||||
ol.Ellipsoid = function(a, flattening) {
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a = a;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.flattening = flattening;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.b = this.a * (1 - this.flattening);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Coordinate} c1 Coordinate 1.
|
||||
* @param {ol.Coordinate} c2 Coordinate 1.
|
||||
* @param {number=} opt_minDeltaLambda Minimum delta lambda for convergence.
|
||||
* @param {number=} opt_maxIterations Maximum iterations.
|
||||
* @return {{distance: number, initialBearing: number, finalBearing: number}}
|
||||
* Vincenty.
|
||||
*/
|
||||
ol.Ellipsoid.prototype.vincenty =
|
||||
function(c1, c2, opt_minDeltaLambda, opt_maxIterations) {
|
||||
var minDeltaLambda = goog.isDef(opt_minDeltaLambda) ?
|
||||
opt_minDeltaLambda : 1e-12;
|
||||
var maxIterations = goog.isDef(opt_maxIterations) ?
|
||||
opt_maxIterations : 100;
|
||||
var f = this.flattening;
|
||||
var lat1 = goog.math.toRadians(c1.y);
|
||||
var lat2 = goog.math.toRadians(c2.y);
|
||||
var deltaLon = goog.math.toRadians(c2.x - c1.x);
|
||||
var U1 = Math.atan((1 - f) * Math.tan(lat1));
|
||||
var cosU1 = Math.cos(U1);
|
||||
var sinU1 = Math.sin(U1);
|
||||
var U2 = Math.atan((1 - f) * Math.tan(lat2));
|
||||
var cosU2 = Math.cos(U2);
|
||||
var sinU2 = Math.sin(U2);
|
||||
var lambda = deltaLon;
|
||||
var cosSquaredAlpha, sinAlpha;
|
||||
var cosLambda, deltaLambda = Infinity, sinLambda;
|
||||
var cos2SigmaM, cosSigma, sigma, sinSigma;
|
||||
var i;
|
||||
for (i = maxIterations; i > 0; --i) {
|
||||
cosLambda = Math.cos(lambda);
|
||||
sinLambda = Math.sin(lambda);
|
||||
var x = cosU2 * sinLambda;
|
||||
var y = cosU1 * sinU2 - sinU1 * cosU2 * cosLambda;
|
||||
sinSigma = Math.sqrt(x * x + y * y);
|
||||
if (sinSigma === 0) {
|
||||
return {
|
||||
distance: 0,
|
||||
initialBearing: 0,
|
||||
finalBearing: 0
|
||||
};
|
||||
}
|
||||
cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
|
||||
sigma = Math.atan2(sinSigma, cosSigma);
|
||||
sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
|
||||
cosSquaredAlpha = 1 - sinAlpha * sinAlpha;
|
||||
cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSquaredAlpha;
|
||||
if (isNaN(cos2SigmaM)) {
|
||||
cos2SigmaM = 0;
|
||||
}
|
||||
var C = f / 16 * cosSquaredAlpha * (4 + f * (4 - 3 * cosSquaredAlpha));
|
||||
var lambdaPrime = deltaLon + (1 - C) * f * sinAlpha * (sigma +
|
||||
C * sinSigma * (cos2SigmaM +
|
||||
C * cosSigma * (2 * cos2SigmaM * cos2SigmaM - 1)));
|
||||
deltaLambda = Math.abs(lambdaPrime - lambda);
|
||||
lambda = lambdaPrime;
|
||||
if (deltaLambda < minDeltaLambda) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i === 0) {
|
||||
return {
|
||||
distance: NaN,
|
||||
finalBearing: NaN,
|
||||
initialBearing: NaN
|
||||
};
|
||||
}
|
||||
var aSquared = this.a * this.a;
|
||||
var bSquared = this.b * this.b;
|
||||
var uSquared = cosSquaredAlpha * (aSquared - bSquared) / bSquared;
|
||||
var A = 1 + uSquared / 16384 *
|
||||
(4096 + uSquared * (uSquared * (320 - 175 * uSquared) - 768));
|
||||
var B = uSquared / 1024 *
|
||||
(256 + uSquared * (uSquared * (74 - 47 * uSquared) - 128));
|
||||
var deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 *
|
||||
(cosSigma * (2 * cos2SigmaM * cos2SigmaM - 1) -
|
||||
B / 6 * cos2SigmaM * (4 * sinSigma * sinSigma - 3) *
|
||||
(4 * cos2SigmaM * cos2SigmaM - 3)));
|
||||
cosLambda = Math.cos(lambda);
|
||||
sinLambda = Math.sin(lambda);
|
||||
var alpha1 = Math.atan2(cosU2 * sinLambda,
|
||||
cosU1 * sinU2 - sinU1 * cosU2 * cosLambda);
|
||||
var alpha2 = Math.atan2(cosU1 * sinLambda,
|
||||
cosU1 * sinU2 * cosLambda - sinU1 * cosU2);
|
||||
return {
|
||||
distance: this.b * A * (sigma - deltaSigma),
|
||||
initialBearing: goog.math.toDegrees(alpha1),
|
||||
finalBearing: goog.math.toDegrees(alpha2)
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the distance from c1 to c2 using Vincenty.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 Coordinate 1.
|
||||
* @param {ol.Coordinate} c2 Coordinate 1.
|
||||
* @param {number=} opt_minDeltaLambda Minimum delta lambda for convergence.
|
||||
* @param {number=} opt_maxIterations Maximum iterations.
|
||||
* @return {number} Vincenty distance.
|
||||
*/
|
||||
ol.Ellipsoid.prototype.vincentyDistance =
|
||||
function(c1, c2, opt_minDeltaLambda, opt_maxIterations) {
|
||||
var vincenty = this.vincenty(c1, c2, opt_minDeltaLambda, opt_maxIterations);
|
||||
return vincenty.distance;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the final bearing from c1 to c2 using Vincenty.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 Coordinate 1.
|
||||
* @param {ol.Coordinate} c2 Coordinate 1.
|
||||
* @param {number=} opt_minDeltaLambda Minimum delta lambda for convergence.
|
||||
* @param {number=} opt_maxIterations Maximum iterations.
|
||||
* @return {number} Initial bearing.
|
||||
*/
|
||||
ol.Ellipsoid.prototype.vincentyFinalBearing =
|
||||
function(c1, c2, opt_minDeltaLambda, opt_maxIterations) {
|
||||
var vincenty = this.vincenty(c1, c2, opt_minDeltaLambda, opt_maxIterations);
|
||||
return vincenty.finalBearing;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the initial bearing from c1 to c2 using Vincenty.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 Coordinate 1.
|
||||
* @param {ol.Coordinate} c2 Coordinate 1.
|
||||
* @param {number=} opt_minDeltaLambda Minimum delta lambda for convergence.
|
||||
* @param {number=} opt_maxIterations Maximum iterations.
|
||||
* @return {number} Initial bearing.
|
||||
*/
|
||||
ol.Ellipsoid.prototype.vincentyInitialBearing =
|
||||
function(c1, c2, opt_minDeltaLambda, opt_maxIterations) {
|
||||
var vincenty = this.vincenty(c1, c2, opt_minDeltaLambda, opt_maxIterations);
|
||||
return vincenty.initialBearing;
|
||||
};
|
||||
10
src/ol/ellipsoid/wgs84.js
Normal file
10
src/ol/ellipsoid/wgs84.js
Normal file
@@ -0,0 +1,10 @@
|
||||
goog.provide('ol.ellipsoid.WGS84');
|
||||
|
||||
goog.require('ol.Ellipsoid');
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.Ellipsoid}
|
||||
*/
|
||||
ol.ellipsoid.WGS84 = new ol.Ellipsoid(6378137, 1 / 298.257223563);
|
||||
@@ -46,17 +46,31 @@ ol.Extent.boundingExtent = function(var_args) {
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the given coordinate is contained or on the edge of the extent.
|
||||
* Checks if the passed coordinate is contained or on the edge
|
||||
* of the extent.
|
||||
*
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @return {boolean} Contains.
|
||||
*/
|
||||
ol.Extent.prototype.contains = function(coordinate) {
|
||||
ol.Extent.prototype.containsCoordinate = function(coordinate) {
|
||||
return this.minX <= coordinate.x && coordinate.x <= this.maxX &&
|
||||
this.minY <= coordinate.y && coordinate.y <= this.maxY;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the passed extent is contained or on the edge of the
|
||||
* extent.
|
||||
*
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @return {boolean} Contains.
|
||||
*/
|
||||
ol.Extent.prototype.containsExtent = function(extent) {
|
||||
return this.minX <= extent.minX && extent.maxX <= this.maxX &&
|
||||
this.minY <= extent.minY && extent.maxY <= this.maxY;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Coordinate} Bottom left coordinate.
|
||||
*/
|
||||
|
||||
@@ -5,6 +5,7 @@ goog.provide('ol.Geolocation');
|
||||
goog.provide('ol.GeolocationProperty');
|
||||
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.math');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Object');
|
||||
goog.require('ol.Projection');
|
||||
@@ -15,8 +16,12 @@ goog.require('ol.Projection');
|
||||
*/
|
||||
ol.GeolocationProperty = {
|
||||
ACCURACY: 'accuracy',
|
||||
ALTITUDE: 'altitude',
|
||||
ALTITUDE_ACCURACY: 'altitudeAccuracy',
|
||||
HEADING: 'heading',
|
||||
POSITION: 'position',
|
||||
PROJECTION: 'projection'
|
||||
PROJECTION: 'projection',
|
||||
SPEED: 'speed'
|
||||
};
|
||||
|
||||
|
||||
@@ -92,10 +97,19 @@ ol.Geolocation.isSupported = 'geolocation' in navigator;
|
||||
*/
|
||||
ol.Geolocation.prototype.positionChange_ = function(position) {
|
||||
var coords = position.coords;
|
||||
this.set(ol.GeolocationProperty.ACCURACY, coords.accuracy);
|
||||
this.set(ol.GeolocationProperty.ALTITUDE,
|
||||
goog.isNull(coords.altitude) ? undefined : coords.altitude);
|
||||
this.set(ol.GeolocationProperty.ALTITUDE_ACCURACY,
|
||||
goog.isNull(coords.altitudeAccuracy) ?
|
||||
undefined : coords.altitudeAccuracy);
|
||||
this.set(ol.GeolocationProperty.HEADING, goog.isNull(coords.heading) ?
|
||||
undefined : goog.math.toRadians(coords.heading));
|
||||
this.position_ = new ol.Coordinate(coords.longitude, coords.latitude);
|
||||
this.set(ol.GeolocationProperty.POSITION,
|
||||
this.transformCoords_(this.position_));
|
||||
this.set(ol.GeolocationProperty.ACCURACY, coords.accuracy);
|
||||
this.set(ol.GeolocationProperty.SPEED,
|
||||
goog.isNull(coords.speed) ? undefined : coords.speed);
|
||||
};
|
||||
|
||||
|
||||
@@ -107,20 +121,6 @@ ol.Geolocation.prototype.positionError_ = function(error) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The position of the device.
|
||||
* @return {ol.Coordinate|undefined} position.
|
||||
*/
|
||||
ol.Geolocation.prototype.getPosition = function() {
|
||||
return /** @type {ol.Coordinate} */ (
|
||||
this.get(ol.GeolocationProperty.POSITION));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Geolocation.prototype,
|
||||
'getPosition',
|
||||
ol.Geolocation.prototype.getPosition);
|
||||
|
||||
|
||||
/**
|
||||
* The accuracy of the position in meters.
|
||||
* @return {number|undefined} accuracy.
|
||||
@@ -135,6 +135,59 @@ goog.exportProperty(
|
||||
ol.Geolocation.prototype.getAccuracy);
|
||||
|
||||
|
||||
/**
|
||||
* @return {number|undefined} Altitude.
|
||||
*/
|
||||
ol.Geolocation.prototype.getAltitude = function() {
|
||||
return /** @type {number|undefined} */ (
|
||||
this.get(ol.GeolocationProperty.ALTITUDE));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Geolocation.prototype,
|
||||
'getAltitude',
|
||||
ol.Geolocation.prototype.getAltitude);
|
||||
|
||||
|
||||
/**
|
||||
* @return {number|undefined} Altitude accuracy.
|
||||
*/
|
||||
ol.Geolocation.prototype.getAltitudeAccuracy = function() {
|
||||
return /** @type {number|undefined} */ (
|
||||
this.get(ol.GeolocationProperty.ALTITUDE_ACCURACY));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Geolocation.prototype,
|
||||
'getAltitudeAccuracy',
|
||||
ol.Geolocation.prototype.getAltitudeAccuracy);
|
||||
|
||||
|
||||
/**
|
||||
* @return {number|undefined} Heading.
|
||||
*/
|
||||
ol.Geolocation.prototype.getHeading = function() {
|
||||
return /** @type {number|undefined} */ (
|
||||
this.get(ol.GeolocationProperty.HEADING));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Geolocation.prototype,
|
||||
'getHeading',
|
||||
ol.Geolocation.prototype.getHeading);
|
||||
|
||||
|
||||
/**
|
||||
* The position of the device.
|
||||
* @return {ol.Coordinate|undefined} position.
|
||||
*/
|
||||
ol.Geolocation.prototype.getPosition = function() {
|
||||
return /** @type {ol.Coordinate} */ (
|
||||
this.get(ol.GeolocationProperty.POSITION));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Geolocation.prototype,
|
||||
'getPosition',
|
||||
ol.Geolocation.prototype.getPosition);
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Projection|undefined} projection.
|
||||
*/
|
||||
@@ -148,6 +201,19 @@ goog.exportProperty(
|
||||
ol.Geolocation.prototype.getProjection);
|
||||
|
||||
|
||||
/**
|
||||
* @return {number|undefined} Speed.
|
||||
*/
|
||||
ol.Geolocation.prototype.getSpeed = function() {
|
||||
return /** @type {number|undefined} */ (
|
||||
this.get(ol.GeolocationProperty.SPEED));
|
||||
};
|
||||
goog.exportProperty(
|
||||
ol.Geolocation.prototype,
|
||||
'getSpeed',
|
||||
ol.Geolocation.prototype.getSpeed);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Projection} projection Projection.
|
||||
*/
|
||||
|
||||
187
src/ol/image.js
Normal file
187
src/ol/image.js
Normal file
@@ -0,0 +1,187 @@
|
||||
goog.provide('ol.Image');
|
||||
goog.provide('ol.ImageState');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventTarget');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.Extent');
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
ol.ImageState = {
|
||||
IDLE: 0,
|
||||
LOADING: 1,
|
||||
LOADED: 2,
|
||||
ERROR: 3
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {goog.events.EventTarget}
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {string} src Image source URI.
|
||||
* @param {?string} crossOrigin Cross origin.
|
||||
*/
|
||||
ol.Image = function(extent, resolution, src, crossOrigin) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
this.extent_ = extent;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.src_ = src;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.resolution_ = resolution;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Image}
|
||||
*/
|
||||
this.image_ = new Image();
|
||||
if (!goog.isNull(crossOrigin)) {
|
||||
this.image_.crossOrigin = crossOrigin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<number, Image>}
|
||||
*/
|
||||
this.imageByContext_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.imageListenerKeys_ = null;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {ol.ImageState}
|
||||
*/
|
||||
this.state = ol.ImageState.IDLE;
|
||||
};
|
||||
goog.inherits(ol.Image, goog.events.EventTarget);
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
ol.Image.prototype.dispatchChangeEvent = function() {
|
||||
this.dispatchEvent(goog.events.EventType.CHANGE);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.Extent} Extent.
|
||||
*/
|
||||
ol.Image.prototype.getExtent = function() {
|
||||
return this.extent_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Object=} opt_context Object.
|
||||
* @return {HTMLCanvasElement|Image|HTMLVideoElement} Image.
|
||||
*/
|
||||
ol.Image.prototype.getImageElement = function(opt_context) {
|
||||
if (goog.isDef(opt_context)) {
|
||||
var image;
|
||||
var key = goog.getUid(opt_context);
|
||||
if (key in this.imageByContext_) {
|
||||
return this.imageByContext_[key];
|
||||
} else if (goog.object.isEmpty(this.imageByContext_)) {
|
||||
image = this.image_;
|
||||
} else {
|
||||
image = /** @type {Image} */ (this.image_.cloneNode(false));
|
||||
}
|
||||
this.imageByContext_[key] = image;
|
||||
return image;
|
||||
} else {
|
||||
return this.image_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Resolution.
|
||||
*/
|
||||
ol.Image.prototype.getResolution = function() {
|
||||
return this.resolution_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.ImageState} State.
|
||||
*/
|
||||
ol.Image.prototype.getState = function() {
|
||||
return this.state;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tracks loading or read errors.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ol.Image.prototype.handleImageError_ = function() {
|
||||
this.state = ol.ImageState.ERROR;
|
||||
this.unlistenImage_();
|
||||
this.dispatchChangeEvent();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tracks successful image load.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ol.Image.prototype.handleImageLoad_ = function() {
|
||||
this.state = ol.ImageState.LOADED;
|
||||
this.unlistenImage_();
|
||||
this.dispatchChangeEvent();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Load not yet loaded URI.
|
||||
*/
|
||||
ol.Image.prototype.load = function() {
|
||||
if (this.state == ol.ImageState.IDLE) {
|
||||
this.state = ol.ImageState.LOADING;
|
||||
goog.asserts.assert(goog.isNull(this.imageListenerKeys_));
|
||||
this.imageListenerKeys_ = [
|
||||
goog.events.listenOnce(this.image_, goog.events.EventType.ERROR,
|
||||
this.handleImageError_, false, this),
|
||||
goog.events.listenOnce(this.image_, goog.events.EventType.LOAD,
|
||||
this.handleImageLoad_, false, this)
|
||||
];
|
||||
this.image_.src = this.src_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Discards event handlers which listen for load completion or errors.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
ol.Image.prototype.unlistenImage_ = function() {
|
||||
goog.asserts.assert(!goog.isNull(this.imageListenerKeys_));
|
||||
goog.array.forEach(this.imageListenerKeys_, goog.events.unlistenByKey);
|
||||
this.imageListenerKeys_ = null;
|
||||
};
|
||||
@@ -106,7 +106,8 @@ ol.interaction.DragPan.prototype.handleDragStart = function(mapBrowserEvent) {
|
||||
var browserEvent = mapBrowserEvent.browserEvent;
|
||||
if (this.condition_(browserEvent)) {
|
||||
if (this.kinetic_) {
|
||||
this.kinetic_.begin(browserEvent.clientX, browserEvent.clientY);
|
||||
this.kinetic_.begin();
|
||||
this.kinetic_.update(browserEvent.clientX, browserEvent.clientY);
|
||||
}
|
||||
var map = mapBrowserEvent.map;
|
||||
map.requestRenderFrame();
|
||||
|
||||
@@ -63,14 +63,12 @@ ol.Kinetic = function(decay, minVelocity, delay) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} x X.
|
||||
* @param {number} y Y.
|
||||
* FIXME empty description for jsdoc
|
||||
*/
|
||||
ol.Kinetic.prototype.begin = function(x, y) {
|
||||
ol.Kinetic.prototype.begin = function() {
|
||||
this.points_.length = 0;
|
||||
this.angle_ = 0;
|
||||
this.initialVelocity_ = 0;
|
||||
this.update(x, y);
|
||||
};
|
||||
|
||||
|
||||
|
||||
1
src/ol/layer/imagelayer.exports
Normal file
1
src/ol/layer/imagelayer.exports
Normal file
@@ -0,0 +1 @@
|
||||
@exportClass ol.layer.ImageLayer ol.layer.LayerOptions
|
||||
24
src/ol/layer/imagelayer.js
Normal file
24
src/ol/layer/imagelayer.js
Normal file
@@ -0,0 +1,24 @@
|
||||
goog.provide('ol.layer.ImageLayer');
|
||||
|
||||
goog.require('ol.layer.Layer');
|
||||
goog.require('ol.source.ImageSource');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.layer.Layer}
|
||||
* @param {ol.layer.LayerOptions} layerOptions Layer options.
|
||||
*/
|
||||
ol.layer.ImageLayer = function(layerOptions) {
|
||||
goog.base(this, layerOptions);
|
||||
};
|
||||
goog.inherits(ol.layer.ImageLayer, ol.layer.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.source.ImageSource} Single image source.
|
||||
*/
|
||||
ol.layer.ImageLayer.prototype.getImageSource = function() {
|
||||
return /** @type {ol.source.ImageSource} */ (this.getSource());
|
||||
};
|
||||
@@ -41,6 +41,16 @@ ol.Rectangle = function(minX, minY, maxX, maxY) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Rectangle} rectangle Rectangle.
|
||||
* @return {boolean} Equals.
|
||||
*/
|
||||
ol.Rectangle.prototype.equals = function(rectangle) {
|
||||
return this.minX == rectangle.minX && this.minY == rectangle.minY &&
|
||||
this.maxX == rectangle.maxX && this.maxY == rectangle.maxY;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Rectangle} rectangle Rectangle.
|
||||
*/
|
||||
@@ -114,3 +124,16 @@ ol.Rectangle.prototype.normalize = function(coordinate) {
|
||||
ol.Rectangle.prototype.toString = function() {
|
||||
return '(' + [this.minX, this.minY, this.maxX, this.maxY].join(', ') + ')';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} value Value.
|
||||
*/
|
||||
ol.Rectangle.prototype.scaleFromCenter = function(value) {
|
||||
var deltaX = (this.getWidth() / 2.0) * (value - 1);
|
||||
var deltaY = (this.getHeight() / 2.0) * (value - 1);
|
||||
this.minX -= deltaX;
|
||||
this.minY -= deltaY;
|
||||
this.maxX += deltaX;
|
||||
this.maxY += deltaY;
|
||||
};
|
||||
|
||||
115
src/ol/renderer/canvas/canvasimagelayerrenderer.js
Normal file
115
src/ol/renderer/canvas/canvasimagelayerrenderer.js
Normal file
@@ -0,0 +1,115 @@
|
||||
goog.provide('ol.renderer.canvas.ImageLayer');
|
||||
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.Image');
|
||||
goog.require('ol.ImageState');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.layer.ImageLayer');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.canvas.Layer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.renderer.canvas.Layer}
|
||||
* @param {ol.renderer.Map} mapRenderer Map renderer.
|
||||
* @param {ol.layer.ImageLayer} imageLayer Single image layer.
|
||||
*/
|
||||
ol.renderer.canvas.ImageLayer = function(mapRenderer, imageLayer) {
|
||||
|
||||
goog.base(this, mapRenderer, imageLayer);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {?ol.Image}
|
||||
*/
|
||||
this.image_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.transform_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
};
|
||||
goog.inherits(ol.renderer.canvas.ImageLayer, ol.renderer.canvas.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.ImageLayer.prototype.getImage = function() {
|
||||
return goog.isNull(this.image_) ?
|
||||
null : this.image_.getImageElement(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.layer.ImageLayer} Single image layer.
|
||||
*/
|
||||
ol.renderer.canvas.ImageLayer.prototype.getImageLayer = function() {
|
||||
return /** @type {ol.layer.ImageLayer} */ (this.getLayer());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.ImageLayer.prototype.getTransform = function() {
|
||||
return this.transform_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.ImageLayer.prototype.renderFrame =
|
||||
function(frameState, layerState) {
|
||||
|
||||
var view2DState = frameState.view2DState;
|
||||
var viewCenter = view2DState.center;
|
||||
var viewResolution = view2DState.resolution;
|
||||
var viewRotation = view2DState.rotation;
|
||||
|
||||
var image;
|
||||
var imageLayer = this.getImageLayer();
|
||||
var imageSource = imageLayer.getImageSource();
|
||||
|
||||
var hints = frameState.viewHints;
|
||||
|
||||
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.PANNING]) {
|
||||
image = imageSource.getImage(frameState.extent, viewResolution);
|
||||
if (!goog.isNull(image)) {
|
||||
var imageState = image.getState();
|
||||
if (imageState == ol.ImageState.IDLE) {
|
||||
goog.events.listenOnce(image, goog.events.EventType.CHANGE,
|
||||
this.handleImageChange, false, this);
|
||||
image.load();
|
||||
} else if (imageState == ol.ImageState.LOADED) {
|
||||
this.image_ = image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!goog.isNull(this.image_)) {
|
||||
image = this.image_;
|
||||
var imageExtent = image.getExtent();
|
||||
var imageResolution = image.getResolution();
|
||||
var transform = this.transform_;
|
||||
goog.vec.Mat4.makeIdentity(transform);
|
||||
goog.vec.Mat4.translate(transform,
|
||||
frameState.size.width / 2, frameState.size.height / 2, 0);
|
||||
goog.vec.Mat4.rotateZ(transform, viewRotation);
|
||||
goog.vec.Mat4.scale(
|
||||
transform,
|
||||
imageResolution / viewResolution,
|
||||
imageResolution / viewResolution,
|
||||
1);
|
||||
goog.vec.Mat4.translate(
|
||||
transform,
|
||||
(imageExtent.minX - viewCenter.x) / imageResolution,
|
||||
(viewCenter.y - imageExtent.maxY) / imageResolution,
|
||||
0);
|
||||
}
|
||||
};
|
||||
@@ -7,9 +7,11 @@ goog.require('goog.dom');
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.layer.ImageLayer');
|
||||
goog.require('ol.layer.TileLayer');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.canvas.ImageLayer');
|
||||
goog.require('ol.renderer.canvas.TileLayer');
|
||||
goog.require('ol.renderer.canvas.VectorLayer');
|
||||
|
||||
@@ -61,7 +63,9 @@ goog.inherits(ol.renderer.canvas.Map, ol.renderer.Map);
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.Map.prototype.createLayerRenderer = function(layer) {
|
||||
if (layer instanceof ol.layer.TileLayer) {
|
||||
if (layer instanceof ol.layer.ImageLayer) {
|
||||
return new ol.renderer.canvas.ImageLayer(this, layer);
|
||||
} else if (layer instanceof ol.layer.TileLayer) {
|
||||
return new ol.renderer.canvas.TileLayer(this, layer);
|
||||
} else if (layer instanceof ol.layer.Vector) {
|
||||
return new ol.renderer.canvas.VectorLayer(this, layer);
|
||||
|
||||
122
src/ol/renderer/dom/domimagelayerrenderer.js
Normal file
122
src/ol/renderer/dom/domimagelayerrenderer.js
Normal file
@@ -0,0 +1,122 @@
|
||||
goog.provide('ol.renderer.dom.ImageLayer');
|
||||
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.Image');
|
||||
goog.require('ol.ImageState');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.layer.ImageLayer');
|
||||
goog.require('ol.renderer.dom.Layer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.renderer.dom.Layer}
|
||||
* @param {ol.renderer.Map} mapRenderer Map renderer.
|
||||
* @param {ol.layer.ImageLayer} imageLayer Image layer.
|
||||
*/
|
||||
ol.renderer.dom.ImageLayer = function(mapRenderer, imageLayer) {
|
||||
var target = goog.dom.createElement(goog.dom.TagName.DIV);
|
||||
target.className = 'ol-layer-image';
|
||||
target.style.position = 'absolute';
|
||||
|
||||
goog.base(this, mapRenderer, imageLayer, target);
|
||||
|
||||
/**
|
||||
* The last rendered image.
|
||||
* @private
|
||||
* @type {?ol.Image}
|
||||
*/
|
||||
this.image_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {goog.vec.Mat4.AnyType}
|
||||
*/
|
||||
this.transform_ = goog.vec.Mat4.createNumberIdentity();
|
||||
|
||||
};
|
||||
goog.inherits(ol.renderer.dom.ImageLayer, ol.renderer.dom.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.layer.ImageLayer} Image layer.
|
||||
*/
|
||||
ol.renderer.dom.ImageLayer.prototype.getImageLayer = function() {
|
||||
return /** @type {ol.layer.ImageLayer} */ (this.getLayer());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.ImageLayer.prototype.renderFrame =
|
||||
function(frameState, layerState) {
|
||||
|
||||
var view2DState = frameState.view2DState;
|
||||
var viewCenter = view2DState.center;
|
||||
var viewResolution = view2DState.resolution;
|
||||
var viewRotation = view2DState.rotation;
|
||||
|
||||
var image = this.image_;
|
||||
var imageLayer = this.getImageLayer();
|
||||
var imageSource = imageLayer.getImageSource();
|
||||
|
||||
var hints = frameState.viewHints;
|
||||
|
||||
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.PANNING]) {
|
||||
var image_ = imageSource.getImage(frameState.extent, viewResolution);
|
||||
if (!goog.isNull(image_)) {
|
||||
var imageState = image_.getState();
|
||||
if (imageState == ol.ImageState.IDLE) {
|
||||
goog.events.listenOnce(image_, goog.events.EventType.CHANGE,
|
||||
this.handleImageChange, false, this);
|
||||
image_.load();
|
||||
} else if (imageState == ol.ImageState.LOADED) {
|
||||
image = image_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!goog.isNull(image)) {
|
||||
var imageExtent = image.getExtent();
|
||||
var imageResolution = image.getResolution();
|
||||
var transform = goog.vec.Mat4.createNumber();
|
||||
goog.vec.Mat4.makeIdentity(transform);
|
||||
goog.vec.Mat4.translate(transform,
|
||||
frameState.size.width / 2, frameState.size.height / 2, 0);
|
||||
goog.vec.Mat4.rotateZ(transform, viewRotation);
|
||||
goog.vec.Mat4.scale(
|
||||
transform,
|
||||
imageResolution / viewResolution,
|
||||
imageResolution / viewResolution,
|
||||
1);
|
||||
goog.vec.Mat4.translate(
|
||||
transform,
|
||||
(imageExtent.minX - viewCenter.x) / imageResolution,
|
||||
(viewCenter.y - imageExtent.maxY) / imageResolution,
|
||||
0);
|
||||
if (image != this.image_) {
|
||||
var imageElement = image.getImageElement(this);
|
||||
imageElement.style.position = 'absolute';
|
||||
goog.dom.removeChildren(this.target);
|
||||
goog.dom.appendChild(this.target, imageElement);
|
||||
this.image_ = image;
|
||||
}
|
||||
this.setTransform(transform);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.vec.Mat4.AnyType} transform Transform.
|
||||
*/
|
||||
ol.renderer.dom.ImageLayer.prototype.setTransform = function(transform) {
|
||||
if (!goog.vec.Mat4.equals(transform, this.transform_)) {
|
||||
ol.dom.transformElement2D(this.target, transform, 6);
|
||||
goog.vec.Mat4.setFromArray(this.transform_, transform);
|
||||
}
|
||||
};
|
||||
@@ -5,8 +5,10 @@ goog.require('goog.asserts');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.style');
|
||||
goog.require('ol.layer.ImageLayer');
|
||||
goog.require('ol.layer.TileLayer');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.dom.ImageLayer');
|
||||
goog.require('ol.renderer.dom.TileLayer');
|
||||
|
||||
|
||||
@@ -57,14 +59,15 @@ ol.renderer.dom.Map.prototype.addLayer = function(layer) {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.dom.Map.prototype.createLayerRenderer = function(layer) {
|
||||
var layerRenderer;
|
||||
if (layer instanceof ol.layer.TileLayer) {
|
||||
var layerRenderer = new ol.renderer.dom.TileLayer(this, layer);
|
||||
goog.dom.appendChild(this.layersPane_, layerRenderer.getTarget());
|
||||
return layerRenderer;
|
||||
} else {
|
||||
goog.asserts.assert(false);
|
||||
return null;
|
||||
layerRenderer = new ol.renderer.dom.TileLayer(this, layer);
|
||||
} else if (layer instanceof ol.layer.ImageLayer) {
|
||||
layerRenderer = new ol.renderer.dom.ImageLayer(this, layer);
|
||||
}
|
||||
goog.asserts.assert(goog.isDef(layerRenderer));
|
||||
goog.dom.appendChild(this.layersPane_, layerRenderer.getTarget());
|
||||
return layerRenderer;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ goog.provide('ol.renderer.Layer');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.FrameState');
|
||||
goog.require('ol.Image');
|
||||
goog.require('ol.ImageState');
|
||||
goog.require('ol.Object');
|
||||
goog.require('ol.Tile');
|
||||
goog.require('ol.TileCoord');
|
||||
@@ -119,6 +121,19 @@ ol.renderer.Layer.prototype.handleLayerContrastChange = goog.nullFunction;
|
||||
ol.renderer.Layer.prototype.handleLayerHueChange = goog.nullFunction;
|
||||
|
||||
|
||||
/**
|
||||
* Handle changes in image state.
|
||||
* @param {goog.events.Event} event Image change event.
|
||||
* @protected
|
||||
*/
|
||||
ol.renderer.Layer.prototype.handleImageChange = function(event) {
|
||||
var image = /** @type {ol.Image} */ (event.target);
|
||||
if (image.getState() === ol.ImageState.LOADED) {
|
||||
this.getMap().requestRenderFrame();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
|
||||
234
src/ol/renderer/webgl/webglimagelayerrenderer.js
Normal file
234
src/ol/renderer/webgl/webglimagelayerrenderer.js
Normal file
@@ -0,0 +1,234 @@
|
||||
goog.provide('ol.renderer.webgl.ImageLayer');
|
||||
|
||||
goog.require('goog.vec.Mat4');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Image');
|
||||
goog.require('ol.ImageState');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.layer.ImageLayer');
|
||||
goog.require('ol.renderer.webgl.Layer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.renderer.webgl.Layer}
|
||||
* @param {ol.renderer.Map} mapRenderer Map renderer.
|
||||
* @param {ol.layer.ImageLayer} imageLayer Tile layer.
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer = function(mapRenderer, imageLayer) {
|
||||
|
||||
goog.base(this, mapRenderer, imageLayer);
|
||||
|
||||
/**
|
||||
* The last rendered image.
|
||||
* @private
|
||||
* @type {?ol.Image}
|
||||
*/
|
||||
this.image_ = null;
|
||||
|
||||
/**
|
||||
* The last rendered texture.
|
||||
* @private
|
||||
* @type {WebGLTexture}
|
||||
*/
|
||||
this.texture_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.texCoordMatrix_ = goog.vec.Mat4.createNumberIdentity();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.vertexCoordMatrix_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
};
|
||||
goog.inherits(ol.renderer.webgl.ImageLayer, ol.renderer.webgl.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {ol.Image} image Image.
|
||||
* @return {WebGLTexture} Texture.
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.createTexture_ = function(image) {
|
||||
|
||||
// We meet the conditions to work with non-power of two textures.
|
||||
// http://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences#Non-Power_of_Two_Texture_Support
|
||||
// http://learningwebgl.com/blog/?p=2101
|
||||
|
||||
var imageElement = image.getImageElement(this);
|
||||
var gl = this.getMapRenderer().getGL();
|
||||
|
||||
var texture = gl.createTexture();
|
||||
|
||||
gl.bindTexture(goog.webgl.TEXTURE_2D, texture);
|
||||
gl.texImage2D(goog.webgl.TEXTURE_2D, 0, goog.webgl.RGBA,
|
||||
goog.webgl.RGBA, goog.webgl.UNSIGNED_BYTE, imageElement);
|
||||
|
||||
gl.texParameteri(
|
||||
goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_WRAP_S,
|
||||
goog.webgl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(
|
||||
goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_WRAP_T,
|
||||
goog.webgl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(
|
||||
goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_MIN_FILTER, goog.webgl.LINEAR);
|
||||
gl.texParameteri(
|
||||
goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_MAG_FILTER, goog.webgl.LINEAR);
|
||||
|
||||
return texture;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.disposeInternal = function() {
|
||||
var mapRenderer = this.getMapRenderer();
|
||||
var gl = mapRenderer.getGL();
|
||||
if (!gl.isContextLost()) {
|
||||
gl.deleteTexture(this.texture_);
|
||||
}
|
||||
goog.base(this, 'disposeInternal');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.getTexCoordMatrix = function() {
|
||||
return this.texCoordMatrix_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.getTexture = function() {
|
||||
return this.texture_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.getVertexCoordMatrix = function() {
|
||||
return this.vertexCoordMatrix_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.layer.ImageLayer} Tile layer.
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.getImageLayer = function() {
|
||||
return /** @type {ol.layer.ImageLayer} */ (this.getLayer());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.handleWebGLContextLost = function() {
|
||||
this.texture_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.renderFrame =
|
||||
function(frameState, layerState) {
|
||||
|
||||
var gl = this.getMapRenderer().getGL();
|
||||
|
||||
var view2DState = frameState.view2DState;
|
||||
var viewCenter = view2DState.center;
|
||||
var viewResolution = view2DState.resolution;
|
||||
var viewRotation = view2DState.rotation;
|
||||
|
||||
var image = this.image_;
|
||||
var texture = this.texture_;
|
||||
var imageLayer = this.getImageLayer();
|
||||
var imageSource = imageLayer.getImageSource();
|
||||
|
||||
var hints = frameState.viewHints;
|
||||
|
||||
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.PANNING]) {
|
||||
var image_ = imageSource.getImage(frameState.extent, viewResolution);
|
||||
if (!goog.isNull(image_)) {
|
||||
var imageState = image_.getState();
|
||||
if (imageState == ol.ImageState.IDLE) {
|
||||
goog.events.listenOnce(image_, goog.events.EventType.CHANGE,
|
||||
this.handleImageChange, false, this);
|
||||
image_.load();
|
||||
} else if (imageState == ol.ImageState.LOADED) {
|
||||
image = image_;
|
||||
texture = this.createTexture_(image_);
|
||||
if (!goog.isNull(this.texture_)) {
|
||||
frameState.postRenderFunctions.push(
|
||||
goog.partial(function(gl, texture) {
|
||||
if (!gl.isContextLost()) {
|
||||
gl.deleteTexture(texture);
|
||||
}
|
||||
}, gl, this.texture_));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!goog.isNull(image)) {
|
||||
goog.asserts.assert(!goog.isNull(texture));
|
||||
|
||||
var canvas = this.getMapRenderer().getCanvas();
|
||||
|
||||
this.updateVertexCoordMatrix_(canvas.width, canvas.height,
|
||||
viewCenter, viewResolution, viewRotation, image.getExtent());
|
||||
|
||||
// Translate and scale to flip the Y coord.
|
||||
var texCoordMatrix = this.texCoordMatrix_;
|
||||
goog.vec.Mat4.makeIdentity(texCoordMatrix);
|
||||
goog.vec.Mat4.scale(texCoordMatrix, 1, -1, 1);
|
||||
goog.vec.Mat4.translate(texCoordMatrix, 0, -1, 0);
|
||||
|
||||
this.image_ = image;
|
||||
this.texture_ = texture;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {number} canvasWidth Canvas width.
|
||||
* @param {number} canvasHeight Canvas height.
|
||||
* @param {ol.Coordinate} viewCenter View center.
|
||||
* @param {number} viewResolution View resolution.
|
||||
* @param {number} viewRotation View rotation.
|
||||
* @param {ol.Extent} imageExtent Image extent.
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.updateVertexCoordMatrix_ =
|
||||
function(canvasWidth, canvasHeight, viewCenter,
|
||||
viewResolution, viewRotation, imageExtent) {
|
||||
|
||||
var canvasExtentWidth = canvasWidth * viewResolution;
|
||||
var canvasExtentHeight = canvasHeight * viewResolution;
|
||||
|
||||
var vertexCoordMatrix = this.vertexCoordMatrix_;
|
||||
goog.vec.Mat4.makeIdentity(vertexCoordMatrix);
|
||||
goog.vec.Mat4.scale(vertexCoordMatrix,
|
||||
2 / canvasExtentWidth, 2 / canvasExtentHeight, 1);
|
||||
goog.vec.Mat4.rotateZ(vertexCoordMatrix, -viewRotation);
|
||||
goog.vec.Mat4.translate(vertexCoordMatrix,
|
||||
imageExtent.minX - viewCenter.x,
|
||||
imageExtent.minY - viewCenter.y,
|
||||
0);
|
||||
goog.vec.Mat4.scale(vertexCoordMatrix,
|
||||
imageExtent.getWidth() / 2, imageExtent.getHeight() / 2, 1);
|
||||
goog.vec.Mat4.translate(vertexCoordMatrix, 1, 1, 0);
|
||||
|
||||
};
|
||||
@@ -97,6 +97,12 @@ ol.renderer.webgl.Layer.prototype.getTexCoordMatrix = goog.abstractMethod;
|
||||
ol.renderer.webgl.Layer.prototype.getTexture = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.vec.Mat4.Number} Matrix.
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.getVertexCoordMatrix = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
||||
@@ -14,9 +14,11 @@ goog.require('goog.webgl');
|
||||
goog.require('ol.FrameState');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.Tile');
|
||||
goog.require('ol.layer.ImageLayer');
|
||||
goog.require('ol.layer.TileLayer');
|
||||
goog.require('ol.renderer.Map');
|
||||
goog.require('ol.renderer.webgl.FragmentShader');
|
||||
goog.require('ol.renderer.webgl.ImageLayer');
|
||||
goog.require('ol.renderer.webgl.TileLayer');
|
||||
goog.require('ol.renderer.webgl.VertexShader');
|
||||
goog.require('ol.structs.LRUCache');
|
||||
@@ -79,11 +81,12 @@ ol.renderer.webgl.map.shader.Vertex = function() {
|
||||
'attribute vec2 aTexCoord;',
|
||||
'',
|
||||
'uniform mat4 uTexCoordMatrix;',
|
||||
'uniform mat4 uVertexCoordMatrix;',
|
||||
'',
|
||||
'varying vec2 vTexCoord;',
|
||||
'',
|
||||
'void main(void) {',
|
||||
' gl_Position = vec4(aPosition, 0., 1.);',
|
||||
' gl_Position = uVertexCoordMatrix * vec4(aPosition, 0., 1.);',
|
||||
' vTexCoord = (uTexCoordMatrix * vec4(aTexCoord, 0., 1.)).st;',
|
||||
'}'
|
||||
].join('\n'));
|
||||
@@ -159,7 +162,8 @@ ol.renderer.webgl.Map = function(container, map) {
|
||||
* uColorMatrix: WebGLUniformLocation,
|
||||
* uOpacity: WebGLUniformLocation,
|
||||
* uTexture: WebGLUniformLocation,
|
||||
* uTexCoordMatrix: WebGLUniformLocation}|null}
|
||||
* uTexCoordMatrix: WebGLUniformLocation,
|
||||
* uVertexCoordMatrix: WebGLUniformLocation}|null}
|
||||
*/
|
||||
this.locations_ = null;
|
||||
|
||||
@@ -270,12 +274,15 @@ ol.renderer.webgl.Map.prototype.bindTileTexture =
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.Map.prototype.createLayerRenderer = function(layer) {
|
||||
var layerRenderer = null;
|
||||
if (layer instanceof ol.layer.TileLayer) {
|
||||
return new ol.renderer.webgl.TileLayer(this, layer);
|
||||
layerRenderer = new ol.renderer.webgl.TileLayer(this, layer);
|
||||
} else if (layer instanceof ol.layer.ImageLayer) {
|
||||
layerRenderer = new ol.renderer.webgl.ImageLayer(this, layer);
|
||||
} else {
|
||||
goog.asserts.assert(false);
|
||||
return null;
|
||||
}
|
||||
return layerRenderer;
|
||||
};
|
||||
|
||||
|
||||
@@ -519,6 +526,7 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
|
||||
aTexCoord: gl.getAttribLocation(program, 'aTexCoord'),
|
||||
uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'),
|
||||
uTexCoordMatrix: gl.getUniformLocation(program, 'uTexCoordMatrix'),
|
||||
uVertexCoordMatrix: gl.getUniformLocation(program, 'uVertexCoordMatrix'),
|
||||
uOpacity: gl.getUniformLocation(program, 'uOpacity'),
|
||||
uTexture: gl.getUniformLocation(program, 'uTexture')
|
||||
};
|
||||
@@ -555,6 +563,9 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
|
||||
gl.uniformMatrix4fv(
|
||||
this.locations_.uTexCoordMatrix, false,
|
||||
layerRenderer.getTexCoordMatrix());
|
||||
gl.uniformMatrix4fv(
|
||||
this.locations_.uVertexCoordMatrix, false,
|
||||
layerRenderer.getVertexCoordMatrix());
|
||||
gl.uniformMatrix4fv(
|
||||
this.locations_.uColorMatrix, false, layerRenderer.getColorMatrix());
|
||||
gl.uniform1f(this.locations_.uOpacity, layer.getOpacity());
|
||||
|
||||
@@ -141,6 +141,12 @@ ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) {
|
||||
*/
|
||||
this.texCoordMatrix_ = goog.vec.Mat4.createNumber();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {!goog.vec.Mat4.Number}
|
||||
*/
|
||||
this.vertexCoordMatrix_ = goog.vec.Mat4.createNumberIdentity();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.TileRange}
|
||||
@@ -237,6 +243,14 @@ ol.renderer.webgl.TileLayer.prototype.getTexture = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.TileLayer.prototype.getVertexCoordMatrix = function() {
|
||||
return this.vertexCoordMatrix_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {ol.layer.TileLayer} Tile layer.
|
||||
*/
|
||||
|
||||
113
src/ol/source/imagesource.js
Normal file
113
src/ol/source/imagesource.js
Normal file
@@ -0,0 +1,113 @@
|
||||
goog.provide('ol.source.ImageSource');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('ol.Attribution');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Image');
|
||||
goog.require('ol.ImageUrlFunction');
|
||||
goog.require('ol.ImageUrlFunctionType');
|
||||
goog.require('ol.Projection');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.array');
|
||||
goog.require('ol.source.Source');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{attributions: (Array.<ol.Attribution>|undefined),
|
||||
* crossOrigin: (null|string|undefined),
|
||||
* extent: (null|ol.Extent|undefined),
|
||||
* projection: (ol.Projection|undefined),
|
||||
* resolutions: (Array.<number>|undefined),
|
||||
* imageUrlFunction: (ol.ImageUrlFunctionType|
|
||||
* undefined)}}
|
||||
*/
|
||||
ol.source.ImageSourceOptions;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.Source}
|
||||
* @param {ol.source.ImageSourceOptions} options Single
|
||||
* image source options.
|
||||
*/
|
||||
ol.source.ImageSource = function(options) {
|
||||
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
extent: options.extent,
|
||||
projection: options.projection
|
||||
});
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {ol.ImageUrlFunctionType}
|
||||
*/
|
||||
this.imageUrlFunction =
|
||||
goog.isDef(options.imageUrlFunction) ?
|
||||
options.imageUrlFunction :
|
||||
ol.ImageUrlFunction.nullImageUrlFunction;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {?string}
|
||||
*/
|
||||
this.crossOrigin_ =
|
||||
goog.isDef(options.crossOrigin) ? options.crossOrigin : 'anonymous';
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.resolutions_ = goog.isDef(options.resolutions) ?
|
||||
options.resolutions : null;
|
||||
goog.asserts.assert(goog.isNull(this.resolutions_) ||
|
||||
goog.array.isSorted(this.resolutions_,
|
||||
function(a, b) {
|
||||
return b - a;
|
||||
}, true));
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.ImageSource, ol.source.Source);
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {ol.Size} size Size.
|
||||
* @return {ol.Image} Single image.
|
||||
*/
|
||||
ol.source.ImageSource.prototype.createImage =
|
||||
function(extent, resolution, size) {
|
||||
var image = null;
|
||||
var imageUrl = this.imageUrlFunction(extent, size);
|
||||
if (goog.isDef(imageUrl)) {
|
||||
image = new ol.Image(
|
||||
extent, resolution, imageUrl, this.crossOrigin_);
|
||||
}
|
||||
return image;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {number} resolution Resolution.
|
||||
* @return {number} Resolution.
|
||||
*/
|
||||
ol.source.ImageSource.prototype.findNearestResolution =
|
||||
function(resolution) {
|
||||
if (!goog.isNull(this.resolutions_)) {
|
||||
var idx = ol.array.linearFindNearest(this.resolutions_, resolution);
|
||||
resolution = this.resolutions_[idx];
|
||||
}
|
||||
return resolution;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} resolution Resolution.
|
||||
* @return {ol.Image} Single image.
|
||||
*/
|
||||
ol.source.ImageSource.prototype.getImage = goog.abstractMethod;
|
||||
1
src/ol/source/singleimagewms.exports
Normal file
1
src/ol/source/singleimagewms.exports
Normal file
@@ -0,0 +1 @@
|
||||
@exportSymbol ol.source.SingleImageWMS
|
||||
99
src/ol/source/singleimagewmssource.js
Normal file
99
src/ol/source/singleimagewmssource.js
Normal file
@@ -0,0 +1,99 @@
|
||||
goog.provide('ol.source.SingleImageWMS');
|
||||
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.Image');
|
||||
goog.require('ol.ImageUrlFunction');
|
||||
goog.require('ol.Projection');
|
||||
goog.require('ol.Size');
|
||||
goog.require('ol.source.ImageSource');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.ImageSource}
|
||||
* @param {ol.source.SingleImageWMSOptions} options Options.
|
||||
*/
|
||||
ol.source.SingleImageWMS = function(options) {
|
||||
|
||||
var projection = ol.Projection.createProjection(
|
||||
options.projection, 'EPSG:3857');
|
||||
var projectionExtent = projection.getExtent();
|
||||
|
||||
var extent = goog.isDef(options.extent) ?
|
||||
options.extent : projectionExtent;
|
||||
|
||||
var version = goog.isDef(options.version) ?
|
||||
options.version : '1.3';
|
||||
|
||||
var baseParams = {
|
||||
'SERVICE': 'WMS',
|
||||
'VERSION': version,
|
||||
'REQUEST': 'GetMap',
|
||||
'STYLES': '',
|
||||
'FORMAT': 'image/png',
|
||||
'TRANSPARENT': true
|
||||
};
|
||||
baseParams[version >= '1.3' ? 'CRS' : 'SRS'] = projection.getCode();
|
||||
goog.object.extend(baseParams, options.params);
|
||||
|
||||
var imageUrlFunction;
|
||||
if (options.url) {
|
||||
var url = goog.uri.utils.appendParamsFromMap(
|
||||
options.url, baseParams);
|
||||
imageUrlFunction = ol.ImageUrlFunction.createBboxParam(url);
|
||||
} else {
|
||||
imageUrlFunction =
|
||||
ol.ImageUrlFunction.nullImageUrlFunction;
|
||||
}
|
||||
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
crossOrigin: options.crossOrigin,
|
||||
extent: extent,
|
||||
projection: projection,
|
||||
resolutions: options.resolutions,
|
||||
imageUrlFunction: imageUrlFunction
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Image}
|
||||
*/
|
||||
this.image_ = null;
|
||||
|
||||
/**
|
||||
* FIXME configurable?
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.ratio_ = 1.5;
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.SingleImageWMS, ol.source.ImageSource);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.source.SingleImageWMS.prototype.getImage =
|
||||
function(extent, resolution) {
|
||||
resolution = this.findNearestResolution(resolution);
|
||||
|
||||
var image = this.image_;
|
||||
if (!goog.isNull(image) &&
|
||||
image.getResolution() == resolution &&
|
||||
image.getExtent().containsExtent(extent)) {
|
||||
return image;
|
||||
}
|
||||
|
||||
extent = new ol.Extent(extent.minX, extent.minY,
|
||||
extent.maxX, extent.maxY);
|
||||
extent.scaleFromCenter(this.ratio_);
|
||||
var width = extent.getWidth() / resolution;
|
||||
var height = extent.getHeight() / resolution;
|
||||
var size = new ol.Size(width, height);
|
||||
|
||||
this.image_ = this.createImage(extent, resolution, size);
|
||||
return this.image_;
|
||||
};
|
||||
1
src/ol/source/staticimage.exports
Normal file
1
src/ol/source/staticimage.exports
Normal file
@@ -0,0 +1 @@
|
||||
@exportSymbol ol.source.StaticImage
|
||||
61
src/ol/source/staticimagesource.js
Normal file
61
src/ol/source/staticimagesource.js
Normal file
@@ -0,0 +1,61 @@
|
||||
goog.provide('ol.source.StaticImage');
|
||||
|
||||
goog.require('ol.Image');
|
||||
goog.require('ol.ImageUrlFunctionType');
|
||||
goog.require('ol.source.ImageSource');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.source.ImageSource}
|
||||
* @param {ol.source.StaticImageOptions} options Options.
|
||||
*/
|
||||
ol.source.StaticImage = function(options) {
|
||||
|
||||
var imageFunction = ol.source.StaticImage.createImageFunction(
|
||||
options.url);
|
||||
|
||||
var imageExtent = options.imageExtent;
|
||||
var imageSize = options.imageSize;
|
||||
var imageResolution = imageExtent.getHeight() / imageSize.height;
|
||||
|
||||
goog.base(this, {
|
||||
attributions: options.attributions,
|
||||
crossOrigin: options.crossOrigin,
|
||||
extent: options.extent,
|
||||
projection: options.projection,
|
||||
imageUrlFunction: imageFunction,
|
||||
resolutions: [imageResolution]
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Image}
|
||||
*/
|
||||
this.image_ = this.createImage(imageExtent, imageResolution, imageSize);
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.StaticImage, ol.source.ImageSource);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.source.StaticImage.prototype.getImage = function(extent, resolution) {
|
||||
if (extent.intersects(this.image_.getExtent())) {
|
||||
return this.image_;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string|undefined} url URL.
|
||||
* @return {ol.ImageUrlFunctionType} Function.
|
||||
*/
|
||||
ol.source.StaticImage.createImageFunction = function(url) {
|
||||
return function(extent, size) {
|
||||
return url;
|
||||
};
|
||||
};
|
||||
189
src/ol/sphere.js
Normal file
189
src/ol/sphere.js
Normal file
@@ -0,0 +1,189 @@
|
||||
/**
|
||||
* @license
|
||||
* Latitude/longitude spherical geodesy formulae taken from
|
||||
* http://www.movable-type.co.uk/scripts/latlong.html
|
||||
* Licenced under CC-BY-3.0.
|
||||
*/
|
||||
|
||||
// FIXME add intersection of two paths given start points and bearings
|
||||
// FIXME add rhumb lines
|
||||
|
||||
goog.provide('ol.Sphere');
|
||||
|
||||
goog.require('goog.math');
|
||||
goog.require('ol.Coordinate');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {number} radius Radius.
|
||||
*/
|
||||
ol.Sphere = function(radius) {
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.radius = radius;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the distance from c1 to c2 using the spherical law of cosines.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 Coordinate 1.
|
||||
* @param {ol.Coordinate} c2 Coordinate 2.
|
||||
* @return {number} Spherical law of cosines distance.
|
||||
*/
|
||||
ol.Sphere.prototype.cosineDistance = function(c1, c2) {
|
||||
var lat1 = goog.math.toRadians(c1.y);
|
||||
var lat2 = goog.math.toRadians(c2.y);
|
||||
var deltaLon = goog.math.toRadians(c2.x - c1.x);
|
||||
return this.radius * Math.acos(
|
||||
Math.sin(lat1) * Math.sin(lat2) +
|
||||
Math.cos(lat1) * Math.cos(lat2) * Math.cos(deltaLon));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the distance of c3 from the great circle path defined by c1 and c2.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 Coordinate 1.
|
||||
* @param {ol.Coordinate} c2 Coordinate 2.
|
||||
* @param {ol.Coordinate} c3 Coordinate 3.
|
||||
* @return {number} Cross-track distance.
|
||||
*/
|
||||
ol.Sphere.prototype.crossTrackDistance = function(c1, c2, c3) {
|
||||
var d12 = this.cosineDistance(c1, c2);
|
||||
var d13 = this.cosineDistance(c1, c2);
|
||||
var theta12 = goog.math.toRadians(this.initialBearing(c1, c2));
|
||||
var theta13 = goog.math.toRadians(this.initialBearing(c1, c3));
|
||||
return this.radius *
|
||||
Math.asin(Math.sin(d13 / this.radius) * Math.sin(theta13 - theta12));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the distance from c1 to c2 using Pythagoras's theorem on an
|
||||
* equirectangular projection.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 Coordinate 1.
|
||||
* @param {ol.Coordinate} c2 Coordinate 2.
|
||||
* @return {number} Equirectangular distance.
|
||||
*/
|
||||
ol.Sphere.prototype.equirectangularDistance = function(c1, c2) {
|
||||
var lat1 = goog.math.toRadians(c1.y);
|
||||
var lat2 = goog.math.toRadians(c2.y);
|
||||
var deltaLon = goog.math.toRadians(c2.x - c1.x);
|
||||
var x = deltaLon * Math.cos((lat1 + lat2) / 2);
|
||||
var y = lat2 - lat1;
|
||||
return this.radius * Math.sqrt(x * x + y * y);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the final bearing from c1 to c2.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 Coordinate 1.
|
||||
* @param {ol.Coordinate} c2 Coordinate 2.
|
||||
* @return {number} Initial bearing.
|
||||
*/
|
||||
ol.Sphere.prototype.finalBearing = function(c1, c2) {
|
||||
return (this.initialBearing(c2, c1) + 180) % 360;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the distance from c1 to c2 using the haversine formula.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 Coordinate 1.
|
||||
* @param {ol.Coordinate} c2 Coordinate 2.
|
||||
* @return {number} Haversine distance.
|
||||
*/
|
||||
ol.Sphere.prototype.haversineDistance = function(c1, c2) {
|
||||
var lat1 = goog.math.toRadians(c1.y);
|
||||
var lat2 = goog.math.toRadians(c2.y);
|
||||
var deltaLatBy2 = (lat2 - lat1) / 2;
|
||||
var deltaLonBy2 = goog.math.toRadians(c2.x - c1.x) / 2;
|
||||
var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) +
|
||||
Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) *
|
||||
Math.cos(lat1) * Math.cos(lat2);
|
||||
return 2 * this.radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the initial bearing from c1 to c2.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 Coordinate 1.
|
||||
* @param {ol.Coordinate} c2 Coordinate 2.
|
||||
* @return {number} Initial bearing.
|
||||
*/
|
||||
ol.Sphere.prototype.initialBearing = function(c1, c2) {
|
||||
var lat1 = goog.math.toRadians(c1.y);
|
||||
var lat2 = goog.math.toRadians(c2.y);
|
||||
var deltaLon = goog.math.toRadians(c2.x - c1.x);
|
||||
var y = Math.sin(deltaLon) * Math.cos(lat2);
|
||||
var x = Math.cos(lat1) * Math.sin(lat2) -
|
||||
Math.sin(lat1) * Math.cos(lat2) * Math.cos(deltaLon);
|
||||
return goog.math.toDegrees(Math.atan2(y, x));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the maximum latitude of the great circle defined by bearing and
|
||||
* latitude.
|
||||
*
|
||||
* @param {number} bearing Bearing.
|
||||
* @param {number} latitude Latitude.
|
||||
* @return {number} Maximum latitude.
|
||||
*/
|
||||
ol.Sphere.prototype.maximumLatitude = function(bearing, latitude) {
|
||||
return Math.cos(Math.abs(Math.sin(goog.math.toRadians(bearing)) *
|
||||
Math.cos(goog.math.toRadians(latitude))));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the midpoint between c1 and c2.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 Coordinate 1.
|
||||
* @param {ol.Coordinate} c2 Coordinate 2.
|
||||
* @return {ol.Coordinate} Midpoint.
|
||||
*/
|
||||
ol.Sphere.prototype.midpoint = function(c1, c2) {
|
||||
var lat1 = goog.math.toRadians(c1.y);
|
||||
var lat2 = goog.math.toRadians(c2.y);
|
||||
var lon1 = goog.math.toRadians(c1.x);
|
||||
var deltaLon = goog.math.toRadians(c2.x - c1.x);
|
||||
var Bx = Math.cos(lat2) * Math.cos(deltaLon);
|
||||
var By = Math.cos(lat2) * Math.sin(deltaLon);
|
||||
var cosLat1PlusBx = Math.cos(lat1) + Bx;
|
||||
var lat = Math.atan2(Math.sin(lat1) + Math.sin(lat2),
|
||||
Math.sqrt(cosLat1PlusBx * cosLat1PlusBx + By * By));
|
||||
var lon = lon1 + Math.atan2(By, cosLat1PlusBx);
|
||||
return new ol.Coordinate(goog.math.toDegrees(lon), goog.math.toDegrees(lat));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the coordinate at the given distance and bearing from c.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 Coordinate.
|
||||
* @param {number} distance Distance.
|
||||
* @param {number} bearing Bearing.
|
||||
* @return {ol.Coordinate} Coordinate.
|
||||
*/
|
||||
ol.Sphere.prototype.offset = function(c1, distance, bearing) {
|
||||
var lat1 = goog.math.toRadians(c1.y);
|
||||
var lon1 = goog.math.toRadians(c1.x);
|
||||
var dByR = distance / this.radius;
|
||||
var lat = Math.asin(
|
||||
Math.sin(lat1) * Math.cos(dByR) +
|
||||
Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing));
|
||||
var lon = lon1 + Math.atan2(
|
||||
Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1),
|
||||
Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat));
|
||||
return new ol.Coordinate(goog.math.toDegrees(lon), goog.math.toDegrees(lat));
|
||||
};
|
||||
@@ -61,16 +61,6 @@ ol.TileRange.prototype.containsTileRange = function(tileRange) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.TileRange} tileRange Tile range.
|
||||
* @return {boolean} Equals.
|
||||
*/
|
||||
ol.TileRange.prototype.equals = function(tileRange) {
|
||||
return this.minX == tileRange.minX && tileRange.maxX == this.maxX &&
|
||||
this.minY == tileRange.minY && tileRange.minY == this.minY;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {number} Height.
|
||||
|
||||
Reference in New Issue
Block a user