kopia lustrzana https://github.com/robhawkes/vizicities
Removed CRS and Project components and updated tests
rodzic
5a79c45bfd
commit
3064d70496
|
@ -193,8 +193,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
var _lodashAssign2 = _interopRequireDefault(_lodashAssign);
|
||||
|
||||
// import CRS from './geo/crs/index';
|
||||
|
||||
var _geoGeo = __webpack_require__(6);
|
||||
|
||||
var _geoGeo2 = _interopRequireDefault(_geoGeo);
|
||||
|
@ -225,7 +223,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
_get(Object.getPrototypeOf(World.prototype), 'constructor', this).call(this);
|
||||
|
||||
var defaults = {
|
||||
// crs: CRS.EPSG3857,
|
||||
skybox: false,
|
||||
postProcessing: false
|
||||
};
|
||||
|
@ -2138,7 +2135,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
// Converts pixel / WebGL coords to geo coords
|
||||
// This just reverses the Y axis to match WebGL
|
||||
Geo.pointToLatLon = function (point) {
|
||||
var _point = VIZI.point(point.x, point.y * -1);
|
||||
var _point = (0, _Point.point)(point.x, point.y * -1);
|
||||
return Geo.unproject(_point);
|
||||
};
|
||||
|
||||
|
@ -2203,47 +2200,27 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
};
|
||||
|
||||
// Convert real metres to a value in world (WebGL) units
|
||||
Geo.metresToWorld = function (metres, pointScale, zoom) {
|
||||
Geo.metresToWorld = function (metres, pointScale) {
|
||||
// Transform metres to projected metres using the latitude point scale
|
||||
//
|
||||
// Latitude scale is chosen because it fluctuates more than longitude
|
||||
var projectedMetres = Geo.metresToProjected(metres, pointScale);
|
||||
|
||||
var scale = Geo.scale(zoom);
|
||||
|
||||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||||
if (zoom) {
|
||||
scale /= 2;
|
||||
}
|
||||
var scale = Geo.scale();
|
||||
|
||||
// Scale projected metres
|
||||
var scaledMetres = scale * projectedMetres;
|
||||
|
||||
// Not entirely sure why this is neccessary
|
||||
if (zoom) {
|
||||
scaledMetres /= pointScale[1];
|
||||
}
|
||||
|
||||
return scaledMetres;
|
||||
};
|
||||
|
||||
// Convert world (WebGL) units to a value in real metres
|
||||
Geo.worldToMetres = function (worldUnits, pointScale, zoom) {
|
||||
var scale = Geo.scale(zoom);
|
||||
|
||||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||||
if (zoom) {
|
||||
scale /= 2;
|
||||
}
|
||||
Geo.worldToMetres = function (worldUnits, pointScale) {
|
||||
var scale = Geo.scale();
|
||||
|
||||
var projectedUnits = worldUnits / scale;
|
||||
var realMetres = Geo.projectedToMetres(projectedUnits, pointScale);
|
||||
|
||||
// Not entirely sure why this is neccessary
|
||||
if (zoom) {
|
||||
realMetres *= pointScale[1];
|
||||
}
|
||||
|
||||
return realMetres;
|
||||
};
|
||||
|
||||
|
@ -18578,11 +18555,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
// TODO: A lot of these utils don't need to be in separate, tiny files
|
||||
|
||||
var _Transformation = __webpack_require__(78);
|
||||
|
||||
var _Transformation2 = _interopRequireDefault(_Transformation);
|
||||
|
||||
var _wrapNum = __webpack_require__(79);
|
||||
var _wrapNum = __webpack_require__(78);
|
||||
|
||||
var _wrapNum2 = _interopRequireDefault(_wrapNum);
|
||||
|
||||
|
@ -18600,7 +18573,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
var Util = {};
|
||||
|
||||
Util.Transformation = _Transformation2['default'];
|
||||
Util.wrapNum = _wrapNum2['default'];
|
||||
Util.extrudePolygon = _extrudePolygon2['default'];
|
||||
Util.GeoJSON = _GeoJSON2['default'];
|
||||
|
@ -18611,69 +18583,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
|
||||
/***/ },
|
||||
/* 78 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
Object.defineProperty(exports, '__esModule', {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||||
|
||||
/*
|
||||
* Transformation is an utility class to perform simple point transformations
|
||||
* through a 2d-matrix.
|
||||
*
|
||||
* Based on:
|
||||
* https://github.com/Leaflet/Leaflet/blob/master/src/geometry/Transformation.js
|
||||
*/
|
||||
|
||||
var _geoPoint = __webpack_require__(8);
|
||||
|
||||
var Transformation = (function () {
|
||||
function Transformation(a, b, c, d) {
|
||||
_classCallCheck(this, Transformation);
|
||||
|
||||
this._a = a;
|
||||
this._b = b;
|
||||
this._c = c;
|
||||
this._d = d;
|
||||
}
|
||||
|
||||
_createClass(Transformation, [{
|
||||
key: 'transform',
|
||||
value: function transform(point, scale) {
|
||||
// Copy input point as to not destroy the original data
|
||||
return this._transform(point.clone(), scale);
|
||||
}
|
||||
|
||||
// Destructive transform (faster)
|
||||
}, {
|
||||
key: '_transform',
|
||||
value: function _transform(point, scale) {
|
||||
scale = scale || 1;
|
||||
|
||||
point.x = scale * (this._a * point.x + this._b);
|
||||
point.y = scale * (this._c * point.y + this._d);
|
||||
return point;
|
||||
}
|
||||
}, {
|
||||
key: 'untransform',
|
||||
value: function untransform(point, scale) {
|
||||
scale = scale || 1;
|
||||
return (0, _geoPoint.point)((point.x / scale - this._b) / this._a, (point.y / scale - this._d) / this._c);
|
||||
}
|
||||
}]);
|
||||
|
||||
return Transformation;
|
||||
})();
|
||||
|
||||
exports['default'] = Transformation;
|
||||
module.exports = exports['default'];
|
||||
|
||||
/***/ },
|
||||
/* 79 */
|
||||
/***/ function(module, exports) {
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -44,7 +44,7 @@ Geo.latLonToPoint = function(latlon) {
|
|||
// Converts pixel / WebGL coords to geo coords
|
||||
// This just reverses the Y axis to match WebGL
|
||||
Geo.pointToLatLon = function(point) {
|
||||
var _point = VIZI.point(point.x, point.y * -1);
|
||||
var _point = Point(point.x, point.y * -1);
|
||||
return Geo.unproject(_point);
|
||||
};
|
||||
|
||||
|
@ -109,47 +109,27 @@ Geo.projectedToMetres = function(projectedUnits, pointScale) {
|
|||
};
|
||||
|
||||
// Convert real metres to a value in world (WebGL) units
|
||||
Geo.metresToWorld = function(metres, pointScale, zoom) {
|
||||
Geo.metresToWorld = function(metres, pointScale) {
|
||||
// Transform metres to projected metres using the latitude point scale
|
||||
//
|
||||
// Latitude scale is chosen because it fluctuates more than longitude
|
||||
var projectedMetres = Geo.metresToProjected(metres, pointScale);
|
||||
|
||||
var scale = Geo.scale(zoom);
|
||||
|
||||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||||
if (zoom) {
|
||||
scale /= 2;
|
||||
}
|
||||
var scale = Geo.scale();
|
||||
|
||||
// Scale projected metres
|
||||
var scaledMetres = (scale * projectedMetres);
|
||||
|
||||
// Not entirely sure why this is neccessary
|
||||
if (zoom) {
|
||||
scaledMetres /= pointScale[1];
|
||||
}
|
||||
|
||||
return scaledMetres;
|
||||
};
|
||||
|
||||
// Convert world (WebGL) units to a value in real metres
|
||||
Geo.worldToMetres = function(worldUnits, pointScale, zoom) {
|
||||
var scale = Geo.scale(zoom);
|
||||
|
||||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||||
if (zoom) {
|
||||
scale /= 2;
|
||||
}
|
||||
Geo.worldToMetres = function(worldUnits, pointScale) {
|
||||
var scale = Geo.scale();
|
||||
|
||||
var projectedUnits = worldUnits / scale;
|
||||
var realMetres = Geo.projectedToMetres(projectedUnits, pointScale);
|
||||
|
||||
// Not entirely sure why this is neccessary
|
||||
if (zoom) {
|
||||
realMetres *= pointScale[1];
|
||||
}
|
||||
|
||||
return realMetres;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* CRS.EPSG3395 (WGS 84 / World Mercator) CRS implementation.
|
||||
*
|
||||
* Based on:
|
||||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.EPSG3395.js
|
||||
*/
|
||||
|
||||
import extend from 'lodash.assign';
|
||||
import Earth from './CRS.Earth';
|
||||
import Mercator from '../projection/Projection.Mercator';
|
||||
import Transformation from '../../util/Transformation';
|
||||
|
||||
var _EPSG3395 = {
|
||||
code: 'EPSG:3395',
|
||||
projection: Mercator,
|
||||
|
||||
// Work out how to de-dupe this (scoping issue)
|
||||
transformScale: 1 / (Math.PI * Mercator.R),
|
||||
|
||||
// Scale and transformation inputs changed to account for central origin in
|
||||
// WebGL, instead of top-left origin used in Leaflet
|
||||
transformation: (function() {
|
||||
// TODO: Cannot use this.transformScale due to scope
|
||||
var scale = 1 / (Math.PI * Mercator.R);
|
||||
|
||||
return new Transformation(scale, 0, -scale, 0);
|
||||
}())
|
||||
};
|
||||
|
||||
const EPSG3395 = extend({}, Earth, _EPSG3395);
|
||||
|
||||
export default EPSG3395;
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* CRS.EPSG3857 (WGS 84 / Pseudo-Mercator) CRS implementation.
|
||||
*
|
||||
* Based on:
|
||||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.EPSG3857.js
|
||||
*/
|
||||
|
||||
import extend from 'lodash.assign';
|
||||
import Earth from './CRS.Earth';
|
||||
import SphericalMercator from '../projection/Projection.SphericalMercator';
|
||||
import Transformation from '../../util/Transformation';
|
||||
|
||||
var _EPSG3857 = {
|
||||
code: 'EPSG:3857',
|
||||
projection: SphericalMercator,
|
||||
|
||||
// Work out how to de-dupe this (scoping issue)
|
||||
transformScale: 1 / (Math.PI * SphericalMercator.R),
|
||||
|
||||
// Scale and transformation inputs changed to account for central origin in
|
||||
// WebGL, instead of top-left origin used in Leaflet
|
||||
transformation: (function() {
|
||||
// TODO: Cannot use this.transformScale due to scope
|
||||
var scale = 1 / (Math.PI * SphericalMercator.R);
|
||||
|
||||
return new Transformation(scale, 0, -scale, 0);
|
||||
}())
|
||||
};
|
||||
|
||||
const EPSG3857 = extend({}, Earth, _EPSG3857);
|
||||
|
||||
const EPSG900913 = extend({}, EPSG3857, {
|
||||
code: 'EPSG:900913'
|
||||
});
|
||||
|
||||
export {EPSG900913};
|
||||
|
||||
export default EPSG3857;
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* CRS.EPSG4326 is a CRS popular among advanced GIS specialists.
|
||||
*
|
||||
* Based on:
|
||||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.EPSG4326.js
|
||||
*/
|
||||
|
||||
import extend from 'lodash.assign';
|
||||
import Earth from './CRS.Earth';
|
||||
import LatLonProjection from '../projection/Projection.LatLon';
|
||||
import Transformation from '../../util/Transformation';
|
||||
|
||||
var _EPSG4326 = {
|
||||
code: 'EPSG:4326',
|
||||
projection: LatLonProjection,
|
||||
|
||||
// Work out how to de-dupe this (scoping issue)
|
||||
transformScale: 1 / 180,
|
||||
|
||||
// Scale and transformation inputs changed to account for central origin in
|
||||
// WebGL, instead of top-left origin used in Leaflet
|
||||
//
|
||||
// TODO: Cannot use this.transformScale due to scope
|
||||
transformation: new Transformation(1 / 180, 0, -1 / 180, 0)
|
||||
};
|
||||
|
||||
const EPSG4326 = extend({}, Earth, _EPSG4326);
|
||||
|
||||
export default EPSG4326;
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
* CRS.Earth is the base class for all CRS representing Earth.
|
||||
*
|
||||
* Based on:
|
||||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.Earth.js
|
||||
*/
|
||||
|
||||
import extend from 'lodash.assign';
|
||||
import CRS from './CRS';
|
||||
import {latLon as LatLon} from '../LatLon';
|
||||
|
||||
const Earth = {
|
||||
wrapLon: [-180, 180],
|
||||
|
||||
R: 6378137,
|
||||
|
||||
// Distance between two geographical points using spherical law of cosines
|
||||
// approximation or Haversine
|
||||
//
|
||||
// See: http://www.movable-type.co.uk/scripts/latlong.html
|
||||
distance: function(latlon1, latlon2, accurate) {
|
||||
var rad = Math.PI / 180;
|
||||
|
||||
var lat1;
|
||||
var lat2;
|
||||
|
||||
var a;
|
||||
|
||||
if (!accurate) {
|
||||
lat1 = latlon1.lat * rad;
|
||||
lat2 = latlon2.lat * rad;
|
||||
|
||||
a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlon2.lon - latlon1.lon) * rad);
|
||||
|
||||
return this.R * Math.acos(Math.min(a, 1));
|
||||
} else {
|
||||
lat1 = latlon1.lat * rad;
|
||||
lat2 = latlon2.lat * rad;
|
||||
|
||||
var lon1 = latlon1.lon * rad;
|
||||
var lon2 = latlon2.lon * rad;
|
||||
|
||||
var deltaLat = lat2 - lat1;
|
||||
var deltaLon = lon2 - lon1;
|
||||
|
||||
var halfDeltaLat = deltaLat / 2;
|
||||
var halfDeltaLon = deltaLon / 2;
|
||||
|
||||
a = Math.sin(halfDeltaLat) * Math.sin(halfDeltaLat) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(halfDeltaLon) * Math.sin(halfDeltaLon);
|
||||
|
||||
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||||
|
||||
return this.R * c;
|
||||
}
|
||||
},
|
||||
|
||||
// Scale factor for converting between real metres and projected metres
|
||||
//
|
||||
// projectedMetres = realMetres * pointScale
|
||||
// realMetres = projectedMetres / pointScale
|
||||
//
|
||||
// Defaults to a scale factor of 1 if no calculation method exists
|
||||
//
|
||||
// Probably need to run this through the CRS transformation or similar so the
|
||||
// resulting scale is relative to the dimensions of the world space
|
||||
// Eg. 1 metre in projected space is likly scaled up or down to some other
|
||||
// number
|
||||
pointScale: function(latlon, accurate) {
|
||||
return (this.projection.pointScale) ? this.projection.pointScale(latlon, accurate) : [1, 1];
|
||||
},
|
||||
|
||||
// Convert real metres to projected units
|
||||
//
|
||||
// Latitude scale is chosen because it fluctuates more than longitude
|
||||
metresToProjected: function(metres, pointScale) {
|
||||
return metres * pointScale[1];
|
||||
},
|
||||
|
||||
// Convert projected units to real metres
|
||||
//
|
||||
// Latitude scale is chosen because it fluctuates more than longitude
|
||||
projectedToMetres: function(projectedUnits, pointScale) {
|
||||
return projectedUnits / pointScale[1];
|
||||
},
|
||||
|
||||
// Convert real metres to a value in world (WebGL) units
|
||||
metresToWorld: function(metres, pointScale, zoom) {
|
||||
// Transform metres to projected metres using the latitude point scale
|
||||
//
|
||||
// Latitude scale is chosen because it fluctuates more than longitude
|
||||
var projectedMetres = this.metresToProjected(metres, pointScale);
|
||||
|
||||
var scale = this.scale(zoom);
|
||||
|
||||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||||
if (zoom) {
|
||||
scale /= 2;
|
||||
}
|
||||
|
||||
// Scale projected metres
|
||||
var scaledMetres = (scale * (this.transformScale * projectedMetres));
|
||||
|
||||
// Not entirely sure why this is neccessary
|
||||
if (zoom) {
|
||||
scaledMetres /= pointScale[1];
|
||||
}
|
||||
|
||||
return scaledMetres;
|
||||
},
|
||||
|
||||
// Convert world (WebGL) units to a value in real metres
|
||||
worldToMetres: function(worldUnits, pointScale, zoom) {
|
||||
var scale = this.scale(zoom);
|
||||
|
||||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||||
if (zoom) {
|
||||
scale /= 2;
|
||||
}
|
||||
|
||||
var projectedUnits = ((worldUnits / scale) / this.transformScale);
|
||||
var realMetres = this.projectedToMetres(projectedUnits, pointScale);
|
||||
|
||||
// Not entirely sure why this is neccessary
|
||||
if (zoom) {
|
||||
realMetres *= pointScale[1];
|
||||
}
|
||||
|
||||
return realMetres;
|
||||
}
|
||||
};
|
||||
|
||||
export default extend({}, CRS, Earth);
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* CRS.Proj4 for any Proj4-supported CRS.
|
||||
*/
|
||||
|
||||
import extend from 'lodash.assign';
|
||||
import Earth from './CRS.Earth';
|
||||
import Proj4Projection from '../projection/Projection.Proj4';
|
||||
import Transformation from '../../util/Transformation';
|
||||
|
||||
var _Proj4 = function(code, def, bounds) {
|
||||
var projection = Proj4Projection(def, bounds);
|
||||
|
||||
// Transformation calcuations
|
||||
var diffX = projection.bounds[1][0] - projection.bounds[0][0];
|
||||
var diffY = projection.bounds[1][1] - projection.bounds[0][1];
|
||||
|
||||
var halfX = diffX / 2;
|
||||
var halfY = diffY / 2;
|
||||
|
||||
// This is the raw scale factor
|
||||
var scaleX = 1 / halfX;
|
||||
var scaleY = 1 / halfY;
|
||||
|
||||
// Find the minimum scale factor
|
||||
//
|
||||
// The minimum scale factor comes from the largest side and is the one
|
||||
// you want to use for both axis so they stay relative in dimension
|
||||
var scale = Math.min(scaleX, scaleY);
|
||||
|
||||
// Find amount to offset each axis by to make the central point lie on
|
||||
// the [0,0] origin
|
||||
var offsetX = scale * (projection.bounds[0][0] + halfX);
|
||||
var offsetY = scale * (projection.bounds[0][1] + halfY);
|
||||
|
||||
return {
|
||||
code: code,
|
||||
projection: projection,
|
||||
|
||||
transformScale: scale,
|
||||
|
||||
// Map the input to a [-1,1] range with [0,0] in the centre
|
||||
transformation: new Transformation(scale, -offsetX, -scale, offsetY)
|
||||
};
|
||||
};
|
||||
|
||||
const Proj4 = function(code, def, bounds) {
|
||||
return extend({}, Earth, _Proj4(code, def, bounds));
|
||||
};
|
||||
|
||||
export default Proj4;
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* A simple CRS that can be used for flat non-Earth maps like panoramas or game
|
||||
* maps.
|
||||
*
|
||||
* Based on:
|
||||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.Simple.js
|
||||
*/
|
||||
|
||||
import extend from 'lodash.assign';
|
||||
import CRS from './CRS';
|
||||
import LatLonProjection from '../projection/Projection.LatLon';
|
||||
import Transformation from '../../util/Transformation';
|
||||
|
||||
var _Simple = {
|
||||
projection: LatLonProjection,
|
||||
|
||||
// Straight 1:1 mapping (-1, -1 would be top-left)
|
||||
transformation: new Transformation(1, 0, 1, 0),
|
||||
|
||||
scale: function(zoom) {
|
||||
// If zoom is provided then return scale based on map tile zoom
|
||||
if (zoom) {
|
||||
return Math.pow(2, zoom);
|
||||
// Else, make no change to scale – may need to increase this or make it a
|
||||
// user-definable variable
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
},
|
||||
|
||||
zoom: function(scale) {
|
||||
return Math.log(scale) / Math.LN2;
|
||||
},
|
||||
|
||||
distance: function(latlon1, latlon2) {
|
||||
var dx = latlon2.lon - latlon1.lon;
|
||||
var dy = latlon2.lat - latlon1.lat;
|
||||
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
},
|
||||
|
||||
infinite: true
|
||||
};
|
||||
|
||||
const Simple = extend({}, CRS, _Simple);
|
||||
|
||||
export default Simple;
|
|
@ -1,120 +0,0 @@
|
|||
/*
|
||||
* CRS is the base object for all defined CRS (Coordinate Reference Systems)
|
||||
*
|
||||
* Based on:
|
||||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.js
|
||||
*/
|
||||
|
||||
import {latLon as LatLon} from '../LatLon';
|
||||
import {point as Point} from '../Point';
|
||||
import wrapNum from '../../util/wrapNum';
|
||||
|
||||
const CRS = {
|
||||
// Scale factor determines final dimensions of world space
|
||||
//
|
||||
// Projection transformation in range -1 to 1 is multiplied by scale factor to
|
||||
// find final world coordinates
|
||||
//
|
||||
// Scale factor can be considered as half the amount of the desired dimension
|
||||
// for the largest side when transformation is equal to 1 or -1, or as the
|
||||
// distance between 0 and 1 on the largest side
|
||||
//
|
||||
// For example, if you want the world dimensions to be between -1000 and 1000
|
||||
// then the scale factor will be 1000
|
||||
scaleFactor: 1000000,
|
||||
|
||||
// Converts geo coords to pixel / WebGL ones
|
||||
latLonToPoint: function(latlon, zoom) {
|
||||
var projectedPoint = this.projection.project(latlon);
|
||||
var scale = this.scale(zoom);
|
||||
|
||||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||||
if (zoom) {
|
||||
scale /= 2;
|
||||
}
|
||||
|
||||
return this.transformation._transform(projectedPoint, scale);
|
||||
},
|
||||
|
||||
// Converts pixel / WebGL coords to geo coords
|
||||
pointToLatLon: function(point, zoom) {
|
||||
var scale = this.scale(zoom);
|
||||
|
||||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||||
if (zoom) {
|
||||
scale /= 2;
|
||||
}
|
||||
|
||||
var untransformedPoint = this.transformation.untransform(point, scale);
|
||||
|
||||
return this.projection.unproject(untransformedPoint);
|
||||
},
|
||||
|
||||
// Converts geo coords to projection-specific coords (e.g. in meters)
|
||||
project: function(latlon) {
|
||||
return this.projection.project(latlon);
|
||||
},
|
||||
|
||||
// Converts projected coords to geo coords
|
||||
unproject: function(point) {
|
||||
return this.projection.unproject(point);
|
||||
},
|
||||
|
||||
// If zoom is provided, returns the map width in pixels for a given zoom
|
||||
// Else, provides fixed scale value
|
||||
scale: function(zoom) {
|
||||
// If zoom is provided then return scale based on map tile zoom
|
||||
if (zoom >= 0) {
|
||||
return 256 * Math.pow(2, zoom);
|
||||
// Else, return fixed scale value to expand projected coordinates from
|
||||
// their 0 to 1 range into something more practical
|
||||
} else {
|
||||
return this.scaleFactor;
|
||||
}
|
||||
},
|
||||
|
||||
// Returns zoom level for a given scale value
|
||||
// This only works with a scale value that is based on map pixel width
|
||||
zoom: function(scale) {
|
||||
return Math.log(scale / 256) / Math.LN2;
|
||||
},
|
||||
|
||||
// Returns the bounds of the world in projected coords if applicable
|
||||
getProjectedBounds: function(zoom) {
|
||||
if (this.infinite) { return null; }
|
||||
|
||||
var b = this.projection.bounds;
|
||||
var s = this.scale(zoom);
|
||||
|
||||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||||
if (zoom) {
|
||||
s /= 2;
|
||||
}
|
||||
|
||||
// Bottom left
|
||||
var min = this.transformation.transform(Point(b[0]), s);
|
||||
|
||||
// Top right
|
||||
var max = this.transformation.transform(Point(b[1]), s);
|
||||
|
||||
return [min, max];
|
||||
},
|
||||
|
||||
// Whether a coordinate axis wraps in a given range (e.g. longitude from -180 to 180); depends on CRS
|
||||
// wrapLon: [min, max],
|
||||
// wrapLat: [min, max],
|
||||
|
||||
// If true, the coordinate space will be unbounded (infinite in all directions)
|
||||
// infinite: false,
|
||||
|
||||
// Wraps geo coords in certain ranges if applicable
|
||||
wrapLatLon: function(latlon) {
|
||||
var lat = this.wrapLat ? wrapNum(latlon.lat, this.wrapLat, true) : latlon.lat;
|
||||
var lon = this.wrapLon ? wrapNum(latlon.lon, this.wrapLon, true) : latlon.lon;
|
||||
var alt = latlon.alt;
|
||||
|
||||
return LatLon(lat, lon, alt);
|
||||
}
|
||||
};
|
||||
|
||||
export default CRS;
|
|
@ -1,17 +0,0 @@
|
|||
import EPSG3857 from './CRS.EPSG3857';
|
||||
import {EPSG900913} from './CRS.EPSG3857';
|
||||
import EPSG3395 from './CRS.EPSG3395';
|
||||
import EPSG4326 from './CRS.EPSG4326';
|
||||
import Simple from './CRS.Simple';
|
||||
import Proj4 from './CRS.Proj4';
|
||||
|
||||
const CRS = {};
|
||||
|
||||
CRS.EPSG3857 = EPSG3857;
|
||||
CRS.EPSG900913 = EPSG900913;
|
||||
CRS.EPSG3395 = EPSG3395;
|
||||
CRS.EPSG4326 = EPSG4326;
|
||||
CRS.Simple = Simple;
|
||||
CRS.Proj4 = Proj4;
|
||||
|
||||
export default CRS;
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Simple equirectangular (Plate Carree) projection, used by CRS like EPSG:4326
|
||||
* and Simple.
|
||||
*
|
||||
* Based on:
|
||||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.LonLat.js
|
||||
*/
|
||||
|
||||
import {latLon as LatLon} from '../LatLon';
|
||||
import {point as Point} from '../Point';
|
||||
|
||||
const ProjectionLatLon = {
|
||||
project: function(latlon) {
|
||||
return Point(latlon.lon, latlon.lat);
|
||||
},
|
||||
|
||||
unproject: function(point) {
|
||||
return LatLon(point.y, point.x);
|
||||
},
|
||||
|
||||
// Scale factor for converting between real metres and degrees
|
||||
//
|
||||
// degrees = realMetres * pointScale
|
||||
// realMetres = degrees / pointScale
|
||||
//
|
||||
// See: http://stackoverflow.com/questions/639695/how-to-convert-latitude-or-longitude-to-meters
|
||||
// See: http://gis.stackexchange.com/questions/75528/length-of-a-degree-where-do-the-terms-in-this-formula-come-from
|
||||
pointScale: function(latlon) {
|
||||
var m1 = 111132.92;
|
||||
var m2 = -559.82;
|
||||
var m3 = 1.175;
|
||||
var m4 = -0.0023;
|
||||
var p1 = 111412.84;
|
||||
var p2 = -93.5;
|
||||
var p3 = 0.118;
|
||||
|
||||
var rad = Math.PI / 180;
|
||||
var lat = latlon.lat * rad;
|
||||
|
||||
var latlen = m1 + m2 * Math.cos(2 * lat) + m3 * Math.cos(4 * lat) + m4 * Math.cos(6 * lat);
|
||||
var lonlen = p1 * Math.cos(lat) + p2 * Math.cos(3 * lat) + p3 * Math.cos(5 * lat);
|
||||
|
||||
return [1 / latlen, 1 / lonlen];
|
||||
},
|
||||
|
||||
bounds: [[-180, -90], [180, 90]]
|
||||
};
|
||||
|
||||
export default ProjectionLatLon;
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Mercator projection that takes into account that the Earth is not a perfect
|
||||
* sphere. Less popular than spherical mercator; used by projections like
|
||||
* EPSG:3395.
|
||||
*
|
||||
* Based on:
|
||||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.Mercator.js
|
||||
*/
|
||||
|
||||
import {latLon as LatLon} from '../LatLon';
|
||||
import {point as Point} from '../Point';
|
||||
|
||||
const Mercator = {
|
||||
// Radius / WGS84 semi-major axis
|
||||
R: 6378137,
|
||||
R_MINOR: 6356752.314245179,
|
||||
|
||||
// WGS84 eccentricity
|
||||
ECC: 0.081819191,
|
||||
ECC2: 0.081819191 * 0.081819191,
|
||||
|
||||
project: function(latlon) {
|
||||
var d = Math.PI / 180;
|
||||
var r = this.R;
|
||||
var y = latlon.lat * d;
|
||||
var tmp = this.R_MINOR / r;
|
||||
var e = Math.sqrt(1 - tmp * tmp);
|
||||
var con = e * Math.sin(y);
|
||||
|
||||
var ts = Math.tan(Math.PI / 4 - y / 2) / Math.pow((1 - con) / (1 + con), e / 2);
|
||||
y = -r * Math.log(Math.max(ts, 1E-10));
|
||||
|
||||
return Point(latlon.lon * d * r, y);
|
||||
},
|
||||
|
||||
unproject: function(point) {
|
||||
var d = 180 / Math.PI;
|
||||
var r = this.R;
|
||||
var tmp = this.R_MINOR / r;
|
||||
var e = Math.sqrt(1 - tmp * tmp);
|
||||
var ts = Math.exp(-point.y / r);
|
||||
var phi = Math.PI / 2 - 2 * Math.atan(ts);
|
||||
|
||||
for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) {
|
||||
con = e * Math.sin(phi);
|
||||
con = Math.pow((1 - con) / (1 + con), e / 2);
|
||||
dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi;
|
||||
phi += dphi;
|
||||
}
|
||||
|
||||
return LatLon(phi * d, point.x * d / r);
|
||||
},
|
||||
|
||||
// Scale factor for converting between real metres and projected metres
|
||||
//
|
||||
// projectedMetres = realMetres * pointScale
|
||||
// realMetres = projectedMetres / pointScale
|
||||
//
|
||||
// See pg.8: http://www.hydrometronics.com/downloads/Web%20Mercator%20-%20Non-Conformal,%20Non-Mercator%20(notes).pdf
|
||||
pointScale: function(latlon) {
|
||||
var rad = Math.PI / 180;
|
||||
var lat = latlon.lat * rad;
|
||||
var sinLat = Math.sin(lat);
|
||||
var sinLat2 = sinLat * sinLat;
|
||||
var cosLat = Math.cos(lat);
|
||||
|
||||
var k = Math.sqrt(1 - this.ECC2 * sinLat2) / cosLat;
|
||||
|
||||
// [scaleX, scaleY]
|
||||
return [k, k];
|
||||
},
|
||||
|
||||
bounds: [[-20037508.34279, -15496570.73972], [20037508.34279, 18764656.23138]]
|
||||
};
|
||||
|
||||
export default Mercator;
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* Proj4 support for any projection.
|
||||
*/
|
||||
|
||||
import proj4 from 'proj4';
|
||||
import {latLon as LatLon} from '../LatLon';
|
||||
import {point as Point} from '../Point';
|
||||
|
||||
const Proj4 = function(def, bounds) {
|
||||
var proj = proj4(def);
|
||||
|
||||
var project = function(latlon) {
|
||||
return Point(proj.forward([latlon.lon, latlon.lat]));
|
||||
};
|
||||
|
||||
var unproject = function(point) {
|
||||
var inverse = proj.inverse([point.x, point.y]);
|
||||
return LatLon(inverse[1], inverse[0]);
|
||||
};
|
||||
|
||||
return {
|
||||
project: project,
|
||||
unproject: unproject,
|
||||
|
||||
// Scale factor for converting between real metres and projected metres\
|
||||
//
|
||||
// Need to work out the best way to provide the pointScale calculations
|
||||
// for custom, unknown projections (if wanting to override default)
|
||||
//
|
||||
// For now, user can manually override crs.pointScale or
|
||||
// crs.projection.pointScale
|
||||
//
|
||||
// projectedMetres = realMetres * pointScale
|
||||
// realMetres = projectedMetres / pointScale
|
||||
pointScale: function(latlon, accurate) {
|
||||
return [1, 1];
|
||||
},
|
||||
|
||||
// Try and calculate bounds if none are provided
|
||||
//
|
||||
// This will provide incorrect bounds for some projections, so perhaps make
|
||||
// bounds a required input instead
|
||||
bounds: (function() {
|
||||
if (bounds) {
|
||||
return bounds;
|
||||
} else {
|
||||
var bottomLeft = project([-90, -180]);
|
||||
var topRight = project([90, 180]);
|
||||
|
||||
return [bottomLeft, topRight];
|
||||
}
|
||||
})()
|
||||
};
|
||||
};
|
||||
|
||||
export default Proj4;
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
* Spherical Mercator is the most popular map projection, used by EPSG:3857 CRS
|
||||
* used by default.
|
||||
*
|
||||
* Based on:
|
||||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js
|
||||
*/
|
||||
|
||||
import {latLon as LatLon} from '../LatLon';
|
||||
import {point as Point} from '../Point';
|
||||
|
||||
const SphericalMercator = {
|
||||
// Radius / WGS84 semi-major axis
|
||||
R: 6378137,
|
||||
MAX_LATITUDE: 85.0511287798,
|
||||
|
||||
// WGS84 eccentricity
|
||||
ECC: 0.081819191,
|
||||
ECC2: 0.081819191 * 0.081819191,
|
||||
|
||||
project: function(latlon) {
|
||||
var d = Math.PI / 180;
|
||||
var max = this.MAX_LATITUDE;
|
||||
var lat = Math.max(Math.min(max, latlon.lat), -max);
|
||||
var sin = Math.sin(lat * d);
|
||||
|
||||
return Point(
|
||||
this.R * latlon.lon * d,
|
||||
this.R * Math.log((1 + sin) / (1 - sin)) / 2
|
||||
);
|
||||
},
|
||||
|
||||
unproject: function(point) {
|
||||
var d = 180 / Math.PI;
|
||||
|
||||
return LatLon(
|
||||
(2 * Math.atan(Math.exp(point.y / this.R)) - (Math.PI / 2)) * d,
|
||||
point.x * d / this.R
|
||||
);
|
||||
},
|
||||
|
||||
// Scale factor for converting between real metres and projected metres
|
||||
//
|
||||
// projectedMetres = realMetres * pointScale
|
||||
// realMetres = projectedMetres / pointScale
|
||||
//
|
||||
// Accurate scale factor uses proper Web Mercator scaling
|
||||
// See pg.9: http://www.hydrometronics.com/downloads/Web%20Mercator%20-%20Non-Conformal,%20Non-Mercator%20(notes).pdf
|
||||
// See: http://jsfiddle.net/robhawkes/yws924cf/
|
||||
pointScale: function(latlon, accurate) {
|
||||
var rad = Math.PI / 180;
|
||||
|
||||
var k;
|
||||
|
||||
if (!accurate) {
|
||||
k = 1 / Math.cos(latlon.lat * rad);
|
||||
|
||||
// [scaleX, scaleY]
|
||||
return [k, k];
|
||||
} else {
|
||||
var lat = latlon.lat * rad;
|
||||
var lon = latlon.lon * rad;
|
||||
|
||||
var a = this.R;
|
||||
|
||||
var sinLat = Math.sin(lat);
|
||||
var sinLat2 = sinLat * sinLat;
|
||||
|
||||
var cosLat = Math.cos(lat);
|
||||
|
||||
// Radius meridian
|
||||
var p = a * (1 - this.ECC2) / Math.pow(1 - this.ECC2 * sinLat2, 3 / 2);
|
||||
|
||||
// Radius prime meridian
|
||||
var v = a / Math.sqrt(1 - this.ECC2 * sinLat2);
|
||||
|
||||
// Scale N/S
|
||||
var h = (a / p) / cosLat;
|
||||
|
||||
// Scale E/W
|
||||
k = (a / v) / cosLat;
|
||||
|
||||
// [scaleX, scaleY]
|
||||
return [k, h];
|
||||
}
|
||||
},
|
||||
|
||||
// Not using this.R due to scoping
|
||||
bounds: (function() {
|
||||
var d = 6378137 * Math.PI;
|
||||
return [[-d, -d], [d, d]];
|
||||
})()
|
||||
};
|
||||
|
||||
export default SphericalMercator;
|
|
@ -1,13 +0,0 @@
|
|||
import LatLon from './Projection.LatLon';
|
||||
import SphericalMercator from './Projection.SphericalMercator';
|
||||
import Mercator from './Projection.Mercator';
|
||||
import Proj4 from './Projection.Proj4';
|
||||
|
||||
const Projection = {};
|
||||
|
||||
Projection.LatLon = LatLon;
|
||||
Projection.SphericalMercator = SphericalMercator;
|
||||
Projection.Mercator = Mercator;
|
||||
Projection.Proj4 = Proj4;
|
||||
|
||||
export default Projection;
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Transformation is an utility class to perform simple point transformations
|
||||
* through a 2d-matrix.
|
||||
*
|
||||
* Based on:
|
||||
* https://github.com/Leaflet/Leaflet/blob/master/src/geometry/Transformation.js
|
||||
*/
|
||||
|
||||
import {point as Point} from '../geo/Point';
|
||||
|
||||
class Transformation {
|
||||
constructor(a, b, c, d) {
|
||||
this._a = a;
|
||||
this._b = b;
|
||||
this._c = c;
|
||||
this._d = d;
|
||||
}
|
||||
|
||||
transform(point, scale) {
|
||||
// Copy input point as to not destroy the original data
|
||||
return this._transform(point.clone(), scale);
|
||||
}
|
||||
|
||||
// Destructive transform (faster)
|
||||
_transform(point, scale) {
|
||||
scale = scale || 1;
|
||||
|
||||
point.x = scale * (this._a * point.x + this._b);
|
||||
point.y = scale * (this._c * point.y + this._d);
|
||||
return point;
|
||||
}
|
||||
|
||||
untransform(point, scale) {
|
||||
scale = scale || 1;
|
||||
return Point(
|
||||
(point.x / scale - this._b) / this._a,
|
||||
(point.y / scale - this._d) / this._c
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Transformation;
|
|
@ -1,6 +1,5 @@
|
|||
// TODO: A lot of these utils don't need to be in separate, tiny files
|
||||
|
||||
import Transformation from './Transformation';
|
||||
import wrapNum from './wrapNum';
|
||||
import extrudePolygon from './extrudePolygon';
|
||||
import GeoJSON from './GeoJSON';
|
||||
|
@ -8,7 +7,6 @@ import Buffer from './Buffer';
|
|||
|
||||
const Util = {};
|
||||
|
||||
Util.Transformation = Transformation;
|
||||
Util.wrapNum = wrapNum;
|
||||
Util.extrudePolygon = extrudePolygon;
|
||||
Util.GeoJSON = GeoJSON;
|
||||
|
|
634
test/unit/CRS.js
634
test/unit/CRS.js
|
@ -1,634 +0,0 @@
|
|||
import extend from 'lodash.assign';
|
||||
import CRS from '../../src/geo/crs/index';
|
||||
import {latLon as LatLon} from '../../src/geo/LatLon';
|
||||
import {point as Point} from '../../src/geo/Point';
|
||||
|
||||
describe('CRS.EPSG3857', () => {
|
||||
var crs = CRS.EPSG3857;
|
||||
|
||||
describe('#code', () => {
|
||||
it('returns the correct code', () => {
|
||||
expect(crs.code).to.equal('EPSG:3857');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#latLonToPoint', () => {
|
||||
it('projects the center', () => {
|
||||
var point = crs.latLonToPoint(LatLon(0, 0));
|
||||
|
||||
expect(point.x).to.be.closeTo(0, 0.01);
|
||||
expect(point.y).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('projects the North-West corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var point = crs.latLonToPoint(LatLon(85.0511287798, -180));
|
||||
|
||||
expect(point.x).to.be.closeTo(-scaleFactor, 0.01);
|
||||
expect(point.y).to.be.closeTo(-scaleFactor, 0.01);
|
||||
});
|
||||
|
||||
it('projects the South-East corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var point = crs.latLonToPoint(LatLon(-85.0511287798, 180));
|
||||
|
||||
expect(point.x).to.be.closeTo(scaleFactor, 0.01);
|
||||
expect(point.x).to.be.closeTo(scaleFactor, 0.01);
|
||||
});
|
||||
|
||||
it('projects using pixels if zoom is given', () => {
|
||||
var point = crs.latLonToPoint(LatLon(-85.0511287798, 180), 1);
|
||||
|
||||
expect(point.x).to.be.closeTo(256, 0.01);
|
||||
expect(point.y).to.be.closeTo(256, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointToLatLon', () => {
|
||||
it('unprojects the center', () => {
|
||||
var latlon = crs.pointToLatLon(Point(0, 0));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the North-West corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var latlon = crs.pointToLatLon(Point(-scaleFactor, -scaleFactor));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(85.0511287798, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(-180, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the South-East corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var latlon = crs.pointToLatLon(Point(scaleFactor, scaleFactor));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-85.0511287798, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(180, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects using pixels if zoom is given', () => {
|
||||
var latlon = crs.pointToLatLon(Point(256, 256), 1);
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-85.0511287798, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(180, 0.01);
|
||||
|
||||
latlon = crs.pointToLatLon(Point(0, 0), 1);
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#project', () => {
|
||||
it('projects the center', () => {
|
||||
var point = crs.project(LatLon(0, 0));
|
||||
|
||||
expect(point.x).to.be.closeTo(0, 0.01);
|
||||
expect(point.y).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('projects the North-West corner', () => {
|
||||
var point = crs.project(LatLon(85.0511287798, -180));
|
||||
|
||||
expect(point.x).to.be.closeTo(-20037508.34279, 0.01);
|
||||
expect(point.y).to.be.closeTo(20037508.34278, 0.01);
|
||||
});
|
||||
|
||||
it('projects the South-East corner', () => {
|
||||
var point = crs.project(LatLon(-85.0511287798, 180));
|
||||
|
||||
expect(point.x).to.be.closeTo(20037508.34278, 0.01);
|
||||
expect(point.y).to.be.closeTo(-20037508.34278, 0.01);
|
||||
});
|
||||
|
||||
it('caps the maximum latitude', () => {
|
||||
var point = crs.project(LatLon(-90, 180));
|
||||
|
||||
expect(point.x).to.be.closeTo(20037508.34278, 0.01);
|
||||
expect(point.y).to.be.closeTo(-20037508.34278, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#unproject', () => {
|
||||
it('unprojects the center', () => {
|
||||
var latlon = crs.unproject(Point(0, 0));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the North-West corner', () => {
|
||||
var latlon = crs.unproject(Point(-20037508.34278, 20037508.34278));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(85.0511287798, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(-180, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the South-East corner', () => {
|
||||
var latlon = crs.unproject(Point(20037508.34278, -20037508.34278));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-85.0511287798, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(180, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#scale', () => {
|
||||
it('uses the scale factor by default', () => {
|
||||
var scale = crs.scale();
|
||||
expect(scale).to.equal(crs.scaleFactor);
|
||||
});
|
||||
|
||||
it('uses the zoom level if provided', () => {
|
||||
var scale = crs.scale(1);
|
||||
expect(scale).to.equal(512);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#zoom', () => {
|
||||
it('returns zoom level for given scale', () => {
|
||||
var scale = 512;
|
||||
var zoom = crs.zoom(scale);
|
||||
|
||||
expect(zoom).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getProjectedBounds', () => {
|
||||
it('returns correct bounds without zoom', () => {
|
||||
var scaleFactor2 = crs.scaleFactor * 2;
|
||||
var bounds = crs.getProjectedBounds();
|
||||
|
||||
expect(Math.abs(bounds[1].x - bounds[0].x)).to.be.closeTo(scaleFactor2, 0.1);
|
||||
expect(Math.abs(bounds[1].y - bounds[0].y)).to.be.closeTo(scaleFactor2, 0.1);
|
||||
});
|
||||
|
||||
it('returns correct bounds with zoom', () => {
|
||||
var bounds = crs.getProjectedBounds(1);
|
||||
|
||||
expect(Math.abs(bounds[1].x - bounds[0].x)).to.be.closeTo(512, 0.1);
|
||||
expect(Math.abs(bounds[1].y - bounds[0].y)).to.be.closeTo(512, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#wrapLatLon', () => {
|
||||
it('wraps longitude between -180 and 180 by default', () => {
|
||||
expect(crs.wrapLatLon(LatLon(0, 190)).lon).to.equal(-170);
|
||||
expect(crs.wrapLatLon(LatLon(0, 360)).lon).to.equal(0);
|
||||
|
||||
expect(crs.wrapLatLon(LatLon(0, -190)).lon).to.equal(170);
|
||||
expect(crs.wrapLatLon(LatLon(0, -360)).lon).to.equal(0);
|
||||
|
||||
expect(crs.wrapLatLon(LatLon(0, 0)).lon).to.equal(0);
|
||||
expect(crs.wrapLatLon(LatLon(0, 180)).lon).to.equal(180);
|
||||
});
|
||||
|
||||
it('keeps altitude value', () => {
|
||||
expect(crs.wrapLatLon(LatLon(0, 190, 100)).lon).to.equal(-170);
|
||||
expect(crs.wrapLatLon(LatLon(0, 190, 100)).alt).to.equal(100);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#distance', () => {
|
||||
it('returns correct distance using cosine law approximation', () => {
|
||||
expect(crs.distance(LatLon(0, 0), LatLon(0.001, 0))).to.be.closeTo(111.31949492321543, 0.1);
|
||||
});
|
||||
|
||||
it('returns correct distance using Haversine', () => {
|
||||
expect(crs.distance(LatLon(0, 0), LatLon(0.001, 0), true)).to.be.closeTo(111.3194907932736, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointScale', () => {
|
||||
var pointScale;
|
||||
|
||||
it('returns approximate point scale factor', () => {
|
||||
pointScale = crs.pointScale(LatLon(0, 0));
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1, 0.1);
|
||||
|
||||
pointScale = crs.pointScale(LatLon(60, 0));
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1.9999999999999996, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1.9999999999999996, 0.1);
|
||||
});
|
||||
|
||||
it('returns accurate point scale factor', () => {
|
||||
pointScale = crs.pointScale(LatLon(0, 0), true);
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1.0067394967683778, 0.1);
|
||||
|
||||
pointScale = crs.pointScale(LatLon(60, 0), true);
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1.994972897047054, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1.9983341753952164, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#metresToProjected', () => {
|
||||
var pointScale;
|
||||
|
||||
it('returns correct projected units', () => {
|
||||
pointScale = crs.pointScale(LatLon(0, 0));
|
||||
expect(crs.metresToProjected(1, pointScale)).to.be.closeTo(1, 0.1);
|
||||
|
||||
pointScale = crs.pointScale(LatLon(60, 0));
|
||||
expect(crs.metresToProjected(1, pointScale)).to.be.closeTo(1.9999999999999996, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#projectedToMetres', () => {
|
||||
var pointScale;
|
||||
|
||||
it('returns correct real metres', () => {
|
||||
pointScale = crs.pointScale(LatLon(0, 0));
|
||||
expect(crs.projectedToMetres(1, pointScale)).to.be.closeTo(1, 0.1);
|
||||
|
||||
pointScale = crs.pointScale(LatLon(60, 0));
|
||||
expect(crs.projectedToMetres(1.9999999999999996, pointScale)).to.be.closeTo(1, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
// These two are combined as it is hard to write an invidual test that can
|
||||
// be specified without knowing or redifining crs.scaleFactor
|
||||
describe('#metresToWorld & #worldToMetres', () => {
|
||||
var pointScale;
|
||||
var worldUnits;
|
||||
var metres;
|
||||
|
||||
it('returns correct world units', () => {
|
||||
pointScale = crs.pointScale(LatLon(0, 0));
|
||||
worldUnits = crs.metresToWorld(1, pointScale);
|
||||
metres = crs.worldToMetres(worldUnits, pointScale);
|
||||
|
||||
expect(metres).to.be.closeTo(1, 0.1);
|
||||
|
||||
pointScale = crs.pointScale(LatLon(60, 0));
|
||||
worldUnits = crs.metresToWorld(1, pointScale);
|
||||
metres = crs.worldToMetres(worldUnits, pointScale);
|
||||
|
||||
expect(metres).to.be.closeTo(1, 0.1);
|
||||
});
|
||||
|
||||
it('returns correct world units using zoom', () => {
|
||||
pointScale = crs.pointScale(LatLon(0, 0));
|
||||
worldUnits = crs.metresToWorld(40075016.68556, pointScale, 1);
|
||||
|
||||
expect(worldUnits).to.be.closeTo(512, 0.1);
|
||||
|
||||
pointScale = crs.pointScale(LatLon(60, 0));
|
||||
worldUnits = crs.metresToWorld(40075016.68556, pointScale, 1);
|
||||
|
||||
expect(worldUnits).to.be.closeTo(512, 0.1);
|
||||
});
|
||||
|
||||
it('returns correct metres using zoom', () => {
|
||||
pointScale = crs.pointScale(LatLon(0, 0));
|
||||
worldUnits = crs.worldToMetres(512, pointScale, 1);
|
||||
|
||||
expect(worldUnits).to.be.closeTo(40075016.68556, 0.1);
|
||||
|
||||
pointScale = crs.pointScale(LatLon(60, 0));
|
||||
worldUnits = crs.worldToMetres(512, pointScale, 1);
|
||||
|
||||
expect(worldUnits).to.be.closeTo(40075016.68556, 0.1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Only test for code as the rest is identical to CRS.EPSG3857
|
||||
describe('CRS.EPSG900913', () => {
|
||||
var crs = CRS.EPSG900913;
|
||||
|
||||
describe('#code', () => {
|
||||
it('returns the correct code', () => {
|
||||
expect(crs.code).to.equal('EPSG:900913');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Basic tests for projection-specific stuff as the rest is likely ok given
|
||||
// correct projected / unprojected values
|
||||
describe('CRS.3395', () => {
|
||||
var crs = CRS.EPSG3395;
|
||||
|
||||
describe('#code', () => {
|
||||
it('returns the correct code', () => {
|
||||
expect(crs.code).to.equal('EPSG:3395');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#latLonToPoint', () => {
|
||||
it('projects the center', () => {
|
||||
var point = crs.latLonToPoint(LatLon(0, 0));
|
||||
|
||||
expect(point.x).to.be.closeTo(0, 0.01);
|
||||
expect(point.y).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('projects the North-West corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var point = crs.latLonToPoint(LatLon(85.0840591556, -180));
|
||||
|
||||
expect(point.x).to.be.closeTo(-scaleFactor, 0.01);
|
||||
expect(point.y).to.be.closeTo(-scaleFactor, 0.01);
|
||||
});
|
||||
|
||||
it('projects the South-East corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var point = crs.latLonToPoint(LatLon(-85.0840591556, 180));
|
||||
|
||||
expect(point.x).to.be.closeTo(scaleFactor, 0.01);
|
||||
expect(point.y).to.be.closeTo(scaleFactor, 0.01);
|
||||
});
|
||||
|
||||
it('projects using pixels if zoom is given', () => {
|
||||
var point = crs.latLonToPoint(LatLon(-85.0840591556, 180), 1);
|
||||
|
||||
expect(point.x).to.be.closeTo(256, 0.01);
|
||||
expect(point.y).to.be.closeTo(256, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointToLatLon', () => {
|
||||
it('unprojects the center', () => {
|
||||
var latlon = crs.pointToLatLon(Point(0, 0));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the North-West corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var latlon = crs.pointToLatLon(Point(-scaleFactor, -scaleFactor));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(85.0840591556, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(-180, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the South-East corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var latlon = crs.pointToLatLon(Point(scaleFactor, scaleFactor));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-85.0840591556, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(180, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects using pixels if zoom is given', () => {
|
||||
var latlon = crs.pointToLatLon(Point(256, 256), 1);
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-85.0840591556, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(180, 0.01);
|
||||
|
||||
latlon = crs.pointToLatLon(Point(0, 0), 1);
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Basic tests for projection-specific stuff as the rest is likely ok given
|
||||
// correct projected / unprojected values
|
||||
describe('CRS.4326', () => {
|
||||
var crs = CRS.EPSG4326;
|
||||
|
||||
describe('#code', () => {
|
||||
it('returns the correct code', () => {
|
||||
expect(crs.code).to.equal('EPSG:4326');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#latLonToPoint', () => {
|
||||
it('projects the center', () => {
|
||||
var point = crs.latLonToPoint(LatLon(0, 0));
|
||||
|
||||
expect(point.x).to.be.closeTo(0, 0.01);
|
||||
expect(point.y).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('projects the North-West corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var point = crs.latLonToPoint(LatLon(90, -180));
|
||||
|
||||
expect(point.x).to.be.closeTo(-scaleFactor, 0.01);
|
||||
|
||||
// Half scale factor as projection is not square
|
||||
expect(point.y).to.be.closeTo(-scaleFactor / 2, 0.01);
|
||||
});
|
||||
|
||||
it('projects the South-East corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var point = crs.latLonToPoint(LatLon(-90, 180));
|
||||
|
||||
expect(point.x).to.be.closeTo(scaleFactor, 0.01);
|
||||
|
||||
// Half scale factor as projection is not square
|
||||
expect(point.y).to.be.closeTo(scaleFactor / 2, 0.01);
|
||||
});
|
||||
|
||||
it('projects using pixels if zoom is given', () => {
|
||||
var point = crs.latLonToPoint(LatLon(-90, 180), 1);
|
||||
|
||||
expect(point.x).to.be.closeTo(256, 0.01);
|
||||
|
||||
// Half width as projection is not square
|
||||
expect(point.y).to.be.closeTo(128, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointToLatLon', () => {
|
||||
it('unprojects the center', () => {
|
||||
var latlon = crs.pointToLatLon(Point(0, 0));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the North-West corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var latlon = crs.pointToLatLon(Point(-scaleFactor, -scaleFactor / 2));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(90, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(-180, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the South-East corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var latlon = crs.pointToLatLon(Point(scaleFactor, scaleFactor / 2));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-90, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(180, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects using pixels if zoom is given', () => {
|
||||
var latlon = crs.pointToLatLon(Point(256, 128), 1);
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-90, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(180, 0.01);
|
||||
|
||||
latlon = crs.pointToLatLon(Point(0, 0), 1);
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Basic tests for projection-specific stuff as the rest is likely ok given
|
||||
// correct projected / unprojected values
|
||||
describe('CRS.Simple', () => {
|
||||
var crs = CRS.Simple;
|
||||
|
||||
describe('#latLonToPoint', () => {
|
||||
it('projects the center', () => {
|
||||
var point = crs.latLonToPoint(LatLon(0, 0));
|
||||
|
||||
expect(point.x).to.be.closeTo(0, 0.01);
|
||||
expect(point.y).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('projects the North-West corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var point = crs.latLonToPoint(LatLon(-500, -500));
|
||||
|
||||
expect(point.x).to.be.closeTo(-500, 0.01);
|
||||
expect(point.y).to.be.closeTo(-500, 0.01);
|
||||
});
|
||||
|
||||
it('projects the South-East corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var point = crs.latLonToPoint(LatLon(500, 500));
|
||||
|
||||
expect(point.x).to.be.closeTo(500, 0.01);
|
||||
expect(point.y).to.be.closeTo(500, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointToLatLon', () => {
|
||||
it('unprojects the center', () => {
|
||||
var latlon = crs.pointToLatLon(Point(0, 0));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the North-West corner', () => {
|
||||
var latlon = crs.pointToLatLon(Point(-500, -500));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-500, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(-500, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the South-East corner', () => {
|
||||
var latlon = crs.pointToLatLon(Point(500, 500));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(500, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(500, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#wrapLatLon', () => {
|
||||
it('no wrapping by default', () => {
|
||||
expect(crs.wrapLatLon(LatLon(0, 190)).lon).to.equal(190);
|
||||
expect(crs.wrapLatLon(LatLon(0, 360)).lon).to.equal(360);
|
||||
|
||||
expect(crs.wrapLatLon(LatLon(0, -190)).lon).to.equal(-190);
|
||||
expect(crs.wrapLatLon(LatLon(0, -360)).lon).to.equal(-360);
|
||||
|
||||
expect(crs.wrapLatLon(LatLon(0, 0)).lon).to.equal(0);
|
||||
expect(crs.wrapLatLon(LatLon(0, 180)).lon).to.equal(180);
|
||||
});
|
||||
|
||||
it('wraps if defined', () => {
|
||||
crs = extend({}, CRS.Simple, {
|
||||
wrapLat: [-90, 90],
|
||||
wrapLon: [-180, 180],
|
||||
});
|
||||
|
||||
expect(crs.wrapLatLon(LatLon(0, 190)).lon).to.equal(-170);
|
||||
expect(crs.wrapLatLon(LatLon(0, 360)).lon).to.equal(0);
|
||||
|
||||
expect(crs.wrapLatLon(LatLon(100, 0)).lat).to.equal(-80);
|
||||
expect(crs.wrapLatLon(LatLon(180, 0)).lat).to.equal(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#distance', () => {
|
||||
it('returns correct distance using trigonometry', () => {
|
||||
expect(crs.distance(LatLon(0, 0), LatLon(100, 0))).to.be.closeTo(100, 0.1);
|
||||
expect(crs.distance(LatLon(0, 0), LatLon(0, 100))).to.be.closeTo(100, 0.1);
|
||||
expect(crs.distance(LatLon(0, 0), LatLon(100, 100))).to.be.closeTo(141.4213562373095, 0.1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Basic tests for projection-specific stuff as the rest is likely ok given
|
||||
// correct projected / unprojected values
|
||||
describe('CRS.Proj4', () => {
|
||||
// British National Grid
|
||||
var crs = CRS.Proj4('EPSG:27700', '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units=m +no_defs', [[-84667.14, 11795.97], [608366.68, 1230247.30]]);
|
||||
|
||||
describe('#code', () => {
|
||||
it('returns the correct code', () => {
|
||||
expect(crs.code).to.equal('EPSG:27700');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#latLonToPoint', () => {
|
||||
it('projects the center', () => {
|
||||
var point = crs.latLonToPoint(LatLon(55.46347028885475, -4.186594751907175));
|
||||
|
||||
expect(point.x).to.be.closeTo(0, 0.01);
|
||||
expect(point.y).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('projects the North-West corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var point = crs.latLonToPoint(LatLon(60.6596573635804, -10.8865578798635));
|
||||
|
||||
// Only test y-axis as we know this is the largest size for 27700
|
||||
expect(point.y).to.be.closeTo(-scaleFactor, 0.01);
|
||||
});
|
||||
|
||||
it('projects the South-East corner', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
var point = crs.latLonToPoint(LatLon(49.9699671340061, 0.904406143400599));
|
||||
|
||||
// Only test y-axis as we know this is the largest size for 27700
|
||||
expect(point.y).to.be.closeTo(scaleFactor, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointToLatLon', () => {
|
||||
it('unprojects the center', () => {
|
||||
var latlon = crs.pointToLatLon(Point(0, 0));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(55.46347028885475, 0.1);
|
||||
expect(latlon.lon).to.be.closeTo(-4.186594751907175, 0.1);
|
||||
});
|
||||
|
||||
it('unprojects the North edge', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
|
||||
// Only test y-axis as we know this is the largest size for 27700
|
||||
//
|
||||
// Increased delta due to inaccuracy so far from 27700 origin
|
||||
var latlon = crs.pointToLatLon(Point(0, -scaleFactor));
|
||||
expect(latlon.lat).to.be.closeTo(60.6596573635804, 1);
|
||||
});
|
||||
|
||||
it('unprojects the South edge', () => {
|
||||
var scaleFactor = crs.scaleFactor;
|
||||
|
||||
// Only test y-axis as we know this is the largest size for 27700
|
||||
//
|
||||
// Increased delta due to inaccuracy so far from 27700 origin
|
||||
var latlon = crs.pointToLatLon(Point(0, scaleFactor));
|
||||
expect(latlon.lat).to.be.closeTo(49.9699671340061, 1);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,232 @@
|
|||
import extend from 'lodash.assign';
|
||||
import Geo from '../../src/geo/Geo';
|
||||
import {latLon as LatLon} from '../../src/geo/LatLon';
|
||||
import {point as Point} from '../../src/geo/Point';
|
||||
|
||||
describe('Geo', () => {
|
||||
describe('#latLonToPoint', () => {
|
||||
it('projects the center', () => {
|
||||
var point = Geo.latLonToPoint(LatLon(0, 0));
|
||||
|
||||
expect(point.x).to.be.closeTo(0, 0.01);
|
||||
expect(point.y).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('projects the North-West corner', () => {
|
||||
var bounds = Geo.bounds;
|
||||
var point = Geo.latLonToPoint(LatLon(85.0511287798, -180));
|
||||
|
||||
expect(point.x).to.be.closeTo(bounds[0][0], 0.01);
|
||||
expect(point.y).to.be.closeTo(bounds[0][1], 0.01);
|
||||
});
|
||||
|
||||
it('projects the South-East corner', () => {
|
||||
var bounds = Geo.bounds;
|
||||
var point = Geo.latLonToPoint(LatLon(-85.0511287798, 180));
|
||||
|
||||
expect(point.x).to.be.closeTo(bounds[1][0], 0.01);
|
||||
expect(point.x).to.be.closeTo(bounds[1][1], 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointToLatLon', () => {
|
||||
it('unprojects the center', () => {
|
||||
var latlon = Geo.pointToLatLon(Point(0, 0));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the North-West corner', () => {
|
||||
var bounds = Geo.bounds;
|
||||
var latlon = Geo.pointToLatLon(Point(bounds[0][0], bounds[0][1]));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(85.0511287798, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(-180, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the South-East corner', () => {
|
||||
var bounds = Geo.bounds;
|
||||
var latlon = Geo.pointToLatLon(Point(bounds[1][0], bounds[1][1]));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-85.0511287798, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(180, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#project', () => {
|
||||
it('projects the center', () => {
|
||||
var point = Geo.project(LatLon(0, 0));
|
||||
|
||||
expect(point.x).to.be.closeTo(0, 0.01);
|
||||
expect(point.y).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('projects the North-West corner', () => {
|
||||
var point = Geo.project(LatLon(85.0511287798, -180));
|
||||
|
||||
expect(point.x).to.be.closeTo(-20037508.34279, 0.01);
|
||||
expect(point.y).to.be.closeTo(20037508.34278, 0.01);
|
||||
});
|
||||
|
||||
it('projects the South-East corner', () => {
|
||||
var point = Geo.project(LatLon(-85.0511287798, 180));
|
||||
|
||||
expect(point.x).to.be.closeTo(20037508.34278, 0.01);
|
||||
expect(point.y).to.be.closeTo(-20037508.34278, 0.01);
|
||||
});
|
||||
|
||||
it('caps the maximum latitude', () => {
|
||||
var point = Geo.project(LatLon(-90, 180));
|
||||
|
||||
expect(point.x).to.be.closeTo(20037508.34278, 0.01);
|
||||
expect(point.y).to.be.closeTo(-20037508.34278, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#unproject', () => {
|
||||
it('unprojects the center', () => {
|
||||
var latlon = Geo.unproject(Point(0, 0));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the North-West corner', () => {
|
||||
var latlon = Geo.unproject(Point(-20037508.34278, 20037508.34278));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(85.0511287798, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(-180, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the South-East corner', () => {
|
||||
var latlon = Geo.unproject(Point(20037508.34278, -20037508.34278));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-85.0511287798, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(180, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#scale', () => {
|
||||
it('defaults to 1', () => {
|
||||
var scale = Geo.scale();
|
||||
expect(scale).to.equal(1);
|
||||
});
|
||||
|
||||
it('uses the zoom level if provided', () => {
|
||||
var scale = Geo.scale(1);
|
||||
expect(scale).to.equal(512);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#zoom', () => {
|
||||
it('returns zoom level for given scale', () => {
|
||||
var scale = 512;
|
||||
var zoom = Geo.zoom(scale);
|
||||
|
||||
expect(zoom).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
// describe('#wrapLatLon', () => {
|
||||
// it('wraps longitude between -180 and 180 by default', () => {
|
||||
// expect(Geo.wrapLatLon(LatLon(0, 190)).lon).to.equal(-170);
|
||||
// expect(Geo.wrapLatLon(LatLon(0, 360)).lon).to.equal(0);
|
||||
//
|
||||
// expect(Geo.wrapLatLon(LatLon(0, -190)).lon).to.equal(170);
|
||||
// expect(Geo.wrapLatLon(LatLon(0, -360)).lon).to.equal(0);
|
||||
//
|
||||
// expect(Geo.wrapLatLon(LatLon(0, 0)).lon).to.equal(0);
|
||||
// expect(Geo.wrapLatLon(LatLon(0, 180)).lon).to.equal(180);
|
||||
// });
|
||||
//
|
||||
// it('keeps altitude value', () => {
|
||||
// expect(Geo.wrapLatLon(LatLon(0, 190, 100)).lon).to.equal(-170);
|
||||
// expect(Geo.wrapLatLon(LatLon(0, 190, 100)).alt).to.equal(100);
|
||||
// });
|
||||
// });
|
||||
|
||||
describe('#distance', () => {
|
||||
it('returns correct distance using cosine law approximation', () => {
|
||||
expect(Geo.distance(LatLon(0, 0), LatLon(0.001, 0))).to.be.closeTo(111.31949492321543, 0.1);
|
||||
});
|
||||
|
||||
it('returns correct distance using Haversine', () => {
|
||||
expect(Geo.distance(LatLon(0, 0), LatLon(0.001, 0), true)).to.be.closeTo(111.3194907932736, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointScale', () => {
|
||||
var pointScale;
|
||||
|
||||
it('returns approximate point scale factor', () => {
|
||||
pointScale = Geo.pointScale(LatLon(0, 0));
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1, 0.1);
|
||||
|
||||
pointScale = Geo.pointScale(LatLon(60, 0));
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1.9999999999999996, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1.9999999999999996, 0.1);
|
||||
});
|
||||
|
||||
it('returns accurate point scale factor', () => {
|
||||
pointScale = Geo.pointScale(LatLon(0, 0), true);
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1.0067394967683778, 0.1);
|
||||
|
||||
pointScale = Geo.pointScale(LatLon(60, 0), true);
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1.994972897047054, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1.9983341753952164, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#metresToProjected', () => {
|
||||
var pointScale;
|
||||
|
||||
it('returns correct projected units', () => {
|
||||
pointScale = Geo.pointScale(LatLon(0, 0));
|
||||
expect(Geo.metresToProjected(1, pointScale)).to.be.closeTo(1, 0.1);
|
||||
|
||||
pointScale = Geo.pointScale(LatLon(60, 0));
|
||||
expect(Geo.metresToProjected(1, pointScale)).to.be.closeTo(1.9999999999999996, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#projectedToMetres', () => {
|
||||
var pointScale;
|
||||
|
||||
it('returns correct real metres', () => {
|
||||
pointScale = Geo.pointScale(LatLon(0, 0));
|
||||
expect(Geo.projectedToMetres(1, pointScale)).to.be.closeTo(1, 0.1);
|
||||
|
||||
pointScale = Geo.pointScale(LatLon(60, 0));
|
||||
expect(Geo.projectedToMetres(1.9999999999999996, pointScale)).to.be.closeTo(1, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
// These two are combined as it is hard to write an invidual test that can
|
||||
// be specified without knowing or redifining Geo.scaleFactor
|
||||
describe('#metresToWorld & #worldToMetres', () => {
|
||||
var pointScale;
|
||||
var worldUnits;
|
||||
var metres;
|
||||
|
||||
it('returns correct world units', () => {
|
||||
pointScale = Geo.pointScale(LatLon(0, 0));
|
||||
worldUnits = Geo.metresToWorld(1, pointScale);
|
||||
metres = Geo.worldToMetres(worldUnits, pointScale);
|
||||
|
||||
expect(metres).to.be.closeTo(1, 0.1);
|
||||
|
||||
pointScale = Geo.pointScale(LatLon(60, 0));
|
||||
worldUnits = Geo.metresToWorld(1, pointScale);
|
||||
metres = Geo.worldToMetres(worldUnits, pointScale);
|
||||
|
||||
expect(metres).to.be.closeTo(1, 0.1);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,327 +0,0 @@
|
|||
import Projection from '../../src/geo/projection/index';
|
||||
import {latLon as LatLon} from '../../src/geo/LatLon';
|
||||
import {point as Point} from '../../src/geo/Point';
|
||||
|
||||
describe('Projection.SphericalMercator', () => {
|
||||
var projection = Projection.SphericalMercator;
|
||||
|
||||
describe('#project', () => {
|
||||
it('projects the center', () => {
|
||||
var point = projection.project(LatLon(0, 0));
|
||||
|
||||
expect(point.x).to.be.closeTo(0, 0.01);
|
||||
expect(point.y).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('projects the North-West corner', () => {
|
||||
var point = projection.project(LatLon(85.0511287798, -180));
|
||||
|
||||
expect(point.x).to.be.closeTo(-20037508.34279, 0.01);
|
||||
expect(point.y).to.be.closeTo(20037508.34278, 0.01);
|
||||
});
|
||||
|
||||
it('projects the South-East corner', () => {
|
||||
var point = projection.project(LatLon(-85.0511287798, 180));
|
||||
|
||||
expect(point.x).to.be.closeTo(20037508.34278, 0.01);
|
||||
expect(point.y).to.be.closeTo(-20037508.34278, 0.01);
|
||||
});
|
||||
|
||||
it('caps the maximum latitude', () => {
|
||||
var point = projection.project(LatLon(-90, 180));
|
||||
|
||||
expect(point.x).to.be.closeTo(20037508.34278, 0.01);
|
||||
expect(point.y).to.be.closeTo(-20037508.34278, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#unproject', () => {
|
||||
it('unprojects the center', () => {
|
||||
var latlon = projection.unproject(Point(0, 0));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the North-West corner', () => {
|
||||
var latlon = projection.unproject(Point(-20037508.34278, 20037508.34278));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(85.0511287798, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(-180, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the South-East corner', () => {
|
||||
var latlon = projection.unproject(Point(20037508.34278, -20037508.34278));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-85.0511287798, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(180, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointScale', () => {
|
||||
var pointScale;
|
||||
|
||||
it('returns approximate point scale factor', () => {
|
||||
pointScale = projection.pointScale(LatLon(0, 0));
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1, 0.1);
|
||||
|
||||
pointScale = projection.pointScale(LatLon(60, 0));
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1.9999999999999996, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1.9999999999999996, 0.1);
|
||||
});
|
||||
|
||||
it('returns accurate point scale factor', () => {
|
||||
pointScale = projection.pointScale(LatLon(0, 0), true);
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1.0067394967683778, 0.1);
|
||||
|
||||
pointScale = projection.pointScale(LatLon(60, 0), true);
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1.994972897047054, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1.9983341753952164, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#bounds', () => {
|
||||
it('returns correct bounds', () => {
|
||||
var dimensions = 40075016.6855785;
|
||||
var bounds = projection.bounds;
|
||||
|
||||
expect(Math.abs(bounds[1][0] - bounds[0][0])).to.be.closeTo(dimensions, 0.1);
|
||||
expect(Math.abs(bounds[1][1] - bounds[0][1])).to.be.closeTo(dimensions, 0.1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Projection.Mercator', () => {
|
||||
var projection = Projection.Mercator;
|
||||
|
||||
describe('#project', () => {
|
||||
it('projects the center', () => {
|
||||
var point = projection.project(LatLon(0, 0));
|
||||
|
||||
expect(point.x).to.be.closeTo(0, 0.01);
|
||||
expect(point.y).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('projects the North-West corner', () => {
|
||||
var point = projection.project(LatLon(85.0840591556, -180));
|
||||
|
||||
expect(point.x).to.be.closeTo(-20037508.34279, 0.01);
|
||||
expect(point.y).to.be.closeTo(20037508.4798169, 0.01);
|
||||
});
|
||||
|
||||
it('projects the South-East corner', () => {
|
||||
var point = projection.project(LatLon(-85.0840591556, 180));
|
||||
|
||||
expect(point.x).to.be.closeTo(20037508.34279, 0.01);
|
||||
expect(point.y).to.be.closeTo(-20037508.4798169, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#unproject', () => {
|
||||
it('unprojects the center', () => {
|
||||
var latlon = projection.unproject(Point(0, 0));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the North-West corner', () => {
|
||||
var latlon = projection.unproject(Point(-20037508.34279, 20037508.4798169));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(85.0840591556, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(-180, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the South-East corner', () => {
|
||||
var latlon = projection.unproject(Point(20037508.34279, -20037508.4798169));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-85.0840591556, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(180, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointScale', () => {
|
||||
var pointScale;
|
||||
|
||||
it('returns point scale factor', () => {
|
||||
pointScale = projection.pointScale(LatLon(0, 0));
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1, 0.1);
|
||||
|
||||
pointScale = projection.pointScale(LatLon(60, 0));
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1.9999999999999996, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1.9999999999999996, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#bounds', () => {
|
||||
it('returns correct bounds', () => {
|
||||
var dimensions = [40075016.68558, 34261226.9711];
|
||||
var bounds = projection.bounds;
|
||||
|
||||
expect(Math.abs(bounds[1][0] - bounds[0][0])).to.be.closeTo(dimensions[0], 0.1);
|
||||
expect(Math.abs(bounds[1][1] - bounds[0][1])).to.be.closeTo(dimensions[1], 0.1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Projection.LatLon', () => {
|
||||
var projection = Projection.LatLon;
|
||||
|
||||
describe('#project', () => {
|
||||
it('projects the center', () => {
|
||||
var point = projection.project(LatLon(0, 0));
|
||||
|
||||
expect(point.x).to.be.closeTo(0, 0.01);
|
||||
expect(point.y).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('projects the North-West corner', () => {
|
||||
var point = projection.project(LatLon(90, -180));
|
||||
|
||||
expect(point.x).to.be.closeTo(-180, 0.01);
|
||||
expect(point.y).to.be.closeTo(90, 0.01);
|
||||
});
|
||||
|
||||
it('projects the South-East corner', () => {
|
||||
var point = projection.project(LatLon(-90, 180));
|
||||
|
||||
expect(point.x).to.be.closeTo(180, 0.01);
|
||||
expect(point.y).to.be.closeTo(-90, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#unproject', () => {
|
||||
it('unprojects the center', () => {
|
||||
var latlon = projection.unproject(Point(0, 0));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(0, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the North-West corner', () => {
|
||||
var latlon = projection.unproject(Point(-180, 90));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(90, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(-180, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the South-East corner', () => {
|
||||
var latlon = projection.unproject(Point(180, -90));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(-90, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(180, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointScale', () => {
|
||||
var pointScale;
|
||||
|
||||
it('returns point scale factor', () => {
|
||||
pointScale = projection.pointScale(LatLon(0, 0));
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(0.000009043695025814084, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(0.000009043695025814084, 0.1);
|
||||
|
||||
pointScale = projection.pointScale(LatLon(60, 0));
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(0.000009043695025814084, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(0.000009043695025814084, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#bounds', () => {
|
||||
it('returns correct bounds', () => {
|
||||
var dimensions = [360, 180];
|
||||
var bounds = projection.bounds;
|
||||
|
||||
expect(Math.abs(bounds[1][0] - bounds[0][0])).to.be.closeTo(dimensions[0], 0.1);
|
||||
expect(Math.abs(bounds[1][1] - bounds[0][1])).to.be.closeTo(dimensions[1], 0.1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Projection.Proj4', () => {
|
||||
// British National Grid
|
||||
var projection = Projection.Proj4('+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units=m +no_defs', [[-84667.14, 11795.97], [608366.68, 1230247.30]]);
|
||||
|
||||
describe('#project', () => {
|
||||
it('projects the center', () => {
|
||||
var point = projection.project(LatLon(55.46347028885475, -4.186594751907175));
|
||||
|
||||
expect(point.x).to.be.closeTo(261849.77, 0.1);
|
||||
expect(point.y).to.be.closeTo(621021.635, 0.1);
|
||||
});
|
||||
|
||||
it('projects the North-West corner', () => {
|
||||
var point = projection.project(LatLon(60.6596573635804, -10.8865578798635));
|
||||
|
||||
expect(point.x).to.be.closeTo(-84667.14, 0.1);
|
||||
expect(point.y).to.be.closeTo(1230247.30, 0.1);
|
||||
});
|
||||
|
||||
it('projects the South-East corner', () => {
|
||||
var point = projection.project(LatLon(49.9699671340061, 0.904406143400599));
|
||||
|
||||
expect(point.x).to.be.closeTo(608366.68, 0.1);
|
||||
expect(point.y).to.be.closeTo(11795.97, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#unproject', () => {
|
||||
it('unprojects the center', () => {
|
||||
var latlon = projection.unproject(Point(261849.77, 621021.635));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(55.46347028885475, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(-4.186594751907175, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the North-West corner', () => {
|
||||
var latlon = projection.unproject(Point(-84667.14, 1230247.30));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(60.6596573635804, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(-10.8865578798635, 0.01);
|
||||
});
|
||||
|
||||
it('unprojects the South-East corner', () => {
|
||||
var latlon = projection.unproject(Point(608366.68, 11795.97));
|
||||
|
||||
expect(latlon.lat).to.be.closeTo(49.9699671340061, 0.01);
|
||||
expect(latlon.lon).to.be.closeTo(0.904406143400599, 0.01);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#pointScale', () => {
|
||||
var pointScale;
|
||||
|
||||
it('returns point scale factor', () => {
|
||||
pointScale = projection.pointScale(LatLon(0, 0));
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1, 0.1);
|
||||
|
||||
pointScale = projection.pointScale(LatLon(60, 0));
|
||||
|
||||
expect(pointScale[0]).to.be.closeTo(1, 0.1);
|
||||
expect(pointScale[1]).to.be.closeTo(1, 0.1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#bounds', () => {
|
||||
it('returns correct bounds', () => {
|
||||
var dimensions = [693033.82, 1218451.33];
|
||||
var bounds = projection.bounds;
|
||||
|
||||
expect(Math.abs(bounds[1][0] - bounds[0][0])).to.be.closeTo(dimensions[0], 0.1);
|
||||
expect(Math.abs(bounds[1][1] - bounds[0][1])).to.be.closeTo(dimensions[1], 0.1);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,47 +0,0 @@
|
|||
import Transformation from '../../src/util/Transformation';
|
||||
import {point as Point} from '../../src/geo/Point';
|
||||
|
||||
describe('Transformation', () => {
|
||||
var transformation;
|
||||
var point;
|
||||
var scale;
|
||||
|
||||
// Probably superflous to use spies here but they serve as an example of how
|
||||
// to use them in this way at least
|
||||
beforeEach(() => {
|
||||
transformation = new Transformation(1, 0.5, 1, 0.5);
|
||||
spy(transformation, 'transform');
|
||||
spy(transformation, 'untransform');
|
||||
|
||||
point = Point(5, 5);
|
||||
scale = 2;
|
||||
});
|
||||
|
||||
describe('#transform', () => {
|
||||
it('can transform', () => {
|
||||
var point2 = transformation.transform(point, scale);
|
||||
expect(transformation.transform).to.have.returned(Point(11, 11));
|
||||
});
|
||||
|
||||
it('uses a scale of 1 by default', () => {
|
||||
transformation.transform(point);
|
||||
expect(transformation.transform).to.have.returned(Point(5.5, 5.5));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#untransform', () => {
|
||||
it('can untransform', () => {
|
||||
var point2 = transformation.transform(point, scale);
|
||||
var point3 = transformation.untransform(point2, scale);
|
||||
|
||||
expect(transformation.untransform).to.have.returned(point);
|
||||
});
|
||||
|
||||
it('uses a scale of 1 by default', () => {
|
||||
var point2 = transformation.transform(point);
|
||||
var point3 = transformation.untransform(point2);
|
||||
|
||||
expect(transformation.untransform).to.have.returned(point);
|
||||
});
|
||||
});
|
||||
});
|
Ładowanie…
Reference in New Issue