Merge branch 'exp'

This commit is contained in:
Tom Payne
2012-08-30 17:05:32 +02:00
164 changed files with 11679 additions and 6992 deletions

View File

@@ -1,149 +0,0 @@
goog.provide('ol.bounds');
goog.require('ol.Bounds');
goog.require('ol.projection');
/**
* @typedef {ol.Bounds|Array.<number>|Object} bounds Location.
*/
ol.LocLike;
/**
* @export
* @param {ol.LocLike} opt_arg Location.
* @return {ol.Bounds} Location.
*/
ol.bounds = function(opt_arg){
if (opt_arg instanceof ol.Bounds) {
return opt_arg;
}
var minX = 0;
var minY = 0;
var maxX = 0;
var maxY = 0;
var projection;
var x = 0;
var y = 0;
var z;
if (goog.isArray(opt_arg)) {
minX = opt_arg[0];
minY = opt_arg[1];
maxX = opt_arg[2];
maxY = opt_arg[3];
} else if (goog.isObject(opt_arg)) {
ol.base.checkKeys(opt_arg, ['minX', 'minY', 'maxX', 'maxY', 'projection']);
minX = ol.API ? opt_arg['minX'] : opt_arg.minX;
minY = ol.API ? opt_arg['minY'] : opt_arg.minY;
maxX = ol.API ? opt_arg['maxX'] : opt_arg.maxX;
maxY = ol.API ? opt_arg['maxY'] : opt_arg.maxY;
projection = ol.projection(ol.API ? opt_arg['projection'] : opt_arg.projection);
}
else {
throw new Error('ol.bounds');
}
var bounds = new ol.Bounds(minX, minY, maxX, maxY, projection);
return bounds;
};
/**
* @export
* @param {ol.Projection=} opt_arg Projection.
* @return {ol.Bounds|ol.Projection|undefined} Result.
*/
ol.Bounds.prototype.projection = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setProjection(opt_arg);
return this;
}
else {
return this.getProjection();
}
};
/**
* @export
* @param {number=} opt_arg Minimum X.
* @return {!ol.Bounds|number} Result.
*/
ol.Bounds.prototype.minX = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setMinX(opt_arg);
return this;
}
else {
return this.getMinX();
}
};
/**
* @export
* @param {number=} opt_arg Minimum Y.
* @return {ol.Bounds|number} Result.
*/
ol.Bounds.prototype.minY = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setMinY(opt_arg);
return this;
}
else {
return this.getMinY();
}
};
/**
* @export
* @param {number=} opt_arg Maximum X.
* @return {ol.Bounds|number} Result.
*/
ol.Bounds.prototype.maxX = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setMaxX(opt_arg);
return this;
}
else {
return this.getMaxX();
}
};
/**
* @export
* @param {number=} opt_arg Maximum Y.
* @return {ol.Bounds|number} Result.
*/
ol.Bounds.prototype.maxY = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setMaxY(opt_arg);
return this;
}
else {
return this.getMaxY();
}
};
/**
* Transform this node into another coordinate reference system. Returns a new
* bounds instead of modifying this bounds.
*
* @param {ol.Projection|string} proj Target projection (or string identifier).
* @return {ol.Bounds} A new bounds in the target projection.
*/
ol.Bounds.prototype.transform = function(proj) {
if (goog.isString(proj)) {
proj = new ol.Projection(proj);
}
return this.doTransform(proj);
};

View File

@@ -1,92 +0,0 @@
goog.provide('ol.feature');
goog.require('ol.base');
goog.require('ol.Feature');
goog.require('ol.geom.Geometry');
/**
* @typedef {ol.Feature|Object|string}
*/
ol.FeatureLike;
/**
* @export
* @param {ol.FeatureLike=} opt_arg Argument.
* @return {ol.Feature} Feature.
*/
ol.feature = function(opt_arg){
/** @type {Object|undefined} */
var properties;
/** @type {ol.geom.Geometry|undefined} */
var geometry;
/** @type {string|undefined} */
var type;
if (arguments.length == 1) {
if (opt_arg instanceof ol.Feature) {
return opt_arg;
}
else if (goog.isObject(opt_arg)) {
ol.base.checkKeys(opt_arg, ['geometry', 'properties', 'type']);
properties = ol.API ? opt_arg['properties'] : opt_arg.properties;
geometry = ol.API ? opt_arg['geometry'] : opt_arg.geometry;
type = ol.API ? opt_arg['type'] : opt_arg.type;
}
else {
throw new Error('ol.feature');
}
}
var feature = new ol.Feature();
if (goog.isDef(type) && type == 'Feature') {
//this means it is a GeoJSON object
//format.read(opt_arg);
} else {
if (goog.isDef(properties)) {
feature.setAttributes(properties);
}
if (goog.isDef(geometry)) {
feature.setGeometry(geometry);
}
}
return feature;
};
/**
* @export
* @param {!string} attr The name of the attribute to be set.
* @param {string|number|boolean} value The value of the attribute to be set.
* @returns {ol.Feature} The feature so calls can be chained
*/
ol.Feature.prototype.set = function(attr, value) {
this.setAttribute(attr, value);
return this;
};
/**
* @export
* @param {!string} attr The name of the attribute to be set.
* @returns {string|number|boolean|undefined} The attribute value requested.
*/
ol.Feature.prototype.get = function(attr) {
return this.getAttribute(attr);
};
/**
* @export
* @param {ol.geom.Geometry=} opt_arg
* @returns {ol.Feature|ol.geom.Geometry|undefined} get or set the geometry on a feature
*/
ol.Feature.prototype.geometry = function(opt_arg) {
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setGeometry(opt_arg);
return this;
} else {
return this.getGeometry();
}
};

View File

@@ -1,133 +0,0 @@
goog.provide('ol.geom.collection');
goog.require('ol.geom.Collection');
goog.require('ol.geom.point');
goog.require('ol.projection');
/**
* @export
* @param {Array.<ol.geom.Geometry>} opt_arg Components.
* @return {ol.geom.Collection} Collection.
*/
ol.geom.collection = function(opt_arg){
if (opt_arg instanceof ol.geom.Collection) {
return opt_arg;
}
var components = [];
if (arguments.length == 1 && goog.isDef(opt_arg)) {
if (goog.isArray(opt_arg)) {
var allValid = goog.array.every(opt_arg, function(geom){
if (geom instanceof ol.geom.Geometry) {
components.push(geom);
return true;
} else {
return false;
}
});
if (!allValid) {
var msg = 'ol.geom.collection: at least one component '
+ 'definition was no geometry.';
throw new Error(msg);
}
} else {
throw new Error('ol.geom.collection');
}
}
var c = new ol.geom.Collection(components);
return c;
};
goog.inherits(ol.geom.collection, ol.geom.geometry);
/**
* @export
* @param {Array.<ol.geom.Geometry>=} opt_arg An array of point specifications.
* @return {Array.<ol.geom.Geometry>|ol.geom.Collection|undefined} Result.
*/
ol.geom.Collection.prototype.components = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
var components = [],
allValid = false;
allValid = goog.array.every(opt_arg, function(geom){
if (geom instanceof ol.geom.Geometry) {
components.push(geom);
return true;
} else {
return false;
}
});
if (!allValid) {
components = [];
}
this.setComponents(components);
return this;
}
else {
return this.getComponents();
}
};
/**
* @export
* @param {ol.geom.Geometry} geom A geometry.
* @param {number=} opt_index An optional index to add the point(s) at. If not
* provided, the point(s) will be added to the end of the list of components.
* @return {ol.geom.Collection} The Collection instance.
*/
ol.geom.Collection.prototype.add = function(geom, opt_index){
var index = this.components_.length;
if (arguments.length == 2 && goog.isDef(opt_index)) {
index = opt_index;
}
this.addComponent(geom, index);
return this;
};
/**
* @export
* @param {Array.<ol.geom.Geometry>} components Some point specifications.
* @param {number=} opt_index An optional index to add the components at. If not
* provided, the components will be added to the end of the list of
* components.
* @return {ol.geom.Collection} The Collection instance.
*/
ol.geom.Collection.prototype.addAll = function(components, opt_index){
var index = this.components_.length;
if (arguments.length == 2 && goog.isDef(opt_index)) {
index = opt_index;
}
goog.array.every(components, function(c){
this.addComponent(c, index);
index++;
return true;
}, this);
return this;
};
/**
* @export
* @param {(ol.geom.Geometry|Array.<ol.geom.Geometry>)} components A point specification or
* an array of point specifications.
* @return {ol.geom.Collection} The Collection instance.
*/
ol.geom.Collection.prototype.remove = function(components){
var compArr = [];
if (!goog.isArray(components)) {
compArr.push(components);
} else {
compArr = components;
}
goog.array.every(compArr, function(c){
this.removeComponent(c);
return true;
}, this);
return this;
};

View File

@@ -1,35 +0,0 @@
goog.provide('ol.geom.geometry');
goog.require('ol.geom.Geometry');
/**
* @export
* @return {ol.geom.Geometry} Geometry..
*/
ol.geom.geometry = function(){
var g = new ol.geom.Geometry();
return g;
};
/**
* @export
* @param {ol.Bounds=} opt_arg new Bounds.
* @return {ol.geom.Geometry|ol.Bounds|undefined} either a Geometry (when used as
* setter) or a Bounds/undefined (if used as getter).
*/
ol.geom.Geometry.prototype.bounds = function(opt_arg) {
if (arguments.length == 1 && goog.isDef(opt_arg)) {
return this.setBounds(opt_arg);
} else {
return this.getBounds();
}
};
/**
* Returns the centroid of the geometry.
*
* @returns {ol.geom.Point} The centroid of the geometry.
*/
ol.geom.Geometry.prototype.centroid = function() {
return this.getCentroid();
};

View File

@@ -1,142 +0,0 @@
goog.provide('ol.geom.linestring');
goog.require('ol.geom.LineString');
goog.require('ol.geom.point');
goog.require('ol.projection');
/**
* @typedef {Array.<ol.PointLike>} linestring LineString.
*/
ol.LineStringLike;
/**
* @export
* @param {ol.LineStringLike} opt_arg Points.
* @return {ol.geom.LineString} LineString.
*/
ol.geom.linestring = function(opt_arg){
if (opt_arg instanceof ol.geom.LineString) {
return opt_arg;
}
var vertices = [];
if (arguments.length == 1 && goog.isDef(opt_arg)) {
if (goog.isArray(opt_arg)) {
var allValid = goog.array.every(opt_arg, function(spec){
var v = ol.geom.point(spec);
if (v instanceof ol.geom.Point) {
vertices.push(v);
return true;
} else {
return false;
}
});
if (!allValid) {
var msg = 'ol.geom.linestring: at least one point '
+ 'definition was erroneous.';
throw new Error(msg);
}
} else {
throw new Error('ol.geom.linestring');
}
}
var ls = new ol.geom.LineString(vertices);
return ls;
};
goog.inherits(ol.geom.linestring, ol.geom.geometry);
/**
* @export
* @param {Array.<ol.PointLike>=} opt_arg An array of vertex specifications.
* @return {Array.<ol.geom.Point>|ol.geom.LineString|undefined} Result.
*/
ol.geom.LineString.prototype.vertices = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
var vertices = [],
allValid = false;
goog.array.every(opt_arg, function(spec){
var v = ol.geom.point(spec);
if (v instanceof ol.geom.Point) {
vertices.push(v);
return true;
} else {
return false;
}
});
if (!allValid) {
vertices = [];
}
this.setVertices(vertices);
return this;
}
else {
return this.getVertices();
}
};
/**
* @export
* @param {ol.PointLike} vertex A point specification.
* @param {number=} opt_index An optional index to add the vertices at. If not
* provided, the vertex will be added to the end of the list of vertices.
* @return {ol.geom.LineString} The LineString instance.
*/
ol.geom.LineString.prototype.add = function(vertex, opt_index){
var index = this.vertices_.length,
allValid = false,
v = ol.geom.point(vertex);
if (arguments.length == 2 && goog.isDef(opt_index)) {
index = opt_index;
}
this.addVertex(v, index);
return this;
};
/**
* @export
* @param {Array.<ol.PointLike>} vertices Some vertex specifications.
* @param {number=} opt_index An optional index to add the vertices at. If not
* provided, the points will be added to the end of the list of vertices.
* @return {ol.geom.LineString} The LineString instance.
*/
ol.geom.LineString.prototype.addAll = function(vertices, opt_index){
var index = this.vertices_.length,
v;
if (arguments.length == 2 && goog.isDef(opt_index)) {
index = opt_index;
}
goog.array.every(vertices, function(vertexSpec){
v = ol.geom.point(vertexSpec);
this.addVertex(v, index);
index++;
return true;
}, this);
return this;
};
/**
* @export
* @param {(ol.geom.Point|Array.<ol.geom.Point>)} vertices A point specification or
* an array of point specifications.
* @return {ol.geom.LineString} The MultiPoint instance.
*/
ol.geom.LineString.prototype.remove = function(vertices){
var vertexArr = [];
if (!goog.isArray(vertices)) {
vertexArr.push(vertices);
} else {
vertexArr = vertices;
}
goog.array.every(vertexArr, function(v){
this.removeVertex(v);
return true;
}, this);
return this;
};

View File

@@ -1,138 +0,0 @@
goog.provide('ol.geom.multilinestring');
goog.require('ol.geom.MultiLineString');
goog.require('ol.geom.point');
goog.require('ol.geom.collection');
goog.require('ol.projection');
/**
* @export
* @param {Array.<ol.LineStringLike>} opt_arg Point.
* @return {ol.geom.MultiLineString} MultiLineString.
*/
ol.geom.multilinestring = function(opt_arg){
if (opt_arg instanceof ol.geom.MultiLineString) {
return opt_arg;
}
var ls = [];
if (arguments.length == 1 && goog.isDef(opt_arg)) {
if (goog.isArray(opt_arg)) {
var allValid = goog.array.every(opt_arg, function(spec){
var l = ol.geom.linestring(spec);
if (l instanceof ol.geom.LineString) {
ls.push(l);
return true;
} else {
return false;
}
});
if (!allValid) {
var msg = 'ol.geom.linestring: at least one linestring '
+ 'definition was erroneous.';
throw new Error(msg);
}
} else {
throw new Error('ol.geom.multilinestring');
}
}
var mls = new ol.geom.MultiLineString(ls);
return mls;
};
goog.inherits(ol.geom.multilinestring, ol.geom.collection);
/**
* @export
* @param {Array.<ol.LineStringLike>=} opt_arg An array of point specifications.
* @return {Array.<ol.geom.LineString>|ol.geom.MultiLineString|undefined} Result.
*/
ol.geom.MultiLineString.prototype.linestrings = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
var ls = [],
allValid = false;
allValid = goog.array.every(opt_arg, function(spec){
var l = ol.geom.linestring(spec);
if (l instanceof ol.geom.LineString) {
ls.push(l);
return true;
} else {
return false;
}
});
if (!allValid) {
ls = [];
}
this.setComponents(ls);
return this;
}
else {
return this.getComponents();
}
};
/**
* @export
* @param {ol.LineStringLike} line A linestring specification.
* @param {number=} opt_index An optional index to add the point(s) at. If not
* provided, the point(s) will be added to the end of the list of points.
* @return {ol.geom.MultiLineString} The MultiPoint instance.
*/
ol.geom.MultiLineString.prototype.add = function(line, opt_index){
var index = this.getLineStrings().length,
l = ol.geom.linestring(line);
if (arguments.length == 2 && goog.isDef(opt_index)) {
index = opt_index;
}
this.addLineString(l, index);
return this;
};
/**
* @export
* @param {Array.<ol.LineStringLike>} lines Some linestring specifications.
* @param {number=} opt_index An optional index to add the points at. If not
* provided, the linestrings will be added to the end of the list of
* linestrings.
* @return {ol.geom.MultiLineString} The MultiLineString instance.
*/
ol.geom.MultiLineString.prototype.addAll = function(lines, opt_index){
var index = this.getLineStrings().length,
l;
if (arguments.length == 2 && goog.isDef(opt_index)) {
index = opt_index;
}
goog.array.every(lines, function(pointSpec){
l = ol.geom.linestring(pointSpec);
this.addLineString(l, index);
index++;
return true;
}, this);
return this;
};
/**
* @export
* @param {(ol.geom.LineString|Array.<ol.geom.LineString>)} lines A linestring
* specification or an array of linestring specifications.
* @return {ol.geom.MultiLineString} The MultiLineString instance.
*/
ol.geom.MultiLineString.prototype.remove = function(lines){
var lineArr = [];
if (!goog.isArray(lines)) {
lineArr.push(lines);
} else {
lineArr = lines;
}
goog.array.every(lineArr, function(l){
this.removeLineString(l);
return true;
}, this);
return this;
};

View File

@@ -1,137 +0,0 @@
goog.provide('ol.geom.multipoint');
goog.require('ol.geom.MultiPoint');
goog.require('ol.geom.point');
goog.require('ol.geom.collection');
goog.require('ol.projection');
/**
* @export
* @param {Array.<ol.PointLike>} opt_arg Point.
* @return {ol.geom.MultiPoint} MultiPoint.
*/
ol.geom.multipoint = function(opt_arg){
if (opt_arg instanceof ol.geom.MultiPoint) {
return opt_arg;
}
var points = [];
if (arguments.length == 1 && goog.isDef(opt_arg)) {
if (goog.isArray(opt_arg)) {
var allValid = goog.array.every(opt_arg, function(spec){
var p = ol.geom.point(spec);
if (p instanceof ol.geom.Point) {
points.push(p);
return true;
} else {
return false;
}
});
if (!allValid) {
var msg = 'ol.geom.multipoint: at least one point '
+ 'definition was erroneous.';
throw new Error(msg);
}
} else {
throw new Error('ol.geom.multipoint');
}
}
var mp = new ol.geom.MultiPoint(points);
return mp;
};
goog.inherits(ol.geom.multipoint, ol.geom.collection);
/**
* @export
* @param {Array.<ol.PointLike>=} opt_arg An array of point specifications.
* @return {Array.<ol.geom.Point>|ol.geom.MultiPoint|undefined} Result.
*/
ol.geom.MultiPoint.prototype.points = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
var points = [],
allValid = false;
allValid = goog.array.every(opt_arg, function(spec){
var p = ol.geom.point(spec);
if (p instanceof ol.geom.Point) {
points.push(p);
return true;
} else {
return false;
}
});
if (!allValid) {
points = [];
}
this.setComponents(points);
return this;
}
else {
return this.getComponents();
}
};
/**
* @export
* @param {ol.PointLike} point A point specification.
* @param {number=} opt_index An optional index to add the point(s) at. If not
* provided, the point(s) will be added to the end of the list of points.
* @return {ol.geom.MultiPoint} The MultiPoint instance.
*/
ol.geom.MultiPoint.prototype.add = function(point, opt_index){
var index = this.getPoints().length,
p = ol.geom.point(point);
if (arguments.length == 2 && goog.isDef(opt_index)) {
index = opt_index;
}
this.addPoint(p, index);
return this;
};
/**
* @export
* @param {Array.<ol.PointLike>} points Some point specifications.
* @param {number=} opt_index An optional index to add the points at. If not
* provided, the points will be added to the end of the list of points.
* @return {ol.geom.MultiPoint} The MultiPoint instance.
*/
ol.geom.MultiPoint.prototype.addAll = function(points, opt_index){
var index = this.getPoints().length,
p;
if (arguments.length == 2 && goog.isDef(opt_index)) {
index = opt_index;
}
goog.array.every(points, function(pointSpec){
p = ol.geom.point(pointSpec);
this.addPoint(p, index);
index++;
return true;
}, this);
return this;
};
/**
* @export
* @param {(ol.geom.Point|Array.<ol.geom.Point>)} points A point specification or
* an array of point specifications.
* @return {ol.geom.MultiPoint} The MultiPoint instance.
*/
ol.geom.MultiPoint.prototype.remove = function(points){
var pointArr = [];
if (!goog.isArray(points)) {
pointArr.push(points);
} else {
pointArr = points;
}
goog.array.every(pointArr, function(p){
this.removePoint(p);
return true;
}, this);
return this;
};

View File

@@ -1,122 +0,0 @@
goog.provide('ol.geom.point');
goog.require('ol.geom.Point');
goog.require('ol.projection');
/**
* @typedef {Array.<number>|Object} point Point.
*/
ol.PointLike;
/**
* @export
* @param {ol.PointLike} opt_arg Point.
* @return {ol.geom.Point} Point.
*/
ol.geom.point = function(opt_arg){
if (opt_arg instanceof ol.geom.Point) {
return opt_arg;
}
var x = 0;
var y = 0;
var z;
var projection;
if (arguments.length == 1 && goog.isDef(opt_arg)) {
if (goog.isArray(opt_arg)) {
x = opt_arg[0];
y = opt_arg[1];
z = opt_arg[2];
projection = opt_arg[3];
} else if (goog.isObject(opt_arg)) {
x = ol.API ? opt_arg['x'] : opt_arg.x;
y = ol.API ? opt_arg['y'] : opt_arg.y;
z = ol.API ? opt_arg['z'] : opt_arg.z;
projection = ol.API ? opt_arg['projection'] : opt_arg.projection;
} else {
throw new Error('ol.geom.point');
}
}
if (goog.isDef(projection)) {
projection = ol.projection(projection);
}
var p = new ol.geom.Point(x,y,z,projection);
return p;
};
goog.inherits(ol.geom.point, ol.geom.geometry);
/**
* @export
* @param {number=} opt_arg X.
* @return {ol.geom.Point|number} Result.
*/
ol.geom.Point.prototype.x = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setX(opt_arg);
return this;
}
else {
return this.getX();
}
};
/**
* @export
* @param {number=} opt_arg Y.
* @return {ol.geom.Point|number} Result.
*/
ol.geom.Point.prototype.y = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setY(opt_arg);
return this;
}
else {
return this.getY();
}
};
/**
* @export
* @param {number=} opt_arg Z.
* @return {ol.geom.Point|number|undefined} Result.
*/
ol.geom.Point.prototype.z = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setZ(opt_arg);
return this;
}
else {
return this.getZ();
}
};
/**
* @export
* @param {ol.Projection=} opt_arg Projection.
* @return {ol.geom.Point|ol.Projection|undefined} Result.
*/
ol.geom.Point.prototype.projection = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setProjection(ol.projection(opt_arg));
return this;
}
else {
return this.getProjection();
}
};
/**
* Returns the centroid of this point; which is a clone of the point itself.
*
* @return {ol.geom.Point} The centroid.
*/
ol.geom.Point.prototype.centroid = function() {
return this.getCentroid();
};

View File

@@ -1,11 +0,0 @@
goog.provide('ol.layer.osm');
goog.require('ol.layer.OSM');
/**
* @export
* @return {ol.layer.OSM}
*/
ol.layer.osm = function() {
return new ol.layer.OSM();
};

View File

@@ -1,41 +0,0 @@
goog.provide('ol.layer.wms');
goog.require('ol.layer.WMS');
/**
* @export
* @param {Object} opt_arg Config object.
* @return {ol.layer.WMS}
*/
ol.layer.wms = function(opt_arg) {
if (opt_arg instanceof ol.layer.WMS) {
return opt_arg;
}
/** @type {string} */
var url;
/** @type {Array.<string>} */
var layers;
/** @type {string} */
var format;
if (goog.isObject(opt_arg)) {
ol.base.checkKeys(opt_arg, ['url', 'layers', 'format']);
url = ol.API ? opt_arg['url'] : opt_arg.url;
layers = ol.API ? opt_arg['layers'] : opt_arg.layers;
format = ol.API ? opt_arg['format'] : opt_arg.format;
}
var msg;
if (!goog.isDef(url)) {
msg = 'Cannot create WMS layer; option "url" is missing';
ol.error(msg);
}
if (!goog.isArray(layers)) {
msg = 'Cannot create WMS layer; option "layers" is missing, ' +
'or is not an array';
ol.error(msg);
}
return new ol.layer.WMS(url, layers, format);
};

View File

@@ -1,31 +0,0 @@
goog.provide('ol.layer.xyz');
goog.require('ol.layer.XYZ');
/**
* @export
* @param {Object} opt_arg Config object.
* @return {ol.layer.XYZ}
*/
ol.layer.xyz = function(opt_arg) {
if (opt_arg instanceof ol.layer.XYZ) {
return opt_arg;
}
/** @type {string} */
var url;
var usage = 'ol.layer.xyz accepts an object with a "url" property';
if (goog.isObject(opt_arg)) {
url = ol.API ? opt_arg['url'] : opt_arg.url;
} else {
throw new Error(usage);
}
if (!goog.isDef(url)) {
throw new Error(usage);
}
return new ol.layer.XYZ(url);
};

View File

@@ -1,146 +0,0 @@
goog.provide('ol.loc');
goog.require('ol.Loc');
goog.require('ol.projection');
/**
* @typedef {ol.Loc|Array.<number>|Object} loc Location.
*/
ol.LocLike;
/**
* @export
* @param {ol.LocLike} opt_arg Location.
* @return {ol.Loc} Location.
*/
ol.loc = function(opt_arg){
if (opt_arg instanceof ol.Loc) {
return opt_arg;
}
/** @type {number|undefined} */
var x;
/** @type {number|undefined} */
var y;
/** @type {number|undefined} */
var z;
/** @type {Object|undefined} */
var projection;
var usage = 'ol.loc accepts a coordinate array or an object with x, y, and (optional) z properties';
if (arguments.length == 1 && goog.isDef(opt_arg)) {
if (goog.isArray(opt_arg)) {
x = opt_arg[0];
y = opt_arg[1];
z = opt_arg[2];
projection = opt_arg[3];
} else if (goog.isObject(opt_arg)) {
ol.base.checkKeys(opt_arg, ['projection', 'x', 'y', 'z']);
x = ol.API ? opt_arg['x'] : opt_arg.x;
y = ol.API ? opt_arg['y'] : opt_arg.y;
z = ol.API ? opt_arg['z'] : opt_arg.z;
projection = ol.API ? opt_arg['projection'] : opt_arg.projection;
} else {
throw new Error(usage);
}
}
if (!goog.isNumber(x) || !goog.isNumber(y)) {
throw new Error(usage);
}
if (goog.isDef(projection)) {
projection = ol.projection(projection);
}
var loc = new ol.Loc(x, y, z, projection);
return loc;
};
/**
* Transform this location to another coordinate reference system. This
* requires that this location has a projection set already (if not, an error
* will be thrown). Returns a new location object and does not modify this
* location.
*
* @export
* @param {string|ol.Projection} proj The destination projection. Can be
* supplied as a projection instance of a string identifier.
* @returns {ol.Loc} A new location.
*/
ol.Loc.prototype.transform = function(proj) {
if (goog.isString(proj)) {
proj = new ol.Projection(proj);
}
return this.doTransform(proj);
};
/**
* @export
* @param {ol.Projection=} opt_arg Projection.
* @return {ol.Loc|ol.Projection|undefined} Result.
*/
ol.Loc.prototype.projection = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
return this.setProjection(ol.projection(opt_arg));
}
else {
return this.getProjection();
}
};
/**
* @export
* @param {number=} opt_arg X.
* @return {ol.Loc|number} Result.
*/
ol.Loc.prototype.x = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setX(opt_arg);
return this;
}
else {
return this.getX();
}
};
/**
* @export
* @param {number=} opt_arg Y.
* @return {ol.Loc|number} Result.
*/
ol.Loc.prototype.y = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setY(opt_arg);
return this;
}
else {
return this.getY();
}
};
/**
* @export
* @param {number=} opt_arg Z.
* @return {ol.Loc|number|undefined} Result.
*/
ol.Loc.prototype.z = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
return this.setZ(opt_arg);
}
else {
return this.getZ();
}
};

View File

@@ -1,256 +0,0 @@
goog.provide('ol.map');
goog.require('ol.Loc');
goog.require('ol.Map');
goog.require('ol.Projection');
goog.require('ol.loc');
goog.require('ol.projection');
goog.require('ol.error');
goog.require('goog.dispose');
/**
* @typedef {ol.Map|{center, zoom, numZoomLevels, projection, userProjection, maxExtent, maxResolution, resolutions, renderTo, layers, controls}|string}
*/
ol.MapLike;
/**
* @export
* @param {ol.MapLike=} opt_arg Argument.
* @return {ol.Map} Map.
*/
ol.map = function(opt_arg) {
/** @type {ol.Loc|undefined} */
var center;
/** @type {number|undefined} */
var zoom;
/** @type {number|undefined} */
var numZoomLevels;
/** @type {ol.Projection|undefined} */
var projection;
/** @type {ol.Projection|undefined} */
var userProjection;
/** @type {ol.Bounds|undefined} */
var maxExtent;
/** @type {number|undefined} */
var maxResolution;
/** @type {Array.<number>|undefined} */
var resolutions;
/** @type {Element|string|undefined} */
var renderTo;
/** @type {Array|undefined} */
var layers;
/** @type {Array|undefined} */
var controls;
if (arguments.length == 1) {
if (opt_arg instanceof ol.Map) {
return opt_arg;
}
else if (goog.isObject(opt_arg)) {
ol.base.checkKeys(opt_arg, ['center', 'zoom', 'numZoomLevels', 'projection', 'userProjection', 'maxExtent', 'maxResolution', 'resolutions', 'renderTo', 'layers', 'controls']);
center = ol.API ? opt_arg['center'] : opt_arg.center;
zoom = ol.API ? opt_arg['zoom'] : opt_arg.zoom;
numZoomLevels = ol.API ? opt_arg['numZoomLevels'] : opt_arg.numZoomLevels;
projection = ol.API ? opt_arg['projection'] : opt_arg.projection;
userProjection = ol.API ? opt_arg['userProjection'] : opt_arg.userProjection;
maxExtent = ol.API ? opt_arg['maxExtent'] : opt_arg.maxExtent;
maxResolution = ol.API ? opt_arg['maxResolution'] : opt_arg.maxResolution;
resolutions = ol.API ? opt_arg['resolutions'] : opt_arg.resolutions;
renderTo = ol.API ? opt_arg['renderTo'] : opt_arg.renderTo;
layers = ol.API ? opt_arg['layers'] : opt_arg.layers;
controls = ol.API ? opt_arg['controls'] : opt_arg.controls;
}
else {
throw new Error('ol.map');
}
}
var map = new ol.Map();
if (goog.isDef(center)) {
map.center(center);
}
if (goog.isDef(zoom)) {
map.setZoom(zoom);
}
if (goog.isDef(numZoomLevels)) {
map.setNumZoomLevels(numZoomLevels);
}
if (goog.isDef(projection)) {
map.setProjection(ol.projection(projection));
}
if (goog.isDef(userProjection)) {
map.setUserProjection(ol.projection(userProjection));
}
if (goog.isDef(maxExtent)) {
map.setMaxExtent(ol.bounds(maxExtent));
}
if (goog.isDef(maxResolution)) {
map.setMaxResolution(maxResolution);
}
if (goog.isDef(resolutions)) {
map.setResolutions(resolutions);
}
if (goog.isDef(layers)) {
map.setLayers(layers);
}
if (goog.isDef(controls)) {
map.setControls(controls);
}
if (goog.isDef(renderTo)) {
map.renderTo(renderTo);
}
return map;
};
/**
* @export
* @param {ol.LocLike=} opt_arg
* @returns {ol.Map|ol.Loc|undefined} Map center.
*/
ol.Map.prototype.center = function(opt_arg) {
if (arguments.length == 1 && goog.isDef(opt_arg)) {
var loc = ol.loc(opt_arg);
var proj = loc.getProjection();
if (goog.isNull(proj)) {
proj = this.getUserProjection();
loc.setProjection(proj);
}
this.setCenter(loc);
return this;
} else {
var proj = this.getUserProjection();
return this.getCenter().doTransform(proj);
}
};
/**
* @export
* @param {ol.ProjectionLike=} opt_arg
* @returns {ol.Map|ol.Projection|undefined}
*/
ol.Map.prototype.projection = function(opt_arg) {
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setProjection(ol.projection(opt_arg));
return this;
} else {
return this.getProjection();
}
};
/**
* @export
* @param {ol.ProjectionLike=} opt_arg
* @returns {ol.Map|ol.Projection|undefined}
*/
ol.Map.prototype.userProjection = function(opt_arg) {
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setUserProjection(ol.projection(opt_arg));
return this;
} else {
return this.getUserProjection();
}
};
/**
* @export
* @param {number=} opt_arg
* @returns {ol.Map|number|undefined} Map center.
*/
ol.Map.prototype.zoom = function(opt_arg) {
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setZoom(opt_arg);
return this;
} else {
return this.getZoom();
}
};
/**
* @export
* @param {number=} opt_arg
* @returns {ol.Map|number|undefined} Map center.
*/
ol.Map.prototype.numZoomLevels = function(opt_arg) {
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setNumZoomLevels(opt_arg);
return this;
} else {
return this.getNumZoomLevels();
}
};
/**
* @export
* @param {Array=} opt_arg
* @returns {ol.Map|Array|undefined} Map center.
*/
ol.Map.prototype.resolutions = function(opt_arg) {
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setResolutions(opt_arg);
return this;
} else {
return this.getResolutions();
}
};
/**
* @export
* @param {Array=} opt_arg
* @returns {ol.Map|Array|undefined} Map center.
*/
ol.Map.prototype.layers = function(opt_arg) {
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setLayers(opt_arg);
return this;
} else {
return this.getLayers();
}
};
/**
* @export
* @param {Array=} opt_arg
* @returns {ol.Map|Array|undefined} Map center.
*/
ol.Map.prototype.controls = function(opt_arg) {
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setControls(opt_arg);
return this;
} else {
return this.getControls();
}
};
/**
* @export
* @param {Array=} opt_arg
* @returns {ol.Map|ol.Bounds|undefined} Map max extent.
*/
ol.Map.prototype.maxExtent = function(opt_arg) {
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setMaxExtent(ol.bounds(opt_arg));
return this;
} else {
return this.getMaxExtent();
}
};
/**
* @param {string|Element} arg Render the map to a container
* @returns {ol.Map}
*/
ol.Map.prototype.renderTo = function(arg) {
this.setContainer(goog.dom.getElement(arg));
return this;
};
/**
*/
ol.Map.prototype.destroy = function() {
goog.dispose(this);
};

View File

@@ -1,139 +0,0 @@
goog.provide('ol.popup');
goog.require('ol.Popup');
goog.require('ol.map');
/**
* @typedef {ol.Popup|{map, anchor, placement, content, template}} popup
*/
ol.PopupLike;
/**
* @export
* @param {ol.PopupLike} opt_arg popup object literal.
* @return {ol.Popup} the popup.
*/
ol.popup = function(opt_arg){
if (opt_arg instanceof ol.Popup) {
return opt_arg;
}
/** @type {ol.Map} */
var map;
/** @type {ol.Loc|ol.Feature|undefined} */
var anchor;
/** @type {string|undefined} */
var placement;
/** @type {string|undefined} */
var content;
/** @type {string|undefined} */
var template;
if (arguments.length == 1 && goog.isDef(opt_arg)) {
if (goog.isObject(opt_arg)) {
ol.base.checkKeys(opt_arg, ['map', 'anchor', 'placement', 'content', 'template']);
map = ol.API ? opt_arg['map'] : opt_arg.map;
anchor = ol.API ? opt_arg['anchor'] : opt_arg.anchor;
placement = ol.API ? opt_arg['placement'] : opt_arg.placement;
content = ol.API ? opt_arg['content'] : opt_arg.content;
template = ol.API ? opt_arg['template'] : opt_arg.template;
}
}
var popup = new ol.Popup(map, anchor);
if (goog.isDef(anchor)) {
popup.setAnchor(anchor);
}
if (goog.isDef(placement)) {
popup.setPlacement(placement);
}
if (goog.isDef(content)) {
popup.setContent(content);
}
if (goog.isDef(template)) {
popup.setTemplate(template);
}
return popup;
};
/**
* @export
* @param {ol.Loc|ol.Feature=} opt_arg a feature or a location.
* @return {ol.Popup|ol.Feature|ol.Loc|undefined} Result.
*/
ol.Popup.prototype.anchor = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setAnchor(opt_arg);
return this;
}
else {
return this.getAnchor();
}
};
/**
* @export
* @param {ol.Map=} opt_arg the map .
* @return {ol.Popup|ol.Map|undefined} the map or the popup.
*/
ol.Popup.prototype.map = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setMap(opt_arg);
return this;
}
else {
return this.getMap();
}
};
/**
* @export
* @param {string=} opt_arg the content for the map (HTML makrkup)
* @return {ol.Popup|string|undefined} the content or the popup.
*/
ol.Popup.prototype.content = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setContent(opt_arg);
return this;
}
else {
return this.getContent();
}
};
/**
* @export
* @param {string=} opt_arg the template to be used to generate the content
* @return {ol.Popup|string|undefined} the template or the popup.
*/
ol.Popup.prototype.template = function(opt_arg){
if (arguments.length == 1 && goog.isDef(opt_arg)) {
this.setTemplate(opt_arg);
return this;
}
else {
return this.getTemplate();
}
};
/**
* Open the popup.
* @export
* @param {ol.Feature|ol.Loc} opt_arg feature or location for the anchor
*/
ol.Popup.prototype.open = function(opt_arg) {
this.doOpen(opt_arg);
};

View File

@@ -1,88 +0,0 @@
goog.provide('ol.projection');
goog.require('ol.base');
goog.require('ol.Projection');
/**
* @typedef {ol.Projection|Object|string}
*/
ol.ProjectionLike;
/**
* @export
* @param {ol.ProjectionLike=} opt_arg Argument.
* @return {ol.Projection} Projection.
*/
ol.projection = function(opt_arg){
/** @type {string} */
var code;
/** @type {undefined|number} */
var units;
/** @type {undefined|Array|ol.UnreferencedBounds} */
var extent;
if (arguments.length == 1 && goog.isDefAndNotNull(opt_arg)) {
if (opt_arg instanceof ol.Projection) {
return opt_arg;
}
else if (goog.isString(opt_arg)) {
code = opt_arg;
}
else if (goog.isObject(opt_arg)) {
ol.base.checkKeys(opt_arg, ['code', 'maxExtent', 'units']);
if (goog.isString(ol.API ? opt_arg['code'] : opt_arg.code)) {
code = ol.API ? opt_arg['code'] : opt_arg.code;
} else {
throw new Error('Projection requires a string code.');
}
units = ol.API ? opt_arg['units'] : opt_arg.units;
extent = ol.API ? opt_arg['maxExtent'] : opt_arg.maxExtent;
}
else {
throw new Error('ol.projection');
}
}
var proj = new ol.Projection(code);
if (goog.isDef(units)) {
proj.setUnits(units);
}
if (goog.isDef(extent)) {
proj.setExtent(
new ol.UnreferencedBounds(extent[0],extent[1],extent[2],extent[3])
);
}
return proj;
};
/**
* @export
* @param {string=} opt_code Code.
* @return {!ol.Projection|string} Result.
*/
ol.Projection.prototype.code = function(opt_code){
if (arguments.length == 1 && goog.isDef(opt_code)) {
this.setCode(opt_code);
return this;
}
else {
return this.getCode();
}
};
/**
* @export
* @param {string=} opt_units Units abbreviation.
* @return {undefined|!ol.Projection|string} Result.
*/
ol.Projection.prototype.units = function(opt_units){
if (goog.isDef(opt_units)) {
return this.setUnits(opt_units);
}
else {
return this.getUnits();
}
};

View File

@@ -1,132 +0,0 @@
goog.require("ol");
// ol.map
goog.exportSymbol('ol.map', ol.map );
goog.exportSymbol('ol.Map', ol.Map );
goog.exportProperty( ol.Map.prototype, 'renderTo', ol.Map.prototype.renderTo );
goog.exportProperty( ol.Map.prototype, 'center', ol.Map.prototype.center );
goog.exportProperty( ol.Map.prototype, 'projection', ol.Map.prototype.projection );
goog.exportProperty( ol.Map.prototype, 'userProjection', ol.Map.prototype.userProjection );
goog.exportProperty( ol.Map.prototype, 'zoom', ol.Map.prototype.zoom );
goog.exportProperty( ol.Map.prototype, 'numZoomLevels', ol.Map.prototype.numZoomLevels );
goog.exportProperty( ol.Map.prototype, 'resolutions', ol.Map.prototype.resolutions );
goog.exportProperty( ol.Map.prototype, 'layers', ol.Map.prototype.layers );
goog.exportProperty( ol.Map.prototype, 'controls', ol.Map.prototype.controls );
goog.exportProperty( ol.Map.prototype, 'maxExtent', ol.Map.prototype.maxExtent );
goog.exportProperty( ol.Map.prototype, 'destroy', ol.Map.prototype.destroy );
// ol.loc
goog.exportSymbol('ol.loc', ol.loc );
goog.exportSymbol('ol.Loc', ol.Loc ); // This is not required only for the tests with isInstanceOf
goog.exportProperty( ol.Loc.prototype, 'projection', ol.Loc.prototype.projection );
goog.exportProperty( ol.Loc.prototype, 'x', ol.Loc.prototype.x );
goog.exportProperty( ol.Loc.prototype, 'y', ol.Loc.prototype.y );
goog.exportProperty( ol.Loc.prototype, 'z', ol.Loc.prototype.z );
goog.exportProperty( ol.Loc.prototype, 'transform', ol.Loc.prototype.transform );
goog.exportProperty( ol.Loc.prototype, 'destroy', ol.Loc.prototype.destroy );
// ol.projection
goog.exportSymbol('ol.projection', ol.projection );
goog.exportSymbol('ol.Projection', ol.Projection );
goog.exportProperty( ol.Projection.prototype, 'code', ol.Projection.prototype.code );
goog.exportProperty( ol.Projection.prototype, 'units', ol.Projection.prototype.units );
// ol.bounds
goog.exportSymbol('ol.bounds', ol.bounds );
goog.exportSymbol('ol.Bounds', ol.Bounds );
goog.exportProperty( ol.Bounds.prototype, 'projection', ol.Bounds.prototype.projection );
goog.exportProperty( ol.Bounds.prototype, 'minX', ol.Bounds.prototype.minX );
goog.exportProperty( ol.Bounds.prototype, 'minY', ol.Bounds.prototype.minY );
goog.exportProperty( ol.Bounds.prototype, 'maxX', ol.Bounds.prototype.maxX );
goog.exportProperty( ol.Bounds.prototype, 'maxY', ol.Bounds.prototype.maxY );
// ol.layer.xyz
goog.exportSymbol('ol.layer.xyz', ol.layer.xyz);
goog.exportSymbol('ol.layer.XYZ', ol.layer.XYZ);
// ol.layer.osm
goog.exportSymbol('ol.layer.osm', ol.layer.osm);
goog.exportSymbol('ol.layer.OSM', ol.layer.OSM);
// ol.layer.wms
goog.exportSymbol('ol.layer.wms', ol.layer.wms);
goog.exportSymbol('ol.layer.WMS', ol.layer.WMS);
// ol.feature
goog.exportSymbol('ol.feature', ol.feature);
goog.exportSymbol('ol.Feature', ol.Feature);
goog.exportProperty(ol.Feature.prototype, 'set', ol.Feature.prototype.set);
goog.exportProperty(ol.Feature.prototype, 'get', ol.Feature.prototype.get);
goog.exportProperty(ol.Feature.prototype, 'geometry', ol.Feature.prototype.geometry);
// ol.geometry
goog.exportSymbol('ol.geom.geometry', ol.geom.geometry);
goog.exportSymbol('ol.geom.Geometry', ol.geom.Geometry);
goog.exportProperty(ol.geom.Geometry.prototype, 'bounds', ol.geom.Geometry.prototype.bounds);
goog.exportProperty(ol.geom.Geometry.prototype, 'centroid', ol.geom.Geometry.prototype.centroid);
// ol.geom.collection
goog.exportSymbol('ol.geom.collection', ol.geom.collection);
goog.exportSymbol('ol.geom.Collection', ol.geom.Collection);
goog.exportProperty(ol.geom.Collection.prototype, 'components', ol.geom.Collection.prototype.components);
goog.exportProperty(ol.geom.Collection.prototype, 'add', ol.geom.Collection.prototype.add);
goog.exportProperty(ol.geom.Collection.prototype, 'addAll', ol.geom.Collection.prototype.addAll);
goog.exportProperty(ol.geom.Collection.prototype, 'remove', ol.geom.Collection.prototype.remove);
goog.exportProperty(ol.geom.Collection.prototype, 'centroid', ol.geom.Collection.prototype.centroid);
// ol.geom.point
goog.exportSymbol('ol.geom.point', ol.geom.point);
goog.exportSymbol('ol.geom.Point', ol.geom.Point);
goog.exportProperty(ol.geom.Point.prototype, 'x', ol.geom.Point.prototype.x);
goog.exportProperty(ol.geom.Point.prototype, 'y', ol.geom.Point.prototype.y);
goog.exportProperty(ol.geom.Point.prototype, 'z', ol.geom.Point.prototype.z);
goog.exportProperty(ol.geom.Point.prototype, 'projection', ol.geom.Point.prototype.projection);
goog.exportProperty(ol.geom.Point.prototype, 'centroid', ol.geom.Point.prototype.centroid);
// ol.geom.linestring
goog.exportSymbol('ol.geom.linestring', ol.geom.linestring);
goog.exportSymbol('ol.geom.LineString', ol.geom.LineString);
goog.exportProperty(ol.geom.LineString.prototype, 'vertices', ol.geom.LineString.prototype.vertices);
goog.exportProperty(ol.geom.LineString.prototype, 'add', ol.geom.LineString.prototype.add);
goog.exportProperty(ol.geom.LineString.prototype, 'addAll', ol.geom.LineString.prototype.addAll);
goog.exportProperty(ol.geom.LineString.prototype, 'remove', ol.geom.LineString.prototype.remove);
goog.exportProperty(ol.geom.LineString.prototype, 'centroid', ol.geom.LineString.prototype.centroid);
// ol.geom.multipoint
goog.exportSymbol('ol.geom.multipoint', ol.geom.multipoint);
goog.exportSymbol('ol.geom.MultiPoint', ol.geom.MultiPoint);
goog.exportProperty(ol.geom.MultiPoint.prototype, 'points', ol.geom.MultiPoint.prototype.points);
goog.exportProperty(ol.geom.MultiPoint.prototype, 'add', ol.geom.MultiPoint.prototype.add);
goog.exportProperty(ol.geom.MultiPoint.prototype, 'addAll', ol.geom.MultiPoint.prototype.addAll);
goog.exportProperty(ol.geom.MultiPoint.prototype, 'remove', ol.geom.MultiPoint.prototype.remove);
goog.exportProperty(ol.geom.MultiPoint.prototype, 'centroid', ol.geom.MultiPoint.prototype.centroid);
// ol.geom.multilinestring
goog.exportSymbol('ol.geom.multilinestring', ol.geom.multilinestring);
goog.exportSymbol('ol.geom.MultiLineString', ol.geom.MultiLineString);
goog.exportProperty(ol.geom.MultiLineString.prototype, 'linestrings', ol.geom.MultiLineString.prototype.linestrings);
goog.exportProperty(ol.geom.MultiLineString.prototype, 'add', ol.geom.MultiLineString.prototype.add);
goog.exportProperty(ol.geom.MultiLineString.prototype, 'addAll', ol.geom.MultiLineString.prototype.addAll);
goog.exportProperty(ol.geom.MultiLineString.prototype, 'remove', ol.geom.MultiLineString.prototype.remove);
goog.exportProperty(ol.geom.MultiLineString.prototype, 'centroid', ol.geom.MultiLineString.prototype.centroid);
// ol.popup
goog.exportSymbol('ol.popup', ol.popup);
goog.exportSymbol('ol.Popup', ol.Popup);
goog.exportProperty(ol.Popup.prototype, 'anchor', ol.Popup.prototype.anchor);
goog.exportProperty(ol.Popup.prototype, 'map', ol.Popup.prototype.map);
goog.exportProperty(ol.Popup.prototype, 'content', ol.Popup.prototype.content);
goog.exportProperty(ol.Popup.prototype, 'template', ol.Popup.prototype.template);
goog.exportProperty(ol.Popup.prototype, 'open', ol.Popup.prototype.open);
/**
* Lookup for dynamically registered controls and renderers does not work in
* advanced compiled mode. For now, we duplicate the registration calls here.
*
* TODO: determine a good way for plugins to register
*/
goog.exportProperty(ol.renderer.Composite, 'isSupported', ol.renderer.Composite.isSupported);
goog.exportProperty(ol.renderer.TileLayerRenderer, 'isSupported', ol.renderer.TileLayerRenderer.isSupported);
goog.exportProperty(ol.renderer.TileLayerRenderer, 'canRender', ol.renderer.TileLayerRenderer.canRender);
goog.exportProperty(ol.renderer.TileLayerRenderer, 'getType', ol.renderer.TileLayerRenderer.getType);

View File

@@ -1,32 +0,0 @@
goog.provide("ol");
goog.require('ol.base');
goog.require('ol.bounds');
goog.require('ol.control.Attribution');
goog.require('ol.control.Zoom');
goog.require('ol.handler.Drag');
goog.require('ol.handler.MouseWheel');
goog.require('ol.handler.Click');
goog.require("ol.map");
goog.require("ol.loc");
goog.require("ol.feature");
goog.require("ol.projection");
goog.require("ol.layer.xyz");
goog.require("ol.layer.osm");
goog.require("ol.layer.wms");
goog.require("ol.popup");
goog.require("ol.Tile");
goog.require("ol.TileSet");
goog.require("ol.TileCache");
goog.require("ol.geom.geometry");
goog.require("ol.geom.point");
goog.require("ol.geom.multipoint");
goog.require("ol.geom.linestring");
goog.require("ol.geom.multilinestring");
goog.require("ol.geom.collection");
goog.require('ol.layer.XYZ');
goog.require('ol.layer.OSM');
goog.require('ol.layer.WMS');
goog.require('ol.renderer.Composite');
goog.require('ol.renderer.TileLayerRenderer');
goog.require('ol.renderer.WebGL');

View File

@@ -1,105 +0,0 @@
goog.provide('ol.Bounds');
goog.require('ol.UnreferencedBounds');
goog.require('ol.Loc');
goog.require('ol.Projection');
goog.require('goog.string.format');
/**
* @export
* @constructor
* @param {number} minX Minimum X.
* @param {number} minY Minimum Y.
* @param {number} maxX Maximum X.
* @param {number} maxY Maximum Y.
* @param {ol.Projection=} opt_projection Projection.
* @extends {ol.UnreferencedBounds}
*/
ol.Bounds = function(minX, minY, maxX, maxY, opt_projection) {
goog.base(this, minX, minY, maxX, maxY);
/**
* @protected
* @type {ol.Projection}
*/
this.projection_ = goog.isDef(opt_projection) ? opt_projection : null;
};
goog.inherits(ol.Bounds, ol.UnreferencedBounds);
/**
* @return {ol.Projection} Projection.
*/
ol.Bounds.prototype.getProjection = function() {
return this.projection_;
};
/**
* @param {ol.Projection} projection Projection.
*/
ol.Bounds.prototype.setProjection = function(projection) {
this.projection_ = projection;
};
/**
* Determine if this bounds intersects the target bounds (bounds that only
* touch are considered intersecting).
*
* @param {ol.Bounds} bounds Target bounds.
* @return {boolean} The provided bounds intersects this bounds.
*/
ol.Bounds.prototype.intersects = function(bounds) {
var otherProj = bounds.getProjection();
if (!goog.isNull(otherProj) && !goog.isNull(this.projection_)) {
bounds = bounds.doTransform(this.projection_);
}
return goog.base(this, "intersects", bounds.toUnreferencedBounds());
};
/**
* Transform this node into another coordinate reference system. Returns a new
* bounds instead of modifying this bounds.
*
* @param {ol.Projection} proj Target projection.
* @return {ol.Bounds} A new bounds in the target projection.
*/
ol.Bounds.prototype.doTransform = function(proj) {
if (goog.isNull(this.projection_)) {
throw new Error("Bounds must have a projection before transforming.");
}
var tl = new ol.Loc(
this.minX_, this.maxY_, undefined, this.projection_).doTransform(proj);
var tr = new ol.Loc(
this.maxX_, this.maxY_, undefined, this.projection_).doTransform(proj);
var bl = new ol.Loc(
this.minX_, this.minY_, undefined, this.projection_).doTransform(proj);
var br = new ol.Loc(
this.maxX_, this.minY_, undefined, this.projection_).doTransform(proj);
var x = [tl.getX(), tr.getX(), bl.getX(), br.getX()].sort();
var y = [tl.getY(), tr.getY(), bl.getY(), br.getY()].sort();
return new ol.Bounds(x[0], y[0], x[3], y[3], proj);
};
/**
* Return a bbox string for this bounds.
*
* @return {string} The "minx,miny,maxx,maxy" representation of this bounds.
*/
ol.Bounds.prototype.toBBOX = function() {
return goog.string.format(
'%f,%f,%f,%f', this.minX_, this.minY_, this.maxX_, this.maxY_);
};
/**
* Cast this bounds into an unreferenced bounds.
*
* @returns {ol.UnreferencedBounds}
*/
ol.Bounds.prototype.toUnreferencedBounds = function() {
return new ol.UnreferencedBounds(
this.getMinX(), this.getMinY(), this.getMaxX(), this.getMaxY());
};

View File

@@ -1,77 +0,0 @@
goog.provide('ol.Feature');
goog.require('ol.geom.Geometry');
/**
* @export
* @constructor
*/
ol.Feature = function() {
/**
* @private
* @type {ol.geom.Geometry}
*/
this.geometry_ = null;
/**
* @private
* @type {Object}
*/
this.attributes_ = {};
};
/**
* @return {ol.geom.Geometry} The geometry associated with the feature.
*/
ol.Feature.prototype.getGeometry = function() {
return this.geometry_;
};
/**
* @param {ol.geom.Geometry} geom the geometry for the feature.
*/
ol.Feature.prototype.setGeometry = function(geom) {
this.geometry_ = geom;
};
/**
* @param {!string} name the attribute value to retrieve.
@return {string|number|boolean} the attribute value.
*/
ol.Feature.prototype.getAttribute = function(name) {
return this.attributes_[name];
};
/**
* @param {!string} name of the attribute to set.
* @param {string|number|boolean} value the attribute value to set.
*/
ol.Feature.prototype.setAttribute = function(name, value) {
this.attributes_[name] = value;
};
/**
* @param {Object} attrs An json structure containing key/value pairs.
*/
ol.Feature.prototype.setAttributes = function(attrs) {
for (var key in attrs) {
this.setAttribute(key, attrs[key]);
}
};
/**
*/
ol.Feature.prototype.destroy = function() {
//remove attributes and geometry, etc.
for (var key in this) {
delete this[key];
}
};

View File

@@ -1,147 +0,0 @@
goog.provide('ol.Loc');
goog.require('ol.Projection');
/**
* @export
* @constructor
* @param {number} x X.
* @param {number} y Y.
* @param {number=} opt_z Z.
* @param {ol.Projection=} opt_projection Projection.
*/
ol.Loc = function(x, y, opt_z, opt_projection) {
/**
* @private
* @type {number}
*/
this.x_ = x;
/**
* @private
* @type {number}
*/
this.y_ = y;
/**
* @private
* @type {number|undefined}
*/
this.z_ = opt_z;
/**
* @private
* @type {ol.Projection}
*/
this.projection_ = goog.isDef(opt_projection) ? opt_projection : null;
};
/**
* @return {ol.Projection|undefined} Projection.
*/
ol.Loc.prototype.getProjection = function() {
return this.projection_;
};
/**
* @return {number} X.
*/
ol.Loc.prototype.getX = function() {
return this.x_;
};
/**
* @return {number} Y.
*/
ol.Loc.prototype.getY = function() {
return this.y_;
};
/**
* @return {number|undefined} Z.
*/
ol.Loc.prototype.getZ = function() {
return this.z_;
};
/**
* @param {ol.Projection} projection Projection.
*/
ol.Loc.prototype.setProjection = function(projection) {
this.projection_ = projection;
};
/**
* @param {number} x X.
*/
ol.Loc.prototype.setX = function(x) {
this.x_ = x;
};
/**
* @param {number} y Y.
*/
ol.Loc.prototype.setY = function(y) {
this.y_ = y;
};
/**
* @param {number|undefined} z Z.
*/
ol.Loc.prototype.setZ = function(z) {
this.z_ = z;
};
/**
* Transform this location to a new location given a projection object.
*
* @param {ol.Projection} proj The destination projection.
* @returns {ol.Loc}
*/
ol.Loc.prototype.doTransform = function(proj) {
var point = {'x': this.x_, 'y': this.y_};
var sourceProj = this.projection_;
if (!goog.isDefAndNotNull(sourceProj)) {
throw new Error("Cannot transform a location without a source projection.");
}
ol.Projection.transform(point, sourceProj, proj);
return new ol.Loc(point['x'], point['y'], this.z_, proj);
};
/**
* Adds the passed x, y(, z) delta to a new location.
*
* @param {number} x
* @param {number} y
* @param {number=} opt_z
* @returns {ol.Loc}
*/
ol.Loc.prototype.add = function(x, y, opt_z) {
var newZ;
if (goog.isDef(this.z_)) {
newZ = (opt_z || 0) + this.z_;
}
return new ol.Loc(this.x_ + x, this.y_ + y, newZ, this.projection_);
};
/**
* Clean up.
* @export
*/
ol.Loc.prototype.destroy = function() {
for (var key in this) {
delete this[key];
}
};

View File

@@ -1,625 +0,0 @@
goog.provide('ol.Map');
goog.require('ol.Loc');
goog.require('ol.Bounds');
goog.require('ol.Projection');
goog.require('ol.control.Control');
goog.require('ol.renderer.MapRenderer');
goog.require('ol.handler.Drag');
goog.require('ol.handler.MouseWheel');
goog.require('ol.handler.Click');
goog.require('goog.dom');
goog.require('goog.math');
goog.require('goog.asserts');
goog.require('goog.events.EventTarget');
/**
* @define {boolean} Whether to enable the drag handler.
*/
ol.ENABLE_DRAG_HANDLER = true;
/**
* @define {boolean} Whether to enable the mousewheel handler.
*/
ol.ENABLE_MOUSEWHEEL_HANDLER = true;
/**
* @define {boolean} Whether to enable the click handler.
*/
ol.ENABLE_CLICK_HANDLER = true;
/**
* @export
* @constructor
* @extends {goog.events.EventTarget}
*
* @event layeradd Fires when a layer is added to the map. The event object
* contains a 'layer' property referencing the added layer.
*/
ol.Map = function() {
goog.base(this);
/**
* @private
* @type {ol.Projection}
*/
this.projection_ = null;
/**
* @private
* @type {ol.Projection}
*/
this.userProjection_ = null;
/**
* @private
* @type {ol.Loc}
*/
this.center_ = null;
/**
* @private
* @type {number|undefined}
*/
this.zoom_ = undefined;
/**
* @private
* @type {number}
*/
this.numZoomLevels_ = 22;
/**
* @private
* @type {Array}
*/
this.resolutions_ = null;
/**
* @private
* @type {Array}
*/
this.layers_ = null;
/**
* @private
* @type {Array}
*/
this.controls_ = null;
/**
* @private
* @type {ol.Bounds}
*/
this.maxExtent_ = null;
/**
* @private
* @type {number|undefined}
*/
this.maxResolution_ = undefined;
/**
* @private
* @type {Element}
*/
this.viewport_ = null;
/**
* @private
* @type {goog.math.Size}
*/
this.viewportSize_ = null;
/**
* @private
* @type {Node}
*/
this.mapOverlay_ = null;
/**
* @private
* @type {Node}
*/
this.staticOverlay_ = null;
/**
* @private
* @type {Element}
*/
this.container_ = null;
};
goog.inherits(ol.Map, goog.events.EventTarget);
/**
@const
@type {string}
*/
ol.Map.prototype.DEFAULT_PROJECTION = "EPSG:3857";
/**
@const
@type {string}
*/
ol.Map.prototype.DEFAULT_USER_PROJECTION = "EPSG:4326";
/**
@const
@type {number}
*/
ol.Map.ZOOM_FACTOR = 2;
/**
@const
@type {number}
*/
ol.Map.DEFAULT_TILE_SIZE = 256;
/**
@const
@type {Array.<string>}
*/
ol.Map.DEFAULT_CONTROLS = ["attribution", "zoom"];
/**
* @return {ol.Loc} Map center in map projection.
*/
ol.Map.prototype.getCenter = function() {
return this.center_;
};
/**
* @return {!ol.Projection} Projection.
*/
ol.Map.prototype.getProjection = function() {
if (goog.isNull(this.projection_)) {
this.projection_ = new ol.Projection(this.DEFAULT_PROJECTION);
}
return this.projection_;
};
/**
* @return {!ol.Projection} User projection.
*/
ol.Map.prototype.getUserProjection = function() {
if (goog.isNull(this.userProjection_)) {
this.userProjection_ = new ol.Projection(this.DEFAULT_USER_PROJECTION);
}
return this.userProjection_;
};
/**
* @return {number|undefined} Zoom.
*/
ol.Map.prototype.getZoom = function() {
return this.zoom_;
};
/**
* @return {number} number of zoom levels.
*/
ol.Map.prototype.getNumZoomLevels = function() {
return this.numZoomLevels_;
};
/**
* @return {Array|undefined} array of resolutions available for this map
*/
ol.Map.prototype.getResolutions = function() {
return this.resolutions_;
};
/**
* @return {Array|undefined} array of layers available for this map
*/
ol.Map.prototype.getLayers = function() {
return this.layers_;
};
/**
* @return {Array.<ol.control.Control>}
*/
ol.Map.prototype.getControls = function() {
return this.controls_;
};
/**
* @return {ol.Bounds} the maxExtent for the map
*/
ol.Map.prototype.getMaxExtent = function() {
if (goog.isDefAndNotNull(this.maxExtent_)) {
return this.maxExtent_;
} else {
var projection = this.getProjection();
var extent = projection.getExtent();
if (goog.isDefAndNotNull(extent)) {
extent = new ol.Bounds(
extent.getMinX(), extent.getMinY(),
extent.getMaxX(), extent.getMaxY());
extent.setProjection(projection);
return extent;
} else {
throw('maxExtent must be defined either in the map or the projection');
}
}
};
/**
* @return {number} the max resolution for the map
*/
ol.Map.prototype.getMaxResolution = function() {
if (goog.isDefAndNotNull(this.maxResolution_)) {
return this.maxResolution_;
} else {
var extent = this.getMaxExtent();
var dim = Math.max(
(extent.getMaxX()-extent.getMinX()),
(extent.getMaxY()-extent.getMinY())
);
return dim/ol.Map.DEFAULT_TILE_SIZE;
}
};
/**
* @param {number} zoom the zoom level being requested
* @return {number} the resolution for the map at the given zoom level
*/
ol.Map.prototype.getResolutionForZoom = function(zoom) {
if (goog.isDefAndNotNull(this.resolutions_)) {
return this.resolutions_[zoom];
} else {
var maxResolution = this.getMaxResolution();
return maxResolution/Math.pow(ol.Map.ZOOM_FACTOR, zoom);
}
};
/**
* @return {number} the resolution for the map at the given zoom level
*/
ol.Map.prototype.getResolution = function() {
goog.asserts.assert(goog.isDef(this.renderer_));
return this.renderer_.getResolution();
};
/**
* TODO: We'll have to ask the map overlay renderer for this. This method will
* not work once map space is not aligned with pixel space.
*
* @param {goog.math.Coordinate|{x: number, y: number}} pixel
* @return {ol.Loc}
*/
ol.Map.prototype.getLocForViewportPixel = function(pixel) {
var size = this.getViewportSize();
var center = this.center_;
var resolution = this.getResolution();
var x = center.getX() + (resolution * (pixel.x - (size.width / 2)));
var y = center.getY() - (resolution * (pixel.y - (size.height / 2)));
return new ol.Loc(x, y, undefined, this.getProjection());
};
/**
* TODO: We'll have to ask the map overlay renderer for this. This method will
* not work once map space is not aligned with pixel space.
*
* @param {ol.Loc} loc
* @return {{x: number, y: number}}
*/
ol.Map.prototype.getViewportPixelForLoc = function(loc) {
var size = this.getViewportSize();
var center = this.center_;
var resolution = this.getResolution();
return {
x: ((loc.getX() - center.getX()) / resolution) + (size.width / 2),
y: ((center.getY() - loc.getY()) / resolution) + (size.height / 2)
};
};
/**
* @return {goog.math.Size}
*/
ol.Map.prototype.getViewportSize = function() {
// TODO: listen for resize and set this.viewportSize_ null
// https://github.com/openlayers/ol3/issues/2
if (goog.isNull(this.viewportSize_)) {
this.viewportSize_ = goog.style.getSize(this.viewport_);
}
return this.viewportSize_;
};
/**
* @param {ol.Loc} center Center in map projection.
*/
ol.Map.prototype.setCenter = function(center) {
goog.asserts.assert(!goog.isNull(center.getProjection()));
this.center_ = center.doTransform(this.getProjection());
this.conditionallyRender();
};
/**
* @param {ol.Loc} center
* @param {number} zoom
*/
ol.Map.prototype.setCenterAndZoom = function(center, zoom) {
goog.asserts.assert(!goog.isNull(center.getProjection()));
this.center_ = center.doTransform(this.getProjection());
this.zoom_ = this.limitZoom(zoom);
this.conditionallyRender();
};
/**
* @param {number} zoom The zoom level to zoom to
* @param {goog.math.Coordinate|{x: number, y: number}=} opt_anchor
* Optional anchor pixel for the zoom origin.
*/
ol.Map.prototype.setZoom = function(zoom, opt_anchor) {
var currentZoom = this.zoom_,
newZoom = this.limitZoom(zoom),
newCenter;
if (newZoom === currentZoom) {
return;
}
if (goog.isDef(opt_anchor)) {
var size = this.getViewportSize(),
anchorLoc = this.getLocForViewportPixel(opt_anchor),
newRes = this.getResolutionForZoom(newZoom);
newCenter = anchorLoc.add(
(size.width/2 - opt_anchor.x) * newRes,
(opt_anchor.y - size.height/2) * newRes
);
} else {
newCenter = this.center_;
}
this.setCenterAndZoom(newCenter, newZoom);
};
/**
* @param {ol.Projection} projection Projection.
*/
ol.Map.prototype.setProjection = function(projection) {
this.projection_ = projection;
};
/**
* @param {ol.Projection} userProjection set the user projection.
*/
ol.Map.prototype.setUserProjection = function(userProjection) {
this.userProjection_ = userProjection;
};
/**
* @param {number} zoom
* @return {number} zoom clamped to the range of available zoom levels.
*/
ol.Map.prototype.limitZoom = function(zoom) {
return goog.math.clamp(zoom, 0, this.getNumZoomLevels()-1);
};
/**
* @param {number} nZoom Zoom.
*/
ol.Map.prototype.setNumZoomLevels = function(nZoom) {
this.numZoomLevels_ = nZoom;
};
/**
* @param {Array} resolutions the map resolutions if set on the map
*/
ol.Map.prototype.setResolutions = function(resolutions) {
this.resolutions_ = resolutions;
};
/**
* @param {Array} layers the layers set on the map
*/
ol.Map.prototype.setLayers = function(layers) {
//TODO remove layers properly if there are layers already
this.layers_ = [];
this.addLayers(layers);
};
ol.Map.prototype.addLayers = function(layers) {
var layer;
for (var i=0, ii=layers.length; i<ii; ++i) {
layer = layers[i];
this.layers_.push(layer);
goog.events.dispatchEvent(this, {type: 'layeradd', 'layer': layer});
}
this.conditionallyRender();
};
/**
* @param {Array.<ol.control.Control>|undefined} opt_controls
*/
ol.Map.prototype.setControls = function(opt_controls) {
if (!this.controls_) {
var control;
for (var i=0, ii=opt_controls.length; i<ii; ++i) {
control = opt_controls[i];
if (!(control instanceof ol.control.Control)) {
control = new ol.control.CONTROL_MAP[control]();
}
control.setMap(this);
}
this.controls_ = opt_controls;
}
};
/**
* @param {ol.Bounds} extent the maxExtent for the map
*/
ol.Map.prototype.setMaxExtent = function(extent) {
this.maxExtent_ = extent;
};
/**
* @param {number} maxResolution the max resolution for the map
*/
ol.Map.prototype.setMaxResolution = function(maxResolution) {
this.maxResolution_ = maxResolution;
};
/**
* @param {Element} container the container to render the map to
*/
ol.Map.prototype.setContainer = function(container) {
this.container_ = container;
this.setViewport();
this.createRenderer();
//TODO Controls could be set earlier, but we need to deal with content that
// controls place on overlays.
this.setControls(ol.Map.DEFAULT_CONTROLS);
// conditionally render
this.conditionallyRender();
};
/**
* Check if everything is ready. Render if so.
*/
ol.Map.prototype.conditionallyRender = function() {
if (goog.isDef(this.renderer_) && !goog.isNull(this.layers_) &&
goog.isDef(this.zoom_) && !goog.isNull(this.center_)) {
this.renderer_.draw(this.layers_, this.center_,
this.getResolutionForZoom(this.zoom_)
);
}
};
/**
* @return {Element}
*/
ol.Map.prototype.getViewport = function() {
return this.viewport_;
};
ol.Map.prototype.setViewport = function() {
if (!this.viewport_) {
this.viewport_ = /** @type {Element} */ (goog.dom.createDom('div', {
'class': 'ol-viewport',
'style': 'width:100%;height:100%;top:0;left:0;position:relative;overflow:hidden'
}));
this.initHandlers();
}
goog.dom.appendChild(this.container_, this.viewport_);
};
/**
* Init the map event handlers.
*/
ol.Map.prototype.initHandlers = function() {
goog.asserts.assert(!goog.isNull(this.viewport_));
var handler,
states = /** @type {ol.handler.states} */ ({});
if (ol.ENABLE_DRAG_HANDLER) {
handler = new ol.handler.Drag(this, states);
this.registerDisposable(handler);
}
if (ol.ENABLE_MOUSEWHEEL_HANDLER) {
handler = new ol.handler.MouseWheel(this, states);
this.registerDisposable(handler);
}
if (ol.ENABLE_CLICK_HANDLER) {
handler = new ol.handler.Click(this, states);
this.registerDisposable(handler);
}
};
ol.Map.prototype.createRenderer = function() {
var Renderer = ol.renderer.MapRenderer.pickRendererType(
ol.Map.preferredRenderers);
this.renderer_ = new Renderer(this.viewport_);
//TODO Consider making a renderer responsible for managing the overlays
var viewport = this.viewport_;
if (!this.mapOverlay_ && !this.staticOverlay_) {
var staticCls = 'ol-overlay-static';
this.mapOverlay_ = goog.dom.createDom('div', 'ol-overlay-map');
this.staticOverlay_ = goog.dom.createDom('div', {
'class': staticCls,
'style': 'width:100%;height:100%;top:0;left:0;position:absolute;z-index:1'
});
}
if (!goog.isNull(viewport)) {
goog.dom.append(viewport, this.mapOverlay_, this.staticOverlay_);
}
};
/**
* TODO: This method will need to be reworked/revisited when renderers can
* display a map that is rotated or otherwise not aligned with pixel space.
*
* @param {number} dx pixels to move in x direction
* @param {number} dy pixels to move in x direction
*/
ol.Map.prototype.moveByViewportPx = function(dx, dy) {
if (!goog.isNull(this.center_) && goog.isDef(this.zoom_)) {
var resolution = this.getResolutionForZoom(this.zoom_),
center = new ol.Loc(
this.center_.getX() - dx * resolution,
this.center_.getY() + dy * resolution
);
center.setProjection(this.getProjection());
this.setCenter(center);
}
};
ol.Map.prototype.zoomIn = function() {
this.setZoom(this.zoom_+1);
};
ol.Map.prototype.zoomOut = function() {
this.setZoom(this.zoom_-1);
};
/**
* @returns {Node} the map overlay element
*/
ol.Map.prototype.getMapOverlay = function() {
return this.mapOverlay_;
};
/**
* @returns {Node} the static overlay element
*/
ol.Map.prototype.getStaticOverlay = function() {
return this.staticOverlay_;
};
/**
* @inheritDoc
*/
ol.Map.prototype.disposeInternal = function() {
goog.base(this, 'disposeInternal');
//remove layers, etc.
for (var key in this) {
delete this[key];
}
};
/**
* List of preferred renderer types. Map renderers have a getType method
* that returns a string describing their type. This list determines the
* preferences for picking a layer renderer.
*
* @type {Array.<string>}
*/
ol.Map.preferredRenderers = ["webgl", "canvas"];

View File

@@ -1,343 +0,0 @@
goog.provide('ol.Popup');
goog.require('ol.Map');
goog.require('ol.Loc');
goog.require('ol.Feature');
/**
* @export
* @constructor
* @param {ol.Map} map the map on which the popup is placed.
* @param {ol.Loc|ol.Feature=} opt_anchor the anchor object for the popup.
* @param {string=} opt_placement the placement of the arrow on the popup.
* @param {boolean=} opt_close include a close button on the popup
*/
ol.Popup = function(map, opt_anchor, opt_placement, opt_close) {
/**
* @private
* @type {ol.Map}
*/
this.map_ = map;
/**
* @private
* @type {ol.Loc|ol.Feature|undefined}
*/
this.anchor_ = opt_anchor;
/**
* can be 'top','bottom','right','left','auto'
* TODO: 'auto' not yet implemented
* @private
* @type {!string}
*/
this.placement_ = goog.isDefAndNotNull(opt_placement)?opt_placement:'top';
/**
* include a close button on the popup - defaults to true.
* @private
* @type {boolean|undefined}
*/
this.closeButton_ = goog.isDefAndNotNull(opt_close) ? opt_close : true;
/**
* @private
* @type {string|undefined}
*/
this.content_ = undefined;
/**
* @private
* @type {string|undefined}
*/
this.template_ = undefined;
/**
* @private
* @type {Element}
*/
this.container_ = null;
/**
* @private
* @type {number}
*/
this.arrowOffset_ = 30; //FIXME: set this from CSS dynamically somehow?
/**
* if the CSS sets either width or height assume the app is specifying the
* size of the popup, if not auto size the popup.
* @private
* @type {boolean}
*/
this.autoSize_ = true;
};
/**
* @const
*/
ol.Popup.CLASS_NAME = 'ol-popup';
/**
* @return {ol.Map} Projection.
*/
ol.Popup.prototype.getMap = function() {
return this.map_;
};
/**
* @param {ol.Map} map the map object to hold this popup.
*/
ol.Popup.prototype.setMap = function(map) {
this.map_ = map;
};
/**
* @return {ol.Feature|ol.Loc|undefined} the anchor .
*/
ol.Popup.prototype.getAnchor = function() {
return this.anchor_;
};
/**
* @param {ol.Feature|ol.Loc} anchor the anchor location to place this popup.
*/
ol.Popup.prototype.setAnchor = function(anchor) {
this.anchor_ = anchor;
};
/**
* @return {string|undefined} the placement value relative to the anchor.
*/
ol.Popup.prototype.getPlacement = function() {
return this.placement_;
};
/**
* @param {string} placement where to place this popup relative to the anchor.
*/
ol.Popup.prototype.setPlacement = function(placement) {
if (!goog.isNull(this.container_)) {
goog.dom.classes.remove(this.container_,
ol.Popup.CLASS_NAME+'-'+this.placement_);
goog.dom.classes.add(this.container_,ol.Popup.CLASS_NAME+'-'+placement);
}
this.placement_ = placement;
};
/**
* @return {string|undefined} static content to be displayed in the popup (HTML)
*/
ol.Popup.prototype.getContent = function() {
return this.content_;
};
/**
* @param {string} content the content to be displayed this popup.
*/
ol.Popup.prototype.setContent = function(content) {
this.content_ = content;
};
/**
* @private
* @returns {string} generates the content
*/
ol.Popup.prototype.generateContent_ = function() {
//set the content
if ( goog.isDefAndNotNull(this.content_) ) {
return this.content_;
} else {
if ( goog.isDefAndNotNull(this.template_) &&
goog.isDefAndNotNull(this.anchor_) &&
(this.anchor_ instanceof ol.Feature)) {
//set content from feature attributes on the template
//TODO: this.setContent(template.apply(this.anchor_.getAttributes()));
return this.template_; //stub to return something
} else {
ol.error('ol.Popup unabale to generate any content');
return '<p>no content</p>';
}
}
};
/**
* @return {string|undefined} the anchor .
*/
ol.Popup.prototype.getTemplate = function() {
return this.template_;
};
/**
* @param {string} template the map object to hold this popup.
*/
ol.Popup.prototype.setTemplate = function(template) {
this.template_ = template;
};
/**
* Open the popup.
* @param {ol.Feature|ol.Loc} opt_arg feature or location for the anchor
*/
ol.Popup.prototype.doOpen = function(opt_arg) {
if (goog.isDef(opt_arg)) {
this.setAnchor(opt_arg);
}
//create popup container if it's not created already
if (goog.isNull(this.container_)) {
this.container_ = goog.dom.createElement('div');
goog.dom.classes.add(this.container_,
ol.Popup.CLASS_NAME, ol.Popup.CLASS_NAME+'-'+this.placement_);
//see if the style class sets width or height
if (goog.style.getStyle(this.container_, 'width').length>0 ||
goog.style.getStyle(this.container_, 'height').length>0 ) {
this.autoSize_ = false;
}
if (this.closeButton_) {
var closeButton = goog.dom.createElement('div');
goog.dom.appendChild(this.container_, closeButton);
goog.dom.classes.add(closeButton, ol.Popup.CLASS_NAME+'-close');
}
goog.events.listen(this.map_, 'click', this.clickHandler,
undefined, this);
goog.dom.appendChild(this.map_.getMapOverlay(), this.container_);
}
this.childContent_=goog.dom.htmlToDocumentFragment(this.generateContent_());
goog.dom.appendChild(this.container_, this.childContent_);
if (this.autoSize_) {
this.registerImageListeners();
}
this.setAnchorOffset_();
};
ol.Popup.prototype.setAnchorOffset_ = function() {
if (goog.isNull(this.container_.parentNode)) {
//this means the popup has already been closed, nothing to do here
//which might happen while waiting for images to load
return;
}
if (!goog.isDefAndNotNull(this.anchor_)) {
//must have an anchor when trying to set the position
ol.error("ol.Popup must have an anchor to set the position");
return;
}
//position the element
if (this.anchor_ instanceof ol.Feature) {
this.pos_ = this.anchor_.getGeometry().getCentroid();
} else {
this.pos_ = new ol.geom.Point(this.anchor_.getX(), this.anchor_.getY());
}
var pos = /** @type {ol.Loc} */ (this.pos_);
var popupPosPx = this.map_.getViewportPixelForLoc(pos);
var popupSize = goog.style.getSize(this.container_);
switch(this.placement_) {
default:
case 'auto':
//TODO: switch based on map quadrant
break;
case 'top':
case 'bottom':
popupPosPx[0] -= popupSize.width / 2.0;
if (this.placement_ == "bottom") {
popupPosPx[1] -= popupSize.height + this.arrowOffset_;
} else {
popupPosPx[1] += this.arrowOffset_;
}
break;
case 'left':
case 'right':
popupPosPx[1] -= popupSize.height / 2.0;
if (this.placement_ == "right") {
popupPosPx[0] -= popupSize.width + this.arrowOffset_;
} else {
popupPosPx[0] += this.arrowOffset_;
}
break;
}
this.moveTo_(popupPosPx);
};
/**
* registerImageListeners
* Called when an image contained by the popup loaded. this function
* updates the popup size, then unregisters the image load listener.
*/
ol.Popup.prototype.registerImageListeners = function() {
// As the images load, this function will call setAnchorOffset_() to
// resize the popup to fit the content div (which presumably is now
// bigger than when the image was not loaded).
//
//cycle through the images and if their size is 0x0, that means that
// they haven't been loaded yet, so we attach the listener, which
// will fire when the images finish loading and will resize the
// popup accordingly to its new size.
var images = this.container_.getElementsByTagName("img");
for (var i = 0, len = images.length; i < len; i++) {
var img = images[i];
if (img.width == 0 || img.height == 0) {
goog.events.listenOnce(img, 'load',
goog.bind(this.setAnchorOffset_, this));
}
}
};
/**
* @param px - {goog.} the top and left position of the popup div.
*/
ol.Popup.prototype.moveTo_ = function(px) {
if (goog.isDefAndNotNull(px)) {
goog.style.setPosition(this.container_, px[0], px[1]);
}
};
/**
* Click handler
* @param {Event} evt the event generated by a click
*/
ol.Popup.prototype.clickHandler = function(evt) {
var target = /** @type {Node} */ evt.target;
if (goog.dom.classes.has(target,ol.Popup.CLASS_NAME+'-close')) {
this.close();
}
};
/**
* Clean up.
* @export
*/
ol.Popup.prototype.close = function() {
goog.dom.removeChildren(this.container_);
goog.dom.removeNode(this.container_);
};
/**
* Clean up.
* @export
*/
ol.Popup.prototype.destroy = function() {
for (var key in this) {
delete this[key];
}
};

View File

@@ -1,257 +0,0 @@
goog.provide('ol.Projection');
goog.require('ol.UnreferencedBounds');
/**
* @export
* @constructor
* @param {string} code Projection identifier.
*/
ol.Projection = function(code) {
/**
* @private
* @type {string}
*/
this.code_ = code;
/**
* @private
* @type {string|undefined}
*/
this.units_ = undefined;
/**
* @private
* @type {Object}
*/
this.proj_ = null;
/**
* @private
* @type {ol.UnreferencedBounds}
*/
this.extent_ = null;
};
/**
* @return {string} Code.
*/
ol.Projection.prototype.getCode = function() {
return this.code_;
};
/**
* @param {string} code Code.
*/
ol.Projection.prototype.setCode = function(code) {
this.code_ = code;
};
/**
* @return {string|undefined} Units abbreviation.
*/
ol.Projection.prototype.getUnits = function() {
return this.units_;
};
/**
* @param {string} units Units abbreviation.
*/
ol.Projection.prototype.setUnits = function(units) {
this.units_ = units;
};
/**
* Get the validity extent of the coordinate reference system.
*
* @return {ol.UnreferencedBounds} The valididty extent.
*/
ol.Projection.prototype.getExtent = function() {
if (goog.isNull(this.extent_)) {
var defs = ol.Projection.defaults[this.code_];
if (goog.isDef(defs)) {
var ext = defs.maxExtent;
if (goog.isDef(ext)) {
this.setExtent(new ol.UnreferencedBounds(ext[0],ext[1],ext[2],ext[3]));
}
}
}
return this.extent_;
};
/**
* @param {!ol.UnreferencedBounds} extent Validity extent.
*/
ol.Projection.prototype.setExtent = function(extent) {
this.extent_ = extent;
};
/**
* Transforms is an object, with from properties, each of which may
* have a to property. This allows you to define projections without
* requiring support for proj4js to be included.
*
* This object has keys which correspond to a 'source' projection object. The
* keys should be strings, corresponding to the projection.getCode() value.
* Each source projection object should have a set of destination projection
* keys included in the object.
*
* Each value in the destination object should be a transformation function,
* where the function is expected to be passed an object with a .x and a .y
* property. The function should return the object, with the .x and .y
* transformed according to the transformation function.
*
* Note - Properties on this object should not be set directly. To add a
* transform method to this object, use the <addTransform> method. For an
* example of usage, see the OpenLayers.Layer.SphericalMercator file.
*
* @type {Object}
*/
ol.Projection.transforms = {};
/**
* Defaults for the SRS codes known to OpenLayers (currently EPSG:4326, CRS:84,
* urn:ogc:def:crs:EPSG:6.6:4326, EPSG:900913, EPSG:3857, EPSG:102113 and
* EPSG:102100). Keys are the SRS code, values are units, maxExtent (the
* validity extent for the SRS) and yx (true if this SRS is known to have a
* reverse axis order).
*
* @type {Object}
*/
ol.Projection.defaults = {
"EPSG:4326": {
units: "degrees",
maxExtent: [-180, -90, 180, 90],
yx: true
},
"CRS:84": {
units: "degrees",
maxExtent: [-180, -90, 180, 90]
},
"EPSG:900913": {
units: "m",
maxExtent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34]
}
};
/**
* Set a custom transform method between two projections. Use this method in
* cases where the proj4js lib is not available or where custom projections
* need to be handled.
*
* @param {string} from The code for the source projection.
* @param {string} to The code for the destination projection.
* @param {function(Object)} method A function that takes an object with x and
* y properties as an argument and transforms that point from the source to
* the destination projection in place. The original point should be
* modified.
*/
ol.Projection.addTransform = function(from, to, method) {
if (method === ol.Projection.nullTransform) {
var defaults = ol.Projection.defaults[from];
if (defaults && !ol.Projection.defaults[to]) {
ol.Projection.defaults[to] = defaults;
}
}
if(!ol.Projection.transforms[from]) {
ol.Projection.transforms[from] = {};
}
ol.Projection.transforms[from][to] = method;
};
/**
* Transform a point coordinate from one projection to another.
*
* @param {Object} point Object with x and y properties.
* @param {ol.Projection} source Source projection.
* @param {ol.Projection} dest Destination projection.
*/
ol.Projection.transform = function(point, source, dest) {
goog.asserts.assertObject(point);
goog.asserts.assertObject(source);
goog.asserts.assertObject(dest);
if (source.proj_ && dest.proj_) {
// TODO: implement Proj4js handling
// point = Proj4js.transform(source.proj_, dest.proj_, point);
} else {
var sourceCode = source.getCode();
var destCode = dest.getCode();
var transforms = ol.Projection.transforms;
if (transforms[sourceCode] && transforms[sourceCode][destCode]) {
transforms[sourceCode][destCode](point);
}
}
};
/**
* A null transformation - useful for defining projection aliases when
* proj4js is not available:
*
* ol.Projection.addTransform("EPSG:3857", "EPSG:900913",
* ol.Projection.nullTransform);
* ol.Projection.addTransform("EPSG:900913", "EPSG:3857",
* ol.Projection.nullTransform);
*
* @type {function(Object)}
*/
ol.Projection.nullTransform = function(point) {
return point;
};
/**
* Note: Transforms for web mercator <-> geographic
* OpenLayers recognizes EPSG:3857, EPSG:900913, EPSG:102113 and EPSG:102100.
* OpenLayers originally started referring to EPSG:900913 as web mercator.
* The EPSG has declared EPSG:3857 to be web mercator.
* ArcGIS 10 recognizes the EPSG:3857, EPSG:102113, and EPSG:102100 as
* equivalent. See http://blogs.esri.com/Dev/blogs/arcgisserver/archive/2009/11/20/ArcGIS-Online-moving-to-Google-_2F00_-Bing-tiling-scheme_3A00_-What-does-this-mean-for-you_3F00_.aspx#12084.
* For geographic, OpenLayers recognizes EPSG:4326, CRS:84 and
* urn:ogc:def:crs:EPSG:6.6:4326. OpenLayers also knows about the reverse axis
* order for EPSG:4326.
*/
(function() {
var pole = 20037508.34;
function inverseMercator(xy) {
xy.x = 180 * xy.x / pole;
xy.y = 180 / Math.PI * (2 * Math.atan(Math.exp((xy.y / pole) * Math.PI)) - Math.PI / 2);
return xy;
}
function forwardMercator(xy) {
xy.x = xy.x * pole / 180;
xy.y = Math.log(Math.tan((90 + xy.y) * Math.PI / 360)) / Math.PI * pole;
return xy;
}
function map(base, codes) {
var add = ol.Projection.addTransform;
var same = ol.Projection.nullTransform;
var i, len, code, other, j;
for (i=0, len=codes.length; i<len; ++i) {
code = codes[i];
add(base, code, forwardMercator);
add(code, base, inverseMercator);
for (j=i+1; j<len; ++j) {
other = codes[j];
add(code, other, same);
add(other, code, same);
}
}
}
// list of equivalent codes for web mercator
var mercator = ["EPSG:900913", "EPSG:3857", "EPSG:102113", "EPSG:102100"],
geographic = ["CRS:84", "urn:ogc:def:crs:EPSG:6.6:4326", "EPSG:4326"],
i;
for (i=mercator.length-1; i>=0; --i) {
map(mercator[i], geographic);
}
for (i=geographic.length-1; i>=0; --i) {
map(geographic[i], mercator);
}
})();

View File

@@ -1,169 +0,0 @@
goog.provide('ol.Tile');
goog.require('ol.Bounds');
goog.require('goog.events.EventTarget');
goog.require('goog.events');
goog.require('goog.asserts');
/**
* The Tile class.
* @constructor
* @extends {goog.events.EventTarget}
* @param {string} url
* @param {ol.Bounds|undefined} opt_bounds
*/
ol.Tile = function(url, opt_bounds) {
/**
* @private
* @type {string}
*/
this.url_ = url;
/**
* @private
* @type {ol.Bounds|undefined}
*/
this.bounds_ = opt_bounds;
/**
* @private
* @type {boolean}
*/
this.loaded_ = false;
/**
* @private
* @type {boolean}
*/
this.loading_ = false;
/**
* @private
* @type {HTMLImageElement}
*/
this.img_ = this.createImage();
goog.events.listenOnce(this.img_, goog.events.EventType.LOAD,
this.handleImageLoad, false, this);
goog.events.listenOnce(this.img_, goog.events.EventType.ERROR,
this.handleImageError, false, this);
};
goog.inherits(ol.Tile, goog.events.EventTarget);
/**
* @protected
* @return {HTMLImageElement}
*/
ol.Tile.prototype.createImage = function() {
// overriden by subclasses
};
/**
* Load the tile. A tile should loaded only once.
*/
ol.Tile.prototype.load = function() {
goog.asserts.assert(!this.loaded_ && !this.loading_);
this.loading_ = true;
this.img_.src = this.url_;
};
/**
* Get the tile url.
* @return {string}
*/
ol.Tile.prototype.getUrl = function() {
return this.url_;
};
/**
* Get the tile bounds.
* @return {ol.Bounds|undefined}
*/
ol.Tile.prototype.getBounds = function() {
return this.bounds_;
};
/**
* Get the tile image.
* @return {HTMLImageElement}
*/
ol.Tile.prototype.getImg = function() {
return this.img_;
};
/**
* Handle load event on the image.
* @param {goog.events.BrowserEvent} evt Event.
*/
ol.Tile.prototype.handleImageLoad = function(evt) {
this.loading_ = false;
this.loaded_ = true;
this.img_.style.visibility = "inherit";
this.img_.style.opacity = 1; // TODO: allow for layer opacity
goog.events.dispatchEvent(this, 'load');
};
/**
* Handle load error event on the image.
* @param {goog.events.BrowserEvent} evt Event.
*/
ol.Tile.prototype.handleImageError = function(evt) {
this.loading_ = false;
goog.events.dispatchEvent(this, 'error');
};
/**
* Is the tile loaded already?
* @return {boolean}
*/
ol.Tile.prototype.isLoaded = function() {
return this.loaded_;
};
/**
* Is the tile being loaded?
* @return {boolean}
*/
ol.Tile.prototype.isLoading = function() {
return this.loading_;
};
/**
*
*/
ol.Tile.prototype.destroy = function() {
goog.events.dispatchEvent(this, 'destroy');
};
/**
* Create a tile constructor, for specific width and height values
* for the tiles.
* @param {number} width
* @param {number} height
* @return {function(new:ol.Tile, string, ol.Bounds=)}
*/
ol.Tile.createConstructor = function(width, height) {
/**
* @constructor
* @extends {ol.Tile}
*/
var Tile = function(url, opt_bounds) {
goog.base(this, url, opt_bounds);
};
goog.inherits(Tile, ol.Tile);
/** @inheritDoc */
Tile.prototype.createImage = (function() {
var img = document.createElement("img");
img.className = "olTile";
img.style.position = "absolute";
img.style.width = width + "px";
img.style.height = height + "px";
img.style.opacity = 0;
img.src = "data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";
return function() {
return img.cloneNode(false);
};
})();
return Tile;
};

View File

@@ -1,23 +0,0 @@
goog.provide('ol.TileCache');
goog.require('goog.structs.LinkedMap');
/**
* A cache of ol.Tile objects.
* @constructor
* @extends {goog.structs.LinkedMap}
* @param {number=} opt_size
*/
ol.TileCache = function(opt_size) {
goog.base(this, opt_size || 100, true /* cache mode */);
};
goog.inherits(ol.TileCache, goog.structs.LinkedMap);
/**
* @inheritDoc
*/
ol.TileCache.prototype.removeNode = function(node) {
goog.base(this, 'removeNode', node);
node.value.destroy();
};

View File

@@ -1,66 +0,0 @@
goog.provide('ol.TileSet');
/**
* The TileSet class. A TileSet instance represents a collection of
* tiles. Tiles of a TileSet have the same resolution, width and
* height.
* @constructor
* @param {Array.<Array.<ol.Tile>>} tiles
* @param {number} tileWidth
* @param {number} tileHeight
* @param {number} resolution
*/
ol.TileSet = function(tiles, tileWidth, tileHeight, resolution) {
/**
* @private
* @type {Array.<Array.<ol.Tile>>}
*/
this.tiles_ = tiles;
/**
* @private
* @type {number}
*/
this.tileWidth_ = tileWidth;
/**
* @private
* @type {number}
*/
this.tileHeight_ = tileHeight;
/**
* @private
* @type {number}
*/
this.resolution_ = resolution;
};
/**
* @return {Array.<Array.<ol.Tile>>}
*/
ol.TileSet.prototype.getTiles = function() {
return this.tiles_;
};
/**
* @return {number}
*/
ol.TileSet.prototype.getResolution = function() {
return this.resolution_;
};
/**
* @return {number}
*/
ol.TileSet.prototype.getTileHeight = function() {
return this.tileHeight_;
};
/**
* @return {number}
*/
ol.TileSet.prototype.getTileWidth = function() {
return this.tileWidth_;
};

View File

@@ -1,130 +0,0 @@
goog.provide('ol.UnreferencedBounds');
/**
* @constructor
* @param {number} minX Minimum X.
* @param {number} minY Minimum Y.
* @param {number} maxX Maximum X.
* @param {number} maxY Maximum Y.
*/
ol.UnreferencedBounds = function(minX, minY, maxX, maxY) {
/**
* @protected
* @type {number}
*/
this.minX_ = minX;
/**
* @protected
* @type {number}
*/
this.minY_ = minY;
/**
* @protected
* @type {number}
*/
this.maxX_ = maxX;
/**
* @protected
* @type {number}
*/
this.maxY_ = maxY;
};
/**
* @return {number} Minimun X.
*/
ol.UnreferencedBounds.prototype.getMinX = function() {
return this.minX_;
};
/**
* @param {number} minX Minimum X.
*/
ol.UnreferencedBounds.prototype.setMinX = function(minX) {
this.minX_ = minX;
};
/**
* @return {number} Minimun Y.
*/
ol.UnreferencedBounds.prototype.getMinY = function() {
return this.minY_;
};
/**
* @param {number} minY Minimum Y.
*/
ol.UnreferencedBounds.prototype.setMinY = function(minY) {
this.minY_ = minY;
};
/**
* @return {number} Maximun X.
*/
ol.UnreferencedBounds.prototype.getMaxX = function() {
return this.maxX_;
};
/**
* @param {number} maxX Maximum X.
*/
ol.UnreferencedBounds.prototype.setMaxX = function(maxX) {
this.maxX_ = maxX;
};
/**
* @return {number} Maximun Y.
*/
ol.UnreferencedBounds.prototype.getMaxY = function() {
return this.maxY_;
};
/**
* @param {number} maxY Maximum Y.
*/
ol.UnreferencedBounds.prototype.setMaxY = function(maxY) {
this.maxY_ = maxY;
};
/**
* @return {number} Bounds width.
*/
ol.UnreferencedBounds.prototype.getWidth = function() {
return this.maxX_ - this.minX_;
};
/**
* @return {number} Bounds height.
*/
ol.UnreferencedBounds.prototype.getHeight = function() {
return this.maxY_ - this.minY_;
};
/**
* Determine if this bounds intersects the target bounds (bounds that only
* touch are considered intersecting).
*
* @param {ol.UnreferencedBounds} bounds Target bounds.
* @return {boolean} The provided bounds intersects this bounds.
*/
ol.UnreferencedBounds.prototype.intersects = function(bounds) {
return !(
// this is left
(this.minX_ > bounds.getMaxX()) ||
// this is right
(this.maxX_ < bounds.getMinX()) ||
// this is above
(this.minY_ > bounds.getMaxY()) ||
// this is below
(this.maxY_ < bounds.getMinY())
);
};

View File

@@ -1,46 +0,0 @@
goog.provide('ol.base');
goog.provide('ol.error');
/**
* @param {string} message Message.
*/
ol.error = function(message) {
if (ol.error.VERBOSE_ERRORS) {
throw new Error(message);
} else {
throw null;
}
};
/**
* Compilation with public API, let's accept options from external world
* @define {boolean}
*/
ol.API = true;
/**
* @define {boolean}
*/
ol.error.VERBOSE_ERRORS = true;
/**
* Options passed in the API from external world are checked for wrong keys
* @define {boolean}
*/
ol.CHECK_KEYS = true;
/**
* @param {Object} obj Object.
* @param {!Array.<string>} allowedKeys Allowed keys.
*/
ol.base.checkKeys = function(obj, allowedKeys) {
if (ol.CHECK_KEYS) {
var keys = goog.object.getKeys(obj);
goog.array.forEach(allowedKeys, function(allowedKey) {
goog.array.remove(keys, allowedKey);
});
if (!goog.array.isEmpty(keys)) {
ol.error('object contains invalid keys: ' + keys.join(', '));
}
}
};

22
src/ol/collection_test.js Normal file
View File

@@ -0,0 +1,22 @@
goog.require('goog.testing.jsunit');
goog.require('ol');
goog.require('ol3.Collection');
function testCreateFromArray() {
var array = [0, 1, 2];
var collection = ol.collection(array);
assertTrue(collection instanceof ol3.Collection);
assertEquals(3, collection.getLength());
assertEquals(0, collection.getAt(0));
assertEquals(1, collection.getAt(1));
assertEquals(2, collection.getAt(2));
}
function testCreateFromCollection() {
var collection1 = new ol3.Collection();
var collection2 = ol.collection(collection1);
assertTrue(collection1 === collection2);
}

View File

@@ -1,95 +0,0 @@
goog.provide('ol.control.Attribution');
goog.require('ol.control.Control');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.events.Event');
/**
* @constructor
* @extends {ol.control.Control}
* @param {boolean|undefined} opt_autoActivate
*/
ol.control.Attribution = function(opt_autoActivate) {
goog.base(this, opt_autoActivate);
/**
* @type {Node}
*/
this.container_ = null;
/**
* Activate this control when it is added to a map. Default is true.
*
* @type {boolean} autoActivate
*/
this.autoActivate_ =
goog.isDef(opt_autoActivate) ? opt_autoActivate : true;
};
goog.inherits(ol.control.Attribution, ol.control.Control);
/**
* @const {string}
*/
ol.control.Attribution.prototype.CLS = 'ol-control-attribution';
/**
* @param {ol.Map} map
*/
ol.control.Attribution.prototype.setMap = function(map) {
var staticOverlay = map.getStaticOverlay();
if (goog.isNull(this.container_)) {
this.container_ = goog.dom.createDom('div', this.CLS);
goog.events.listen(this.container_, 'click',
goog.events.Event.stopPropagation);
}
if (!goog.isNull(staticOverlay)) {
goog.dom.append(staticOverlay, this.container_);
}
goog.base(this, 'setMap', map);
};
/** @inheritDoc */
ol.control.Attribution.prototype.activate = function() {
var active = goog.base(this, 'activate');
if (active) {
goog.events.listen(this.map_, 'layeradd', this.update, false, this);
this.update();
}
return active;
};
/** @inheritDoc */
ol.control.Attribution.prototype.deactivate = function() {
var inactive = goog.base(this, 'deactivate');
if (inactive) {
goog.events.unlisten(this.map_, 'layeradd', this.update, false, this);
}
return inactive;
};
ol.control.Attribution.prototype.update = function() {
var attribution = [],
layers = this.map_.getLayers(), layerAttribution;
for (var i=0, ii=layers.length; i<ii; ++i) {
layerAttribution = layers[i].getAttribution();
if (layerAttribution &&
!~goog.array.indexOf(attribution, layerAttribution)) {
attribution.push(layerAttribution);
}
}
this.container_.innerHTML = attribution.join(', ');
};
ol.control.Attribution.prototype.destroy = function() {
goog.events.unlisten(this.container_, 'click',
goog.events.Event.stopPropagation);
goog.dom.removeNode(this.container_);
goog.base(this, 'destroy');
};
ol.control.addControl('attribution', ol.control.Attribution);

View File

@@ -1,85 +0,0 @@
goog.provide('ol.control');
goog.provide('ol.control.Control');
goog.require('goog.object');
/**
* @enum {Object}
*/
ol.control.CONTROL_MAP = {};
/**
* @param {string} name
* @param {Function} Control
*/
ol.control.addControl = function(name, Control) {
ol.control.CONTROL_MAP[name] = Control;
};
/**
* @constructor
* @param {boolean|undefined} opt_autoActivate
*/
ol.control.Control = function(opt_autoActivate) {
/**
* @type {ol.Map} map
* @protected
*/
this.map_ = null;
/**
* @type {boolean} active
* @private
*/
this.active_ = false;
/**
* Activate this control when it is added to a map. Default is false.
*
* @type {boolean} autoActivate
*/
this.autoActivate_ =
goog.isDef(opt_autoActivate) ? opt_autoActivate : false;
};
/**
* @return {ol.Map} getMap
*/
ol.control.Control.prototype.getMap = function() {
return this.map_;
};
/**
* @param {ol.Map} map
*/
ol.control.Control.prototype.setMap = function(map) {
this.map_ = map;
if (this.autoActivate_) {
this.activate();
}
};
/**
* @return {boolean}
*/
ol.control.Control.prototype.activate = function() {
var returnValue = !this.active_;
this.active_ = true;
return returnValue;
};
/**
* @return {boolean}
*/
ol.control.Control.prototype.deactivate = function() {
var returnValue = this.active_;
this.active_ = false;
return returnValue;
};
ol.control.Control.prototype.destroy = function() {
this.deactivate();
goog.object.clear(this);
};

View File

@@ -1,122 +0,0 @@
goog.provide('ol.control.Zoom');
goog.require('ol.control.Control');
goog.require('goog.dom');
/**
* @constructor
* @extends {ol.control.Control}
* @param {boolean|undefined} opt_autoActivate
*/
ol.control.Zoom = function(opt_autoActivate) {
goog.base(this, opt_autoActivate);
/**
* @type {Node}
*/
this.inButton_ = null;
/**
* @type {Node}
*/
this.outButton_ = null;
/**
* Activate this control when it is added to a map. Default is true.
*
* @type {boolean}
*/
this.autoActivate_ =
goog.isDef(opt_autoActivate) ? opt_autoActivate : true;
};
goog.inherits(ol.control.Zoom, ol.control.Control);
/**
* @param {ol.Map} map
*/
ol.control.Zoom.prototype.setMap = function(map) {
var container = goog.dom.createDom('div', ol.control.Zoom.RES.CLS);
this.inButton_ = goog.dom.createDom(
'div', ol.control.Zoom.RES.IN_CLS,
goog.dom.createDom('a', {'href': '#zoomIn'})
);
goog.dom.setTextContent(
/** @type {Element} */ (this.inButton_.firstChild),
ol.control.Zoom.RES.IN_TEXT
);
this.outButton_ = goog.dom.createDom(
'div', ol.control.Zoom.RES.OUT_CLS,
goog.dom.createDom('a', {'href': '#zoomOut'})
);
goog.dom.setTextContent(
/** @type {Element} */ (this.outButton_.firstChild),
ol.control.Zoom.RES.OUT_TEXT
);
goog.dom.append(container, this.inButton_, this.outButton_);
var overlay = map.getStaticOverlay();
if (goog.isDefAndNotNull(overlay)) {
goog.dom.append(overlay, container);
}
goog.base(this, 'setMap', map);
};
/** @inheritDoc */
ol.control.Zoom.prototype.activate = function() {
var active = goog.base(this, 'activate');
if (active) {
goog.events.listen(this.inButton_, 'click', this.handleIn, false, this);
goog.events.listen(this.outButton_, 'click', this.handleOut, false, this);
}
return active;
};
/** @inheritDoc */
ol.control.Zoom.prototype.deactivate = function() {
var inactive = goog.base(this, 'deactivate');
if (inactive) {
goog.events.unlisten(this.inButton_, 'click', this.handleIn, false, this);
goog.events.unlisten(this.outButton_, 'click', this.handleOut, false, this);
}
return inactive;
};
/**
* @param {Event} evt
*/
ol.control.Zoom.prototype.handleIn = function(evt) {
this.map_.zoomIn();
evt.preventDefault();
evt.stopPropagation();
};
/**
* @param {Event} evt
*/
ol.control.Zoom.prototype.handleOut = function(evt) {
this.map_.zoomOut();
evt.preventDefault();
evt.stopPropagation();
};
ol.control.Zoom.prototype.destroy = function() {
goog.dom.removeNode(goog.dom.getElementByClass(
ol.control.Zoom.RES.CLS,
/** @type {Element} */ (this.map_.getStaticOverlay())
));
goog.base(this, 'destroy');
};
ol.control.addControl('zoom', ol.control.Zoom);
ol.control.Zoom.RES = {
CLS: 'ol-control-zoom',
IN_CLS: 'ol-control-zoom-in',
OUT_CLS: 'ol-control-zoom-out',
IN_TEXT: '+',
OUT_TEXT: '\u2212'
};

View File

@@ -1,58 +0,0 @@
goog.provide('ol.coord.AccessorInterface');
goog.require('ol.Projection');
/**
* The AccessorInterface in coord package
*
* @interface
*
* @param {number} x X.
* @param {number} y Y.
* @param {number=} opt_z Z.
* @param {ol.Projection=} opt_projection Projection.
*/
ol.coord.AccessorInterface = function(x, y, opt_z, opt_projection){
};
/**
* @return {number} X.
*/
ol.coord.AccessorInterface.prototype.getX = function(){};
/**
* @return {number} Y.
*/
ol.coord.AccessorInterface.prototype.getY = function(){};
/**
* @return {number|undefined} Z.
*/
ol.coord.AccessorInterface.prototype.getZ = function(){};
/**
* @return {ol.Projection|undefined} Projection.
*/
ol.coord.AccessorInterface.prototype.getProjection = function() {};
/**
* @param {number} x X.
*/
ol.coord.AccessorInterface.prototype.setX = function(x){};
/**
* @param {number} y Y.
*/
ol.coord.AccessorInterface.prototype.setY = function(y){};
/**
* @param {number|undefined} z Z.
*/
ol.coord.AccessorInterface.prototype.setZ = function(z){};
/**
* @param {ol.Projection} projection Projection.
*/
ol.coord.AccessorInterface.prototype.setProjection = function(projection) {};

View File

@@ -1,198 +0,0 @@
goog.provide('ol.geom.Collection');
goog.require('goog.array');
goog.require('ol.geom.Geometry');
goog.require('ol.Projection');
goog.require('ol.base');
/**
* Creates ol.geom.Collection objects.
*
* @export
* @extends {ol.geom.Geometry}
* @param {Array.<ol.geom.Geometry>} components An array of components.
*
* @constructor
*/
ol.geom.Collection = function(components) {
/**
* @private
* @type {Array.<Function>}
*/
this.typeBlacklist_ = [
ol.geom.Collection
];
/**
* @private
* @type {Array.<Function>}
*/
this.typeWhitelist_ = [
ol.geom.MultiPoint,
ol.geom.MultiLineString
// TODO uncomment when implemented
// ,ol.geom.MultiPolygon
];
/**
* @private
* @type {Array.<ol.geom.Geometry>}
*/
this.components_ = [];
if (arguments.length === 1 && goog.isDef(components)) {
this.setComponents(components);
}
};
goog.inherits(ol.geom.Collection, ol.geom.Geometry);
/**
* Sets the list of disallowed types for the collection.
* @param {Array.<Function>} typeBlacklist Array of constructors to disallow.
*/
ol.geom.Collection.prototype.setTypeBlacklist = function(typeBlacklist){
this.typeBlacklist_ = typeBlacklist;
};
/**
* Gets the list of disallowed types for the collection.
* @return {Array.<Function>} Array of constructors to disallow.
*/
ol.geom.Collection.prototype.getTypeBlacklist = function(){
return this.typeBlacklist_;
};
/**
* Sets the list of always allowed types for the collection.
* @param {Array.<Function>} typeWhitelist Array of constructors to allow.
*/
ol.geom.Collection.prototype.setTypeWhitelist = function(typeWhitelist){
this.typeWhitelist_ = typeWhitelist;
};
/**
* Gets the list of always allowed types for the collection.
* @return {Array.<Function>} Array of constructors to allow.
*/
ol.geom.Collection.prototype.getTypeWhitelist = function(){
return this.typeWhitelist_;
};
/**
* Sets the Collection's components.
*
* @return {Array.<ol.geom.Geometry>} An array of components.
*/
ol.geom.Collection.prototype.getComponents = function() {
return this.components_;
};
/**
* Gets the Collection's components.
*
* @param {Array.<ol.geom.Geometry>} components An array of components.
*/
ol.geom.Collection.prototype.setComponents = function(components) {
var allValidTypes = goog.array.every(
components,
this.isAllowedComponent,
this
);
if (allValidTypes) {
this.components_ = components;
} else {
var msg = 'ol.geom.Collection: at least one component passed to '
+ 'setComponents is not allowed.';
ol.error(msg);
}
};
/**
* Adds the given component to the list of components at the specified index.
*
* @param {ol.geom.Geometry} component A component to be added.
* @param {number} index The index where to add.
*/
ol.geom.Collection.prototype.addComponent = function(component, index) {
if (this.isAllowedComponent(component)) {
goog.array.insertAt(this.components_, component, index);
} else {
var msg = 'ol.geom.Collection: component is not allowed to be added.';
ol.error(msg);
}
};
/**
* Checks whether the passed component is an instance of any of the constructors
* listed in the passed list.
*
* @param {ol.geom.Geometry} component The component to check.
* @param {Array.<Function>} list The List of constructors to check the
* component against.
*
* @return {boolean} Whether the passed component is an instance of any of the
* constructors listed in the passed list.
*
* @private
*/
ol.geom.Collection.prototype.isOnList = function(component, list) {
var isOnList = !goog.array.every(list, function(listedConstr){
if (component instanceof listedConstr) {
return false;
} else {
return true;
}
});
return isOnList;
};
/**
* Checks whether the passed component is allowed according to the black and
* whitelists.
*
* @param {ol.geom.Geometry} component The component to check.
* @return {boolean} Whether the passed component is allowed as part of this
* collection according to black- and whitelist.
*/
ol.geom.Collection.prototype.isAllowedComponent = function(component){
var whitelist = this.getTypeWhitelist(),
blacklist = this.getTypeBlacklist(),
isOnWhitelist = this.isOnList(component, whitelist),
isOnBlacklist = this.isOnList(component, blacklist);
return (isOnWhitelist || !isOnBlacklist);
};
/**
* Removes the given component from the list of components.
*
* @param {ol.geom.Geometry} component A component to be removed.
*/
ol.geom.Collection.prototype.removeComponent = function(component) {
goog.array.remove(this.components_, component);
};
/**
* Compute the centroid for this geometry collection.
*
* @returns {ol.geom.Point} The centroid of the collection.
*/
ol.geom.Collection.prototype.getCentroid = function() {
var components = this.getComponents(),
len = components.length,
sum_x = 0, sum_y = 0,
centroid = null;
if (len > 0) {
goog.array.forEach(components, function(component){
var singleCentroid = component.getCentroid();
if (goog.isDefAndNotNull(singleCentroid)) {
sum_x += singleCentroid.getX();
sum_y += singleCentroid.getX();
} else {
len--;
}
});
centroid = new ol.geom.Point(sum_x / len, sum_y / len);
}
return centroid;
};

View File

@@ -1,58 +0,0 @@
goog.provide('ol.geom.Geometry');
goog.require('ol.geom.IGeometry');
goog.require('ol.Bounds');
/**
* Creates ol.Geometry objects.
*
* @export
* @implements {ol.geom.IGeometry}
* @constructor
*/
ol.geom.Geometry = function() {
/**
* @private
* @type {ol.Bounds|undefined}
*/
this.bounds_ = undefined;
};
/**
* @return {ol.Bounds|undefined} The ol.Bounds.
*/
ol.geom.Geometry.prototype.getBounds = function() {
return this.bounds_;
};
/**
* @param {ol.Bounds} bounds The new ol.Bounds.
* @return {ol.geom.Geometry} This.
*/
ol.geom.Geometry.prototype.setBounds = function(bounds) {
this.bounds_ = bounds;
return this;
};
/**
* Returns the centroid of the geometry.
*
* @returns {ol.geom.Point} The centroid of the geometry.
*/
ol.geom.Geometry.prototype.getCentroid = function() {
// throw an error to enforce subclasses to implement it properly
ol.error('ol.geom.Geometry: getCentroid must be implemented by subclasses');
return null;
};
/**
* Returns the area of the geometry.
*
* @returns {number} The area of the geometry.
*/
ol.geom.Geometry.prototype.getArea = function() {
// throw an error to enforce subclasses to implement it properly
ol.error('ol.geom.Geometry: getArea must be implemented by subclasses');
return 0;
};

View File

@@ -1,27 +0,0 @@
goog.provide('ol.geom.IGeometry');
//goog.require('ol.geom.Point');
//goog.require('ol.Bounds');
/**
* Interface for geometry classes forcing ol.geom.* classes to implement
* expected functionality.
*
* @interface
*/
ol.geom.IGeometry = function(){};
/**
* @return {ol.geom.Point} The centroid of the geometry.
*/
ol.geom.IGeometry.prototype.getCentroid = function(){};
/**
* @return {ol.Bounds|undefined} The centroid of the geometry.
*/
ol.geom.IGeometry.prototype.getBounds = function(){};
/**
* @return {number} The area of the geometry.
*/
ol.geom.IGeometry.prototype.getArea = function(){};

View File

@@ -1,76 +0,0 @@
goog.provide('ol.geom.LineString');
goog.require('goog.array');
goog.require('ol.geom.Geometry');
goog.require('ol.geom.Collection');
goog.require('ol.geom.Point');
goog.require('ol.Projection');
/**
* Creates ol.geom.LineString objects.
*
* @export
* @extends {ol.geom.Geometry}
* @param {Array.<ol.geom.Point>} vertices An array of points building the
* linestrings vertices.
*
* @constructor
*/
ol.geom.LineString = function(vertices) {
/**
* @private
* @type {Array.<ol.geom.Point>}
*/
this.vertices_ = vertices;
};
goog.inherits(ol.geom.LineString, ol.geom.Geometry);
/**
* Sets the LineString's points.
*
* @return {Array.<ol.geom.Point>} An array of points.
*/
ol.geom.LineString.prototype.getVertices = function() {
return this.vertices_;
};
/**
* Gets the LineString's points.
*
* @param {Array.<ol.geom.Point>} vertices An array of points.
*/
ol.geom.LineString.prototype.setVertices = function(vertices) {
this.vertices_ = vertices;
};
/**
* Adds the given vertex to the list of vertices at the specified index.
*
* @param {ol.geom.Point} vertex A point to be added.
* @param {number} index The index where to add.
*/
ol.geom.LineString.prototype.addVertex = function(vertex, index) {
goog.array.insertAt(this.vertices_,vertex,index);
};
/**
* Removes the given vertex from the list of vertices.
*
* @param {ol.geom.Point} vertex A point to be removed.
*/
ol.geom.LineString.prototype.removeVertex = function(vertex) {
goog.array.remove(this.vertices_, vertex);
};
/**
* Compute the centroid for this linestring.
*
* @returns {ol.geom.Point} The centroid of the linestring.
*/
ol.geom.LineString.prototype.getCentroid = function() {
var vertices = this.getVertices(),
collection = new ol.geom.Collection(vertices);
return collection.getCentroid();
};

View File

@@ -1,61 +0,0 @@
goog.provide('ol.geom.MultiLineString');
goog.require('goog.array');
goog.require('ol.geom.Collection');
/**
* Creates ol.geom.MultiLineString objects.
*
* @export
* @extends {ol.geom.Collection}
* @param {Array.<ol.geom.LineString>} linestrings An array of linestrings.
*
* @constructor
*/
ol.geom.MultiLineString = function(linestrings) {
this.setTypeWhitelist([ol.geom.LineString]);
this.setTypeBlacklist([ol.geom.Geometry]);
if (arguments.length === 1 && goog.isDef(linestrings)) {
this.setLineStrings(linestrings);
}
};
goog.inherits(ol.geom.MultiLineString, ol.geom.Collection);
/**
* Gets the MultiLineString's linestrings.
*
* @return {Array.<ol.geom.LineString>} An array of linestrings.
*/
ol.geom.MultiLineString.prototype.getLineStrings = function() {
return this.getComponents();
};
/**
* Sets the MultiLineString's linestrings.
*
* @param {Array.<ol.geom.LineString>} linestrings An array of linestrings.
*/
ol.geom.MultiLineString.prototype.setLineStrings = function(linestrings) {
this.setComponents(linestrings);
};
/**
* Adds the given linestring to the list of linestrings at the specified index.
*
* @param {ol.geom.LineString} linestring A linestring to be added.
* @param {number} index The index where to add.
*/
ol.geom.MultiLineString.prototype.addLineString = function(linestring, index) {
this.addComponent(linestring, index);
};
/**
* Removes the given linestring from the list of linestrings.
*
* @param {ol.geom.LineString} linestring A linestring to be removed.
*/
ol.geom.MultiLineString.prototype.removeLineString = function(linestring) {
this.removeComponent(linestring);
};

View File

@@ -1,61 +0,0 @@
goog.provide('ol.geom.MultiPoint');
goog.require('goog.array');
goog.require('ol.geom.Collection');
/**
* Creates ol.geom.MultiPoint objects.
*
* @export
* @extends {ol.geom.Collection}
* @param {Array.<ol.geom.Point>} points An array of points.
*
* @constructor
*/
ol.geom.MultiPoint = function(points) {
this.setTypeWhitelist([ol.geom.Point]);
this.setTypeBlacklist([ol.geom.Geometry]);
if (arguments.length === 1 && goog.isDef(points)) {
this.setPoints(points);
}
};
goog.inherits(ol.geom.MultiPoint, ol.geom.Collection);
/**
* Sets the MultiPoint's points.
*
* @return {Array.<ol.geom.Point>} An array of points.
*/
ol.geom.MultiPoint.prototype.getPoints = function() {
return this.getComponents();
};
/**
* Gets the MultiPoint's points.
*
* @param {Array.<ol.geom.Point>} points An array of points.
*/
ol.geom.MultiPoint.prototype.setPoints = function(points) {
this.setComponents(points);
};
/**
* Adds the given point to the list of points at the specified index.
*
* @param {ol.geom.Point} point A point to be added.
* @param {number} index The index where to add.
*/
ol.geom.MultiPoint.prototype.addPoint = function(point, index) {
this.addComponent(point, index);
};
/**
* Removes the given point from the list of points.
*
* @param {ol.geom.Point} point A point to be removed.
*/
ol.geom.MultiPoint.prototype.removePoint = function(point) {
this.removeComponent(point);
};

View File

@@ -1,163 +0,0 @@
goog.provide('ol.geom.Point');
goog.require('ol.geom.Geometry');
goog.require('ol.Projection');
goog.require('ol.coord.AccessorInterface');
goog.require('ol.base');
/**
* Creates ol.geom.Point objects.
*
* @export
* @extends {ol.geom.Geometry}
* @param {number} x X.
* @param {number} y Y.
* @param {number=} opt_z Z.
* @param {ol.Projection=} opt_projection Projection.
*
* @implements {ol.coord.AccessorInterface}
*
* @constructor
*/
ol.geom.Point = function(x, y, opt_z, opt_projection) {
/**
* @private
* @type {number}
*/
this.x_ = x;
/**
* @private
* @type {number}
*/
this.y_ = y;
/**
* @private
* @type {number|undefined}
*/
this.z_ = opt_z;
/**
* @private
* @type {ol.Projection}
*/
this.projection_ = goog.isDef(opt_projection) ? opt_projection : null;
};
goog.inherits(ol.geom.Point, ol.geom.Geometry);
/**
* @return {number} X.
*/
ol.geom.Point.prototype.getX = function() {
return this.x_;
};
/**
* @return {number} Y.
*/
ol.geom.Point.prototype.getY = function() {
return this.y_;
};
/**
* @return {number|undefined} Z.
*/
ol.geom.Point.prototype.getZ = function() {
return this.z_;
};
/**
* @return {ol.Projection|undefined} Projection.
*/
ol.geom.Point.prototype.getProjection = function() {
return this.projection_;
};
/**
* @param {ol.Projection} projection Projection.
*/
ol.geom.Point.prototype.setProjection = function(projection) {
this.projection_ = projection;
};
/**
* @param {number} x X.
*/
ol.geom.Point.prototype.setX = function(x) {
this.x_ = x;
};
/**
* @param {number} y Y.
*/
ol.geom.Point.prototype.setY = function(y) {
this.y_ = y;
};
/**
* @param {number|undefined} z Z.
*/
ol.geom.Point.prototype.setZ = function(z) {
this.z_ = z;
};
/**
* Transform this point to another coordinate reference system. This
* requires that this point has a projection set already (if not, an error
* will be thrown). Returns a new point object and does not modify this
* point.
*
* @param {string|!ol.Projection} proj The destination projection. Can be
* supplied as a projection instance of a string identifier.
* @returns {!ol.geom.Point} A new location.
*/
ol.geom.Point.prototype.transform = function(proj) {
if (goog.isString(proj)) {
proj = new ol.Projection(proj);
}
return this._transform(proj);
};
/**
* Transform this point to a new location given a projection object.
*
* @param {!ol.Projection} proj The destination projection.
* @returns {!ol.geom.Point}
* @private
*/
ol.geom.Point.prototype._transform = function(proj) {
var point = {'x': this.x_, 'y': this.y_};
var sourceProj = this.projection_;
if (!goog.isDefAndNotNull(sourceProj)) {
var msg = 'Cannot transform a point without a source projection.';
ol.error(msg);
}
ol.Projection.transform(point, sourceProj, proj);
return new ol.geom.Point(point['x'], point['y'], this.z_, proj);
};
/**
* Returns the centroid of the point.
*
* @returns {ol.geom.Point} The centroid of the point.
*/
ol.geom.Point.prototype.getCentroid = function() {
return new ol.geom.Point(this.x_, this.y_, this.z_, this.projection_);
};
/**
* Returns the area of the geometry whcih is always 0.
*
* @returns {number} The area of the point (always 0).
*/
ol.geom.Point.prototype.getArea = function() {
return 0;
};

View File

@@ -1,22 +0,0 @@
goog.provide('ol.layer.Layer');
/**
* @constructor
* @export
*/
ol.layer.Layer = function() {
/**
* @type {string}
* @protected
*/
this.attribution_;
};
/**
* @return {string}
*/
ol.layer.Layer.prototype.getAttribution = function() {
return this.attribution_;
};

View File

@@ -1,21 +0,0 @@
goog.provide('ol.layer.OSM');
goog.require('ol.layer.XYZ');
/**
* Class for OSM layers.
*
* @export
* @constructor
* @extends {ol.layer.XYZ}
*/
ol.layer.OSM = function() {
//TODO Is this attribution still correct?
/** @inheritDoc */
this.attribution_ = "Data CC-By-SA by <a target='_blank' href='http://openstreetmap.org/'>OpenStreetMap</a>";
goog.base(this, 'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png');
};
goog.inherits(ol.layer.OSM, ol.layer.XYZ);

View File

@@ -1,490 +0,0 @@
goog.provide('ol.layer.TileLayer');
goog.require('ol.error');
goog.require('ol.layer.Layer');
goog.require('ol.Tile');
goog.require('ol.TileCache');
/**
* @constructor
* @extends {ol.layer.Layer}
*/
ol.layer.TileLayer = function() {
/**
* @private
* @type {string|undefined}
*/
this.url_ = undefined;
/**
* @protected
* @type {ol.Projection}
*/
this.projection_ = null;
/**
* @private
* @type {ol.Bounds}
*/
this.extent_ = null;
/**
* @protected
* @type {number}
*/
this.tileWidth_ = 256;
/**
* @protected
* @type {number}
*/
this.tileHeight_ = 256;
/**
* @protected
* @type {function(new:ol.Tile, string, ol.Bounds=)}
*/
this.Tile = ol.Tile.createConstructor(this.tileWidth_, this.tileHeight_);
/**
* @protected
* @type {number|undefined}
*/
this.tileOriginX_ = undefined;
/**
* @protected
* @type {number|undefined}
*/
this.tileOriginY_ = undefined;
/**
* @private
* @type {string}
*/
this.tileOriginCorner_ = 'tl';
/**
* @private
* @type {number|undefined}
*/
this.maxResolution_ = undefined;
/**
* @private
* @type {boolean}
*/
this.xRight_ = true;
/**
* @private
* @type {boolean}
*/
this.yDown_ = true;
/**
* @private
* @type {number|undefined}
*/
this.numZoomLevels_ = undefined;
/**
* @protected
* @type {Array.<number>}
*/
this.resolutions_ = null;
/**
* @private
* @type {ol.TileCache}
*/
this.cache_ = new ol.TileCache();
};
goog.inherits(ol.layer.TileLayer, ol.layer.Layer);
/**
* @protected
* @param {number} x
* @param {number} y
* @param {number} z
* @return {string}
*/
ol.layer.TileLayer.prototype.getTileUrl = function(x, y, z) {
// overridden by subclasses
};
/**
* @return {string|undefined} The layer URL.
*/
ol.layer.TileLayer.prototype.getUrl = function() {
return this.url_;
};
/**
* @return {boolean} The tile index increases from left to right.
*/
ol.layer.TileLayer.prototype.getXRight = function() {
return this.xRight_;
};
/**
* @return {boolean} The tile index increases from top to bottom.
*/
ol.layer.TileLayer.prototype.getYDown = function() {
return this.yDown_;
};
/**
* @param {boolean} right The tile index increases from left to right.
*/
ol.layer.TileLayer.prototype.setXRight = function(right) {
this.xRight_ = right;
};
/**
* @param {boolean} down The tile index increases from top to bottom.
*/
ol.layer.TileLayer.prototype.setYDown = function(down) {
this.yDown_ = down;
};
/**
* Get layer extent. Return null if the layer has no extent
* and no projection.
* @return {ol.UnreferencedBounds}
*/
ol.layer.TileLayer.prototype.getExtent = function() {
if (!goog.isNull(this.extent_)) {
return this.extent_;
}
if (!goog.isNull(this.projection_)) {
return this.projection_.getExtent();
}
return null;
};
/**
* Get tile size.
* @return {Array.<number>}
*/
ol.layer.TileLayer.prototype.getTileSize = function() {
return [this.tileWidth_, this.tileHeight_];
};
/**
* Get tile origin.
* @return {Array.<number>}
*/
ol.layer.TileLayer.prototype.getTileOrigin = function() {
if (goog.isDef(this.tileOriginX_) &&
goog.isDef(this.tileOriginY_)) {
return [this.tileOriginX_, this.tileOriginY_];
}
var errmsg = 'Cannot calculate tile origin; ';
if (goog.isDef(this.tileOriginCorner_)) {
var extent = this.getExtent();
if (!goog.isNull(extent)) {
var tileOriginX, tileOriginY;
switch (this.tileOriginCorner_) {
case "tl":
tileOriginX = extent.getMinX();
tileOriginY = extent.getMaxY();
break;
case "tr":
tileOriginX = extent.getMaxX();
tileOriginY = extent.getMaxY();
break;
case "bl":
tileOriginX = extent.getMinX();
tileOriginY = extent.getMinY();
break;
case "br":
tileOriginX = extent.getMaxX();
tileOriginY = extent.getMinY();
break;
default:
errmsg += 'tileOriginCorner value is incorrect.';
ol.error(errmsg);
}
return [tileOriginX, tileOriginY];
}
errmsg += 'layer has no extent.';
ol.error(errmsg);
}
errmsg += 'layer has no tileOriginCorner.';
ol.error(errmsg);
return null;
};
/**
* Get max resolution. Return undefined if the layer has no maxResolution,
* and no extent from which maxResolution could be derived.
* @return {number|undefined}
*/
ol.layer.TileLayer.prototype.getMaxResolution = function() {
if (!goog.isDef(this.maxResolution_)) {
var extent = this.getExtent();
if (!goog.isNull(extent)) {
this.maxResolution_ = Math.max(
(extent.getMaxX() - extent.getMinX()) / this.tileWidth_,
(extent.getMaxY() - extent.getMinY()) / this.tileHeight_);
}
}
return this.maxResolution_;
};
/**
* Get the number of the zoom levels.
* @return {number|undefined}
*/
ol.layer.TileLayer.prototype.getNumZoomLevels = function() {
return this.numZoomLevels_;
};
/**
* Get layer resolutions. Return null if the layer has no resolutions.
* @return {Array.<number>}
*/
ol.layer.TileLayer.prototype.getResolutions = function() {
if (goog.isNull(this.resolutions_)) {
var maxResolution = this.getMaxResolution(),
numZoomLevels = this.getNumZoomLevels();
if (goog.isDef(maxResolution) && goog.isDef(numZoomLevels)) {
this.resolutions_ = [];
for (var i = 0; i < numZoomLevels; i++) {
this.resolutions_[i] = maxResolution / Math.pow(2, i);
}
}
}
return this.resolutions_;
};
/**
* Set the layer URL.
* @param {string} url
*/
ol.layer.TileLayer.prototype.setUrl = function(url) {
this.url_ = url;
};
/**
* Set layer projection.
* @param {ol.Projection} projection
*/
ol.layer.TileLayer.prototype.setProjection = function(projection) {
this.projection_ = projection;
};
/**
* Set layer extent.
* @param {ol.Bounds} extent
*/
ol.layer.TileLayer.prototype.setExtent = function(extent) {
this.extent_ = extent;
};
/**
* Set tile origin.
* @param {number} tileOriginX
* @param {number} tileOriginY
*/
ol.layer.TileLayer.prototype.setTileOrigin = function(tileOriginX, tileOriginY) {
this.tileOriginX_ = tileOriginX;
this.tileOriginY_ = tileOriginY;
};
/**
* Set tile origin corner.
* @param {string} tileOriginCorner
*/
ol.layer.TileLayer.prototype.setTileOriginCorner = function(tileOriginCorner) {
this.tileOriginCorner_ = tileOriginCorner;
};
/**
* Set maximum resolution.
* @param {number} maxResolution
*/
ol.layer.TileLayer.prototype.setMaxResolution = function(maxResolution) {
this.maxResolution_ = maxResolution;
};
/**
* Set the number of zoom levels.
* @param {number} numZoomLevels
*/
ol.layer.TileLayer.prototype.setNumZoomLevels = function(numZoomLevels) {
this.numZoomLevels_ = numZoomLevels;
};
/**
* Set resolutions for the layer.
* @param {Array.<number>} resolutions
*/
ol.layer.TileLayer.prototype.setResolutions = function(resolutions) {
this.resolutions_ = resolutions;
};
/**
* Get a tile from the cache, or create a tile and add to
* the cache.
* @param url {string}
* @param bounds {ol.Bounds}
*/
ol.layer.TileLayer.prototype.getTile = function(url, bounds) {
var tile = this.cache_.get(url);
if (!goog.isDef(tile)) {
tile = new this.Tile(url, bounds);
this.cache_.set(tile.getUrl(), tile);
}
return tile;
};
/**
* Get a tile from the cache, or create a tile and add to
* the cache.
* @param {number} x
* @param {number} y
* @param {number} z
*/
ol.layer.TileLayer.prototype.getTileForXYZ = function(x, y, z) {
if (!this.validXY(x, y, z)) {
return null;
}
var tileUrl = this.getTileUrl(x, y, z);
var tile = this.cache_.get(tileUrl);
if (!goog.isDef(tile)) {
tile = new this.Tile(tileUrl);
this.cache_.set(tileUrl, tile);
}
return tile;
};
/**
* Determine if the tile x/y/z intersects the layer extent. Always
* return true if the layer has no extent.
* @param {number} x
* @param {number} y
* @param {number} z
* @return {boolean}
*/
ol.layer.TileLayer.prototype.validXY = function(x, y, z) {
var extent = this.getExtent();
if (goog.isNull(extent)) {
return true;
}
var extentMinX = extent.getMinX(),
extentMinY = extent.getMinY(),
extentMaxX = extent.getMaxX(),
extentMaxY = extent.getMaxY();
var tileOrigin = this.getTileOrigin(),
tileOriginX = tileOrigin[0],
tileOriginY = tileOrigin[1];
var resolution = this.getResolutions()[z];
var tileWidth = this.tileWidth_ * resolution,
tileHeight = this.tileHeight_ * resolution;
var minX, maxX;
if (this.xRight_) {
minX = Math.floor((extentMinX - tileOriginX) / tileWidth);
maxX = Math.ceil((extentMaxX - tileOriginX) / tileWidth) - 1;
} else {
minX = Math.floor((tileOriginX - extentMaxX) / tileWidth);
maxX = Math.ceil((tileOriginX - extentMinX) / tileWidth) - 1;
}
var minY, maxY;
if (this.yDown_) {
minY = Math.floor((tileOriginY - extentMaxY) / tileHeight);
maxY = Math.ceil((tileOriginY - extentMinY) / tileHeight) - 1;
} else {
minY = Math.floor((extentMinY - tileOriginY) / tileHeight);
maxY = Math.ceil((extentMaxY - tileOriginY) / tileHeight) - 1;
}
return x >= minX && x <= maxX && y >= minY && y <= maxY;
};
/**
* Get data from the layer. This is the layer's main API function.
* @param {ol.Bounds} bounds
* @param {number} resolution
*/
ol.layer.TileLayer.prototype.getData = function(bounds, resolution) {
var me = this,
zoomAndRes = me.getZoomAndRes(resolution),
zoom = zoomAndRes[0];
resolution = zoomAndRes[1];
// define some values used for the actual tiling
var boundsMinX = bounds.getMinX(),
boundsMaxX = bounds.getMaxX(),
boundsMinY = bounds.getMinY(),
boundsMaxY = bounds.getMaxY(),
tileWidth = me.tileWidth_,
tileHeight = me.tileHeight_,
tileOrigin = me.getTileOrigin(),
tileOriginX = tileOrigin[0],
tileOriginY = tileOrigin[1],
tileWidthGeo = tileWidth * resolution,
tileHeightGeo = tileHeight * resolution;
// make sure we don't create tiles outside the layer extent
var extent = this.getExtent();
if (extent) {
boundsMinX = Math.max(boundsMinX, extent.getMinX());
boundsMaxX = Math.min(boundsMaxX, extent.getMaxX());
boundsMinY = Math.max(boundsMinY, extent.getMinY());
boundsMaxY = Math.min(boundsMaxY, extent.getMaxY());
}
var offsetX = Math.floor(
(boundsMinX - tileOriginX) / tileWidthGeo),
offsetY = Math.floor(
(tileOriginY - boundsMaxY) / tileHeightGeo),
gridLeft = tileOriginX + tileWidthGeo * offsetX,
gridTop = tileOriginY - tileHeightGeo * offsetY;
// now tile
var tiles = [],
tile,
url,
tileBottom, tileRight, tileBounds;
for (var y=0, tileTop=gridTop; tileTop > boundsMinY;
++y, tileTop-=tileHeightGeo) {
tiles[y] = [];
tileBottom = tileTop - tileHeightGeo;
for (var x=0, tileLeft=gridLeft; tileLeft < boundsMaxX;
++x, tileLeft+=tileWidthGeo) {
tileRight = tileLeft + tileWidthGeo;
tileBounds = new ol.Bounds(tileLeft, tileBottom,
tileRight, tileTop, this.projection_);
url = this.getTileUrl(offsetX + x, offsetY + y, zoom);
tile = this.getTile(url, tileBounds);
tiles[y][x] = tile;
}
}
return new ol.TileSet(tiles, tileWidth, tileHeight, resolution);
};
/**
* Get the zoom level (z) and layer resolution for the given resolution.
* @param {number} resolution
* @return {Array.<number>}
*/
ol.layer.TileLayer.prototype.getZoomAndRes = function(resolution) {
var delta = Number.POSITIVE_INFINITY,
currentDelta,
resolutions = this.getResolutions(),
zoom;
for (var i=resolutions.length-1; i>=0; --i) {
currentDelta = Math.abs(resolutions[i] - resolution);
if (currentDelta > delta) {
break;
}
delta = currentDelta;
}
zoom = i + 1;
return [zoom, resolutions[zoom]];
};

View File

@@ -1,74 +0,0 @@
goog.provide('ol.layer.WMS');
goog.require('goog.Uri');
goog.require('ol.layer.TileLayer');
/**
* Class for WMS layers.
*
* @export
* @constructor
* @extends {ol.layer.TileLayer}
* @param {string} url The WMS URL.
* @param {Array.<string>} layers List of layers.
* @param {string|undefined} format Image format (e.g. "image/jpeg")
*/
ol.layer.WMS = function(url, layers, format) {
goog.base(this);
this.setUrl(url);
/**
* @private
* @type {Array.<string>}
*/
this.layers_ = layers;
/**
* @private
* @type {string|undefined}
*/
this.format_ = format;
};
goog.inherits(ol.layer.WMS, ol.layer.TileLayer);
/**
* @const
* @type {Object}
*/
ol.layer.WMS.prototype.DEFAULT_PARAMS = {
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
"STYLES": "",
"FORMAT": "image/png"
};
/**
* @inheritDoc
*/
ol.layer.WMS.prototype.getTileUrl = function(x, y, z) {
var tileOrigin = this.getTileOrigin(),
tileOriginX = tileOrigin[0],
tileOriginY = tileOrigin[1];
var resolution = this.getResolutions()[z];
var tileWidth = this.tileWidth_ * resolution,
tileHeight = this.tileHeight_ * resolution;
var minX = tileOriginX + (x * tileWidth),
maxY = tileOriginY - (y * tileHeight),
maxX = minX + tileWidth,
minY = maxY - tileHeight;
var qd = new goog.Uri.QueryData();
qd.extend(this.DEFAULT_PARAMS);
qd.set('WIDTH', this.tileWidth_);
qd.set('HEIGHT', this.tileHeight_);
qd.set('BBOX', [minX, minY, maxX, maxY].join(','));
qd.set('LAYERS', [this.layers_].join(','));
// FIXME this requires a projection in the layer, which should
// not be required
qd.set('SRS', this.projection_.getCode());
var uri = new goog.Uri(this.getUrl());
uri.setQueryData(qd);
return uri.toString();
};

View File

@@ -1,35 +0,0 @@
goog.provide('ol.layer.XYZ');
goog.require('ol.layer.TileLayer');
goog.require('ol.Projection');
goog.require('ol.TileSet');
/**
* Class for XYZ layers.
*
* @export
* @constructor
* @extends {ol.layer.TileLayer}
* @param {string} url URL template. E.g.
* http://a.tile.openstreetmap.org/{z}/{x}/{y}.png.
*/
ol.layer.XYZ = function(url) {
goog.base(this);
this.setUrl(url);
this.setProjection(new ol.Projection("EPSG:3857"));
this.setNumZoomLevels(22);
};
goog.inherits(ol.layer.XYZ, ol.layer.TileLayer);
/**
* @inheritDoc
*/
ol.layer.XYZ.prototype.getTileUrl = function(x, y, z) {
var base = this.getUrl();
return base.replace('{x}', x + '')
.replace('{y}', y + '')
.replace('{z}', z + '');
};

19
src/ol/object_test.js Normal file
View File

@@ -0,0 +1,19 @@
goog.require('goog.testing.jsunit');
goog.require('ol');
goog.require('ol3.Object');
function testObject1() {
var obj = {k: 1};
obj = ol.object(obj);
assertTrue(obj instanceof ol3.Object);
assertEquals(1, obj.get('k'));
}
function testObject2() {
var obj1 = new ol3.Object();
var obj2 = ol.object(obj1);
assertTrue(obj2 === obj1);
}

168
src/ol/ol.js Normal file
View File

@@ -0,0 +1,168 @@
goog.provide('ol');
goog.provide('ol.layer');
goog.require('goog.dom');
goog.require('ol3.Collection');
goog.require('ol3.Coordinate');
goog.require('ol3.Layer');
goog.require('ol3.Map');
goog.require('ol3.Object');
goog.require('ol3.Projection');
goog.require('ol3.createMap');
goog.require('ol3.layer.OpenStreetMap');
goog.exportSymbol('ol', ol);
/**
* @typedef {Array|ol3.Collection}
*/
ol.Collection;
/**
* @typedef {Array.<number>|ol3.Coordinate|{x: number, y: number}}
*/
ol.Coordinate;
/**
* @typedef {{center: (ol.Coordinate|undefined),
* layers: (ol.Collection|undefined),
* renderTo: (Element|string|undefined),
* resolution: (number|undefined),
* zoom: (number|undefined)}}
*/
ol.MapOptions;
/**
* @typedef {Object|ol3.Object}
*/
ol.Object;
/**
* @typedef {ol3.Projection|string}
*/
ol.Projection;
/**
* @param {ol.Collection} collection Collection.
* @return {ol3.Collection} Collection.
*/
ol.collection = function(collection) {
if (collection instanceof ol3.Collection) {
return collection;
} else if (goog.isArray(collection)) {
var array = /** @type {Array} */ collection;
return new ol3.Collection(collection);
} else {
return null;
}
};
goog.exportProperty(ol, 'collection', ol.collection);
/**
* @param {ol.Coordinate} coordinate Coordinate.
* @return {ol3.Coordinate} Coordinate.
*/
ol.coordinate = function(coordinate) {
if (coordinate instanceof ol3.Coordinate) {
return coordinate;
} else if (goog.isArray(coordinate)) {
var array = /** @type {Array.<number>} */ coordinate;
return new ol3.Coordinate(array[1], array[0]);
} else if (goog.isObject(coordinate)) {
var object = /** @type {{x: number, y: number}} */ coordinate;
return new ol3.Coordinate(object.x, object.y);
} else {
return null;
}
};
goog.exportProperty(ol, 'coordinate', ol.coordinate);
goog.exportProperty(ol, 'layer', ol.layer);
/**
* @return {ol3.Layer} Layer.
*/
ol.layer.osm = function() {
return new ol3.layer.OpenStreetMap();
};
goog.exportProperty(ol.layer, 'osm', ol.layer.osm);
/**
* @param {ol.MapOptions=} opt_mapOptions Options.
* @return {ol3.Map} Map.
*/
ol.map = function(opt_mapOptions) {
var options = opt_mapOptions || {};
var center = ol.coordinate(/** @type {ol.Coordinate} */
(goog.object.get(options, 'center', null)));
var layers = ol.collection(/** @type {ol.Collection} */
(goog.object.get(options, 'layers', null)));
var projection = ol.projection(/** @type {ol.Projection} */
(goog.object.get(options, 'projection', 'EPSG:3857')));
var resolution = /** @type {number|undefined} */
goog.object.get(options, 'resolution');
if (!goog.isDef(resolution) && goog.object.containsKey(options, 'zoom')) {
var zoom = /** @type {number} */ goog.object.get(options, 'zoom');
resolution = ol3.Projection.EPSG_3857_HALF_SIZE / (128 << zoom);
}
var target = goog.dom.getElement(/** @type {Element|string} */
(goog.object.get(options, 'renderTo', 'map')));
var userProjection = ol.projection(/** @type {ol.Projection} */
(goog.object.get(options, 'userProjection', 'EPSG:4326')));
var map = ol3.createMap(target, {
'layers': layers,
'projection': projection,
'resolution': resolution,
'userProjection': userProjection
});
if (!goog.isNull(center)) {
map.setUserCenter(center);
}
return map;
};
goog.exportProperty(ol, 'map', ol.map);
/**
* @param {ol.Object} object Object.
* @return {ol3.Object} Object.
*/
ol.object = function(object) {
if (object instanceof ol3.Object) {
return object;
} else if (goog.isObject(object)) {
var values = /** @type {Object} */ object;
return new ol3.Object(values);
} else {
return null;
}
};
goog.exportProperty(ol, 'object', ol.object);
/**
* @param {ol.Projection} projection Projection.
* @return {ol3.Projection} Projection.
*/
ol.projection = function(projection) {
if (projection instanceof ol3.Projection) {
return projection;
} else if (goog.isString(projection)) {
var code = /** @type {string} */ projection;
return ol3.Projection.getFromCode(code);
} else {
return null;
}
};
goog.exportProperty(ol, 'projection', ol.projection);

View File

@@ -1,314 +0,0 @@
goog.provide('ol.renderer.Composite');
goog.require('ol.renderer.MapRenderer');
goog.require('ol.renderer.LayerRenderer');
goog.require('ol.layer.Layer');
goog.require('ol.Loc');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.style');
goog.require('goog.math.Coordinate');
/**
* @constructor
* @param {!Element} container
* @extends {ol.renderer.MapRenderer}
*/
ol.renderer.Composite = function(container) {
goog.base(this, container);
/**
* @type {Array.<ol.renderer.LayerRenderer>}
* @private
*/
this.renderers_ = [];
/**
* Pixel buffer for renderer container.
*
* @type {number}
* @private
*/
this.buffer_ = 128;
/**
* @type {Element}
* @private
*/
this.target_ = null;
/**
* The current top left corner location of the target element (map coords).
*
* @type {ol.Loc}
* @private
*/
this.targetOrigin_ = null;
/**
* The pixel offset of the target element with respect to its container.
*
* @type {goog.math.Coordinate}
* @private
*/
this.targetOffset_ = null;
/**
* @type {Object}
* @private
*/
this.layerContainers_ = {};
};
goog.inherits(ol.renderer.Composite, ol.renderer.MapRenderer);
/**
* @param {Array.<ol.layer.Layer>} layers
* @param {ol.Loc} center
* @param {number} resolution
* @param {boolean} animate
*/
ol.renderer.Composite.prototype.draw = function(layers, center, resolution, animate) {
if (goog.isNull(this.target_)) {
// first rendering
this.createTarget_(center, resolution);
}
// TODO: deal with layer order and removal
if (this.renderedResolution_) {
if (resolution !== this.renderedResolution_) {
// TODO: apply transition to old target
this.resetTarget_(center, resolution);
}
}
this.renderedResolution_ = resolution;
// shift target element to account for center change
if (this.renderedCenter_) {
this.shiftTarget_(center, resolution);
}
this.renderedCenter_ = center;
// update each layer renderer
var renderer;
for (var i=0, ii=layers.length; i<ii; ++i) {
renderer = this.getOrCreateRenderer_(layers[i], i);
renderer.draw(center, resolution);
}
};
/**
* Create a new target element for layer renderer containers.
*
* @param {ol.Loc} center
* @param {number} resolution
*/
ol.renderer.Composite.prototype.createTarget_ = function(center, resolution) {
this.targetOrigin_ = this.getOriginForCenterAndRes_(center, resolution);
var containerSize = this.getContainerSize();
var containerWidth = containerSize.width;
var containerHeight = containerSize.height;
var buffer = this.buffer_;
var targetWidth = containerWidth + (2 * buffer);
var targetHeight = containerHeight + (2 * buffer);
var offset = new goog.math.Coordinate(-buffer, -buffer);
var target = goog.dom.createDom('div', {
'class': 'ol-renderer-composite',
'style': 'width:' + targetWidth + 'px;height:' + targetHeight + 'px;' +
'top:' + offset.y + 'px;left:' + offset.x + 'px;' +
'position:absolute'
});
this.target_ = target;
this.targetOffset_ = offset;
this.renderedCenter_ = center;
goog.dom.appendChild(this.container_, target);
};
/**
* @param {ol.Loc} center
* @param {number} resolution
* @return {ol.Loc}
*/
ol.renderer.Composite.prototype.getOriginForCenterAndRes_ = function(center, resolution) {
var containerSize = this.getContainerSize();
var containerWidth = containerSize.width;
var containerHeight = containerSize.height;
var buffer = this.buffer_;
var targetWidth = containerWidth + (2 * buffer);
var targetHeight = containerHeight + (2 * buffer);
return new ol.Loc(
center.getX() - (resolution * targetWidth / 2),
center.getY() + (resolution * targetHeight / 2)
);
};
/**
* Adjust the position of the renderer target given the new center.
*
* @param {ol.Loc} center
* @param {number} resolution
*/
ol.renderer.Composite.prototype.shiftTarget_ = function(center, resolution) {
var oldCenter = this.renderedCenter_;
var dx = Math.round((oldCenter.getX() - center.getX()) / resolution);
var dy = Math.round((center.getY() - oldCenter.getY()) / resolution);
if (!(dx == 0 && dy == 0)) {
var offset = this.targetOffset_;
offset.x += Math.round((oldCenter.getX() - center.getX()) / resolution);
offset.y += Math.round((center.getY() - oldCenter.getY()) / resolution);
goog.style.setPosition(this.target_, offset);
}
};
/**
* Reposition the target element back to the original offset.
*
* @param {ol.Loc} center
* @param {number} resolution
*/
ol.renderer.Composite.prototype.resetTarget_ = function(center, resolution) {
this.targetOrigin_ = this.getOriginForCenterAndRes_(center, resolution);
for (var i=0, ii=this.renderers_.length; i<ii; ++i) {
this.renderers_[i].setContainerOrigin(this.targetOrigin_);
}
var offset = new goog.math.Coordinate(-this.buffer_, -this.buffer_);
this.targetOffset_ = offset;
this.renderedCenter_ = center;
goog.style.setPosition(this.target_, offset);
};
/**
* @param {ol.layer.Layer} layer
* @param {number} index
*/
ol.renderer.Composite.prototype.getOrCreateRenderer_ = function(layer, index) {
var renderer = this.getRenderer_(layer);
if (goog.isNull(renderer)) {
renderer = this.createRenderer_(layer);
goog.array.insertAt(this.renderers_, renderer, index);
}
return renderer;
};
/**
* @param {ol.layer.Layer} layer
* @return {ol.renderer.LayerRenderer}
*/
ol.renderer.Composite.prototype.getRenderer_ = function(layer) {
function finder(candidate) {
return candidate.getLayer() === layer;
}
var renderer = goog.array.find(this.renderers_, finder);
return /** @type {ol.renderer.LayerRenderer} */ renderer;
};
/**
* @param {ol.layer.Layer} layer
*/
ol.renderer.Composite.prototype.createRenderer_ = function(layer) {
var Renderer = this.pickRendererType(layer);
goog.asserts.assert(Renderer, "No supported renderer for layer: " + layer);
var container = goog.dom.createDom('div', {
'class': 'ol-renderer-composite-layer',
'style': 'width:100%;height:100%;top:0;left:0;position:absolute'
});
goog.dom.appendChild(this.target_, container);
var renderer = new Renderer(container, layer);
renderer.setContainerOrigin(this.targetOrigin_);
this.layerContainers_[goog.getUid(renderer)] = container;
return renderer;
};
/**
* @param {ol.renderer.LayerRenderer} renderer
* @return {Element}
*/
ol.renderer.Composite.prototype.getRendererContainer_ = function(renderer) {
var container = this.layerContainers_[goog.getUid(renderer)];
goog.asserts.assert(goog.isDef(container));
return container;
};
/**
* List of preferred renderer types. Layer renderers have a getType method
* that returns a string describing their type. This list determines the
* preferences for picking a layer renderer.
*
* @type {Array.<string>}
*/
ol.renderer.Composite.preferredRenderers = ["svg", "canvas", "vml"];
/**
* @param {ol.layer.Layer} layer
* @returns {Function}
*/
ol.renderer.Composite.prototype.pickRendererType = function(layer) {
// maps candidate renderer types to candidate renderers
var types = {};
function picker(Candidate) {
var supports = Candidate['isSupported']() && Candidate['canRender'](layer);
if (supports) {
types[Candidate['getType']()] = Candidate;
}
return supports;
}
var Candidates = goog.array.filter(ol.renderer.Composite.registry_, picker);
// check to see if any preferred renderers are available
var preferences = ol.renderer.Composite.preferredRenderers;
var Renderer;
for (var i=0, ii=preferences.length; i<ii; ++i) {
Renderer = types[preferences[i]];
if (Renderer) {
break;
}
}
// if we didn't find any of the preferred renderers, use the first
return Renderer || Candidates[0] || null;
};
/**
* @type {Array.<Function>}
* @private
*/
ol.renderer.Composite.registry_ = [];
/**
* @param {Function} Renderer
*/
ol.renderer.Composite.register = function(Renderer) {
ol.renderer.Composite.registry_.push(Renderer);
};
/**
* return {string}
*/
ol.renderer.Composite.getType = function() {
// TODO: revisit
return "composite";
};
/**
* TODO: determine if there is a better way to register these renderers
*
* @export
* @return {boolean}
*/
ol.renderer.Composite.isSupported = function() {
return true;
};
ol.renderer.MapRenderer.register(ol.renderer.Composite);

View File

@@ -1,98 +0,0 @@
goog.provide('ol.renderer.LayerRenderer');
goog.require('goog.math.Coordinate');
goog.require('goog.math.Size');
/**
* A single layer renderer that will be created by the composite map renderer.
*
* @constructor
* @param {!Element} container
* @param {!ol.layer.Layer} layer
*/
ol.renderer.LayerRenderer = function(container, layer) {
/**
* @type {!Element}
* @protected
*/
this.container_ = container;
/**
* @type {goog.math.Size}
* @private
*/
this.containerSize_ = null;
/**
* Location of the top-left corner of the renderer container in map coords.
*
* @type {ol.Loc}
* @protected
*/
this.containerOrigin_ = null;
/**
* @type {!ol.layer.Layer}
* @protected
*/
this.layer_ = layer;
};
/**
* @return {goog.math.Size}
* @protected
*/
ol.renderer.LayerRenderer.prototype.getContainerSize = function() {
// TODO: listen for resize and set this.constainerSize_ null
// https://github.com/openlayers/ol3/issues/2
if (goog.isNull(this.containerSize_)) {
this.containerSize_ = goog.style.getSize(this.container_);
}
return this.containerSize_;
};
/**
* Set the location of the top-left corner of the renderer container.
*
* @param {ol.Loc} origin The container origin.
*/
ol.renderer.LayerRenderer.prototype.setContainerOrigin = function(origin) {
this.containerOrigin_ = origin;
};
/**
* Get layer being rendered.
*
* @returns {!ol.layer.Layer}
*/
ol.renderer.LayerRenderer.prototype.getLayer = function() {
return this.layer_;
};
/**
* Get an identifying string for this renderer.
*
* @returns {string|undefined}
*/
ol.renderer.LayerRenderer.prototype.getType = function() {};
/**
* Determine if this renderer is supported in the given environment.
*
* @returns {boolean}
*/
ol.renderer.LayerRenderer.isSupported = function() {
return false;
};
/**
* Determine if this renderer is capable of renderering the given layer.
*
* @param {ol.layer.Layer} layer
* @returns {boolean}
*/
ol.renderer.LayerRenderer.canRender = function(layer) {
return false;
};

View File

@@ -1,110 +0,0 @@
goog.provide('ol.renderer.MapRenderer');
goog.require('goog.style');
goog.require('goog.math.Size');
/**
* @constructor
* @param {!Element} container
*/
ol.renderer.MapRenderer = function(container) {
/**
* @type !Element
* @protected
*/
this.container_ = container;
/**
* @type {goog.math.Size}
* @private
*/
this.containerSize_ = null;
/**
* @type {ol.Loc}
* @protected
*/
this.renderedCenter_;
/**
* @type {number}
* @protected
*/
this.renderedResolution_;
};
/**
* @return {goog.math.Size}
* @protected
*/
ol.renderer.MapRenderer.prototype.getContainerSize = function() {
// TODO: listen for resize and set this.constainerSize_ null
// https://github.com/openlayers/ol3/issues/2
if (goog.isNull(this.containerSize_)) {
this.containerSize_ = goog.style.getSize(this.container_);
}
return this.containerSize_;
};
/**
* @param {Array.<ol.layer.Layer>} layers
* @param {ol.Loc} center
* @param {number} resolution
* @param {boolean} animate
*/
ol.renderer.MapRenderer.prototype.draw = function(layers, center, resolution, animate) {
};
/**
* @return {number} The rendered resolution.
*/
ol.renderer.MapRenderer.prototype.getResolution = function() {
return this.renderedResolution_;
};
/**
* TODO: determine a closure friendly way to register map renderers.
* @type {Array}
* @private
*/
ol.renderer.MapRenderer.registry_ = [];
/**
* @param {Function} Renderer
*/
ol.renderer.MapRenderer.register = function(Renderer) {
ol.renderer.MapRenderer.registry_.push(Renderer);
};
/**
* @param {Array.<string>} preferences List of preferred renderer types.
* @returns {Function} A renderer constructor.
*/
ol.renderer.MapRenderer.pickRendererType = function(preferences) {
// map of candidate renderer types to candidate renderers
var types = {};
function picker(Candidate) {
var supports = Candidate.isSupported();
if (supports) {
types[Candidate.getType()] = Candidate;
}
return supports;
}
var Candidates = goog.array.filter(ol.renderer.MapRenderer.registry_, picker);
// check to see if any preferred renderers are available
var Renderer;
for (var i=0, ii=preferences.length; i<ii; ++i) {
Renderer = types[preferences[i]];
if (Renderer) {
break;
}
}
// if we didn't find any of the preferred renderers, use the first
return Renderer || Candidates[0] || null;
};

View File

@@ -1,352 +0,0 @@
goog.provide('ol.renderer.TileLayerRenderer');
goog.require('ol.renderer.LayerRenderer');
goog.require('ol.layer.TileLayer');
goog.require('ol.renderer.Composite');
goog.require('ol.TileSet');
goog.require('ol.Bounds');
goog.require('goog.style');
goog.require('goog.math.Box');
/**
* A single layer renderer that will be created by the composite map renderer.
*
* @constructor
* @param {!Element} container
* @param {!ol.layer.Layer} layer
* @extends {ol.renderer.LayerRenderer}
*/
ol.renderer.TileLayerRenderer = function(container, layer) {
goog.base(this, container, layer);
/**
* @type {Array.<number>}
*/
this.layerResolutions_ = layer.getResolutions();
/**
* @type {Array.<number>}
*/
this.tileOrigin_ = layer.getTileOrigin();
/**
* @type {Array.<number>}
*/
this.tileSize_ = layer.getTileSize();
/**
* @type {boolean}
*/
this.xRight_ = layer.getXRight();
/**
* @type {boolean}
*/
this.yDown_ = layer.getYDown();
/**
* @type {number|undefined}
* @private
*/
this.renderedResolution_ = undefined;
/**
* @type {number|undefined}
* @private
*/
this.renderedZ_ = undefined;
};
goog.inherits(ol.renderer.TileLayerRenderer, ol.renderer.LayerRenderer);
/**
* Render the layer.
*
* @param {!ol.Loc} center
* @param {number} resolution
*/
ol.renderer.TileLayerRenderer.prototype.draw = function(center, resolution) {
if (resolution !== this.renderedResolution_) {
this.changeResolution_(resolution);
}
var z = this.renderedZ_;
var tileOrigin = this.tileOrigin_;
var offset = this.getTileOffset_();
var tileBox = this.getTileBox_(center, resolution);
var fragment = document.createDocumentFragment();
var ijz, key, tile, xyz, box, img, newTiles = false;
for (var i=tileBox.left; i<tileBox.right; ++i) {
for (var j=tileBox.top; j<tileBox.bottom; ++j) {
ijz = [i, j, z];
key = ijz.join(",");
tile = this.renderedTiles_[key];
if (!tile) {
xyz = this.getTileCoordsFromNormalizedCoords_(ijz);
tile = this.layer_.getTileForXYZ(xyz[0], xyz[1], xyz[2]);
if (tile) {
if (!tile.isLoaded() && !tile.isLoading()) {
tile.load();
}
this.renderedTiles_[key] = tile;
box = this.getTilePixelBox_(ijz, resolution);
img = tile.getImg();
img.style.top = (box.top - offset.y) + "px";
img.style.left = (box.left - offset.x) + "px";
/**
* We need to set the size here even if the scale is 1
* because the image may have been scaled previously. If
* we want to avoid setting size unnecessarily, the tile
* should keep track of the scale.
*/
img.style.height = (box.bottom - box.top) + "px";
img.style.width = (box.right - box.left) + "px";
goog.dom.appendChild(fragment, img);
newTiles = true;
}
}
}
}
if (newTiles) {
this.container_.appendChild(fragment);
}
this.renderedTileBox_ = tileBox;
this.removeInvisibleTiles_();
};
/**
* Get the pixel offset between the tile origin and the container origin.
* TODO: cache this and invalidate it with changes to the container origin.
*
* @return {goog.math.Coordinate}
*/
ol.renderer.TileLayerRenderer.prototype.getTileOffset_ = function() {
var resolution = this.renderedResolution_;
return new goog.math.Coordinate(
Math.round((this.containerOrigin_.getX() - this.tileOrigin_[0]) / resolution),
Math.round((this.tileOrigin_[1] - this.containerOrigin_.getY()) / resolution)
);
};
/**
* @param {Array.<number>} ijz
* @param {number} resolution
* @return {goog.math.Box}
*/
ol.renderer.TileLayerRenderer.prototype.getTilePixelBox_ = function(ijz, resolution) {
var tileResolution = this.layerResolutions_[ijz[2]];
var scale = resolution / tileResolution;
var tileSize = this.tileSize_;
// desired tile size (in fractional pixels)
var fpxTileWidth = tileSize[0] / scale;
var fpxTileHeight = tileSize[1] / scale;
var col = ijz[0];
var left = Math.round(col * fpxTileWidth); // inclusive
var right = Math.round((col + 1) * fpxTileWidth); // exclusive
var row = ijz[1];
var top = Math.round(row * fpxTileHeight); // inclusive
var bottom = Math.round((row + 1) * fpxTileWidth); // exclusive
return new goog.math.Box(top, right, bottom, left);
};
/**
* @param {ol.Loc} loc
* @param {number} resolution
* @return {goog.math.Coordinate}
*/
ol.renderer.TileLayerRenderer.prototype.getNormalizedTileCoord_ = function(loc, resolution) {
var tileOrigin = this.tileOrigin_;
var tileSize = this.tileSize_;
var pair = this.getPreferredResAndZ_(resolution);
var tileResolution = pair[0];
var z = pair[1];
var scale = resolution / tileResolution;
// offset from tile origin in pixel space
var dx = Math.floor((loc.getX() - tileOrigin[0]) / resolution);
var dy = Math.floor((tileOrigin[1] - loc.getY()) / resolution);
// desired tile size (in fractional pixels)
var fpxTileWidth = tileSize[0] / scale;
var fpxTileHeight = tileSize[1] / scale;
// determine normalized col number (0 based, ascending right)
var col = Math.floor(dx / fpxTileWidth);
// determine normalized row number (0 based, ascending down)
var row = Math.floor(dy / fpxTileHeight);
var box = this.getTilePixelBox_([col, row, z], resolution);
// adjust col to allow for stretched tiles
if (dx < box.left) {
col -= 1;
} else if (dx >= box.right) {
col += 1;
}
// adjust row to allow for stretched tiles
if (dy < box.top) {
row -= 1;
} else if (dy >= box.bottom) {
row += 1;
}
return new goog.math.Coordinate(col, row);
};
/**
* @param {number} resolution
* @return {Array.<number>}
*/
ol.renderer.TileLayerRenderer.prototype.getPreferredResAndZ_ = (function() {
var cache = {};
return function(resolution) {
if (resolution in cache) {
return cache[resolution];
}
var minDiff = Number.POSITIVE_INFINITY;
var candidate, diff, z, r;
for (var i=0, ii=this.layerResolutions_.length; i<ii; ++i) {
// assumes sorted resolutions
candidate = this.layerResolutions_[i];
diff = Math.abs(resolution - candidate);
if (diff < minDiff) {
z = i;
r = candidate;
minDiff = diff;
} else {
break;
}
}
var pair = cache[resolution] = [r, z];
return pair;
};
})();
/**
* Tiles rendered at the current resolution;
* @type {Object}
*/
ol.renderer.TileLayerRenderer.prototype.renderedTiles_ = {};
/**
* @param {Array.<number>} ijz
* @return {Array.<number>}
*/
ol.renderer.TileLayerRenderer.prototype.getTileCoordsFromNormalizedCoords_ = function(ijz) {
return [
this.xRight_ ? ijz[0] : -ijz[0] - 1,
this.yDown_ ? ijz[1] : -ijz[1] - 1,
ijz[2]
];
};
/**
* @param {ol.Loc} center
* @param {number} resolution
* @return {goog.math.Box}
*/
ol.renderer.TileLayerRenderer.prototype.getTileBox_ = function(center, resolution) {
var size = this.getContainerSize();
var halfWidth = size.width / 2;
var halfHeight = size.height / 2;
var leftTop = new ol.Loc(
center.getX() - (resolution * halfWidth),
center.getY() + (resolution * halfHeight));
var rightBottom = new ol.Loc(
center.getX() + (resolution * halfWidth),
center.getY() - (resolution * halfHeight));
var ltCoord = this.getNormalizedTileCoord_(leftTop, resolution);
var rbCoord = this.getNormalizedTileCoord_(rightBottom, resolution);
// right and bottom are treated as excluded, so we increment for the box
rbCoord.x += 1;
rbCoord.y += 1;
return goog.math.Box.boundingBox(ltCoord, rbCoord);
};
/**
* Get rid of tiles outside the rendered extent.
*/
ol.renderer.TileLayerRenderer.prototype.removeInvisibleTiles_ = function() {
var index, prune, i, j, z, tile;
var box = this.renderedTileBox_;
for (var ijz in this.renderedTiles_) {
index = ijz.split(",");
i = +index[0];
j = +index[1];
z = +index[2];
prune = this.renderedZ_ !== z ||
i < box.left || // beyond on the left side
i >= box.right || // beyond on the right side
j < box.top || // above
j >= box.bottom; // below
if (prune) {
tile = this.renderedTiles_[ijz];
delete this.renderedTiles_[ijz];
this.container_.removeChild(tile.getImg());
}
}
};
/**
* Deal with changes in resolution.
* TODO: implement the animation
*
* @param {number} resolution New resolution.
*/
ol.renderer.TileLayerRenderer.prototype.changeResolution_ = function(resolution) {
var pair = this.getPreferredResAndZ_(resolution);
this.renderedZ_ = pair[1];
this.renderedResolution_ = resolution;
this.renderedTiles_ = {};
goog.dom.removeChildren(this.container_);
};
/**
* Get an identifying string for this renderer.
*
* @export
* @returns {string}
*/
ol.renderer.TileLayerRenderer.getType = function() {
// TODO: revisit
return "tile";
};
/**
* Determine if this renderer type is supported in this environment.
*
* @export
* @return {boolean} This renderer is supported.
*/
ol.renderer.TileLayerRenderer.isSupported = function() {
return true;
};
/**
* Determine if this renderer can render the given layer.
*
* @export
* @param {ol.layer.Layer} layer The candidate layer.
* @return {boolean} This renderer is capable of rendering the layer.
*/
ol.renderer.TileLayerRenderer.canRender = function(layer) {
return layer instanceof ol.layer.TileLayer;
};
ol.renderer.Composite.register(ol.renderer.TileLayerRenderer);

View File

@@ -1,276 +0,0 @@
/**
* @fileoverview WebGL based MapRenderer drawing all the supplied layers in OpenGL
*/
goog.provide('ol.renderer.WebGL');
goog.require('ol.renderer.MapRenderer');
goog.require('ol.layer.Layer');
goog.require('ol.Loc');
goog.require('goog.events');
goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.vec.Mat4');
goog.require('goog.webgl');
/**
* Initialization of the native WebGL renderer (canvas, context, layers)
* @constructor
* @param {!Element} container
* @extends {ol.renderer.MapRenderer}
*/
ol.renderer.WebGL = function(container) {
/**
* @private
* @type {!Element}
*/
this.canvas_ = goog.dom.createDom('canvas', 'ol-renderer-webgl-canvas'); // Suppose to have: style: 'width:100%;height:100%;'
/**
* @private
* @type {WebGLRenderingContext}
*/
this.gl_ = (this.canvas_.getContext('experimental-webgl', {
'alpha': false,
'depth': false,
'antialias': true,
'stencil': false,
'preserveDrawingBuffer': false
}));
goog.asserts.assert(!goog.isNull(this.gl_), "The WebGL is not supported on your browser. Check http://get.webgl.org/");
goog.dom.append(container, this.canvas_);
goog.base(this, container);
/**
* @private
* @type {Object.<string, WebGLTexture>}
*/
this.textureCache_ = {};
var gl = this.gl_;
var clearColor = [0, 0, 0]; // hardcoded background color
gl.clearColor(clearColor[0], clearColor[1], clearColor[2], 1);
gl.disable(goog.webgl.DEPTH_TEST);
gl.disable(goog.webgl.SCISSOR_TEST);
gl.disable(goog.webgl.CULL_FACE);
var fragmentShader = gl.createShader(goog.webgl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, [
'precision mediump float;',
'',
'uniform sampler2D uTexture;',
'',
'varying vec2 vTexCoord;',
'',
'void main(void) {',
' gl_FragColor = vec4(vec3(texture2D(uTexture, vTexCoord)), 1.);',
'}'
].join('\n'));
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, goog.webgl.COMPILE_STATUS)) {
window.console.log(gl.getShaderInfoLog(fragmentShader));
goog.asserts.assert(gl.getShaderParameter(fragmentShader, goog.webgl.COMPILE_STATUS));
}
var vertexShader = gl.createShader(goog.webgl.VERTEX_SHADER);
gl.shaderSource(vertexShader, [
'attribute vec2 aPosition;',
'attribute vec2 aTexCoord;',
'',
'uniform mat4 uMVPMatrix;',
'',
'varying vec2 vTexCoord;',
'',
'void main(void) {',
' gl_Position = uMVPMatrix * vec4(aPosition, 0.0, 1.0);',
' vTexCoord = aTexCoord;',
'}'
].join('\n'));
if (!gl.getShaderParameter(vertexShader, goog.webgl.COMPILE_STATUS)) {
window.console.log(gl.getShaderInfoLog(vertexShader));
goog.asserts.assert(gl.getShaderParameter(vertexShader, goog.webgl.COMPILE_STATUS));
}
var program = gl.createProgram();
gl.attachShader(program, fragmentShader);
gl.attachShader(program, vertexShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, goog.webgl.LINK_STATUS)) {
window.console.log(gl.getProgramInfoLog(program));
goog.asserts.assert(gl.getProgramParameter(program, goog.webgl.LINK_STATUS));
}
this.mvpMatrixLocation_ = gl.getUniformLocation(program, 'uMVPMatrix');
this.textureLocation_ = gl.getUniformLocation(program, 'uTexture');
var texCoordBuffer = gl.createBuffer();
gl.bindBuffer(goog.webgl.ARRAY_BUFFER, texCoordBuffer);
gl.bufferData(goog.webgl.ARRAY_BUFFER, new Float32Array([0, 1, 1, 1, 0, 0, 1, 0]), goog.webgl.STATIC_DRAW);
var texCoordLocation = gl.getAttributeLocation(program, 'aTexCoord');
gl.enableVertexAttribArray(texCoordLocation);
gl.vertexAttribPointer(texCoordLocation, 2, goog.webgl.FLOAT, false, 0, 0);
gl.bindBuffer(goog.webgl.ARRAY_BUFFER, null);
this.positionLocation_ = gl.getAttributeLocation(program, 'aPosition');
gl.enableVertexAttribArray(this.positionLocation_);
this.positionBuffer_ = gl.createBuffer();
};
goog.inherits(ol.renderer.WebGL, ol.renderer.MapRenderer);
/**
* Determine if this renderer type is supported in this environment.
* A static method.
* @returns {boolean} This renderer is supported.
*/
ol.renderer.WebGL.isSupported = function() {
return !goog.isNull( goog.dom.createDom('canvas').getContext('experimental-webgl') );
};
/**
* @param {ol.Tile} tile Tile.
* @protected
*/
ol.renderer.WebGL.prototype.bindTexture = function(tile) {
var gl = this.gl_;
var url = tile.getUrl();
if (url in this.textureCache_) {
gl.bindTexture(gl.TEXTURE_2D, this.textureCache_[url]);
} else {
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, tile.getImg());
gl.texParameteri(goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_MAG_FILTER, goog.webgl.LINEAR);
gl.texParameteri(goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_MIN_FILTER, goog.webgl.LINEAR);
this.textureCache_[url] = texture;
}
};
/**
* @param {ol.Tile} tile Tile.
* @protected
*/
ol.renderer.WebGL.prototype.handleTileLoad = function(tile) {
this.redraw();
};
/**
* @param {ol.Tile} tile Tile.
* @protected
*/
ol.renderer.WebGL.prototype.handleTileDestroy = function(tile) {
var gl = this.gl_;
var url = tile.getUrl();
if (url in this.textureCache_) {
gl.deleteTexture(this.textureCache_[url]);
delete this.textureCache_[url];
}
};
/**
* @inheritDoc
*/
ol.renderer.WebGL.prototype.draw = function(layers, center, resolution, animate) {
var gl = this.gl_;
var width = this.canvas_.width;
var height = this.canvas_.height;
var bounds = new ol.Bounds(
center.getX() - width * resolution / 2,
center.getY() - height * resolution / 2,
center.getX() + width * resolution / 2,
center.getY() + height * resolution / 2,
center.getProjection());
/** @type {goog.vec.Mat4.Type} */
var cameraMatrix;
goog.vec.Mat4.makeIdentity(cameraMatrix);
goog.vec.Mat4.scale(cameraMatrix, resolution, resolution, 1);
goog.vec.Mat4.translate(cameraMatrix, -center.getX(), -center.getY(), 0);
/** @type {goog.vec.Mat4.Type} */
var positionToViewportMatrix;
goog.vec.Mat4.makeIdentity(positionToViewportMatrix);
goog.vec.Mat4.scale(positionToViewportMatrix, 1 / width, 1 / height, 1);
goog.vec.Mat4.multMat(positionToViewportMatrix, cameraMatrix, positionToViewportMatrix);
/** @type {goog.vec.Mat4.Type} */
var viewportToPositionMatrix;
var inverted = goog.vec.Mat4.invert(positionToViewportMatrix, viewportToPositionMatrix);
goog.asserts.assert(inverted);
/** @type {goog.vec.Mat4.Type} */
var targetPixelToPositionMatrix;
goog.vec.Mat4.makeIdentity(targetPixelToPositionMatrix);
goog.vec.Mat4.translate(targetPixelToPositionMatrix, -1, 1, 0);
goog.vec.Mat4.scale(targetPixelToPositionMatrix, 2 / width, -2 / height, 1);
goog.vec.Mat4.multMat(viewportToPositionMatrix, targetPixelToPositionMatrix, targetPixelToPositionMatrix);
gl.clear(goog.webgl.COLOR_BUFFER_BIT);
gl.bindBuffer(goog.webgl.ARRAY_BUFFER, this.positionBuffer_);
gl.uniform1i(this.textureLocation_, 0);
gl.uniformMatrix4fv(this.positionLocation_, false, positionToViewportMatrix);
goog.array.forEach(layers, function(layer) {
if (!(layer instanceof ol.layer.TileLayer)) {
return;
}
var tileLayer = /** @type {ol.layer.TileLayer} */ (layer);
var tileSet = layer.getData(bounds, resolution);
var tiles = tileSet.getTiles();
var i, j, row, tile, tileBounds, positions, texture;
for (i = 0; i < tiles.length; ++i) {
row = tiles[i];
for (j = 0; j < row.length; ++j) {
tile = row[j];
if (!tile.isLoaded()) {
if (!tile.isLoading()) {
goog.events.listen(tile, 'load', this.handleTileLoad,
undefined, this);
goog.events.listen(tile, 'destroy', this.handleTileDestroy,
undefined, this);
tile.load();
}
continue;
}
tileBounds = tile.getBounds();
positions = [
tileBounds.getMinX(), tileBounds.getMinY(),
tileBounds.getMaxX(), tileBounds.getMinY(),
tileBounds.getMinX(), tileBounds.getMaxY(),
tileBounds.getMaxX(), tileBounds.getMaxY()
];
gl.bufferData(goog.webgl.ARRAY_BUFFER, new Float32Array(positions), goog.webgl.DYNAMIC_DRAW);
gl.vertexAttribPointer(this.positionLocation_, 2, goog.webgl.FLOAT, false, 0, 0);
this.bindTexture(tile);
gl.drawArrays(goog.webgl.TRIANGLES, 0, 4);
}
}
}, this);
this.renderedLayers_ = layers;
this.renderedCenter_ = center;
this.renderedResolution_ = resolution;
this.renderedAnimate_ = animate;
};
/**
*/
ol.renderer.WebGL.prototype.redraw = function() {
this.draw(this.renderedLayers_, this.renderedCenter_, this.renderedResolution_, this.renderedAnimate_);
};

59
src/ol3/base/array.js Normal file
View File

@@ -0,0 +1,59 @@
goog.provide('ol3.array');
goog.require('goog.array');
/**
* @param {Array.<number>} arr Array.
* @param {number} target Target.
* @return {number} Index.
*/
ol3.array.binaryFindNearest = function(arr, target) {
var index = goog.array.binarySearch(arr, target, function(a, b) {
return b - a;
});
if (index >= 0) {
return index;
} else if (index == -1) {
return 0;
} else if (index == -arr.length - 1) {
return arr.length - 1;
} else {
var left = -index - 2;
var right = -index - 1;
if (arr[left] - target < target - arr[right]) {
return left;
} else {
return right;
}
}
};
/**
* @param {Array.<number>} arr Array.
* @param {number} target Target.
* @return {number} Index.
*/
ol3.array.linearFindNearest = function(arr, target) {
var n = arr.length;
if (arr[0] <= target) {
return 0;
} else if (target <= arr[n - 1]) {
return n - 1;
} else {
var i;
for (i = 1; i < n; ++i) {
if (arr[i] == target) {
return i;
} else if (arr[i] < target) {
if (arr[i - 1] - target < target - arr[i]) {
return i - 1;
} else {
return i;
}
}
}
return n - 1;
}
};

View File

@@ -0,0 +1,46 @@
goog.require('goog.testing.jsunit');
goog.require('ol3.array');
function testBinaryFindNearest() {
var arr = [1000, 500, 100];
assertEquals(0, ol3.array.binaryFindNearest(arr, 10000));
assertEquals(0, ol3.array.binaryFindNearest(arr, 1000));
assertEquals(0, ol3.array.binaryFindNearest(arr, 900));
assertEquals(1, ol3.array.binaryFindNearest(arr, 750));
assertEquals(1, ol3.array.binaryFindNearest(arr, 550));
assertEquals(1, ol3.array.binaryFindNearest(arr, 500));
assertEquals(1, ol3.array.binaryFindNearest(arr, 450));
assertEquals(2, ol3.array.binaryFindNearest(arr, 300));
assertEquals(2, ol3.array.binaryFindNearest(arr, 200));
assertEquals(2, ol3.array.binaryFindNearest(arr, 100));
assertEquals(2, ol3.array.binaryFindNearest(arr, 50));
}
function testLinearFindNearest() {
var arr = [1000, 500, 100];
assertEquals(0, ol3.array.linearFindNearest(arr, 10000));
assertEquals(0, ol3.array.linearFindNearest(arr, 1000));
assertEquals(0, ol3.array.linearFindNearest(arr, 900));
assertEquals(1, ol3.array.linearFindNearest(arr, 750));
assertEquals(1, ol3.array.linearFindNearest(arr, 550));
assertEquals(1, ol3.array.linearFindNearest(arr, 500));
assertEquals(1, ol3.array.linearFindNearest(arr, 450));
assertEquals(2, ol3.array.linearFindNearest(arr, 300));
assertEquals(2, ol3.array.linearFindNearest(arr, 200));
assertEquals(2, ol3.array.linearFindNearest(arr, 100));
assertEquals(2, ol3.array.linearFindNearest(arr, 50));
}

View File

@@ -0,0 +1,58 @@
goog.provide('ol3.Attribution');
goog.require('ol3.CoverageArea');
goog.require('ol3.Projection');
/**
* @constructor
* @param {string} html HTML.
* @param {Array.<ol3.CoverageArea>=} opt_coverageAreas Coverage areas.
* @param {ol3.Projection=} opt_projection Projection.
*/
ol3.Attribution = function(html, opt_coverageAreas, opt_projection) {
/**
* @private
* @type {string}
*/
this.html_ = html;
/**
* @private
* @type {Array.<ol3.CoverageArea>}
*/
this.coverageAreas_ = opt_coverageAreas || null;
/**
* @private
* @type {ol3.Projection}
*/
this.projection_ = opt_projection || null;
};
/**
* @return {Array.<ol3.CoverageArea>} Coverage areas.
*/
ol3.Attribution.prototype.getCoverageAreas = function() {
return this.coverageAreas_;
};
/**
* @return {string} HTML.
*/
ol3.Attribution.prototype.getHtml = function() {
return this.html_;
};
/**
* @return {ol3.Projection} Projection.
*/
ol3.Attribution.prototype.getProjection = function() {
return this.projection_;
};

215
src/ol3/base/collection.js Normal file
View File

@@ -0,0 +1,215 @@
/**
* @fileoverview An implementation of Google Maps' MVCArray.
* @see https://developers.google.com/maps/documentation/javascript/reference
*/
goog.provide('ol3.Collection');
goog.provide('ol3.CollectionEvent');
goog.provide('ol3.CollectionEventType');
goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.events.Event');
goog.require('ol3.Object');
/**
* @enum {string}
*/
ol3.CollectionEventType = {
ADD: 'add',
INSERT_AT: 'insert_at',
REMOVE: 'remove',
REMOVE_AT: 'remove_at',
SET_AT: 'set_at'
};
/**
* @constructor
* @extends {goog.events.Event}
* @param {ol3.CollectionEventType} type Type.
* @param {*=} opt_elem Element.
* @param {number=} opt_index Index.
* @param {*=} opt_prev Value.
* @param {Object=} opt_target Target.
*/
ol3.CollectionEvent =
function(type, opt_elem, opt_index, opt_prev, opt_target) {
goog.base(this, type, opt_target);
/**
* @type {*}
*/
this.elem = opt_elem;
/**
* @type {number|undefined}
*/
this.index = opt_index;
/**
* @type {*}
*/
this.prev = opt_prev;
};
goog.inherits(ol3.CollectionEvent, goog.events.Event);
/**
* @enum {string}
*/
ol3.CollectionProperty = {
LENGTH: 'length'
};
/**
* @constructor
* @extends {ol3.Object}
* @param {Array=} opt_array Array.
*/
ol3.Collection = function(opt_array) {
goog.base(this);
/**
* @private
* @type {Array}
*/
this.array_ = opt_array || [];
this.updateLength_();
};
goog.inherits(ol3.Collection, ol3.Object);
/**
*/
ol3.Collection.prototype.clear = function() {
while (this[ol3.CollectionProperty.LENGTH]) {
this.pop();
}
};
/**
* @param {Function} f Function.
* @param {Object=} opt_obj Object.
*/
ol3.Collection.prototype.forEach = function(f, opt_obj) {
goog.array.forEach(this.array_, f, opt_obj);
};
/**
* @return {Array} Array.
*/
ol3.Collection.prototype.getArray = function() {
return this.array_;
};
/**
* @param {number} index Index.
* @return {*} Element.
*/
ol3.Collection.prototype.getAt = function(index) {
return this.array_[index];
};
/**
* @return {number} Length.
*/
ol3.Collection.prototype.getLength = function() {
return /** @type {number} */ this.get(ol3.CollectionProperty.LENGTH);
};
/**
* @param {number} index Index.
* @param {*} elem Element.
*/
ol3.Collection.prototype.insertAt = function(index, elem) {
goog.array.insertAt(this.array_, elem, index);
this.updateLength_();
this.dispatchEvent(new ol3.CollectionEvent(
ol3.CollectionEventType.ADD, elem, undefined, undefined, this));
this.dispatchEvent(new ol3.CollectionEvent(
ol3.CollectionEventType.INSERT_AT, elem, index, undefined, this));
};
/**
* @return {*} Element.
*/
ol3.Collection.prototype.pop = function() {
return this.removeAt(this.getLength() - 1);
};
/**
* @param {*} elem Element.
* @return {number} Length.
*/
ol3.Collection.prototype.push = function(elem) {
var n = this.array_.length;
this.insertAt(n, elem);
return n;
};
/**
* @param {number} index Index.
* @return {*} Value.
*/
ol3.Collection.prototype.removeAt = function(index) {
var prev = this.array_[index];
goog.array.removeAt(this.array_, index);
this.updateLength_();
this.dispatchEvent(new ol3.CollectionEvent(
ol3.CollectionEventType.REMOVE, prev, undefined, undefined, this));
this.dispatchEvent(new ol3.CollectionEvent(ol3.CollectionEventType.REMOVE_AT,
undefined, index, prev, this));
return prev;
};
/**
* @param {number} index Index.
* @param {*} elem Element.
*/
ol3.Collection.prototype.setAt = function(index, elem) {
var n = this[ol3.CollectionProperty.LENGTH];
if (index < n) {
var prev = this.array_[index];
this.array_[index] = elem;
this.dispatchEvent(new ol3.CollectionEvent(ol3.CollectionEventType.SET_AT,
elem, index, prev, this));
this.dispatchEvent(new ol3.CollectionEvent(ol3.CollectionEventType.REMOVE,
prev, undefined, undefined, this));
this.dispatchEvent(new ol3.CollectionEvent(ol3.CollectionEventType.ADD,
elem, undefined, undefined, this));
} else {
var j;
for (j = n; j < index; ++j) {
this.insertAt(j, undefined);
}
this.insertAt(index, elem);
}
};
/**
* @private
*/
ol3.Collection.prototype.updateLength_ = function() {
this.set(ol3.CollectionProperty.LENGTH, this.array_.length);
};

View File

@@ -0,0 +1,238 @@
goog.require('goog.array');
goog.require('goog.testing.jsunit');
goog.require('ol3.Collection');
goog.require('ol3.CollectionEventType');
function testEmpty() {
var collection = new ol3.Collection();
assertEquals(0, collection.getLength());
assertTrue(goog.array.equals(collection.getArray(), []));
assertUndefined(collection.getAt(0));
}
function testConstruct() {
var array = [0, 1, 2];
var collection = new ol3.Collection(array);
assertEquals(0, collection.getAt(0));
assertEquals(1, collection.getAt(1));
assertEquals(2, collection.getAt(2));
}
function testPush() {
var collection = new ol3.Collection();
collection.push(1);
assertEquals(1, collection.getLength());
assertTrue(goog.array.equals(collection.getArray(), [1]));
assertEquals(1, collection.getAt(0));
}
function testPushPop() {
var collection = new ol3.Collection();
collection.push(1);
collection.pop();
assertEquals(0, collection.getLength());
assertTrue(goog.array.equals(collection.getArray(), []));
assertUndefined(collection.getAt(0));
}
function testInsertAt() {
var collection = new ol3.Collection([0, 2]);
collection.insertAt(1, 1);
assertEquals(0, collection.getAt(0));
assertEquals(1, collection.getAt(1));
assertEquals(2, collection.getAt(2));
}
function testSetAt() {
var collection = new ol3.Collection();
collection.setAt(1, 1);
assertEquals(2, collection.getLength());
assertUndefined(collection.getAt(0));
assertEquals(1, collection.getAt(1));
}
function testRemoveAt() {
var collection = new ol3.Collection([0, 1, 2]);
collection.removeAt(1);
assertEquals(0, collection.getAt(0));
assertEquals(2, collection.getAt(1));
}
function testForEachEmpty() {
var collection = new ol3.Collection();
var forEachCalled = false;
collection.forEach(function() {
forEachCalled = true;
});
assertFalse(forEachCalled);
}
function testForEachPopulated() {
var collection = new ol3.Collection();
collection.push(1);
collection.push(2);
var forEachCount = 0;
collection.forEach(function() {
++forEachCount;
});
assertEquals(2, forEachCount);
}
function testSetAtEvent() {
var collection = new ol3.Collection(['a', 'b']);
var index, prev;
goog.events.listen(collection, ol3.CollectionEventType.SET_AT, function(e) {
index = e.index;
prev = e.prev;
});
collection.setAt(1, 1);
assertEquals(1, index);
assertEquals('b', prev);
}
function testRemoveAtEvent() {
var collection = new ol3.Collection(['a']);
var index, prev;
goog.events.listen(
collection, ol3.CollectionEventType.REMOVE_AT, function(e) {
index = e.index;
prev = e.prev;
});
collection.pop();
assertEquals(0, index);
assertEquals('a', prev);
}
function testInsertAtEvent() {
var collection = new ol3.Collection([0, 2]);
var index;
goog.events.listen(
collection, ol3.CollectionEventType.INSERT_AT, function(e) {
index = e.index;
});
collection.insertAt(1, 1);
assertEquals(1, index);
}
function testSetAtBeyondEnd() {
var collection = new ol3.Collection();
var inserts = [];
goog.events.listen(
collection, ol3.CollectionEventType.INSERT_AT, function(e) {
inserts.push(e.index);
});
collection.setAt(2, 0);
assertEquals(3, collection.getLength());
assertUndefined(collection.getAt(0));
assertUndefined(collection.getAt(1));
assertEquals(0, collection.getAt(2));
assertEquals(3, inserts.length);
assertEquals(0, inserts[0]);
assertEquals(1, inserts[1]);
assertEquals(2, inserts[2]);
}
function testLengthChangeInsertAt() {
var collection = new ol3.Collection([0, 1, 2]);
var lengthEventDispatched;
goog.events.listen(collection, 'length_changed', function() {
lengthEventDispatched = true;
});
collection.insertAt(2, 3);
assertTrue(lengthEventDispatched);
}
function testLengthChangeRemoveAt() {
var collection = new ol3.Collection([0, 1, 2]);
var lengthEventDispatched;
goog.events.listen(collection, 'length_changed', function() {
lengthEventDispatched = true;
});
collection.removeAt(0);
assertTrue(lengthEventDispatched);
}
function testLengthChangeSetAt() {
var collection = new ol3.Collection([0, 1, 2]);
var lengthEventDispatched;
goog.events.listen(collection, 'length_changed', function() {
lengthEventDispatched = true;
});
collection.setAt(1, 1);
assertUndefined(lengthEventDispatched);
}
function testForEach() {
var collection = new ol3.Collection([1, 2, 4]);
var sum = 0;
collection.forEach(function(elem) {
sum += elem;
});
assertEquals(7, sum);
}
function testForEachScope() {
var collection = new ol3.Collection([0]);
var that;
var uniqueObj = {};
collection.forEach(function(elem) {
that = this;
}, uniqueObj);
assertTrue(that === uniqueObj);
}
function testAddEvent() {
var collection = new ol3.Collection();
var elem;
goog.events.listen(collection, ol3.CollectionEventType.ADD, function(e) {
elem = e.elem;
});
collection.push(1);
assertEquals(1, elem);
}
function testAddRemoveEvent() {
var collection = new ol3.Collection([1]);
var addedElem;
goog.events.listen(collection, ol3.CollectionEventType.ADD, function(e) {
addedElem = e.elem;
});
var removedElem;
goog.events.listen(collection, ol3.CollectionEventType.REMOVE, function(e) {
removedElem = e.elem;
});
collection.setAt(0, 2);
assertEquals(1, removedElem);
assertEquals(2, addedElem);
}
function testRemove() {
var collection = new ol3.Collection([1]);
var elem;
goog.events.listen(collection, ol3.CollectionEventType.REMOVE, function(e) {
elem = e.elem;
});
collection.pop();
assertEquals(1, elem);
}

56
src/ol3/base/color.js Normal file
View File

@@ -0,0 +1,56 @@
goog.provide('ol3.Color');
goog.require('goog.color');
/**
* @constructor
* @param {number} r Red.
* @param {number} g Green.
* @param {number} b Blue.
* @param {number} a Alpha.
*/
ol3.Color = function(r, g, b, a) {
/**
* @type {number}
*/
this.r = r;
/**
* @type {number}
*/
this.g = g;
/**
* @type {number}
*/
this.b = b;
/**
* @type {number}
*/
this.a = a;
};
/**
* @param {string} str String.
* @param {number=} opt_a Alpha.
* @return {ol3.Color} Color.
*/
ol3.Color.createFromString = function(str, opt_a) {
var rgb = goog.color.hexToRgb(goog.color.parse(str).hex);
var a = opt_a || 255;
return new ol3.Color(rgb[0], rgb[1], rgb[2], a);
};
/**
* @return {ol3.Color} Clone.
*/
ol3.Color.prototype.clone = function() {
return new ol3.Color(this.r, this.g, this.b, this.a);
};

View File

@@ -0,0 +1,31 @@
goog.provide('ol3.Coordinate');
goog.require('goog.math.Vec2');
/**
* @constructor
* @extends {goog.math.Vec2}
* @param {number} x X.
* @param {number} y Y.
*/
ol3.Coordinate = function(x, y) {
goog.base(this, x, y);
};
goog.inherits(ol3.Coordinate, goog.math.Vec2);
/**
* @const
* @type {ol3.Coordinate}
*/
ol3.Coordinate.ZERO = new ol3.Coordinate(0, 0);
/**
* @return {ol3.Coordinate} Clone.
*/
ol3.Coordinate.prototype.clone = function() {
return new ol3.Coordinate(this.x, this.y);
};

View File

@@ -0,0 +1,57 @@
goog.provide('ol3.CoordinateFormat');
goog.provide('ol3.CoordinateFormatType');
goog.require('goog.math');
goog.require('ol3.Coordinate');
/**
* @typedef {function((ol3.Coordinate|undefined)): string}
*/
ol3.CoordinateFormatType;
/**
* @param {number} precision Precision.
* @return {ol3.CoordinateFormatType} Coordinate format.
*/
ol3.CoordinateFormat.createXY = function(precision) {
return function(coordinate) {
if (goog.isDef(coordinate)) {
return coordinate.x.toFixed(precision) + ', ' +
coordinate.y.toFixed(precision);
} else {
return '';
}
};
};
/**
* @private
* @param {number} degrees Degrees.
* @param {string} hemispheres Hemispheres.
* @return {string} String.
*/
ol3.CoordinateFormat.degreesToHDMS_ = function(degrees, hemispheres) {
var normalizedDegrees = goog.math.modulo(degrees + 180, 360) - 180;
var x = Math.abs(Math.round(3600 * normalizedDegrees));
return Math.floor(x / 3600) + '\u00b0 ' +
Math.floor((x / 60) % 60) + '\u2032 ' +
Math.floor(x % 60) + '\u2033 ' +
hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0);
};
/**
* @param {ol3.Coordinate|undefined} coordinate Coordinate.
* @return {string} Coordinate format.
*/
ol3.CoordinateFormat.hdms = function(coordinate) {
if (goog.isDef(coordinate)) {
return ol3.CoordinateFormat.degreesToHDMS_(coordinate.y, 'NS') + ' ' +
ol3.CoordinateFormat.degreesToHDMS_(coordinate.x, 'EW');
} else {
return '';
}
};

View File

@@ -0,0 +1,45 @@
goog.provide('ol3.CoverageArea');
goog.require('ol3.Extent');
/**
* @constructor
* @param {ol3.Extent} extent Extent.
*/
ol3.CoverageArea = function(extent) {
/**
* @type {ol3.Extent}
*/
this.extent = extent;
};
/**
* @param {ol3.Extent} extent Extent.
* @return {boolean} Intersects.
*/
ol3.CoverageArea.prototype.intersectsExtent = function(extent) {
return this.extent.intersects(extent);
};
/**
* @param {ol3.Extent} extent Extent.
* @param {number} resolution Resolution.
* @return {boolean} Intersects.
*/
ol3.CoverageArea.prototype.intersectsExtentAndResolution = goog.abstractMethod;
/**
* @param {ol3.TransformFunction} transformFn Transform.
* @return {ol3.CoverageArea} Transformed coverage area.
*/
ol3.CoverageArea.prototype.transform = function(transformFn) {
var extent = this.extent.transform(transformFn);
return new ol3.CoverageArea(extent);
};

153
src/ol3/base/createmap.js Normal file
View File

@@ -0,0 +1,153 @@
goog.provide('ol3.RendererHint');
goog.provide('ol3.createMap');
goog.require('goog.object');
goog.require('ol3.Collection');
goog.require('ol3.Map');
goog.require('ol3.MapProperty');
goog.require('ol3.Projection');
goog.require('ol3.dom');
goog.require('ol3.dom.MapRenderer');
goog.require('ol3.interaction.AltDragRotate');
goog.require('ol3.interaction.CenterConstraint');
goog.require('ol3.interaction.Constraints');
goog.require('ol3.interaction.DblClickZoom');
goog.require('ol3.interaction.DragPan');
goog.require('ol3.interaction.KeyboardPan');
goog.require('ol3.interaction.KeyboardZoom');
goog.require('ol3.interaction.MouseWheelZoom');
goog.require('ol3.interaction.ResolutionConstraint');
goog.require('ol3.interaction.RotationConstraint');
goog.require('ol3.interaction.ShiftDragZoom');
goog.require('ol3.webgl');
goog.require('ol3.webgl.MapRenderer');
/**
* @define {string} Default projection code.
*/
ol3.DEFAULT_PROJECTION_CODE = 'EPSG:3857';
/**
* @define {string} Default user projection code.
*/
ol3.DEFAULT_USER_PROJECTION_CODE = 'EPSG:4326';
/**
* @define {boolean} Whether to enable DOM.
*/
ol3.ENABLE_DOM = true;
/**
* @define {boolean} Whether to enable WebGL.
*/
ol3.ENABLE_WEBGL = true;
/**
* @enum {string}
*/
ol3.RendererHint = {
DOM: 'dom',
WEBGL: 'webgl'
};
/**
* @type {Array.<ol3.RendererHint>}
*/
ol3.DEFAULT_RENDERER_HINT = [
ol3.RendererHint.WEBGL,
ol3.RendererHint.DOM
];
/**
* @param {Element} target Target.
* @param {Object.<string, *>=} opt_values Values.
* @param {ol3.RendererHint|Array.<ol3.RendererHint>=} opt_rendererHints
* Renderer hints.
* @return {ol3.Map} Map.
*/
ol3.createMap = function(target, opt_values, opt_rendererHints) {
var values = {};
if (goog.isDef(opt_values)) {
goog.object.extend(values, opt_values);
}
// FIXME this should be a configuration option
var centerConstraint = ol3.interaction.CenterConstraint.snapToPixel;
var resolutionConstraint =
ol3.interaction.ResolutionConstraint.createSnapToPower(
Math.exp(Math.log(2) / 8), ol3.Projection.EPSG_3857_HALF_SIZE / 128);
var rotationConstraint = ol3.interaction.RotationConstraint.none;
var constraints = new ol3.interaction.Constraints(
centerConstraint, resolutionConstraint, rotationConstraint);
if (!goog.object.containsKey(values, ol3.MapProperty.INTERACTIONS)) {
var interactions = new ol3.Collection();
interactions.push(new ol3.interaction.AltDragRotate(constraints));
interactions.push(new ol3.interaction.DblClickZoom(constraints));
interactions.push(new ol3.interaction.DragPan(constraints));
interactions.push(new ol3.interaction.KeyboardPan(constraints, 16));
interactions.push(new ol3.interaction.KeyboardZoom(constraints));
interactions.push(new ol3.interaction.MouseWheelZoom(constraints));
interactions.push(new ol3.interaction.ShiftDragZoom(constraints));
values[ol3.MapProperty.INTERACTIONS] = interactions;
}
if (!goog.object.containsKey(values, ol3.MapProperty.LAYERS)) {
values[ol3.MapProperty.LAYERS] = new ol3.Collection();
}
if (!goog.object.containsKey(values, ol3.MapProperty.PROJECTION)) {
values[ol3.MapProperty.PROJECTION] =
ol3.Projection.getFromCode(ol3.DEFAULT_PROJECTION_CODE);
}
if (!goog.object.containsKey(values, ol3.MapProperty.USER_PROJECTION)) {
values[ol3.MapProperty.USER_PROJECTION] =
ol3.Projection.getFromCode(ol3.DEFAULT_USER_PROJECTION_CODE);
}
/**
* @type {Array.<ol3.RendererHint>}
*/
var rendererHints;
if (goog.isDef(opt_rendererHints)) {
if (goog.isArray(opt_rendererHints)) {
rendererHints = opt_rendererHints;
} else {
rendererHints = [opt_rendererHints];
}
} else {
rendererHints = ol3.DEFAULT_RENDERER_HINT;
}
var i, rendererHint, rendererConstructor;
for (i = 0; i < rendererHints.length; ++i) {
rendererHint = rendererHints[i];
if (rendererHint == ol3.RendererHint.DOM) {
if (ol3.ENABLE_DOM && ol3.dom.isSupported()) {
rendererConstructor = ol3.dom.MapRenderer;
break;
}
} else if (rendererHint == ol3.RendererHint.WEBGL) {
if (ol3.ENABLE_WEBGL && ol3.webgl.isSupported()) {
rendererConstructor = ol3.webgl.MapRenderer;
break;
}
}
}
if (goog.isDef(rendererConstructor)) {
return new ol3.Map(target, rendererConstructor, values);
} else {
return null;
}
};

59
src/ol3/base/extent.js Normal file
View File

@@ -0,0 +1,59 @@
goog.provide('ol3.Extent');
goog.require('ol3.Coordinate');
goog.require('ol3.Rectangle');
goog.require('ol3.TransformFunction');
/**
* @constructor
* @extends {ol3.Rectangle}
* @param {number} minX Minimum X.
* @param {number} minY Minimum Y.
* @param {number} maxX Maximum X.
* @param {number} maxY Maximum Y.
*/
ol3.Extent = function(minX, minY, maxX, maxY) {
goog.base(this, minX, minY, maxX, maxY);
};
goog.inherits(ol3.Extent, ol3.Rectangle);
/**
* @param {...ol3.Coordinate} var_args Coordinates.
* @return {!ol3.Extent} Bounding extent.
*/
ol3.Extent.boundingExtent = function(var_args) {
var coordinate0 = arguments[0];
var extent = new ol3.Extent(coordinate0.x, coordinate0.y,
coordinate0.x, coordinate0.y);
var i;
for (i = 1; i < arguments.length; ++i) {
var coordinate = arguments[i];
extent.minX = Math.min(extent.minX, coordinate.x);
extent.minY = Math.min(extent.minY, coordinate.y);
extent.maxX = Math.max(extent.maxX, coordinate.x);
extent.maxY = Math.max(extent.maxY, coordinate.y);
}
return extent;
};
/**
* @return {ol3.Extent} Extent.
*/
ol3.Extent.prototype.clone = function() {
return new ol3.Extent(this.minX, this.minY, this.maxX, this.maxY);
};
/**
* @param {ol3.TransformFunction} transformFn Transform function.
* @return {ol3.Extent} Extent.
*/
ol3.Extent.prototype.transform = function(transformFn) {
var min = transformFn(new ol3.Coordinate(this.minX, this.minY));
var max = transformFn(new ol3.Coordinate(this.maxX, this.maxY));
return new ol3.Extent(min.x, min.y, max.x, max.y);
};

View File

@@ -0,0 +1,29 @@
goog.require('goog.testing.jsunit');
goog.require('ol3.Extent');
goog.require('ol3.Projection');
function testClone() {
var extent = new ol3.Extent(1, 2, 3, 4);
var clonedExtent = extent.clone();
assertTrue(clonedExtent instanceof ol3.Extent);
assertFalse(clonedExtent === extent);
assertEquals(extent.minX, clonedExtent.minX);
assertEquals(extent.minY, clonedExtent.minY);
assertEquals(extent.maxX, clonedExtent.maxX);
assertEquals(extent.maxY, clonedExtent.maxY);
}
function testTransform() {
var transformFn =
ol3.Projection.getTransformFromCodes('EPSG:4326', 'EPSG:3857');
var sourceExtent = new ol3.Extent(-15, -30, 45, 60);
var destinationExtent = sourceExtent.transform(transformFn);
assertNotNullNorUndefined(destinationExtent);
// FIXME check values with third-party tool
assertRoughlyEquals(-1669792.3618991037, destinationExtent.minX, 1e-9);
assertRoughlyEquals(-3503549.843504376, destinationExtent.minY, 1e-9);
assertRoughlyEquals(5009377.085697311, destinationExtent.maxX, 1e-9);
assertRoughlyEquals(8399737.889818361, destinationExtent.maxY, 1e-9);
}

228
src/ol3/base/layer.js Normal file
View File

@@ -0,0 +1,228 @@
goog.provide('ol3.Layer');
goog.provide('ol3.LayerProperty');
goog.require('goog.math');
goog.require('ol3.Object');
goog.require('ol3.Store');
/**
* @enum {string}
*/
ol3.LayerProperty = {
BRIGHTNESS: 'brightness',
CONTRAST: 'contrast',
HUE: 'hue',
OPACITY: 'opacity',
SATURATION: 'saturation',
VISIBLE: 'visible'
};
/**
* @constructor
* @extends {ol3.Object}
* @param {ol3.Store} store Store.
* @param {Object.<string, *>=} opt_values Values.
*/
ol3.Layer = function(store, opt_values) {
goog.base(this);
/**
* @private
* @type {ol3.Store}
*/
this.store_ = store;
this.setBrightness(0);
this.setContrast(0);
this.setHue(0);
this.setOpacity(1);
this.setSaturation(0);
this.setVisible(true);
if (goog.isDef(opt_values)) {
this.setValues(opt_values);
}
};
goog.inherits(ol3.Layer, ol3.Object);
/**
* @return {number} Brightness.
*/
ol3.Layer.prototype.getBrightness = function() {
return /** @type {number} */ this.get(ol3.LayerProperty.BRIGHTNESS);
};
goog.exportProperty(
ol3.Layer.prototype,
'getBrightness',
ol3.Layer.prototype.getBrightness);
/**
* @return {number} Contrast.
*/
ol3.Layer.prototype.getContrast = function() {
return /** @type {number} */ this.get(ol3.LayerProperty.CONTRAST);
};
goog.exportProperty(
ol3.Layer.prototype,
'getContrast',
ol3.Layer.prototype.getContrast);
/**
* @return {number} Hue.
*/
ol3.Layer.prototype.getHue = function() {
return /** @type {number} */ this.get(ol3.LayerProperty.HUE);
};
goog.exportProperty(
ol3.Layer.prototype,
'getHue',
ol3.Layer.prototype.getHue);
/**
* @return {number} Opacity.
*/
ol3.Layer.prototype.getOpacity = function() {
return /** @type {number} */ this.get(ol3.LayerProperty.OPACITY);
};
goog.exportProperty(
ol3.Layer.prototype,
'getOpacity',
ol3.Layer.prototype.getOpacity);
/**
* @return {number} Saturation.
*/
ol3.Layer.prototype.getSaturation = function() {
return /** @type {number} */ this.get(ol3.LayerProperty.SATURATION);
};
goog.exportProperty(
ol3.Layer.prototype,
'getSaturation',
ol3.Layer.prototype.getSaturation);
/**
* @return {ol3.Store} Store.
*/
ol3.Layer.prototype.getStore = function() {
return this.store_;
};
/**
* @return {boolean} Visible.
*/
ol3.Layer.prototype.getVisible = function() {
return /** @type {boolean} */ this.get(ol3.LayerProperty.VISIBLE);
};
goog.exportProperty(
ol3.Layer.prototype,
'getVisible',
ol3.Layer.prototype.getVisible);
/**
* @return {boolean} Is ready.
*/
ol3.Layer.prototype.isReady = function() {
return this.getStore().isReady();
};
/**
* @param {number} brightness Brightness.
*/
ol3.Layer.prototype.setBrightness = function(brightness) {
brightness = goog.math.clamp(brightness, -1, 1);
if (brightness != this.getBrightness()) {
this.set(ol3.LayerProperty.BRIGHTNESS, brightness);
}
};
goog.exportProperty(
ol3.Layer.prototype,
'setBrightness',
ol3.Layer.prototype.setBrightness);
/**
* @param {number} contrast Contrast.
*/
ol3.Layer.prototype.setContrast = function(contrast) {
contrast = goog.math.clamp(contrast, -1, 1);
if (contrast != this.getContrast()) {
this.set(ol3.LayerProperty.CONTRAST, contrast);
}
};
goog.exportProperty(
ol3.Layer.prototype,
'setContrast',
ol3.Layer.prototype.setContrast);
/**
* @param {number} hue Hue.
*/
ol3.Layer.prototype.setHue = function(hue) {
if (hue != this.getHue()) {
this.set(ol3.LayerProperty.HUE, hue);
}
};
goog.exportProperty(
ol3.Layer.prototype,
'setHue',
ol3.Layer.prototype.setHue);
/**
* @param {number} opacity Opacity.
*/
ol3.Layer.prototype.setOpacity = function(opacity) {
opacity = goog.math.clamp(opacity, 0, 1);
if (opacity != this.getOpacity()) {
this.set(ol3.LayerProperty.OPACITY, opacity);
}
};
goog.exportProperty(
ol3.Layer.prototype,
'setOpacity',
ol3.Layer.prototype.setOpacity);
/**
* @param {number} saturation Saturation.
*/
ol3.Layer.prototype.setSaturation = function(saturation) {
saturation = goog.math.clamp(saturation, -1, 1);
if (saturation != this.getSaturation()) {
this.set(ol3.LayerProperty.SATURATION, saturation);
}
};
goog.exportProperty(
ol3.Layer.prototype,
'setSaturation',
ol3.Layer.prototype.setSaturation);
/**
* @param {boolean} visible Visible.
*/
ol3.Layer.prototype.setVisible = function(visible) {
visible = !!visible;
if (visible != this.getVisible()) {
this.set(ol3.LayerProperty.VISIBLE, visible);
}
};
goog.exportProperty(
ol3.Layer.prototype,
'setVisible',
ol3.Layer.prototype.setVisible);

View File

@@ -0,0 +1,127 @@
goog.provide('ol3.LayerRenderer');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('ol3.Layer');
goog.require('ol3.LayerProperty');
goog.require('ol3.Object');
/**
* @constructor
* @extends {ol3.Object}
* @param {ol3.MapRenderer} mapRenderer Map renderer.
* @param {ol3.Layer} layer Layer.
*/
ol3.LayerRenderer = function(mapRenderer, layer) {
goog.base(this);
/**
* @private
* @type {ol3.MapRenderer}
*/
this.mapRenderer_ = mapRenderer;
/**
* @private
* @type {ol3.Layer}
*/
this.layer_ = layer;
goog.events.listen(this.layer_,
ol3.Object.getChangedEventType(ol3.LayerProperty.BRIGHTNESS),
this.handleLayerBrightnessChange, false, this);
goog.events.listen(this.layer_,
ol3.Object.getChangedEventType(ol3.LayerProperty.CONTRAST),
this.handleLayerContrastChange, false, this);
goog.events.listen(this.layer_,
ol3.Object.getChangedEventType(ol3.LayerProperty.HUE),
this.handleLayerHueChange, false, this);
goog.events.listen(this.layer_, goog.events.EventType.LOAD,
this.handleLayerLoad, false, this);
goog.events.listen(this.layer_,
ol3.Object.getChangedEventType(ol3.LayerProperty.OPACITY),
this.handleLayerOpacityChange, false, this);
goog.events.listen(this.layer_,
ol3.Object.getChangedEventType(ol3.LayerProperty.SATURATION),
this.handleLayerSaturationChange, false, this);
goog.events.listen(this.layer_,
ol3.Object.getChangedEventType(ol3.LayerProperty.VISIBLE),
this.handleLayerVisibleChange, false, this);
};
goog.inherits(ol3.LayerRenderer, ol3.Object);
/**
* @return {ol3.Layer} Layer.
*/
ol3.LayerRenderer.prototype.getLayer = function() {
return this.layer_;
};
/**
* @return {ol3.Map} Map.
*/
ol3.LayerRenderer.prototype.getMap = function() {
return this.mapRenderer_.getMap();
};
/**
* @return {ol3.MapRenderer} Map renderer.
*/
ol3.LayerRenderer.prototype.getMapRenderer = function() {
return this.mapRenderer_;
};
/**
* @protected
*/
ol3.LayerRenderer.prototype.handleLayerBrightnessChange = goog.nullFunction;
/**
* @protected
*/
ol3.LayerRenderer.prototype.handleLayerContrastChange = goog.nullFunction;
/**
* @protected
*/
ol3.LayerRenderer.prototype.handleLayerHueChange = goog.nullFunction;
/**
* @protected
*/
ol3.LayerRenderer.prototype.handleLayerLoad = goog.nullFunction;
/**
* @protected
*/
ol3.LayerRenderer.prototype.handleLayerOpacityChange = goog.nullFunction;
/**
* @protected
*/
ol3.LayerRenderer.prototype.handleLayerSaturationChange = goog.nullFunction;
/**
* @protected
*/
ol3.LayerRenderer.prototype.handleLayerVisibleChange = goog.nullFunction;

803
src/ol3/base/map.js Normal file
View File

@@ -0,0 +1,803 @@
// FIXME better map browser event types
// FIXME recheck layer/map projection compatability when projection changes
// FIXME layer renderers should skip when they can't reproject
// FIXME add tilt and height?
goog.provide('ol3.Map');
goog.provide('ol3.MapEventType');
goog.provide('ol3.MapProperty');
goog.require('goog.array');
goog.require('goog.debug.Logger');
goog.require('goog.dispose');
goog.require('goog.dom');
goog.require('goog.dom.ViewportSizeMonitor');
goog.require('goog.events');
goog.require('goog.events.BrowserEvent');
goog.require('goog.events.Event');
goog.require('goog.events.EventType');
goog.require('goog.events.KeyHandler');
goog.require('goog.events.KeyHandler.EventType');
goog.require('goog.events.MouseWheelEvent');
goog.require('goog.events.MouseWheelHandler');
goog.require('goog.events.MouseWheelHandler.EventType');
goog.require('goog.functions');
goog.require('goog.fx.DragEvent');
goog.require('goog.fx.Dragger');
goog.require('goog.fx.anim');
goog.require('goog.fx.anim.Animated');
goog.require('goog.object');
goog.require('ol3.Collection');
goog.require('ol3.Color');
goog.require('ol3.Coordinate');
goog.require('ol3.Extent');
goog.require('ol3.Interaction');
goog.require('ol3.LayerRenderer');
goog.require('ol3.MapBrowserEvent');
goog.require('ol3.Object');
goog.require('ol3.Pixel');
goog.require('ol3.Projection');
goog.require('ol3.Size');
goog.require('ol3.TransformFunction');
/**
* @enum {string}
*/
ol3.MapEventType = {
POST_RENDER: 'postrender'
};
/**
* @enum {string}
*/
ol3.MapProperty = {
BACKGROUND_COLOR: 'backgroundColor',
CENTER: 'center',
INTERACTIONS: 'interactions',
LAYERS: 'layers',
PROJECTION: 'projection',
RESOLUTION: 'resolution',
ROTATION: 'rotation',
SIZE: 'size',
USER_PROJECTION: 'userProjection'
};
/**
* @enum {number}
*/
ol3.MapPaneZIndex = {
VIEWPORT: 1000
};
/**
* @constructor
* @extends {ol3.Object}
* @implements {goog.fx.anim.Animated}
* @param {Element} container Container.
* @param {function(new: ol3.MapRenderer, Element, ol3.Map)} rendererConstructor
* Renderer constructor.
* @param {Object=} opt_values Values.
* @param {goog.dom.ViewportSizeMonitor=} opt_viewportSizeMonitor
* Viewport size monitor.
*/
ol3.Map = function(
container, rendererConstructor, opt_values, opt_viewportSizeMonitor) {
goog.base(this);
if (goog.DEBUG) {
/**
* @protected
* @type {goog.debug.Logger}
*/
this.logger = goog.debug.Logger.getLogger('ol3.map.' + goog.getUid(this));
}
/**
* @type {ol3.TransformFunction}
* @private
*/
this.userToMapTransform_ = ol3.Projection.identityTransform;
/**
* @type {ol3.TransformFunction}
* @private
*/
this.mapToUserTransform_ = ol3.Projection.cloneTransform;
/**
* @private
* @type {boolean}
*/
this.animatedRenderer_ = false;
/**
* @private
* @type {number}
*/
this.animatingCount_ = 0;
/**
* @private
* @type {number}
*/
this.freezeRenderingCount_ = 0;
/**
* @private
* @type {boolean}
*/
this.dirty_ = false;
/**
* @private
* @type {Element}
*/
this.container_ = container;
/**
* @private
* @type {Element}
*/
this.viewport_ = goog.dom.createElement(goog.dom.TagName.DIV);
this.viewport_.className = 'ol-viewport';
this.viewport_.style.position = 'relative';
this.viewport_.style.overflow = 'hidden';
this.viewport_.style.width = '100%';
this.viewport_.style.height = '100%';
this.viewport_.style.zIndex = ol3.MapPaneZIndex.VIEWPORT;
goog.dom.appendChild(container, this.viewport_);
goog.events.listen(this.viewport_, [
goog.events.EventType.DBLCLICK
], this.handleBrowserEvent, false, this);
// FIXME we probably shouldn't listen on document...
var keyHandler = new goog.events.KeyHandler(document);
goog.events.listen(keyHandler, goog.events.KeyHandler.EventType.KEY,
this.handleBrowserEvent, false, this);
this.registerDisposable(keyHandler);
var mouseWheelHandler = new goog.events.MouseWheelHandler(this.viewport_);
goog.events.listen(mouseWheelHandler,
goog.events.MouseWheelHandler.EventType.MOUSEWHEEL,
this.handleBrowserEvent, false, this);
this.registerDisposable(mouseWheelHandler);
var dragger = new goog.fx.Dragger(this.viewport_);
dragger.defaultAction = function() {};
goog.events.listen(dragger, [
goog.fx.Dragger.EventType.START,
goog.fx.Dragger.EventType.DRAG,
goog.fx.Dragger.EventType.END
], this.handleDraggerEvent, false, this);
this.registerDisposable(dragger);
/**
* @type {ol3.MapRenderer}
* @private
*/
this.renderer_ = new rendererConstructor(this.viewport_, this);
this.registerDisposable(this.renderer_);
/**
* @private
* @type {goog.dom.ViewportSizeMonitor}
*/
this.viewportSizeMonitor_ =
opt_viewportSizeMonitor || new goog.dom.ViewportSizeMonitor();
goog.events.listen(this.viewportSizeMonitor_, goog.events.EventType.RESIZE,
this.handleBrowserWindowResize, false, this);
goog.events.listen(
this, ol3.Object.getChangedEventType(ol3.MapProperty.PROJECTION),
this.handleProjectionChanged, false, this);
goog.events.listen(
this, ol3.Object.getChangedEventType(ol3.MapProperty.USER_PROJECTION),
this.handleUserProjectionChanged, false, this);
if (goog.isDef(opt_values)) {
this.setValues(opt_values);
}
this.handleBrowserWindowResize();
};
goog.inherits(ol3.Map, ol3.Object);
/**
* @return {boolean} Can rotate.
*/
ol3.Map.prototype.canRotate = function() {
return this.renderer_.canRotate();
};
/**
* @param {ol3.Extent} extent Extent.
*/
ol3.Map.prototype.fitExtent = function(extent) {
this.withFrozenRendering(function() {
this.setCenter(extent.getCenter());
this.setResolution(this.getResolutionForExtent(extent));
if (this.canRotate()) {
this.setRotation(0);
}
}, this);
};
/**
* @param {ol3.Extent} userExtent Extent in user projection.
*/
ol3.Map.prototype.fitUserExtent = function(userExtent) {
this.fitExtent(userExtent.transform(this.userToMapTransform_));
};
/**
*/
ol3.Map.prototype.freezeRendering = function() {
++this.freezeRenderingCount_;
};
/**
* @return {ol3.Color|undefined} Background color.
*/
ol3.Map.prototype.getBackgroundColor = function() {
return /** @type {ol3.Color|undefined} */ (
this.get(ol3.MapProperty.BACKGROUND_COLOR));
};
goog.exportProperty(
ol3.Map.prototype,
'getBackgroundColor',
ol3.Map.prototype.getBackgroundColor);
/**
* @return {ol3.Coordinate|undefined} Center.
*/
ol3.Map.prototype.getCenter = function() {
return /** @type {ol3.Coordinate} */ this.get(ol3.MapProperty.CENTER);
};
goog.exportProperty(
ol3.Map.prototype,
'getCenter',
ol3.Map.prototype.getCenter);
/**
* @return {Element} Container.
*/
ol3.Map.prototype.getContainer = function() {
return this.container_;
};
/**
* @param {ol3.Pixel} pixel Pixel.
* @return {ol3.Coordinate|undefined} Coordinate.
*/
ol3.Map.prototype.getCoordinateFromPixel = function(pixel) {
if (this.isDef()) {
return this.renderer_.getCoordinateFromPixel(pixel);
} else {
return undefined;
}
};
/**
* @return {ol3.Extent|undefined} Extent.
*/
ol3.Map.prototype.getExtent = function() {
if (this.isDef()) {
var center = this.getCenter();
var resolution = this.getResolution();
var size = this.getSize();
var minX = center.x - resolution * size.width / 2;
var minY = center.y - resolution * size.height / 2;
var maxX = center.x + resolution * size.width / 2;
var maxY = center.y + resolution * size.height / 2;
return new ol3.Extent(minX, minY, maxX, maxY);
} else {
return undefined;
}
};
/**
* @return {ol3.Collection} Interactions.
*/
ol3.Map.prototype.getInteractions = function() {
return /** @type {ol3.Collection} */ this.get(ol3.MapProperty.INTERACTIONS);
};
goog.exportProperty(
ol3.Map.prototype,
'getInteractions',
ol3.Map.prototype.getInteractions);
/**
* @return {ol3.Collection} Layers.
*/
ol3.Map.prototype.getLayers = function() {
return /** @type {ol3.Collection} */ (this.get(ol3.MapProperty.LAYERS));
};
/**
* @param {ol3.Coordinate} coordinate Coordinate.
* @return {ol3.Pixel|undefined} Pixel.
*/
ol3.Map.prototype.getPixelFromCoordinate = function(coordinate) {
if (this.isDef()) {
return this.renderer_.getPixelFromCoordinate(coordinate);
} else {
return undefined;
}
};
/**
* @return {ol3.Projection|undefined} Projection.
*/
ol3.Map.prototype.getProjection = function() {
return /** @type {ol3.Projection} */ this.get(ol3.MapProperty.PROJECTION);
};
goog.exportProperty(
ol3.Map.prototype,
'getProjection',
ol3.Map.prototype.getProjection);
/**
* @return {number|undefined} Resolution.
*/
ol3.Map.prototype.getResolution = function() {
return /** @type {number} */ this.get(ol3.MapProperty.RESOLUTION);
};
goog.exportProperty(
ol3.Map.prototype,
'getResolution',
ol3.Map.prototype.getResolution);
/**
* @param {ol3.Extent} extent Extent.
* @return {number|undefined} Resolution.
*/
ol3.Map.prototype.getResolutionForExtent = function(extent) {
var size = this.getSize();
if (goog.isDef(size)) {
var xResolution = (extent.maxX - extent.minX) / size.width;
var yResolution = (extent.maxY - extent.minY) / size.height;
return Math.max(xResolution, yResolution);
} else {
return undefined;
}
};
/**
* @return {ol3.Extent} Rotated extent.
*/
ol3.Map.prototype.getRotatedExtent = function() {
goog.asserts.assert(this.isDef());
var center = /** @type {!ol3.Coordinate} */ this.getCenter();
var resolution = this.getResolution();
var rotation = this.getRotation() || 0;
var size = this.getSize();
var xScale = resolution * size.width / 2;
var yScale = resolution * size.height / 2;
var corners = [
new ol3.Coordinate(-xScale, -yScale),
new ol3.Coordinate(-xScale, yScale),
new ol3.Coordinate(xScale, -yScale),
new ol3.Coordinate(xScale, yScale)
];
goog.array.forEach(corners, function(corner) {
corner.rotate(rotation);
corner.add(center);
});
return ol3.Extent.boundingExtent.apply(null, corners);
};
/**
* @return {number|undefined} Rotation.
*/
ol3.Map.prototype.getRotation = function() {
return /** @type {number|undefined} */ this.get(ol3.MapProperty.ROTATION);
};
goog.exportProperty(
ol3.Map.prototype,
'getRotation',
ol3.Map.prototype.getRotation);
/**
* @return {ol3.Size|undefined} Size.
*/
ol3.Map.prototype.getSize = function() {
return /** @type {ol3.Size|undefined} */ this.get(ol3.MapProperty.SIZE);
};
goog.exportProperty(
ol3.Map.prototype,
'getSize',
ol3.Map.prototype.getSize);
/**
* @return {ol3.Coordinate|undefined} Center in user projection.
*/
ol3.Map.prototype.getUserCenter = function() {
var center = this.getCenter();
if (goog.isDef(center)) {
return this.mapToUserTransform_(center);
} else {
return undefined;
}
};
/**
* @return {ol3.Extent|undefined} Extent in user projection.
*/
ol3.Map.prototype.getUserExtent = function() {
var extent = this.getExtent();
if (goog.isDef(extent)) {
return extent.transform(this.mapToUserTransform_);
} else {
return undefined;
}
};
/**
* @export
* @return {ol3.Projection|undefined} Projection.
*/
ol3.Map.prototype.getUserProjection = function() {
return /** @type {ol3.Projection} */ this.get(
ol3.MapProperty.USER_PROJECTION);
};
goog.exportProperty(
ol3.Map.prototype,
'getUserProjection',
ol3.Map.prototype.getUserProjection);
/**
* @return {Element} Viewport.
*/
ol3.Map.prototype.getViewport = function() {
return this.viewport_;
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @param {string=} opt_type Type.
*/
ol3.Map.prototype.handleBrowserEvent = function(browserEvent, opt_type) {
var type = opt_type || browserEvent.type;
var mapBrowserEvent = new ol3.MapBrowserEvent(type, this, browserEvent);
var interactions = this.getInteractions();
var interactionsArray = /** @type {Array.<ol3.Interaction>} */
interactions.getArray();
goog.array.every(interactionsArray, function(interaction) {
interaction.handleMapBrowserEvent(mapBrowserEvent);
return !mapBrowserEvent.defaultPrevented;
});
};
/**
* @param {goog.fx.DragEvent} dragEvent Drag event.
*/
ol3.Map.prototype.handleDraggerEvent = function(dragEvent) {
var browserEvent = dragEvent.browserEvent;
this.handleBrowserEvent(browserEvent, dragEvent.type);
};
/**
* @protected
*/
ol3.Map.prototype.handleProjectionChanged = function() {
this.recalculateTransforms_();
};
/**
* @protected
*/
ol3.Map.prototype.handleUserProjectionChanged = function() {
this.recalculateTransforms_();
};
/**
* @protected
*/
ol3.Map.prototype.handleBrowserWindowResize = function() {
var size = new ol3.Size(this.container_.clientWidth,
this.container_.clientHeight);
this.setSize(size);
};
/**
* @return {boolean} Is animating.
*/
ol3.Map.prototype.isAnimating = function() {
return this.animatingCount_ > 0;
};
/**
* @return {boolean} Is defined.
*/
ol3.Map.prototype.isDef = function() {
return goog.isDefAndNotNull(this.getCenter()) &&
goog.isDef(this.getResolution()) &&
goog.isDefAndNotNull(this.getSize());
};
/**
* @inheritDoc
*/
ol3.Map.prototype.onAnimationFrame = function() {
if (goog.DEBUG) {
this.logger.info('onAnimationFrame');
}
this.renderFrame_();
};
/**
* @private
*/
ol3.Map.prototype.recalculateTransforms_ = function() {
var projection = this.getProjection();
var userProjection = this.getUserProjection();
if (goog.isDefAndNotNull(projection) &&
goog.isDefAndNotNull(userProjection)) {
this.mapToUserTransform_ = ol3.Projection.getTransform(
projection, userProjection);
this.userToMapTransform_ = ol3.Projection.getTransform(
userProjection, projection);
} else {
this.mapToUserTransform_ = ol3.Projection.cloneTransform;
this.userToMapTransform_ = ol3.Projection.identityTransform;
}
};
/**
*/
ol3.Map.prototype.render = function() {
if (this.animatingCount_ < 1) {
if (this.freezeRenderingCount_ === 0) {
this.renderFrame_();
} else {
this.dirty_ = true;
}
}
};
/**
* @private
*/
ol3.Map.prototype.renderFrame_ = function() {
if (goog.DEBUG) {
this.logger.info('renderFrame_');
}
var animatedRenderer = this.renderer_.render();
this.dirty_ = false;
if (animatedRenderer != this.animatedRenderer_) {
if (animatedRenderer) {
this.startAnimating();
} else {
this.stopAnimating();
}
this.animatedRenderer_ = animatedRenderer;
}
if (goog.DEBUG) {
this.logger.info('postrender');
}
this.dispatchEvent(ol3.MapEventType.POST_RENDER);
};
/**
* @param {ol3.Color} backgroundColor Background color.
*/
ol3.Map.prototype.setBackgroundColor = function(backgroundColor) {
this.set(ol3.MapProperty.BACKGROUND_COLOR, backgroundColor);
};
goog.exportProperty(
ol3.Map.prototype,
'setBackgroundColor',
ol3.Map.prototype.setBackgroundColor);
/**
* @param {ol3.Coordinate|undefined} center Center.
*/
ol3.Map.prototype.setCenter = function(center) {
this.set(ol3.MapProperty.CENTER, center);
};
goog.exportProperty(
ol3.Map.prototype,
'setCenter',
ol3.Map.prototype.setCenter);
/**
* @param {ol3.Collection} interactions Interactions.
*/
ol3.Map.prototype.setInteractions = function(interactions) {
this.set(ol3.MapProperty.INTERACTIONS, interactions);
};
goog.exportProperty(
ol3.Map.prototype,
'setInteractions',
ol3.Map.prototype.setInteractions);
/**
* @export
* @param {ol3.Collection} layers Layers.
*/
ol3.Map.prototype.setLayers = function(layers) {
this.set(ol3.MapProperty.LAYERS, layers);
};
goog.exportProperty(
ol3.Map.prototype,
'setLayers',
ol3.Map.prototype.setLayers);
/**
* @export
* @param {ol3.Projection} projection Projection.
*/
ol3.Map.prototype.setProjection = function(projection) {
this.set(ol3.MapProperty.PROJECTION, projection);
};
goog.exportProperty(
ol3.Map.prototype,
'setProjection',
ol3.Map.prototype.setProjection);
/**
* @export
* @param {number|undefined} resolution Resolution.
*/
ol3.Map.prototype.setResolution = function(resolution) {
this.set(ol3.MapProperty.RESOLUTION, resolution);
};
goog.exportProperty(
ol3.Map.prototype,
'setResolution',
ol3.Map.prototype.setResolution);
/**
* @export
* @param {number|undefined} rotation Rotation.
*/
ol3.Map.prototype.setRotation = function(rotation) {
this.set(ol3.MapProperty.ROTATION, rotation);
};
goog.exportProperty(
ol3.Map.prototype,
'setRotation',
ol3.Map.prototype.setRotation);
/**
* @param {ol3.Size} size Size.
*/
ol3.Map.prototype.setSize = function(size) {
var currentSize = this.getSize();
if (!goog.isDef(currentSize) || !currentSize.equals(size)) {
this.set(ol3.MapProperty.SIZE, size);
}
};
goog.exportProperty(
ol3.Map.prototype,
'setSize',
ol3.Map.prototype.setSize);
/**
* @export
* @param {ol3.Coordinate} userCenter Center in user projection.
*/
ol3.Map.prototype.setUserCenter = function(userCenter) {
this.setCenter(this.userToMapTransform_(userCenter));
};
goog.exportProperty(
ol3.Map.prototype,
'setUserCenter',
ol3.Map.prototype.setUserCenter);
/**
* @export
* @param {ol3.Projection} userProjection User projection.
*/
ol3.Map.prototype.setUserProjection = function(userProjection) {
this.set(ol3.MapProperty.USER_PROJECTION, userProjection);
};
goog.exportProperty(
ol3.Map.prototype,
'setUserProjection',
ol3.Map.prototype.setUserProjection);
/**
*/
ol3.Map.prototype.startAnimating = function() {
if (++this.animatingCount_ == 1) {
if (goog.DEBUG) {
this.logger.info('startAnimating');
}
goog.fx.anim.registerAnimation(this);
}
};
/**
*/
ol3.Map.prototype.stopAnimating = function() {
goog.asserts.assert(this.animatingCount_ > 0);
if (--this.animatingCount_ === 0) {
if (goog.DEBUG) {
this.logger.info('stopAnimating');
}
goog.fx.anim.unregisterAnimation(this);
}
};
/**
*/
ol3.Map.prototype.unfreezeRendering = function() {
goog.asserts.assert(this.freezeRenderingCount_ > 0);
if (--this.freezeRenderingCount_ === 0 &&
this.animatingCount_ < 1 &&
this.dirty_) {
this.renderFrame_();
}
};
/**
* @param {function(this: T)} f Function.
* @param {T=} opt_obj Object.
* @template T
*/
ol3.Map.prototype.withFrozenRendering = function(f, opt_obj) {
this.freezeRendering();
try {
f.call(opt_obj);
} finally {
this.unfreezeRendering();
}
};

View File

@@ -0,0 +1,53 @@
goog.provide('ol3.MapBrowserEvent');
goog.require('goog.events.BrowserEvent');
goog.require('goog.style');
goog.require('ol3.Coordinate');
goog.require('ol3.MapEvent');
goog.require('ol3.Pixel');
/**
* @constructor
* @extends {ol3.MapEvent}
* @param {string} type Event type.
* @param {ol3.Map} map Map.
* @param {goog.events.BrowserEvent} browserEvent Browser event.
*/
ol3.MapBrowserEvent = function(type, map, browserEvent) {
goog.base(this, type, map);
/**
* @type {goog.events.BrowserEvent}
*/
this.browserEvent = browserEvent;
/**
* @private
* @type {ol3.Coordinate|undefined}
*/
this.coordinate_ = undefined;
};
goog.inherits(ol3.MapBrowserEvent, ol3.MapEvent);
/**
* @return {ol3.Coordinate|undefined} Coordinate.
*/
ol3.MapBrowserEvent.prototype.getCoordinate = function() {
if (goog.isDef(this.coordinate_)) {
return this.coordinate_;
} else {
var map = this.map;
var browserEvent = this.browserEvent;
var eventPosition = goog.style.getRelativePosition(
browserEvent, map.getViewport());
var pixel = new ol3.Pixel(eventPosition.x, eventPosition.y);
var coordinate = map.getCoordinateFromPixel(pixel);
this.coordinate_ = coordinate;
return coordinate;
}
};

36
src/ol3/base/mapevent.js Normal file
View File

@@ -0,0 +1,36 @@
goog.provide('ol3.MapEvent');
goog.require('goog.events.Event');
/**
* @constructor
* @extends {goog.events.Event}
* @param {string} type Event type.
* @param {ol3.Map} map Map.
*/
ol3.MapEvent = function(type, map) {
goog.base(this, type);
/**
* @type {ol3.Map}
*/
this.map = map;
/**
* @type {boolean}
*/
this.defaultPrevented = false;
};
goog.inherits(ol3.MapEvent, goog.events.Event);
/**
*/
ol3.MapEvent.prototype.preventDefault = function() {
goog.base(this, 'preventDefault');
this.defaultPrevented = true;
};

376
src/ol3/base/maprenderer.js Normal file
View File

@@ -0,0 +1,376 @@
goog.provide('ol3.MapRenderer');
goog.require('goog.Disposable');
goog.require('goog.events');
goog.require('goog.fx.anim');
goog.require('goog.fx.anim.Animated');
goog.require('goog.vec.Mat4');
goog.require('ol3.Map');
goog.require('ol3.MapProperty');
/**
* @constructor
* @extends {goog.Disposable}
* @param {Element} container Container.
* @param {ol3.Map} map Map.
*/
ol3.MapRenderer = function(container, map) {
goog.base(this);
/**
* @private
* @type {Element}
*/
this.container_ = container;
/**
* @protected
* @type {ol3.Map}
*/
this.map = map;
/**
* @protected
* @type {Object.<number, ol3.LayerRenderer>}
*/
this.layerRenderers = {};
/**
* @private
* @type {Array.<number>}
*/
this.layersListenerKeys_ = null;
/**
* @private
* @type {goog.vec.Mat4.Number}
*/
this.coordinateToPixelMatrix_ = goog.vec.Mat4.createNumber();
/**
* @private
* @type {goog.vec.Mat4.Number}
*/
this.pixelToCoordinateMatrix_ = goog.vec.Mat4.createNumber();
/**
* @private
* @type {boolean}
*/
this.matricesDirty_ = true;
/**
* @private
* @type {Array.<number>}
*/
this.mapListenerKeys_ = [
goog.events.listen(
map, ol3.Object.getChangedEventType(ol3.MapProperty.BACKGROUND_COLOR),
this.handleBackgroundColorChanged, false, this),
goog.events.listen(
map, ol3.Object.getChangedEventType(ol3.MapProperty.CENTER),
this.handleCenterChanged, false, this),
goog.events.listen(
map, ol3.Object.getChangedEventType(ol3.MapProperty.LAYERS),
this.handleLayersChanged, false, this),
goog.events.listen(
map, ol3.Object.getChangedEventType(ol3.MapProperty.RESOLUTION),
this.handleResolutionChanged, false, this),
goog.events.listen(
map, ol3.Object.getChangedEventType(ol3.MapProperty.ROTATION),
this.handleRotationChanged, false, this),
goog.events.listen(
map, ol3.Object.getChangedEventType(ol3.MapProperty.SIZE),
this.handleSizeChanged, false, this)
];
};
goog.inherits(ol3.MapRenderer, goog.Disposable);
/**
* @param {ol3.Layer} layer Layer.
* @protected
*/
ol3.MapRenderer.prototype.addLayer = function(layer) {
var layerRenderer = this.createLayerRenderer(layer);
this.setLayerRenderer(layer, layerRenderer);
};
/**
* @return {boolean} Can rotate.
*/
ol3.MapRenderer.prototype.canRotate = goog.functions.FALSE;
/**
* @param {ol3.Layer} layer Layer.
* @protected
* @return {ol3.LayerRenderer} layerRenderer Layer renderer.
*/
ol3.MapRenderer.prototype.createLayerRenderer = goog.abstractMethod;
/**
* @inheritDoc
*/
ol3.MapRenderer.prototype.disposeInternal = function() {
goog.object.forEach(this.layerRenderers, function(layerRenderer) {
goog.dispose(layerRenderer);
});
goog.array.forEach(this.mapListenerKeys_, goog.events.unlistenByKey);
if (!goog.isNull(this.layersListenerKeys_)) {
goog.array.forEach(this.layersListenerKeys_, goog.events.unlistenByKey);
}
goog.base(this, 'disposeInternal');
};
/**
* @param {function(this: T, ol3.Layer, ol3.LayerRenderer, number)} f Function.
* @param {T=} opt_obj Object.
* @template T
*/
ol3.MapRenderer.prototype.forEachReadyVisibleLayer = function(f, opt_obj) {
var layers = this.map.getLayers();
layers.forEach(function(layer, index) {
if (layer.isReady() && layer.getVisible()) {
var layerRenderer = this.getLayerRenderer(layer);
f.call(opt_obj, layer, layerRenderer, index);
}
}, this);
};
/**
* @param {ol3.Pixel} pixel Pixel.
* @return {ol3.Coordinate} Coordinate.
*/
ol3.MapRenderer.prototype.getCoordinateFromPixel = function(pixel) {
this.updateMatrices_();
var vec3 = [pixel.x, pixel.y, 0];
goog.vec.Mat4.multVec3(this.pixelToCoordinateMatrix_, vec3, vec3);
return new ol3.Coordinate(vec3[0], vec3[1]);
};
/**
* @param {ol3.Layer} layer Layer.
* @protected
* @return {ol3.LayerRenderer} Layer renderer.
*/
ol3.MapRenderer.prototype.getLayerRenderer = function(layer) {
var key = goog.getUid(layer);
var layerRenderer = this.layerRenderers[key];
goog.asserts.assert(goog.isDef(layerRenderer));
return layerRenderer;
};
/**
* @return {ol3.Map} Map.
*/
ol3.MapRenderer.prototype.getMap = function() {
return this.map;
};
/**
* @param {ol3.Coordinate} coordinate Coordinate.
* @return {ol3.Pixel} Pixel.
*/
ol3.MapRenderer.prototype.getPixelFromCoordinate = function(coordinate) {
this.updateMatrices_();
var vec3 = [coordinate.x, coordinate.y, 0];
goog.vec.Mat4.multVec3(this.coordinateToPixelMatrix_, vec3, vec3);
return new ol3.Pixel(vec3[0], vec3[1]);
};
/**
*/
ol3.MapRenderer.prototype.handleBackgroundColorChanged = goog.nullFunction;
/**
* @protected
*/
ol3.MapRenderer.prototype.handleCenterChanged = function() {
this.matricesDirty_ = true;
};
/**
* @param {ol3.CollectionEvent} collectionEvent Collection event.
* @protected
*/
ol3.MapRenderer.prototype.handleLayersAdd = function(collectionEvent) {
var layer = /** @type {ol3.Layer} */ collectionEvent.elem;
this.addLayer(layer);
};
/**
* @protected
*/
ol3.MapRenderer.prototype.handleLayersChanged = function() {
var layerRenderers = goog.object.getValues(this.layerRenderers);
goog.array.forEach(layerRenderers, function(layerRenderer) {
this.removeLayerRenderer(layerRenderer);
}, this);
this.layerRenderers = {};
if (!goog.isNull(this.layersListenerKeys_)) {
goog.array.forEach(this.layersListenerKeys_, goog.events.unlistenByKey);
this.layersListenerKeys_ = null;
}
var layers = this.map.getLayers();
if (goog.isDefAndNotNull(layers)) {
layers.forEach(this.addLayer, this);
this.layersListenerKeys_ = [
goog.events.listen(layers, ol3.CollectionEventType.ADD,
this.handleLayersAdd, false, this),
goog.events.listen(layers, ol3.CollectionEventType.REMOVE,
this.handleLayersRemove, false, this)
];
}
};
/**
* @param {ol3.CollectionEvent} collectionEvent Collection event.
* @protected
*/
ol3.MapRenderer.prototype.handleLayersRemove = function(collectionEvent) {
var layer = /** @type {ol3.Layer} */ collectionEvent.elem;
this.removeLayer(layer);
};
/**
* @protected
*/
ol3.MapRenderer.prototype.handleResolutionChanged = function() {
this.matricesDirty_ = true;
};
/**
* @protected
*/
ol3.MapRenderer.prototype.handleRotationChanged = function() {
this.matricesDirty_ = true;
};
/**
* @protected
*/
ol3.MapRenderer.prototype.handleSizeChanged = function() {
this.matricesDirty_ = true;
};
/**
* @param {ol3.Layer} layer Layer.
* @protected
*/
ol3.MapRenderer.prototype.removeLayer = function(layer) {
goog.dispose(this.removeLayerRenderer(layer));
};
/**
* @param {ol3.Layer} layer Layer.
* @return {ol3.LayerRenderer} Layer renderer.
* @protected
*/
ol3.MapRenderer.prototype.removeLayerRenderer = function(layer) {
var key = goog.getUid(layer);
if (key in this.layerRenderers) {
var layerRenderer = this.layerRenderers[key];
delete this.layerRenderers[key];
return layerRenderer;
} else {
return null;
}
};
/**
* @return {boolean} Animating.
*/
ol3.MapRenderer.prototype.render = function() {
var animate = false;
this.forEachReadyVisibleLayer(function(layer, layerRenderer) {
if (layerRenderer.render()) {
animate = true;
}
});
return animate;
};
/**
* @param {ol3.Layer} layer Layer.
* @param {ol3.LayerRenderer} layerRenderer Layer renderer.
* @protected
*/
ol3.MapRenderer.prototype.setLayerRenderer = function(layer, layerRenderer) {
var key = goog.getUid(layer);
goog.asserts.assert(!(key in this.layerRenderers));
this.layerRenderers[key] = layerRenderer;
};
/**
* @private
*/
ol3.MapRenderer.prototype.updateMatrices_ = function() {
if (this.matricesDirty_) {
var map = this.map;
var center = /** @type {!ol3.Coordinate} */ map.getCenter();
var resolution = /** @type {number} */ map.getResolution();
var rotation = map.getRotation();
var size = /** @type {!ol3.Size} */ map.getSize();
goog.vec.Mat4.makeIdentity(this.coordinateToPixelMatrix_);
goog.vec.Mat4.translate(this.coordinateToPixelMatrix_,
size.width / 2,
size.height / 2,
0);
goog.vec.Mat4.scale(this.coordinateToPixelMatrix_,
1 / resolution,
-1 / resolution,
1);
if (this.canRotate() && goog.isDef(rotation)) {
goog.vec.Mat4.rotate(this.coordinateToPixelMatrix_,
-rotation,
0,
0,
1);
}
goog.vec.Mat4.translate(this.coordinateToPixelMatrix_,
-center.x,
-center.y,
0);
var inverted = goog.vec.Mat4.invert(
this.coordinateToPixelMatrix_, this.pixelToCoordinateMatrix_);
goog.asserts.assert(inverted);
this.matricesDirty_ = false;
}
};

267
src/ol3/base/object.js Normal file
View File

@@ -0,0 +1,267 @@
/**
* @fileoverview An implementation of Google Maps' MVCObject.
* @see https://developers.google.com/maps/articles/mvcfun
* @see https://developers.google.com/maps/documentation/javascript/reference
*/
goog.provide('ol3.Object');
goog.require('goog.array');
goog.require('goog.events');
goog.require('goog.events.EventTarget');
goog.require('goog.object');
/**
* @enum {string}
*/
ol3.ObjectProperty = {
ACCESSORS: 'ol_accessors_',
BINDINGS: 'ol_bindings_'
};
/**
* @constructor
* @extends {goog.events.EventTarget}
* @param {Object.<string, *>=} opt_values Values.
*/
ol3.Object = function(opt_values) {
goog.base(this);
if (goog.isDef(opt_values)) {
this.setValues(opt_values);
}
};
goog.inherits(ol3.Object, goog.events.EventTarget);
/**
* @private
* @type {Object.<string, string>}
*/
ol3.Object.changedEventTypeCache_ = {};
/**
* @private
* @type {Object.<string, string>}
*/
ol3.Object.getterNameCache_ = {};
/**
* @private
* @type {Object.<string, string>}
*/
ol3.Object.setterNameCache_ = {};
/**
* @param {string} str String.
* @return {string} Capitalized string.
*/
ol3.Object.capitalize = function(str) {
return str.substr(0, 1).toUpperCase() + str.substr(1);
};
/**
* @param {ol3.Object} obj Object.
* @return {Object.<string, {target: ol3.Object, key: string}>} Accessors.
*/
ol3.Object.getAccessors = function(obj) {
return obj[ol3.ObjectProperty.ACCESSORS] ||
(obj[ol3.ObjectProperty.ACCESSORS] = {});
};
/**
* @param {string} key Key.
* @return {string} Changed name.
*/
ol3.Object.getChangedEventType = function(key) {
return ol3.Object.changedEventTypeCache_[key] ||
(ol3.Object.changedEventTypeCache_[key] = key.toLowerCase() + '_changed');
};
/**
* @param {string} key String.
* @return {string} Getter name.
*/
ol3.Object.getGetterName = function(key) {
return ol3.Object.getterNameCache_[key] ||
(ol3.Object.getterNameCache_[key] = 'get' + ol3.Object.capitalize(key));
};
/**
* @param {ol3.Object} obj Object.
* @return {Object.<string, ?number>} Listeners.
*/
ol3.Object.getListeners = function(obj) {
return obj[ol3.ObjectProperty.BINDINGS] ||
(obj[ol3.ObjectProperty.BINDINGS] = {});
};
/**
* @param {string} key String.
* @return {string} Setter name.
*/
ol3.Object.getSetterName = function(key) {
return ol3.Object.setterNameCache_[key] ||
(ol3.Object.setterNameCache_[key] = 'set' + ol3.Object.capitalize(key));
};
/**
* @param {string} key Key.
* @param {ol3.Object} target Target.
* @param {string=} opt_targetKey Target key.
* @param {boolean=} opt_noNotify No notify.
*/
ol3.Object.prototype.bindTo =
function(key, target, opt_targetKey, opt_noNotify) {
var targetKey = opt_targetKey || key;
this.unbind(key);
var eventType = ol3.Object.getChangedEventType(targetKey);
var listeners = ol3.Object.getListeners(this);
listeners[key] = goog.events.listen(target, eventType, function() {
this.notifyInternal_(key);
}, undefined, this);
var accessors = ol3.Object.getAccessors(this);
accessors[key] = {target: target, key: targetKey};
var noNotify = opt_noNotify || false;
if (!noNotify) {
this.notifyInternal_(key);
}
};
/**
* @param {string} key Key.
*/
ol3.Object.prototype.changed = goog.nullFunction;
/**
* @param {string} key Key.
* @return {*} Value.
*/
ol3.Object.prototype.get = function(key) {
var accessors = ol3.Object.getAccessors(this);
if (goog.object.containsKey(accessors, key)) {
var accessor = accessors[key];
var target = accessor.target;
var targetKey = accessor.key;
var getterName = ol3.Object.getGetterName(targetKey);
if (target[getterName]) {
return target[getterName]();
} else {
return target.get(targetKey);
}
} else {
return this[key];
}
};
/**
* @param {string} key Key.
*/
ol3.Object.prototype.notify = function(key) {
var accessors = ol3.Object.getAccessors(this);
if (goog.object.containsKey(accessors, key)) {
var accessor = accessors[key];
var target = accessor.target;
var targetKey = accessor.key;
target.notify(targetKey);
} else {
this.notifyInternal_(key);
}
};
/**
* @param {string} key Key.
* @private
*/
ol3.Object.prototype.notifyInternal_ = function(key) {
var eventType = ol3.Object.getChangedEventType(key);
this.dispatchEvent(eventType);
};
/**
* @param {string} key Key.
* @param {*} value Value.
*/
ol3.Object.prototype.set = function(key, value) {
var accessors = ol3.Object.getAccessors(this);
if (goog.object.containsKey(accessors, key)) {
var accessor = accessors[key];
var target = accessor.target;
var targetKey = accessor.key;
var setterName = ol3.Object.getSetterName(targetKey);
if (target[setterName]) {
target[setterName](value);
} else {
target.set(targetKey, value);
}
} else {
this[key] = value;
this.notifyInternal_(key);
}
};
/**
* @param {Object.<string, *>} options Options.
*/
ol3.Object.prototype.setOptions = function(options) {
goog.object.forEach(options, function(value, key) {
var setterName = ol3.Object.getSetterName(key);
if (this[setterName]) {
this[setterName](value);
} else {
this.set(key, value);
}
}, this);
};
/**
* @param {Object.<string, *>} values Values.
*/
ol3.Object.prototype.setValues = ol3.Object.prototype.setOptions;
/**
* @param {string} key Key.
*/
ol3.Object.prototype.unbind = function(key) {
var listeners = ol3.Object.getListeners(this);
var listener = listeners[key];
if (listener) {
delete listeners[key];
goog.events.unlistenByKey(listener);
var value = this.get(key);
var accessors = ol3.Object.getAccessors(this);
delete accessors[key];
this[key] = value;
}
};
/**
*/
ol3.Object.prototype.unbindAll = function() {
var listeners = ol3.Object.getListeners(this);
var keys = goog.object.getKeys(listeners);
goog.array.forEach(keys, function(key) {
this.unbind(key);
}, this);
};

389
src/ol3/base/object_test.js Normal file
View File

@@ -0,0 +1,389 @@
goog.require('goog.testing.jsunit');
goog.require('ol3.Object');
function testModel() {
var m = new ol3.Object();
assertNotNullNorUndefined(m);
}
function testGetUndefined() {
var m = new ol3.Object();
assertUndefined(m.get('k'));
}
function testGetSetGet() {
var m = new ol3.Object();
assertUndefined(m.get('k'));
m.set('k', 1);
assertEquals(1, m.get('k'));
}
function testSetValues() {
var m = new ol3.Object();
m.setValues({
k1: 1,
k2: 2
});
assertEquals(1, m.get('k1'));
assertEquals(2, m.get('k2'));
}
function testNotifyKeyEvent() {
var m = new ol3.Object();
var eventDispatched = false;
goog.events.listen(m, 'k_changed', function() {
eventDispatched = true;
});
m.notify('k');
assertTrue(eventDispatched);
}
function testBindSetNotifyKeyEvent() {
var m = new ol3.Object();
var n = new ol3.Object();
var callbackCalled = false;
goog.events.listen(n, 'k_changed', function() {
eventDispatched = true;
});
n.bindTo('k', m);
m.set('k', 1);
assertTrue(eventDispatched);
}
function testSetNotifyKeyEvent() {
var m = new ol3.Object();
var eventDispatched = false;
goog.events.listen(m, 'k_changed', function() {
eventDispatched = true;
});
m.set('k', 1);
assertTrue(eventDispatched);
}
function testSetBind() {
var m = new ol3.Object();
var n = new ol3.Object();
m.set('k', 1);
assertEquals(1, m.get('k'));
assertUndefined(n.get('k'));
n.bindTo('k', m);
assertEquals(1, m.get('k'));
assertEquals(1, n.get('k'));
}
function testBindSet() {
var m = new ol3.Object();
var n = new ol3.Object();
n.bindTo('k', m);
m.set('k', 1);
assertEquals(1, m.get('k'));
assertEquals(1, n.get('k'));
}
function testBindSetBackwards() {
var m = new ol3.Object();
var n = new ol3.Object();
n.bindTo('k', m);
n.set('k', 1);
assertEquals(1, m.get('k'));
assertEquals(1, n.get('k'));
}
function testSetBindBackwards() {
var m = new ol3.Object();
var n = new ol3.Object();
n.set('k', 1);
n.bindTo('k', m);
assertUndefined(m.get('k'));
assertUndefined(n.get('k'));
}
function testBindSetUnbind() {
var m = new ol3.Object();
var n = new ol3.Object();
n.bindTo('k', m);
n.set('k', 1);
assertEquals(1, m.get('k'));
assertEquals(1, n.get('k'));
n.unbind('k');
assertEquals(1, m.get('k'));
assertEquals(1, n.get('k'));
n.set('k', 2);
assertEquals(1, m.get('k'));
assertEquals(2, n.get('k'));
}
function testUnbindAll() {
var m = new ol3.Object();
var n = new ol3.Object();
n.bindTo('k', m);
n.set('k', 1);
assertEquals(m.get('k'), 1);
assertEquals(n.get('k'), 1);
n.unbindAll();
assertEquals(m.get('k'), 1);
assertEquals(n.get('k'), 1);
n.set('k', 2);
assertEquals(m.get('k'), 1);
assertEquals(n.get('k'), 2);
}
function testBindNotify() {
var m = new ol3.Object();
var n = new ol3.Object();
m.bindTo('k', n);
mEventDispatched = false;
goog.events.listen(m, 'k_changed', function() {
mEventDispatched = true;
});
nEventDispatched = false;
goog.events.listen(n, 'k_changed', function() {
nEventDispatched = true;
});
n.set('k', 1);
assertTrue(mEventDispatched);
assertTrue(nEventDispatched);
}
function testBindBackwardsNotify() {
var m = new ol3.Object();
var n = new ol3.Object();
n.bindTo('k', m);
mEventDispatched = false;
goog.events.listen(m, 'k_changed', function() {
mEventDispatched = true;
});
nEventDispatched = false;
goog.events.listen(n, 'k_changed', function() {
nEventDispatched = true;
});
n.set('k', 1);
assertTrue(mEventDispatched);
assertTrue(nEventDispatched);
}
function testBindRename() {
var m = new ol3.Object();
var n = new ol3.Object();
n.bindTo('kn', m, 'km');
m.set('km', 1);
assertEquals(m.get('km'), 1);
assertEquals(n.get('kn'), 1);
}
function testBindRenameEvents() {
var m = new ol3.Object();
var n = new ol3.Object();
kmEventDispatched = false;
goog.events.listen(m, 'km_changed', function() {
kmEventDispatched = true;
});
knEventDispatched = false;
goog.events.listen(n, 'kn_changed', function() {
knEventDispatched = true;
});
n.bindTo('kn', m, 'km');
m.set('km', 1);
assertEquals(m.get('km'), 1);
assertEquals(n.get('kn'), 1);
assertTrue(kmEventDispatched);
assertTrue(knEventDispatched);
}
function testTransitiveBindForwards() {
var m = new ol3.Object();
var n = new ol3.Object();
var o = new ol3.Object();
n.bindTo('kn', m, 'km');
o.bindTo('ko', n, 'kn');
m.set('km', 1);
assertEquals(1, m.get('km'));
assertEquals(1, n.get('kn'));
assertEquals(1, o.get('ko'));
}
function testTransitiveBindBackwards() {
var m = new ol3.Object();
var n = new ol3.Object();
var o = new ol3.Object();
n.bindTo('kn', m, 'km');
o.bindTo('ko', n, 'kn');
o.set('ko', 1);
assertEquals(1, m.get('km'));
assertEquals(1, n.get('kn'));
assertEquals(1, o.get('ko'));
}
function testMrideyAccessors() {
// http://blog.mridey.com/2010/03/maps-javascript-api-v3-more-about.html
var a = new ol3.Object();
a.set('level', 2);
assertEquals(2, a.get('level'));
var b = new ol3.Object();
b.setValues({
level: 2,
index: 3,
description: 'Hello world.'
});
assertEquals(3, b.get('index'));
}
function testMrideyBinding() {
// http://blog.mridey.com/2010/03/maps-javascript-api-v3-more-about.html
var a = new ol3.Object();
a.set('level', 2);
var b = new ol3.Object();
b.bindTo('index', a, 'level');
assertEquals(2, b.get('index'));
a.set('level', 3);
assertEquals(3, b.get('index'));
b.set('index', 4);
assertEquals(4, a.get('level'));
var c = new ol3.Object();
c.bindTo('zoom', a, 'level');
assertEquals(4, c.get('zoom'));
b.unbind('index');
assertEquals(4, b.get('index'));
c.set('zoom', 5);
assertEquals(5, a.get('level'));
assertEquals(4, b.get('index'));
}
function testCircularBind() {
var a = new ol3.Object();
var b = new ol3.Object();
a.bindTo('k', b);
assertThrows(function() {
b.bindTo('k', a);
});
}
function testPriority() {
var a = new ol3.Object();
var b = new ol3.Object();
a.set('k', 1);
b.set('k', 2);
a.bindTo('k', b);
assertEquals(2, a.get('k'));
assertEquals(2, b.get('k'));
}
function testPriorityUndefined() {
var a = new ol3.Object();
var b = new ol3.Object();
a.set('k', 1);
a.bindTo('k', b);
assertUndefined(a.get('k'));
assertUndefined(b.get('k'));
}
function testSetter() {
var a = new ol3.Object();
var x;
var setterCalled;
a.setX = function(value) {
this.x = value;
setterCalled = true;
};
a.set('x', 1);
assertEquals(1, a.get('x'));
assertUndefined(setterCalled);
}
function testSetterBind() {
var a = new ol3.Object();
var x;
var setterCalled;
a.setX = function(value) {
this.x = value;
setterCalled = true;
};
var b = new ol3.Object();
b.bindTo('x', a);
b.set('x', 1);
assertEquals(1, a.get('x'));
assertEquals(1, b.get('x'));
assertTrue(setterCalled);
}
function testGetter() {
var a = new ol3.Object();
var getterCalled;
a.getX = function() {
getterCalled = true;
return 1;
};
assertUndefined(a.get('x'));
assertUndefined(getterCalled);
}
function testGetterBind() {
var a = new ol3.Object();
var getterCalled;
a.getX = function() {
getterCalled = true;
return 1;
};
var b = new ol3.Object();
b.bindTo('x', a);
assertEquals(1, b.get('x'));
assertTrue(getterCalled);
}
function testBindSelf() {
var a = new ol3.Object();
assertThrows(function() {
a.bindTo('k', a);
});
}
function testCreateWithOptions() {
var obj = new ol3.Object({k: 1});
assertEquals(1, obj.get('k'));
}
function testEventTypeCaseSensitivity() {
var obj = new ol3.Object();
var lowercaseEventDispatched = false;
goog.events.listen(obj, 'k_changed', function() {
lowercaseEventDispatched = true;
});
var uppercaseEventDispatched = false;
goog.events.listen(obj, 'K_changed', function() {
uppercaseEventDispatched = true;
});
obj.set('K', 1);
assertTrue(lowercaseEventDispatched);
assertFalse(uppercaseEventDispatched);
}

9
src/ol3/base/ol.js Normal file
View File

@@ -0,0 +1,9 @@
goog.provide('ol3');
goog.require('goog.debug.Logger');
if (goog.DEBUG) {
var logger = goog.debug.Logger.getLogger('ol3');
logger.setLevel(goog.debug.Logger.Level.FINEST);
}

24
src/ol3/base/pixel.js Normal file
View File

@@ -0,0 +1,24 @@
goog.provide('ol3.Pixel');
goog.require('goog.math.Coordinate');
/**
* @constructor
* @extends {goog.math.Coordinate}
* @param {number} x X.
* @param {number} y Y.
*/
ol3.Pixel = function(x, y) {
goog.base(this, x, y);
};
goog.inherits(ol3.Pixel, goog.math.Coordinate);
/**
* @return {ol3.Pixel} Clone.
*/
ol3.Pixel.prototype.clone = function() {
return new ol3.Pixel(this.x, this.y);
};

View File

@@ -0,0 +1,18 @@
goog.provide('ol3.PixelBounds');
goog.require('ol3.Rectangle');
/**
* @constructor
* @extends {ol3.Rectangle}
* @param {number} minX Minimum X.
* @param {number} minY Minimum Y.
* @param {number} maxX Maximum X.
* @param {number} maxY Maximum Y.
*/
ol3.PixelBounds = function(minX, minY, maxX, maxY) {
goog.base(this, minX, minY, maxX, maxY);
};
goog.inherits(ol3.PixelBounds, ol3.Rectangle);

500
src/ol3/base/projection.js Normal file
View File

@@ -0,0 +1,500 @@
goog.provide('ol3.Projection');
goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.object');
goog.require('ol3.Coordinate');
goog.require('ol3.Extent');
goog.require('ol3.TransformFunction');
/**
* @define {boolean} Enable Proj4js.
*/
ol3.ENABLE_PROJ4JS = true;
/**
* @enum {string}
*/
ol3.ProjectionUnits = {
DEGREES: 'degrees',
METERS: 'm'
};
/**
* @constructor
* @param {string} code Code.
* @param {ol3.ProjectionUnits} units Units.
* @param {ol3.Extent} extent Extent.
*/
ol3.Projection = function(code, units, extent) {
/**
* @private
* @type {string}
*/
this.code_ = code;
/**
* @private
* @type {ol3.ProjectionUnits}
*/
this.units_ = units;
/**
* @private
* @type {ol3.Extent}
*/
this.extent_ = extent;
};
/**
* @return {string} Code.
*/
ol3.Projection.prototype.getCode = function() {
return this.code_;
};
/**
* @return {ol3.Extent} Extent.
*/
ol3.Projection.prototype.getExtent = function() {
return this.extent_;
};
/**
* @return {ol3.ProjectionUnits} Units.
*/
ol3.Projection.prototype.getUnits = function() {
return this.units_;
};
/**
* @constructor
* @extends {ol3.Projection}
* @param {string} code Code.
* @param {Proj4js.Proj} proj4jsProj Proj4js projection.
*/
ol3.Proj4jsProjection = function(code, proj4jsProj) {
var units = /** @type {ol3.ProjectionUnits} */ proj4jsProj.units;
goog.base(this, code, units, null);
/**
* @private
* @type {Proj4js.Proj}
*/
this.proj4jsProj_ = proj4jsProj;
};
goog.inherits(ol3.Proj4jsProjection, ol3.Projection);
/**
* @return {Proj4js.Proj} Proj4js projection.
*/
ol3.Proj4jsProjection.prototype.getProj4jsProj = function() {
return this.proj4jsProj_;
};
/**
* @private
* @type {Object.<string, ol3.Proj4jsProjection>}
*/
ol3.Projection.proj4jsProjections_ = {};
/**
* @private
* @type {Object.<string, ol3.Projection>}
*/
ol3.Projection.projections_ = {};
/**
* @private
* @type {Object.<string, Object.<string, ol3.TransformFunction>>}
*/
ol3.Projection.transforms_ = {};
/**
* @param {Array.<ol3.Projection>} projections Projections.
* @private
*/
ol3.Projection.addEquivalentProjections_ = function(projections) {
ol3.Projection.addProjections(projections);
goog.array.forEach(projections, function(source) {
goog.array.forEach(projections, function(destination) {
ol3.Projection.addTransform(
source, destination, ol3.Projection.cloneTransform);
});
});
};
/**
* @param {Array.<ol3.Projection>} projections1 Projections.
* @param {Array.<ol3.Projection>} projections2 Projections.
* @param {ol3.TransformFunction} forwardTransform Forward transform.
* @param {ol3.TransformFunction} inverseTransform Inverse transform.
* @private
*/
ol3.Projection.addEquivalentTransforms_ =
function(projections1, projections2, forwardTransform, inverseTransform) {
goog.array.forEach(projections1, function(projection1) {
goog.array.forEach(projections2, function(projection2) {
ol3.Projection.addTransform(projection1, projection2, forwardTransform);
ol3.Projection.addTransform(projection2, projection1, inverseTransform);
});
});
};
/**
* @param {ol3.Proj4jsProjection} proj4jsProjection Proj4js projection.
*/
ol3.Projection.addProj4jsProjection = function(proj4jsProjection) {
var proj4jsProjections = ol3.Projection.proj4jsProjections_;
var code = proj4jsProjection.getCode();
goog.asserts.assert(!goog.object.containsKey(proj4jsProjections, code));
proj4jsProjections[code] = proj4jsProjection;
};
/**
* @param {ol3.Projection} projection Projection.
*/
ol3.Projection.addProjection = function(projection) {
var projections = ol3.Projection.projections_;
var code = projection.getCode();
goog.asserts.assert(!goog.object.containsKey(projections, code));
projections[code] = projection;
};
/**
* @param {Array.<ol3.Projection>} projections Projections.
*/
ol3.Projection.addProjections = function(projections) {
goog.array.forEach(projections, function(projection) {
ol3.Projection.addProjection(projection);
});
};
/**
* @param {ol3.Projection} source Source.
* @param {ol3.Projection} destination Destination.
* @param {ol3.TransformFunction} transformFn Transform.
*/
ol3.Projection.addTransform = function(source, destination, transformFn) {
var projections = ol3.Projection.projections_;
var sourceCode = source.getCode();
var destinationCode = destination.getCode();
var transforms = ol3.Projection.transforms_;
if (!goog.object.containsKey(transforms, sourceCode)) {
transforms[sourceCode] = {};
}
goog.asserts.assert(
!goog.object.containsKey(transforms[sourceCode], destinationCode));
transforms[sourceCode][destinationCode] = transformFn;
};
/**
* @param {string} code Code.
* @return {ol3.Projection} Projection.
*/
ol3.Projection.getFromCode = function(code) {
var projection = ol3.Projection.projections_[code];
if (ol3.Projection.isProj4jsSupported() && !goog.isDef(projection)) {
projection = ol3.Projection.getProj4jsProjectionFromCode_(code);
}
if (!goog.isDef(projection)) {
goog.asserts.assert(goog.isDef(projection));
projection = null;
}
return projection;
};
/**
* @param {string} code Code.
* @private
* @return {ol3.Proj4jsProjection} Proj4js projection.
*/
ol3.Projection.getProj4jsProjectionFromCode_ = function(code) {
var proj4jsProjections = ol3.Projection.proj4jsProjections_;
var proj4jsProjection = proj4jsProjections[code];
if (!goog.isDef(proj4jsProjection)) {
var proj4jsProj = new Proj4js.Proj(code);
proj4jsProjection = new ol3.Proj4jsProjection(code, proj4jsProj);
proj4jsProjections[code] = proj4jsProjection;
}
return proj4jsProjection;
};
/**
* @param {ol3.Projection} projection1 Projection 1.
* @param {ol3.Projection} projection2 Projection 2.
* @return {boolean} Equivalent.
*/
ol3.Projection.equivalent = function(projection1, projection2) {
if (projection1 === projection2) {
return true;
} else if (projection1.getUnits() != projection2.getUnits()) {
return false;
} else {
var transformFn = ol3.Projection.getTransform(projection1, projection2);
return transformFn === ol3.Projection.cloneTransform;
}
};
/**
* @param {ol3.Projection} source Source.
* @param {ol3.Projection} destination Destination.
* @return {ol3.TransformFunction} Transform.
*/
ol3.Projection.getTransform = function(source, destination) {
var transforms = ol3.Projection.transforms_;
var sourceCode = source.getCode();
var destinationCode = destination.getCode();
var transform;
if (goog.object.containsKey(transforms, sourceCode) &&
goog.object.containsKey(transforms[sourceCode], destinationCode)) {
transform = transforms[sourceCode][destinationCode];
}
if (ol3.Projection.isProj4jsSupported() && !goog.isDef(transform)) {
var proj4jsSource;
if (source instanceof ol3.Proj4jsProjection) {
proj4jsSource = source;
} else {
proj4jsSource =
ol3.Projection.getProj4jsProjectionFromCode_(source.getCode());
}
var sourceProj4jsProj = proj4jsSource.getProj4jsProj();
var proj4jsDestination;
if (destination instanceof ol3.Proj4jsProjection) {
proj4jsDestination = destination;
} else {
proj4jsDestination =
ol3.Projection.getProj4jsProjectionFromCode_(source.getCode());
}
var destinationProj4jsProj = proj4jsDestination.getProj4jsProj();
transform =
/**
* @param {ol3.Coordinate} coordinate Coordinate.
* @return {ol3.Coordinate} Coordinate.
*/
function(coordinate) {
var proj4jsPoint = new Proj4js.Point(coordinate.x, coordinate.y);
proj4jsPoint = Proj4js.transform(
sourceProj4jsProj, destinationProj4jsProj, proj4jsPoint);
return new ol3.Coordinate(proj4jsPoint.x, proj4jsPoint.y);
};
ol3.Projection.addTransform(source, destination, transform);
}
if (!goog.isDef(transform)) {
goog.asserts.assert(goog.isDef(transform));
transform = ol3.Projection.identityTransform;
}
return transform;
};
/**
* @param {string} sourceCode Source code.
* @param {string} destinationCode Destination code.
* @return {ol3.TransformFunction} Transform.
*/
ol3.Projection.getTransformFromCodes = function(sourceCode, destinationCode) {
var source = ol3.Projection.getFromCode(sourceCode);
var destination = ol3.Projection.getFromCode(destinationCode);
return ol3.Projection.getTransform(source, destination);
};
/**
* @return {boolean} Has Proj4js.
*/
ol3.Projection.isProj4jsSupported = function() {
return ol3.ENABLE_PROJ4JS && 'Proj4js' in goog.global;
};
/**
* @param {ol3.Coordinate} point Point.
* @return {ol3.Coordinate} Point.
*/
ol3.Projection.identityTransform = function(point) {
return point;
};
/**
* @param {ol3.Coordinate} point Point.
* @return {ol3.Coordinate} Point.
*/
ol3.Projection.cloneTransform = function(point) {
return point.clone();
};
/**
* @param {ol3.Coordinate} point Point.
* @param {ol3.Projection} source Source.
* @param {ol3.Projection} destination Destination.
* @return {ol3.Coordinate} Point.
*/
ol3.Projection.transform = function(point, source, destination) {
var transformFn = ol3.Projection.getTransform(source, destination);
return transformFn(point);
};
/**
* @param {ol3.Coordinate} point Point.
* @param {string} sourceCode Source code.
* @param {string} destinationCode Destination code.
* @return {ol3.Coordinate} Point.
*/
ol3.Projection.transformWithCodes =
function(point, sourceCode, destinationCode) {
var transformFn = ol3.Projection.getTransformFromCodes(
sourceCode, destinationCode);
return transformFn(point);
};
/**
* @const
* @type {number}
*/
ol3.Projection.EPSG_3857_RADIUS = 6378137;
/**
* @param {ol3.Coordinate} point Point.
* @return {ol3.Coordinate} Point.
*/
ol3.Projection.forwardSphericalMercator = function(point) {
var x = ol3.Projection.EPSG_3857_RADIUS * Math.PI * point.x / 180;
var y = ol3.Projection.EPSG_3857_RADIUS *
Math.log(Math.tan(Math.PI * (point.y + 90) / 360));
return new ol3.Coordinate(x, y);
};
/**
* @param {ol3.Coordinate} point Point.
* @return {ol3.Coordinate} Point.
*/
ol3.Projection.inverseSphericalMercator = function(point) {
var x = 180 * point.x / (ol3.Projection.EPSG_3857_RADIUS * Math.PI);
var y = 360 * Math.atan(
Math.exp(point.y / ol3.Projection.EPSG_3857_RADIUS)) / Math.PI - 90;
return new ol3.Coordinate(x, y);
};
/**
* @const
* @type {number}
*/
ol3.Projection.EPSG_3857_HALF_SIZE = Math.PI * ol3.Projection.EPSG_3857_RADIUS;
/**
* @const
* @type {ol3.Extent}
*/
ol3.Projection.EPSG_3857_EXTENT = new ol3.Extent(
-ol3.Projection.EPSG_3857_HALF_SIZE,
-ol3.Projection.EPSG_3857_HALF_SIZE,
ol3.Projection.EPSG_3857_HALF_SIZE,
ol3.Projection.EPSG_3857_HALF_SIZE);
/**
* @private
* @type {Array.<string>}
*/
ol3.Projection.EPSG_3857_LIKE_CODES_ = [
'EPSG:3857',
'EPSG:102100',
'EPSG:102113',
'EPSG:900913'
];
/**
* @const
* @private
* @type {Array.<ol3.Projection>}
*/
ol3.Projection.EPSG_3857_LIKE_PROJECTIONS_ = goog.array.map(
ol3.Projection.EPSG_3857_LIKE_CODES_,
function(code) {
return new ol3.Projection(
code,
ol3.ProjectionUnits.METERS,
ol3.Projection.EPSG_3857_EXTENT);
});
/**
* @const
* @private
* @type {ol3.Extent}
*/
ol3.Projection.EPSG_4326_EXTENT_ = new ol3.Extent(-180, -90, 180, 90);
/**
* @private
* @type {Array.<string>}
*/
ol3.Projection.EPSG_4326_LIKE_CODES_ = [
'CRS:84',
'EPSG:4326',
'urn:ogc:def:crs:EPSG:6.6:4326'
];
/**
* @const
* @type {Array.<ol3.Projection>}
*/
ol3.Projection.EPSG_4326_LIKE_PROJECTIONS = goog.array.map(
ol3.Projection.EPSG_4326_LIKE_CODES_,
function(code) {
return new ol3.Projection(
code,
ol3.ProjectionUnits.DEGREES,
ol3.Projection.EPSG_4326_EXTENT_);
});
ol3.Projection.addEquivalentProjections_(
ol3.Projection.EPSG_3857_LIKE_PROJECTIONS_);
ol3.Projection.addEquivalentProjections_(
ol3.Projection.EPSG_4326_LIKE_PROJECTIONS);
ol3.Projection.addEquivalentTransforms_(
ol3.Projection.EPSG_4326_LIKE_PROJECTIONS,
ol3.Projection.EPSG_3857_LIKE_PROJECTIONS_,
ol3.Projection.forwardSphericalMercator,
ol3.Projection.inverseSphericalMercator);

View File

@@ -0,0 +1,87 @@
goog.require('goog.array');
goog.require('goog.testing.jsunit');
goog.require('ol3.Coordinate');
goog.require('ol3.Projection');
function _testAllEquivalent(codes) {
var projections = goog.array.map(codes, ol3.Projection.getFromCode);
goog.array.forEach(projections, function(source) {
goog.array.forEach(projections, function(destination) {
assertTrue(ol3.Projection.equivalent(source, destination));
});
});
}
function testEpsg3857Equivalence() {
_testAllEquivalent([
'EPSG:3857',
'EPSG:102100',
'EPSG:102113',
'EPSG:900913'
]);
}
function testEpsg4326Equivalence() {
_testAllEquivalent([
'CRS:84',
'urn:ogc:def:crs:EPSG:6.6:4326',
'EPSG:4326'
]);
}
function testIdentityTransform() {
var epsg4326 = ol3.Projection.getFromCode('EPSG:4326');
var uniqueObject = {};
var sourcePoint = new ol3.Coordinate(uniqueObject, uniqueObject);
var destinationPoint = ol3.Projection.transform(
sourcePoint, epsg4326, epsg4326);
assertFalse(sourcePoint === destinationPoint);
assertTrue(destinationPoint.x === sourcePoint.x);
assertTrue(destinationPoint.y === sourcePoint.y);
}
function testForwardSphericalMercatorOrigin() {
var point = ol3.Projection.transformWithCodes(
new ol3.Coordinate(0, 0), 'EPSG:4326', 'EPSG:3857');
assertNotNullNorUndefined(point);
assertEquals(0, point.x);
assertRoughlyEquals(0, point.y, 1e-9);
}
function testInverseSphericalMercatorOrigin() {
var point = ol3.Projection.transformWithCodes(
new ol3.Coordinate(0, 0), 'EPSG:3857', 'EPSG:4326');
assertNotNullNorUndefined(point);
assertEquals(0, point.x);
assertEquals(0, point.y);
}
function testForwardSphericalMercatorAlastaira() {
// http://alastaira.wordpress.com/2011/01/23/the-google-maps-bing-maps-spherical-mercator-projection/
var point = ol3.Projection.transformWithCodes(
new ol3.Coordinate(-5.625, 52.4827802220782),
'EPSG:4326',
'EPSG:900913');
assertNotNullNorUndefined(point);
assertRoughlyEquals(-626172.13571216376, point.x, 1e-9);
assertRoughlyEquals(6887893.4928337997, point.y, 1e-9);
}
function testInverseSphericalMercatorAlastaira() {
// http://alastaira.wordpress.com/2011/01/23/the-google-maps-bing-maps-spherical-mercator-projection/
var point = ol3.Projection.transformWithCodes(
new ol3.Coordinate(-626172.13571216376, 6887893.4928337997),
'EPSG:900913',
'EPSG:4326');
assertNotNullNorUndefined(point);
assertRoughlyEquals(-5.625, point.x, 1e-9);
assertRoughlyEquals(52.4827802220782, point.y, 1e-9);
}

123
src/ol3/base/rectangle.js Normal file
View File

@@ -0,0 +1,123 @@
goog.provide('ol3.Rectangle');
goog.require('goog.asserts');
goog.require('ol3.Coordinate');
goog.require('ol3.Size');
/**
* @constructor
* @param {number} minX Minimum X.
* @param {number} minY Minimum Y.
* @param {number} maxX Maximum X.
* @param {number} maxY Maximum Y.
*/
ol3.Rectangle = function(minX, minY, maxX, maxY) {
goog.asserts.assert(minX <= maxX);
goog.asserts.assert(minY <= maxY);
/**
* @type {number}
*/
this.minX = minX;
/**
* @type {number}
*/
this.minY = minY;
/**
* @type {number}
*/
this.maxX = maxX;
/**
* @type {number}
*/
this.maxY = maxY;
};
/**
* @return {ol3.Rectangle} Clone.
*/
ol3.Rectangle.prototype.clone = function() {
return new ol3.Rectangle(this.minX, this.minY, this.maxX, this.maxY);
};
/**
* @param {ol3.Coordinate} coordinate Coordinate.
* @return {boolean} Contains.
*/
ol3.Rectangle.prototype.contains = function(coordinate) {
return this.minX <= coordinate.x && coordinate.x <= this.maxX &&
this.minY <= coordinate.y && coordinate.y <= this.maxY;
};
/**
* @return {ol3.Coordinate} Center.
*/
ol3.Rectangle.prototype.getCenter = function() {
return new ol3.Coordinate(
(this.minX + this.maxX) / 2, (this.minY + this.maxY) / 2);
};
/**
* @return {number} Height.
*/
ol3.Rectangle.prototype.getHeight = function() {
return this.maxY - this.minY;
};
/**
* @return {ol3.Size} Size.
*/
ol3.Rectangle.prototype.getSize = function() {
return new ol3.Size(this.getWidth(), this.getHeight());
};
/**
* @return {number} Width.
*/
ol3.Rectangle.prototype.getWidth = function() {
return this.maxX - this.minX;
};
/**
* @param {ol3.Rectangle} rectangle Rectangle.
* @return {boolean} Intersects.
*/
ol3.Rectangle.prototype.intersects = function(rectangle) {
return this.minX <= rectangle.maxX &&
this.maxX >= rectangle.minX &&
this.minY <= rectangle.maxY &&
this.maxY >= rectangle.minY;
};
/**
* @param {ol3.Coordinate} coordinate Coordinate.
* @return {ol3.Coordinate} Coordinate.
*/
ol3.Rectangle.prototype.normalize = function(coordinate) {
return new ol3.Coordinate(
(coordinate.x - this.minX) / this.getWidth(),
(coordinate.y - this.minY) / this.getHeight());
};
/**
* @return {string} String.
*/
ol3.Rectangle.prototype.toString = function() {
return '(' + [this.minX, this.minY, this.maxX, this.maxY].join(', ') + ')';
};

View File

@@ -0,0 +1,142 @@
goog.require('goog.testing.jsunit');
goog.require('ol3.Coordinate');
goog.require('ol3.Rectangle');
function testCenter() {
var rectangle = new ol3.Rectangle(1, 2, 3, 4);
var center = rectangle.getCenter();
assertEquals(2, center.x);
assertEquals(3, center.y);
}
function testClone() {
var rectangle = new ol3.Rectangle(1, 2, 3, 4);
var clonedRectangle = rectangle.clone();
assertTrue(clonedRectangle instanceof ol3.Rectangle);
assertFalse(clonedRectangle === rectangle);
assertEquals(rectangle.minX, clonedRectangle.minX);
assertEquals(rectangle.minY, clonedRectangle.minY);
assertEquals(rectangle.maxX, clonedRectangle.maxX);
assertEquals(rectangle.maxY, clonedRectangle.maxY);
}
function testContainsPositive() {
var rectangle = new ol3.Rectangle(1, 2, 3, 4);
assertTrue(rectangle.contains(new ol3.Coordinate(1, 2)));
assertTrue(rectangle.contains(new ol3.Coordinate(1, 3)));
assertTrue(rectangle.contains(new ol3.Coordinate(1, 4)));
assertTrue(rectangle.contains(new ol3.Coordinate(2, 2)));
assertTrue(rectangle.contains(new ol3.Coordinate(2, 3)));
assertTrue(rectangle.contains(new ol3.Coordinate(2, 4)));
assertTrue(rectangle.contains(new ol3.Coordinate(3, 2)));
assertTrue(rectangle.contains(new ol3.Coordinate(3, 3)));
assertTrue(rectangle.contains(new ol3.Coordinate(3, 4)));
}
function testContainsNegative() {
var rectangle = new ol3.Rectangle(1, 2, 3, 4);
assertFalse(rectangle.contains(new ol3.Coordinate(0, 1)));
assertFalse(rectangle.contains(new ol3.Coordinate(0, 2)));
assertFalse(rectangle.contains(new ol3.Coordinate(0, 3)));
assertFalse(rectangle.contains(new ol3.Coordinate(0, 4)));
assertFalse(rectangle.contains(new ol3.Coordinate(0, 5)));
assertFalse(rectangle.contains(new ol3.Coordinate(1, 1)));
assertFalse(rectangle.contains(new ol3.Coordinate(1, 5)));
assertFalse(rectangle.contains(new ol3.Coordinate(2, 1)));
assertFalse(rectangle.contains(new ol3.Coordinate(2, 5)));
assertFalse(rectangle.contains(new ol3.Coordinate(3, 1)));
assertFalse(rectangle.contains(new ol3.Coordinate(3, 5)));
assertFalse(rectangle.contains(new ol3.Coordinate(4, 1)));
assertFalse(rectangle.contains(new ol3.Coordinate(4, 2)));
assertFalse(rectangle.contains(new ol3.Coordinate(4, 3)));
assertFalse(rectangle.contains(new ol3.Coordinate(4, 4)));
assertFalse(rectangle.contains(new ol3.Coordinate(4, 5)));
}
function testIntersects() {
var rectangle1 = new ol3.Rectangle(50, 50, 100, 100);
function assertIntersects(rectangle2) {
assertTrue(rectangle1 + ' expected to intersect ' + rectangle2,
rectangle1.intersects(rectangle2));
}
function assertNotIntersects(rectangle2) {
assertFalse(rectangle1 + ' expected to not intersect ' + rectangle2,
rectangle1.intersects(rectangle2));
}
assertIntersects(rectangle1);
assertIntersects(new ol3.Rectangle(20, 20, 80, 80));
assertIntersects(new ol3.Rectangle(20, 50, 80, 100));
assertIntersects(new ol3.Rectangle(20, 80, 80, 120));
assertIntersects(new ol3.Rectangle(50, 20, 100, 80));
assertIntersects(new ol3.Rectangle(50, 80, 100, 120));
assertIntersects(new ol3.Rectangle(80, 20, 120, 80));
assertIntersects(new ol3.Rectangle(80, 50, 120, 100));
assertIntersects(new ol3.Rectangle(80, 80, 120, 120));
assertIntersects(new ol3.Rectangle(20, 20, 120, 120));
assertIntersects(new ol3.Rectangle(70, 70, 80, 80));
assertNotIntersects(new ol3.Rectangle(10, 10, 30, 30));
assertNotIntersects(new ol3.Rectangle(30, 10, 70, 30));
assertNotIntersects(new ol3.Rectangle(50, 10, 100, 30));
assertNotIntersects(new ol3.Rectangle(80, 10, 120, 30));
assertNotIntersects(new ol3.Rectangle(120, 10, 140, 30));
assertNotIntersects(new ol3.Rectangle(10, 30, 30, 70));
assertNotIntersects(new ol3.Rectangle(120, 30, 140, 70));
assertNotIntersects(new ol3.Rectangle(10, 50, 30, 100));
assertNotIntersects(new ol3.Rectangle(120, 50, 140, 100));
assertNotIntersects(new ol3.Rectangle(10, 80, 30, 120));
assertNotIntersects(new ol3.Rectangle(120, 80, 140, 120));
assertNotIntersects(new ol3.Rectangle(10, 120, 30, 140));
assertNotIntersects(new ol3.Rectangle(30, 120, 70, 140));
assertNotIntersects(new ol3.Rectangle(50, 120, 100, 140));
assertNotIntersects(new ol3.Rectangle(80, 120, 120, 140));
assertNotIntersects(new ol3.Rectangle(120, 120, 140, 140));
}
function testSize() {
var rectangle = new ol3.Rectangle(0, 1, 2, 4);
var size = rectangle.getSize();
assertEquals(2, size.width);
assertEquals(3, size.height);
}
function testNormalize() {
var rectangle = new ol3.Rectangle(0, 1, 2, 3);
var coordinate;
coordinate = rectangle.normalize(new ol3.Coordinate(1, 2));
assertEquals(0.5, coordinate.x);
assertEquals(0.5, coordinate.y);
coordinate = rectangle.normalize(new ol3.Coordinate(0, 3));
assertEquals(0, coordinate.x);
assertEquals(1, coordinate.y);
coordinate = rectangle.normalize(new ol3.Coordinate(2, 1));
assertEquals(1, coordinate.x);
assertEquals(0, coordinate.y);
coordinate = rectangle.normalize(new ol3.Coordinate(0, 0));
assertEquals(0, coordinate.x);
assertEquals(-0.5, coordinate.y);
coordinate = rectangle.normalize(new ol3.Coordinate(-1, 1));
assertEquals(-0.5, coordinate.x);
assertEquals(0, coordinate.y);
}
function testToString() {
var rectangle = new ol3.Rectangle(0, 1, 2, 3);
assertEquals('(0, 1, 2, 3)', rectangle.toString());
}

25
src/ol3/base/size.js Normal file
View File

@@ -0,0 +1,25 @@
goog.provide('ol3.Size');
goog.require('goog.math.Size');
/**
* @constructor
* @extends {goog.math.Size}
* @param {number} width Width.
* @param {number} height Height.
*/
ol3.Size = function(width, height) {
goog.base(this, width, height);
};
goog.inherits(ol3.Size, goog.math.Size);
/**
* @param {ol3.Size} size Size.
* @return {boolean} Equals.
*/
ol3.Size.prototype.equals = function(size) {
return this.width == size.width && this.height == size.height;
};

96
src/ol3/base/store.js Normal file
View File

@@ -0,0 +1,96 @@
goog.provide('ol3.Store');
goog.require('goog.functions');
goog.require('ol3.Attribution');
goog.require('ol3.Extent');
goog.require('ol3.Projection');
/**
* @constructor
* @param {ol3.Projection} projection Projection.
* @param {ol3.Extent=} opt_extent Extent.
* @param {Array.<ol3.Attribution>=} opt_attributions Attributions.
*/
ol3.Store = function(projection, opt_extent, opt_attributions) {
/**
* @private
* @type {ol3.Projection}
*/
this.projection_ = projection;
/**
* @private
* @type {ol3.Extent}
*/
this.extent_ = opt_extent || projection.getExtent();
/**
* @private
* @type {Array.<ol3.Attribution>}
*/
this.attributions_ = opt_attributions || null;
};
/**
* @return {Array.<ol3.Attribution>} Attributions.
*/
ol3.Store.prototype.getAttributions = function() {
return this.attributions_;
};
/**
* @return {ol3.Extent} Extent.
*/
ol3.Store.prototype.getExtent = function() {
return this.extent_;
};
/**
* @return {ol3.Projection} Projection.
*/
ol3.Store.prototype.getProjection = function() {
return this.projection_;
};
/**
* @return {Array.<number>|undefined} Resolutions.
*/
ol3.Store.prototype.getResolutions = goog.abstractMethod;
/**
* @return {boolean} Is ready.
*/
ol3.Store.prototype.isReady = goog.functions.TRUE;
/**
* @param {Array.<ol3.Attribution>} attributions Attributions.
*/
ol3.Store.prototype.setAttributions = function(attributions) {
this.attributions_ = attributions;
};
/**
* @param {ol3.Extent} extent Extent.
*/
ol3.Store.prototype.setExtent = function(extent) {
this.extent_ = extent;
};
/**
* @param {ol3.Projection} projection Projetion.
*/
ol3.Store.prototype.setProjection = function(projection) {
this.projection_ = projection;
};

View File

@@ -0,0 +1,9 @@
goog.provide('ol3.TransformFunction');
goog.require('ol3.Coordinate');
/**
* @typedef {function(ol3.Coordinate): ol3.Coordinate}
*/
ol3.TransformFunction;

View File

@@ -0,0 +1,398 @@
// FIXME handle rotation
// FIXME handle date line wrap
// FIXME handle layer order
// FIXME check clean-up code
goog.provide('ol3.control.Attribution');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.object');
goog.require('goog.style');
goog.require('ol3.Collection');
goog.require('ol3.Control');
goog.require('ol3.CoverageArea');
goog.require('ol3.Layer');
goog.require('ol3.MapProperty');
goog.require('ol3.TileCoverageArea');
/**
* @constructor
* @extends {ol3.Control}
* @param {ol3.Map} map Map.
*/
ol3.control.Attribution = function(map) {
goog.base(this, map);
/**
* @private
* @type {Element}
*/
this.ulElement_ = goog.dom.createElement(goog.dom.TagName.UL);
/**
* @private
* @type {Array.<number>}
*/
this.layersListenerKeys_ = null;
/**
* @private
* @type {Object.<number, ?number>}
*/
this.layerVisibleChangeListenerKeys_ = {};
/**
* @private
* @type {Object.<number, Element>}
*/
this.attributionElements_ = {};
/**
* @private
* @type {Object.<number, Array.<ol3.CoverageArea>>}
*/
this.coverageAreass_ = {};
goog.events.listen(
map, ol3.Object.getChangedEventType(ol3.MapProperty.CENTER),
this.handleMapChanged, false, this);
goog.events.listen(
map, ol3.Object.getChangedEventType(ol3.MapProperty.LAYERS),
this.handleMapLayersChanged, false, this);
goog.events.listen(map,
ol3.Object.getChangedEventType(ol3.MapProperty.RESOLUTION),
this.handleMapChanged, false, this);
goog.events.listen(map, ol3.Object.getChangedEventType(ol3.MapProperty.SIZE),
this.handleMapChanged, false, this);
this.handleMapLayersChanged();
};
goog.inherits(ol3.control.Attribution, ol3.Control);
/**
* @param {ol3.Layer} layer Layer.
* @protected
*/
ol3.control.Attribution.prototype.addLayer = function(layer) {
var layerKey = goog.getUid(layer);
this.layerVisibleChangeListenerKeys_[layerKey] = goog.events.listen(
layer, ol3.Object.getChangedEventType(ol3.LayerProperty.VISIBLE),
this.handleLayerVisibleChanged, false, this);
if (layer.getStore().isReady()) {
this.createAttributionElementsForLayer_(layer);
} else {
goog.events.listenOnce(layer, goog.events.EventType.LOAD,
this.handleLayerLoad, false, this);
}
};
/**
* @param {ol3.Layer} layer Layer.
* @private
*/
ol3.control.Attribution.prototype.createAttributionElementsForLayer_ =
function(layer) {
var store = layer.getStore();
var attributions = store.getAttributions();
if (goog.isNull(attributions)) {
return;
}
var map = this.getMap();
var mapIsDef = map.isDef();
var mapExtent = /** @type {ol3.Extent} */ map.getExtent();
var mapProjection = /** @type {ol3.Projection} */ map.getProjection();
var mapResolution = /** @type {number} */ map.getResolution();
var layerVisible = layer.getVisible();
var attributionVisibilities;
if (mapIsDef && layerVisible) {
attributionVisibilities = this.getLayerAttributionVisiblities_(
layer, mapExtent, mapResolution, mapProjection);
} else {
attributionVisibilities = null;
}
goog.array.forEach(attributions, function(attribution) {
var attributionKey = goog.getUid(attribution);
var attributionElement = goog.dom.createElement(goog.dom.TagName.LI);
attributionElement.innerHTML = attribution.getHtml();
if (!map.isDef ||
!layerVisible ||
goog.isNull(attributionVisibilities) ||
!attributionVisibilities[attributionKey]) {
goog.style.showElement(attributionElement, false);
}
goog.dom.appendChild(this.ulElement_, attributionElement);
this.attributionElements_[attributionKey] = attributionElement;
}, this);
};
/**
* @inheritDoc
*/
ol3.control.Attribution.prototype.getElement = function() {
return this.ulElement_;
};
/**
* @param {ol3.Layer} layer Layer.
* @param {ol3.Extent} mapExtent Map extent.
* @param {number} mapResolution Map resolution.
* @param {ol3.Projection} mapProjection Map projection.
* @return {Object.<number, boolean>} Attribution visibilities.
* @private
*/
ol3.control.Attribution.prototype.getLayerAttributionVisiblities_ =
function(layer, mapExtent, mapResolution, mapProjection) {
var store = layer.getStore();
var attributions = store.getAttributions();
if (goog.isNull(attributions)) {
return null;
}
var mapZ;
if (store instanceof ol3.TileStore) {
var tileStore = /** @type {ol3.TileStore} */ store;
var tileGrid = tileStore.getTileGrid();
mapZ = tileGrid.getZForResolution(mapResolution);
}
var attributionVisibilities = {};
goog.array.forEach(attributions, function(attribution) {
var attributionKey = goog.getUid(attribution);
var attributionVisible = true;
var coverageAreas;
if (attributionKey in this.coverageAreass_) {
coverageAreas = this.coverageAreass_[attributionKey];
} else {
var attributionProjection = attribution.getProjection();
coverageAreas = attribution.getCoverageAreas();
if (!goog.isNull(coverageAreas) &&
!ol3.Projection.equivalent(attributionProjection, mapProjection)) {
var transformFn = ol3.Projection.getTransform(
attributionProjection, mapProjection);
if (transformFn !== ol3.Projection.cloneTransform) {
coverageAreas = goog.array.map(coverageAreas, function(coverageArea) {
return coverageArea.transform(transformFn);
});
}
}
this.coverageAreass_[attributionKey] = coverageAreas;
}
if (!goog.isNull(coverageAreas)) {
if (store instanceof ol3.TileStore) {
attributionVisible = goog.array.some(
coverageAreas,
/**
* @param {ol3.TileCoverageArea} tileCoverageArea
* Tile coverage area.
*/
function(tileCoverageArea) {
goog.asserts.assert(
tileCoverageArea instanceof ol3.TileCoverageArea);
return tileCoverageArea.intersectsExtentAndZ(mapExtent, mapZ);
});
} else {
attributionVisible = goog.array.some(
coverageAreas,
function(coverageArea) {
return coverageArea.intersectsExtentAndResolution(
mapExtent, mapResolution);
});
}
}
attributionVisibilities[attributionKey] = attributionVisible;
}, this);
return attributionVisibilities;
};
/**
* @param {goog.events.Event} event Event.
*/
ol3.control.Attribution.prototype.handleLayerLoad = function(event) {
var layer = /** @type {ol3.Layer} */ event.target;
this.createAttributionElementsForLayer_(layer);
};
/**
* @param {goog.events.Event} event Event.
* @protected
*/
ol3.control.Attribution.prototype.handleLayerVisibleChanged = function(event) {
var map = this.getMap();
var mapIsDef = map.isDef();
var mapExtent = /** @type {ol3.Extent} */ map.getExtent();
var mapProjection = /** @type {ol3.Projection} */ map.getProjection();
var mapResolution = /** @type {number} */ map.getResolution();
var layer = /** @type {ol3.Layer} */ event.target;
this.updateLayerAttributionsVisibility_(
layer, mapIsDef, mapExtent, mapResolution, mapProjection);
};
/**
* @param {ol3.CollectionEvent} collectionEvent Collection event.
* @protected
*/
ol3.control.Attribution.prototype.handleLayersAdd = function(collectionEvent) {
var layer = /** @type {ol3.Layer} */ collectionEvent.elem;
this.addLayer(layer);
};
/**
* @param {ol3.CollectionEvent} collectionEvent Collection event.
* @protected
*/
ol3.control.Attribution.prototype.handleLayersRemove =
function(collectionEvent) {
var layer = /** @type {ol3.Layer} */ collectionEvent.elem;
this.removeLayer(layer);
};
/**
* @protected
*/
ol3.control.Attribution.prototype.handleMapChanged = function() {
var map = this.getMap();
var mapIsDef = map.isDef();
var mapExtent = /** @type {ol3.Extent} */ map.getExtent();
var mapProjection = /** @type {ol3.Projection} */ map.getProjection();
var mapResolution = map.getResolution();
var layers = map.getLayers();
layers.forEach(function(layer) {
this.updateLayerAttributionsVisibility_(
layer, mapIsDef, mapExtent, mapResolution, mapProjection);
}, this);
};
/**
* @protected
*/
ol3.control.Attribution.prototype.handleMapLayersChanged = function() {
if (!goog.isNull(this.layersListenerKeys_)) {
goog.array.forEach(this.layersListenerKeys_, goog.events.unlistenByKey);
this.layersListenerKeys_ = null;
}
goog.object.forEach(this.attributionElements_, function(attributionElement) {
goog.dom.removeNode(attributionElement);
}, this);
this.attributionElements_ = {};
this.coverageAreass_ = {};
var map = this.getMap();
var layers = map.getLayers();
if (goog.isDefAndNotNull(layers)) {
layers.forEach(this.addLayer, this);
this.layersListenerKeys_ = [
goog.events.listen(layers, ol3.CollectionEventType.ADD,
this.handleLayersAdd, false, this),
goog.events.listen(layers, ol3.CollectionEventType.REMOVE,
this.handleLayersRemove, false, this)
];
}
};
/**
* @param {ol3.Layer} layer Layer.
* @protected
*/
ol3.control.Attribution.prototype.removeLayer = function(layer) {
var layerKey = goog.getUid(layer);
goog.events.unlistenByKey(this.layerVisibleChangeListenerKeys_[layerKey]);
delete this.layerVisibleChangeListenerKeys_[layerKey];
goog.array.forEach(layer.getStore().getAttributions(), function(attribution) {
var attributionKey = goog.getUid(attribution);
delete this.coverageAreass_[attributionKey];
var attributionElement = this.attributionElements_[attributionKey];
goog.dom.removeNode(attributionElement);
delete this.attributionElements_[attributionKey];
}, this);
};
/**
* @param {ol3.Layer} layer Layer.
* @param {boolean} mapIsDef Map is defined.
* @param {ol3.Extent} mapExtent Map extent.
* @param {number} mapResolution Map resolution.
* @param {ol3.Projection} mapProjection Map projection.
* @private
*/
ol3.control.Attribution.prototype.updateLayerAttributionsVisibility_ =
function(layer, mapIsDef, mapExtent, mapResolution, mapProjection) {
if (mapIsDef && layer.getVisible()) {
var attributionVisibilities = this.getLayerAttributionVisiblities_(
layer, mapExtent, mapResolution, mapProjection);
goog.object.forEach(
attributionVisibilities,
function(attributionVisible, attributionKey) {
var attributionElement = this.attributionElements_[attributionKey];
goog.style.showElement(attributionElement, attributionVisible);
},
this);
} else {
var store = layer.getStore();
var attributions = store.getAttributions();
if (!goog.isNull(attributions)) {
goog.array.forEach(attributions, function(attribution) {
var attributionKey = goog.getUid(attribution);
var attributionElement = this.attributionElements_[attributionKey];
goog.style.showElement(attributionElement, false);
}, this);
}
}
};

View File

@@ -0,0 +1,33 @@
goog.provide('ol3.Control');
goog.require('ol3.Map');
/**
* @constructor
* @param {ol3.Map} map Map.
*/
ol3.Control = function(map) {
/**
* @private
* @type {ol3.Map}
*/
this.map_ = map;
};
/**
* @return {Element} Element.
*/
ol3.Control.prototype.getElement = goog.abstractMethod;
/**
* @return {ol3.Map} Map.
*/
ol3.Control.prototype.getMap = function() {
return this.map_;
};

View File

@@ -0,0 +1,128 @@
// FIXME should listen on appropriate pane, once it is defined
goog.provide('ol3.control.MousePosition');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('ol3.Control');
goog.require('ol3.MapProperty');
goog.require('ol3.Object');
goog.require('ol3.Projection');
goog.require('ol3.TransformFunction');
/**
* @constructor
* @extends {ol3.Control}
* @param {ol3.Map} map Map.
* @param {ol3.Projection=} opt_projection Projection.
* @param {ol3.CoordinateFormatType=} opt_coordinateFormat Coordinate format.
* @param {string=} opt_undefinedHTML Undefined HTML.
*/
ol3.control.MousePosition =
function(map, opt_projection, opt_coordinateFormat, opt_undefinedHTML) {
goog.base(this, map);
/**
* @private
* @type {Element}
*/
this.divElement_ = goog.dom.createElement(goog.dom.TagName.DIV);
/**
* @private
* @type {ol3.Projection}
*/
this.projection_ = opt_projection || null;
/**
* @private
* @type {ol3.CoordinateFormatType|undefined}
*/
this.coordinateFormat_ = opt_coordinateFormat;
/**
* @private
* @type {string}
*/
this.undefinedHTML_ = opt_undefinedHTML || '';
/**
* @private
* @type {ol3.TransformFunction}
*/
this.transform_ = ol3.Projection.identityTransform;
goog.events.listen(map,
ol3.Object.getChangedEventType(ol3.MapProperty.PROJECTION),
this.handleMapProjectionChanged, false, this);
goog.events.listen(map.getViewport(), goog.events.EventType.MOUSEMOVE,
this.handleMouseMove, false, this);
goog.events.listen(map.getViewport(), goog.events.EventType.MOUSEOUT,
this.handleMouseOut, false, this);
this.handleMapProjectionChanged();
};
goog.inherits(ol3.control.MousePosition, ol3.Control);
/**
* @inheritDoc
*/
ol3.control.MousePosition.prototype.getElement = function() {
return this.divElement_;
};
/**
* @protected
*/
ol3.control.MousePosition.prototype.handleMapProjectionChanged = function() {
var map = this.getMap();
var mapProjection = map.getProjection();
if (!goog.isDef(mapProjection) || goog.isNull(this.projection_)) {
this.transform_ = ol3.Projection.identityTransform;
} else {
this.transform_ =
ol3.Projection.getTransform(mapProjection, this.projection_);
}
// FIXME should we instead re-calculate using the last known mouse position?
this.divElement_.innerHTML = this.undefinedHTML_;
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @protected
*/
ol3.control.MousePosition.prototype.handleMouseMove = function(browserEvent) {
var map = this.getMap();
var pixel = new ol3.Pixel(browserEvent.offsetX, browserEvent.offsetY);
var coordinate = map.getCoordinateFromPixel(pixel);
var html;
if (goog.isDef(coordinate)) {
coordinate = this.transform_(coordinate);
if (goog.isDef(this.coordinateFormat_)) {
html = this.coordinateFormat_(coordinate);
} else {
html = coordinate.toString();
}
} else {
html = this.undefinedHTML_;
}
this.divElement_.innerHTML = html;
};
/**
* @param {goog.events.BrowserEvent} browserEvent Browser event.
* @protected
*/
ol3.control.MousePosition.prototype.handleMouseOut = function(browserEvent) {
this.divElement_.innerHTML = this.undefinedHTML_;
};

9
src/ol3/dom/dom.js Normal file
View File

@@ -0,0 +1,9 @@
goog.provide('ol3.dom');
goog.require('goog.functions');
/**
* @return {boolean} Is supported.
*/
ol3.dom.isSupported = goog.functions.TRUE;

View File

@@ -0,0 +1,84 @@
goog.provide('ol3.dom.LayerRenderer');
goog.require('ol3.Coordinate');
goog.require('ol3.LayerRenderer');
/**
* @constructor
* @extends {ol3.LayerRenderer}
* @param {ol3.MapRenderer} mapRenderer Map renderer.
* @param {ol3.Layer} layer Layer.
* @param {!Element} target Target.
*/
ol3.dom.LayerRenderer = function(mapRenderer, layer, target) {
goog.base(this, mapRenderer, layer);
/**
* @type {!Element}
* @protected
*/
this.target = target;
/**
* Top left corner of the target in map coords.
*
* @type {ol3.Coordinate}
* @protected
*/
this.origin = null;
this.handleLayerOpacityChange();
this.handleLayerVisibleChange();
};
goog.inherits(ol3.dom.LayerRenderer, ol3.LayerRenderer);
/**
* @override
* @return {ol3.MapRenderer} Map renderer.
*/
ol3.dom.LayerRenderer.prototype.getMapRenderer = function() {
return /** @type {ol3.dom.MapRenderer} */ goog.base(this, 'getMapRenderer');
};
/**
* @inheritDoc
*/
ol3.dom.LayerRenderer.prototype.handleLayerLoad = function() {
this.getMap().render();
};
/**
* @inheritDoc
*/
ol3.dom.LayerRenderer.prototype.handleLayerOpacityChange = function() {
goog.style.setOpacity(this.target, this.getLayer().getOpacity());
};
/**
* @inheritDoc
*/
ol3.dom.LayerRenderer.prototype.handleLayerVisibleChange = function() {
goog.style.showElement(this.target, this.getLayer().getVisible());
};
/**
*/
ol3.dom.LayerRenderer.prototype.render = goog.abstractMethod;
/**
* Set the location of the top left corner of the target.
*
* @param {ol3.Coordinate} origin Origin.
*/
ol3.dom.LayerRenderer.prototype.setOrigin = function(origin) {
this.origin = origin;
};

169
src/ol3/dom/maprenderer.js Normal file
View File

@@ -0,0 +1,169 @@
goog.provide('ol3.dom.MapRenderer');
goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.style');
goog.require('ol3.Coordinate');
goog.require('ol3.Map');
goog.require('ol3.MapRenderer');
goog.require('ol3.TileLayer');
goog.require('ol3.dom.TileLayerRenderer');
/**
* @constructor
* @extends {ol3.MapRenderer}
* @param {Element} container Container.
* @param {ol3.Map} map Map.
*/
ol3.dom.MapRenderer = function(container, map) {
goog.base(this, container, map);
/**
* @type {!Element}
* @private
*/
this.layersPane_ = goog.dom.createElement(goog.dom.TagName.DIV);
this.layersPane_.className = 'ol-layers-pane';
this.layersPane_.style.position = 'absolute';
goog.dom.appendChild(container, this.layersPane_);
/**
* @type {Object}
* @private
*/
this.layerPanes_ = {};
/**
* @type {ol3.Coordinate|undefined}
* @private
*/
this.renderedCenter_ = undefined;
/**
* The pixel offset of the layers pane with respect to its container.
*
* @type {ol3.Coordinate}
* @private
*/
this.layersPaneOffset_ = null;
};
goog.inherits(ol3.dom.MapRenderer, ol3.MapRenderer);
/**
* @inheritDoc
*/
ol3.dom.MapRenderer.prototype.createLayerRenderer = function(layer) {
if (layer instanceof ol3.TileLayer) {
var layerPane = goog.dom.createElement(goog.dom.TagName.DIV);
layerPane.className = 'ol-layer';
layerPane.style.position = 'absolute';
goog.dom.appendChild(this.layersPane_, layerPane);
var layerRenderer = new ol3.dom.TileLayerRenderer(this, layer, layerPane);
this.layerPanes_[goog.getUid(layerRenderer)] = layerPane;
return layerRenderer;
} else {
goog.asserts.assert(false);
return null;
}
};
/**
* @inheritDoc
*/
ol3.dom.MapRenderer.prototype.handleCenterChanged = function() {
goog.base(this, 'handleCenterChanged');
var map = this.getMap();
if (!map.isDef()) {
return;
}
// FIXME: shiftLayersPane_ and resetLayersPane_ should be called
// elsewhere as we may be frozen here
if (goog.isDef(this.renderedCenter_)) {
this.shiftLayersPane_();
} else {
this.resetLayersPane_();
}
map.render();
};
/**
* @inheritDoc
*/
ol3.dom.MapRenderer.prototype.handleResolutionChanged = function() {
goog.base(this, 'handleResolutionChanged');
var map = this.getMap();
if (!map.isDef()) {
return;
}
// FIXME: resetLayersPane_ should be called
// elsewhere as we may be frozen here
this.resetLayersPane_();
map.render();
};
/**
* Reset the layers pane to its initial position.
* @private
*/
ol3.dom.MapRenderer.prototype.resetLayersPane_ = function() {
var offset = new ol3.Coordinate(0, 0);
goog.style.setPosition(this.layersPane_, offset);
this.layersPaneOffset_ = offset;
this.renderedCenter_ = this.map.getCenter();
this.setOrigin_();
};
/**
* Set the origin for each layer renderer.
* @private
*/
ol3.dom.MapRenderer.prototype.setOrigin_ = function() {
var center = this.map.getCenter();
var resolution = this.map.getResolution();
var targetSize = this.map.getSize();
var targetWidth = targetSize.width;
var targetHeight = targetSize.height;
var origin = new ol3.Coordinate(
center.x - resolution * targetWidth / 2,
center.y + resolution * targetHeight / 2);
goog.object.forEach(this.layerRenderers, function(layerRenderer) {
layerRenderer.setOrigin(origin);
});
};
/**
* Move the layers pane.
* @private
*/
ol3.dom.MapRenderer.prototype.shiftLayersPane_ = function() {
var center = this.map.getCenter();
var oldCenter = this.renderedCenter_;
var resolution = this.map.getResolution();
var dx = Math.round((oldCenter.x - center.x) / resolution);
var dy = Math.round((center.y - oldCenter.y) / resolution);
if (!(dx === 0 && dy === 0)) {
var offset = this.layersPaneOffset_;
offset.x += Math.round((oldCenter.x - center.x) / resolution);
offset.y += Math.round((center.y - oldCenter.y) / resolution);
goog.style.setPosition(this.layersPane_, offset);
this.renderedCenter_ = center;
}
};

View File

@@ -0,0 +1,148 @@
goog.provide('ol3.dom.TileLayerRenderer');
goog.require('goog.dom');
goog.require('ol3.Coordinate');
goog.require('ol3.Extent');
goog.require('ol3.dom.LayerRenderer');
/**
* @constructor
* @extends {ol3.dom.LayerRenderer}
* @param {ol3.MapRenderer} mapRenderer Map renderer.
* @param {ol3.TileLayer} tileLayer Tile layer.
* @param {!Element} target Target.
*/
ol3.dom.TileLayerRenderer = function(mapRenderer, tileLayer, target) {
goog.base(this, mapRenderer, tileLayer, target);
/**
* @type {Object}
* @private
*/
this.renderedTiles_ = {};
/**
* @type {number|undefined}
* @private
*/
this.renderedMapResolution_ = undefined;
};
goog.inherits(ol3.dom.TileLayerRenderer, ol3.dom.LayerRenderer);
/**
* @override
* @return {ol3.TileLayer} Layer.
*/
ol3.dom.TileLayerRenderer.prototype.getLayer = function() {
return /** @type {ol3.TileLayer} */ goog.base(this, 'getLayer');
};
/**
* Get the pixel offset between the tile origin and the container origin.
* @private
* @param {number} z Z.
* @param {number} resolution Resolution.
* @return {ol3.Coordinate} Offset.
*/
ol3.dom.TileLayerRenderer.prototype.getTileOffset_ = function(z, resolution) {
var tileLayer = this.getLayer();
var tileStore = tileLayer.getStore();
var tileGrid = tileStore.getTileGrid();
var tileOrigin = tileGrid.getOrigin(z);
var offset = new ol3.Coordinate(
Math.round((this.origin.x - tileOrigin.x) / resolution),
Math.round((tileOrigin.y - this.origin.y) / resolution));
return offset;
};
/**
* Get rid of tiles outside the rendered extent.
* @private
* @param {ol3.TileBounds} tileBounds Tile bounds.
* @param {number} z Z.
*/
ol3.dom.TileLayerRenderer.prototype.removeInvisibleTiles_ = function(
tileBounds, z) {
var key, tileCoord, prune, tile;
for (key in this.renderedTiles_) {
tileCoord = ol3.TileCoord.createFromString(key);
prune = z !== tileCoord.z ||
tileCoord.x < tileBounds.minX ||
tileCoord.x > tileBounds.maxX ||
tileCoord.y < tileBounds.minY ||
tileCoord.y > tileBounds.maxY;
if (prune) {
tile = this.renderedTiles_[key];
delete this.renderedTiles_[key];
goog.dom.removeNode(tile.getImage(this));
}
}
};
/**
* @inheritDoc
*/
ol3.dom.TileLayerRenderer.prototype.render = function() {
var map = this.getMap();
if (!map.isDef()) {
return;
}
var mapExtent = /** @type {!ol3.Extent} */ map.getExtent();
var mapResolution = /** @type {number} */ map.getResolution();
var tileLayer = this.getLayer();
var tileStore = tileLayer.getStore();
var tileGrid = tileStore.getTileGrid();
if (mapResolution != this.renderedMapResolution_) {
this.renderedTiles_ = {};
goog.dom.removeChildren(this.target);
}
// z represents the "best" resolution
var z = tileGrid.getZForResolution(mapResolution);
var tileBounds =
tileGrid.getTileBoundsForExtentAndResolution(mapExtent, mapResolution);
var tileOffset = this.getTileOffset_(z, mapResolution);
var fragment = document.createDocumentFragment();
var key, tile, pixelBounds, img, newTiles = false;
tileBounds.forEachTileCoord(z, function(tileCoord) {
key = tileCoord.toString();
tile = this.renderedTiles_[key];
if (!goog.isDef(tile)) {
tile = tileStore.getTile(tileCoord);
if (goog.isNull(tile)) {
} else {
tile.load();
this.renderedTiles_[key] = tile;
pixelBounds = tileGrid.getPixelBoundsForTileCoordAndResolution(
tileCoord, mapResolution);
img = tile.getImage(this);
img.style.position = 'absolute';
img.style.left = (pixelBounds.minX - tileOffset.x) + 'px';
img.style.top = (-pixelBounds.maxY - tileOffset.y) + 'px';
img.style.width = pixelBounds.getWidth() + 'px';
img.style.height = pixelBounds.getHeight() + 'px';
goog.dom.appendChild(fragment, img);
newTiles = true;
}
}
}, this);
if (newTiles) {
goog.dom.appendChild(this.target, fragment);
}
this.removeInvisibleTiles_(tileBounds, z);
this.renderedMapResolution_ = mapResolution;
};

View File

@@ -0,0 +1,60 @@
goog.provide('ol3.interaction.AltDragRotate');
goog.require('ol3.MapBrowserEvent');
goog.require('ol3.interaction.Drag');
/**
* @constructor
* @extends {ol3.interaction.Drag}
* @param {ol3.interaction.Constraints} constraints Constraints.
*/
ol3.interaction.AltDragRotate = function(constraints) {
goog.base(this, constraints);
/**
* @private
* @type {number}
*/
this.startRotation_ = 0;
};
goog.inherits(ol3.interaction.AltDragRotate, ol3.interaction.Drag);
/**
* @inheritDoc
*/
ol3.interaction.AltDragRotate.prototype.handleDrag = function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
var map = mapBrowserEvent.map;
var size = map.getSize();
var theta = Math.atan2(
size.height / 2 - browserEvent.offsetY,
browserEvent.offsetX - size.width / 2);
this.rotate(map, this.startRotation_, -theta);
};
/**
* @inheritDoc
*/
ol3.interaction.AltDragRotate.prototype.handleDragStart =
function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
var map = mapBrowserEvent.map;
if (browserEvent.isMouseActionButton() && browserEvent.altKey &&
map.canRotate()) {
var size = map.getSize();
var theta = Math.atan2(
size.height / 2 - browserEvent.offsetY,
browserEvent.offsetX - size.width / 2);
this.startRotation_ = (map.getRotation() || 0) + theta;
browserEvent.preventDefault();
return true;
} else {
return false;
}
};

View File

@@ -0,0 +1,47 @@
goog.provide('ol3.interaction.CenterConstraint');
goog.provide('ol3.interaction.CenterConstraintType');
goog.require('ol3.Coordinate');
/**
* @typedef {function((ol3.Coordinate|undefined),
* (number|undefined),
* ol3.Coordinate): (ol3.Coordinate|undefined)}
*/
ol3.interaction.CenterConstraintType;
/**
* @param {ol3.Coordinate|undefined} center Center.
* @param {number|undefined} resolution Resolution.
* @param {ol3.Coordinate} delta Delta.
* @return {ol3.Coordinate|undefined} Center.
*/
ol3.interaction.CenterConstraint.none = function(center, resolution, delta) {
if (goog.isDefAndNotNull(center) && goog.isDef(resolution)) {
var x = center.x + delta.x;
var y = center.y + delta.y;
return new ol3.Coordinate(x, y);
} else {
return undefined;
}
};
/**
* @param {ol3.Coordinate|undefined} center Center.
* @param {number|undefined} resolution Resolution.
* @param {ol3.Coordinate} delta Delta.
* @return {ol3.Coordinate|undefined} Center.
*/
ol3.interaction.CenterConstraint.snapToPixel =
function(center, resolution, delta) {
if (goog.isDefAndNotNull(center) && goog.isDef(resolution)) {
var x = Math.floor((center.x + delta.x) / resolution + 0.5) * resolution;
var y = Math.floor((center.y + delta.y) / resolution + 0.5) * resolution;
return new ol3.Coordinate(x, y);
} else {
return undefined;
}
};

View File

@@ -0,0 +1,36 @@
goog.provide('ol3.interaction.Constraints');
goog.require('ol3.interaction.CenterConstraintType');
goog.require('ol3.interaction.ResolutionConstraintType');
goog.require('ol3.interaction.RotationConstraintType');
/**
* @constructor
* @param {ol3.interaction.CenterConstraintType} centerConstraint
* Center constraint.
* @param {ol3.interaction.ResolutionConstraintType} resolutionConstraint
* Resolution constraint.
* @param {ol3.interaction.RotationConstraintType} rotationConstraint
* Rotation constraint.
*/
ol3.interaction.Constraints =
function(centerConstraint, resolutionConstraint, rotationConstraint) {
/**
* @type {ol3.interaction.CenterConstraintType}
*/
this.center = centerConstraint;
/**
* @type {ol3.interaction.ResolutionConstraintType}
*/
this.resolution = resolutionConstraint;
/**
* @type {ol3.interaction.RotationConstraintType}
*/
this.rotation = rotationConstraint;
};

View File

@@ -0,0 +1,36 @@
goog.provide('ol3.interaction.DblClickZoom');
goog.require('goog.events.EventType');
goog.require('ol3.Interaction');
goog.require('ol3.MapBrowserEvent');
goog.require('ol3.interaction.Constraints');
/**
* @constructor
* @extends {ol3.Interaction}
* @param {ol3.interaction.Constraints} constraints Constraints.
*/
ol3.interaction.DblClickZoom = function(constraints) {
goog.base(this, constraints);
};
goog.inherits(ol3.interaction.DblClickZoom, ol3.Interaction);
/**
* @inheritDoc
*/
ol3.interaction.DblClickZoom.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
if (browserEvent.type == goog.events.EventType.DBLCLICK &&
browserEvent.isMouseActionButton()) {
var map = mapBrowserEvent.map;
var resolution = map.getResolution();
var delta = mapBrowserEvent.browserEvent.shiftKey ? -1 : 1;
var anchor = mapBrowserEvent.getCoordinate();
this.zoom(map, resolution, delta, anchor);
mapBrowserEvent.preventDefault();
}
};

122
src/ol3/interaction/drag.js Normal file
View File

@@ -0,0 +1,122 @@
goog.provide('ol3.interaction.Drag');
goog.require('goog.asserts');
goog.require('goog.events.EventType');
goog.require('goog.functions');
goog.require('ol3.Coordinate');
goog.require('ol3.Interaction');
goog.require('ol3.MapBrowserEvent');
goog.require('ol3.interaction.Constraints');
/**
* @constructor
* @extends {ol3.Interaction}
* @param {ol3.interaction.Constraints} constraints Constraints.
*/
ol3.interaction.Drag = function(constraints) {
goog.base(this, constraints);
/**
* @private
* @type {boolean}
*/
this.dragging_ = false;
/**
* @type {number}
*/
this.startX = 0;
/**
* @type {number}
*/
this.startY = 0;
/**
* @type {number}
*/
this.offsetX = 0;
/**
* @type {number}
*/
this.offsetY = 0;
/**
* @type {ol3.Coordinate}
*/
this.startCenter = null;
/**
* @type {ol3.Coordinate}
*/
this.startCoordinate = null;
};
goog.inherits(ol3.interaction.Drag, ol3.Interaction);
/**
* @param {ol3.MapBrowserEvent} mapBrowserEvent Event.
* @protected
*/
ol3.interaction.Drag.prototype.handleDrag = goog.nullFunction;
/**
* @param {ol3.MapBrowserEvent} mapBrowserEvent Event.
* @protected
*/
ol3.interaction.Drag.prototype.handleDragEnd = goog.nullFunction;
/**
* @param {ol3.MapBrowserEvent} mapBrowserEvent Event.
* @protected
* @return {boolean} Capture dragging.
*/
ol3.interaction.Drag.prototype.handleDragStart = goog.functions.FALSE;
/**
* @inheritDoc
*/
ol3.interaction.Drag.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
var map = mapBrowserEvent.map;
if (!map.isDef()) {
return;
}
var browserEvent = mapBrowserEvent.browserEvent;
if (this.dragging_) {
if (mapBrowserEvent.type == goog.fx.Dragger.EventType.DRAG) {
goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
this.deltaX = browserEvent.clientX - this.startX;
this.deltaY = browserEvent.clientY - this.startY;
this.handleDrag(mapBrowserEvent);
} else if (mapBrowserEvent.type == goog.fx.Dragger.EventType.END) {
goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
this.deltaX = browserEvent.clientX - this.startX;
this.deltaY = browserEvent.clientY - this.startY;
this.handleDragEnd(mapBrowserEvent);
this.dragging_ = false;
}
} else if (mapBrowserEvent.type == goog.fx.Dragger.EventType.START) {
goog.asserts.assert(browserEvent instanceof goog.events.BrowserEvent);
this.startX = browserEvent.clientX;
this.startY = browserEvent.clientY;
this.deltaX = 0;
this.deltaY = 0;
this.startCenter = /** @type {!ol3.Coordinate} */ map.getCenter();
this.startCoordinate = /** @type {ol3.Coordinate} */
mapBrowserEvent.getCoordinate();
if (this.handleDragStart(mapBrowserEvent)) {
this.dragging_ = true;
mapBrowserEvent.preventDefault();
}
}
};

View File

@@ -0,0 +1,48 @@
goog.provide('ol3.interaction.DragPan');
goog.require('ol3.Coordinate');
goog.require('ol3.MapBrowserEvent');
goog.require('ol3.interaction.Constraints');
goog.require('ol3.interaction.Drag');
/**
* @constructor
* @extends {ol3.interaction.Drag}
* @param {ol3.interaction.Constraints} constraints Constraints.
*/
ol3.interaction.DragPan = function(constraints) {
goog.base(this, constraints);
};
goog.inherits(ol3.interaction.DragPan, ol3.interaction.Drag);
/**
* @inheritDoc
*/
ol3.interaction.DragPan.prototype.handleDrag = function(mapBrowserEvent) {
var map = mapBrowserEvent.map;
var resolution = map.getResolution();
var rotation = map.getRotation();
var delta =
new ol3.Coordinate(-resolution * this.deltaX, resolution * this.deltaY);
if (map.canRotate() && goog.isDef(rotation)) {
delta.rotate(rotation);
}
this.pan(map, delta, this.startCenter);
};
/**
* @inheritDoc
*/
ol3.interaction.DragPan.prototype.handleDragStart = function(mapBrowserEvent) {
var browserEvent = mapBrowserEvent.browserEvent;
if (!browserEvent.shiftKey) {
browserEvent.preventDefault();
return true;
} else {
return false;
}
};

View File

@@ -0,0 +1,107 @@
// FIXME factor out key precondition (shift et. al)
goog.provide('ol3.Interaction');
goog.require('ol3.MapBrowserEvent');
goog.require('ol3.interaction.Constraints');
/**
* @constructor
* @param {ol3.interaction.Constraints} constraints Constraints.
*/
ol3.Interaction = function(constraints) {
/**
* @protected
* @type {ol3.interaction.Constraints}
*/
this.constraints = constraints;
};
/**
* @param {ol3.Map} map Map.
* @param {ol3.Extent} extent Extent.
*/
ol3.Interaction.prototype.fitExtent = function(map, extent) {
var resolution = map.getResolutionForExtent(extent);
resolution = this.constraints.resolution(resolution, 0);
var center = extent.getCenter();
center = this.constraints.center(center, resolution, ol3.Coordinate.ZERO);
map.withFrozenRendering(function() {
map.setCenter(center);
map.setResolution(resolution);
});
};
/**
* @param {ol3.MapBrowserEvent} mapBrowserEvent Map browser event.
*/
ol3.Interaction.prototype.handleMapBrowserEvent = goog.abstractMethod;
/**
* @param {ol3.Map} map Map.
* @param {ol3.Coordinate} delta Delta.
* @param {ol3.Coordinate=} opt_anchor Anchor.
*/
ol3.Interaction.prototype.pan = function(map, delta, opt_anchor) {
var center = opt_anchor ? opt_anchor : map.getCenter();
var resolution = map.getResolution();
center = this.constraints.center(center, resolution, delta);
map.setCenter(center);
};
/**
* @param {ol3.Map} map Map.
* @param {number|undefined} rotation Rotation.
* @param {number} delta Delta.
* @param {ol3.Coordinate=} opt_anchor Anchor.
*/
ol3.Interaction.prototype.rotate = function(map, rotation, delta, opt_anchor) {
// FIXME handle rotation about anchor
rotation = this.constraints.rotation(rotation, delta);
map.setRotation(rotation);
};
/**
* @param {ol3.Map} map Map.
* @param {number|undefined} resolution Resolution.
*/
ol3.Interaction.prototype.setResolution = function(map, resolution) {
resolution = this.constraints.resolution(resolution, 0);
map.setResolution(resolution);
};
/**
* @param {ol3.Map} map Map.
* @param {number|undefined} resolution Resolution.
* @param {number} delta Delta.
* @param {ol3.Coordinate=} opt_anchor Anchor.
*/
ol3.Interaction.prototype.zoom = function(map, resolution, delta, opt_anchor) {
if (goog.isDefAndNotNull(opt_anchor)) {
var anchor = opt_anchor;
var mapCenter = /** @type {!ol3.Coordinate} */ map.getCenter();
var mapResolution = map.getResolution();
resolution = this.constraints.resolution(resolution, delta);
var x = anchor.x - resolution * (anchor.x - mapCenter.x) / mapResolution;
var y = anchor.y - resolution * (anchor.y - mapCenter.y) / mapResolution;
var center = new ol3.Coordinate(x, y);
center = this.constraints.center(center, resolution, ol3.Coordinate.ZERO);
map.withFrozenRendering(function() {
map.setCenter(center);
map.setResolution(resolution);
});
} else {
resolution = this.constraints.resolution(resolution, delta);
map.setResolution(resolution);
}
};

View File

@@ -0,0 +1,53 @@
// FIXME this class is ugly and should be removed
goog.provide('ol3.interaction.Keyboard');
goog.require('ol3.Interaction');
/**
* @constructor
* @extends {ol3.Interaction}
*/
ol3.interaction.Keyboard = function() {
goog.base(this, null);
/**
* @private
* @type {Object.<number, Function>}
*/
this.charCodeCallbacks_ = {};
};
goog.inherits(ol3.interaction.Keyboard, ol3.Interaction);
/**
* @param {string} s String.
* @param {Function} callback Callback.
*/
ol3.interaction.Keyboard.prototype.addCallback = function(s, callback) {
var i;
for (i = 0; i < s.length; ++i) {
this.charCodeCallbacks_[s.charCodeAt(i)] = callback;
}
};
/**
* @inheritDoc
*/
ol3.interaction.Keyboard.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
if (mapBrowserEvent.type == goog.events.KeyHandler.EventType.KEY) {
var keyEvent = /** @type {goog.events.KeyEvent} */
mapBrowserEvent.browserEvent;
var callback = this.charCodeCallbacks_[keyEvent.charCode];
if (callback) {
callback();
mapBrowserEvent.preventDefault();
}
}
};

View File

@@ -0,0 +1,62 @@
goog.provide('ol3.interaction.KeyboardPan');
goog.require('goog.events.KeyCodes');
goog.require('goog.events.KeyHandler.EventType');
goog.require('ol3.Interaction');
goog.require('ol3.interaction.Constraints');
/**
* @constructor
* @extends {ol3.Interaction}
* @param {ol3.interaction.Constraints} constraints Constraints.
* @param {number} pixelDelta Pixel delta.
*/
ol3.interaction.KeyboardPan = function(constraints, pixelDelta) {
goog.base(this, constraints);
/**
* @private
* @type {number}
*/
this.pixelDelta_ = pixelDelta;
};
goog.inherits(ol3.interaction.KeyboardPan, ol3.Interaction);
/**
* @inheritDoc
*/
ol3.interaction.KeyboardPan.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
if (mapBrowserEvent.type == goog.events.KeyHandler.EventType.KEY) {
var keyEvent = /** @type {goog.events.KeyEvent} */
mapBrowserEvent.browserEvent;
var keyCode = keyEvent.keyCode;
if (keyCode == goog.events.KeyCodes.DOWN ||
keyCode == goog.events.KeyCodes.LEFT ||
keyCode == goog.events.KeyCodes.RIGHT ||
keyCode == goog.events.KeyCodes.UP) {
var map = mapBrowserEvent.map;
var resolution = map.getResolution();
var delta;
var mapUnitsDelta = resolution * this.pixelDelta_;
if (keyCode == goog.events.KeyCodes.DOWN) {
delta = new ol3.Coordinate(0, -mapUnitsDelta);
} else if (keyCode == goog.events.KeyCodes.LEFT) {
delta = new ol3.Coordinate(-mapUnitsDelta, 0);
} else if (keyCode == goog.events.KeyCodes.RIGHT) {
delta = new ol3.Coordinate(mapUnitsDelta, 0);
} else {
goog.asserts.assert(keyCode == goog.events.KeyCodes.UP);
delta = new ol3.Coordinate(0, mapUnitsDelta);
}
this.pan(map, delta);
keyEvent.preventDefault();
mapBrowserEvent.preventDefault();
}
}
};

View File

@@ -0,0 +1,39 @@
goog.provide('ol3.interaction.KeyboardZoom');
goog.require('goog.events.KeyCodes');
goog.require('goog.events.KeyHandler.EventType');
goog.require('ol3.Interaction');
goog.require('ol3.interaction.ResolutionConstraintType');
/**
* @constructor
* @extends {ol3.Interaction}
* @param {ol3.interaction.Constraints} constraints Constraints.
*/
ol3.interaction.KeyboardZoom = function(constraints) {
goog.base(this, constraints);
};
goog.inherits(ol3.interaction.KeyboardZoom, ol3.Interaction);
/**
* @inheritDoc
*/
ol3.interaction.KeyboardZoom.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
if (mapBrowserEvent.type == goog.events.KeyHandler.EventType.KEY) {
var keyEvent = /** @type {goog.events.KeyEvent} */
mapBrowserEvent.browserEvent;
var charCode = keyEvent.charCode;
if (charCode == '+'.charCodeAt(0) || charCode == '-'.charCodeAt(0)) {
var map = mapBrowserEvent.map;
var resolution = map.getResolution();
var delta = charCode == '+'.charCodeAt(0) ? 1 : -1;
this.zoom(map, resolution, delta);
keyEvent.preventDefault();
mapBrowserEvent.preventDefault();
}
}
};

View File

@@ -0,0 +1,41 @@
goog.provide('ol3.interaction.MouseWheelZoom');
goog.require('goog.events.MouseWheelEvent');
goog.require('goog.events.MouseWheelHandler.EventType');
goog.require('ol3.MapBrowserEvent');
goog.require('ol3.interaction.Constraints');
/**
* @constructor
* @extends {ol3.Interaction}
* @param {ol3.interaction.Constraints} constraints Constraints.
*/
ol3.interaction.MouseWheelZoom = function(constraints) {
goog.base(this, constraints);
};
goog.inherits(ol3.interaction.MouseWheelZoom, ol3.Interaction);
/**
* @inheritDoc
*/
ol3.interaction.MouseWheelZoom.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) {
if (mapBrowserEvent.type ==
goog.events.MouseWheelHandler.EventType.MOUSEWHEEL) {
var map = mapBrowserEvent.map;
var mouseWheelEvent = /** @type {goog.events.MouseWheelEvent} */
mapBrowserEvent.browserEvent;
goog.asserts.assert(mouseWheelEvent instanceof goog.events.MouseWheelEvent);
if (mouseWheelEvent.deltaY !== 0) {
var delta = mouseWheelEvent.deltaY < 0 ? 1 : -1;
var resolution = map.getResolution();
var anchor = mapBrowserEvent.getCoordinate();
this.zoom(map, resolution, delta, anchor);
mapBrowserEvent.preventDefault();
mouseWheelEvent.preventDefault();
}
}
};

Some files were not shown because too many files have changed in this diff Show More