Open Street Map plugin screenshot
Dark mode ready
Multilingual support
Supports v5.x

Open Street Map by Traineratwot

Community

OpenStreetMap field for Filament forms with Leaflet.js — pick coordinates, geocode addresses, and store points in 11 formats (WKT, GeoJSON, array, DMS, map URLs)

Tags: Form Editor Field Form Field
Supported versions:
5.x
Traineratwot avatar Author: Traineratwot

Package health

Automated checks of this plugin's Composer package

80 / 100
Security 68
Maintenance 90
Ecosystem 100
15 checks
Third-party plugin. This is built by the community, not the Filament team. Filament does not review, endorse, or vet the security of plugins outside the filament/ namespace. Review the source and install at your own risk. Found malware or an unresolved security issue the author won't address? Report it .
Powered by Plumb Last scanned 1 month ago

Documentation

Latest Version on Packagist

Total Downloads

Add openstreetmap field to filament form

Full free map API

#Interface

2024-01-19_09-54-03

#How it view in database

NVIDIA_Share_Yn8wCeCsJf

#Installation

You can install the package via composer:

composer require traineratwot/filament-openstreetmap

Then publish the Leaflet assets:

php artisan vendor:publish --tag=filament-openstreetmap-assets

This copies Leaflet JS/CSS to public/vendor/filament-openstreetmap/leaflet/.

#Usage

Make model with migration


