Allow geometries to use a shared vertex array

The ol.geom.SharedVertices structure represents a flattened array of vertex coordinates.  This is intended to support optimal WebGL rendering.
This commit is contained in:
Tim Schaub
2013-03-02 18:39:24 +01:00
parent bdfa2cc88c
commit b52d283641
23 changed files with 1086 additions and 217 deletions

View File

@@ -0,0 +1,79 @@
goog.provide('ol.geom.AbstractCollection');
goog.require('ol.Extent');
goog.require('ol.geom.Geometry');
/**
* A collection of geometries. This constructor is not to be used directly.
*
* @constructor
* @extends {ol.geom.Geometry}
*/
ol.geom.AbstractCollection = function() {
goog.base(this);
/**
* @type {number}
*/
this.dimension;
/**
* @type {Array.<ol.geom.Geometry>}
*/
this.components = null;
/**
* @type {ol.Extent}
* @protected
*/
this.bounds = null;
};
goog.inherits(ol.geom.AbstractCollection, ol.geom.Geometry);
/**
* @inheritDoc
*/
ol.geom.AbstractCollection.prototype.getBounds = function() {
if (goog.isNull(this.bounds)) {
var minX,
minY = minX = Number.POSITIVE_INFINITY,
maxX,
maxY = maxX = Number.NEGATIVE_INFINITY,
components = this.components,
len = components.length,
bounds, i;
for (i = 0; i < len; ++i) {
bounds = components[i].getBounds();
minX = Math.min(bounds.minX, minX);
minY = Math.min(bounds.minY, minY);
maxX = Math.max(bounds.maxX, maxX);
maxY = Math.max(bounds.maxY, maxY);
}
this.bounds = new ol.Extent(minX, minY, maxX, maxY);
}
return this.bounds;
};
/**
* @inheritDoc
*/
ol.geom.AbstractCollection.prototype.getCoordinates = function() {
var count = this.components.length;
var coordinates = new Array(count);
for (var i = 0; i < count; ++i) {
coordinates[i] = this.components[i].getCoordinates();
}
return coordinates;
};
/**
* @inheritDoc
*/
ol.geom.AbstractCollection.prototype.getType = goog.abstractMethod;

14
src/ol/geom/base.js Normal file
View File

@@ -0,0 +1,14 @@
goog.provide('ol.geom.Vertex');
goog.provide('ol.geom.VertexArray');
/**
* @typedef {Array.<number>}
*/
ol.geom.Vertex;
/**
* @typedef {Array.<ol.geom.Vertex>}
*/
ol.geom.VertexArray;

View File

@@ -1,15 +1,23 @@
goog.require('ol.Extent');
goog.provide('ol.geom.Coordinate');
goog.provide('ol.geom.CoordinateArray');
goog.provide('ol.geom.Geometry'); goog.provide('ol.geom.Geometry');
goog.provide('ol.geom.GeometryType'); goog.provide('ol.geom.GeometryType');
goog.require('ol.Extent');
goog.require('ol.geom.SharedVertices');
/** /**
* @constructor * @constructor
*/ */
ol.geom.Geometry = function() {}; ol.geom.Geometry = function() {
/**
* @type {ol.geom.SharedVertices}
* @protected
*/
this.vertices = null;
};
/** /**
@@ -26,6 +34,21 @@ ol.geom.Geometry.prototype.dimension;
ol.geom.Geometry.prototype.getBounds = goog.abstractMethod; ol.geom.Geometry.prototype.getBounds = goog.abstractMethod;
/**
* @return {Array} The GeoJSON style coordinates array for the geometry.
*/
ol.geom.Geometry.prototype.getCoordinates = goog.abstractMethod;
/**
* Get the shared vertices for this geometry.
* @return {ol.geom.SharedVertices} The shared vertices.
*/
ol.geom.Geometry.prototype.getSharedVertices = function() {
return this.vertices;
};
/** /**
* Get the geometry type. * Get the geometry type.
* @return {ol.geom.GeometryType} The geometry type. * @return {ol.geom.GeometryType} The geometry type.
@@ -33,18 +56,6 @@ ol.geom.Geometry.prototype.getBounds = goog.abstractMethod;
ol.geom.Geometry.prototype.getType = goog.abstractMethod; ol.geom.Geometry.prototype.getType = goog.abstractMethod;
/**
* @typedef {Array.<number>}
*/
ol.geom.Coordinate;
/**
* @typedef {Array.<ol.geom.Coordinate>}
*/
ol.geom.CoordinateArray;
/** /**
* @enum {string} * @enum {string}
*/ */

View File

