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

Geographical Bundle Laravel Package

studio-vinari/geographical-bundle

Studio Vinari's Geographical Bundle is a Symfony package for managing geographical data such as countries, regions, and cities. It provides extensible Doctrine entities, fixtures, and integration helpers for building address forms, location pickers, and region-aware applications with simple setup.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package. The first thing to understand before writing any code is that there is no service provider, no facade, no php artisan vendor:publish, and no auto-discovery. composer require studio-vinari/geographical-bundle in a Laravel app will install some classes and then do absolutely nothing, because the only integration surface is Symfony's DI container and Twig extension system. Your real starting point is not the README but three files in the repo:

  • DependencyInjection/Configuration.php — the actual config schema (vich_geographical tree: provider, API key, map options).
  • Annotation/*.php — the @Vich\Geographical\Annotation classes that mark entity properties as coordinate/address fields.
  • Twig/ extension + Resources/views/ — the vich_geographical_render(...) helper that emits the map container and JS.

Read those and you have read ~90% of the package. Everything else is glue.

Your first use case — the one this bundle exists to solve — is: "a Doctrine entity has latitude/longitude (or an address), and a Twig template renders a map with a marker for it." Reproduce that in Laravel in roughly an hour: an Eloquent model with two decimal columns, a Blade partial that inlines a GeoJSON payload into a data- attribute, and ~30 lines of Leaflet. Do that before deciding you need anything heavier.

If you are actually working in a legacy Symfony app that already depends on this, the getting-started advice is different: pin symfony/* and doctrine/orm to versions the 2017 release supports, freeze the vendor directory, and start planning an exit rather than extending the bundle.

Implementation Patterns

The bundle's model is annotation-driven mapping + template-rendered map. Here is how each piece translates to idiomatic Laravel.

Entity mapping → Eloquent + casts. Where Symfony uses @Vich\Geographical\Annotation\Coordinate on properties, Laravel uses a migration and a cast:

$table->decimal('latitude', 10, 7)->nullable()->index();
$table->decimal('longitude', 10, 7)->nullable()->index();
// model
protected $casts = ['latitude' => 'float', 'longitude' => 'float'];

Keep latitude/longitude as the canonical pair; do not invent a location string column unless you also store a real spatial column.

Map rendering → Blade component, not a helper. The bundle's Twig helper is a god-function that mixes config, entity data, and JS. In Laravel, make a component <x-geo-map :markers="$markers" /> that serializes markers into a data-markers attribute and lets a small Leaflet script hydrate it. Keep the API key in config('services.maps.key') and the JS in a Vite entry point — never inline the key into a Blade template you might render in an email or JSON response.

Address → coordinate → queued job. The bundle's geocoding concept maps cleanly to a GeocodeAddress job using geocoder-php (Google or Nominatim provider), with RateLimited middleware, results cached by address hash, and the result written back to the model. Do not geocode synchronously in a controller; the free tiers and latency will make you regret it.

Admin editing → map picker, not text inputs. The Symfony bundle shipped JS to render maps read-only; the day-to-day need is the inverse — click a point, fill latitude/longitude. Build this as a Livewire or Alpine island bound to the two inputs. Users typing coordinates is the #1 source of garbage data.

Data endpoint → GeoJSON + clustering. For more than a few dozen rows, don't render all markers server-side. Add GET /map/markers returning a FeatureCollection, filter by viewport bbox, and use leaflet.markercluster. This is the pattern that scales, and it's the one the bundle's per-entity render helper cannot express.

Legacy Symfony interop. If you genuinely need the bundle in a Symfony app that shares a database with Laravel, the clean split is: Symfony app owns the entity mapping and writes latitude/longitude; Laravel reads those columns and serves the map. Don't try to shuttle annotations across framework boundaries.

Gotchas and Tips

  • It will not boot in Laravel, full stop. There is no bridge worth writing. The Twig extension can't be registered (Twig isn't in the Laravel stack), and the DI compiler pass expects the Symfony container. Treat the repo as a design reference.
  • Age is the headline risk. Last release 2017, zero dependents, zero stars. Annotation-based mapping was deprecated in Symfony 4 and effectively removed with the PHP 8 attributes migration. The bundle predates Doctrine\Common\Annotations reader removal, so upgrading PHP or Doctrine will break it in non-obvious ways.
  • Google Maps assumptions. The JS side assumes Google Maps v3 with an API key and the pre-2018 billing model. If you copy the rendering code verbatim, budget for a key-rotation and billing review. Leaflet/MapLibre + OSM tiles is the cheap default for an internal tool.
  • Precision ≠ queryability. decimal(10,7) renders fine but is useless for "within 5km" queries. Prefilter with a bounding box on indexed columns, then Haversine in SQL or in PHP. Reaching for PostGIS/MySQL 8 ST_Distance_Sphere is worth it once you need real spatial filters.
  • Antimeridian and wrapping bugs. Any bounds logic ported from the bundle will mishandle longitudes crossing ±180 and produce "empty map" symptoms that look like a data problem. Test with points at lng: 179 and lng: -179.
  • Null and NaN coordinates. Serializing a null latitude into JS yields NaN and silently kills the whole marker layer in some Leaflet versions. Filter server-side (whereNotNull('latitude')->whereNotNull('longitude')) and assert in the component.
  • Geocoder quota blowups. The bundle didn't cache geocoding results. Whatever you build, cache by normalized address string and queue the calls behind a rate limiter.
  • Debugging order of operations: inspect rendered HTML for the map container id and the data-markers payload first, then the browser console for JS include-order errors, then the network tab for a 403 from the tile/API provider. In practice 80% of "map doesn't render" is one of those three.
  • Extension points. The bundle's extension surface (map providers, marker templates) is Twig + DI. The Laravel equivalent is a Blade component with named slots and a small Marker value object — keep rendering decisions out of your Eloquent models so you can swap Leaflet for MapLibre later without touching domain code.
  • Verdict: extract the ideas (coordinate annotations → casts, render helper → component, address → geocoder job), not the dependency. For maintained equivalents in the PHP ecosystem, geocoder-php for geocoding and a plain Leaflet/MapLibre front end will outlive this repository by a decade.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle