webbingbrasil / filament-maps
为 Filament 提供地图组件。
Requires
- php: ^8.0
- filament/filament: ^3.0.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- laravel/pint: ^1.13
README
使用 Leaflet 渲染地图小部件。
- 支持同一页面上多个地图
- 内置操作:
CenterMapAction
、ZoomAction
、FullpageAction
和FullscreenAction
- 直接在地图控制按钮上添加 Filament 操作
- 支持多层。包含 DarkModeTile 层。
- 支持标记聚合
注意 对于 Filament 2.x,请使用 2.x 分支
安装
composer require webbingbrasil/filament-maps
使用
创建一个小部件类,并扩展 Webbingbrasil\FilamentMaps\Widgets\MapWidget
use Webbingbrasil\FilamentMaps\Actions; use Webbingbrasil\FilamentMaps\Marker; use Webbingbrasil\FilamentMaps\Widgets\MapWidget; class Map extends MapWidget { protected int | string | array $columnSpan = 2; protected bool $hasBorder = false; public function getMarkers(): array { return [ Marker::make('pos2')->lat(-15.7942)->lng(-47.8822)->popup('Hello Brasilia!'), ]; } public function getActions(): array { return [ Actions\ZoomAction::make(), Actions\CenterMapAction::make()->zoom(2), ]; } }
如果您使用
make:filament-widget
命令创建了一个新小部件,请记住删除与之一起创建的视图,否则地图将无法渲染。
地图配置
对于某些配置,可以使用属性
$mapOptions
:包含 Leaflet 可用选项的数组。有关详细信息,请参阅 Leaflet 文档$tileLayerUrl
:字符串或包含瓦片层 URL 的数组。默认为 OpenStreetMap。$hasBorder
:在地图周围显示边框。默认为true
。$rounded
:在地图周围显示圆角边框。默认为true
。$height
:地图的高度。默认为400px
。$heading
:设置地图的航向。$footer
:设置地图的页脚。$fullpage
:以全页模式显示地图。默认为false
。
但您也可以使用 setUp
方法以获得更多控制
public function setUp(): void { $this ->tileLayerUrl(...) ->height(..) ->rounded(..) ->mapOptions(..) ->mapMarkers([ ... ]) ->fitBounds([ [lat, lng], [lat, lng] ... ]) ->actions([ .. ]); }
setUp
方法在组件的mount
阶段被调用。有关更多信息,请参阅 livewire 生命周期钩子
全局配置
如果您想为地图小部件的所有实例设置默认配置,您可以在服务提供者中使用 configureUsing
方法
MyMap::configureUsing(function (ResellerMap $widget) { $widget->mapMarkers([ Marker::make('id') ->lat(51.505) ->lng(-0.09) ->popup('I am a popup') ->tooltip('I am a tooltip'), ]) ->tileLayerUrl('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png') ->tileLayerOptions([ 'attribution' => 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors', ]) });
瓦片层
默认情况下,地图使用 OpenStreetMap 瓦片,但您可以使用 $tileLayerUrl
属性或 tileLayerUrl
方法将其更改为任何其他提供者。建议同时使用 tileLayerOptions
设置正确的归属。
多个瓦片层
您还可以使用多个瓦片层
protected string | array $tileLayerUrl = [ 'OpenStreetMap' => 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 'OpenTopoMap' => 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png' ]; protected array $tileLayerOptions = [ 'OpenStreetMap' => [ 'attribution' => 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors', ], 'OpenTopoMap' => [ 'attribution' => 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors, SRTM | Map style © <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)', ], ];
并且您可以使用操作来更改瓦片层
Actions\Action::make('mode') ->icon('filamentmapsicon-o-square-3-stack-3d') ->callback('setTileLayer(mode === "OpenStreetMap" ? "OpenTopoMap" : "OpenStreetMap")'),
深色模式
如果您想使用深色模式瓦片层,您可以使用 HasDarkModeTiles
特性。这个特性将自动设置两个瓦片层并监听 Filament dark-mode-toggled
事件。您可以使用 $lightModeTileLayerUrl
和 $darkModeTileLayerUrl
属性更改默认瓦片层。
操作
您可以向地图小部件添加操作。操作是按钮,可以点击它来执行使用 JS 回调的操作。您可以创建自己的操作或使用包中提供的操作。
缩放操作
ZoomAction
操作将在地图上添加一个按钮,可以放大或缩小地图。您可以使用 zoom()
方法设置缩放级别。
use Webbingbrasil\FilamentMaps\Actions; Actions\ZoomAction::make()->zoom(2), // Zoom in/out 2 levels
中心地图操作
此操作将使地图中心定位在特定位置。
use Webbingbrasil\FilamentMaps\Actions; public function getActions(): array { return [ Actions\CenterMapAction::make()->centerTo([51.505, -0.09])->zoom(13), ]; }
您还可以将地图中心定位在用户位置
Actions\CenterMapAction::make()->centerOnUserPosition()->zoom(13)
注意:中心对用户位置功能仅在用户浏览器支持 Navigator.geolocation 时才可用。此外,用户必须位于安全上下文(HTTPS)中,并需要允许访问位置。
适应边界
您可以使用 fitBounds() 调整地图的缩放级别和中心,以显示给定的地理区域
Actions\CenterMapAction::make()->fitBounds([ [lat, lng], [lat, lng], ])
您可以为 fitBounds() 传递多个点或使用 setUp() 中配置的初始边界
public function setUp(): void { $this->fitBounds([ [lat, lng], [lat, lng], ... ]); } public function getActions(): array { return [ CenterMapAction::make()->fitBounds($this->getFitBounds()), ]; }
全页或全屏操作
您可以在地图中添加一个按钮,以全页或全屏模式显示。
use Webbingbrasil\FilamentMaps\Actions; Actions\FullpageAction::make() Actions\FullscreenAction::make()
自定义操作
您可以使用 Webbingbrasil\FilamentMaps\Actions\Action
创建自己的操作。
例如,添加新标记的操作
use Webbingbrasil\FilamentMaps\Actions; Actions\Action::make('form') ->icon('filamentmapsicon-o-arrows-pointing-in') ->form([ Forms\Components\TextInput::make('name') ->label('Name') ->required(), Forms\Components\TextInput::make('lat') ->label('Latitude') ->required(), Forms\Components\TextInput::make('lng') ->label('Longitude') ->required(), ]) ->action(function (array $data, self $livewire) { $livewire ->addMarker( Marker::make(Str::camel($data['name'])) ->lat($data['lat']) ->lng($data['lng']) ->popup($data['name']) ) ->centerTo(location: [$data['lat'], $data['lng']], zoom: 13) })
在这个例子中,我们使用 addMarker()
方法动态添加新标记,并使用 centerTo()
设置新的地图中心和缩放级别。
您可以使用以下方式操作标记数据
$liveWire->mapMarkers(array $markers); // update the markers $livewire->addMarker(Marker $marker); // add a new marker $livewire->removeMarker(string $id); // remove a marker $livewire->updateMarker(string $id, Marker $marker); // update a marker
注意:标记需要有一个唯一名称。如果您尝试添加与现有标记名称相同的标记,则现有的标记将被替换。
使用 JS
如果您想使用自定义javascript来操作地图而不使用 Livewire,则此方法很有用。
Actions\Action::make('center') ->alpineClickHandler(<<<JS map.setView([0,0], 2) JS)
使用
map
属性在您的操作处理程序中访问 Leaflet 实例。
操作位置
您可以使用 position()
方法设置操作的位置
$this ->actions([ Actions\CenterMapAction::make()->position('topright'), ]) }
操作图标
您可以使用 icon()
方法设置操作图标
Actions\Action::make()->icon('heroicon-o-home')
标记
您可以将标记添加到地图小部件中。标记是地图上的点,可以单击以打开信息弹出窗口或执行 JS 回调。
use Webbingbrasil\FilamentMaps\Marker; $this ->mapMarkers([ Marker::make('id') ->lat(51.505) ->lng(-0.09) ->popup('I am a popup'), Marker::make('id') ->lat(51.505) ->lng(-0.09) ->tooltip('I am a tooltip') ->callback(<<<JS alert('Hello World!'); JS), ]) }
回调方法在标记渲染期间调用,必须返回在点击事件上执行的 JS。使用
map
在您的回调中访问 Leaflet 实例。
标记聚合
您可以使用 MarkerCluster
类将标记分组。如果您在地图上有很多标记,这很有用。
use Webbingbrasil\FilamentMaps\MarkerCluster; $this ->mapMarkers([ MarkerCluster::make([ Marker::make('id') ->lat(51.505) ->lng(-0.09) ->popup('I am a popup'), Marker::make('id') ->lat(51.505) ->lng(-0.09) ->tooltip('I am a tooltip') ->callback(<<<JS alert('Hello World!'); JS), ]), ]) }
标记图标颜色
您可以使用 color()
方法设置标记图标的颜色
Marker::make('id') ->color(Marker::COLOR_RED)
请参阅 Marker::COLOR_*
常量以获取所有可用颜色。默认颜色是 Marker::COLOR_BLUE
。
标记自定义图标
您可以使用 icon()
方法为标记设置自定义图标
Marker::make('id') ->icon( string $iconUrl, string $shadowUrl, array $iconSize, array $iconAnchor, array $popupAnchor, array $shadowSize )
您可以从 leaflet-color-markers 获取额外的图标和相关的配置
显示标记详细信息
目前,标记没有与操作相同的功能,但使用 livewire 事件,您可以执行类似操作,例如
为您的标记添加回调
Marker::make('place')->callback('Livewire.emit("updateFooter", ' . $placeId . ')');
在地图小部件中注册事件监听器
protected $listeners = ['updateFooter' => 'showMarkerData']; public function showMarkerData($placeId) { $place = Place::find($placeId); $this->footer = view('marker-details', $place); }
多边形线
您可以将多边形线添加到地图小部件中。多边形线是地图上在两个经纬度点之间绘制的线。如果您有多个多边形线,则每条多边形线必须具有唯一的名称。
public function getPolylines(): array { return [ Polyline::make('polyline') ->latlngs([ [45.51, -122.68], [37.77, -122.43], [34.04, -118.2] ])->options(['color' => 'blue', 'weight' => 5]) ->tooltip('I am a tooltip') ->popup('I am a popup'), ]; }
您可以使用 Leaflet 多边形线选项 中列出的选项
多边形线操作
您可以使用上述描述的操作来操作多边形线
Actions\Action::make('add line') ->tooltip('Add line') ->icon('filamentmapsicon-o-map-pin') ->form([ Forms\Components\TextInput::make('name') ->label('Name') ->required(), Forms\Components\Section::make('Start') ->schema([ Forms\Components\TextInput::make('lat1') ->label('Latitude') ->required(), Forms\Components\TextInput::make('lng1') ->label('Longitude') ->required(), ]), Forms\Components\Section::make('End') ->schema([ Forms\Components\TextInput::make('lat2') ->label('Latitude') ->required(), Forms\Components\TextInput::make('lng2') ->label('Longitude') ->required(), ]), ]) ->action(function (array $data, self $livewire) { $livewire ->addPolyline( Polyline::make(Str::camel($data['name'])) ->latlngs([ [$data['lat1'], $data['lng1']], [$data['lat2'], $data['lng2']] ]) ); })
在这个例子中,我们使用 addPolyline()
方法动态添加新多边形线。您还可以使用 removePolyline()
和 updatePolyline()
方法。
$livewire->addPolyline(Polyline::make('polyline-name')->latlngs([...])->options([..])); $livewire->removePolyline('polyline-name'); $livewire->updatePolyline(Polyline::make('polyline-name')->latlngs([...])->options([...]));
多边形
您可以将多边形添加到地图小部件中。多边形是地图上在两个经纬度点之间绘制的线。如果您有多个多边形,则每个多边形必须具有唯一的名称。
public function getPolylgones(): array { return [ Polygone::make('polygone') ->latlngs([ [45.51, -122.68], [37.77, -122.43], [34.04, -118.2] ])->options(['color' => 'blue', 'weight' => 5]) ->tooltip('I am a tooltip') ->popup('I am a popup'), ]; }
您可以使用 Leaflet 多边形选项 中列出的选项
多边形操作
$livewire->addPolygone(Polygone::make('polygone-name')->latlngs([...])->options([..])); $livewire->removePolygone('polygone-name'); $livewire->updatePolygone(Polygone::make('polygone-name')->latlngs([...])->options([...]));
矩形
您可以将矩形添加到地图小部件中。如果您有多个矩形,则每个矩形都必须有一个唯一名称。
public function getRectangles(): array { return [ Rectangle::make('rectangle') ->bounds([ [54.559322, -5.767822], [56.1210604, -3.021240] ])->tooltip('rectangle') ->options(['color' => 'red']) ]; }
您可以使用以下链接中列出的选项:Leaflet 矩形选项
矩形操作
$livewire->addRectangle(Polygone::make('rectangle-name')->bounds([...])->options([..])); $livewire->removeRectangle('rectangle-name'); $livewire->updateRectangle(Polygone::make('rectangle-name')->bounds([...])->options([...]));
圆圈
您可以将圆圈添加到地图小部件中。如果您有多个圆圈,则每个圆圈都必须有一个唯一名称。
public function getCircles(): array { return [ Circle::make('circle') ->lat(-15.7942) ->lng(-47.8822) ->options(['radius' => 200000]) ->popup('Hello Brasilia!') ->tooltip('test2'), ]; }
您可以使用以下链接中列出的选项:Leaflet 圆圈选项
矩形操作
$livewire->addCircle(Circle::make('circle-name')->lat(...)->lng(...)->options([..])); $livewire->removeCircle('circle-name'); $livewire->updateCircle(Circle::make('circle-name')->lat(...)->lng(...)->options([...]));