kopia lustrzana https://github.com/robhawkes/vizicities
				
				
				
			Added Point and LatLon as well as updating all the tests
							rodzic
							
								
									b91cd9f999
								
							
						
					
					
						commit
						1b1f4bc5af
					
				
										
											
												Plik diff jest za duży
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										55
									
								
								src/World.js
								
								
								
								
							
							
						
						
									
										55
									
								
								src/World.js
								
								
								
								
							| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
import EventEmitter from 'eventemitter3';
 | 
			
		||||
import extend from 'lodash.assign';
 | 
			
		||||
import CRS from './geo/CRS/index';
 | 
			
		||||
import Point from './geo/Point';
 | 
			
		||||
import LatLon from './geo/LatLon';
 | 
			
		||||
import Engine from './engine/Engine';
 | 
			
		||||
 | 
			
		||||
// Pretty much any event someone using ViziCities would need will be emitted or
 | 
			
		||||
| 
						 | 
				
			
			@ -14,9 +16,7 @@ class World extends EventEmitter {
 | 
			
		|||
      crs: CRS.EPSG3857
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    this._options = extend(defaults, options);
 | 
			
		||||
 | 
			
		||||
    console.log(this._options);
 | 
			
		||||
    this.options = extend(defaults, options);
 | 
			
		||||
 | 
			
		||||
    this._layers = [];
 | 
			
		||||
    this._controls = [];
 | 
			
		||||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ class World extends EventEmitter {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  _onControlsMoveEnd(point) {
 | 
			
		||||
    this._resetView(this.unproject(point));
 | 
			
		||||
    this._resetView(this.pointToLatLon([point.x, point.z]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Reset world view
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +92,17 @@ class World extends EventEmitter {
 | 
			
		|||
 | 
			
		||||
  // Set world view
 | 
			
		||||
  setView(latlon) {
 | 
			
		||||
    // Store initial geographic coordinate for the [0,0,0] world position
 | 
			
		||||
    //
 | 
			
		||||
    // The origin point doesn't move in three.js / 3D space so only set it once
 | 
			
		||||
    // here instead of every time _resetView is called
 | 
			
		||||
    //
 | 
			
		||||
    // If it was updated every time then coorindates would shift over time and
 | 
			
		||||
    // would be out of place / context with previously-placed points (0,0 would
 | 
			
		||||
    // refer to a different point each time)
 | 
			
		||||
    this._originLatlon = latlon;
 | 
			
		||||
    this._originPoint = this.project(latlon);
 | 
			
		||||
 | 
			
		||||
    this._resetView(latlon);
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -102,10 +113,42 @@ class World extends EventEmitter {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  // Transform geographic coordinate to world point
 | 
			
		||||
  project(latlon) {}
 | 
			
		||||
  //
 | 
			
		||||
  // This doesn't take into account the origin offset
 | 
			
		||||
  //
 | 
			
		||||
  // For example, this takes a geographic coordinate and returns a point
 | 
			
		||||
  // relative to the origin point of the projection (not the world)
 | 
			
		||||
  project(latlon) {
 | 
			
		||||
    return this.options.crs.latLonToPoint(LatLon(latlon));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Transform world point to geographic coordinate
 | 
			
		||||
  unproject(point) {}
 | 
			
		||||
  //
 | 
			
		||||
  // This doesn't take into account the origin offset
 | 
			
		||||
  //
 | 
			
		||||
  // For example, this takes a point relative to the origin point of the
 | 
			
		||||
  // projection (not the world) and returns a geographic coordinate
 | 
			
		||||
  unproject(point) {
 | 
			
		||||
    return this.options.crs.pointToLatLon(Point(point));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Takes into account the origin offset
 | 
			
		||||
  //
 | 
			
		||||
  // For example, this takes a geographic coordinate and returns a point
 | 
			
		||||
  // relative to the three.js / 3D origin (0,0)
 | 
			
		||||
  latLonToPoint(latlon) {
 | 
			
		||||
    var projectedPoint = this.project(LatLon(latlon));
 | 
			
		||||
    return projectedPoint._subtract(this._originPoint);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Takes into account the origin offset
 | 
			
		||||
  //
 | 
			
		||||
  // For example, this takes a point relative to the three.js / 3D origin (0,0)
 | 
			
		||||
  // and returns the exact geographic coordinate at that point
 | 
			
		||||
  pointToLatLon(point) {
 | 
			
		||||
    var projectedPoint = Point(point).add(this._originPoint);
 | 
			
		||||
    return this.unproject(projectedPoint);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  addLayer(layer) {
 | 
			
		||||
    layer._addToWorld(this);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,7 +75,11 @@ class Orbit extends EventEmitter {
 | 
			
		|||
    // See: http://stackoverflow.com/a/26188674/997339
 | 
			
		||||
    this._controls = new _OrbitControls(world._engine._camera, world._container);
 | 
			
		||||
 | 
			
		||||
    this._controls.maxPolarAngle = Math.PI / 2;
 | 
			
		||||
    // Disable keys for now as no events are fired for them anyway
 | 
			
		||||
    this._controls.keys = false;
 | 
			
		||||
 | 
			
		||||
    // 89 degrees
 | 
			
		||||
    this._controls.maxPolarAngle = 1.5533;
 | 
			
		||||
 | 
			
		||||
    // this._controls.enableDamping = true;
 | 
			
		||||
    // this._controls.dampingFactor = 0.25;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
/*
 | 
			
		||||
 * LatLon is a helper class for ensuring consistent geographic coordinates.
 | 
			
		||||
 *
 | 
			
		||||
 * Based on:
 | 
			
		||||
 * https://github.com/Leaflet/Leaflet/blob/master/src/geo/LatLng.js
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
class LatLon {
 | 
			
		||||
  constructor(lat, lon, alt) {
 | 
			
		||||
    if (isNaN(lat) || isNaN(lon)) {
 | 
			
		||||
      throw new Error('Invalid LatLon object: (' + lat + ', ' + lon + ')');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.lat = +lat;
 | 
			
		||||
    this.lon = +lon;
 | 
			
		||||
 | 
			
		||||
    if (alt !== undefined) {
 | 
			
		||||
      this.alt = +alt;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  clone() {
 | 
			
		||||
    return new LatLon(this.lat, this.lon, this.alt);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Initialise without requiring new keyword
 | 
			
		||||
//
 | 
			
		||||
// Accepts (LatLon), ([lat, lon, alt]), ([lat, lon]) and (lat, lon, alt)
 | 
			
		||||
// Also converts between lng and lon
 | 
			
		||||
export default function(a, b, c) {
 | 
			
		||||
  if (a instanceof LatLon) {
 | 
			
		||||
    return a;
 | 
			
		||||
  }
 | 
			
		||||
  if (Array.isArray(a) && typeof a[0] !== 'object') {
 | 
			
		||||
    if (a.length === 3) {
 | 
			
		||||
      return new LatLon(a[0], a[1], a[2]);
 | 
			
		||||
    }
 | 
			
		||||
    if (a.length === 2) {
 | 
			
		||||
      return new LatLon(a[0], a[1]);
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
  if (a === undefined || a === null) {
 | 
			
		||||
    return a;
 | 
			
		||||
  }
 | 
			
		||||
  if (typeof a === 'object' && 'lat' in a) {
 | 
			
		||||
    return new LatLon(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);
 | 
			
		||||
  }
 | 
			
		||||
  if (b === undefined) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
  return new LatLon(a, b, c);
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Point is a helper class for ensuring consistent world positions.
 | 
			
		||||
 *
 | 
			
		||||
 * Based on:
 | 
			
		||||
 * https://github.com/Leaflet/Leaflet/blob/master/src/geo/Point.js
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
class Point {
 | 
			
		||||
  constructor(x, y, round) {
 | 
			
		||||
    this.x = (round ? Math.round(x) : x);
 | 
			
		||||
    this.y = (round ? Math.round(y) : y);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  clone() {
 | 
			
		||||
    return new Point(this.x, this.y);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Non-destructive
 | 
			
		||||
  add(point) {
 | 
			
		||||
    return this.clone()._add(_point(point));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Destructive
 | 
			
		||||
  _add(point) {
 | 
			
		||||
    this.x += point.x;
 | 
			
		||||
    this.y += point.y;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Non-destructive
 | 
			
		||||
  subtract(point) {
 | 
			
		||||
    return this.clone()._subtract(_point(point));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Destructive
 | 
			
		||||
  _subtract(point) {
 | 
			
		||||
    this.x -= point.x;
 | 
			
		||||
    this.y -= point.y;
 | 
			
		||||
    return this;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Accepts (point), ([x, y]) and (x, y, round)
 | 
			
		||||
var _point = function(x, y, round) {
 | 
			
		||||
  if (x instanceof Point) {
 | 
			
		||||
    return x;
 | 
			
		||||
  }
 | 
			
		||||
  if (Array.isArray(x)) {
 | 
			
		||||
    return new Point(x[0], x[1]);
 | 
			
		||||
  }
 | 
			
		||||
  if (x === undefined || x === null) {
 | 
			
		||||
    return x;
 | 
			
		||||
  }
 | 
			
		||||
  return new Point(x, y, round);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Initialise without requiring new keyword
 | 
			
		||||
export default _point;
 | 
			
		||||
| 
						 | 
				
			
			@ -7,12 +7,12 @@
 | 
			
		|||
 | 
			
		||||
import extend from 'lodash.assign';
 | 
			
		||||
import Earth from './CRS.Earth';
 | 
			
		||||
import LatLon from '../projection/Projection.LatLon';
 | 
			
		||||
import LatLonProjection from '../projection/Projection.LatLon';
 | 
			
		||||
import Transformation from '../../util/Transformation';
 | 
			
		||||
 | 
			
		||||
var _EPSG4326 = {
 | 
			
		||||
  code: 'EPSG:4326',
 | 
			
		||||
  projection: LatLon,
 | 
			
		||||
  projection: LatLonProjection,
 | 
			
		||||
 | 
			
		||||
  // Work out how to de-dupe this (scoping issue)
 | 
			
		||||
  transformScale: 1 / 180,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
 | 
			
		||||
import extend from 'lodash.assign';
 | 
			
		||||
import CRS from './CRS';
 | 
			
		||||
import LatLon from '../LatLon';
 | 
			
		||||
 | 
			
		||||
const Earth = {
 | 
			
		||||
  wrapLon: [-180, 180],
 | 
			
		||||
| 
						 | 
				
			
			@ -26,18 +27,18 @@ const Earth = {
 | 
			
		|||
    var a;
 | 
			
		||||
 | 
			
		||||
    if (!accurate) {
 | 
			
		||||
      lat1 = latlon1[0] * rad;
 | 
			
		||||
      lat2 = latlon2[0] * rad;
 | 
			
		||||
      lat1 = latlon1.lat * rad;
 | 
			
		||||
      lat2 = latlon2.lat * rad;
 | 
			
		||||
 | 
			
		||||
      a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlon2[1] - latlon1[1]) * 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[0] * rad;
 | 
			
		||||
      lat2 = latlon2[0] * rad;
 | 
			
		||||
      lat1 = latlon1.lat * rad;
 | 
			
		||||
      lat2 = latlon2.lat * rad;
 | 
			
		||||
 | 
			
		||||
      var lon1 = latlon1[1] * rad;
 | 
			
		||||
      var lon2 = latlon2[1] * rad;
 | 
			
		||||
      var lon1 = latlon1.lon * rad;
 | 
			
		||||
      var lon2 = latlon2.lon * rad;
 | 
			
		||||
 | 
			
		||||
      var deltaLat = lat2 - lat1;
 | 
			
		||||
      var deltaLon = lon2 - lon1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,11 +8,11 @@
 | 
			
		|||
 | 
			
		||||
import extend from 'lodash.assign';
 | 
			
		||||
import CRS from './CRS';
 | 
			
		||||
import LatLon from '../projection/Projection.LatLon';
 | 
			
		||||
import LatLonProjection from '../projection/Projection.LatLon';
 | 
			
		||||
import Transformation from '../../util/Transformation';
 | 
			
		||||
 | 
			
		||||
var _Simple = {
 | 
			
		||||
  projection: LatLon,
 | 
			
		||||
  projection: LatLonProjection,
 | 
			
		||||
 | 
			
		||||
  // Straight 1:1 mapping (-1, -1 would be top-left)
 | 
			
		||||
  transformation: new Transformation(1, 0, 1, 0),
 | 
			
		||||
| 
						 | 
				
			
			@ -33,8 +33,8 @@ var _Simple = {
 | 
			
		|||
  },
 | 
			
		||||
 | 
			
		||||
  distance: function(latlon1, latlon2) {
 | 
			
		||||
    var dx = latlon2[1] - latlon1[1];
 | 
			
		||||
    var dy = latlon2[0] - latlon1[0];
 | 
			
		||||
    var dx = latlon2.lon - latlon1.lon;
 | 
			
		||||
    var dy = latlon2.lat - latlon1.lat;
 | 
			
		||||
 | 
			
		||||
    return Math.sqrt(dx * dx + dy * dy);
 | 
			
		||||
  },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,8 @@
 | 
			
		|||
 * https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.js
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import LatLon from '../LatLon';
 | 
			
		||||
import Point from '../Point';
 | 
			
		||||
import wrapNum from '../../util/wrapNum';
 | 
			
		||||
 | 
			
		||||
const CRS = {
 | 
			
		||||
| 
						 | 
				
			
			@ -90,10 +92,10 @@ const CRS = {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // Bottom left
 | 
			
		||||
    var min = this.transformation.transform(b[0], s);
 | 
			
		||||
    var min = this.transformation.transform(Point(b[0]), s);
 | 
			
		||||
 | 
			
		||||
    // Top right
 | 
			
		||||
    var max = this.transformation.transform(b[1], s);
 | 
			
		||||
    var max = this.transformation.transform(Point(b[1]), s);
 | 
			
		||||
 | 
			
		||||
    return [min, max];
 | 
			
		||||
  },
 | 
			
		||||
| 
						 | 
				
			
			@ -107,11 +109,11 @@ const CRS = {
 | 
			
		|||
 | 
			
		||||
  // Wraps geo coords in certain ranges if applicable
 | 
			
		||||
  wrapLatLon: function(latlon) {
 | 
			
		||||
    var lat = this.wrapLat ? wrapNum(latlon[0], this.wrapLat, true) : latlon[0];
 | 
			
		||||
    var lng = this.wrapLon ? wrapNum(latlon[1], this.wrapLon, true) : latlon[1];
 | 
			
		||||
    var alt = latlon[2];
 | 
			
		||||
    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 [lat, lng, alt];
 | 
			
		||||
    return LatLon(lat, lon, alt);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,13 +6,16 @@
 | 
			
		|||
 * https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.LonLat.js
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
const LatLon = {
 | 
			
		||||
import LatLon from '../LatLon';
 | 
			
		||||
import Point from '../Point';
 | 
			
		||||
 | 
			
		||||
const ProjectionLatLon = {
 | 
			
		||||
  project: function(latlon) {
 | 
			
		||||
    return [latlon[1], latlon[0]];
 | 
			
		||||
    return Point(latlon.lon, latlon.lat);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  unproject: function(point) {
 | 
			
		||||
    return [point[1], point[0]];
 | 
			
		||||
    return LatLon(point.y, point.x);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  // Scale factor for converting between real metres and degrees
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +35,7 @@ const LatLon = {
 | 
			
		|||
    var p3 = 0.118;
 | 
			
		||||
 | 
			
		||||
    var rad = Math.PI / 180;
 | 
			
		||||
    var lat = latlon[0] * rad;
 | 
			
		||||
    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);
 | 
			
		||||
| 
						 | 
				
			
			@ -43,4 +46,4 @@ const LatLon = {
 | 
			
		|||
  bounds: [[-180, -90], [180, 90]]
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default LatLon;
 | 
			
		||||
export default ProjectionLatLon;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,9 @@
 | 
			
		|||
 * https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.Mercator.js
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import LatLon from '../LatLon';
 | 
			
		||||
import Point from '../Point';
 | 
			
		||||
 | 
			
		||||
const Mercator = {
 | 
			
		||||
  // Radius / WGS84 semi-major axis
 | 
			
		||||
  R: 6378137,
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +22,7 @@ const Mercator = {
 | 
			
		|||
  project: function(latlon) {
 | 
			
		||||
    var d = Math.PI / 180;
 | 
			
		||||
    var r = this.R;
 | 
			
		||||
    var y = latlon[0] * d;
 | 
			
		||||
    var y = latlon.lat * d;
 | 
			
		||||
    var tmp = this.R_MINOR / r;
 | 
			
		||||
    var e = Math.sqrt(1 - tmp * tmp);
 | 
			
		||||
    var con = e * Math.sin(y);
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +30,7 @@ const Mercator = {
 | 
			
		|||
    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 [latlon[1] * d * r, y];
 | 
			
		||||
    return Point(latlon.lon * d * r, y);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  unproject: function(point) {
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +38,7 @@ const Mercator = {
 | 
			
		|||
    var r = this.R;
 | 
			
		||||
    var tmp = this.R_MINOR / r;
 | 
			
		||||
    var e = Math.sqrt(1 - tmp * tmp);
 | 
			
		||||
    var ts = Math.exp(-point[1] / r);
 | 
			
		||||
    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++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +48,7 @@ const Mercator = {
 | 
			
		|||
      phi += dphi;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return [phi * d, point[0] * d / r];
 | 
			
		||||
    return LatLon(phi * d, point.x * d / r);
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  // Scale factor for converting between real metres and projected metres
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +59,7 @@ const Mercator = {
 | 
			
		|||
  // 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[0] * rad;
 | 
			
		||||
    var lat = latlon.lat * rad;
 | 
			
		||||
    var sinLat = Math.sin(lat);
 | 
			
		||||
    var sinLat2 = sinLat * sinLat;
 | 
			
		||||
    var cosLat = Math.cos(lat);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,17 +3,19 @@
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
import proj4 from 'proj4';
 | 
			
		||||
import LatLon from '../LatLon';
 | 
			
		||||
import Point from '../Point';
 | 
			
		||||
 | 
			
		||||
const Proj4 = function(def, bounds) {
 | 
			
		||||
  var proj = proj4(def);
 | 
			
		||||
 | 
			
		||||
  var project = function(latlon) {
 | 
			
		||||
    return proj.forward([latlon[1], latlon[0]]);
 | 
			
		||||
    return Point(proj.forward([latlon.lon, latlon.lat]));
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  var unproject = function(point) {
 | 
			
		||||
    var inverse = proj.inverse(point);
 | 
			
		||||
    return [inverse[1], inverse[0]];
 | 
			
		||||
    var inverse = proj.inverse([point.x, point.y]);
 | 
			
		||||
    return LatLon(inverse[1], inverse[0]);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,9 @@
 | 
			
		|||
 * https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import LatLon from '../LatLon';
 | 
			
		||||
import Point from '../Point';
 | 
			
		||||
 | 
			
		||||
const SphericalMercator = {
 | 
			
		||||
  // Radius / WGS84 semi-major axis
 | 
			
		||||
  R: 6378137,
 | 
			
		||||
| 
						 | 
				
			
			@ -18,22 +21,22 @@ const SphericalMercator = {
 | 
			
		|||
  project: function(latlon) {
 | 
			
		||||
    var d = Math.PI / 180;
 | 
			
		||||
    var max = this.MAX_LATITUDE;
 | 
			
		||||
    var lat = Math.max(Math.min(max, latlon[0]), -max);
 | 
			
		||||
    var lat = Math.max(Math.min(max, latlon.lat), -max);
 | 
			
		||||
    var sin = Math.sin(lat * d);
 | 
			
		||||
 | 
			
		||||
    return [
 | 
			
		||||
      this.R * latlon[1] * 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 [
 | 
			
		||||
      (2 * Math.atan(Math.exp(point[1] / this.R)) - (Math.PI / 2)) * d,
 | 
			
		||||
      point[0] * d / this.R
 | 
			
		||||
    ];
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			@ -50,13 +53,13 @@ const SphericalMercator = {
 | 
			
		|||
    var k;
 | 
			
		||||
 | 
			
		||||
    if (!accurate) {
 | 
			
		||||
      k = 1 / Math.cos(latlon[0] * rad);
 | 
			
		||||
      k = 1 / Math.cos(latlon.lat * rad);
 | 
			
		||||
 | 
			
		||||
      // [scaleX, scaleY]
 | 
			
		||||
      return [k, k];
 | 
			
		||||
    } else {
 | 
			
		||||
      var lat = latlon[0] * rad;
 | 
			
		||||
      var lon = latlon[1] * rad;
 | 
			
		||||
      var lat = latlon.lat * rad;
 | 
			
		||||
      var lon = latlon.lon * rad;
 | 
			
		||||
 | 
			
		||||
      var a = this.R;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,8 @@
 | 
			
		|||
 * https://github.com/Leaflet/Leaflet/blob/master/src/geometry/Transformation.js
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import Point from '../geo/Point';
 | 
			
		||||
 | 
			
		||||
class Transformation {
 | 
			
		||||
  constructor(a, b, c, d) {
 | 
			
		||||
    this._a = a;
 | 
			
		||||
| 
						 | 
				
			
			@ -16,24 +18,24 @@ class Transformation {
 | 
			
		|||
 | 
			
		||||
  transform(point, scale) {
 | 
			
		||||
    // Copy input point as to not destroy the original data
 | 
			
		||||
    return this._transform([point[0], point[1]], scale);
 | 
			
		||||
    return this._transform(point.clone(), scale);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Destructive transform (faster)
 | 
			
		||||
  _transform(point, scale) {
 | 
			
		||||
    scale = scale || 1;
 | 
			
		||||
 | 
			
		||||
    point[0] = scale * (this._a * point[0] + this._b);
 | 
			
		||||
    point[1] = scale * (this._c * point[1] + this._d);
 | 
			
		||||
    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[0] / scale - this._b) / this._a,
 | 
			
		||||
      (point[1] / scale - this._d) / this._c
 | 
			
		||||
    ];
 | 
			
		||||
    return Point(
 | 
			
		||||
      (point.x / scale - this._b) / this._a,
 | 
			
		||||
      (point.y / scale - this._d) / this._c
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
import World from './World';
 | 
			
		||||
import Controls from './controls/index';
 | 
			
		||||
import EnvironmentLayer from './layer/environment/EnvironmentLayer';
 | 
			
		||||
import Point from './geo/Point';
 | 
			
		||||
import LatLon from './geo/LatLon';
 | 
			
		||||
 | 
			
		||||
const VIZI = {
 | 
			
		||||
  version: '0.3',
 | 
			
		||||
| 
						 | 
				
			
			@ -8,7 +10,9 @@ const VIZI = {
 | 
			
		|||
  // Public API
 | 
			
		||||
  World: World,
 | 
			
		||||
  Controls: Controls,
 | 
			
		||||
  EnvironmentLayer: EnvironmentLayer
 | 
			
		||||
  EnvironmentLayer: EnvironmentLayer,
 | 
			
		||||
  Point: Point,
 | 
			
		||||
  LatLon: LatLon
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default VIZI;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										352
									
								
								test/unit/CRS.js
								
								
								
								
							
							
						
						
									
										352
									
								
								test/unit/CRS.js
								
								
								
								
							| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
import extend from 'lodash.assign';
 | 
			
		||||
import CRS from '../../src/geo/crs/index';
 | 
			
		||||
import LatLon from '../../src/geo/LatLon';
 | 
			
		||||
import Point from '../../src/geo/Point';
 | 
			
		||||
 | 
			
		||||
describe('CRS.EPSG3857', () => {
 | 
			
		||||
  var crs = CRS.EPSG3857;
 | 
			
		||||
| 
						 | 
				
			
			@ -12,123 +14,123 @@ describe('CRS.EPSG3857', () => {
 | 
			
		|||
 | 
			
		||||
  describe('#latLonToPoint', () => {
 | 
			
		||||
    it('projects the center', () => {
 | 
			
		||||
      var point = crs.latLonToPoint([0, 0]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([85.0511287798, -180]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(85.0511287798, -180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(-scaleFactor, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(-scaleFactor, 0.01);
 | 
			
		||||
      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([-85.0511287798, 180]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(-85.0511287798, 180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(scaleFactor, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(scaleFactor, 0.01);
 | 
			
		||||
      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([-85.0511287798, 180], 1);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(-85.0511287798, 180), 1);
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(256, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(256, 0.01);
 | 
			
		||||
      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([0, 0]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([-scaleFactor, -scaleFactor]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(-scaleFactor, -scaleFactor));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(85.0511287798, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(-180, 0.01);
 | 
			
		||||
      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([scaleFactor, scaleFactor]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(scaleFactor, scaleFactor));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(-85.0511287798, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(180, 0.01);
 | 
			
		||||
      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([256, 256], 1);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(256, 256), 1);
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(-85.0511287798, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(180, 0.01);
 | 
			
		||||
      expect(latlon.lat).to.be.closeTo(-85.0511287798, 0.01);
 | 
			
		||||
      expect(latlon.lon).to.be.closeTo(180, 0.01);
 | 
			
		||||
 | 
			
		||||
      latlon = crs.pointToLatLon([0, 0], 1);
 | 
			
		||||
      latlon = crs.pointToLatLon(Point(0, 0), 1);
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([0, 0]);
 | 
			
		||||
      var point = crs.project(LatLon(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([85.0511287798, -180]);
 | 
			
		||||
      var point = crs.project(LatLon(85.0511287798, -180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(-20037508.34279, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(20037508.34278, 0.01);
 | 
			
		||||
      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([-85.0511287798, 180]);
 | 
			
		||||
      var point = crs.project(LatLon(-85.0511287798, 180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(20037508.34278, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(-20037508.34278, 0.01);
 | 
			
		||||
      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([-90, 180]);
 | 
			
		||||
      var point = crs.project(LatLon(-90, 180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(20037508.34278, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(-20037508.34278, 0.01);
 | 
			
		||||
      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([0, 0]);
 | 
			
		||||
      var latlon = crs.unproject(Point(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([-20037508.34278, 20037508.34278]);
 | 
			
		||||
      var latlon = crs.unproject(Point(-20037508.34278, 20037508.34278));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(85.0511287798, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(-180, 0.01);
 | 
			
		||||
      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([20037508.34278, -20037508.34278]);
 | 
			
		||||
      var latlon = crs.unproject(Point(20037508.34278, -20037508.34278));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(-85.0511287798, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(180, 0.01);
 | 
			
		||||
      expect(latlon.lat).to.be.closeTo(-85.0511287798, 0.01);
 | 
			
		||||
      expect(latlon.lon).to.be.closeTo(180, 0.01);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -158,43 +160,43 @@ describe('CRS.EPSG3857', () => {
 | 
			
		|||
      var scaleFactor2 = crs.scaleFactor * 2;
 | 
			
		||||
      var bounds = crs.getProjectedBounds();
 | 
			
		||||
 | 
			
		||||
      expect(Math.abs(bounds[1][0] - bounds[0][0])).to.be.closeTo(scaleFactor2, 0.1);
 | 
			
		||||
      expect(Math.abs(bounds[1][1] - bounds[0][1])).to.be.closeTo(scaleFactor2, 0.1);
 | 
			
		||||
      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][0] - bounds[0][0])).to.be.closeTo(512, 0.1);
 | 
			
		||||
      expect(Math.abs(bounds[1][1] - bounds[0][1])).to.be.closeTo(512, 0.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([0, 190])[1]).to.equal(-170);
 | 
			
		||||
      expect(crs.wrapLatLon([0, 360])[1]).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([0, -190])[1]).to.equal(170);
 | 
			
		||||
      expect(crs.wrapLatLon([0, -360])[1]).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([0, 0])[1]).to.equal(0);
 | 
			
		||||
      expect(crs.wrapLatLon([0, 180])[1]).to.equal(180);
 | 
			
		||||
      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([0, 190, 100])[1]).to.equal(-170);
 | 
			
		||||
      expect(crs.wrapLatLon([0, 190, 100])[2]).to.equal(100);
 | 
			
		||||
      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([0, 0], [0.001, 0])).to.be.closeTo(111.31949492321543, 0.1);
 | 
			
		||||
      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([0, 0], [0.001, 0], true)).to.be.closeTo(111.3194907932736, 0.1);
 | 
			
		||||
      expect(crs.distance(LatLon(0, 0), LatLon(0.001, 0), true)).to.be.closeTo(111.3194907932736, 0.1);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -202,24 +204,24 @@ describe('CRS.EPSG3857', () => {
 | 
			
		|||
    var pointScale;
 | 
			
		||||
 | 
			
		||||
    it('returns approximate point scale factor', () => {
 | 
			
		||||
      pointScale = crs.pointScale([0, 0]);
 | 
			
		||||
      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([60, 0]);
 | 
			
		||||
      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([0, 0], true);
 | 
			
		||||
      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([60, 0], true);
 | 
			
		||||
      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);
 | 
			
		||||
| 
						 | 
				
			
			@ -230,10 +232,10 @@ describe('CRS.EPSG3857', () => {
 | 
			
		|||
    var pointScale;
 | 
			
		||||
 | 
			
		||||
    it('returns correct projected units', () => {
 | 
			
		||||
      pointScale = crs.pointScale([0, 0]);
 | 
			
		||||
      pointScale = crs.pointScale(LatLon(0, 0));
 | 
			
		||||
      expect(crs.metresToProjected(1, pointScale)).to.be.closeTo(1, 0.1);
 | 
			
		||||
 | 
			
		||||
      pointScale = crs.pointScale([60, 0]);
 | 
			
		||||
      pointScale = crs.pointScale(LatLon(60, 0));
 | 
			
		||||
      expect(crs.metresToProjected(1, pointScale)).to.be.closeTo(1.9999999999999996, 0.1);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			@ -242,10 +244,10 @@ describe('CRS.EPSG3857', () => {
 | 
			
		|||
    var pointScale;
 | 
			
		||||
 | 
			
		||||
    it('returns correct real metres', () => {
 | 
			
		||||
      pointScale = crs.pointScale([0, 0]);
 | 
			
		||||
      pointScale = crs.pointScale(LatLon(0, 0));
 | 
			
		||||
      expect(crs.projectedToMetres(1, pointScale)).to.be.closeTo(1, 0.1);
 | 
			
		||||
 | 
			
		||||
      pointScale = crs.pointScale([60, 0]);
 | 
			
		||||
      pointScale = crs.pointScale(LatLon(60, 0));
 | 
			
		||||
      expect(crs.projectedToMetres(1.9999999999999996, pointScale)).to.be.closeTo(1, 0.1);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			@ -258,13 +260,13 @@ describe('CRS.EPSG3857', () => {
 | 
			
		|||
    var metres;
 | 
			
		||||
 | 
			
		||||
    it('returns correct world units', () => {
 | 
			
		||||
      pointScale = crs.pointScale([0, 0]);
 | 
			
		||||
      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([60, 0]);
 | 
			
		||||
      pointScale = crs.pointScale(LatLon(60, 0));
 | 
			
		||||
      worldUnits = crs.metresToWorld(1, pointScale);
 | 
			
		||||
      metres = crs.worldToMetres(worldUnits, pointScale);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -272,24 +274,24 @@ describe('CRS.EPSG3857', () => {
 | 
			
		|||
    });
 | 
			
		||||
 | 
			
		||||
    it('returns correct world units using zoom', () => {
 | 
			
		||||
      pointScale = crs.pointScale([0, 0]);
 | 
			
		||||
      pointScale = crs.pointScale(LatLon(0, 0));
 | 
			
		||||
      worldUnits = crs.metresToWorld(40075016.68556, pointScale, 1);
 | 
			
		||||
 | 
			
		||||
      expect(worldUnits).to.be.closeTo(512, 0.1);
 | 
			
		||||
 | 
			
		||||
      pointScale = crs.pointScale([60, 0]);
 | 
			
		||||
      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([0, 0]);
 | 
			
		||||
      pointScale = crs.pointScale(LatLon(0, 0));
 | 
			
		||||
      worldUnits = crs.worldToMetres(512, pointScale, 1);
 | 
			
		||||
 | 
			
		||||
      expect(worldUnits).to.be.closeTo(40075016.68556, 0.1);
 | 
			
		||||
 | 
			
		||||
      pointScale = crs.pointScale([60, 0]);
 | 
			
		||||
      pointScale = crs.pointScale(LatLon(60, 0));
 | 
			
		||||
      worldUnits = crs.worldToMetres(512, pointScale, 1);
 | 
			
		||||
 | 
			
		||||
      expect(worldUnits).to.be.closeTo(40075016.68556, 0.1);
 | 
			
		||||
| 
						 | 
				
			
			@ -321,70 +323,70 @@ describe('CRS.3395', () => {
 | 
			
		|||
 | 
			
		||||
  describe('#latLonToPoint', () => {
 | 
			
		||||
    it('projects the center', () => {
 | 
			
		||||
      var point = crs.latLonToPoint([0, 0]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([85.0840591556, -180]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(85.0840591556, -180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(-scaleFactor, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(-scaleFactor, 0.01);
 | 
			
		||||
      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([-85.0840591556, 180]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(-85.0840591556, 180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(scaleFactor, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(scaleFactor, 0.01);
 | 
			
		||||
      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([-85.0840591556, 180], 1);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(-85.0840591556, 180), 1);
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(256, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(256, 0.01);
 | 
			
		||||
      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([0, 0]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([-scaleFactor, -scaleFactor]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(-scaleFactor, -scaleFactor));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(85.0840591556, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(-180, 0.01);
 | 
			
		||||
      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([scaleFactor, scaleFactor]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(scaleFactor, scaleFactor));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(-85.0840591556, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(180, 0.01);
 | 
			
		||||
      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([256, 256], 1);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(256, 256), 1);
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(-85.0840591556, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(180, 0.01);
 | 
			
		||||
      expect(latlon.lat).to.be.closeTo(-85.0840591556, 0.01);
 | 
			
		||||
      expect(latlon.lon).to.be.closeTo(180, 0.01);
 | 
			
		||||
 | 
			
		||||
      latlon = crs.pointToLatLon([0, 0], 1);
 | 
			
		||||
      latlon = crs.pointToLatLon(Point(0, 0), 1);
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon.lat).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon.lon).to.be.closeTo(0, 0.01);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -402,76 +404,76 @@ describe('CRS.4326', () => {
 | 
			
		|||
 | 
			
		||||
  describe('#latLonToPoint', () => {
 | 
			
		||||
    it('projects the center', () => {
 | 
			
		||||
      var point = crs.latLonToPoint([0, 0]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([90, -180]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(90, -180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(-scaleFactor, 0.01);
 | 
			
		||||
      expect(point.x).to.be.closeTo(-scaleFactor, 0.01);
 | 
			
		||||
 | 
			
		||||
      // Half scale factor as projection is not square
 | 
			
		||||
      expect(point[1]).to.be.closeTo(-scaleFactor / 2, 0.01);
 | 
			
		||||
      expect(point.y).to.be.closeTo(-scaleFactor / 2, 0.01);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('projects the South-East corner', () => {
 | 
			
		||||
      var scaleFactor = crs.scaleFactor;
 | 
			
		||||
      var point = crs.latLonToPoint([-90, 180]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(-90, 180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(scaleFactor, 0.01);
 | 
			
		||||
      expect(point.x).to.be.closeTo(scaleFactor, 0.01);
 | 
			
		||||
 | 
			
		||||
      // Half scale factor as projection is not square
 | 
			
		||||
      expect(point[1]).to.be.closeTo(scaleFactor / 2, 0.01);
 | 
			
		||||
      expect(point.y).to.be.closeTo(scaleFactor / 2, 0.01);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('projects using pixels if zoom is given', () => {
 | 
			
		||||
      var point = crs.latLonToPoint([-90, 180], 1);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(-90, 180), 1);
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(256, 0.01);
 | 
			
		||||
      expect(point.x).to.be.closeTo(256, 0.01);
 | 
			
		||||
 | 
			
		||||
      // Half width as projection is not square
 | 
			
		||||
      expect(point[1]).to.be.closeTo(128, 0.01);
 | 
			
		||||
      expect(point.y).to.be.closeTo(128, 0.01);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('#pointToLatLon', () => {
 | 
			
		||||
    it('unprojects the center', () => {
 | 
			
		||||
      var latlon = crs.pointToLatLon([0, 0]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([-scaleFactor, -scaleFactor / 2]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(-scaleFactor, -scaleFactor / 2));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(90, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(-180, 0.01);
 | 
			
		||||
      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([scaleFactor, scaleFactor / 2]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(scaleFactor, scaleFactor / 2));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(-90, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(180, 0.01);
 | 
			
		||||
      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([256, 128], 1);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(256, 128), 1);
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(-90, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(180, 0.01);
 | 
			
		||||
      expect(latlon.lat).to.be.closeTo(-90, 0.01);
 | 
			
		||||
      expect(latlon.lon).to.be.closeTo(180, 0.01);
 | 
			
		||||
 | 
			
		||||
      latlon = crs.pointToLatLon([0, 0], 1);
 | 
			
		||||
      latlon = crs.pointToLatLon(Point(0, 0), 1);
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon.lat).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon.lon).to.be.closeTo(0, 0.01);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -483,62 +485,62 @@ describe('CRS.Simple', () => {
 | 
			
		|||
 | 
			
		||||
  describe('#latLonToPoint', () => {
 | 
			
		||||
    it('projects the center', () => {
 | 
			
		||||
      var point = crs.latLonToPoint([0, 0]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([-500, -500]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(-500, -500));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(-500, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(-500, 0.01);
 | 
			
		||||
      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([500, 500]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(500, 500));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(500, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(500, 0.01);
 | 
			
		||||
      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([0, 0]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([-500, -500]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(-500, -500));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(-500, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(-500, 0.01);
 | 
			
		||||
      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([500, 500]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(500, 500));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(500, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(500, 0.01);
 | 
			
		||||
      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([0, 190])[1]).to.equal(190);
 | 
			
		||||
      expect(crs.wrapLatLon([0, 360])[1]).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([0, -190])[1]).to.equal(-190);
 | 
			
		||||
      expect(crs.wrapLatLon([0, -360])[1]).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([0, 0])[1]).to.equal(0);
 | 
			
		||||
      expect(crs.wrapLatLon([0, 180])[1]).to.equal(180);
 | 
			
		||||
      expect(crs.wrapLatLon(LatLon(0, 0)).lon).to.equal(0);
 | 
			
		||||
      expect(crs.wrapLatLon(LatLon(0, 180)).lon).to.equal(180);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('wraps if defined', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -547,19 +549,19 @@ describe('CRS.Simple', () => {
 | 
			
		|||
        wrapLon: [-180, 180],
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      expect(crs.wrapLatLon([0, 190])[1]).to.equal(-170);
 | 
			
		||||
      expect(crs.wrapLatLon([0, 360])[1]).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([100, 0])[0]).to.equal(-80);
 | 
			
		||||
      expect(crs.wrapLatLon([180, 0])[0]).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([0, 0], [100, 0])).to.be.closeTo(100, 0.1);
 | 
			
		||||
      expect(crs.distance([0, 0], [0, 100])).to.be.closeTo(100, 0.1);
 | 
			
		||||
      expect(crs.distance([0, 0], [100, 100])).to.be.closeTo(141.4213562373095, 0.1);
 | 
			
		||||
      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);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -578,35 +580,35 @@ describe('CRS.Proj4', () => {
 | 
			
		|||
 | 
			
		||||
  describe('#latLonToPoint', () => {
 | 
			
		||||
    it('projects the center', () => {
 | 
			
		||||
      var point = crs.latLonToPoint([55.46347028885475, -4.186594751907175]);
 | 
			
		||||
      var point = crs.latLonToPoint(LatLon(55.46347028885475, -4.186594751907175));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([60.6596573635804, -10.8865578798635]);
 | 
			
		||||
      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[1]).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([49.9699671340061, 0.904406143400599]);
 | 
			
		||||
      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[1]).to.be.closeTo(scaleFactor, 0.01);
 | 
			
		||||
      expect(point.y).to.be.closeTo(scaleFactor, 0.01);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('#pointToLatLon', () => {
 | 
			
		||||
    it('unprojects the center', () => {
 | 
			
		||||
      var latlon = crs.pointToLatLon([0, 0]);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(55.46347028885475, 0.1);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(-4.186594751907175, 0.1);
 | 
			
		||||
      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', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -615,8 +617,8 @@ describe('CRS.Proj4', () => {
 | 
			
		|||
      // 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([0, -scaleFactor]);
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(60.6596573635804, 1);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(0, -scaleFactor));
 | 
			
		||||
      expect(latlon.lat).to.be.closeTo(60.6596573635804, 1);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('unprojects the South edge', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -625,8 +627,8 @@ describe('CRS.Proj4', () => {
 | 
			
		|||
      // 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([0, scaleFactor]);
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(49.9699671340061, 1);
 | 
			
		||||
      var latlon = crs.pointToLatLon(Point(0, scaleFactor));
 | 
			
		||||
      expect(latlon.lat).to.be.closeTo(49.9699671340061, 1);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,58 +1,60 @@
 | 
			
		|||
import Projection from '../../src/geo/projection/index';
 | 
			
		||||
import LatLon from '../../src/geo/LatLon';
 | 
			
		||||
import Point from '../../src/geo/Point';
 | 
			
		||||
 | 
			
		||||
describe('Projection.SphericalMercator', () => {
 | 
			
		||||
  var projection = Projection.SphericalMercator;
 | 
			
		||||
 | 
			
		||||
  describe('#project', () => {
 | 
			
		||||
    it('projects the center', () => {
 | 
			
		||||
      var point = projection.project([0, 0]);
 | 
			
		||||
      var point = projection.project(LatLon(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([85.0511287798, -180]);
 | 
			
		||||
      var point = projection.project(LatLon(85.0511287798, -180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(-20037508.34279, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(20037508.34278, 0.01);
 | 
			
		||||
      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([-85.0511287798, 180]);
 | 
			
		||||
      var point = projection.project(LatLon(-85.0511287798, 180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(20037508.34278, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(-20037508.34278, 0.01);
 | 
			
		||||
      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([-90, 180]);
 | 
			
		||||
      var point = projection.project(LatLon(-90, 180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(20037508.34278, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(-20037508.34278, 0.01);
 | 
			
		||||
      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([0, 0]);
 | 
			
		||||
      var latlon = projection.unproject(Point(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([-20037508.34278, 20037508.34278]);
 | 
			
		||||
      var latlon = projection.unproject(Point(-20037508.34278, 20037508.34278));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(85.0511287798, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(-180, 0.01);
 | 
			
		||||
      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([20037508.34278, -20037508.34278]);
 | 
			
		||||
      var latlon = projection.unproject(Point(20037508.34278, -20037508.34278));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(-85.0511287798, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(180, 0.01);
 | 
			
		||||
      expect(latlon.lat).to.be.closeTo(-85.0511287798, 0.01);
 | 
			
		||||
      expect(latlon.lon).to.be.closeTo(180, 0.01);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -60,24 +62,24 @@ describe('Projection.SphericalMercator', () => {
 | 
			
		|||
    var pointScale;
 | 
			
		||||
 | 
			
		||||
    it('returns approximate point scale factor', () => {
 | 
			
		||||
      pointScale = projection.pointScale([0, 0]);
 | 
			
		||||
      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([60, 0]);
 | 
			
		||||
      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([0, 0], true);
 | 
			
		||||
      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([60, 0], true);
 | 
			
		||||
      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);
 | 
			
		||||
| 
						 | 
				
			
			@ -100,47 +102,47 @@ describe('Projection.Mercator', () => {
 | 
			
		|||
 | 
			
		||||
  describe('#project', () => {
 | 
			
		||||
    it('projects the center', () => {
 | 
			
		||||
      var point = projection.project([0, 0]);
 | 
			
		||||
      var point = projection.project(LatLon(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([85.0840591556, -180]);
 | 
			
		||||
      var point = projection.project(LatLon(85.0840591556, -180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(-20037508.34279, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(20037508.4798169, 0.01);
 | 
			
		||||
      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([-85.0840591556, 180]);
 | 
			
		||||
      var point = projection.project(LatLon(-85.0840591556, 180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(20037508.34279, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(-20037508.4798169, 0.01);
 | 
			
		||||
      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([0, 0]);
 | 
			
		||||
      var latlon = projection.unproject(Point(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([-20037508.34279, 20037508.4798169]);
 | 
			
		||||
      var latlon = projection.unproject(Point(-20037508.34279, 20037508.4798169));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(85.0840591556, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(-180, 0.01);
 | 
			
		||||
      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([20037508.34279, -20037508.4798169]);
 | 
			
		||||
      var latlon = projection.unproject(Point(20037508.34279, -20037508.4798169));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(-85.0840591556, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(180, 0.01);
 | 
			
		||||
      expect(latlon.lat).to.be.closeTo(-85.0840591556, 0.01);
 | 
			
		||||
      expect(latlon.lon).to.be.closeTo(180, 0.01);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -148,12 +150,12 @@ describe('Projection.Mercator', () => {
 | 
			
		|||
    var pointScale;
 | 
			
		||||
 | 
			
		||||
    it('returns point scale factor', () => {
 | 
			
		||||
      pointScale = projection.pointScale([0, 0]);
 | 
			
		||||
      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([60, 0]);
 | 
			
		||||
      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);
 | 
			
		||||
| 
						 | 
				
			
			@ -176,47 +178,47 @@ describe('Projection.LatLon', () => {
 | 
			
		|||
 | 
			
		||||
  describe('#project', () => {
 | 
			
		||||
    it('projects the center', () => {
 | 
			
		||||
      var point = projection.project([0, 0]);
 | 
			
		||||
      var point = projection.project(LatLon(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([90, -180]);
 | 
			
		||||
      var point = projection.project(LatLon(90, -180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(-180, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(90, 0.01);
 | 
			
		||||
      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([-90, 180]);
 | 
			
		||||
      var point = projection.project(LatLon(-90, 180));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(180, 0.01);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(-90, 0.01);
 | 
			
		||||
      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([0, 0]);
 | 
			
		||||
      var latlon = projection.unproject(Point(0, 0));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(0, 0.01);
 | 
			
		||||
      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([-180, 90]);
 | 
			
		||||
      var latlon = projection.unproject(Point(-180, 90));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(90, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(-180, 0.01);
 | 
			
		||||
      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([180, -90]);
 | 
			
		||||
      var latlon = projection.unproject(Point(180, -90));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(-90, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(180, 0.01);
 | 
			
		||||
      expect(latlon.lat).to.be.closeTo(-90, 0.01);
 | 
			
		||||
      expect(latlon.lon).to.be.closeTo(180, 0.01);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -224,12 +226,12 @@ describe('Projection.LatLon', () => {
 | 
			
		|||
    var pointScale;
 | 
			
		||||
 | 
			
		||||
    it('returns point scale factor', () => {
 | 
			
		||||
      pointScale = projection.pointScale([0, 0]);
 | 
			
		||||
      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([60, 0]);
 | 
			
		||||
      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);
 | 
			
		||||
| 
						 | 
				
			
			@ -253,47 +255,47 @@ describe('Projection.Proj4', () => {
 | 
			
		|||
 | 
			
		||||
  describe('#project', () => {
 | 
			
		||||
    it('projects the center', () => {
 | 
			
		||||
      var point = projection.project([55.46347028885475, -4.186594751907175]);
 | 
			
		||||
      var point = projection.project(LatLon(55.46347028885475, -4.186594751907175));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(261849.77, 0.1);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(621021.635, 0.1);
 | 
			
		||||
      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([60.6596573635804, -10.8865578798635]);
 | 
			
		||||
      var point = projection.project(LatLon(60.6596573635804, -10.8865578798635));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(-84667.14, 0.1);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(1230247.30, 0.1);
 | 
			
		||||
      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([49.9699671340061, 0.904406143400599]);
 | 
			
		||||
      var point = projection.project(LatLon(49.9699671340061, 0.904406143400599));
 | 
			
		||||
 | 
			
		||||
      expect(point[0]).to.be.closeTo(608366.68, 0.1);
 | 
			
		||||
      expect(point[1]).to.be.closeTo(11795.97, 0.1);
 | 
			
		||||
      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([261849.77, 621021.635]);
 | 
			
		||||
      var latlon = projection.unproject(Point(261849.77, 621021.635));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(55.46347028885475, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(-4.186594751907175, 0.01);
 | 
			
		||||
      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([-84667.14, 1230247.30]);
 | 
			
		||||
      var latlon = projection.unproject(Point(-84667.14, 1230247.30));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(60.6596573635804, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(-10.8865578798635, 0.01);
 | 
			
		||||
      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([608366.68, 11795.97]);
 | 
			
		||||
      var latlon = projection.unproject(Point(608366.68, 11795.97));
 | 
			
		||||
 | 
			
		||||
      expect(latlon[0]).to.be.closeTo(49.9699671340061, 0.01);
 | 
			
		||||
      expect(latlon[1]).to.be.closeTo(0.904406143400599, 0.01);
 | 
			
		||||
      expect(latlon.lat).to.be.closeTo(49.9699671340061, 0.01);
 | 
			
		||||
      expect(latlon.lon).to.be.closeTo(0.904406143400599, 0.01);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -301,12 +303,12 @@ describe('Projection.Proj4', () => {
 | 
			
		|||
    var pointScale;
 | 
			
		||||
 | 
			
		||||
    it('returns point scale factor', () => {
 | 
			
		||||
      pointScale = projection.pointScale([0, 0]);
 | 
			
		||||
      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([60, 0]);
 | 
			
		||||
      pointScale = projection.pointScale(LatLon(60, 0));
 | 
			
		||||
 | 
			
		||||
      expect(pointScale[0]).to.be.closeTo(1, 0.1);
 | 
			
		||||
      expect(pointScale[1]).to.be.closeTo(1, 0.1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
import Transformation from '../../src/util/Transformation';
 | 
			
		||||
import Point from '../../src/geo/Point';
 | 
			
		||||
 | 
			
		||||
describe('Transformation', () => {
 | 
			
		||||
  var transformation;
 | 
			
		||||
| 
						 | 
				
			
			@ -12,19 +13,19 @@ describe('Transformation', () => {
 | 
			
		|||
    spy(transformation, 'transform');
 | 
			
		||||
    spy(transformation, 'untransform');
 | 
			
		||||
 | 
			
		||||
    point = [5, 5];
 | 
			
		||||
    point = Point(5, 5);
 | 
			
		||||
    scale = 2;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe('#transform', () => {
 | 
			
		||||
    it('can transform', () => {
 | 
			
		||||
      var point2 = transformation.transform(point, scale);
 | 
			
		||||
      expect(transformation.transform).to.have.returned([11, 11]);
 | 
			
		||||
      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([5.5, 5.5]);
 | 
			
		||||
      expect(transformation.transform).to.have.returned(Point(5.5, 5.5));
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue