Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Interface Laravel Package

geo-io/interface

A lightweight set of PHP interfaces for geometric objects such as points, linestrings, polygons and collections, giving geo-io geometry implementations and parsers a shared contract so spatial code stays decoupled and interoperable.

Deep Wiki
Context7

Getting Started

geo-io/interface is a contracts-only package: it ships interfaces, enums, and a couple of small value objects for describing geometries (points, line strings, polygons, collections) and their metadata. It does not parse, validate, serialise, or do spatial math — for that you pair it with geo-io/wkt, geo-io/wkb, or your own readers/writers.

composer require geo-io/interface

Where to look first, in order:

  1. GeometryInterface`` / PointInterface/LineStringInterface/PolygonInterface/GeometryCollectionInterface` — the actual shape of the model. Skim the getters; they tell you what the rest of the geo-io ecosystem expects from a geometry.
  2. GeometryType — the enum used everywhere to discriminate between POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION. Most real code is match ($geometry->getType()) { ... }.
  3. Coordinate (and BoundingBox if present in your version) — the only value objects you're likely to construct by hand. Confirm whether Z/M dimensions are supported by the version you pulled in.
  4. composer.json — check the PHP constraint. The enum usage means PHP 8.1+ in recent releases; older tags may not have enums at all.

First use case: define a boundary in your own application — a service or DTO that accepts anything implementing GeometryInterface and returns a WKT string via geo-io/wkt. Type-hint the interface, not the concrete class, and you can swap in geometries coming from your ORM, a GeoJSON decoder, or a WKB parser without changing your signature.

use GeoIO\Geometry\GeometryInterface;
use GeoIO\Geometry\GeometryType;

final class GeometryDescriber
{
    public function describe(GeometryInterface $geometry): string
    {
        return match ($geometry->getType()) {
            GeometryType::POINT        => 'a point',
            GeometryType::LINESTRING   => 'a line',
            GeometryType::POLYGON      => 'a polygon',
            default                    => 'a collection',
        };
    }
}

Implementation Patterns

Code against the interfaces, never against the package's internals. The whole point of geo-io/interface is that your domain can be the implementation. A Warehouse, Route, or DeliveryZone entity can implement PolygonInterface directly, exposing getExteriorRing() / getInteriorRings() and letting you hand it straight to a WKT writer. This is the highest-leverage pattern with this package: your model stays your model, and geo-io becomes a serialisation detail rather than a parallel object graph.

Enum-driven dispatch instead of instanceof chains. GeometryType gives you a stable, serialisable discriminator. Handlers keyed by the enum case scale better than if ($g instanceof MultiPolygon) branches, and the enum case names map cleanly onto WKT/WKB type strings when you do GeometryType::from($typeString).

Adapter pattern for foreign geometries. When data arrives from PostGIS, a GeoJSON library, or an existing GIS SDK, wrap it in a thin class that implements PointInterface/PolygonInterface by delegating. You get one conversion point in your codebase instead of one per call site, and the wrapper is trivial enough to unit test with a fake coordinate list.

Factory + immutable value objects. Build geometries through a single factory or named constructors (GeometryFactory::point($x, $y)) rather than new scattered everywhere. Coordinate is a value object — treat it as immutable, compare it with an epsilon helper you write yourself, and use it as an array/cache key by casting to a canonical string (sprintf('%.9F %.9F', $x, $y)).

Test doubles are one-liners. Because the package is nothing but interfaces, you can create anonymous classes inside tests to stub a geometry, rather than pulling in a full geometry library. That keeps test suites fast and free of fixture files.

$stub = new class implements \GeoIO\Geometry\PointInterface {
    public function getType(): \GeoIO\Geometry\GeometryType { return \GeoIO\Geometry\GeometryType::POINT; }
    public function getCoordinate(): \GeoIO\Geometry\CoordinateInterface { /* ... */ }
    public function getDimension(): int { return 2; }
    public function isEmpty(): bool { return false; }
};

Integrate at the container boundary. In Symfony/Laravel, alias the geo-io interfaces to your concrete factory, and tag your writers/parsers so a GeometryRenderer can be swapped between WKT, WKB, and GeoJSON without touching controllers.

Gotchas and Tips

  • It's an interface package — it will not save you from invalid geometry. Nothing enforces that a polygon's exterior ring is closed, that a line string has at least two points, or that the SRID is sane. Put those invariants in your implementing classes or a validator; otherwise errors surface deep inside a writer or, worse, in a downstream database.
  • Check the enum style before switching on it. Recent versions ship a GeometryType enum; older tags may use class constants or strings. GeometryType::from() throws on unknown input — use tryFrom() when parsing untrusted WKT and handle null. Also confirm whether comparisons are case-sensitive (POINT vs point).
  • Coordinate axis order is your problem, not the package's. Coordinate stores x/y; whether that means longitude/latitude (GeoJSON, EPSG:4326) or northing/easting is a convention you must document and enforce. A single swapped axis is nearly impossible to spot in logs.
  • Floats are not equal. Value objects built on floating-point coordinates will not behave with ==. Use a tolerance-based comparison (abs($a - $b) < 1e-9) and never in_array() or array_unique() on raw coordinates. For hash keys, normalise to a fixed precision string first.
  • Immutability is a convention, not enforced. If you return an array of child Coordinate objects from a getter, callers can mutate them. Prefer returning fresh arrays/copies, or make your coordinates readonly where the language allows.
  • No equals() contract. If you need equality across two geometries from different libraries, write a comparator; don't assume the package provides one.
  • json_encode() will not give you GeoJSON. The interfaces expose no JsonSerializable behaviour. Add your own normaliser if you need JSON in an API response — and be aware the GeoJSON spec requires [x, y] arrays, not objects.
  • Keep the geo-io family in lockstep. geo-io/wkt and geo-io/wkb are released against specific interface versions; a minor bump in the interface could add methods your concrete classes then fail to implement. Pin both, and run your test suite after any composer update.
  • Debugging tip: when a writer rejects your geometry, var_dump(get_class($geometry)) plus a dump of getType() and the first coordinate usually localises the problem faster than reading the writer's source — mismatched types and empty child collections are the two most common culprits.
  • Extension points are limited by design: no abstract base classes, no traits. Your extension surface is "implement the interface." If you find yourself writing the same boilerplate across many geometries, write your own abstract base in your own namespace rather than expecting one here.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons