Symfony UX 地图
实验性功能 此组件目前为实验性功能,可能会发生变化,甚至剧烈变化。
Symfony UX Map 是一个 Symfony 扩展包,用于在 Symfony 应用程序中集成交互式地图。它是 Symfony UX 倡议 的一部分。
安装
使用 Composer 和 Symfony Flex 安装此扩展包
1
$ composer require symfony/ux-map
如果您正在使用 WebpackEncore,请安装您的 assets 并重启 Encore (如果您正在使用 AssetMapper,则无需此操作)
1 2
$ npm install --force
$ npm run watch
配置
配置在您的 config/packages/ux_map.yaml
文件中完成
1 2 3 4 5 6 7 8 9
# config/packages/ux_map.yaml
ux_map:
renderer: '%env(resolve:default::UX_MAP_DSN)%'
# Google Maps specific configuration
google_maps:
# Configure the default Map Id (https://developers.google.com/maps/documentation/get-map-id),
# without to manually configure it in each map instance (through "new GoogleOptions(mapId: 'your_map_id')").
default_map_id: null
UX_MAP_DSN
环境变量配置要使用的渲染器。
地图渲染器
Symfony UX Map 扩展包支持多种渲染器。地图渲染器是一种服务,提供在浏览器中渲染地图并与之交互所需的代码和图形资源。
可用的渲染器
UX Map 附带两个渲染器:Google Maps 和 Leaflet。
渲染器 | |
---|---|
Google Maps | 安装: composer require symfony/ux-google-map DSN: UX_MAP_DSN=google://GOOGLE_MAPS_API_KEY@default |
Leaflet | 安装: composer require symfony/ux-leaflet-map DSN: UX_MAP_DSN=leaflet://default |
提示
阅读 Symfony UX Map Leaflet 桥接文档 和 Symfony UX Map Google Maps 桥接文档,了解每个渲染器可用的配置选项。
创建地图
通过调用 new Map()
创建地图。您可以配置中心、缩放级别和添加标记。首先创建一个新的地图实例
1 2 3 4
use Symfony\UX\Map\Map;
// Create a new map instance
$myMap = (new Map());
中心和缩放
您可以使用 center()
和 zoom()
方法设置地图的中心和缩放级别
1 2 3 4 5 6 7 8 9 10 11
use Symfony\UX\Map\Map;
use Symfony\UX\Map\Point;
$myMap
// Explicitly set the center and zoom
->center(new Point(46.903354, 1.888334))
->zoom(6)
// Or automatically fit the bounds to the markers
->fitBoundsToMarkers()
;
添加标记
您可以使用 addMarker()
方法向地图添加标记
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
$myMap
->addMarker(new Marker(
position: new Point(48.8566, 2.3522),
title: 'Paris'
))
// With an info window associated to the marker:
->addMarker(new Marker(
position: new Point(45.7640, 4.8357),
title: 'Lyon',
infoWindow: new InfoWindow(
headerContent: '<b>Lyon</b>',
content: 'The French town in the historic Rhône-Alpes region, located at the junction of the Rhône and Saône rivers.'
)
))
// You can also pass arbitrary data via the `extra` option in both the marker
// and the infoWindow; you can later use this data in your custom Stimulus controllers
->addMarker(new Marker(
position: new Point(45.7740, 4.8351),
extra: [
'icon_mask_url' => 'https://maps.gstatic.com/mapfiles/place_api/icons/v2/tree_pinlet.svg',
],
infoWindow: new InfoWindow(
// ...
extra: [
'num_items' => 3,
'includes_link' => true,
],
),
))
;
从地图中移除元素
可以通过使用 Map::remove*()
方法移除元素,例如 Marker
、Polygon
和 Polyline
实例
1 2 3 4 5 6 7 8 9
// Add elements
$map->addMarker($marker = new Marker(/* ... */));
$map->addPolygon($polygon = new Polygon(/* ... */));
$map->addPolyline($polyline = new Polyline(/* ... */));
// And later, remove those elements
$map->removeMarker($marker);
$map->removePolygon($polygon);
$map->removePolyline($polyline);
不幸的是,如果您无法存储元素实例,您仍然可以通过传递标识符字符串来删除它们
1 2 3 4 5 6 7 8 9 10
$map = new Map(/* ... */);
// Add elements
$map->addMarker(new Marker(id: 'my-marker', /* ... */));
$map->addPolygon(new Polygon(id: 'my-polygon', /* ... */));
$map->addPolyline(new Polyline(id: 'my-marker', /* ... */));
// And later, remove those elements
$map->removeMarker('my-marker');
$map->removePolygon('my-polygon');
$map->removePolyline('my-marker');
添加多边形
您还可以添加多边形(Polygons),它表示由一系列 Point
实例封闭的区域
1 2 3 4 5 6 7 8 9 10 11
$myMap->addPolygon(new Polygon(
points: [
new Point(48.8566, 2.3522),
new Point(45.7640, 4.8357),
new Point(43.2965, 5.3698),
new Point(44.8378, -0.5792),
],
infoWindow: new InfoWindow(
content: 'Paris, Lyon, Marseille, Bordeaux',
),
));
添加折线
您可以添加折线(Polylines),它表示由一系列 Point
实例组成的路径
1 2 3 4 5 6 7 8 9 10 11
$myMap->addPolyline(new Polyline(
points: [
new Point(48.8566, 2.3522),
new Point(45.7640, 4.8357),
new Point(43.2965, 5.3698),
new Point(44.8378, -0.5792),
],
infoWindow: new InfoWindow(
content: 'A line passing through Paris, Lyon, Marseille, Bordeaux',
),
));
渲染地图
要在您的 Twig 模板中渲染地图,请使用 ux_map
Twig 函数,例如
为了可见,地图必须具有定义的高度
1
{{ ux_map(my_map, { style: 'height: 300px' }) }}
您也可以添加自定义 HTML 属性
1
{{ ux_map(my_map, { style: 'height: 300px', id: 'events-map', class: 'mb-3' }) }}
Twig 函数 ux_map()
ux_map()
Twig 函数允许您在 Twig 模板中创建和渲染地图。该函数接受与 Map
类相同的参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
{{ ux_map(
center: [51.5074, 0.1278],
zoom: 3,
markers: [
{ position: [51.5074, 0.1278], title: 'London' },
{ position: [48.8566, 2.3522], title: 'Paris' },
{
position: [40.7128, -74.0060],
title: 'New York',
infoWindow: { content: 'Welcome to <b>New York</b>' }
},
],
attributes: {
class: 'foo',
style: 'height: 800px; width: 100%; border: 4px solid red; margin-block: 10vh;',
}
) }}
Twig 组件 <twig:ux:map />
或者,您可以使用 <twig:ux:map />
组件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<twig:ux:map
center="[51.5074, 0.1278]"
zoom="3"
markers='[
{"position": [51.5074, 0.1278], "title": "London"},
{"position": [48.8566, 2.3522], "title": "Paris"},
{
"position": [40.7128, -74.0060],
"title": "New York",
"infoWindow": {"content": "Welcome to <b>New York</b>"}
}
]'
class="foo"
style="height: 800px; width: 100%; border: 4px solid red; margin-block: 10vh;"
/>
<twig:ux:map />
组件需要 Twig Component 扩展包。
1
$ composer require symfony/ux-twig-component
与地图交互
Symfony UX Map 允许您使用自定义 Stimulus 控制器扩展其默认行为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
// assets/controllers/mymap_controller.js
import { Controller } from '@hotwired/stimulus';
export default class extends Controller {
connect() {
this.element.addEventListener('ux:map:pre-connect', this._onPreConnect);
this.element.addEventListener('ux:map:connect', this._onConnect);
this.element.addEventListener('ux:map:marker:before-create', this._onMarkerBeforeCreate);
this.element.addEventListener('ux:map:marker:after-create', this._onMarkerAfterCreate);
this.element.addEventListener('ux:map:info-window:before-create', this._onInfoWindowBeforeCreate);
this.element.addEventListener('ux:map:info-window:after-create', this._onInfoWindowAfterCreate);
}
disconnect() {
// You should always remove listeners when the controller is disconnected to avoid side effects
this.element.removeEventListener('ux:map:pre-connect', this._onPreConnect);
this.element.removeEventListener('ux:map:connect', this._onConnect);
this.element.removeEventListener('ux:map:marker:before-create', this._onMarkerBeforeCreate);
this.element.removeEventListener('ux:map:marker:after-create', this._onMarkerAfterCreate);
this.element.removeEventListener('ux:map:info-window:before-create', this._onInfoWindowBeforeCreate);
this.element.removeEventListener('ux:map:info-window:after-create', this._onInfoWindowAfterCreate);
}
_onPreConnect(event) {
// The map is not created yet
// You can use this event to configure the map before it is created
console.log(event.detail.options);
}
_onConnect(event) {
// The map, markers and infoWindows are created
// The instances depend on the renderer you are using
console.log(event.detail.map);
console.log(event.detail.markers);
console.log(event.detail.infoWindows);
}
_onMarkerBeforeCreate(event) {
// The marker is not created yet
// You can use this event to configure the marker before it is created
console.log(event.detail.definition);
}
_onMarkerAfterCreate(event) {
// The marker is created
// The instance depends on the renderer you are using
console.log(event.detail.marker);
}
_onInfoWindowBeforeCreate(event) {
// The infoWindow is not created yet
// You can use this event to configure the infoWindow before it is created
console.log(event.detail.definition);
// The associated marker instance is also available
console.log(event.detail.marker);
}
_onInfoWindowAfterCreate(event) {
// The infoWindow is created
// The instance depends on the renderer you are using
console.log(event.detail.infoWindow);
// The associated marker instance is also available
console.log(event.detail.marker);
}
}
然后,您可以在您的模板中使用此控制器
1
{{ ux_map(my_map, { 'data-controller': 'mymap', style: 'height: 300px' }) }}
提示
阅读 Symfony UX Map Leaflet 桥接文档 和 Symfony UX Map Google Maps 桥接文档,了解自定义标记所需的准确代码。
与 Live 组件一起使用
2.22
在 Live 组件内部渲染地图并与之交互的功能在 Map 2.22 中添加。
要在 Live 组件内部使用地图,您需要使用 ComponentWithMapTrait
trait 并实现 instantiateMap
方法以返回一个 Map
实例。
您可以使用 LiveAction
属性与地图交互
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
namespace App\Twig\Components;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\DefaultActionTrait;
use Symfony\UX\Map\InfoWindow;
use Symfony\UX\Map\Live\ComponentWithMapTrait;
use Symfony\UX\Map\Map;
use Symfony\UX\Map\Marker;
use Symfony\UX\Map\Point;
#[AsLiveComponent]
final class MapLivePlayground
{
use DefaultActionTrait;
use ComponentWithMapTrait;
protected function instantiateMap(): Map
{
return (new Map())
->center(new Point(48.8566, 2.3522))
->zoom(7)
->addMarker(new Marker(position: new Point(48.8566, 2.3522), title: 'Paris', infoWindow: new InfoWindow('Paris')))
->addMarker(new Marker(position: new Point(45.75, 4.85), title: 'Lyon', infoWindow: new InfoWindow('Lyon')))
;
}
}
然后,您可以使用 ux_map()
在您的组件模板中渲染地图
1 2 3
<div{{ attributes }}>
{{ ux_map(map, {style: 'height: 300px'}) }}
</div>
然后,您可以定义 Live Actions 以从客户端与地图交互。您可以使用 getMap()
方法检索地图实例,并更改地图中心、缩放级别、添加标记等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#[LiveAction]
public function doSomething(): void
{
// Change the map center
$this->getMap()->center(new Point(45.7640, 4.8357));
// Change the map zoom
$this->getMap()->zoom(6);
// Add a new marker
$this->getMap()->addMarker(new Marker(position: new Point(43.2965, 5.3698), title: 'Marseille', infoWindow: new InfoWindow('Marseille')));
// Add a new polygon
$this->getMap()->addPolygon(new Polygon(points: [
new Point(48.8566, 2.3522),
new Point(45.7640, 4.8357),
new Point(43.2965, 5.3698),
new Point(44.8378, -0.5792),
], infoWindow: new InfoWindow('Paris, Lyon, Marseille, Bordeaux')));
}
1 2 3 4 5 6 7 8 9 10 11
<div{{ attributes.defaults() }}>
{{ ux_map(map, { style: 'height: 300px' }) }}
<button
type="button"
data-action="live#action"
data-live-action-param="doSomething"
>
Do something with the map
</button>
</div>
向后兼容性承诺
此扩展包旨在遵循与 Symfony 框架相同的向后兼容性承诺:http://symfony.ac.cn/doc/current/contributing/code/bc.html