WebWorldWind/test/geom/Location.test.js
2020-08-12 17:28:51 -05:00

702 lines
26 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright 2003-2006, 2009, 2017, 2020 United States Government, as represented
* by the Administrator of the National Aeronautics and Space Administration.
* All rights reserved.
*
* The NASAWorldWind/WebWorldWind platform is licensed under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License
* at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* NASAWorldWind/WebWorldWind also contains the following 3rd party Open Source
* software:
*
* ES6-Promise under MIT License
* libtess.js SGI Free Software License B
* Proj4 under MIT License
* JSZip under MIT License
*
* A complete listing of 3rd Party software notices and licenses included in
* WebWorldWind can be found in the WebWorldWind 3rd-party notices and licenses
* PDF found in code directory.
*/
define([
'src/geom/Location',
'src/geom/Angle',
'src/globe/EarthElevationModel',
'src/globe/ElevationModel',
'src/globe/Globe'
], function (Location, Angle, EarthElevationModel, ElevationModel, Globe) {
"use strict";
describe("Location Tests", function () {
it("Should construct a location", function () {
var location = new Location(37.52, 15.08);
expect(location.latitude).toEqual(37.52);
expect(location.longitude).toEqual(15.08);
});
it("Should create a location initialized at (0,0)", function () {
var locationZero = Location.ZERO;
expect(locationZero.latitude).toEqual(0);
expect(locationZero.longitude).toEqual(0);
});
it("Should create a location from radians coordinates", function () {
var radiansLatitude = 37.52 / Angle.RADIANS_TO_DEGREES;
var radiansLongitude = 15.08 / Angle.RADIANS_TO_DEGREES;
var location = Location.fromRadians(radiansLatitude, radiansLongitude);
expect(location.latitude).toBeCloseTo(37.52);
expect(location.longitude).toBeCloseTo(15.08);
});
describe("Copies this location to the latitude and longitude of a specified location", function () {
it("Copies the location successfully", function () {
var location = new Location(0, 0);
var locationTarget = new Location(37.52, 15.08);
location.copy(locationTarget);
expect(location.latitude).toEqual(37.52);
expect(location.longitude).toEqual(15.08);
});
it("Should throw an exception on missing location input", function () {
expect(function () {
var location = new Location(0, 0);
location.copy(null);
}).toThrow();
});
});
it('Sets latitude and longitude of a location', function () {
var location = new Location(0, 0);
location.set(37.52, 15.08);
expect(location.latitude).toEqual(37.52);
expect(location.longitude).toEqual(15.08);
});
describe('Checks if two locations are equal', function () {
it('Equal locations', function () {
var locationA = new Location(37.52, 15.08);
var locationB = new Location(37.52, 15.08);
expect(locationA.equals(locationB)).toBe(true);
});
it('Different locations', function () {
var locationA = new Location(37.52, 15.08);
var locationB = new Location(37, 18);
expect(locationA.equals(locationB)).toBe(false);
});
});
describe('Computes a location along a path', function () {
var locationA = new Location(37.52, 15.00);
var locationB = new Location(45.48, 9.09);
it('Compute with Great Circle', function () {
var resultLocation = Location.interpolateAlongPath(
WorldWind.GREAT_CIRCLE,
0.5,
locationA,
locationB,
new Location());
expect(resultLocation.latitude).toBeCloseTo(41.537, 2);
expect(resultLocation.longitude).toBeCloseTo(12.227, 2);
});
it('Compute with Rhumb Line', function () {
var resultLocation = Location.interpolateAlongPath(
WorldWind.RHUMB_LINE,
0.5,
locationA,
locationB,
new Location());
expect(resultLocation.latitude).toBeCloseTo(41.5, 2);
expect(resultLocation.longitude).toBeCloseTo(12.135, 2);
});
it('Compute with Linear', function () {
var resultLocation = Location.interpolateAlongPath(
WorldWind.LINEAR,
0.5,
locationA,
locationB,
new Location());
expect(resultLocation.latitude).toBeCloseTo(41.5, 2);
expect(resultLocation.longitude).toBeCloseTo(12.044, 2);
});
it('Compute with Linear with fraction greater than 1', function () {
var resultLocation = Location.interpolateAlongPath(
WorldWind.LINEAR,
4.5,
locationA,
locationB,
new Location());
expect(resultLocation.latitude).toBeCloseTo(45.48, 2);
expect(resultLocation.longitude).toBeCloseTo(9.089, 2);
});
it('Compute with Linear with not recognized path', function () {
var resultLocation = Location.interpolateAlongPath(
null,
0.5,
locationA,
locationB,
new Location());
expect(resultLocation.latitude).toBeCloseTo(41.5, 2);
expect(resultLocation.longitude).toBeCloseTo(12.044, 2);
});
it('Store result in the provided variable', function () {
var resultLocation = new Location(0, 0);
Location.interpolateAlongPath(
WorldWind.LINEAR,
0.5,
locationA,
locationB,
resultLocation);
expect(resultLocation.latitude).toBeCloseTo(41.5, 2);
expect(resultLocation.longitude).toBeCloseTo(12.044, 2);
});
describe('Exceptions', function () {
it('Location A not provided', function () {
expect(function () {
Location.interpolateAlongPath(
WorldWind.LINEAR,
0.5,
null,
locationB,
new Location());
}).toThrow();
});
it('Location B not provided', function () {
expect(function () {
Location.interpolateAlongPath(
WorldWind.LINEAR,
0.5,
locationA,
null,
new Location());
}).toThrow();
});
it('Result storage not provided', function () {
expect(function () {
Location.interpolateAlongPath(
WorldWind.LINEAR,
0.5,
locationA,
locationB,
null);
}).toThrow();
});
});
});
describe('Computes a location along a great circle path', function () {
var locationA = new Location(37.52, 15.00);
var locationB = new Location(45.48, 9.09);
it('Compute with Great Circle', function () {
var resultLocation = Location.interpolateGreatCircle(
0.5,
locationA,
locationB,
new Location());
expect(resultLocation.latitude).toBeCloseTo(41.537, 2);
expect(resultLocation.longitude).toBeCloseTo(12.227, 2);
});
it('Equal locations', function () {
var resultLocation = Location.interpolateGreatCircle(
0.5,
locationA,
locationA,
new Location());
expect(resultLocation).toEqual(locationA);
});
describe('Exceptions', function () {
it('Location A not provided', function () {
expect(function () {
Location.interpolateGreatCircle(
0.5,
null,
locationB,
new Location());
}).toThrow();
});
it('Location B not provided', function () {
expect(function () {
Location.interpolateGreatCircle(
0.5,
locationA,
null,
new Location());
}).toThrow();
});
it('Result storage not provided', function () {
expect(function () {
Location.interpolateGreatCircle(
0.5,
locationA,
locationB,
null);
}).toThrow();
});
});
});
describe('Computes a location along a rhumb path', function () {
var locationA = new Location(37.52, 15.00);
var locationB = new Location(45.48, 9.09);
it('Compute with rhumb path', function () {
var resultLocation = Location.interpolateRhumb(
0.5,
locationA,
locationB,
new Location());
expect(resultLocation.latitude).toBeCloseTo(41.5, 2);
expect(resultLocation.longitude).toBeCloseTo(12.135, 2);
});
it('Equal locations', function () {
var resultLocation = Location.interpolateRhumb(
0.5,
locationA,
locationA,
new Location());
expect(resultLocation).toEqual(locationA);
});
describe('Exceptions', function () {
it('Location A not provided', function () {
expect(function () {
Location.interpolateRhumb(
0.5,
null,
locationB,
new Location());
}).toThrow();
});
it('Location B not provided', function () {
expect(function () {
Location.interpolateRhumb(
0.5,
locationA,
null,
new Location());
}).toThrow();
});
it('Result storage not provided', function () {
expect(function () {
Location.interpolateRhumb(
0.5,
locationA,
locationB,
null);
}).toThrow();
});
});
});
describe('Computes a location along a linear path', function () {
var locationA = new Location(37.52, 15.00);
var locationB = new Location(45.48, 9.09);
it('Compute with linear path', function () {
var resultLocation = Location.interpolateLinear(
0.5,
locationA,
locationB,
new Location());
expect(resultLocation.latitude).toBeCloseTo(41.5, 2);
expect(resultLocation.longitude).toBeCloseTo(12.044, 2);
});
it('Equal locations', function () {
var resultLocation = Location.interpolateLinear(
0.5,
locationA,
locationA,
new Location());
expect(resultLocation).toEqual(locationA);
});
describe('Exceptions', function () {
it('Location A not provided', function () {
expect(function () {
Location.interpolateLinear(
0.5,
null,
locationB,
new Location());
}).toThrow();
});
it('Location B not provided', function () {
expect(function () {
Location.interpolateLinear(
0.5,
locationA,
null,
new Location());
}).toThrow();
});
it('Result storage not provided', function () {
expect(function () {
Location.interpolateLinear(
0.5,
locationA,
locationB,
null);
}).toThrow();
});
});
});
describe('Computes the great circle angle pointing from the first to the second location', function () {
var locationA = new Location(37.52, 15.00);
var locationB = new Location(45.48, 9.09);
it('Compute the angle', function () {
var resultAngle = Location.greatCircleAzimuth(
locationA,
locationB);
expect(resultAngle).toBeCloseTo(-27.154, 2);
});
it('Compute the angle with equal locations', function () {
var resultAngle = Location.greatCircleAzimuth(
locationA,
locationA);
expect(resultAngle).toEqual(0);
});
describe('Exceptions', function () {
it('Location A not provided', function () {
expect(function () {
Location.greatCircleAzimuth(
locationA,
null);
}).toThrow();
});
it('Location B not provided', function () {
expect(function () {
Location.greatCircleAzimuth(
null,
locationB);
}).toThrow();
});
});
});
describe('Computes the rhumb angle pointing from the first to the second location', function () {
var locationA = new Location(37.52, 15.00);
var locationB = new Location(45.48, 9.09);
it('Compute the angle', function () {
var resultAngle = Location.rhumbAzimuth(
locationA,
locationB);
expect(resultAngle).toBeCloseTo(-29.026, 2);
});
it('Compute the angle with equal locations', function () {
var resultAngle = Location.rhumbAzimuth(
locationA,
locationA);
expect(resultAngle).toEqual(0);
});
describe('Exceptions', function () {
it('Location A not provided', function () {
expect(function () {
Location.rhumbAzimuth(
locationA,
null);
}).toThrow();
});
it('Location B not provided', function () {
expect(function () {
Location.rhumbAzimuth(
null,
locationB);
}).toThrow();
});
});
});
describe('Computes the linear angle pointing from the first to the second location', function () {
var locationA = new Location(37.52, 15.00);
var locationB = new Location(45.48, 9.09);
it('Compute the angle', function () {
var resultAngle = Location.linearAzimuth(
locationA,
locationB);
expect(resultAngle).toBeCloseTo(-36.592, 2);
});
it('Compute the angle with equal locations', function () {
var resultAngle = Location.linearAzimuth(
locationA,
locationA);
expect(resultAngle).toEqual(0);
});
describe('Exceptions', function () {
it('Location A not provided', function () {
expect(function () {
Location.linearAzimuth(
locationA,
null);
}).toThrow();
});
it('Location B not provided', function () {
expect(function () {
Location.linearAzimuth(
null,
locationB);
}).toThrow();
});
});
});
describe('Computes the rhumb angular distance between two locations', function () {
var locationA = new Location(37.52, 15.00);
var locationB = new Location(45.48, 9.09);
it('Compute the distance', function () {
var resultDistance = Location.rhumbDistance(
locationA,
locationB);
expect(resultDistance).toBeCloseTo(0.158, 2);
});
it('Compute the distance with equal locations', function () {
var resultDistance = Location.rhumbDistance(
locationA,
locationA);
expect(resultDistance).toEqual(0);
});
describe('Exceptions', function () {
it('Location A not provided', function () {
expect(function () {
Location.rhumbDistance(
locationA,
null);
}).toThrow();
});
it('Location B not provided', function () {
expect(function () {
Location.rhumbDistance(
null,
locationB);
}).toThrow();
});
});
});
describe('Computes the linear angular distance between two locations', function () {
var locationA = new Location(37.52, 15.00);
var locationB = new Location(45.48, 9.09);
it('Compute the distance', function () {
var resultDistance = Location.linearDistance(
locationA,
locationB);
expect(resultDistance).toBeCloseTo(0.173, 2);
});
it('Compute the distance with equal locations', function () {
var resultDistance = Location.linearDistance(
locationA,
locationA);
expect(resultDistance).toEqual(0);
});
describe('Exceptions', function () {
it('Location A not provided', function () {
expect(function () {
Location.linearDistance(
locationA,
null);
}).toThrow();
});
it('Location B not provided', function () {
expect(function () {
Location.linearDistance(
null,
locationB);
}).toThrow();
});
});
});
describe('Determines whether a list of locations crosses the dateline', function () {
it('Locations cross the dateline', function () {
var locations = [new Location(29.94, 160.57), new Location(29.96, -151.66)];
var cross = Location.locationsCrossDateLine(locations);
expect(cross).toBe(true);
});
it('Locations do not cross the dateline', function () {
var locations = [new Location(37.52, 15.00), new Location(40, 18.00)];
var cross = Location.locationsCrossDateLine(locations);
expect(cross).toBe(false);
});
it('Locations not provided', function () {
expect(function () {
Location.locationsCrossDateLine(null);
}).toThrow();
});
});
describe('Great-Circle-Arc-Extreme-Latitude Locations', function () {
it('Returns extreme locations', function () {
var locations = [
new Location(37.00, 15.00),
new Location(47.00, 15.00),
new Location(47.00, 17.00),
new Location(55.00, 12.00),
new Location(55.00, 18.00),
];
var result = Location.greatCircleArcExtremeLocations(locations);
expect(result[0]).toEqual(new Location(37.00, 15.00));
expect(result[1]).toEqual(new Location(55.00, 12.00));
});
it('Locations not provided', function () {
expect(function () {
Location.greatCircleArcExtremeLocations(null);
}).toThrow();
});
});
describe('Great-Circle-Arc-Extreme-Latitude between two Locations', function () {
it('Returns extreme locations', function () {
var locationA = new Location(187.00, 65.00);
var locationB = new Location(145.00, 88.00);
var result = Location.greatCircleArcExtremeForTwoLocations(locationA, locationB);
expect(result[0].latitude).toBeCloseTo(-3.503, 2);
expect(result[0].longitude).toBeCloseTo(-113.306, 2);
expect(result[1]).toEqual(new Location(187.00, 65.00));
});
it('Locations not provided', function () {
expect(function () {
Location.greatCircleArcExtremeForTwoLocations(null);
}).toThrow();
});
});
describe('Great-Circle-Extreme-Locations Using Azimuth', function () {
it('Returns extreme locations', function () {
var location = new Location(37.52, 15.08);
var expectedLocations = [
new Location(-9.527, 70.736),
new Location(9.527, -109.263)
];
var result = Location.greatCircleExtremeLocationsUsingAzimuth(location, 120);
expect(result[0].latitude).toBeCloseTo(expectedLocations[0].latitude);
expect(result[0].longitude).toBeCloseTo(expectedLocations[0].longitude);
expect(result[1].latitude).toBeCloseTo(expectedLocations[1].latitude);
expect(result[1].longitude).toBeCloseTo(expectedLocations[1].longitude);
});
it('Locations not provided', function () {
expect(function () {
Location.greatCircleExtremeLocationsUsingAzimuth(null, 120);
}).toThrow();
});
});
describe('Determines where a line between two positions crosses a given meridian', function () {
it('Meridian intersected', function () {
var locationA = new Location(-120, 15.08);
var locationB = new Location(87.00, 25.12);
var globe = new Globe(new EarthElevationModel());
var intersection = Location.intersectionWithMeridian(locationA, locationB, 180, globe);
expect(intersection).toBeCloseTo(-54.824);
});
it('Meridian not intersected', function () {
var locationA = new Location(37.52, 15.08);
var locationB = new Location(87.00, 25.12);
var globe = new Globe(new EarthElevationModel());
var intersection = Location.intersectionWithMeridian(locationA, locationB, 180, globe);
expect(intersection).toEqual(null);
});
});
it("Checks location Poles", function () {
expect(Location.poles).toEqual({
'NONE': 0,
'NORTH': 1,
'SOUTH': 2
});
});
});
});