PHPackages                             matthiasmullie/geo - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. matthiasmullie/geo

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

matthiasmullie/geo
==================

Geography helper

1.1.2(2y ago)6377.6k↓23.2%7[1 PRs](https://github.com/matthiasmullie/geo/pulls)1MITPHPPHP &gt;=5.3.0

Since Sep 30Pushed 2y ago5 watchersCompare

[ Source](https://github.com/matthiasmullie/geo)[ Packagist](https://packagist.org/packages/matthiasmullie/geo)[ Docs](https://github.com/matthiasmullie/geo)[ GitHub Sponsors](https://github.com/matthiasmullie)[ RSS](/packages/matthiasmullie-geo/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (3)Versions (6)Used By (1)

Geo
===

[](#geo)

[![Build status](https://camo.githubusercontent.com/0a4a24295d62147da3747d16572b4301c7c36c1b0b14dc1fb13e0d9c638a3f1c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d617474686961736d756c6c69652f67656f2f746573742e796d6c3f6272616e63683d6d6173746572267374796c653d666c61742d737175617265)](https://github.com/matthiasmullie/geo/actions/workflows/test.yml)[![Code coverage](https://camo.githubusercontent.com/6f2d507858c692cf9bae1f65417f9a3565eeedc64074b09765d2664d143dacad/687474703a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f67682f6d617474686961736d756c6c69652f67656f3f7374796c653d666c61742d737175617265)](https://codecov.io/gh/matthiasmullie/geo)[![Latest version](https://camo.githubusercontent.com/741195f7302863993a5d6a62d6a99a2addec8307d1ebc3896318fba936876363/687474703a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d617474686961736d756c6c69652f67656f3f7374796c653d666c61742d737175617265)](https://packagist.org/packages/matthiasmullie/geo)[![Downloads total](https://camo.githubusercontent.com/288fe9454533c40b9550b10b0b304d326ea3a50ad297d69c559d69df4e253dc9/687474703a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d617474686961736d756c6c69652f67656f3f7374796c653d666c61742d737175617265)](https://packagist.org/packages/matthiasmullie/geo)[![License](https://camo.githubusercontent.com/36edb8775b725bacb8f5d5f7da12de5cb2d924a4eee71f67ed105bc2cba5d609/687474703a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6d617474686961736d756c6c69652f67656f3f7374796c653d666c61742d737175617265)](https://github.com/matthiasmullie/geo/blob/master/LICENSE)

I strongly suggest reading some background information at

Usage
-----

[](#usage)

### Find anything in a 10km radius of Kortrijk railway station

[](#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

[](#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 &amp; 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
------------

[](#installation)

Simply add a dependency on `matthiasmullie/geo` to your composer.json file if you use [Composer](https://getcomposer.org/) 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
-------

[](#license)

Geo is [MIT](http://opensource.org/licenses/MIT) licensed.

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity43

Moderate usage in the ecosystem

Community18

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 90.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~817 days

Total

5

Last Release

980d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/cad3300bf52ada70b17962024941977a92a4da8551cbb92493de23c4bbbb5252?d=identicon)[matthiasmullie](/maintainers/matthiasmullie)

---

Top Contributors

[![matthiasmullie](https://avatars.githubusercontent.com/u/312776?v=4)](https://github.com/matthiasmullie "matthiasmullie (29 commits)")[![andrewtch](https://avatars.githubusercontent.com/u/925330?v=4)](https://github.com/andrewtch "andrewtch (2 commits)")[![machadoug](https://avatars.githubusercontent.com/u/1613200?v=4)](https://github.com/machadoug "machadoug (1 commits)")

---

Tags

geographygeodistanceclustercoordinate

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/matthiasmullie-geo/health.svg)

```
[![Health](https://phpackages.com/badges/matthiasmullie-geo/health.svg)](https://phpackages.com/packages/matthiasmullie-geo)
```

###  Alternatives

[mjaschen/phpgeo

Simple Yet Powerful Geo Library

1.6k8.6M22](/packages/mjaschen-phpgeo)[geokit/geokit

Geo-Toolkit for PHP

251924.7k6](/packages/geokit-geokit)[brick/geo

GIS geometry library

245862.1k15](/packages/brick-geo)[creof/geo-parser

Parser for geography coordinate strings

624.4M15](/packages/creof-geo-parser)[data-values/geo

Geographical value objects, parsers and formatters

20631.0k18](/packages/data-values-geo)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
