UX Map 用于在 Symfony 应用中构建交互式地图,可使用 Leaflet 或 Google Maps 渲染。整体思路是在 PHP 中构建地图数据模型,在 Twig 中渲染,并通过 Stimulus 控制器扩展交互。
用途
在 Symfony 项目中以 PHP 代码定义地图内容,再由 Twig 输出到页面,避免在模板或前端脚本中硬编码地图结构。渲染器可切换:Leaflet 与 Google Maps 可互换,PHP 代码使用相同的 Map、Marker、Point 等类,仅渲染器专属选项不同。
核心对象
- Map:PHP 对象,持有标记、图形与选项
- Point:纬度 + 经度
- Marker:地图上的图钉,可带 InfoWindow
- Polygon:闭合图形(由 Point 数组构成)
- Polyline:开放线条(由 Point 数组构成)
- Circle:中心 Point + 半径(单位:米)
- InfoWindow:附加到 Marker、Polygon 或 Circle 的弹窗
注意 Point(lat, lng) 的纬度在前,与 Google Maps 约定一致,但与 GeoJSON 的 [lng, lat] 相反,顺序写错会导致标记位置错误。
安装
安装基础包:
composer require symfony/ux-map
然后安装一个渲染器(二选一):
composer require symfony/ux-leaflet-map # Leaflet(免费、开源)
# 或
composer require symfony/ux-google-map # Google Maps(需要 API key)
必须安装渲染器,否则地图无法渲染。基础包只提供 PHP API。
在 PHP 中构建地图
使用 Map、Point、Marker、InfoWindow、Polygon、Polyline、Circle 等类。示例包括:设置 center(new Point(...))、zoom、minZoom、maxZoom;通过 addMarker 添加带 InfoWindow 的标记;标记可设置自定义图标(借助 UX Icons 集成,如 Icon::ux('mdi:tower-eiffel')->width(32)->height(32));通过 extra 参数附加自定义数据(如 ['category' => 'landmark']);通过 addPolygon、addPolyline、addCircle 添加图形;通过 fitBoundsToMarkers() 自动适配边界以显示所有标记。
建议使用 fitBoundsToMarkers() 自动计算中心与缩放;若无标记,地图回退到手动设置的中心与缩放,因此应始终提供这两个默认值。
在 Twig 中渲染
Twig 函数:
{{ ux_map(map, {style: 'height: 400px; width: 100%;'}) }}
可传入自定义属性与 Stimulus 控制器,例如 'data-controller': 'custom-map'、class 等。
Twig 组件(HTML 语法):需要 symfony/ux-twig-component,允许不写 PHP 直接内联定义地图。
<twig:ux:map
:center="[48.8566, 2.3522]"
zoom="12"
:markers='[...]'
:fitBoundsToMarkers="true"
style="height: 400px; width: 100%;"
class="rounded shadow"
/>
配置
在 config/packages/ux_map.yaml 中配置 renderer,使用 '%env(resolve:default::UX_MAP_DSN)%';Google Maps 专属配置中可设置 default_map_id(可选)。
在 .env 中设置渲染器 DSN:
UX_MAP_DSN=leaflet://default
# 或
UX_MAP_DSN=google://GOOGLE_MAPS_API_KEY@default
渲染器选项
Leaflet 选项包括 TileLayer(url、attribution、options 如 minZoom/maxZoom)、zoomControl 及其位置 ZoomControlOptions(ControlPosition::TOP_LEFT)、attributionControl 及其位置等。
Google Maps 选项包括 mapId、gestureHandling、backgroundColor、doubleClickZoom、zoomControlOptions、mapTypeControlOptions(mapTypeIds、position、style)、streetViewControlOptions、fullscreenControlOptions;可通过传入 false 禁用各类控件(zoomControl、mapTypeControl、streetViewControl、fullscreenControl)。
地图事件(Stimulus)
可附加自定义 Stimulus 控制器监听事件,例如 ux:map:connect(detail: {map, markers},地图初始化完成)、ux:map:marker:before-create / after-create、polygon、polyline、circle 的 before-create / after-create、ux:map:info-window:before-create / after-create。在控制器中通过 this.element.addEventListener 绑定。extra 参数中的数据可在事件 detail.definition.extra 中读取。
LiveComponent 集成
使用 ComponentWithMapTrait 使地图具备响应式能力。示例中定义 AsLiveComponent 类,使用 DefaultActionTrait 与 ComponentWithMapTrait,通过 #[LiveProp(writable: true)] 定义可写的 query,并在 instantiateMap() 中根据过滤条件构建 Map 与 Marker。模板中使用 data-model="debounce(300)|query" 绑定搜索输入,并调用 ux_map(this.map, ...) 渲染。
适用场景
需要在 Symfony 后端集中定义地图数据(标记、区域、路线、半径范围、弹窗)并由 Twig 输出的场景;需要切换 Leaflet 与 Google Maps 渲染器的场景;需要地图随组件状态动态更新的场景。
限制与注意事项
- 必须安装渲染器,否则地图不渲染。
- Google Maps 渲染器需要 API key。
- Google Maps 的具体计费方式与价格暂未提供。
- Point 参数顺序为纬度在前,顺序错误会导致标记位置错误。
- 使用 Twig 组件语法需要额外安装 symfony/ux-twig-component。
- fitBoundsToMarkers() 在无标记时会回退到手动设置的中心与缩放。
参考
- API(所有类、方法、选项):references/api.md
- Patterns(常用配方、控制器、动态地图):references/patterns.md
- Gotchas(常见错误、调试):references/gotchas.md