dotswan/filament-map-picker

在 Filament 应用程序中使用基于地图的界面轻松选择和检索地理坐标。

v1.3.0 2024-09-13 08:02 UTC

This package is auto-updated.

Last update: 2024-09-19 07:25:17 UTC


README

Latest Version on Packagist Total Downloads Software License

为 Filament 定制的字段,允许您轻松在地图上选择位置并获取地理坐标。

270298161-46b97f72-518b-40c5-963b-8e9d39d77d67

简介

Map Picker 是一个 Filament 定制字段,旨在简化在地图上选择位置和获取其地理坐标的过程。

  • 功能包括
    • Filament-v3 字段,具有 OpenStreetMap 集成
    • 在标记移动完成后接收实时坐标
    • 根据您的喜好定制控件和标记外观
  • PHP 和 Filament 的最新版本
  • 应用最佳实践

支持的地图

Map Picker 目前支持以下地图

  1. Open Street Map(OSM)

根据需要和测试,将添加更多地图选项到包中。

安装

您可以通过 Composer 轻松安装此包

composer require dotswan/filament-map-picker

基本用法

资源文件

<?php
namespace App\Filament\Resources;
use Filament\Resources\Resource;
use Filament\Resources\Forms\Form;
use Dotswan\MapPicker\Fields\Map;
...

class FilamentResource extends Resource
{
    ...
    public static function form(Form $form)
    {
        return $form->schema([
            Map::make('location')
                    ->label('Location')
                    ->columnSpanFull()
                    ->defaultLocation(latitude: 40.4168, longitude: -3.7038)
                    ->afterStateUpdated(function (Set $set, ?array $state): void {
                        $set('latitude', $state['lat']);
                        $set('longitude', $state['lng']);
                    })
                    ->afterStateHydrated(function ($state, $record, Set $set): void {
                        $set('location', ['lat' => $record->latitude, 'lng' => $record->longitude]);
                    })
                    ->extraStyles([
                        'min-height: 150vh',
                        'border-radius: 50px'
                    ])
                    ->liveLocation(true, true, 5000)
                    ->showMarker()
                    ->markerColor("#22c55eff")
                    ->showFullscreenControl()
                    ->showZoomControl()
                    ->draggable()
                    ->tilesUrl("https://tile.openstreetmap.de/{z}/{x}/{y}.png")
                    ->zoom(15)
                    ->detectRetina()
                    ->showMyLocationButton()
                    ->extraTileControl([])
                    ->extraControl([
                        'zoomDelta'           => 1,
                        'zoomSnap'            => 2,
                    ])
           ]);
    }
    ...
}

如果您希望通过操作或更改其他输入值来更新地图位置和标记,可以使用以下方法触发地图刷新

use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\Actions;
use Filament\Support\Enums\VerticalAlignment;

Actions::make([
    Action::make('Set Default Location')
        ->icon('heroicon-m-map-pin')
        ->action(function (Set $set, $state, $livewire): void {
            $set('location', ['lat' => '52.35510989541003', 'lng' => '4.883422851562501']);
            $set('latitude', '52.35510989541003');
            $set('longitude', '4.883422851562501');
            $livewire->dispatch('refreshMap');
        })
])->verticalAlignment(VerticalAlignment::Start);

liveLocation 选项

liveLocation 方法接受三个参数

  1. bool $send: 确定是否发送用户的实时位置。
  2. bool $realtime: 控制是否定期将实时位置发送到服务器。
  3. int $milliseconds: 设置用户位置更新并发送到服务器的间隔(以毫秒为单位)。

示例

Map::make('location')
    ->liveLocation(true, true, 10000)  // Updates live location every 10 seconds
    ->showMarker()
    ->draggable()

作为信息列表字段的用法

MapEntry 信息列表字段显示地图。

use Dotswan\MapPicker\Infolists\MapEntry;

    public static function infolist(Infolist $infolist): Infolist
    {
        return $infolist
            ->schema([
                MapEntry::make('location')
                    ->extraStyles([
                        'min-height: 50vh',
                        'border-radius: 50px'
                    ])
                    ->state(fn ($record) => ['lat' => $record?->latitude, 'lng' => $record?->longitude])
                    ->showMarker()
                    ->markerColor("#22c55eff")
                    ->showFullscreenControl()
                    ->draggable(false)
                    ->zoom(15),

                .....
            ]);
    }

处理地图位置的指南

本节解释了如何在您的应用程序中使用此包处理和显示地图位置。

步骤 1:定义您的数据库模式

确保您的数据库表包括纬度和经度列。这是存储您位置坐标所必需的。您可以定义您的表模式如下

$table->double('latitude')->nullable();
$table->double('longitude')->nullable();

步骤 2:检索和设置坐标

在加载记录时,确保您正确检索和设置纬度和经度值。请在您的表单组件中使用以下方法

->afterStateHydrated(function ($state, $record, Set $set): void {
    $set('location', ['lat' => $record?->latitude, 'lng' => $record?->longitude]);
})

步骤 3:添加纬度和经度表单字段

向您的表单添加纬度和经度隐藏表单字段。这确保了值的存在,但不会显示给用户

TextInput::make('latitude')
    ->hiddenLabel()
    ->hidden(),

TextInput::make('longitude')
    ->hiddenLabel()
    ->hidden()

如果您更喜欢以只读格式显示这些值,将 hidden() 替换为 readOnly()

替代方法:使用单个位置属性

如果您希望将位置作为单个字段处理,您可以在模型中定义一个自定义属性。这种方法避免了需要单独的纬度和经度列

class YourModel extends Model
{
    protected function location(): Attribute
    {
        return Attribute::make(
            get: fn (mixed $value, array $attributes) => [
                'latitude' => $attributes['latitude'],
                'longitude' => $attributes['longitude']
            ],
            set: fn (array $value) => [
                'latitude' => $value['latitude'],
                'longitude' => $value['longitude']
            ],
        );
    }
}

这种方法将纬度和经度封装在单个位置属性中,简化了您的代码。

许可

MIT 许可证 © Dotswan

安全性

我们非常重视安全问题。如果您发现任何错误或安全问题,请通过我们的GitHub问题追踪器向我们报告,以帮助我们维护一个安全的项目。您也可以直接通过tech@dotswan.com联系我们。

贡献

我们欢迎贡献!贡献是开源社区如此令人惊叹的学习、灵感和创造的地方。您所提供的任何贡献都备受赞赏。

如果您有任何建议可以使这个项目变得更好,请克隆仓库并创建一个拉取请求。您也可以简单地创建一个带有“增强”标签的问题。别忘了给项目加星!再次感谢!

  1. 克隆项目
  2. 创建您的功能分支(git checkout -b feature/AmazingFeature
  3. 提交您的更改(git commit -m '添加一些AmazingFeature'
  4. 将更改推送到分支(git push origin feature/AmazingFeature
  5. 打开拉取请求