@@ -1,65 +1,43 @@
goog.provide('ol.geom.GeometryCollection'); goog.provide('ol.geom.GeometryCollection');
goog.require('ol.Extent'); goog.require('ol.geom.AbstractCollection');
goog.require('ol.geom.Geometry'); goog.require('ol.geom.Geometry');
goog.require('ol.geom.GeometryType'); goog.require('ol.geom.GeometryType');
/** /**
* A collection of geometries. This constructor should not called. Instead * A mixed collection of geometries. Used one of the fixed type multi-part
* create one of the fixed type collections. * constructors for collections of the same type.
*
* @constructor * @constructor
* @extends {ol.geom.Geometry} * @extends {ol.geom.AbstractCollection}
* @param {Array.<ol.geom.Geometry>} geometries Array of geometries.
*/ */
ol.geom.GeometryCollection = function() { ol.geom.GeometryCollection = function(geometries) {
goog.base(this); goog.base(this);
/** /**
* @type {Array.<ol.geom.Geometry>} * @type {Array.<ol.geom.Geometry>}
*/ */
this.components = null; this.components = geometries;
var dimension = 0;
for (var i = 0, ii = geometries.length; i < ii; ++i) {
if (goog.isDef(dimension)) {
dimension = geometries[i].dimension;
} else {
goog.asserts.assert(dimension == geometries[i].dimension);
}
}
/** /**
* @type {number} * @type {number}
*/ */
this.dimension; this.dimension = dimension;
/**
* @type {ol.Extent}
* @protected
*/
this.bounds = null;
}; };
goog.inherits(ol.geom.GeometryCollection, ol.geom.Geometry); goog.inherits(ol.geom.GeometryCollection, ol.geom.AbstractCollection);
/**
* @inheritDoc
*/
ol.geom.GeometryCollection.prototype.getBounds = function() {
if (goog.isNull(this.bounds)) {
var minX,
minY = minX = Number.POSITIVE_INFINITY,
maxX,
maxY = maxX = Number.NEGATIVE_INFINITY,
components = this.components,
len = components.length,
bounds, i;
for (i = 0; i < len; ++i) {
bounds = components[i].getBounds();
minX = Math.min(bounds.minX, minX);
minY = Math.min(bounds.minY, minY);
maxX = Math.max(bounds.maxX, maxX);
maxY = Math.max(bounds.maxY, maxY);
}
this.bounds = new ol.Extent(minX, minY, maxX, maxY);
}
return this.bounds;
};
/** /**

View File

@@ -1,20 +1,21 @@
goog.provide('ol.geom.LinearRing'); goog.provide('ol.geom.LinearRing');
goog.require('ol.geom.CoordinateArray');
goog.require('ol.geom.GeometryType'); goog.require('ol.geom.GeometryType');
goog.require('ol.geom.LineString'); goog.require('ol.geom.LineString');
goog.require('ol.geom.SharedVertices');
goog.require('ol.geom.VertexArray');
/** /**
* @constructor * @constructor
* @extends {ol.geom.LineString} * @extends {ol.geom.LineString}
* @param {ol.geom.CoordinateArray} coordinates Coordinates array (e.g. * @param {ol.geom.VertexArray} coordinates Vertex array (e.g.
* [[x0, y0], [x1, y1], [x0, y0]]). * [[x0, y0], [x1, y1]]).
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
*/ */
ol.geom.LinearRing = function(coordinates) { ol.geom.LinearRing = function(coordinates, opt_shared) {
goog.base(this, coordinates, opt_shared);
goog.base(this, coordinates);
/** /**
* We're intentionally not enforcing that rings be closed right now. This * We're intentionally not enforcing that rings be closed right now. This
@@ -30,5 +31,5 @@ goog.inherits(ol.geom.LinearRing, ol.geom.LineString);
* @inheritDoc * @inheritDoc
*/ */
ol.geom.LinearRing.prototype.getType = function() { ol.geom.LinearRing.prototype.getType = function() {
return ol.geom.GeometryType.GEOMETRYCOLLECTION; return ol.geom.GeometryType.LINEARRING;
}; };

View File

@@ -2,44 +2,47 @@ goog.provide('ol.geom.LineString');
goog.require('goog.asserts'); goog.require('goog.asserts');
goog.require('ol.Extent'); goog.require('ol.Extent');
goog.require('ol.geom.CoordinateArray');
goog.require('ol.geom.Geometry'); goog.require('ol.geom.Geometry');
goog.require('ol.geom.GeometryType'); goog.require('ol.geom.GeometryType');
goog.require('ol.geom.SharedVertices');
goog.require('ol.geom.VertexArray');
/** /**
* @constructor * @constructor
* @extends {ol.geom.Geometry} * @extends {ol.geom.Geometry}
* @param {ol.geom.CoordinateArray} coordinates Coordinates array (e.g. * @param {ol.geom.VertexArray} coordinates Vertex array (e.g.
* [[x0, y0], [x1, y1]]). * [[x0, y0], [x1, y1]]).
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
*/ */
ol.geom.LineString = function(coordinates) { ol.geom.LineString = function(coordinates, opt_shared) {
goog.base(this); goog.base(this);
goog.asserts.assert(goog.isArray(coordinates[0]));
// assume the same dimension for all coordinates var vertices = opt_shared,
var dimension = coordinates[0].length, dimension;
count = coordinates.length,
length = count * dimension; if (!goog.isDef(vertices)) {
dimension = coordinates[0].length;
vertices = new ol.geom.SharedVertices({dimension: dimension});
}
/** /**
* @type {Array} * @type {ol.geom.SharedVertices}
*/ */
this.coordinates = new Array(length); this.vertices = vertices;
var i, offset, j;
for (i = 0; i < count; ++i) { /**
goog.asserts.assert(coordinates[i].length === dimension); * @type {string}
offset = i * dimension; * @private
for (j = 0; j < dimension; ++j) { */
this.coordinates[offset + j] = coordinates[i][j]; this.sharedId_ = vertices.add(coordinates);
}
}
/** /**
* @type {number} * @type {number}
*/ */
this.dimension = dimension; this.dimension = vertices.getDimension();
goog.asserts.assert(this.dimension >= 2); goog.asserts.assert(this.dimension >= 2);
/** /**
@@ -52,6 +55,45 @@ ol.geom.LineString = function(coordinates) {
goog.inherits(ol.geom.LineString, ol.geom.Geometry); goog.inherits(ol.geom.LineString, ol.geom.Geometry);
/**
* Get a vertex coordinate value for the given dimension.
* @param {number} index Vertex index.
* @param {number} dim Coordinate dimension.
* @return {number} The vertex coordinate value.
*/
ol.geom.LineString.prototype.get = function(index, dim) {
return this.vertices.get(this.sharedId_, index, dim);
};
/**
* @inheritDoc
* @return {ol.geom.VertexArray} Coordinates array.
*/
ol.geom.LineString.prototype.getCoordinates = function() {
var count = this.getCount();
var coordinates = new Array(count);
var vertex;
for (var i = 0; i < count; ++i) {
vertex = new Array(this.dimension);
for (var j = 0; j < this.dimension; ++j) {
vertex[j] = this.get(i, j);
}
coordinates[i] = vertex;
}
return coordinates;
};
/**
* Get the count of vertices in this linestring.
* @return {number} The vertex count.
*/
ol.geom.LineString.prototype.getCount = function() {
return this.vertices.getCount(this.sharedId_);
};
/** /**
* @inheritDoc * @inheritDoc
*/ */
@@ -61,14 +103,15 @@ ol.geom.LineString.prototype.getBounds = function() {
minY = minX = Number.POSITIVE_INFINITY, minY = minX = Number.POSITIVE_INFINITY,
maxX, maxX,
maxY = maxX = Number.NEGATIVE_INFINITY, maxY = maxX = Number.NEGATIVE_INFINITY,
coordinates = this.coordinates, vertices = this.vertices,
len = coordinates.length, id = this.sharedId_,
dim = this.dimension, count = vertices.getCount(id),
dimension = this.dimension,
x, y, i; x, y, i;
for (i = 0; i < len; i += dim) { for (i = 0; i < count; ++i) {
x = coordinates[i]; x = vertices.get(id, i, 0);
y = coordinates[i + 1]; y = vertices.get(id, i, 1);
minX = Math.min(minX, x); minX = Math.min(minX, x);
minY = Math.min(minY, y); minY = Math.min(minY, y);
maxX = Math.max(maxX, x); maxX = Math.max(maxX, x);
@@ -86,3 +129,12 @@ ol.geom.LineString.prototype.getBounds = function() {
ol.geom.LineString.prototype.getType = function() { ol.geom.LineString.prototype.getType = function() {
return ol.geom.GeometryType.LINESTRING; return ol.geom.GeometryType.LINESTRING;
}; };
/**
* Get the identifier used to mark this line in the shared vertices structure.
* @return {string} The identifier.
*/
ol.geom.LineString.prototype.getSharedId = function() {
return this.sharedId_;
};

View File

@@ -1,45 +1,50 @@
goog.provide('ol.geom.MultiLineString'); goog.provide('ol.geom.MultiLineString');
goog.require('goog.asserts'); goog.require('goog.asserts');
goog.require('ol.geom.CoordinateArray'); goog.require('ol.geom.AbstractCollection');
goog.require('ol.geom.GeometryCollection');
goog.require('ol.geom.GeometryType'); goog.require('ol.geom.GeometryType');
goog.require('ol.geom.LineString'); goog.require('ol.geom.LineString');
goog.require('ol.geom.SharedVertices');
goog.require('ol.geom.VertexArray');
/** /**
* @constructor * @constructor
* @extends {ol.geom.GeometryCollection} * @extends {ol.geom.AbstractCollection}
* @param {Array.<ol.geom.CoordinateArray>} coordinates Coordinates array. * @param {Array.<ol.geom.VertexArray>} coordinates Coordinates array.
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
*/ */
ol.geom.MultiLineString = function(coordinates) { ol.geom.MultiLineString = function(coordinates, opt_shared) {
goog.base(this); goog.base(this);
goog.asserts.assert(goog.isArray(coordinates[0][0]));
var numParts = coordinates.length, var vertices = opt_shared,
dimension; dimension;
if (!goog.isDef(vertices)) {
// try to get dimension from first vertex in first line
dimension = coordinates[0][0].length;
vertices = new ol.geom.SharedVertices({dimension: dimension});
}
var numParts = coordinates.length;
/** /**
* @type {Array.<ol.geom.LineString>} * @type {Array.<ol.geom.LineString>}
*/ */
this.components = new Array(numParts); this.components = new Array(numParts);
for (var i = 0; i < numParts; ++i) { for (var i = 0; i < numParts; ++i) {
this.components[i] = new ol.geom.LineString(coordinates[i]); this.components[i] = new ol.geom.LineString(coordinates[i], vertices);
if (!goog.isDef(dimension)) {
dimension = this.components[i].dimension;
} else {
goog.asserts.assert(this.components[i].dimension === dimension);
}
} }
/** /**
* @type {number} * @type {number}
*/ */
this.dimension = dimension; this.dimension = vertices.getDimension();
goog.asserts.assert(this.dimension >= 2);
}; };
goog.inherits(ol.geom.MultiLineString, ol.geom.GeometryCollection); goog.inherits(ol.geom.MultiLineString, ol.geom.AbstractCollection);
/** /**
@@ -48,3 +53,20 @@ goog.inherits(ol.geom.MultiLineString, ol.geom.GeometryCollection);
ol.geom.MultiLineString.prototype.getType = function() { ol.geom.MultiLineString.prototype.getType = function() {
return ol.geom.GeometryType.MULTILINESTRING; return ol.geom.GeometryType.MULTILINESTRING;
}; };
/**
* Create a multi-linestring geometry from an array of linestring geometries.
*
* @param {Array.<ol.geom.LineString>} geometries Array of geometries.
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
* @return {ol.geom.MultiLineString} A new geometry.
*/
ol.geom.MultiLineString.fromParts = function(geometries, opt_shared) {
var count = geometries.length;
var coordinates = new Array(count);
for (var i = 0; i < count; ++i) {
coordinates[i] = geometries[i].getCoordinates();
}
return new ol.geom.MultiLineString(coordinates, opt_shared);
};

View File

@@ -1,45 +1,55 @@
goog.provide('ol.geom.MultiPoint'); goog.provide('ol.geom.MultiPoint');
goog.require('goog.asserts'); goog.require('goog.asserts');
goog.require('ol.geom.CoordinateArray'); goog.require('ol.geom.AbstractCollection');
goog.require('ol.geom.GeometryCollection');
goog.require('ol.geom.GeometryType'); goog.require('ol.geom.GeometryType');
goog.require('ol.geom.Point'); goog.require('ol.geom.Point');
goog.require('ol.geom.SharedVertices');
goog.require('ol.geom.VertexArray');
/** /**
* @constructor * @constructor
* @extends {ol.geom.GeometryCollection} * @extends {ol.geom.AbstractCollection}
* @param {ol.geom.CoordinateArray} coordinates Coordinates array. * @param {ol.geom.VertexArray} coordinates Coordinates array.
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
*/ */
ol.geom.MultiPoint = function(coordinates) { ol.geom.MultiPoint = function(coordinates, opt_shared) {
goog.base(this); goog.base(this);
goog.asserts.assert(goog.isArray(coordinates[0]));
var numParts = coordinates.length, var vertices = opt_shared,
dimension; dimension;
if (!goog.isDef(vertices)) {
// try to get dimension from first vertex
dimension = coordinates[0].length;
vertices = new ol.geom.SharedVertices({dimension: dimension});
}
/**
* @type {ol.geom.SharedVertices}
*/
this.vertices = vertices;
var numParts = coordinates.length;
/** /**
* @type {Array.<ol.geom.Point>} * @type {Array.<ol.geom.Point>}
*/ */
this.components = new Array(numParts); this.components = new Array(numParts);
for (var i = 0; i < numParts; ++i) { for (var i = 0; i < numParts; ++i) {
this.components[i] = new ol.geom.Point(coordinates[i]); this.components[i] = new ol.geom.Point(coordinates[i], vertices);
if (!goog.isDef(dimension)) {
dimension = this.components[i].dimension;
} else {
goog.asserts.assert(this.components[i].dimension === dimension);
}
} }
/** /**
* @type {number} * @type {number}
*/ */
this.dimension = dimension; this.dimension = vertices.getDimension();
goog.asserts.assert(this.dimension >= 2);
}; };
goog.inherits(ol.geom.MultiPoint, ol.geom.GeometryCollection); goog.inherits(ol.geom.MultiPoint, ol.geom.AbstractCollection);
/** /**
@@ -48,3 +58,20 @@ goog.inherits(ol.geom.MultiPoint, ol.geom.GeometryCollection);
ol.geom.MultiPoint.prototype.getType = function() { ol.geom.MultiPoint.prototype.getType = function() {
return ol.geom.GeometryType.MULTIPOINT; return ol.geom.GeometryType.MULTIPOINT;
}; };
/**
* Create a multi-point geometry from an array of point geometries.
*
* @param {Array.<ol.geom.Point>} geometries Array of geometries.
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
* @return {ol.geom.MultiPoint} A new geometry.
*/
ol.geom.MultiPoint.fromParts = function(geometries, opt_shared) {
var count = geometries.length;
var coordinates = new Array(count);
for (var i = 0; i < count; ++i) {
coordinates[i] = geometries[i].getCoordinates();
}
return new ol.geom.MultiPoint(coordinates, opt_shared);
};

View File

@@ -1,46 +1,51 @@
goog.provide('ol.geom.MultiPolygon'); goog.provide('ol.geom.MultiPolygon');
goog.require('goog.asserts'); goog.require('goog.asserts');
goog.require('ol.geom.CoordinateArray'); goog.require('ol.geom.AbstractCollection');
goog.require('ol.geom.GeometryCollection');
goog.require('ol.geom.GeometryType'); goog.require('ol.geom.GeometryType');
goog.require('ol.geom.Polygon'); goog.require('ol.geom.Polygon');
goog.require('ol.geom.SharedVertices');
goog.require('ol.geom.VertexArray');
/** /**
* @constructor * @constructor
* @extends {ol.geom.GeometryCollection} * @extends {ol.geom.AbstractCollection}
* @param {Array.<Array.<ol.geom.CoordinateArray>>} coordinates Coordinates * @param {Array.<Array.<ol.geom.VertexArray>>} coordinates Coordinates
* array. * array.
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
*/ */
ol.geom.MultiPolygon = function(coordinates) { ol.geom.MultiPolygon = function(coordinates, opt_shared) {
goog.base(this); goog.base(this);
goog.asserts.assert(goog.isArray(coordinates[0][0][0]));
var numParts = coordinates.length, var vertices = opt_shared,
dimension; dimension;
if (!goog.isDef(vertices)) {
// try to get dimension from first vertex in first ring of the first poly
dimension = coordinates[0][0][0].length;
vertices = new ol.geom.SharedVertices({dimension: dimension});
}
var numParts = coordinates.length;
/** /**
* @type {Array.<ol.geom.Polygon>} * @type {Array.<ol.geom.Polygon>}
*/ */
this.components = new Array(numParts); this.components = new Array(numParts);
for (var i = 0; i < numParts; ++i) { for (var i = 0; i < numParts; ++i) {
this.components[i] = new ol.geom.Polygon(coordinates[i]); this.components[i] = new ol.geom.Polygon(coordinates[i], vertices);
if (!goog.isDef(dimension)) {
dimension = this.components[i].dimension;
} else {
goog.asserts.assert(this.components[i].dimension === dimension);
}
} }
/** /**
* @type {number} * @type {number}
*/ */
this.dimension = dimension; this.dimension = vertices.getDimension();
goog.asserts.assert(this.dimension >= 2);
}; };
goog.inherits(ol.geom.MultiPolygon, ol.geom.GeometryCollection); goog.inherits(ol.geom.MultiPolygon, ol.geom.AbstractCollection);
/** /**
@@ -49,3 +54,20 @@ goog.inherits(ol.geom.MultiPolygon, ol.geom.GeometryCollection);
ol.geom.MultiPolygon.prototype.getType = function() { ol.geom.MultiPolygon.prototype.getType = function() {
return ol.geom.GeometryType.MULTIPOLYGON; return ol.geom.GeometryType.MULTIPOLYGON;
}; };
/**
* Create a multi-polygon geometry from an array of polygon geometries.
*
* @param {Array.<ol.geom.Polygon>} geometries Array of geometries.
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
* @return {ol.geom.MultiPolygon} A new geometry.
*/
ol.geom.MultiPolygon.fromParts = function(geometries, opt_shared) {
var count = geometries.length;
var coordinates = new Array(count);
for (var i = 0; i < count; ++i) {
coordinates[i] = geometries[i].getCoordinates();
}
return new ol.geom.MultiPolygon(coordinates, opt_shared);
};

View File

@@ -2,30 +2,45 @@ goog.provide('ol.geom.Point');
goog.require('goog.asserts'); goog.require('goog.asserts');
goog.require('ol.Extent'); goog.require('ol.Extent');
goog.require('ol.geom.Coordinate');
goog.require('ol.geom.Geometry'); goog.require('ol.geom.Geometry');
goog.require('ol.geom.GeometryType'); goog.require('ol.geom.GeometryType');
goog.require('ol.geom.SharedVertices');
goog.require('ol.geom.Vertex');
/** /**
* @constructor * @constructor
* @extends {ol.geom.Geometry} * @extends {ol.geom.Geometry}
* @param {ol.geom.Coordinate} coordinates Coordinates array (e.g. [x, y]). * @param {ol.geom.Vertex} coordinates Coordinates array (e.g. [x, y]).
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
*/ */
ol.geom.Point = function(coordinates) { ol.geom.Point = function(coordinates, opt_shared) {
goog.base(this); goog.base(this);
var vertices = opt_shared,
dimension;
if (!goog.isDef(vertices)) {
dimension = coordinates.length;
vertices = new ol.geom.SharedVertices({dimension: dimension});
}
/** /**
* @type {Array} * @type {ol.geom.SharedVertices}
*/ */
this.coordinates = coordinates; this.vertices = vertices;
/**
* @type {string}
* @private
*/
this.sharedId_ = vertices.add([coordinates]);
/** /**
* @type {number} * @type {number}
*/ */
this.dimension = coordinates.length; this.dimension = vertices.getDimension();
goog.asserts.assert(this.dimension >= 2); goog.asserts.assert(this.dimension >= 2);
/** /**
@@ -38,22 +53,53 @@ ol.geom.Point = function(coordinates) {
goog.inherits(ol.geom.Point, ol.geom.Geometry); goog.inherits(ol.geom.Point, ol.geom.Geometry);
/**
* @param {number} dim Coordinate dimension.
* @return {number} The coordinate value.
*/
ol.geom.Point.prototype.get = function(dim) {
return this.vertices.get(this.sharedId_, 0, dim);
};
/** /**
* @inheritDoc * @inheritDoc
*/ */
ol.geom.Point.prototype.getBounds = function() { ol.geom.Point.prototype.getBounds = function() {
if (goog.isNull(this.bounds_)) { if (goog.isNull(this.bounds_)) {
var x = this.coordinates[0], var x = this.get(0),
y = this.coordinates[1]; y = this.get(1);
this.bounds_ = new ol.Extent(x, y, x, y); this.bounds_ = new ol.Extent(x, y, x, y);
} }
return this.bounds_; return this.bounds_;
}; };
/**
* @inheritDoc
* @return {ol.geom.Vertex} Coordinates array.
*/
ol.geom.Point.prototype.getCoordinates = function() {
var coordinates = new Array(this.dimension);
for (var i = 0; i < this.dimension; ++i) {
coordinates[i] = this.get(i);
}
return coordinates;
};
/** /**
* @inheritDoc * @inheritDoc
*/ */
ol.geom.Point.prototype.getType = function() { ol.geom.Point.prototype.getType = function() {
return ol.geom.GeometryType.POINT; return ol.geom.GeometryType.POINT;
}; };
/**
* Get the identifier used to mark this point in the shared vertices structure.
* @return {string} The identifier.
*/
ol.geom.Point.prototype.getSharedId = function() {
return this.sharedId_;
};

View File

@@ -2,43 +2,53 @@ goog.provide('ol.geom.Polygon');
goog.require('goog.asserts'); goog.require('goog.asserts');
goog.require('ol.Extent'); goog.require('ol.Extent');
goog.require('ol.geom.CoordinateArray');
goog.require('ol.geom.Geometry'); goog.require('ol.geom.Geometry');
goog.require('ol.geom.GeometryType'); goog.require('ol.geom.GeometryType');
goog.require('ol.geom.LinearRing'); goog.require('ol.geom.LinearRing');
goog.require('ol.geom.SharedVertices');
goog.require('ol.geom.VertexArray');
/** /**
* @constructor * @constructor
* @extends {ol.geom.Geometry} * @extends {ol.geom.Geometry}
* @param {Array.<ol.geom.CoordinateArray>} coordinates Array of rings. First * @param {Array.<ol.geom.VertexArray>} coordinates Array of rings. First
* is outer, any remaining are inner. * is outer, any remaining are inner.
* @param {ol.geom.SharedVertices=} opt_shared Shared vertices.
*/ */
ol.geom.Polygon = function(coordinates) { ol.geom.Polygon = function(coordinates, opt_shared) {
goog.base(this); goog.base(this);
goog.asserts.assert(goog.isArray(coordinates[0][0]));
var numRings = coordinates.length, var vertices = opt_shared,
dimension; dimension;
if (!goog.isDef(vertices)) {
// try to get dimension from first vertex in first ring
dimension = coordinates[0][0].length;
vertices = new ol.geom.SharedVertices({dimension: dimension});
}
/**
* @type {ol.geom.SharedVertices}
*/
this.vertices = vertices;
var numRings = coordinates.length;
/** /**
* @type {Array.<ol.geom.LinearRing>} * @type {Array.<ol.geom.LinearRing>}
*/ */
this.rings = new Array(numRings); this.rings = new Array(numRings);
for (var i = 0; i < numRings; ++i) { for (var i = 0; i < numRings; ++i) {
this.rings[i] = new ol.geom.LinearRing(coordinates[i]); this.rings[i] = new ol.geom.LinearRing(coordinates[i], vertices);
if (!goog.isDef(dimension)) {
dimension = this.rings[i].dimension;
} else {
goog.asserts.assert(this.rings[i].dimension === dimension);
}
} }
/** /**
* @type {number} * @type {number}
*/ */
this.dimension = dimension; this.dimension = vertices.getDimension();
goog.asserts.assert(this.dimension >= 2); goog.asserts.assert(this.dimension >= 2);
/** /**
@@ -59,6 +69,19 @@ ol.geom.Polygon.prototype.getBounds = function() {
}; };
/**
* @return {Array.<ol.geom.VertexArray>} Coordinates array.
*/
ol.geom.Polygon.prototype.getCoordinates = function() {
var count = this.rings.length;
var coordinates = new Array(count);
for (var i = 0; i < count; ++i) {
coordinates[i] = this.rings[i].getCoordinates();
}
return coordinates;
};
/** /**
* @inheritDoc * @inheritDoc
*/ */

View File

@@ -0,0 +1,195 @@
goog.provide('ol.geom.SharedVertices');
goog.require('goog.asserts');
goog.require('ol.geom.Vertex');
goog.require('ol.geom.VertexArray');
/**
* @typedef {{dimension: (number),
* offset: (ol.geom.Vertex|undefined)}}
*/
ol.geom.SharedVerticesOptions;
/**
* Provides methods for dealing with shared, flattened arrays of vertices.
*
* @constructor
* @param {ol.geom.SharedVerticesOptions=} opt_options Shared vertices options.
*/
ol.geom.SharedVertices = function(opt_options) {
var options = goog.isDef(opt_options) ? opt_options : {};
/**
* @type {number}
* @private
*/
this.counter_ = 0;
/**
* @type {Array.<number>}
*/
this.coordinates = [];
/**
* Number of dimensions per vertex. Default is 2.
* @type {number}
* @private
*/
this.dimension_ = options.dimension || 2;
/**
* Vertex offset.
* @type {Array.<number>}
* @private
*/
this.offset_ = options.offset || null;
goog.asserts.assert(goog.isNull(this.offset_) ||
this.offset_.length === this.dimension_);
/**
* @type {Object}
* @private
*/
this.lookup_ = {};
/**
* @type {Array.<string>}
* @private
*/
this.ids_ = [];
};
/**
* Adds a vertex array to the shared coordinate array.
* @param {ol.geom.VertexArray} vertices Array of vertices.
* @return {string} Index used to reference the added vertex array.
*/
ol.geom.SharedVertices.prototype.add = function(vertices) {
var start = this.coordinates.length;
var offset = this.offset_;
var dimension = this.dimension_;
var count = vertices.length;
var vertex, index;
for (var i = 0; i < count; ++i) {
vertex = vertices[i];
goog.asserts.assert(vertex.length == dimension);
if (!offset) {
Array.prototype.push.apply(this.coordinates, vertex);
} else {
index = start + (i * dimension);
for (var j = 0; j < dimension; ++j) {
this.coordinates[index + j] = vertex[j] - offset[j];
}
}
}
var id = this.getId_();
var idIndex = this.ids_.push(id) - 1;
this.lookup_[id] = {
idIndex: idIndex,
start: start,
count: count
};
return id;
};
/**
* @param {string} id The vertex array identifier (returned by add).
* @param {number} index The vertex index.
* @param {number} dim The coordinate dimension.
* @return {number} The coordinate value.
*/
ol.geom.SharedVertices.prototype.get = function(id, index, dim) {
goog.asserts.assert(dim <= this.dimension_);
goog.asserts.assert(this.lookup_.hasOwnProperty(id));
goog.asserts.assert(index < this.lookup_[id].count);
var start = this.lookup_[id].start;
var value = this.coordinates[start + (index * this.dimension_) + dim];
if (this.offset_) {
value += this.offset_[dim];
}
return value;
};
/**
* @param {string} id The vertex array identifier (returned by add).
* @return {number} The number of vertices in the referenced array.
*/
ol.geom.SharedVertices.prototype.getCount = function(id) {
goog.asserts.assert(this.lookup_.hasOwnProperty(id));
return this.lookup_[id].count;
};
/**
* Gets an identifier that is unique for this instance.
* @return {string} Identifier.
* @private
*/
ol.geom.SharedVertices.prototype.getId_ = function() {
return String(++this.counter_);
};
/**
* @return {number} The dimension of each vertex in the array.
*/
ol.geom.SharedVertices.prototype.getDimension = function() {
return this.dimension_;
};
/**
* @return {Array.<number>} The offset array for vertex coordinates (or null).
*/
ol.geom.SharedVertices.prototype.getOffset = function() {
return this.offset_;
};
/**
* @param {string} id The vertex array identifier (returned by add).
* @return {number} The start index in the shared vertices array.
*/
ol.geom.SharedVertices.prototype.getStart = function(id) {
goog.asserts.assert(this.lookup_.hasOwnProperty(id));
return this.lookup_[id].start;
};
/**
* @param {number} id The vertex array identifier (returned by add).
* @return {ol.geom.VertexArray} The removed vertex array.
*/
ol.geom.SharedVertices.prototype.remove = function(id) {
goog.asserts.assert(this.lookup_.hasOwnProperty(id));
var info = this.lookup_[id];
var dimension = this.dimension_;
var length = info.count * dimension;
var removed = this.coordinates.splice(info.start, length);
var offset = this.offset_;
var array = new Array(info.count);
var vertex;
for (var i = 0; i < info.count; ++i) {
vertex = new Array(dimension);
for (var j = 0; j < dimension; ++j) {
vertex[j] = removed[(i * dimension) + j] + (offset ? offset[j] : 0);
}
array[i] = vertex;
}
delete this.lookup_[id];
this.ids_.splice(info.idIndex, 1);
var afterInfo;
for (var k = info.idIndex, kk = this.ids_.length; k < kk; ++k) {
afterInfo = this.lookup_[this.ids_[k]];
afterInfo.idIndex -= 1;
afterInfo.start -= length;
}
return array;
};

View File

@@ -8,6 +8,9 @@ goog.require('ol.Pixel');
goog.require('ol.canvas'); goog.require('ol.canvas');
goog.require('ol.geom.Geometry'); goog.require('ol.geom.Geometry');
goog.require('ol.geom.GeometryType'); goog.require('ol.geom.GeometryType');
goog.require('ol.geom.LineString');
goog.require('ol.geom.Point');
goog.require('ol.geom.Polygon');
goog.require('ol.style.LineLiteral'); goog.require('ol.style.LineLiteral');
goog.require('ol.style.PointLiteral'); goog.require('ol.style.PointLiteral');
goog.require('ol.style.PolygonLiteral'); goog.require('ol.style.PolygonLiteral');
@@ -108,20 +111,18 @@ ol.renderer.canvas.Renderer.prototype.renderLineStringFeatures_ =
function(features, symbolizer) { function(features, symbolizer) {
var context = this.context_, var context = this.context_,
i, ii, line, coords, dim, j, jj, x, y; i, ii, line, dim, j, jj, x, y;
context.globalAlpha = symbolizer.opacity; context.globalAlpha = symbolizer.opacity;
context.strokeStyle = symbolizer.strokeStyle; context.strokeStyle = symbolizer.strokeStyle;
context.lineWidth = symbolizer.strokeWidth * this.inverseScale_; context.lineWidth = symbolizer.strokeWidth * this.inverseScale_;
context.beginPath(); context.beginPath();
for (i = 0, ii = features.length; i < ii; ++i) { for (i = 0, ii = features.length; i < ii; ++i) {
line = features[i].getGeometry(); line = /** @type {ol.geom.LineString} */ features[i].getGeometry();
dim = line.dimension; dim = line.dimension;
coords = line.coordinates; for (j = 0, jj = line.getCount(); j < jj; ++j) {
for (j = 0, jj = coords.length; j < jj; j += dim) { x = line.get(j, 0);
x = coords[j]; y = line.get(j, 1);
y = coords[j + 1];
if (j === 0) { if (j === 0) {
context.moveTo(x, y); context.moveTo(x, y);
} else { } else {
@@ -143,7 +144,7 @@ ol.renderer.canvas.Renderer.prototype.renderPointFeatures_ =
function(features, symbolizer) { function(features, symbolizer) {
var context = this.context_, var context = this.context_,
canvas, i, ii, coords, vec; canvas, i, ii, point, vec;
if (symbolizer instanceof ol.style.ShapeLiteral) { if (symbolizer instanceof ol.style.ShapeLiteral) {
canvas = ol.renderer.canvas.Renderer.renderShape(symbolizer); canvas = ol.renderer.canvas.Renderer.renderShape(symbolizer);
@@ -156,9 +157,9 @@ ol.renderer.canvas.Renderer.prototype.renderPointFeatures_ =
context.setTransform(1, 0, 0, 1, -mid, -mid); context.setTransform(1, 0, 0, 1, -mid, -mid);
context.globalAlpha = 1; context.globalAlpha = 1;
for (i = 0, ii = features.length; i < ii; ++i) { for (i = 0, ii = features.length; i < ii; ++i) {
coords = features[i].getGeometry().coordinates; point = /** @type {ol.geom.Point} */ features[i].getGeometry();
vec = goog.vec.Mat4.multVec3( vec = goog.vec.Mat4.multVec3(
this.transform_, [coords[0], coords[1], 0], []); this.transform_, [point.get(0), point.get(1), 0], []);
context.drawImage(canvas, vec[0], vec[1]); context.drawImage(canvas, vec[0], vec[1]);
} }
context.restore(); context.restore();
@@ -176,7 +177,7 @@ ol.renderer.canvas.Renderer.prototype.renderPolygonFeatures_ =
var context = this.context_, var context = this.context_,
strokeStyle = symbolizer.strokeStyle, strokeStyle = symbolizer.strokeStyle,
fillStyle = symbolizer.fillStyle, fillStyle = symbolizer.fillStyle,
i, ii, poly, rings, numRings, coords, dim, j, jj, x, y; i, ii, poly, rings, numRings, ring, dim, j, jj, x, y;
context.globalAlpha = symbolizer.opacity; context.globalAlpha = symbolizer.opacity;
if (strokeStyle) { if (strokeStyle) {
@@ -196,7 +197,7 @@ ol.renderer.canvas.Renderer.prototype.renderPolygonFeatures_ =
*/ */
context.beginPath(); context.beginPath();
for (i = 0, ii = features.length; i < ii; ++i) { for (i = 0, ii = features.length; i < ii; ++i) {
poly = features[i].getGeometry(); poly = /** @type {ol.geom.Polygon} */ features[i].getGeometry();
dim = poly.dimension; dim = poly.dimension;
rings = poly.rings; rings = poly.rings;
numRings = rings.length; numRings = rings.length;
@@ -205,10 +206,10 @@ ol.renderer.canvas.Renderer.prototype.renderPolygonFeatures_ =
// TODO: use sketch canvas to render outer and punch holes for inner rings // TODO: use sketch canvas to render outer and punch holes for inner rings
throw new Error('Rendering holes not implemented'); throw new Error('Rendering holes not implemented');
} else { } else {
coords = rings[0].coordinates; ring = rings[0];
for (j = 0, jj = coords.length; j < jj; j += dim) { for (j = 0, jj = ring.getCount(); j < jj; ++j) {
x = coords[j]; x = ring.get(j, 0);
y = coords[j + 1]; y = ring.get(j, 1);
if (j === 0) { if (j === 0) {
context.moveTo(x, y); context.moveTo(x, y);
} else { } else {

View File

@@ -0,0 +1,79 @@
goog.provide('ol.test.geom.GeometryCollection');
describe('ol.geom.GeometryCollection', function() {
var outer = [[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]],
inner1 = [[1, 1], [2, 1], [2, 2], [1, 2], [1, 1]],
inner2 = [[8, 8], [9, 8], [9, 9], [8, 9], [8, 8]];
describe('constructor', function() {
it('creates a geometry collection from an array of geometries', function() {
var point = new ol.geom.Point([10, 20]);
var line = new ol.geom.LineString([[10, 20], [30, 40]]);
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
var multi = new ol.geom.GeometryCollection([point, line, poly]);
expect(multi).toBeA(ol.geom.GeometryCollection);
expect(multi).toBeA(ol.geom.Geometry);
});
});
describe('#components', function() {
it('is an array of geometries', function() {
var point = new ol.geom.Point([10, 20]);
var line = new ol.geom.LineString([[10, 20], [30, 40]]);
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
var multi = new ol.geom.GeometryCollection([point, line, poly]);
expect(multi.components.length).toBe(3);
expect(multi.components[0]).toBeA(ol.geom.Point);
expect(multi.components[1]).toBeA(ol.geom.LineString);
expect(multi.components[2]).toBeA(ol.geom.Polygon);
});
});
describe('#dimension', function() {
it('can be 2', function() {
var point = new ol.geom.Point([10, 20]);
var line = new ol.geom.LineString([[10, 20], [30, 40]]);
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
var multi = new ol.geom.GeometryCollection([point, line, poly]);
expect(multi.dimension).toBe(2);
});
it('can be 3', function() {
var multi = new ol.geom.GeometryCollection([
new ol.geom.Point([30, 40, 50])
]);
expect(multi.dimension).toBe(3);
});
});
describe('#getBounds()', function() {
it('returns the bounding extent', function() {
var point = new ol.geom.Point([10, 2]);
var line = new ol.geom.LineString([[1, 20], [30, 40]]);
var multi = new ol.geom.GeometryCollection([point, line]);
var bounds = multi.getBounds();
expect(bounds.minX).toBe(1);
expect(bounds.minY).toBe(2);
expect(bounds.maxX).toBe(30);
expect(bounds.maxY).toBe(40);
});
});
});
goog.require('ol.geom.Geometry');
goog.require('ol.geom.GeometryCollection');
goog.require('ol.geom.LineString');
goog.require('ol.geom.Point');
goog.require('ol.geom.Polygon');

View File

@@ -17,20 +17,6 @@ describe('ol.geom.LinearRing', function() {
}); });
describe('#coordinates', function() {
it('is an array', function() {
var ring = new ol.geom.LinearRing([[10, 20], [30, 40]]);
expect(ring.coordinates.length).toBe(4);
expect(ring.coordinates[0]).toBe(10);
expect(ring.coordinates[1]).toBe(20);
expect(ring.coordinates[2]).toBe(30);
expect(ring.coordinates[3]).toBe(40);
});
});
describe('#dimension', function() { describe('#dimension', function() {
it('can be 2', function() { it('can be 2', function() {
@@ -45,6 +31,14 @@ describe('ol.geom.LinearRing', function() {
}); });
describe('#getCoordinates()', function() {
it('is an array', function() {
var ring = new ol.geom.LinearRing([[10, 20], [30, 40]]);
expect(ring.getCoordinates()).toEqual([[10, 20], [30, 40]]);
});
});
}); });

View File

@@ -16,18 +16,12 @@ describe('ol.geom.LineString', function() {
}).toThrow(); }).toThrow();
}); });
}); it('accepts shared vertices', function() {
var vertices = new ol.geom.SharedVertices();
describe('#coordinates', function() { var l1 = new ol.geom.LineString([[10, 20], [30, 40]], vertices);
var l2 = new ol.geom.LineString([[50, 60], [70, 80]], vertices);
it('is an array', function() { expect(l1.getCoordinates()).toEqual([[10, 20], [30, 40]]);
var line = new ol.geom.LineString([[10, 20], [30, 40]]); expect(l2.getCoordinates()).toEqual([[50, 60], [70, 80]]);
expect(line.coordinates.length).toBe(4);
expect(line.coordinates[0]).toBe(10);
expect(line.coordinates[1]).toBe(20);
expect(line.coordinates[2]).toBe(30);
expect(line.coordinates[3]).toBe(40);
}); });
}); });
@@ -59,8 +53,51 @@ describe('ol.geom.LineString', function() {
}); });
describe('#getCoordinates', function() {
it('returns an array', function() {
var line = new ol.geom.LineString([[10, 20], [30, 40]]);
expect(line.getCoordinates()).toEqual([[10, 20], [30, 40]]);
});
});
describe('#getSharedId()', function() {
it('returns identifiers', function() {
var vertices = new ol.geom.SharedVertices();
var l1 = new ol.geom.LineString([[10, 20], [30, 40]], vertices);
var l2 = new ol.geom.LineString(
[[50, 60], [70, 80], [90, 100]], vertices);
var id1 = l1.getSharedId();
var id2 = l2.getSharedId();
expect(vertices.coordinates).toEqual(
[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]);
expect(vertices.getStart(id1)).toBe(0);
expect(vertices.getCount(id1)).toBe(2);
expect(vertices.get(id1, 0, 0)).toBe(10);
expect(vertices.get(id1, 0, 1)).toBe(20);
expect(vertices.get(id1, 1, 0)).toBe(30);
expect(vertices.get(id1, 1, 1)).toBe(40);
expect(vertices.getStart(id2)).toBe(4);
expect(vertices.getCount(id2)).toBe(3);
expect(vertices.get(id2, 0, 0)).toBe(50);
expect(vertices.get(id2, 0, 1)).toBe(60);
expect(vertices.get(id2, 1, 0)).toBe(70);
expect(vertices.get(id2, 1, 1)).toBe(80);
expect(vertices.get(id2, 2, 0)).toBe(90);
expect(vertices.get(id2, 2, 1)).toBe(100);
});
});
}); });
goog.require('ol.geom.Geometry'); goog.require('ol.geom.Geometry');
goog.require('ol.geom.LineString'); goog.require('ol.geom.LineString');
goog.require('ol.geom.SharedVertices');

View File

@@ -68,6 +68,19 @@ describe('ol.geom.MultiLineString', function() {
}); });
describe('#getCoordinates', function() {
it('returns an array', function() {
var coordinates = [
[[10, 20], [30, 40]],
[[20, 30], [40, 50]]
];
var multi = new ol.geom.MultiLineString(coordinates);
expect(multi.getCoordinates()).toEqual(coordinates);
});
});
}); });
goog.require('ol.geom.Geometry'); goog.require('ol.geom.Geometry');

View File

@@ -58,6 +58,15 @@ describe('ol.geom.MultiPoint', function() {
}); });
describe('#getCoordinates', function() {
it('returns an array', function() {
var multi = new ol.geom.MultiPoint([[10, 20], [30, 40]]);
expect(multi.getCoordinates()).toEqual([[10, 20], [30, 40]]);
});
});
}); });
goog.require('ol.geom.Geometry'); goog.require('ol.geom.Geometry');

View File

@@ -71,6 +71,20 @@ describe('ol.geom.MultiPolygon', function() {
}); });
describe('#getCoordinates', function() {
it('returns an array', function() {
var coordinates = [
[outer1, inner1a, inner1b],
[outer2]
];
var multi = new ol.geom.MultiPolygon(coordinates);
expect(multi.getCoordinates()).toEqual(coordinates);
});
});
}); });
goog.require('ol.geom.Geometry'); goog.require('ol.geom.Geometry');

