Geography helper

Maintainers

👁 matthiasmullie

Package info

github.com/matthiasmullie/geo

pkg:composer/matthiasmullie/geo

Fund package maintenance!

matthiasmullie

Statistics

Installs: 81 116

Dependents: 1

Suggesters: 0

Stars: 63

Open Issues: 2

1.1.2 2023-09-11 19:54 UTC

Requires

  • php: >=5.3.0

Suggests

None

Provides

None

Conflicts

None

Replaces

None

MIT 745be10fbad1c871eab6f9b5925ec33471eed4e4

geodistancegeographycoordinatecluster

This package is auto-updated.

Last update: 2026-06-14 00:34:49 UTC


README

👁 Build status
👁 Code coverage
👁 Latest version
👁 Downloads total
👁 License

I strongly suggest reading some background information at https://www.mullie.eu/geographic-searches/

Usage

Find anything in a 10km radius of Kortrijk railway station

The Geo class is particularly useful to do simple distance-based calculations:

$geo = new Geo\Geo('km');

// coord of Kortrijk railway station
$coord = new Geo\Coordinate(50.824167, 3.263889);

// calculate bounding box of 10km around this coordinate
$bounds = $geo->bounds($coord, 10);

/*
 * Now pass this on this the database, so it executes a query like:
 * SELECT *
 * FROM coordinates
 * WHERE
 * lat BETWEEN :swlat AND :nelat
 * lng BETWEEN :swlng AND :nelng
 *
 * :swlat being $bounds->sw->latitude
 * :swlng being $bounds->sw->longitude
 * :nelat being $bounds->ne->latitude
 * :nelng being $bounds->ne->longitude
 *
 * Assume we have the database results in a variable called $results
 */

// now weed out entries that fit in the bounding box, but not exactly in
// the radius we want them to be in
foreach ($results as $i => $result) {
 $resultCoord = new Geo\Coordinate($result['lat'], $result['lng']);

 // actual distance between source coordinate & result from DB
 $distance = $geo->distance($coord, $resultCoord);

 // if distance is too large, get rid of the result
 if ($distance > 10) {
 unset($results[$i]);
 }
}

Cluster coordinates

The Clusterer class can be useful when dealing with a huge amount of locations. E.g. you want to display thousands of locations on a map. Google Maps (and probably others too) can create clusters too, but you'll still have to get all locations to your frontend. Instead of outputting all coordinates and waiting for the full list to load, we can do the clustering in PHP already & serve that frontend of yours a more lightweight selection of coordinates!

$clusterer = new Geo\Clusterer(
 // your viewport: in this case an approximation of bounding box around Belgium
 new Geo\Bounds(
 new Geo\Coordinate(51.474654, 6.344604),
 new Geo\Coordinate(49.482639, 2.471924)
 )
);

// create a matrix of about 12 cells (this may differ from 12, depending on
// the exact measurements of the bounding box)
$clusterer->setNumberOfClusters(12);

// start clustering after 2 locations in the same cell
$clusterer->setMinClusterLocations(2);

// add locations to clusterer
$clusterer->addCoordinate(new Geo\Coordinate(50.824167, 3.263889)); // Kortrijk railway station
$clusterer->addCoordinate(new Geo\Coordinate(51.035278, 3.709722)); // Gent-Sint-Pieters railway station
$clusterer->addCoordinate(new Geo\Coordinate(50.881365, 4.715682)); // Leuven railway station
$clusterer->addCoordinate(new Geo\Coordinate(50.860526, 4.361787)); // Brussels North railway station
$clusterer->addCoordinate(new Geo\Coordinate(50.836712, 4.337521)); // Brussels South railway station
$clusterer->addCoordinate(new Geo\Coordinate(50.845466, 4.357113)); // Brussels Central railway station
$clusterer->addCoordinate(new Geo\Coordinate(51.216227, 4.421180)); // Antwerpen Central railway station

// now get the results...
$clusterer->getClusters(); // returns 1 cluster: all 3 Brussels stations
$clusterer->getCoordinates(); // returns 4 non-clustered coordinates

Installation

Simply add a dependency on matthiasmullie/geo to your composer.json file if you use Composer to manage the dependencies of your project:

composer require matthiasmullie/geo

Although it's recommended to use Composer, you can actually include these files anyway you want.

License

Geo is MIT licensed.