Skip to content

Commit

Permalink
#67 Add a proper API for checking if a point is within the bounding a…
Browse files Browse the repository at this point in the history
…rea of it's CRS
  • Loading branch information
dvdoug committed Aug 23, 2024
1 parent 1ad806c commit 2634d1a
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## [Unreleased]

## [5.10.0] - 2024-08-23
### Added
- Added a new method `isWithinCRSBoundingArea()` on most `Point` objects to check if they lie within the bounds
of their defined CRS

## [5.9.2] - 2024-08-18
### Changed
- Split declaration of the `Projected::EPSG_*` constants into multiple files internally to aid with static analysis
Expand Down Expand Up @@ -340,8 +345,9 @@ Initial release of this fork (based off of v2.3 of original)
- Eastings and northings are rounded to 1m, and lat/long to 5dp (approx 1m) to avoid any misconceptions that precision is the same thing as accuracy.
- When calculating surface distances, a more accurate mean radius is now used rather than that derived from historical definitions of a nautical mile

[Unreleased]: https://github.com/dvdoug/PHPCoord/compare/v5.9.2..master
[Unreleased]: https://github.com/dvdoug/PHPCoord/compare/v5.10.0..master

[5.10.0]: https://github.com/dvdoug/PHPCoord/compare/v5.9.2..v5.10.0
[5.9.2]: https://github.com/dvdoug/PHPCoord/compare/v5.9.1..v5.9.2
[5.9.1]: https://github.com/dvdoug/PHPCoord/compare/v5.9.0..v5.9.1
[5.9.0]: https://github.com/dvdoug/PHPCoord/compare/v5.8.0..v5.9.0
Expand Down
10 changes: 10 additions & 0 deletions src/CoordinateOperation/AutoConversion.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ public function convert(Compound|Geocentric|Geographic2D|Geographic3D|Projected|
return $point;
}

/**
* Calculates if the point as constructed actually lies within the bounding box of the CRS.
*/
public function isWithinCRSBoundingArea(): bool
{
$pointAsWGS84 = $this->getPointForBoundaryCheck(); // some obscure CRSs might not be able to convert

return !$pointAsWGS84 instanceof GeographicValue || $this->crs->getBoundingArea()->containsPoint($pointAsWGS84);
}

/**
* @return array<int, array{operation: string, name: string, source_crs: string, target_crs: string, accuracy: float, in_reverse: bool}>
*/
Expand Down
37 changes: 37 additions & 0 deletions tests/Geometry/BoundingAreaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@
namespace PHPCoord\Geometry;

use PHPCoord\CoordinateOperation\GeographicValue;
use PHPCoord\CoordinateReferenceSystem\Geographic2D;
use PHPCoord\CoordinateReferenceSystem\Projected;
use PHPCoord\Datum\Datum;
use PHPCoord\Point\GeographicPoint;
use PHPCoord\Point\ProjectedPoint;
use PHPCoord\UnitOfMeasure\Angle\Degree;
use PHPCoord\UnitOfMeasure\Length\Metre;
use PHPUnit\Framework\TestCase;

class BoundingAreaTest extends TestCase
Expand Down Expand Up @@ -102,4 +107,36 @@ public function testNetherlandsBufferedCorrectly(): void
$polygon = BoundingArea::createFromExtentCodes(['urn:ogc:def:area:EPSG::1275']);
self::assertTrue($polygon->containsPoint(new GeographicValue(new Degree(50.965613067768), new Degree(5.8249181759236), null, Datum::fromSRID(Datum::EPSG_WORLD_GEODETIC_SYSTEM_1984_ENSEMBLE))));
}

public function testBoundaryChecking(): void
{
$newYorkInED50 = GeographicPoint::create(
latitude: new Degree(40.689167),
longitude: new Degree(-74.044444),
crs: Geographic2D::fromSRID(Geographic2D::EPSG_ED50)
);

$newYorkInNAD83 = GeographicPoint::create(
latitude: new Degree(40.689167),
longitude: new Degree(-74.044444),
crs: Geographic2D::fromSRID(Geographic2D::EPSG_NAD83_2011)
);

$newYorkInCorrectUTM = ProjectedPoint::createFromEastingNorthing(
easting: new Metre(580741),
northing: new Metre(4504692),
crs: Projected::fromSRID(Projected::EPSG_WGS_84_UTM_ZONE_18N)
);

$newYorkInOSGB = ProjectedPoint::createFromEastingNorthing(
easting: new Metre(580741),
northing: new Metre(4504692),
crs: Projected::fromSRID(Projected::EPSG_OSGB36_BRITISH_NATIONAL_GRID)
);

self::assertFalse($newYorkInED50->isWithinCRSBoundingArea());
self::assertTrue($newYorkInNAD83->isWithinCRSBoundingArea());
self::assertTrue($newYorkInCorrectUTM->isWithinCRSBoundingArea());
self::assertFalse($newYorkInOSGB->isWithinCRSBoundingArea());
}
}

0 comments on commit 2634d1a

Please sign in to comment.