Merge pull request #7643 from tschaub/sphere
Replace ol/Sphere with ol/sphere
This commit is contained in:
@@ -35,6 +35,52 @@ register(proj4);
|
||||
|
||||
The map and sources no longer accept a `logo` option. Instead, if you wish to append a logo to your map, add the desired markup directly in your HTML. In addition, you can use the `attributions` property of a source to display arbitrary markup per-source with the attribution control.
|
||||
|
||||
#### Replacement of `ol/Sphere` constructor with `ol/sphere` functions
|
||||
|
||||
The `ol/Sphere` constructor has been removed. If you were using the `getGeodesicArea` method, use the `getArea` function instead. If you were using the `haversineDistance` method, use the `getDistance` function instead.
|
||||
|
||||
Examples before:
|
||||
```js
|
||||
// using ol@4
|
||||
import Sphere from 'ol/sphere';
|
||||
|
||||
var sphere = new Sphere(Sphere.DEFAULT_RADIUS);
|
||||
var area = sphere.getGeodesicArea(polygon);
|
||||
var distance = sphere.haversineDistance(g1, g2);
|
||||
```
|
||||
|
||||
Examples after:
|
||||
```js
|
||||
// using ol@5
|
||||
import {circular as circularPolygon} from 'ol/geom/Polygon';
|
||||
import {getArea, getDistance} from 'ol/sphere';
|
||||
|
||||
var area = getArea(polygon);
|
||||
var distance = getDistance(g1, g2);
|
||||
var circle = circularPolygon(center, radius);
|
||||
```
|
||||
|
||||
#### New signature for the `circular` function for creating polygons
|
||||
|
||||
The `circular` function exported from `ol/geom/Polygon` no longer requires a `Sphere` as the first argument.
|
||||
|
||||
Example before:
|
||||
```js
|
||||
// using ol@4
|
||||
import Polygon from 'ol/geom/polygon';
|
||||
import Sphere from 'ol/sphere';
|
||||
|
||||
var poly = Polygon.circular(new Sphere(Sphere.DEFAULT_RADIUS), center, radius);
|
||||
```
|
||||
|
||||
Example after:
|
||||
```js
|
||||
// using ol@5
|
||||
import {circular as circularPolygon} from 'ol/geom/Polygon';
|
||||
|
||||
var poly = circularPolygon(center, radius);
|
||||
```
|
||||
|
||||
#### Removal of optional this arguments.
|
||||
|
||||
The following methods did get the optional this (i.e. opt_this) arguments removed. Please use closures, the es6 arrow function or the bind method to achieve this effect (Bind is explained here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).
|
||||
|
||||
@@ -3,7 +3,7 @@ layout: example.html
|
||||
title: Measure
|
||||
shortdesc: Using a draw interaction to measure lengths and areas.
|
||||
docs: >
|
||||
<p>The <code>ol.Sphere.getLength()</code> and <code>ol.Sphere.getArea()</code>
|
||||
<p>The <code>getLength()</code> and <code>getArea()</code>
|
||||
functions calculate spherical lengths and areas for geometries. Lengths are
|
||||
calculated by assuming great circle segments between geometry coordinates.
|
||||
Areas are calculated as if edges of polygons were great circle segments.</p>
|
||||
@@ -11,7 +11,7 @@ docs: >
|
||||
methods return measures of projected (planar) geometries. These can be very
|
||||
different than on-the-ground measures in certain situations — in northern
|
||||
and southern latitudes using Web Mercator for example. For better results,
|
||||
use the functions on <code>ol.Sphere</code>.</p>
|
||||
use the functions in the <code>ol/sphere</code> module.</p>
|
||||
tags: "draw, edit, measure, vector"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import _ol_Map_ from '../src/ol/Map.js';
|
||||
import _ol_Observable_ from '../src/ol/Observable.js';
|
||||
import _ol_Overlay_ from '../src/ol/Overlay.js';
|
||||
import _ol_Sphere_ from '../src/ol/Sphere.js';
|
||||
import {getArea, getLength} from '../src/ol/sphere.js';
|
||||
import _ol_View_ from '../src/ol/View.js';
|
||||
import LineString from '../src/ol/geom/LineString.js';
|
||||
import Polygon from '../src/ol/geom/Polygon.js';
|
||||
@@ -144,7 +144,7 @@ var draw; // global so we can remove it later
|
||||
* @return {string} The formatted length.
|
||||
*/
|
||||
var formatLength = function(line) {
|
||||
var length = _ol_Sphere_.getLength(line);
|
||||
var length = getLength(line);
|
||||
var output;
|
||||
if (length > 100) {
|
||||
output = (Math.round(length / 1000 * 100) / 100) +
|
||||
@@ -163,7 +163,7 @@ var formatLength = function(line) {
|
||||
* @return {string} Formatted area.
|
||||
*/
|
||||
var formatArea = function(polygon) {
|
||||
var area = _ol_Sphere_.getArea(polygon);
|
||||
var area = getArea(polygon);
|
||||
var output;
|
||||
if (area > 10000) {
|
||||
output = (Math.round(area / 1000000 * 100) / 100) +
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import _ol_Feature_ from '../src/ol/Feature.js';
|
||||
import _ol_Map_ from '../src/ol/Map.js';
|
||||
import _ol_Sphere_ from '../src/ol/Sphere.js';
|
||||
import _ol_View_ from '../src/ol/View.js';
|
||||
import Polygon from '../src/ol/geom/Polygon.js';
|
||||
import {circular as circularPolygon} from '../src/ol/geom/Polygon.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import _ol_layer_Vector_ from '../src/ol/layer/Vector.js';
|
||||
import _ol_source_TileWMS_ from '../src/ol/source/TileWMS.js';
|
||||
@@ -57,13 +56,11 @@ var map3857 = new _ol_Map_({
|
||||
})
|
||||
});
|
||||
|
||||
var wgs84Sphere = new _ol_Sphere_(6378137);
|
||||
|
||||
var radius = 800000;
|
||||
var x, y;
|
||||
for (x = -180; x < 180; x += 30) {
|
||||
for (y = -90; y < 90; y += 30) {
|
||||
var circle4326 = Polygon.circular(wgs84Sphere, [x, y], radius, 64);
|
||||
var circle4326 = circularPolygon([x, y], radius, 64);
|
||||
var circle3857 = circle4326.clone().transform('EPSG:4326', 'EPSG:3857');
|
||||
vectorLayer4326.getSource().addFeature(new _ol_Feature_(circle4326));
|
||||
vectorLayer3857.getSource().addFeature(new _ol_Feature_(circle3857));
|
||||
|
||||
@@ -4,14 +4,12 @@
|
||||
import {inherits} from './index.js';
|
||||
import _ol_GeolocationProperty_ from './GeolocationProperty.js';
|
||||
import _ol_Object_ from './Object.js';
|
||||
import _ol_Sphere_ from './Sphere.js';
|
||||
import _ol_events_ from './events.js';
|
||||
import EventType from './events/EventType.js';
|
||||
import Polygon from './geom/Polygon.js';
|
||||
import {circular as circularPolygon} from './geom/Polygon.js';
|
||||
import _ol_has_ from './has.js';
|
||||
import {toRadians} from './math.js';
|
||||
import {get as getProjection, getTransformFromProjections, identityTransform} from './proj.js';
|
||||
import _ol_proj_EPSG4326_ from './proj/EPSG4326.js';
|
||||
|
||||
|
||||
/**
|
||||
@@ -74,12 +72,6 @@ var Geolocation = function(opt_options) {
|
||||
*/
|
||||
this.transform_ = identityTransform;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Sphere}
|
||||
*/
|
||||
this.sphere_ = new _ol_Sphere_(_ol_proj_EPSG4326_.RADIUS);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
@@ -175,8 +167,7 @@ Geolocation.prototype.positionChange_ = function(position) {
|
||||
this.set(_ol_GeolocationProperty_.POSITION, projectedPosition);
|
||||
this.set(_ol_GeolocationProperty_.SPEED,
|
||||
coords.speed === null ? undefined : coords.speed);
|
||||
var geometry = Polygon.circular(
|
||||
this.sphere_, this.position_, coords.accuracy);
|
||||
var geometry = circularPolygon(this.position_, coords.accuracy);
|
||||
geometry.applyTransform(this.transform_);
|
||||
this.set(_ol_GeolocationProperty_.ACCURACY_GEOMETRY, geometry);
|
||||
this.changed();
|
||||
|
||||
@@ -15,7 +15,7 @@ import _ol_coordinate_ from './coordinate.js';
|
||||
import {inAndOut} from './easing.js';
|
||||
import {getForViewAndSize, getCenter, getHeight, getWidth, isEmpty} from './extent.js';
|
||||
import GeometryType from './geom/GeometryType.js';
|
||||
import Polygon from './geom/Polygon.js';
|
||||
import {fromExtent as polygonFromExtent} from './geom/Polygon.js';
|
||||
import SimpleGeometry from './geom/SimpleGeometry.js';
|
||||
import {clamp, modulo} from './math.js';
|
||||
import _ol_obj_ from './obj.js';
|
||||
@@ -884,10 +884,10 @@ _ol_View_.prototype.fit = function(geometryOrExtent, opt_options) {
|
||||
24); // Invalid extent or geometry provided as `geometry`
|
||||
assert(!isEmpty(geometryOrExtent),
|
||||
25); // Cannot fit empty extent provided as `geometry`
|
||||
geometry = Polygon.fromExtent(geometryOrExtent);
|
||||
geometry = polygonFromExtent(geometryOrExtent);
|
||||
} else if (geometryOrExtent.getType() === GeometryType.CIRCLE) {
|
||||
geometryOrExtent = geometryOrExtent.getExtent();
|
||||
geometry = Polygon.fromExtent(geometryOrExtent);
|
||||
geometry = polygonFromExtent(geometryOrExtent);
|
||||
geometry.rotate(this.getRotation(), getCenter(geometryOrExtent));
|
||||
} else {
|
||||
geometry = geometryOrExtent;
|
||||
|
||||
@@ -9,6 +9,7 @@ import GeometryType from '../geom/GeometryType.js';
|
||||
import LinearRing from '../geom/LinearRing.js';
|
||||
import Point from '../geom/Point.js';
|
||||
import SimpleGeometry from '../geom/SimpleGeometry.js';
|
||||
import {offset as sphereOffset} from '../sphere.js';
|
||||
import _ol_geom_flat_area_ from '../geom/flat/area.js';
|
||||
import _ol_geom_flat_closest_ from '../geom/flat/closest.js';
|
||||
import _ol_geom_flat_contains_ from '../geom/flat/contains.js';
|
||||
@@ -366,32 +367,35 @@ Polygon.prototype.setFlatCoordinates = function(layout, flatCoordinates, ends) {
|
||||
this.changed();
|
||||
};
|
||||
|
||||
export default Polygon;
|
||||
|
||||
|
||||
/**
|
||||
* Create an approximation of a circle on the surface of a sphere.
|
||||
* @param {ol.Sphere} sphere The sphere.
|
||||
* @param {ol.Coordinate} center Center (`[lon, lat]` in degrees).
|
||||
* @param {number} radius The great-circle distance from the center to
|
||||
* the polygon vertices.
|
||||
* @param {number=} opt_n Optional number of vertices for the resulting
|
||||
* polygon. Default is `32`.
|
||||
* @param {number=} opt_sphereRadius Optional radius for the sphere (defaults to
|
||||
* the Earth's mean radius using the WGS84 ellipsoid).
|
||||
* @return {ol.geom.Polygon} The "circular" polygon.
|
||||
* @api
|
||||
*/
|
||||
Polygon.circular = function(sphere, center, radius, opt_n) {
|
||||
export function circular(center, radius, opt_n, opt_sphereRadius) {
|
||||
var n = opt_n ? opt_n : 32;
|
||||
/** @type {Array.<number>} */
|
||||
var flatCoordinates = [];
|
||||
var i;
|
||||
for (i = 0; i < n; ++i) {
|
||||
extend(flatCoordinates, sphere.offset(center, radius, 2 * Math.PI * i / n));
|
||||
extend(flatCoordinates, sphereOffset(center, radius, 2 * Math.PI * i / n, opt_sphereRadius));
|
||||
}
|
||||
flatCoordinates.push(flatCoordinates[0], flatCoordinates[1]);
|
||||
var polygon = new Polygon(null);
|
||||
polygon.setFlatCoordinates(
|
||||
GeometryLayout.XY, flatCoordinates, [flatCoordinates.length]);
|
||||
return polygon;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -400,7 +404,7 @@ Polygon.circular = function(sphere, center, radius, opt_n) {
|
||||
* @return {ol.geom.Polygon} The polygon.
|
||||
* @api
|
||||
*/
|
||||
Polygon.fromExtent = function(extent) {
|
||||
export function fromExtent(extent) {
|
||||
var minX = extent[0];
|
||||
var minY = extent[1];
|
||||
var maxX = extent[2];
|
||||
@@ -411,7 +415,7 @@ Polygon.fromExtent = function(extent) {
|
||||
polygon.setFlatCoordinates(
|
||||
GeometryLayout.XY, flatCoordinates, [flatCoordinates.length]);
|
||||
return polygon;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -423,7 +427,7 @@ Polygon.fromExtent = function(extent) {
|
||||
* @return {ol.geom.Polygon} Polygon geometry.
|
||||
* @api
|
||||
*/
|
||||
Polygon.fromCircle = function(circle, opt_sides, opt_angle) {
|
||||
export function fromCircle(circle, opt_sides, opt_angle) {
|
||||
var sides = opt_sides ? opt_sides : 32;
|
||||
var stride = circle.getStride();
|
||||
var layout = circle.getLayout();
|
||||
@@ -435,10 +439,9 @@ Polygon.fromCircle = function(circle, opt_sides, opt_angle) {
|
||||
}
|
||||
var ends = [flatCoordinates.length];
|
||||
polygon.setFlatCoordinates(layout, flatCoordinates, ends);
|
||||
Polygon.makeRegular(
|
||||
polygon, circle.getCenter(), circle.getRadius(), opt_angle);
|
||||
makeRegular(polygon, circle.getCenter(), circle.getRadius(), opt_angle);
|
||||
return polygon;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -449,7 +452,7 @@ Polygon.fromCircle = function(circle, opt_sides, opt_angle) {
|
||||
* @param {number=} opt_angle Start angle for the first vertex of the polygon in
|
||||
* radians. Default is 0.
|
||||
*/
|
||||
Polygon.makeRegular = function(polygon, center, radius, opt_angle) {
|
||||
export function makeRegular(polygon, center, radius, opt_angle) {
|
||||
var flatCoordinates = polygon.getFlatCoordinates();
|
||||
var layout = polygon.getLayout();
|
||||
var stride = polygon.getStride();
|
||||
@@ -464,5 +467,4 @@ Polygon.makeRegular = function(polygon, center, radius, opt_angle) {
|
||||
flatCoordinates[offset + 1] = center[1] + (radius * Math.sin(angle));
|
||||
}
|
||||
polygon.setFlatCoordinates(layout, flatCoordinates, ends);
|
||||
};
|
||||
export default Polygon;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import MultiLineString from '../geom/MultiLineString.js';
|
||||
import MultiPoint from '../geom/MultiPoint.js';
|
||||
import MultiPolygon from '../geom/MultiPolygon.js';
|
||||
import Point from '../geom/Point.js';
|
||||
import Polygon from '../geom/Polygon.js';
|
||||
import Polygon, {fromCircle, makeRegular} from '../geom/Polygon.js';
|
||||
import DrawEventType from '../interaction/DrawEventType.js';
|
||||
import _ol_interaction_Pointer_ from '../interaction/Pointer.js';
|
||||
import _ol_interaction_Property_ from '../interaction/Property.js';
|
||||
@@ -795,10 +795,10 @@ Draw.createRegularPolygon = function(opt_sides, opt_angle) {
|
||||
var radius = Math.sqrt(
|
||||
_ol_coordinate_.squaredDistance(center, end));
|
||||
var geometry = opt_geometry ? /** @type {ol.geom.Polygon} */ (opt_geometry) :
|
||||
Polygon.fromCircle(new Circle(center), opt_sides);
|
||||
fromCircle(new Circle(center), opt_sides);
|
||||
var angle = opt_angle ? opt_angle :
|
||||
Math.atan((end[1] - center[1]) / (end[0] - center[0]));
|
||||
Polygon.makeRegular(geometry, center, radius, angle);
|
||||
makeRegular(geometry, center, radius, angle);
|
||||
return geometry;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -10,7 +10,7 @@ import Event from '../events/Event.js';
|
||||
import {boundingExtent, getArea} from '../extent.js';
|
||||
import GeometryType from '../geom/GeometryType.js';
|
||||
import Point from '../geom/Point.js';
|
||||
import Polygon from '../geom/Polygon.js';
|
||||
import {fromExtent as polygonFromExtent} from '../geom/Polygon.js';
|
||||
import _ol_interaction_ExtentEventType_ from '../interaction/ExtentEventType.js';
|
||||
import _ol_interaction_Pointer_ from '../interaction/Pointer.js';
|
||||
import _ol_layer_Vector_ from '../layer/Vector.js';
|
||||
@@ -376,7 +376,7 @@ _ol_interaction_Extent_.prototype.createOrUpdateExtentFeature_ = function(extent
|
||||
if (!extent) {
|
||||
extentFeature = new _ol_Feature_({});
|
||||
} else {
|
||||
extentFeature = new _ol_Feature_(Polygon.fromExtent(extent));
|
||||
extentFeature = new _ol_Feature_(polygonFromExtent(extent));
|
||||
}
|
||||
this.extentFeature_ = extentFeature;
|
||||
this.extentOverlay_.getSource().addFeature(extentFeature);
|
||||
@@ -384,7 +384,7 @@ _ol_interaction_Extent_.prototype.createOrUpdateExtentFeature_ = function(extent
|
||||
if (!extent) {
|
||||
extentFeature.setGeometry(undefined);
|
||||
} else {
|
||||
extentFeature.setGeometry(Polygon.fromExtent(extent));
|
||||
extentFeature.setGeometry(polygonFromExtent(extent));
|
||||
}
|
||||
}
|
||||
return extentFeature;
|
||||
|
||||
@@ -10,7 +10,7 @@ import EventType from '../events/EventType.js';
|
||||
import {boundingExtent, createEmpty} from '../extent.js';
|
||||
import {TRUE, FALSE} from '../functions.js';
|
||||
import GeometryType from '../geom/GeometryType.js';
|
||||
import Polygon from '../geom/Polygon.js';
|
||||
import {fromCircle} from '../geom/Polygon.js';
|
||||
import _ol_interaction_Pointer_ from '../interaction/Pointer.js';
|
||||
import _ol_obj_ from '../obj.js';
|
||||
import _ol_source_Vector_ from '../source/Vector.js';
|
||||
@@ -435,7 +435,7 @@ _ol_interaction_Snap_.prototype.updateFeature_ = function(feature) {
|
||||
* @private
|
||||
*/
|
||||
_ol_interaction_Snap_.prototype.writeCircleGeometry_ = function(feature, geometry) {
|
||||
var polygon = Polygon.fromCircle(geometry);
|
||||
var polygon = fromCircle(geometry);
|
||||
var coordinates = polygon.getCoordinates()[0];
|
||||
var i, ii, segment, segmentData;
|
||||
for (i = 0, ii = coordinates.length - 1; i < ii; ++i) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @module ol/proj
|
||||
*/
|
||||
import Sphere from './Sphere.js';
|
||||
import {getDistance} from './sphere.js';
|
||||
import {applyTransform} from './extent.js';
|
||||
import {modulo} from './math.js';
|
||||
import EPSG3857 from './proj/EPSG3857.js';
|
||||
@@ -21,13 +21,6 @@ import {add as addTransformFunc, clear as clearTransformFuncs, get as getTransfo
|
||||
export var METERS_PER_UNIT = Units.METERS_PER_UNIT;
|
||||
|
||||
|
||||
/**
|
||||
* A place to store the mean radius of the Earth.
|
||||
* @type {ol.Sphere}
|
||||
*/
|
||||
var SPHERE = new Sphere(Sphere.DEFAULT_RADIUS);
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<number>} input Input coordinate array.
|
||||
* @param {Array.<number>=} opt_output Output array of coordinate values.
|
||||
@@ -150,10 +143,8 @@ export function getPointResolution(projection, resolution, point, opt_units) {
|
||||
point[0], point[1] + resolution / 2
|
||||
];
|
||||
vertices = toEPSG4326(vertices, vertices, 2);
|
||||
var width = SPHERE.haversineDistance(
|
||||
vertices.slice(0, 2), vertices.slice(2, 4));
|
||||
var height = SPHERE.haversineDistance(
|
||||
vertices.slice(4, 6), vertices.slice(6, 8));
|
||||
var width = getDistance(vertices.slice(0, 2), vertices.slice(2, 4));
|
||||
var height = getDistance(vertices.slice(4, 6), vertices.slice(6, 8));
|
||||
pointResolution = (width + height) / 2;
|
||||
var metersPerUnit = opt_units ?
|
||||
Units.METERS_PER_UNIT[opt_units] :
|
||||
|
||||
@@ -1,113 +1,69 @@
|
||||
/**
|
||||
* @module ol/Sphere
|
||||
*/
|
||||
* @license
|
||||
* Latitude/longitude spherical geodesy formulae taken from
|
||||
* http://www.movable-type.co.uk/scripts/latlong.html
|
||||
* Licensed under CC-BY-3.0.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Latitude/longitude spherical geodesy formulae taken from
|
||||
* http://www.movable-type.co.uk/scripts/latlong.html
|
||||
* Licensed under CC-BY-3.0.
|
||||
* @module ol/Sphere
|
||||
*/
|
||||
import {toRadians, toDegrees} from './math.js';
|
||||
import GeometryType from './geom/GeometryType.js';
|
||||
|
||||
|
||||
/**
|
||||
* Object literal with options for the {@link ol.Sphere.getLength} or
|
||||
* {@link ol.Sphere.getArea} functions.
|
||||
* Object literal with options for the {@link getLength} or
|
||||
* {@link getArea} functions.
|
||||
* @typedef {{projection: (ol.ProjectionLike|undefined),
|
||||
* radius: (number|undefined)}}
|
||||
*/
|
||||
export var SphereMetricOptions;
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Class to create objects that can be used with {@link
|
||||
* ol.geom.Polygon.circular}.
|
||||
*
|
||||
* For example to create a sphere whose radius is equal to the semi-major
|
||||
* axis of the WGS84 ellipsoid:
|
||||
*
|
||||
* ```js
|
||||
* var wgs84Sphere= new ol.Sphere(6378137);
|
||||
* ```
|
||||
*
|
||||
* @constructor
|
||||
* @param {number} radius Radius.
|
||||
* @api
|
||||
*/
|
||||
var _ol_Sphere_ = function(radius) {
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.radius = radius;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the geodesic area for a list of coordinates.
|
||||
*
|
||||
* [Reference](https://trs-new.jpl.nasa.gov/handle/2014/40409)
|
||||
* Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
|
||||
* Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
|
||||
* Laboratory, Pasadena, CA, June 2007
|
||||
*
|
||||
* @param {Array.<ol.Coordinate>} coordinates List of coordinates of a linear
|
||||
* ring. If the ring is oriented clockwise, the area will be positive,
|
||||
* otherwise it will be negative.
|
||||
* @return {number} Area.
|
||||
* @api
|
||||
*/
|
||||
_ol_Sphere_.prototype.geodesicArea = function(coordinates) {
|
||||
return _ol_Sphere_.getArea_(coordinates, this.radius);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the distance from c1 to c2 using the haversine formula.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 Coordinate 1.
|
||||
* @param {ol.Coordinate} c2 Coordinate 2.
|
||||
* @return {number} Haversine distance.
|
||||
* @api
|
||||
*/
|
||||
_ol_Sphere_.prototype.haversineDistance = function(c1, c2) {
|
||||
return _ol_Sphere_.getDistance_(c1, c2, this.radius);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the coordinate at the given distance and bearing from `c1`.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 The origin point (`[lon, lat]` in degrees).
|
||||
* @param {number} distance The great-circle distance between the origin
|
||||
* point and the target point.
|
||||
* @param {number} bearing The bearing (in radians).
|
||||
* @return {ol.Coordinate} The target point.
|
||||
*/
|
||||
_ol_Sphere_.prototype.offset = function(c1, distance, bearing) {
|
||||
var lat1 = toRadians(c1[1]);
|
||||
var lon1 = toRadians(c1[0]);
|
||||
var dByR = distance / this.radius;
|
||||
var lat = Math.asin(
|
||||
Math.sin(lat1) * Math.cos(dByR) +
|
||||
Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing));
|
||||
var lon = lon1 + Math.atan2(
|
||||
Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1),
|
||||
Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat));
|
||||
return [toDegrees(lon), toDegrees(lat)];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The mean Earth radius (1/3 * (2a + b)) for the WGS84 ellipsoid.
|
||||
* https://en.wikipedia.org/wiki/Earth_radius#Mean_radius
|
||||
* @type {number}
|
||||
*/
|
||||
_ol_Sphere_.DEFAULT_RADIUS = 6371008.8;
|
||||
export var DEFAULT_RADIUS = 6371008.8;
|
||||
|
||||
|
||||
/**
|
||||
* Get the great circle distance (in meters) between two geographic coordinates.
|
||||
* @param {Array} c1 Starting coordinate.
|
||||
* @param {Array} c2 Ending coordinate.
|
||||
* @param {number=} opt_radius The sphere radius to use. Defaults to the Earth's
|
||||
* mean radius using the WGS84 ellipsoid.
|
||||
* @return {number} The great circle distance between the points (in meters).
|
||||
* @api
|
||||
*/
|
||||
export function getDistance(c1, c2, opt_radius) {
|
||||
var radius = opt_radius || DEFAULT_RADIUS;
|
||||
var lat1 = toRadians(c1[1]);
|
||||
var lat2 = toRadians(c2[1]);
|
||||
var deltaLatBy2 = (lat2 - lat1) / 2;
|
||||
var deltaLonBy2 = toRadians(c2[0] - c1[0]) / 2;
|
||||
var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) +
|
||||
Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) *
|
||||
Math.cos(lat1) * Math.cos(lat2);
|
||||
return 2 * radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the cumulative great circle length of linestring coordinates (geographic).
|
||||
* @param {Array} coordinates Linestring coordinates.
|
||||
* @param {number} radius The sphere radius to use.
|
||||
* @return {number} The length (in meters).
|
||||
*/
|
||||
function getLengthInternal(coordinates, radius) {
|
||||
var length = 0;
|
||||
for (var i = 0, ii = coordinates.length; i < ii - 1; ++i) {
|
||||
length += getDistance(coordinates[i], coordinates[i + 1], radius);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -122,17 +78,19 @@ _ol_Sphere_.DEFAULT_RADIUS = 6371008.8;
|
||||
* @param {(ol.ProjectionLike|undefined)} opt_options.projection Projection of
|
||||
* the geometry. By default, the geometry is assumed to be in EPSG:3857
|
||||
* (Web Mercator).
|
||||
* @param {(number|undefined)} opt_options.radius Sphere radius. By default,
|
||||
* the radius of the earth is used (Clarke 1866 Authalic Sphere).
|
||||
* @param {(number|undefined)} opt_options.radius Sphere radius. Defaults to
|
||||
* the Earth's mean radius using the WGS84 ellipsoid.
|
||||
* @return {number} The spherical length (in meters).
|
||||
* @api
|
||||
*/
|
||||
_ol_Sphere_.getLength = function(geometry, opt_options) {
|
||||
export function getLength(geometry, opt_options) {
|
||||
var options = opt_options || {};
|
||||
var radius = options.radius || _ol_Sphere_.DEFAULT_RADIUS;
|
||||
var radius = options.radius || DEFAULT_RADIUS;
|
||||
var projection = options.projection || 'EPSG:3857';
|
||||
geometry = geometry.clone().transform(projection, 'EPSG:4326');
|
||||
var type = geometry.getType();
|
||||
if (type !== GeometryType.GEOMETRY_COLLECTION) {
|
||||
geometry = geometry.clone().transform(projection, 'EPSG:4326');
|
||||
}
|
||||
var length = 0;
|
||||
var coordinates, coords, i, ii, j, jj;
|
||||
switch (type) {
|
||||
@@ -143,14 +101,14 @@ _ol_Sphere_.getLength = function(geometry, opt_options) {
|
||||
case GeometryType.LINE_STRING:
|
||||
case GeometryType.LINEAR_RING: {
|
||||
coordinates = /** @type {ol.geom.SimpleGeometry} */ (geometry).getCoordinates();
|
||||
length = _ol_Sphere_.getLength_(coordinates, radius);
|
||||
length = getLengthInternal(coordinates, radius);
|
||||
break;
|
||||
}
|
||||
case GeometryType.MULTI_LINE_STRING:
|
||||
case GeometryType.POLYGON: {
|
||||
coordinates = /** @type {ol.geom.SimpleGeometry} */ (geometry).getCoordinates();
|
||||
for (i = 0, ii = coordinates.length; i < ii; ++i) {
|
||||
length += _ol_Sphere_.getLength_(coordinates[i], radius);
|
||||
length += getLengthInternal(coordinates[i], radius);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -159,7 +117,7 @@ _ol_Sphere_.getLength = function(geometry, opt_options) {
|
||||
for (i = 0, ii = coordinates.length; i < ii; ++i) {
|
||||
coords = coordinates[i];
|
||||
for (j = 0, jj = coords.length; j < jj; ++j) {
|
||||
length += _ol_Sphere_.getLength_(coords[j], radius);
|
||||
length += getLengthInternal(coords[j], radius);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -167,7 +125,7 @@ _ol_Sphere_.getLength = function(geometry, opt_options) {
|
||||
case GeometryType.GEOMETRY_COLLECTION: {
|
||||
var geometries = /** @type {ol.geom.GeometryCollection} */ (geometry).getGeometries();
|
||||
for (i = 0, ii = geometries.length; i < ii; ++i) {
|
||||
length += _ol_Sphere_.getLength(geometries[i], opt_options);
|
||||
length += getLength(geometries[i], opt_options);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -176,101 +134,7 @@ _ol_Sphere_.getLength = function(geometry, opt_options) {
|
||||
}
|
||||
}
|
||||
return length;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the cumulative great circle length of linestring coordinates (geographic).
|
||||
* @param {Array} coordinates Linestring coordinates.
|
||||
* @param {number} radius The sphere radius to use.
|
||||
* @return {number} The length (in meters).
|
||||
*/
|
||||
_ol_Sphere_.getLength_ = function(coordinates, radius) {
|
||||
var length = 0;
|
||||
for (var i = 0, ii = coordinates.length; i < ii - 1; ++i) {
|
||||
length += _ol_Sphere_.getDistance_(coordinates[i], coordinates[i + 1], radius);
|
||||
}
|
||||
return length;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the great circle distance between two geographic coordinates.
|
||||
* @param {Array} c1 Starting coordinate.
|
||||
* @param {Array} c2 Ending coordinate.
|
||||
* @param {number} radius The sphere radius to use.
|
||||
* @return {number} The great circle distance between the points (in meters).
|
||||
*/
|
||||
_ol_Sphere_.getDistance_ = function(c1, c2, radius) {
|
||||
var lat1 = toRadians(c1[1]);
|
||||
var lat2 = toRadians(c2[1]);
|
||||
var deltaLatBy2 = (lat2 - lat1) / 2;
|
||||
var deltaLonBy2 = toRadians(c2[0] - c1[0]) / 2;
|
||||
var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) +
|
||||
Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) *
|
||||
Math.cos(lat1) * Math.cos(lat2);
|
||||
return 2 * radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the spherical area of a geometry. This is the area (in meters) assuming
|
||||
* that polygon edges are segments of great circles on a sphere.
|
||||
* @param {ol.geom.Geometry} geometry A geometry.
|
||||
* @param {SphereMetricOptions=} opt_options Options for the area
|
||||
* calculation. By default, geometries are assumed to be in 'EPSG:3857'.
|
||||
* You can change this by providing a `projection` option.
|
||||
* @return {number} The spherical area (in square meters).
|
||||
* @api
|
||||
*/
|
||||
_ol_Sphere_.getArea = function(geometry, opt_options) {
|
||||
var options = opt_options || {};
|
||||
var radius = options.radius || _ol_Sphere_.DEFAULT_RADIUS;
|
||||
var projection = options.projection || 'EPSG:3857';
|
||||
geometry = geometry.clone().transform(projection, 'EPSG:4326');
|
||||
var type = geometry.getType();
|
||||
var area = 0;
|
||||
var coordinates, coords, i, ii, j, jj;
|
||||
switch (type) {
|
||||
case GeometryType.POINT:
|
||||
case GeometryType.MULTI_POINT:
|
||||
case GeometryType.LINE_STRING:
|
||||
case GeometryType.MULTI_LINE_STRING:
|
||||
case GeometryType.LINEAR_RING: {
|
||||
break;
|
||||
}
|
||||
case GeometryType.POLYGON: {
|
||||
coordinates = /** @type {ol.geom.Polygon} */ (geometry).getCoordinates();
|
||||
area = Math.abs(_ol_Sphere_.getArea_(coordinates[0], radius));
|
||||
for (i = 1, ii = coordinates.length; i < ii; ++i) {
|
||||
area -= Math.abs(_ol_Sphere_.getArea_(coordinates[i], radius));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeometryType.MULTI_POLYGON: {
|
||||
coordinates = /** @type {ol.geom.SimpleGeometry} */ (geometry).getCoordinates();
|
||||
for (i = 0, ii = coordinates.length; i < ii; ++i) {
|
||||
coords = coordinates[i];
|
||||
area += Math.abs(_ol_Sphere_.getArea_(coords[0], radius));
|
||||
for (j = 1, jj = coords.length; j < jj; ++j) {
|
||||
area -= Math.abs(_ol_Sphere_.getArea_(coords[j], radius));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeometryType.GEOMETRY_COLLECTION: {
|
||||
var geometries = /** @type {ol.geom.GeometryCollection} */ (geometry).getGeometries();
|
||||
for (i = 0, ii = geometries.length; i < ii; ++i) {
|
||||
area += _ol_Sphere_.getArea(geometries[i], opt_options);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error('Unsupported geometry type: ' + type);
|
||||
}
|
||||
}
|
||||
return area;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -287,7 +151,7 @@ _ol_Sphere_.getArea = function(geometry, opt_options) {
|
||||
* @param {number} radius The sphere radius.
|
||||
* @return {number} Area (in square meters).
|
||||
*/
|
||||
_ol_Sphere_.getArea_ = function(coordinates, radius) {
|
||||
function getAreaInternal(coordinates, radius) {
|
||||
var area = 0, len = coordinates.length;
|
||||
var x1 = coordinates[len - 1][0];
|
||||
var y1 = coordinates[len - 1][1];
|
||||
@@ -300,5 +164,92 @@ _ol_Sphere_.getArea_ = function(coordinates, radius) {
|
||||
y1 = y2;
|
||||
}
|
||||
return area * radius * radius / 2.0;
|
||||
};
|
||||
export default _ol_Sphere_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the spherical area of a geometry. This is the area (in meters) assuming
|
||||
* that polygon edges are segments of great circles on a sphere.
|
||||
* @param {ol.geom.Geometry} geometry A geometry.
|
||||
* @param {SphereMetricOptions=} opt_options Options for the area
|
||||
* calculation. By default, geometries are assumed to be in 'EPSG:3857'.
|
||||
* You can change this by providing a `projection` option.
|
||||
* @return {number} The spherical area (in square meters).
|
||||
* @api
|
||||
*/
|
||||
export function getArea(geometry, opt_options) {
|
||||
var options = opt_options || {};
|
||||
var radius = options.radius || DEFAULT_RADIUS;
|
||||
var projection = options.projection || 'EPSG:3857';
|
||||
var type = geometry.getType();
|
||||
if (type !== GeometryType.GEOMETRY_COLLECTION) {
|
||||
geometry = geometry.clone().transform(projection, 'EPSG:4326');
|
||||
}
|
||||
var area = 0;
|
||||
var coordinates, coords, i, ii, j, jj;
|
||||
switch (type) {
|
||||
case GeometryType.POINT:
|
||||
case GeometryType.MULTI_POINT:
|
||||
case GeometryType.LINE_STRING:
|
||||
case GeometryType.MULTI_LINE_STRING:
|
||||
case GeometryType.LINEAR_RING: {
|
||||
break;
|
||||
}
|
||||
case GeometryType.POLYGON: {
|
||||
coordinates = /** @type {ol.geom.Polygon} */ (geometry).getCoordinates();
|
||||
area = Math.abs(getAreaInternal(coordinates[0], radius));
|
||||
for (i = 1, ii = coordinates.length; i < ii; ++i) {
|
||||
area -= Math.abs(getAreaInternal(coordinates[i], radius));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeometryType.MULTI_POLYGON: {
|
||||
coordinates = /** @type {ol.geom.SimpleGeometry} */ (geometry).getCoordinates();
|
||||
for (i = 0, ii = coordinates.length; i < ii; ++i) {
|
||||
coords = coordinates[i];
|
||||
area += Math.abs(getAreaInternal(coords[0], radius));
|
||||
for (j = 1, jj = coords.length; j < jj; ++j) {
|
||||
area -= Math.abs(getAreaInternal(coords[j], radius));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeometryType.GEOMETRY_COLLECTION: {
|
||||
var geometries = /** @type {ol.geom.GeometryCollection} */ (geometry).getGeometries();
|
||||
for (i = 0, ii = geometries.length; i < ii; ++i) {
|
||||
area += getArea(geometries[i], opt_options);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error('Unsupported geometry type: ' + type);
|
||||
}
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the coordinate at the given distance and bearing from `c1`.
|
||||
*
|
||||
* @param {ol.Coordinate} c1 The origin point (`[lon, lat]` in degrees).
|
||||
* @param {number} distance The great-circle distance between the origin
|
||||
* point and the target point.
|
||||
* @param {number} bearing The bearing (in radians).
|
||||
* @param {number=} opt_radius The sphere radius to use. Defaults to the Earth's
|
||||
* mean radius using the WGS84 ellipsoid.
|
||||
* @return {ol.Coordinate} The target point.
|
||||
*/
|
||||
export function offset(c1, distance, bearing, opt_radius) {
|
||||
var radius = opt_radius || DEFAULT_RADIUS;
|
||||
var lat1 = toRadians(c1[1]);
|
||||
var lon1 = toRadians(c1[0]);
|
||||
var dByR = distance / radius;
|
||||
var lat = Math.asin(
|
||||
Math.sin(lat1) * Math.cos(dByR) +
|
||||
Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing));
|
||||
var lon = lon1 + Math.atan2(
|
||||
Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1),
|
||||
Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat));
|
||||
return [toDegrees(lon), toDegrees(lat)];
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as _ol_extent_ from '../../../../src/ol/extent.js';
|
||||
import Circle from '../../../../src/ol/geom/Circle.js';
|
||||
import LinearRing from '../../../../src/ol/geom/LinearRing.js';
|
||||
import Polygon from '../../../../src/ol/geom/Polygon.js';
|
||||
import Polygon, {fromCircle, fromExtent} from '../../../../src/ol/geom/Polygon.js';
|
||||
|
||||
|
||||
describe('ol.geom.Polygon', function() {
|
||||
describe('ol/geom/Polygon', function() {
|
||||
|
||||
it('can be constructed with a null geometry', function() {
|
||||
expect(function() {
|
||||
@@ -561,10 +561,10 @@ describe('ol.geom.Polygon', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('ol.geom.Polygon.fromExtent', function() {
|
||||
describe('fromExtent()', function() {
|
||||
it('creates the correct polygon', function() {
|
||||
var extent = [1, 2, 3, 5];
|
||||
var polygon = Polygon.fromExtent(extent);
|
||||
var polygon = fromExtent(extent);
|
||||
var flatCoordinates = polygon.getFlatCoordinates();
|
||||
expect(flatCoordinates).to.eql(
|
||||
[1, 2, 1, 5, 3, 5, 3, 2, 1, 2]);
|
||||
@@ -574,11 +574,11 @@ describe('ol.geom.Polygon', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('ol.geom.Polygon.fromCircle', function() {
|
||||
describe('fromCircle()', function() {
|
||||
|
||||
it('creates a regular polygon', function() {
|
||||
var circle = new Circle([0, 0, 0], 1, 'XYZ');
|
||||
var polygon = Polygon.fromCircle(circle);
|
||||
var polygon = fromCircle(circle);
|
||||
var coordinates = polygon.getLinearRing(0).getCoordinates();
|
||||
expect(coordinates[0].length).to.eql(3);
|
||||
expect(coordinates[0][2]).to.eql(0);
|
||||
@@ -599,7 +599,7 @@ describe('ol.geom.Polygon', function() {
|
||||
|
||||
it('creates a regular polygon with custom sides and angle', function() {
|
||||
var circle = new Circle([0, 0], 1);
|
||||
var polygon = Polygon.fromCircle(circle, 4, Math.PI / 2);
|
||||
var polygon = fromCircle(circle, 4, Math.PI / 2);
|
||||
var coordinates = polygon.getLinearRing(0).getCoordinates();
|
||||
expect(coordinates[4]).to.eql(coordinates[0]);
|
||||
expect(coordinates[0][0]).to.roughlyEqual(0, 1e-9);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import _ol_Map_ from '../../../../src/ol/Map.js';
|
||||
import _ol_View_ from '../../../../src/ol/View.js';
|
||||
import * as _ol_extent_ from '../../../../src/ol/extent.js';
|
||||
import Polygon from '../../../../src/ol/geom/Polygon.js';
|
||||
import {fromExtent as polygonFromExtent} from '../../../../src/ol/geom/Polygon.js';
|
||||
import DragZoom from '../../../../src/ol/interaction/DragZoom.js';
|
||||
import _ol_layer_Vector_ from '../../../../src/ol/layer/Vector.js';
|
||||
import _ol_render_Box_ from '../../../../src/ol/render/Box.js';
|
||||
@@ -72,7 +72,7 @@ describe('ol.interaction.DragZoom', function() {
|
||||
|
||||
var box = new _ol_render_Box_();
|
||||
var extent = [-110, 40, -90, 60];
|
||||
box.geometry_ = Polygon.fromExtent(extent);
|
||||
box.geometry_ = polygonFromExtent(extent);
|
||||
interaction.box_ = box;
|
||||
|
||||
interaction.onBoxEnd();
|
||||
@@ -94,7 +94,7 @@ describe('ol.interaction.DragZoom', function() {
|
||||
|
||||
var box = new _ol_render_Box_();
|
||||
var extent = [-11.25, -11.25, 11.25, 11.25];
|
||||
box.geometry_ = Polygon.fromExtent(extent);
|
||||
box.geometry_ = polygonFromExtent(extent);
|
||||
interaction.box_ = box;
|
||||
|
||||
map.getView().setResolution(0.25);
|
||||
|
||||
@@ -1,97 +1,173 @@
|
||||
// See http://www.movable-type.co.uk/scripts/latlong.html
|
||||
// FIXME add tests for offset
|
||||
|
||||
|
||||
import _ol_Sphere_ from '../../../src/ol/Sphere.js';
|
||||
import {getArea, getDistance, getLength} from '../../../src/ol/sphere.js';
|
||||
import WKT from '../../../src/ol/format/WKT.js';
|
||||
import GeometryCollection from '../../../src/ol/geom/GeometryCollection.js';
|
||||
import LineString from '../../../src/ol/geom/LineString.js';
|
||||
import MultiLineString from '../../../src/ol/geom/MultiLineString.js';
|
||||
import MultiPoint from '../../../src/ol/geom/MultiPoint.js';
|
||||
import Point from '../../../src/ol/geom/Point.js';
|
||||
import _ol_proj_EPSG4326_ from '../../../src/ol/proj/EPSG4326.js';
|
||||
|
||||
|
||||
describe('ol.Sphere', function() {
|
||||
describe('ol/sphere', function() {
|
||||
|
||||
var sphere = new _ol_Sphere_(6371);
|
||||
var expected = [{
|
||||
c1: [0, 0],
|
||||
c2: [0, 0],
|
||||
haversineDistance: 0
|
||||
}, {
|
||||
c1: [0, 0],
|
||||
c2: [45, 45],
|
||||
haversineDistance: 6671.695598673525
|
||||
}, {
|
||||
c1: [0, 0],
|
||||
c2: [-45, 45],
|
||||
haversineDistance: 6671.695598673525
|
||||
}, {
|
||||
c1: [0, 0],
|
||||
c2: [-45, -45],
|
||||
haversineDistance: 6671.695598673525
|
||||
}, {
|
||||
c1: [0, 0],
|
||||
c2: [45, -45],
|
||||
haversineDistance: 6671.695598673525
|
||||
}, {
|
||||
c1: [45, 45],
|
||||
c2: [45, 45],
|
||||
haversineDistance: 0
|
||||
}, {
|
||||
c1: [45, 45],
|
||||
c2: [-45, 45],
|
||||
haversineDistance: 6671.695598673525
|
||||
}, {
|
||||
c1: [45, 45],
|
||||
c2: [-45, -45],
|
||||
haversineDistance: 13343.391197347048
|
||||
}, {
|
||||
c1: [45, 45],
|
||||
c2: [45, -45],
|
||||
haversineDistance: 10007.543398010286
|
||||
}, {
|
||||
c1: [-45, 45],
|
||||
c2: [-45, 45],
|
||||
haversineDistance: 0
|
||||
}, {
|
||||
c1: [-45, 45],
|
||||
c2: [-45, -45],
|
||||
haversineDistance: 10007.543398010286
|
||||
}, {
|
||||
c1: [-45, 45],
|
||||
c2: [45, -45],
|
||||
haversineDistance: 13343.391197347048
|
||||
}, {
|
||||
c1: [-45, -45],
|
||||
c2: [-45, -45],
|
||||
haversineDistance: 0
|
||||
}, {
|
||||
c1: [-45, -45],
|
||||
c2: [45, -45],
|
||||
haversineDistance: 6671.695598673525
|
||||
}, {
|
||||
c1: [45, -45],
|
||||
c2: [45, -45],
|
||||
haversineDistance: 0
|
||||
}];
|
||||
describe('getDistance()', function() {
|
||||
|
||||
describe('haversineDistance', function() {
|
||||
var expected = [{
|
||||
c1: [0, 0],
|
||||
c2: [0, 0],
|
||||
distance: 0
|
||||
}, {
|
||||
c1: [0, 0],
|
||||
c2: [45, 45],
|
||||
distance: 6671704.814011975
|
||||
}, {
|
||||
c1: [0, 0],
|
||||
c2: [-45, 45],
|
||||
distance: 6671704.814011975
|
||||
}, {
|
||||
c1: [0, 0],
|
||||
c2: [-45, -45],
|
||||
distance: 6671704.814011975
|
||||
}, {
|
||||
c1: [0, 0],
|
||||
c2: [45, -45],
|
||||
distance: 6671704.814011975
|
||||
}, {
|
||||
c1: [45, 45],
|
||||
c2: [45, 45],
|
||||
distance: 0
|
||||
}, {
|
||||
c1: [45, 45],
|
||||
c2: [-45, 45],
|
||||
distance: 6671704.814011975
|
||||
}, {
|
||||
c1: [45, 45],
|
||||
c2: [-45, -45],
|
||||
distance: 13343409.628023949
|
||||
}, {
|
||||
c1: [45, 45],
|
||||
c2: [45, -45],
|
||||
distance: 10007557.221017962
|
||||
}, {
|
||||
c1: [-45, 45],
|
||||
c2: [-45, 45],
|
||||
distance: 0
|
||||
}, {
|
||||
c1: [-45, 45],
|
||||
c2: [-45, -45],
|
||||
distance: 10007557.221017962
|
||||
}, {
|
||||
c1: [-45, 45],
|
||||
c2: [45, -45],
|
||||
distance: 13343409.628023949
|
||||
}, {
|
||||
c1: [-45, -45],
|
||||
c2: [-45, -45],
|
||||
distance: 0
|
||||
}, {
|
||||
c1: [-45, -45],
|
||||
c2: [45, -45],
|
||||
distance: 6671704.814011975
|
||||
}, {
|
||||
c1: [45, -45],
|
||||
c2: [45, -45],
|
||||
distance: 0
|
||||
}];
|
||||
|
||||
it('results match Chris Veness\'s reference implementation', function() {
|
||||
var e, i;
|
||||
for (i = 0; i < expected.length; ++i) {
|
||||
e = expected[i];
|
||||
expect(sphere.haversineDistance(e.c1, e.c2)).to.roughlyEqual(
|
||||
e.haversineDistance, 1e-9);
|
||||
}
|
||||
expected.forEach(function(e, i) {
|
||||
it('calculates the distance between two points: ' + i, function() {
|
||||
expect(getDistance(e.c1, e.c2)).to.roughlyEqual(e.distance, 1e-6);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLength()', function() {
|
||||
var cases = [{
|
||||
geometry: new Point([0, 0]),
|
||||
length: 0
|
||||
}, {
|
||||
geometry: new MultiPoint([[0, 0], [1, 1]]),
|
||||
length: 0
|
||||
}, {
|
||||
geometry: new LineString([
|
||||
[12801741.441226462, -3763310.627144653],
|
||||
[14582853.293918837, -2511525.2348457114],
|
||||
[15918687.18343812, -2875744.624352243],
|
||||
[16697923.618991036, -4028802.0261344076]
|
||||
]),
|
||||
length: 4407939.124914191
|
||||
}, {
|
||||
geometry: new GeometryCollection([
|
||||
new LineString([
|
||||
[12801741.441226462, -3763310.627144653],
|
||||
[14582853.293918837, -2511525.2348457114],
|
||||
[15918687.18343812, -2875744.624352243],
|
||||
[16697923.618991036, -4028802.0261344076]
|
||||
]),
|
||||
new LineString([
|
||||
[12801741.441226462, -3763310.627144653],
|
||||
[14582853.293918837, -2511525.2348457114],
|
||||
[15918687.18343812, -2875744.624352243],
|
||||
[16697923.618991036, -4028802.0261344076]
|
||||
])
|
||||
]),
|
||||
length: 2 * 4407939.124914191
|
||||
}, {
|
||||
geometry: new LineString([
|
||||
[115, -32],
|
||||
[131, -22],
|
||||
[143, -25],
|
||||
[150, -34]
|
||||
]),
|
||||
options: {projection: 'EPSG:4326'},
|
||||
length: 4407939.124914191
|
||||
}, {
|
||||
geometry: new MultiLineString([
|
||||
[
|
||||
[115, -32],
|
||||
[131, -22],
|
||||
[143, -25],
|
||||
[150, -34]
|
||||
], [
|
||||
[115, -32],
|
||||
[131, -22],
|
||||
[143, -25],
|
||||
[150, -34]
|
||||
]
|
||||
]),
|
||||
options: {projection: 'EPSG:4326'},
|
||||
length: 2 * 4407939.124914191
|
||||
}, {
|
||||
geometry: new GeometryCollection([
|
||||
new LineString([
|
||||
[115, -32],
|
||||
[131, -22],
|
||||
[143, -25],
|
||||
[150, -34]
|
||||
]),
|
||||
new LineString([
|
||||
[115, -32],
|
||||
[131, -22],
|
||||
[143, -25],
|
||||
[150, -34]
|
||||
])
|
||||
]),
|
||||
options: {projection: 'EPSG:4326'},
|
||||
length: 2 * 4407939.124914191
|
||||
}];
|
||||
|
||||
cases.forEach(function(c, i) {
|
||||
it('works for case ' + i, function() {
|
||||
var c = cases[i];
|
||||
var length = getLength(c.geometry, c.options);
|
||||
expect(length).to.roughlyEqual(c.length, 1e-8);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Vincenty area', function() {
|
||||
describe('getArea()', function() {
|
||||
var geometry;
|
||||
var expectedArea = 145652224192.4434;
|
||||
before(function(done) {
|
||||
afterLoadText('spec/ol/format/wkt/illinois.wkt', function(wkt) {
|
||||
try {
|
||||
@@ -104,100 +180,24 @@ describe('ol.Sphere', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('results match the expected area of Ilinois', function() {
|
||||
var coords = geometry.getPolygon(0).getLinearRing(0).getCoordinates();
|
||||
var sphere = new _ol_Sphere_(_ol_proj_EPSG4326_.RADIUS);
|
||||
expect(sphere.geodesicArea(coords)).to.equal(145978332359.37125);
|
||||
it('calculates the area of Ilinois', function() {
|
||||
var area = getArea(geometry, {projection: 'EPSG:4326'});
|
||||
expect(area).to.equal(expectedArea);
|
||||
});
|
||||
|
||||
it('calculates the area of a projected geometry', function() {
|
||||
var projected = geometry.clone().transform('EPSG:4326', 'EPSG:3857');
|
||||
var area = getArea(projected);
|
||||
expect(area).to.roughlyEqual(expectedArea, 1e-3);
|
||||
});
|
||||
|
||||
it('calculates the area of a projected geometry collection', function() {
|
||||
var part = geometry.clone().transform('EPSG:4326', 'EPSG:3857');
|
||||
var collection = new GeometryCollection([part, part.clone()]);
|
||||
var area = getArea(collection);
|
||||
expect(area).to.roughlyEqual(2 * expectedArea, 1e-3);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('ol.Sphere.getLength()', function() {
|
||||
var cases = [{
|
||||
geometry: new Point([0, 0]),
|
||||
length: 0
|
||||
}, {
|
||||
geometry: new MultiPoint([[0, 0], [1, 1]]),
|
||||
length: 0
|
||||
}, {
|
||||
geometry: new LineString([
|
||||
[12801741.441226462, -3763310.627144653],
|
||||
[14582853.293918837, -2511525.2348457114],
|
||||
[15918687.18343812, -2875744.624352243],
|
||||
[16697923.618991036, -4028802.0261344076]
|
||||
]),
|
||||
length: 4407939.124914191
|
||||
}, {
|
||||
geometry: new LineString([
|
||||
[115, -32],
|
||||
[131, -22],
|
||||
[143, -25],
|
||||
[150, -34]
|
||||
]),
|
||||
options: {projection: 'EPSG:4326'},
|
||||
length: 4407939.124914191
|
||||
}, {
|
||||
geometry: new MultiLineString([
|
||||
[
|
||||
[115, -32],
|
||||
[131, -22],
|
||||
[143, -25],
|
||||
[150, -34]
|
||||
], [
|
||||
[115, -32],
|
||||
[131, -22],
|
||||
[143, -25],
|
||||
[150, -34]
|
||||
]
|
||||
]),
|
||||
options: {projection: 'EPSG:4326'},
|
||||
length: 2 * 4407939.124914191
|
||||
}, {
|
||||
geometry: new GeometryCollection([
|
||||
new LineString([
|
||||
[115, -32],
|
||||
[131, -22],
|
||||
[143, -25],
|
||||
[150, -34]
|
||||
]),
|
||||
new LineString([
|
||||
[115, -32],
|
||||
[131, -22],
|
||||
[143, -25],
|
||||
[150, -34]
|
||||
])
|
||||
]),
|
||||
options: {projection: 'EPSG:4326'},
|
||||
length: 2 * 4407939.124914191
|
||||
}];
|
||||
|
||||
cases.forEach(function(c, i) {
|
||||
it('works for case ' + i, function() {
|
||||
var c = cases[i];
|
||||
var length = _ol_Sphere_.getLength(c.geometry, c.options);
|
||||
expect(length).to.roughlyEqual(c.length, 1e-8);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('ol.Sphere.getArea()', function() {
|
||||
var geometry;
|
||||
before(function(done) {
|
||||
afterLoadText('spec/ol/format/wkt/illinois.wkt', function(wkt) {
|
||||
try {
|
||||
var format = new WKT();
|
||||
geometry = format.readGeometry(wkt);
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calculates the area of Ilinois', function() {
|
||||
var area = _ol_Sphere_.getArea(geometry, {projection: 'EPSG:4326'});
|
||||
expect(area).to.equal(145652224192.4434);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user