View File

@@ -10,6 +10,16 @@ describe('ol.geom.Point', function() {
expect(point).toBeA(ol.geom.Geometry); expect(point).toBeA(ol.geom.Geometry);
}); });
it('accepts shared vertices', function() {
var vertices = new ol.geom.SharedVertices();
var p1 = new ol.geom.Point([10, 20], vertices);
var p2 = new ol.geom.Point([30, 40], vertices);
var p3 = new ol.geom.Point([50, 60], vertices);
expect(p1.getCoordinates()).toEqual([10, 20]);
expect(p2.getCoordinates()).toEqual([30, 40]);
expect(p3.getCoordinates()).toEqual([50, 60]);
});
it('throws when given with insufficient dimensions', function() { it('throws when given with insufficient dimensions', function() {
expect(function() { expect(function() {
var point = new ol.geom.Point([1]); var point = new ol.geom.Point([1]);
@@ -18,19 +28,6 @@ describe('ol.geom.Point', function() {
}); });
describe('#coordinates', function() {
it('is an array', function() {
var point = new ol.geom.Point([10, 20]);
expect(point.coordinates.length).toBe(2);
expect(point.coordinates[0]).toBe(10);
expect(point.coordinates[1]).toBe(20);
});
});
describe('#dimension', function() { describe('#dimension', function() {
it('can be 2', function() { it('can be 2', function() {
@@ -58,7 +55,52 @@ describe('ol.geom.Point', function() {
}); });
describe('#getCoordinates()', function() {
it('returns an array', function() {
var point = new ol.geom.Point([10, 20]);
expect(point.getCoordinates()).toEqual([10, 20]);
});
});
describe('#getSharedId()', function() {
it('returns identifiers', function() {
var vertices = new ol.geom.SharedVertices();
var p1 = new ol.geom.Point([10, 20], vertices);
var p2 = new ol.geom.Point([30, 40], vertices);
var p3 = new ol.geom.Point([50, 60], vertices);
var id1 = p1.getSharedId();
var id2 = p2.getSharedId();
var id3 = p3.getSharedId();
expect(vertices.coordinates).toEqual(
[10, 20, 30, 40, 50, 60]);
expect(vertices.getStart(id1)).toBe(0);
expect(vertices.getCount(id1)).toBe(1);
expect(vertices.get(id1, 0, 0)).toBe(10);
expect(vertices.get(id1, 0, 1)).toBe(20);
expect(vertices.getStart(id2)).toBe(2);
expect(vertices.getCount(id2)).toBe(1);
expect(vertices.get(id2, 0, 0)).toBe(30);
expect(vertices.get(id2, 0, 1)).toBe(40);
expect(vertices.getStart(id3)).toBe(4);
expect(vertices.getCount(id3)).toBe(1);
expect(vertices.get(id3, 0, 0)).toBe(50);
expect(vertices.get(id3, 0, 1)).toBe(60);
});
});
}); });
goog.require('ol.geom.Geometry'); goog.require('ol.geom.Geometry');
goog.require('ol.geom.Point'); goog.require('ol.geom.Point');
goog.require('ol.geom.SharedVertices');

View File

@@ -1,4 +1,4 @@
gooog.require('ol.test.geom.Polygon'); goog.provide('ol.test.geom.Polygon');
describe('ol.geom.Polygon', function() { describe('ol.geom.Polygon', function() {
@@ -20,6 +20,16 @@ describe('ol.geom.Polygon', function() {
}).toThrow(); }).toThrow();
}); });
it('accepts shared vertices', function() {
var vertices = new ol.geom.SharedVertices();
var p1 = new ol.geom.Polygon([outer], vertices);
var p2 = new ol.geom.Polygon([outer, inner1], vertices);
var p3 = new ol.geom.Polygon([outer, inner2], vertices);
expect(p1.getCoordinates()).toEqual([outer]);
expect(p2.getCoordinates()).toEqual([outer, inner1]);
expect(p3.getCoordinates()).toEqual([outer, inner2]);
});
}); });
describe('#rings', function() { describe('#rings', function() {
@@ -62,8 +72,17 @@ describe('ol.geom.Polygon', function() {
}); });
describe('#getCoordinates()', function() {
it('returns an array', function() {
var poly = new ol.geom.Polygon([outer, inner1, inner2]);
expect(poly.getCoordinates()).toEqual([outer, inner1, inner2]);
});
});
}); });
goog.require('ol.geom.Geometry'); goog.require('ol.geom.Geometry');
goog.require('ol.geom.Polygon'); goog.require('ol.geom.Polygon');
goog.require('ol.geom.SharedVertices');