return new class extends Migration {
    public function up(): void
    {
        Schema::create('points', function (Blueprint $table) {
            $table->id();
            $table->string('point')->nullable();
            $table->json('point_array')->nullable();
            $table->timestamps();
            $table->softDeletes();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('points');
    }
};
namespace App\Models;

use MatanYadaev\EloquentSpatial\Objects\Point;
use Illuminate\Database\Eloquent\Model;

class Point extends Model
{
    use SoftDeletes;

    protected $guarded = ['id'];

    protected function casts()
    {
        return [
            'point' => PointCast::class,
            'point_array' => PointCast::class . ':' . PointFormat::ARRAY->value ,
        ];
    }
}

Make filament resource


<?php

namespace App\Filament\Resources;

use Traineratwot\FilamentOpenStreetMap\Forms\Components\MapInput;


class MapPointResource extends Resource
{
    protected static ?string $model = MapPoint::class;

    public static function form(Schema $schema): Schema
    {
        return $schema
            ->components([
                MapInput::make('point')
                    ->columnSpan(2)
                    ->saveFormat(PointFormat::WKT)
                ,
                MapInput::make('point_array')
                    ->saveFormat(PointFormat::ARRAY)
                ,

                TextEntry::make('created_at')
                    ->label('Created Date')
                    ->dateTime(),

                TextEntry::make('updated_at')
                    ->label('Last Modified Date')
                    ->dateTime(),
            ]);
    }
}

The Point value object is the recommended way to work with coordinates. It handles format conversion, parsing, and distance calculations.

use Traineratwot\FilamentOpenStreetMap\Data\Point;

// Create a point
$point = new Point(55.7558, 37.6173);

// Format to different output formats
$point->format(PointFormat::LAT_LNG);      // "55.7558,37.6173"
$point->format(PointFormat::WKT);          // "POINT(37.6173 55.7558)"
$point->format(PointFormat::GEOJSON);      // {"type":"Point","coordinates":[37.6173,55.7558]}
$point->format(PointFormat::URL_GOOGLE);   // https://www.google.com/maps/search/?api=1&query=...
$point->format(PointFormat::DMS);          // 55°45'20.88"N 37°37'2.28"E

// Parse from any supported format (auto-detection)
$point = Point::fromValue('55.7558,37.6173');
$point = Point::fromValue('POINT(37.6173 55.7558)');
$point = Point::fromValue('{"type":"Point","coordinates":[37.6173,55.7558]}');
$point = Point::fromValue('https://www.openstreetmap.org/?mlat=55.7558&mlon=37.6173');
$point = Point::fromValue(['latitude' => 55.7558, 'longitude' => 37.6173]);
$point = Point::fromValue([37.6173, 55.7558]); // [lng, lat] array

// Distance to another point (meters)
$moscow = new Point(55.7558, 37.6173);
$berlin = new Point(52.5200, 13.4050);
$moscow->distanceTo($berlin); // ~1609960 meters

// Check equality
$point1->equals($point2); // true if within 0.000001 precision

#Using Point in MapInput

use Traineratwot\FilamentOpenStreetMap\Data\Point;

MapInput::make('location')
    ->saveFormat(PointFormat::WKT)

#Markers

You can add predefined markers to the map. Clicking a marker applies its coordinates to the field value.

use Traineratwot\FilamentOpenStreetMap\Data\Point;

MapInput::make('point')
    ->markers([
        ['title' => 'Office', 'point' => new Point(55.75, 37.61), 'color' => '#ff0000'],
        ['title' => 'Home',   'point' => new Point(55.76, 37.62)],
    ])

Each marker accepts:

  • title — popup text (optional)
  • point — Point instance or [lat, lng] array
  • color — marker dot color (default #3388ff)

#Dynamic markers (Closure)

MapInput::make('point')
    ->markers(fn () => auth()->user()->locations->map(fn ($loc) => [
        'title' => $loc->name,
        'point' => [$loc->lat, $loc->lng],
        'color' => $loc->is_active ? '#22c55e' : '#ef4444',
    ])->toArray())

#Markers Only mode

Restrict selection to predefined markers only — map clicks are disabled, search filters the marker list.

MapInput::make('point')
    ->markers([
        ['title' => 'Moscow',  'point' => new Point(55.7558, 37.6173)],
        ['title' => 'Berlin',  'point' => new Point(52.5200, 13.4050)],
        ['title' => 'Paris',   'point' => new Point(48.8566,  2.3522)],
    ])
    ->markersOnly()

#Dynamic markersOnly (Closure)

MapInput::make('point')
    ->markers(fn () => $this->getAvailablePoints())
    ->markersOnly(fn () => $record?->restrict_selection ?? false)

You can save in database in thar formats

foreach (PointFormat::cases() as $p){
   dump($p->getExample());
}

#   $point = new Point(55.7558, 37.6173);
#    return $point->format(PointFormat::URL_YANDEX);
"55.7558,37.6173" // app/Console/Commands/DevTestCommand.php:17
"37.6173,55.7558" // app/Console/Commands/DevTestCommand.php:17
"POINT(37.6173 55.7558)" // app/Console/Commands/DevTestCommand.php:17
"{"type":"Point","coordinates":[37.6173,55.7558]}" // app/Console/Commands/DevTestCommand.php:17
"55°45'20.88"N 37°37'2.28"E" // app/Console/Commands/DevTestCommand.php:17
"55.755800, 37.617300" // app/Console/Commands/DevTestCommand.php:17
"https://www.google.com/maps/search/?api=1&query=55.7558,37.6173" // app/Console/Commands/DevTestCommand.php:17
"https://www.openstreetmap.org/?mlat=55.7558&mlon=37.6173#map=15/55.7558/37.6173" // app/Console/Commands/DevTestCommand.php:17
"https://yandex.ru/maps/?pt=37.6173,55.7558&z=15&l=map" // app/Console/Commands/DevTestCommand.php:17
"{"latitude":55.7558,"longitude":37.6173}" // app/Console/Commands/DevTestCommand.php:17
"[37.6173,55.7558]" // app/Console/Commands/DevTestCommand.php:17

#Changelog

Please see CHANGELOG for more information on what has changed recently.

#Contributing

Please see CONTRIBUTING for details.

#Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

#Credits

#License

The MIT License (MIT). Please see License File for more information.

#Used packages

composer: matanyadaev/laravel-eloquent-spatial
js: Leaflet.js (vendored)

The author

Traineratwot avatar Author: Traineratwot

OpenStreetMap field for Filament forms with Leaflet.js — pick coordinates, geocode addresses, and store points in 11 formats (WKT, GeoJSON, array, DMS, map URLs)

Plugins
1
Stars
22