phpgeo provides abstractions to geographical coordinates (including support for different ellipsoids) and allows you to calculate geographical distances between coordinates with high precision.
Minimum required PHP version is 8.1. phpgeo is tested up to PHP 8.3.
New features will only go into the main branch and won't be backported.
It's possible to install older versions of phpgeo for older PHP versions. Please refer to the following table for the compatibility matrix:
PHP Version | phpgeo Version | Support Status | Composer Install |
---|---|---|---|
8.3 | 5.x | active | composer require mjaschen/phpgeo |
8.2 | 5.x | active | composer require mjaschen/phpgeo |
8.1 | 5.x | active | composer require mjaschen/phpgeo |
8.0 | 4.x | composer require mjaschen/phpgeo:^4.0 |
|
7.4 | 4.x | composer require mjaschen/phpgeo:^4.0 |
|
7.3 | 4.x | composer require mjaschen/phpgeo:^4.0 |
|
7.2 | 3.x | end of life | composer require mjaschen/phpgeo:^3.0 |
7.1 | 2.x | end of life | composer require mjaschen/phpgeo:^2.0 |
7.0 | 2.x | end of life | composer require mjaschen/phpgeo:^2.0 |
5.6 | 1.x | end of life | composer require mjaschen/phpgeo:^1.0 |
5.5 | 1.x | end of life | composer require mjaschen/phpgeo:^1.0 |
5.4 | 1.x | end of life | composer require mjaschen/phpgeo:^1.0 |
The documentation is available at phpgeo.marcusjaschen.de.
Using Composer, just add it to your composer.json
by running:
composer require mjaschen/phpgeo
Update the version constraint in the project's composer.json
and
run composer update
or require the new version by running:
composer require mjaschen/phpgeo:^5.0
phpgeo has some breaking changes in the 5.x release line. Please refer to the following list to see what has changed and what you need to do to upgrade your code.
Change | Description | Action |
---|---|---|
setPoint1() and setPoint2() methods removed from Line |
The Line class now is immutable. |
Use the constructor to create a new instance of Line . |
removed support for PHP 7.3, 7.4 and 8.0 | Older PHP versions are no longer supported. | Upgrade to at least PHP 8.1. |
Starting with version 2.0.0 phpgeo is licensed under the MIT license. Older versions were GPL-licensed.
Info: Please visit the documentation site for complete and up-to-date documentation with many examples!
phpgeo provides the following features (follow the links for examples):
18° 54′ 41″ -155° 40′ 42″
)This list is incomplete, please visit the documentation site for the full monty of documentation and examples!
Use the calculator object directly:
<?php
use LocationCoordinate;
use LocationDistanceVincenty;
$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit
$calculator = new Vincenty();
echo $calculator->getDistance($coordinate1, $coordinate2); // returns 128130.850 (meters; ≈128 kilometers)
or call the getDistance()
method of a Coordinate object by injecting a calculator object:
<?php
use LocationCoordinate;
use LocationDistanceVincenty;
$coordinate1 = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
$coordinate2 = new Coordinate(20.709722, -156.253333); // Haleakala Summit
echo $coordinate1->getDistance($coordinate2, new Vincenty()); // returns 128130.850 (meters; ≈128 kilometers)
Polylines can be simplified to save storage space or bandwidth. Simplification is done with the Ramer–Douglas–Peucker algorithm (AKA Douglas-Peucker algorithm).
<?php
use LocationCoordinate;
use LocationPolyline;
use LocationDistanceVincenty;
$polyline = new Polyline();
$polyline->addPoint(new Coordinate(10.0, 10.0));
$polyline->addPoint(new Coordinate(20.0, 20.0));
$polyline->addPoint(new Coordinate(30.0, 10.0));
$processor = new Simplify($polyline);
// remove all points which perpendicular distance is less
// than 1500 km from the surrounding points.
$simplified = $processor->simplify(1500000);
// simplified is the polyline without the second point (which
// perpendicular distance is ~1046 km and therefore below
// the simplification threshold)
phpgeo has a polygon implementation which can be used to determinate if a point is contained in it or not.
A polygon consists of at least three points. Points are instances of the Coordinate
class.
Warning: The calculation gives wrong results if the polygons has points on both sides of the 180/-180 degrees meridian.
<?php
use LocationCoordinate;
use LocationPolygon;
$geofence = new Polygon();
$geofence->addPoint(new Coordinate(-12.085870,-77.016261));
$geofence->addPoint(new Coordinate(-12.086373,-77.033813));
$geofence->addPoint(new Coordinate(-12.102823,-77.030938));
$geofence->addPoint(new Coordinate(-12.098669,-77.006476));
$outsidePoint = new Coordinate(-12.075452, -76.985079);
$insidePoint = new Coordinate(-12.092542, -77.021540);
var_dump($geofence->contains($outsidePoint)); // returns bool(false) the point is outside the polygon
var_dump($geofence->contains($insidePoint)); // returns bool(true) the point is inside the polygon
You can format a coordinate in different styles.
<?php
use LocationCoordinate;
use LocationFormatterCoordinateDecimalDegrees;
$coordinate = new Coordinate(19.820664, -155.468066); // Mauna Kea Summit
echo $coordinate->format(new DecimalDegrees());
<?php
use LocationCoordinate;
use LocationFormatterCoordinateDMS;
$coordinate = new Coordinate(18.911306, -155.678268); // South Point, HI, USA
$formatter = new DMS();
echo $coordinate->format($formatter); // 18° 54′ 41″ -155° 40′ 42″
$formatter->setSeparator(", ")
->useCardinalLetters(true)
->setUnits(DMS::UNITS_ASCII);
echo $coordinate->format($formatter); // 18° 54' 41" N, 155° 40' 42" W
<?php
use LocationCoordinate;
use LocationFormatterCoordinateGeoJSON;
$coordinate = new Coordinate(18.911306, -155.678268); // South Point, HI, USA
echo $coordinate->format(new GeoJSON()); // { "type" : "point" , "coordinates" : [ -155.678268, 18.911306 ] }
Before submitting a pull request, please be sure to run all checks and tests and ensure everything is green.
composer ci:lint
composer ci:psalm
composer ci:tests
To run all checks and tests at once, just use composer ci
.
Of course, it's possible to use the test runners directly, e.g. for PHPUnit:
./vendor/bin/phpunit
Psalm:
./vendor/bin/psalm
It's possible to run the whole CI test matrix locally with act:
act --rm -P ubuntu-latest=shivammathur/node:latest