Skip to content

Commit

Permalink
Merge branch '4.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
dvdoug committed Jan 29, 2022
2 parents 95073cf + f3ff8a0 commit 8a522fb
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 5 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@
- Some internal simplifications and optimisations
- Supported PHP versions changed to `^8.0`

## [4.6.0] - 2021-10-22
Unless a major bug is found, this will be the last release in the v4.x series. The next feature release will be v5.0.
## [4.6.1] - 2022-01-29
Unless a major bug is found, this will be the last release in the v4.x series. All future releases will be v5.x.
This is because one of PHP8.1's [new deprecations](https://github.com/php/php-src/commit/afc4d67c8b4e02a985a4cd27b8e79b343eb3c0ad)
requires a significant non-backwards compatible change to address.

### Fixed
- Guard against divide by zero issues when calculating distance between two points

## [4.6.0] - 2021-10-22
### Changed
- Updates to data for Papua New Guinea, Ukraine and WGS84
- Some internal simplifications and optimisations
Expand Down
2 changes: 1 addition & 1 deletion license.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Software
--------

Copyright (C) 2020-2021 Doug Wright
Copyright (C) 2020-2022 Doug Wright

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
4 changes: 2 additions & 2 deletions src/Point.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ protected static function vincenty(GeographicValue $from, GeographicValue $to, E
$cosSigma = sin($U1) * sin($U2) + cos($U1) * cos($U2) * cos($lambda);
$sigma = atan2($sinSigma, $cosSigma);

$sinAlpha = cos($U1) * cos($U2) * sin($lambda) / $sinSigma;
$sinAlpha = $sinSigma ? (cos($U1) * cos($U2) * sin($lambda) / $sinSigma) : 0;
$cosSqAlpha = (1 - $sinAlpha ** 2);
$cos2SigmaM = $cosSqAlpha ? $cosSigma - (2 * sin($U1) * sin($U2) / $cosSqAlpha) : 0;
$C = $f / 16 * $cosSqAlpha * (4 + $f * (4 - 3 * $cosSqAlpha));
Expand All @@ -178,7 +178,7 @@ protected static function vincenty(GeographicValue $from, GeographicValue $to, E
$sinAlphaN = $sinAlpha;

$C = $f / 16 * $cosSqAlpha * (4 + $f * (4 - 3 * $cosSqAlpha));
$cos2SigmaM = cos($sigma) - 2 * sin($U1) * sin($U2) / $cosSqAlpha;
$cos2SigmaM = $cosSqAlpha ? cos($sigma) - 2 * sin($U1) * sin($U2) / $cosSqAlpha : 0;
$D = (1 - $C) * $f * ($sigma + $C * $sinSigma * ($cos2SigmaM + $C * cos($sigma) * (-1 + 2 * $cos2SigmaM ** 2)));
$sinAlpha = ($LPrime - $lambdaPrime) / $D;
$cosSqAlpha = (1 - $sinAlpha ** 2);
Expand Down
6 changes: 6 additions & 0 deletions tests/CompoundPointTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ public function testCompoundWithEpochDateTimeImmutable(): void
self::assertEquals('((123, 456), (789))', $object->__toString());
}

/**
* @group distance
*/
public function testDistanceCalculation(): void
{
$from = CompoundPoint::create(
Expand All @@ -107,6 +110,9 @@ public function testDistanceCalculation(): void
self::assertEqualsWithDelta(115423.134596, $from->calculateDistance($to)->getValue(), 0.000001);
}

/**
* @group distance
*/
public function testDistanceDifferentCRS(): void
{
$this->expectException(InvalidCoordinateReferenceSystemException::class);
Expand Down
6 changes: 6 additions & 0 deletions tests/GeocentricPointTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,19 @@ public function testWithFeetAsUnits(): void
self::assertEquals(37.4904, $object->getZ()->getValue());
}

/**
* @group distance
*/
public function testDistanceCalculation(): void
{
$from = GeocentricPoint::create(Geocentric::fromSRID(Geocentric::EPSG_WGS_84), new Metre(6121151.5493), new Metre(-1563978.9235), new Metre(-872615.3556));
$to = GeocentricPoint::create(Geocentric::fromSRID(Geocentric::EPSG_WGS_84), new Metre(3797282.484), new Metre(-423484.681), new Metre(5090128.466));
self::assertEqualsWithDelta(6824225.464, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceDifferentCRSsNoAutoconversion(): void
{
$this->expectException(InvalidArgumentException::class);
Expand Down
61 changes: 61 additions & 0 deletions tests/GeographicPointTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,62 +118,89 @@ public function test3DWithoutHeight(): void
$object = GeographicPoint::create(Geographic3D::fromSRID(Geographic3D::EPSG_WGS_84), new Degree(0.123), new Degree(0.456), null);
}

/**
* @group distance
*/
public function testDistanceCalculation(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Degree(51.54105), new Degree(-0.12319), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Degree(51.507977), new Degree(-0.124588), null);
self::assertEqualsWithDelta(3680.925, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceCalculationReversedOrder(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Degree(51.507977), new Degree(-0.124588), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Degree(51.54105), new Degree(-0.12319), null);
self::assertEqualsWithDelta(3680.925, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceCalculationVincentyExample1(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_CH1903), Degree::fromSexagesimalDMSS('554500.00'), new Degree(0), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_CH1903), Degree::fromSexagesimalDMSS('-332600.00'), Degree::fromSexagesimalDMSS('1081300.00'), null);
self::assertEqualsWithDelta(14110526.170, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceCalculationVincentyExample2(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), Degree::fromSexagesimalDMSS('371954.95367'), new Degree(0), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), Degree::fromSexagesimalDMSS('260742.83946'), Degree::fromSexagesimalDMSS('412835.50729'), null);
self::assertEqualsWithDelta(4085966.703, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceCalculationVincentyExample3(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), Degree::fromSexagesimalDMSS('351611.24862'), new Degree(0), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), Degree::fromSexagesimalDMSS('672214.77638'), Degree::fromSexagesimalDMSS('1374728.31435'), null);
self::assertEqualsWithDelta(8084823.839, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceCalculationVincentyExample4(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), Degree::fromSexagesimalDMSS('10000.00'), new Degree(0), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), Degree::fromSexagesimalDMSS('-05953.83076'), Degree::fromSexagesimalDMSS('1791748.02997'), null);
self::assertEqualsWithDelta(19960000.000, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceCalculationVincentyExample5(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), Degree::fromSexagesimalDMSS('10000.00'), new Degree(0), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), Degree::fromSexagesimalDMSS('10115.18952'), Degree::fromSexagesimalDMSS('1794617.84244'), null);
self::assertEqualsWithDelta(19780006.558, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceCalculationAntipodeWikiExample1(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Degree(0), new Degree(0), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Degree(0.5), new Degree(179.5), null);
self::assertEqualsWithDelta(19936288.579, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceCalculationAntipodeWikiExample2(): void
{
self::markTestSkipped(); // this doesn't work the rest do, think it might be rounding issues
Expand All @@ -182,27 +209,39 @@ public function testDistanceCalculationAntipodeWikiExample2(): void
self::assertEqualsWithDelta(19944127.421, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceCalculationAntipodeVincentyExample1(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), Degree::fromSexagesimalDMSS('414145.88000'), new Degree(0), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), Degree::fromSexagesimalDMSS('-414146.20000'), Degree::fromSexagesimalDMSS('1795959.44000'), null);
self::assertEqualsWithDelta(20004566.7228, $from->calculateDistance($to)->getValue(), 0.0001);
}

/**
* @group distance
*/
public function testDistanceCalculationAntipodeVincentyExample2(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), new Degree(0), new Degree(0), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), new Degree(0), Degree::fromSexagesimalDMSS('1794149.78063'), null);
self::assertEqualsWithDelta(19996147.4169, $from->calculateDistance($to)->getValue(), 0.0001);
}