View File

@@ -0,0 +1,195 @@
goog.provide('ol.test.geom.SharedVertices');
describe('ol.geom.SharedVertices', function() {
describe('constructor', function() {
it('creates an instance', function() {
var vertices = new ol.geom.SharedVertices();
expect(vertices).toBeA(ol.geom.SharedVertices);
});
it('accepts options', function() {
var vertices = new ol.geom.SharedVertices({
dimension: 4,
offset: [1, 2, 3, 4]
});
expect(vertices.getDimension()).toBe(4);
expect(vertices.getOffset()).toEqual([1, 2, 3, 4]);
});
});
describe('offset option', function() {
it('offsets the internally stored vertex coordinates', function() {
var vertices = new ol.geom.SharedVertices({offset: [3, -1]});
vertices.add([[3, -1], [0, 0]]);
vertices.add([[10, 20]]);
expect(vertices.coordinates).toEqual([0, 0, -3, 1, 7, 21]);
});
});
describe('#add()', function() {
it('adds vertex arrays to the shared coordinates', function() {
var vertices = new ol.geom.SharedVertices();
expect(vertices.coordinates.length).toBe(0);
vertices.add([[1, 2], [3, 4]]);
expect(vertices.coordinates).toEqual([1, 2, 3, 4]);
vertices.add([[5, 6]]);
expect(vertices.coordinates).toEqual([1, 2, 3, 4, 5, 6]);
});
it('returns an identifier for coordinate access', function() {
var vertices = new ol.geom.SharedVertices();
var id = vertices.add([[1, 2], [3, 4]]);
expect(typeof id).toBe('string');
});
});
describe('#get()', function() {
it('provides access to vertex coordinates', function() {
var vertices = new ol.geom.SharedVertices();
var first = vertices.add([[1, 2], [3, 4]]);
var second = vertices.add([[5, 6]]);
expect(vertices.get(first, 0, 0)).toBe(1);
expect(vertices.get(first, 0, 1)).toBe(2);
expect(vertices.get(first, 1, 0)).toBe(3);
expect(vertices.get(first, 1, 1)).toBe(4);
expect(vertices.get(second, 0, 0)).toBe(5);
expect(vertices.get(second, 0, 1)).toBe(6);
});
it('works for non-2d vertices', function() {
var vertices = new ol.geom.SharedVertices({dimension: 3});
var id = vertices.add([[1, 2, 3], [4, 5, 6]]);
expect(vertices.get(id, 0, 0)).toBe(1);
expect(vertices.get(id, 0, 1)).toBe(2);
expect(vertices.get(id, 0, 2)).toBe(3);
expect(vertices.get(id, 1, 0)).toBe(4);
expect(vertices.get(id, 1, 1)).toBe(5);
expect(vertices.get(id, 1, 2)).toBe(6);
});
it('works when an offset is provided', function() {
var vertices = new ol.geom.SharedVertices({offset: [3, 3]});
var id = vertices.add([[1, 2], [3, 4], [5, 6]]);
expect(vertices.get(id, 0, 0)).toBe(1);
expect(vertices.get(id, 0, 1)).toBe(2);
expect(vertices.get(id, 1, 0)).toBe(3);
expect(vertices.get(id, 1, 1)).toBe(4);
expect(vertices.get(id, 2, 0)).toBe(5);
expect(vertices.get(id, 2, 1)).toBe(6);
});
});
describe('#getCount()', function() {
it('returns the length of an identified vertex array', function() {
var vertices = new ol.geom.SharedVertices();
var first = vertices.add([[2, 3], [3, 4], [4, 5]]);
var second = vertices.add([[5, 6], [6, 6]]);
expect(vertices.getCount(first)).toBe(3);
expect(vertices.getCount(second)).toBe(2);
});
});
describe('#getDimension()', function() {
it('returns 2 by default', function() {
var vertices = new ol.geom.SharedVertices();
expect(vertices.getDimension()).toBe(2);
});
it('returns the dimension provided to the constructor', function() {
var vertices = new ol.geom.SharedVertices({dimension: 10});
expect(vertices.getDimension()).toBe(10);
});
});
describe('#getOffset()', function() {
it('returns null by default', function() {
var vertices = new ol.geom.SharedVertices();
expect(vertices.getOffset()).toBeNull();
});
it('returns the offset provided to the constructor', function() {
var vertices = new ol.geom.SharedVertices({offset: [1, 2]});
expect(vertices.getOffset()).toEqual([1, 2]);
});
});
describe('#getStart()', function() {
it('returns the start of the identified vertex array', function() {
var vertices = new ol.geom.SharedVertices();
var first = vertices.add([[1, 2]]);
var second = vertices.add([[3, 4], [5, 6]]);
var third = vertices.add([[7, 8], [9, 10], [11, 12]]);
expect(vertices.coordinates).toEqual(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
expect(vertices.getStart(first)).toBe(0);
expect(vertices.getStart(second)).toBe(2);
expect(vertices.getStart(third)).toBe(6);
});
});
describe('#remove()', function() {
it('removes a vertex array', function() {
var vertices = new ol.geom.SharedVertices();
var first = vertices.add([[1, 2], [3, 4]]);
var second = vertices.add([[5, 6]]);
var third = vertices.add([[7, 8], [9, 10], [11, 12]]);
expect(vertices.remove(second)).toEqual([[5, 6]]);
expect(vertices.coordinates).toEqual([1, 2, 3, 4, 7, 8, 9, 10, 11, 12]);
expect(vertices.remove(first)).toEqual([[1, 2], [3, 4]]);
expect(vertices.coordinates).toEqual([7, 8, 9, 10, 11, 12]);
expect(vertices.remove(third)).toEqual([[7, 8], [9, 10], [11, 12]]);
expect(vertices.coordinates).toEqual([]);
});
it('adjusts returned vertices by offset', function() {
var vertices = new ol.geom.SharedVertices({offset: [10, 20]});
var first = vertices.add([[1, 2]]);
var second = vertices.add([[3, 4]]);
var third = vertices.add([[5, 6]]);
expect(vertices.remove(second)).toEqual([[3, 4]]);
expect(vertices.coordinates).toEqual([-9, -18, -5, -14]);
expect(vertices.remove(third)).toEqual([[5, 6]]);
expect(vertices.coordinates).toEqual([-9, -18]);
expect(vertices.remove(first)).toEqual([[1, 2]]);
expect(vertices.coordinates).toEqual([]);
});
});
describe('#coordinates', function() {
it('is not reassigned', function() {
var vertices = new ol.geom.SharedVertices();
var first = vertices.add([[1, 2], [3, 4]]);
var coordinates = vertices.coordinates;
var second = vertices.add([[5, 6]]);
expect(vertices.coordinates).toBe(coordinates);
vertices.remove(first);
expect(vertices.coordinates).toBe(coordinates);
vertices.remove(second);
expect(vertices.coordinates).toBe(coordinates);
});
});
});
goog.require('ol.geom.SharedVertices');

View File

@@ -76,8 +76,7 @@ describe('ol.parser.geojson', function() {
var obj = ol.parser.geojson.read(str); var obj = ol.parser.geojson.read(str);
expect(obj).toBeA(ol.geom.Point); expect(obj).toBeA(ol.geom.Point);
expect(obj.coordinates[0]).toBe(10); expect(obj.getCoordinates()).toEqual([10, 20]);
expect(obj.coordinates[1]).toBe(20);
}); });
it('parses linestring', function() { it('parses linestring', function() {
@@ -88,10 +87,7 @@ describe('ol.parser.geojson', function() {
var obj = ol.parser.geojson.read(str); var obj = ol.parser.geojson.read(str);
expect(obj).toBeA(ol.geom.LineString); expect(obj).toBeA(ol.geom.LineString);
expect(obj.coordinates[0]).toBe(10); expect(obj.getCoordinates()).toEqual([[10, 20], [30, 40]]);
expect(obj.coordinates[1]).toBe(20);
expect(obj.coordinates[2]).toBe(30);
expect(obj.coordinates[3]).toBe(40);
}); });
it('parses polygon', function() { it('parses polygon', function() {