PHPackages                             jeorgy/laravel-postgis - 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. [Database &amp; ORM](/categories/database)
4. /
5. jeorgy/laravel-postgis

ActiveLibrary[Database &amp; ORM](/categories/database)

jeorgy/laravel-postgis
======================

A production-grade Laravel package for PostGIS spatial types and geospatial queries through Eloquent.

v2.0.1(1mo ago)040MITPHPPHP ^8.4

Since Oct 7Pushed 1mo agoCompare

[ Source](https://github.com/jeorgy/laravel-postgis)[ Packagist](https://packagist.org/packages/jeorgy/laravel-postgis)[ RSS](/packages/jeorgy-laravel-postgis/feed)WikiDiscussions master Synced today

READMEChangelog (1)Dependencies (5)Versions (16)Used By (0)

Laravel PostGIS
===============

[](#laravel-postgis)

Biblioteca para consultas geoespaciais em Eloquent com PostgreSQL/PostGIS: cálculo de distâncias, filtros por polígonos, conversão GeoJSON/WKT e objetos de valor imutáveis — com API moderna, tipada e nativa ao Laravel.

Requisitos
----------

[](#requisitos)

- PHP **&gt;= 8.4**
- Laravel **^12.0**
- PostgreSQL com extensão **PostGIS** habilitada

```
CREATE EXTENSION IF NOT EXISTS postgis;
```

Instalação
----------

[](#instalação)

### Via Packagist (versão estável)

[](#via-packagist-versão-estável)

```
composer require jeorgy/laravel-postgis
```

### Via repositório local (desenvolvimento)

[](#via-repositório-local-desenvolvimento)

Se você está testando a versão de desenvolvimento antes da publicação, adicione um repositório local no `composer.json` da sua aplicação Laravel:

```
{
    "repositories": [
        {
            "type": "path",
            "url": "/caminho/absoluto/para/laravel-postgis"
        }
    ],
    "require": {
        "jeorgy/laravel-postgis": "*"
    }
}
```

Em seguida:

```
composer require jeorgy/laravel-postgis:@dev
```

### Via repositório Git

[](#via-repositório-git)

```
{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/jeorgy/laravel-postgis"
        }
    ],
    "require": {
        "jeorgy/laravel-postgis": "dev-main"
    }
}
```

O Service Provider é registrado automaticamente via Laravel Package Auto-Discovery.

---

Configuração do Modelo
----------------------

[](#configuração-do-modelo)

Adicione a trait `Postgis` (ou `HasSpatialColumns`) ao seu modelo Eloquent que possui uma coluna geoespacial.

```
use Illuminate\Database\Eloquent\Model;
use Jeorgy\LaravelPostgis\Postgis;

class Place extends Model
{
    use Postgis;
}
```

### Coluna personalizada

[](#coluna-personalizada)

Por padrão a trait usa a coluna `location`. Para alterar, defina a propriedade `$location`:

```
class Place extends Model
{
    use Postgis;

    protected $location = 'coordinates';
}
```

### Unidade de distância

[](#unidade-de-distância)

Use a propriedade `$spatialUnit` com o enum `DistanceUnit` para configurar a unidade retornada pelo escopo `withDistance`:

```
use Jeorgy\LaravelPostgis\Enums\DistanceUnit;

class Place extends Model
{
    use Postgis;

    protected DistanceUnit $spatialUnit = DistanceUnit::KILOMETER;
}
```

EnumUnidadeFator de divisão`DistanceUnit::METER`metros1 (padrão)`DistanceUnit::KILOMETER`quilômetros1000`DistanceUnit::MILE`milhas1609.344### Migration

[](#migration)

Garanta que a coluna geoespacial seja do tipo adequado ao PostGIS:

```
Schema::create('places', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->specificType('location', 'geography(Point, 4326)');
    $table->timestamps();
});
```

---

Objetos de Valor
----------------

[](#objetos-de-valor)

### Point

[](#point)

Objeto imutável (`final readonly class`) que representa um ponto geográfico.

```
use Jeorgy\LaravelPostgis\Geometries\Point;

$point = new Point(latitude: -23.5505, longitude: -46.6333);
$point = new Point(latitude: -23.5505, longitude: -46.6333, srid: 4326);

$point->latitude;   // -23.5505
$point->longitude;  // -46.6333
$point->srid;       // 4326

$point->toWkt();    // "POINT(-46.6333 -23.5505)"
$point->toGeoJson();
// ['type' => 'Point', 'coordinates' => [-46.6333, -23.5505]]
```

Validações aplicadas automaticamente na construção:

- Latitude deve estar entre `-90` e `90`
- Longitude deve estar entre `-180` e `180`
- SRID deve ser um inteiro positivo

### Polygon

[](#polygon)

Objeto que representa um polígono a partir de anéis de coordenadas ou GeoJSON.

```
use Jeorgy\LaravelPostgis\Geometries\Polygon;

// A partir de anéis de coordenadas [lng, lat]
$polygon = new Polygon([
    [[30, 10], [10, 20], [20, 40], [40, 40]],
]);

// A partir de um objeto GeoJSON
$geoJson = json_decode('{"geometry":{"coordinates":[[[30,10],[10,20],[20,40],[40,40]]]}}');
$polygon = Polygon::fromGeoJson($geoJson);

$polygon->toWkt();    // "POLYGON((30 10, 10 20, 20 40, 40 40, 30 10))"
$polygon->toGeoJson(); // ['type' => 'Polygon', 'coordinates' => [...]]
```

O anel é fechado automaticamente no WKT se o primeiro e último ponto diferirem.

---

Escopos de Consulta
-------------------

[](#escopos-de-consulta)

### `withDistance`

[](#withdistance)

Adiciona uma coluna `distance` ao resultado usando `ST_DistanceSphere`. O valor retornado respeita a `$spatialUnit` do modelo.

```
$origin = new Point(latitude: -23.5505, longitude: -46.6333);

$places = Place::query()
    ->withDistance($origin)
    ->orderBy('distance')
    ->get();

// $place->distance => distância em metros (ou km/milhas conforme $spatialUnit)
```

Passando `null`, a coluna `distance` retorna `0`:

```
Place::query()->withDistance(null)->get();
```

Também aceita array `[lat, lng]` ou array associativo `['lat' => ..., 'lng' => ...]`:

```
Place::query()->withDistance([-23.5505, -46.6333])->get();
Place::query()->withDistance(['lat' => -23.5505, 'lng' => -46.6333])->get();
```

---

### `whereDistance` / `orWhereDistance`

[](#wheredistance--orwheredistance)

Filtra registros por distância com um operador de comparação. O valor de `$units` é sempre em **metros** (independente da `$spatialUnit`).

```
use Jeorgy\LaravelPostgis\Geometries\Point;

$origin = new Point(latitude: -23.5505, longitude: -46.6333);

// Registros a menos de 5 km (5000 metros)
Place::query()
    ->whereDistance($origin, '', 10000)
    ->get();
```

Operadores válidos: `=`, `=`

Operadores inválidos lançam `SpatialQueryException`.

---

### `whereCovers` / `orWhereCovers`

[](#wherecovers--orwherecovers)

Filtra registros cujo ponto geoespacial está dentro de um polígono, usando `ST_Covers`.

```
use Jeorgy\LaravelPostgis\Geometries\Polygon;

// A partir de um objeto Polygon
$polygon = new Polygon([
    [[-46.7, -23.6], [-46.5, -23.6], [-46.5, -23.4], [-46.7, -23.4]],
]);

Place::query()->whereCovers($polygon)->get();

// A partir de um objeto GeoJSON
$geoJson = json_decode('{"geometry":{"coordinates":[[[30,10],[10,20],[20,40],[40,40]]]}}');

Place::query()
    ->where('active', true)
    ->whereCovers($geoJson)
    ->orWhereCovers($outroGeoJson)
    ->get();
```

---

Cast de Ponto
-------------

[](#cast-de-ponto)

Para que o Eloquent hidrate e persista automaticamente a coluna como um objeto `Point`:

```
use Jeorgy\LaravelPostgis\Casts\PointCast;

class Place extends Model
{
    use Postgis;

    protected $casts = [
        'location' => PointCast::class,
    ];
}

// Hidratação automática
$place = Place::find(1);
$place->location;           // instância de Point
$place->location->latitude; // float
```

---

Exemplo completo
----------------

[](#exemplo-completo)

```
use Jeorgy\LaravelPostgis\Enums\DistanceUnit;
use Jeorgy\LaravelPostgis\Geometries\Point;
use Jeorgy\LaravelPostgis\Geometries\Polygon;
use Jeorgy\LaravelPostgis\Postgis;

class Place extends Model
{
    use Postgis;

    protected DistanceUnit $spatialUnit = DistanceUnit::KILOMETER;

    protected $casts = [
        'location' => \Jeorgy\LaravelPostgis\Casts\PointCast::class,
    ];
}

$origin = new Point(latitude: -23.5505, longitude: -46.6333);

$nearby = Place::query()
    ->withDistance($origin)
    ->whereDistance($origin, '