/**
* @group distance
*/
public function testDistanceCalculationAntipodeVincentyExample3(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), Degree::fromSexagesimalDMSS('300000.00000'), new Degree(0), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_ED50), Degree::fromSexagesimalDMSS('-300000.00000'), Degree::fromSexagesimalDMSS('1794000.00000'), null);
self::assertEqualsWithDelta(19994364.6069, $from->calculateDistance($to)->getValue(), 0.0001);
}

/**
* @group distance
*/
public function testDistanceCalculationAntipodeVincentyExample4(): void
{
self::markTestSkipped(); // this doesn't work the rest do, think it might be rounding issues
Expand All @@ -211,20 +250,39 @@ public function testDistanceCalculationAntipodeVincentyExample4(): void
self::assertEqualsWithDelta(20000433.9629, $from->calculateDistance($to)->getValue(), 0.0001);
}

/**
* @group distance
*/
public function testDistanceCalculationSmallDistance(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Degree(45.306833), new Degree(5.887717), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Degree(45.306833), new Degree(5.887733), null);
self::assertEqualsWithDelta(1.255, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceCalculationSmallDistance2(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Degree(0), new Degree(0), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Degree(0), new Degree(0.1), null);
self::assertEqualsWithDelta(11131.949, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceCalculationSmallDistance3(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Degree(37.774929), new Degree(-122.419416), null);
$to = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Degree(37.774929), new Degree(-122.419416), null);
self::assertEqualsWithDelta(0, $from->calculateDistance($to)->getValue(), 0.001);
}

