thinwrap/location

thinwrap/location for PHP — unified facade for 21 connectors across 6 providers, spanning routing, matrix, geocoding, and isochrone. Built-in polyline utilities. Stateless, BYO PSR-18 client.

PHP constraints

Runtime dependencies
php-http/discovery, psr/http-client, psr/http-factory
BYO HTTP client
consumer-supplied PSR-18 client via php-http/discovery
Provenance
cosign-signed GitHub Release artifacts
Minimum runtime
PHP 8.2+
  • PSR-17/PSR-18 discovery is auto-detected; consumers can also pass clients explicitly

30-second install

composer require thinwrap/location

2-minute end-to-end example

Compute a route between two waypoints through any supported provider. The example below uses Mapbox; switching providers means swapping the provider id case and config DTO — input and output shape stay identical.

<?php
use Thinwrap\Location\Routing;
use Thinwrap\Location\Enum\LocationProviderId;
use Thinwrap\Location\Config\MapboxConfig;
use Thinwrap\Location\DTO\LatLng;
use Thinwrap\Location\DTO\Routing\RoutingOptions;

$routing = new Routing(LocationProviderId::Mapbox, new MapboxConfig(accessToken: getenv('MAPBOX_TOKEN')));

$result = $routing->route(new RoutingOptions(
    waypoints: [
        new LatLng(37.7749, -122.4194),
        new LatLng(37.3382, -121.8863),
    ],
));

echo "Distance: {$result->totalDistanceMeters}m, Duration: {$result->totalDurationSeconds}s\n";
echo $result->polyline; // Google precision-5 encoded

Same code works for all supported routing providers — swap to LocationProviderId::Google, ::Here, ::Esri, ::TomTom, or ::Osrm and pass the matching config DTO.

See the universal route snippet for the full copy-paste pattern.

Supported providers

6 providers ship with thinwrap/location@1.0.0.
ProviderOperationsAuthREADME
google Google Maps Platformrouting, matrix, geocodingquerydocs
mapbox Mapboxrouting, matrix, geocoding, isochronequerydocs
here HERErouting, matrix, geocoding, isochroneheaderdocs
esri ESRI ArcGISrouting, matrix, geocoding, isochronebearerdocs
tomtom TomTomrouting, matrix, geocoding, isochronequerydocs
osrm OSRM (self-hosted)routing, matrixheaderdocs

Migration paths

Built-in polyline utilities

Every routing connector emits a Google precision-5 encoded polyline on$result->polyline. Decode, re-encode, or convert HERE's flex-polyline / ESRI's path geometry without a third-party library:

<?php
use Thinwrap\Location\Util\Polyline;

$points = Polyline::decode($result->polyline);    // LatLng[]
$reEncoded = Polyline::encode($points);            // back to precision-5
$here = Polyline::decodeFlex('BFoz5...');          // HERE flex-polyline
$esri = Polyline::encodeEsriPaths([[[-74, 40], [-73.5, 40.5]]]);

Operation coverage

Provider × operation gaps below are architectural, not bugs:

  • OSRM ships only routing +matrix — geocoding and isochrone are out of scope by design for OSRM.
  • Google does not expose a public isochrone API at v1.0; if Google adds one, it lands in a minor release.

Migration: from a Google Maps PHP SDK

Drop the SDK; the wrapper hits the same HTTP endpoint and normalizes the response. Cross-language parity with/packages/location-ts is tracked as a design goal, not a hard release gate.

Migration: from hand-rolled cURL or Guzzle

Keep your PSR-18 client; replace the per-vendor request shape with one uniform call. The wrapper holds no state — every operation is a single method call from input to output (HERE Matrix v8's submit-poll-retrieve cycle stays hidden behind one matrix(...)).

Migration: from a TS service rewriting in PHP

The TS variant ships the same facade shape and provider set. Method names, result-shape fields, and error semantics are parity-locked. Port input/output payloads as-is.

Read more