Move vector code out of the way
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
goog.provide('ol.geom.AbstractCollection');
|
||||
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryEvent');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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 {Array.<ol.geom.Geometry>}
|
||||
* @protected
|
||||
*/
|
||||
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 bounds = ol.extent.createEmpty();
|
||||
var components = this.components;
|
||||
for (var i = 0, ii = components.length; i < ii; ++i) {
|
||||
ol.extent.extend(bounds, components[i].getBounds());
|
||||
}
|
||||
this.bounds = bounds;
|
||||
}
|
||||
return this.bounds;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<ol.geom.Geometry>} Components.
|
||||
*/
|
||||
ol.geom.AbstractCollection.prototype.getComponents = function() {
|
||||
return this.components;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
|
||||
/**
|
||||
* Listener for component change events.
|
||||
* @param {ol.geom.GeometryEvent} evt Geometry event.
|
||||
* @protected
|
||||
*/
|
||||
ol.geom.AbstractCollection.prototype.handleComponentChange = function(evt) {
|
||||
this.bounds = null;
|
||||
var oldExtent = ol.extent.createEmpty();
|
||||
var components = this.components;
|
||||
for (var i = components.length - 1; i >= 0; --i) {
|
||||
var component = components[i];
|
||||
ol.extent.extend(oldExtent,
|
||||
component === evt.target && !goog.isNull(evt.oldExtent) ?
|
||||
evt.oldExtent : component.getBounds());
|
||||
}
|
||||
this.dispatchEvent(new ol.geom.GeometryEvent(goog.events.EventType.CHANGE,
|
||||
this, oldExtent));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.AbstractCollection.prototype.transform = function(transform) {
|
||||
var components = this.components;
|
||||
for (var i = 0, ii = components.length; i < ii; ++i) {
|
||||
components[i].transform(transform);
|
||||
}
|
||||
this.bounds = null;
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
goog.provide('ol.geom.Geometry');
|
||||
goog.provide('ol.geom.GeometryEvent');
|
||||
goog.provide('ol.geom.GeometryType');
|
||||
|
||||
goog.require('goog.events.Event');
|
||||
goog.require('goog.events.EventTarget');
|
||||
goog.require('goog.object');
|
||||
goog.require('ol.Extent');
|
||||
goog.require('ol.TransformFunction');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {goog.events.EventTarget}
|
||||
* @todo stability experimental
|
||||
*/
|
||||
ol.geom.Geometry = function() {
|
||||
goog.base(this);
|
||||
};
|
||||
goog.inherits(ol.geom.Geometry, goog.events.EventTarget);
|
||||
|
||||
|
||||
/**
|
||||
* Create a clone of this geometry.
|
||||
* @return {ol.geom.Geometry} The cloned geometry.
|
||||
*/
|
||||
ol.geom.Geometry.prototype.clone = function() {
|
||||
return new this.constructor(goog.object.unsafeClone(this.getCoordinates()));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the rectangular 2D envelope for this geoemtry.
|
||||
* @return {ol.Extent} The bounding rectangular envelope.
|
||||
*/
|
||||
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 geometry type.
|
||||
* @return {ol.geom.GeometryType} The geometry type.
|
||||
*/
|
||||
ol.geom.Geometry.prototype.getType = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Transform a geometry in place.
|
||||
* @param {ol.TransformFunction} transform Transform function.
|
||||
*/
|
||||
ol.geom.Geometry.prototype.transform = goog.abstractMethod;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for geometry events.
|
||||
* @constructor
|
||||
* @extends {goog.events.Event}
|
||||
* @param {string} type Event type.
|
||||
* @param {ol.geom.Geometry} target The target geometry.
|
||||
* @param {ol.Extent} oldExtent The previous geometry extent.
|
||||
*/
|
||||
ol.geom.GeometryEvent = function(type, target, oldExtent) {
|
||||
goog.base(this, type, target);
|
||||
|
||||
this.oldExtent = oldExtent;
|
||||
};
|
||||
goog.inherits(ol.geom.GeometryEvent, goog.events.Event);
|
||||
|
||||
|
||||
/**
|
||||
* Geometry types.
|
||||
*
|
||||
* @enum {string}
|
||||
* @todo stability experimental
|
||||
*/
|
||||
ol.geom.GeometryType = {
|
||||
POINT: 'point',
|
||||
LINESTRING: 'linestring',
|
||||
LINEARRING: 'linearring',
|
||||
POLYGON: 'polygon',
|
||||
MULTIPOINT: 'multipoint',
|
||||
MULTILINESTRING: 'multilinestring',
|
||||
MULTIPOLYGON: 'multipolygon',
|
||||
GEOMETRYCOLLECTION: 'geometrycollection'
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
goog.provide('ol.geom.GeometryCollection');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.geom.AbstractCollection');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A mixed collection of geometries. Used one of the fixed type multi-part
|
||||
* constructors for collections of the same type.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.geom.AbstractCollection}
|
||||
* @param {Array.<ol.geom.Geometry>} geometries Array of geometries.
|
||||
* @todo stability experimental
|
||||
*/
|
||||
ol.geom.GeometryCollection = function(geometries) {
|
||||
goog.base(this);
|
||||
|
||||
for (var i = geometries.length - 1; i >= 0; --i) {
|
||||
goog.events.listen(geometries[i], goog.events.EventType.CHANGE,
|
||||
this.handleComponentChange, false, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.Geometry>}
|
||||
* @protected
|
||||
*/
|
||||
this.components = geometries;
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.GeometryCollection, ol.geom.AbstractCollection);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.GeometryCollection.prototype.clone = function() {
|
||||
var numComponents = this.components.length;
|
||||
var components = new Array(numComponents);
|
||||
for (var i = 0; i < numComponents; ++i) {
|
||||
components[i] = this.components[i].clone();
|
||||
}
|
||||
return new ol.geom.GeometryCollection(components);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.GeometryCollection.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.GEOMETRYCOLLECTION;
|
||||
};
|
||||
@@ -0,0 +1,100 @@
|
||||
goog.provide('ol.geom.LinearRing');
|
||||
|
||||
goog.require('ol.CoordinateArray');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.LineString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.LineString}
|
||||
* @param {ol.CoordinateArray} coordinates Vertex array (e.g.
|
||||
* [[x0, y0], [x1, y1]]).
|
||||
* @todo stability experimental
|
||||
*/
|
||||
ol.geom.LinearRing = function(coordinates) {
|
||||
goog.base(this, coordinates);
|
||||
|
||||
/**
|
||||
* We're intentionally not enforcing that rings be closed right now. This
|
||||
* will allow proper rendering of data from tiled vector sources that leave
|
||||
* open rings.
|
||||
*/
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.LinearRing, ol.geom.LineString);
|
||||
|
||||
|
||||
/**
|
||||
* Determine if a vertex array representing a linear ring is in clockwise
|
||||
* order.
|
||||
*
|
||||
* This method comes from Green's Theorem and was mentioned in an answer to a
|
||||
* a Stack Overflow question (http://tinyurl.com/clockwise-method).
|
||||
*
|
||||
* Note that calculating the cross product for each pair of edges could be
|
||||
* avoided by first finding the lowest, rightmost vertex. See OGR's
|
||||
* implementation for an example of this.
|
||||
* https://github.com/OSGeo/gdal/blob/trunk/gdal/ogr/ogrlinearring.cpp
|
||||
*
|
||||
* @param {ol.CoordinateArray} coordinates Linear ring coordinates.
|
||||
* @return {boolean} The coordinates are in clockwise order.
|
||||
*/
|
||||
ol.geom.LinearRing.isClockwise = function(coordinates) {
|
||||
var length = coordinates.length;
|
||||
var edge = 0;
|
||||
|
||||
var last = coordinates[length - 1];
|
||||
var x1 = last[0];
|
||||
var y1 = last[1];
|
||||
|
||||
var x2, y2, coord;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
coord = coordinates[i];
|
||||
x2 = coord[0];
|
||||
y2 = coord[1];
|
||||
edge += (x2 - x1) * (y2 + y1);
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
return edge > 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.LinearRing.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.LINEARRING;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check whether a given coordinate is inside this ring. Note that this is a
|
||||
* fast and simple check - points on an edge or vertex of the ring are either
|
||||
* classified inside or outside.
|
||||
*
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @return {boolean} Whether the coordinate is inside the ring.
|
||||
*/
|
||||
ol.geom.LinearRing.prototype.containsCoordinate = function(coordinate) {
|
||||
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
|
||||
var x = coordinate[0], y = coordinate[1];
|
||||
var vertices = this.getCoordinates();
|
||||
var inside = false;
|
||||
var xi, yi, xj, yj, intersect;
|
||||
var numVertices = vertices.length;
|
||||
for (var i = 0, j = numVertices - 1; i < numVertices; j = i++) {
|
||||
xi = vertices[i][0];
|
||||
yi = vertices[i][1];
|
||||
xj = vertices[j][0];
|
||||
yj = vertices[j][1];
|
||||
intersect = ((yi > y) != (yj > y)) &&
|
||||
(x < (xj - xi) * (y - yi) / (yj - yi) + xi);
|
||||
if (intersect) {
|
||||
inside = !inside;
|
||||
}
|
||||
}
|
||||
return inside;
|
||||
};
|
||||
@@ -0,0 +1,138 @@
|
||||
goog.provide('ol.geom.LineString');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.CoordinateArray');
|
||||
goog.require('ol.coordinate');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryEvent');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.Geometry}
|
||||
* @param {ol.CoordinateArray} coordinates Array of coordinates (e.g.
|
||||
* [[x0, y0], [x1, y1]]).
|
||||
* @todo stability experimental
|
||||
*/
|
||||
ol.geom.LineString = function(coordinates) {
|
||||
goog.base(this);
|
||||
goog.asserts.assert(goog.isArray(coordinates[0]));
|
||||
|
||||
/**
|
||||
* Array of coordinates.
|
||||
* @type {ol.CoordinateArray}
|
||||
* @private
|
||||
*/
|
||||
this.coordinates_ = coordinates;
|
||||
|
||||
/**
|
||||
* @type {ol.Extent}
|
||||
* @private
|
||||
*/
|
||||
this.bounds_ = null;
|
||||
|
||||
};
|
||||
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) {
|
||||
var coordinates = this.getCoordinates();
|
||||
goog.asserts.assert(coordinates.length > index);
|
||||
return coordinates[index][dim];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {ol.CoordinateArray} Coordinates array.
|
||||
*/
|
||||
ol.geom.LineString.prototype.getCoordinates = function() {
|
||||
return this.coordinates_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the count of vertices in this linestring.
|
||||
* @return {number} The vertex count.
|
||||
*/
|
||||
ol.geom.LineString.prototype.getCount = function() {
|
||||
return this.getCoordinates().length;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.LineString.prototype.getBounds = function() {
|
||||
if (goog.isNull(this.bounds_)) {
|
||||
var coordinates = this.getCoordinates();
|
||||
var extent = ol.extent.createEmpty();
|
||||
for (var i = 0, ii = coordinates.length; i < ii; ++i) {
|
||||
ol.extent.extendCoordinate(extent, coordinates[i]);
|
||||
}
|
||||
this.bounds_ = extent;
|
||||
}
|
||||
return this.bounds_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.LineString.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.LINESTRING;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the distance from a coordinate to this linestring.
|
||||
*
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @return {number} Distance from the coordinate to this linestring.
|
||||
*/
|
||||
ol.geom.LineString.prototype.distanceFromCoordinate = function(coordinate) {
|
||||
var coordinates = this.getCoordinates();
|
||||
var dist2 = Infinity;
|
||||
for (var i = 0, j = 1, len = coordinates.length; j < len; i = j++) {
|
||||
dist2 = Math.min(dist2, ol.coordinate.squaredDistanceToSegment(coordinate,
|
||||
[coordinates[i], coordinates[j]]));
|
||||
}
|
||||
return Math.sqrt(dist2);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the linestring coordinates.
|
||||
* @param {ol.CoordinateArray} coordinates Coordinates array.
|
||||
*/
|
||||
ol.geom.LineString.prototype.setCoordinates = function(coordinates) {
|
||||
var oldBounds = this.bounds_;
|
||||
this.bounds_ = null;
|
||||
this.coordinates_ = coordinates;
|
||||
this.dispatchEvent(new ol.geom.GeometryEvent(goog.events.EventType.CHANGE,
|
||||
this, oldBounds));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.LineString.prototype.transform = function(transform) {
|
||||
var coordinates = this.getCoordinates();
|
||||
var coord;
|
||||
for (var i = 0, ii = coordinates.length; i < ii; ++i) {
|
||||
coord = coordinates[i];
|
||||
transform(coord, coord, coord.length);
|
||||
}
|
||||
this.setCoordinates(coordinates); // for change event
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
goog.provide('ol.geom.MultiLineString');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.CoordinateArray');
|
||||
goog.require('ol.geom.AbstractCollection');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.LineString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.AbstractCollection}
|
||||
* @param {Array.<ol.CoordinateArray>} coordinates Coordinates array.
|
||||
* @todo stability experimental
|
||||
*/
|
||||
ol.geom.MultiLineString = function(coordinates) {
|
||||
goog.base(this);
|
||||
goog.asserts.assert(goog.isArray(coordinates[0][0]));
|
||||
|
||||
var numParts = coordinates.length;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.LineString>}
|
||||
* @protected
|
||||
*/
|
||||
this.components = new Array(numParts);
|
||||
for (var i = 0; i < numParts; ++i) {
|
||||
var component = new ol.geom.LineString(coordinates[i]);
|
||||
this.components[i] = component;
|
||||
goog.events.listen(component, goog.events.EventType.CHANGE,
|
||||
this.handleComponentChange, false, this);
|
||||
}
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.MultiLineString, ol.geom.AbstractCollection);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.MultiLineString.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.MULTILINESTRING;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the distance from a coordinate to this multilinestring. This is
|
||||
* the closest distance of the coordinate to one of this multilinestring's
|
||||
* components.<
|
||||
*
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @return {number} Distance from the coordinate to this multilinestring.
|
||||
*/
|
||||
ol.geom.MultiLineString.prototype.distanceFromCoordinate =
|
||||
function(coordinate) {
|
||||
var distance = Infinity;
|
||||
for (var i = 0, ii = this.components.length; i < ii; ++i) {
|
||||
distance = Math.min(distance,
|
||||
this.components[i].distanceFromCoordinate(coordinate));
|
||||
}
|
||||
return distance;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a multi-linestring geometry from an array of linestring geometries.
|
||||
*
|
||||
* @param {Array.<ol.geom.LineString>} geometries Array of geometries.
|
||||
* @return {ol.geom.MultiLineString} A new geometry.
|
||||
*/
|
||||
ol.geom.MultiLineString.fromParts = function(geometries) {
|
||||
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);
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
goog.provide('ol.geom.MultiPoint');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.CoordinateArray');
|
||||
goog.require('ol.geom.AbstractCollection');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.Point');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.AbstractCollection}
|
||||
* @param {ol.CoordinateArray} coordinates Coordinates array.
|
||||
* @todo stability experimental
|
||||
*/
|
||||
ol.geom.MultiPoint = function(coordinates) {
|
||||
goog.base(this);
|
||||
goog.asserts.assert(goog.isArray(coordinates[0]));
|
||||
|
||||
var numParts = coordinates.length;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.Point>}
|
||||
* @protected
|
||||
*/
|
||||
this.components = new Array(numParts);
|
||||
for (var i = 0; i < numParts; ++i) {
|
||||
var component = new ol.geom.Point(coordinates[i]);
|
||||
this.components[i] = component;
|
||||
goog.events.listen(component, goog.events.EventType.CHANGE,
|
||||
this.handleComponentChange, false, this);
|
||||
}
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.MultiPoint, ol.geom.AbstractCollection);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.MultiPoint.prototype.getType = function() {
|
||||
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.
|
||||
* @return {ol.geom.MultiPoint} A new geometry.
|
||||
*/
|
||||
ol.geom.MultiPoint.fromParts = function(geometries) {
|
||||
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);
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
goog.provide('ol.geom.MultiPolygon');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.CoordinateArray');
|
||||
goog.require('ol.geom.AbstractCollection');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.Polygon');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.AbstractCollection}
|
||||
* @param {Array.<Array.<ol.CoordinateArray>>} coordinates Coordinates
|
||||
* array.
|
||||
* @todo stability experimental
|
||||
*/
|
||||
ol.geom.MultiPolygon = function(coordinates) {
|
||||
goog.base(this);
|
||||
goog.asserts.assert(goog.isArray(coordinates[0][0][0]));
|
||||
|
||||
var numParts = coordinates.length;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.Polygon>}
|
||||
* @protected
|
||||
*/
|
||||
this.components = new Array(numParts);
|
||||
for (var i = 0; i < numParts; ++i) {
|
||||
var component = new ol.geom.Polygon(coordinates[i]);
|
||||
this.components[i] = component;
|
||||
goog.events.listen(component, goog.events.EventType.CHANGE,
|
||||
this.handleComponentChange, false, this);
|
||||
}
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.MultiPolygon, ol.geom.AbstractCollection);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.MultiPolygon.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.MULTIPOLYGON;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check whether a given coordinate is inside this multipolygon.
|
||||
*
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @return {boolean} Whether the coordinate is inside the multipolygon.
|
||||
*/
|
||||
ol.geom.MultiPolygon.prototype.containsCoordinate = function(coordinate) {
|
||||
var containsCoordinate = false;
|
||||
for (var i = 0, ii = this.components.length; i < ii; ++i) {
|
||||
if (this.components[i].containsCoordinate(coordinate)) {
|
||||
containsCoordinate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return containsCoordinate;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a multi-polygon geometry from an array of polygon geometries.
|
||||
*
|
||||
* @param {Array.<ol.geom.Polygon>} geometries Array of geometries.
|
||||
* @return {ol.geom.MultiPolygon} A new geometry.
|
||||
*/
|
||||
ol.geom.MultiPolygon.fromParts = function(geometries) {
|
||||
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);
|
||||
};
|
||||
@@ -0,0 +1,97 @@
|
||||
goog.provide('ol.geom.Point');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryEvent');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.geom.Geometry}
|
||||
* @param {ol.Coordinate} coordinates Coordinate values (e.g. [x, y]).
|
||||
* @todo stability experimental
|
||||
*/
|
||||
ol.geom.Point = function(coordinates) {
|
||||
goog.base(this);
|
||||
|
||||
/**
|
||||
* Point coordinate values.
|
||||
* @type {ol.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
this.coordinates_ = coordinates;
|
||||
|
||||
/**
|
||||
* @type {ol.Extent}
|
||||
* @private
|
||||
*/
|
||||
this.bounds_ = null;
|
||||
|
||||
};
|
||||
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.getCoordinates()[dim];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.Point.prototype.getBounds = function() {
|
||||
if (goog.isNull(this.bounds_)) {
|
||||
var x = this.get(0),
|
||||
y = this.get(1);
|
||||
this.bounds_ = [x, y, x, y];
|
||||
}
|
||||
return this.bounds_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {ol.Coordinate} Coordinates array.
|
||||
*/
|
||||
ol.geom.Point.prototype.getCoordinates = function() {
|
||||
return this.coordinates_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.Point.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.POINT;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the point coordinates.
|
||||
* @param {ol.Coordinate} coordinates Coordinates array.
|
||||
*/
|
||||
ol.geom.Point.prototype.setCoordinates = function(coordinates) {
|
||||
var oldBounds = this.bounds_;
|
||||
this.bounds_ = null;
|
||||
this.coordinates_ = coordinates;
|
||||
this.dispatchEvent(new ol.geom.GeometryEvent(goog.events.EventType.CHANGE,
|
||||
this, oldBounds));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.Point.prototype.transform = function(transform) {
|
||||
var coordinates = this.getCoordinates();
|
||||
transform(coordinates, coordinates, coordinates.length);
|
||||
this.setCoordinates(coordinates); // for change event
|
||||
};
|
||||
@@ -0,0 +1,207 @@
|
||||
goog.provide('ol.geom.Polygon');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.CoordinateArray');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.geom.Geometry');
|
||||
goog.require('ol.geom.GeometryEvent');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.LinearRing');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a polygon from an array of vertex arrays. Coordinates for the
|
||||
* exterior ring will be forced to clockwise order. Coordinates for any
|
||||
* interior rings will be forced to counter-clockwise order. In cases where
|
||||
* the opposite winding order occurs in the passed vertex arrays, they will
|
||||
* be modified in place.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.geom.Geometry}
|
||||
* @param {Array.<ol.CoordinateArray>} coordinates Array of rings. First
|
||||
* is outer, any remaining are inner.
|
||||
* @todo stability experimental
|
||||
*/
|
||||
ol.geom.Polygon = function(coordinates) {
|
||||
goog.base(this);
|
||||
goog.asserts.assert(goog.isArray(coordinates[0][0]));
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Coordinate}
|
||||
*/
|
||||
this.labelPoint_ = null;
|
||||
|
||||
var numRings = coordinates.length;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.geom.LinearRing>}
|
||||
* @private
|
||||
*/
|
||||
this.rings_ = new Array(numRings);
|
||||
var ringCoords, ring;
|
||||
for (var i = 0; i < numRings; ++i) {
|
||||
ringCoords = coordinates[i];
|
||||
if (i === 0) {
|
||||
// force exterior ring to be clockwise
|
||||
if (!ol.geom.LinearRing.isClockwise(ringCoords)) {
|
||||
ringCoords.reverse();
|
||||
}
|
||||
} else {
|
||||
// force interior rings to be counter-clockwise
|
||||
if (ol.geom.LinearRing.isClockwise(ringCoords)) {
|
||||
ringCoords.reverse();
|
||||
}
|
||||
}
|
||||
ring = new ol.geom.LinearRing(ringCoords);
|
||||
goog.events.listen(ring, goog.events.EventType.CHANGE,
|
||||
this.handleRingChange_, false, this);
|
||||
this.rings_[i] = ring;
|
||||
}
|
||||
|
||||
};
|
||||
goog.inherits(ol.geom.Polygon, ol.geom.Geometry);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.Polygon.prototype.getBounds = function() {
|
||||
return this.rings_[0].getBounds();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<ol.CoordinateArray>} Coordinates array.
|
||||
* @todo stability experimental
|
||||
*/
|
||||
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
|
||||
*/
|
||||
ol.geom.Polygon.prototype.getType = function() {
|
||||
return ol.geom.GeometryType.POLYGON;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get polygon rings.
|
||||
* @return {Array.<ol.geom.LinearRing>} Array of rings. The first ring is the
|
||||
* exterior and any additional rings are interior.
|
||||
*/
|
||||
ol.geom.Polygon.prototype.getRings = function() {
|
||||
return this.rings_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Listener for ring change events.
|
||||
* @param {ol.geom.GeometryEvent} evt Geometry event.
|
||||
* @private
|
||||
*/
|
||||
ol.geom.Polygon.prototype.handleRingChange_ = function(evt) {
|
||||
var ring = evt.target;
|
||||
var oldExtent = null;
|
||||
if (ring === this.rings_[0]) {
|
||||
oldExtent = evt.oldExtent;
|
||||
} else {
|
||||
oldExtent = this.getBounds();
|
||||
}
|
||||
this.dispatchEvent(new ol.geom.GeometryEvent(goog.events.EventType.CHANGE,
|
||||
this, oldExtent));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check whether a given coordinate is inside this polygon. Note that this is a
|
||||
* fast and simple check - points on an edge or vertex of the polygon or one of
|
||||
* its inner rings are either classified inside or outside.
|
||||
*
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @return {boolean} Whether the coordinate is inside the polygon.
|
||||
*/
|
||||
ol.geom.Polygon.prototype.containsCoordinate = function(coordinate) {
|
||||
var rings = this.rings_;
|
||||
/** @type {boolean} */
|
||||
var containsCoordinate;
|
||||
for (var i = 0, ii = rings.length; i < ii; ++i) {
|
||||
containsCoordinate = rings[i].containsCoordinate(coordinate);
|
||||
// if inner ring (i > 0) contains coordinate, polygon does not contain it
|
||||
if (i > 0) {
|
||||
containsCoordinate = !containsCoordinate;
|
||||
}
|
||||
if (!containsCoordinate) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return containsCoordinate;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculates a point that is guaranteed to lie in the interior of the polygon.
|
||||
* Inspired by JTS's com.vividsolutions.jts.geom.Geometry#getInteriorPoint.
|
||||
* @return {ol.Coordinate} A point which is in the interior of the polygon.
|
||||
*/
|
||||
ol.geom.Polygon.prototype.getInteriorPoint = function() {
|
||||
if (goog.isNull(this.labelPoint_)) {
|
||||
var center = ol.extent.getCenter(this.getBounds()),
|
||||
resultY = center[1],
|
||||
vertices = this.rings_[0].getCoordinates(),
|
||||
intersections = [],
|
||||
maxLength = 0,
|
||||
i, vertex1, vertex2, x, segmentLength, resultX;
|
||||
|
||||
// Calculate intersections with the horizontal bounding box center line
|
||||
for (i = vertices.length - 1; i >= 1; --i) {
|
||||
vertex1 = vertices[i];
|
||||
vertex2 = vertices[i - 1];
|
||||
if ((vertex1[1] >= resultY && vertex2[1] <= resultY) ||
|
||||
(vertex1[1] <= resultY && vertex2[1] >= resultY)) {
|
||||
x = (resultY - vertex1[1]) / (vertex2[1] - vertex1[1]) *
|
||||
(vertex2[0] - vertex1[0]) + vertex1[0];
|
||||
intersections.push(x);
|
||||
}
|
||||
}
|
||||
|
||||
// Find the longest segment of the horizontal bounding box center line that
|
||||
// has its center point inside the polygon
|
||||
intersections.sort();
|
||||
for (i = intersections.length - 1; i >= 1; --i) {
|
||||
segmentLength = Math.abs(intersections[i] - intersections[i - 1]);
|
||||
if (segmentLength > maxLength) {
|
||||
x = (intersections[i] + intersections[i - 1]) / 2;
|
||||
if (this.containsCoordinate([x, resultY])) {
|
||||
maxLength = segmentLength;
|
||||
resultX = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.labelPoint_ = [resultX, resultY];
|
||||
}
|
||||
|
||||
return this.labelPoint_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.geom.Polygon.prototype.transform = function(transform) {
|
||||
var rings = this.rings_;
|
||||
for (var i = 0, ii = rings.length; i < ii; ++i) {
|
||||
rings[i].transform(transform);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user