/**
* @group distance
*/
public function testDistanceDifferentCRSs(): void
{
$from = GeographicPoint::create(Geographic2D::fromSRID(Geographic2D::EPSG_OSGB36), new Degree(51.54105), new Degree(-0.12319), null);
Expand All @@ -237,6 +295,9 @@ public function testDistanceDifferentCRSs(): void
}
}

/**
* @group distance
*/
public function testDistanceDifferentCRSsNoAutoconversion(): void
{
$this->expectException(InvalidCoordinateReferenceSystemException::class);
Expand Down
15 changes: 15 additions & 0 deletions tests/ProjectedPointTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,29 @@ public function testWithFeetAsUnitsEastingNorthing(): void
self::assertEquals(37.4904, $object->getNorthing()->getValue());
}

/**
* @group distance
*/
public function testDistanceCalculationEastingNorthing(): void
{
$from = ProjectedPoint::createFromEastingNorthing(Projected::fromSRID(Projected::EPSG_WGS_84_WORLD_MERCATOR), new Metre(438700), new Metre(114800));
$to = ProjectedPoint::createFromEastingNorthing(Projected::fromSRID(Projected::EPSG_WGS_84_WORLD_MERCATOR), new Metre(533600), new Metre(180500));
self::assertEqualsWithDelta(115423.134596, $from->calculateDistance($to)->getValue(), 0.000001);
}

/**
* @group distance
*/
public function testDistanceDifferentCRSEastingNorthing(): void
{
$from = ProjectedPoint::createFromEastingNorthing(Projected::fromSRID(Projected::EPSG_WGS_84_WORLD_MERCATOR), new Metre(438700), new Metre(114800));
$to = ProjectedPoint::createFromEastingNorthing(Projected::fromSRID(Projected::EPSG_WGS_84_PSEUDO_MERCATOR), new Metre(533600), new Metre(180500));
self::assertEqualsWithDelta(114739.81913, $from->calculateDistance($to)->getValue(), 0.000001);
}

/**
* @group distance
*/
public function testDistanceDifferentCRSNoAutoconversion(): void
{
$this->expectException(InvalidCoordinateReferenceSystemException::class);
Expand All @@ -124,6 +133,9 @@ public function testWithFeetAsUnitsWestingNorthing(): void
self::assertEquals(37.4904, $object->getNorthing()->getValue());
}

/**
* @group distance
*/
public function testDistanceCalculationWestingNorthing(): void
{
$from = ProjectedPoint::createFromWestingNorthing(Projected::fromSRID(Projected::EPSG_ETRS89_FAROE_LAMBERT), new Metre(438700), new Metre(114800));
Expand All @@ -147,6 +159,9 @@ public function testWithFeetAsUnitsWestingSouthing(): void
self::assertEquals(37.4904, $object->getSouthing()->getValue());
}

/**
* @group distance
*/
public function testDistanceCalculationWestingSouthing(): void
{
$from = ProjectedPoint::createFromWestingSouthing(Projected::fromSRID(Projected::EPSG_ST_STEPHEN_GRID_FERRO), new Metre(438700), new Metre(114800));
Expand Down
9 changes: 9 additions & 0 deletions tests/UTMPointTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public function testAsGeographicPointSouthernHemisphere(): void
self::assertEqualsWithDelta(151.211111, $to->getLongitude()->getValue(), 0.00001);
}

/**
* @group distance
*/
public function testDistanceSameZone(): void
{
$from = new UTMPoint(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Metre(630084), new Metre(4833439), 32, UTMPoint::HEMISPHERE_NORTH);
Expand All @@ -41,6 +44,9 @@ public function testDistanceSameZone(): void
self::assertEquals($distance->getValue(), 500);
}

/**
* @group distance
*/
public function testDistanceSameZoneDifferentCRS(): void
{
$from = new UTMPoint(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Metre(630084), new Metre(4833439), 32, UTMPoint::HEMISPHERE_NORTH);
Expand All @@ -50,6 +56,9 @@ public function testDistanceSameZoneDifferentCRS(): void
self::assertEqualsWithDelta($distance->getValue(), 500, 0.1);
}

/**
* @group distance
*/
public function testDistanceDifferentZoneSameCRS(): void
{
$from = new UTMPoint(Geographic2D::fromSRID(Geographic2D::EPSG_WGS_84), new Metre(630084), new Metre(4833439), 32, UTMPoint::HEMISPHERE_NORTH);
Expand Down

0 comments on commit 8a522fb

Please sign in to comment.