dotswan/filament-map-picker
A Filament v3 custom field for picking locations on an OpenStreetMap map and retrieving coordinates in real time. Includes GeoMan integration for drawing, editing, and manipulating markers, polygons, polylines, and circles.
Architecture fit
Dotswan\MapPicker\Fields\Map) plus a matching infolist entry (MapEntry). Value is realized only if our admin surface runs Filament; for API-first products, headless storefronts, or non-Filament admin (Nova, Backpack, hand-rolled Livewire), it is out of scope.lat, lng, optional geojson) and leaves persistence, validation, geocoding, and spatial querying to us. That is the right boundary — no hidden ORM assumptions, no opinionated migrations — but it means the picker is the cheap 20% of the work. The data model, coordinate validation, and backfill are ours.Integration feasibility
composer require, field classes used exactly like native Filament fields, fluent configuration matching Filament conventions (->draggable(), ->zoom(), ->columnSpanFull()). A mid-level Filament developer can produce a working prototype in under a day.refreshMap dispatch pattern for programmatic marker updates. That materially reduces discovery cost.afterStateUpdated to fan the picker state into latitude/longitude/geojson columns; (b) afterStateHydrated to rehydrate from the record. Both are the correct Livewire idiom — but they are copy-paste snippets, not tested framework code. Treat them as recipes, not guarantees.Technical risk
| Risk | Severity | Notes |
|---|---|---|
| Filament v4 compatibility | High | README and install docs are explicitly v3 (^1.8). If our roadmap crosses v4, this package may become a blocker with no fallback but a fork. |
| Tile provider dependency | High | Default tilesUrl points at public OSM tile infrastructure, which has a strict usage policy. Production traffic at any real volume needs a paid/self-hosted tile provider and matching attribution. |
| Bus factor / vendor | Medium | Single-vendor package (Dotswan), 136 stars, 0 dependents. Low score (24.9) reflects thin ecosystem validation, not necessarily poor code. |
| Test coverage | Medium | README/changelog/releases exist; no evidence of an automated JS/PHP test suite. Front-end field behaviour is effectively untested from our side. |
| State contract looseness | Medium | Default state is ['lat' => 0, 'lng' => 0] — the classic Null Island failure. Nothing validates coordinate ranges or "user actually moved the marker." |
strip_tags on GeoJSON |
Medium | The documented hydration recipe sanitizes geometry with strip_tags on a text column. That is a smell: it implies geometry may be stored as unsanitized text and hints at an XSS/encoding surface we should own explicitly. |
| Bundled JS licensing | Low | Leaflet (BSD-2) and Leaflet-Geoman (MIT) are permissive, but verify what is actually vendored, including any CDN-side loading. |
Key questions
tilesUrl string?geojson (JSON column vs. text), and is strip_tags actually necessary or a workaround?POINT) or just two decimals.Stack fit
rangeSelectField), delivery/service-area configuration, property or asset location capture, and admin-only GeoJSON authoring (zones, polygons) where Geoman's draw/edit/cut tools replace a separate GIS tool.Migration path
latitude (decimal 10,7) and longitude (decimal 10,7), plus a geojson JSON column only if polygons/regions are genuinely in scope. Do not start with a spatial type unless query requirements justify it — the package emits plain numbers.Compatibility
^1.8) and commit the lockfile. Never float this dependency.Sequencing
Maintenance
LocationPicker field extending the vendor field) localizes any patch or fork swap to a single file.Support
Scaling
liveLocation(true, true, 5000) posts browser geolocation to the server on an interval. This is a real, sustained write path — restrict it to specific screens and never enable it on a resource the user leaves open in a tab all day.Failure modes
[lat: 0, lng: 0] silently persists as a valid-looking "off the coast of Africa" record. This is the highest-probability data-quality defect; block it in the validator, not the UI.showMyLocationButton and liveLocation fail on permission denial or insecure origin — degrades to manual placement. Acceptable, but should not be the only input path.tile.openstreetmap.org or a CDN-hosted Leaflet bundle breaks the field silently in production with no server error. Add a smoke test that asserts the map container initializes.boundaries() pan-back UX: the map snaps back when dragged outside the box, which reads as a bug to first-time users. Document it or constrain via minZoom deliberately.strip_tags pattern means malformed or hostile geometry content can round-trip. Validate structure server-side (schema check, not tag stripping).Ramp-up
rangeSelectField.Bottom line: adopt with guardrails if we are committed to Filament v3 — pin the version, wrap the field, own the tile provider, and validate coordinates server-side. Defer if a Filament v4 migration is within two quarters, because that upgrade path is unproven and the package would become a schedule risk rather than a shortcut.
How can I help you explore Laravel packages today?