You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为flutter_map创建适配Mapbox的3D地球投影Crs类并保留标记?

问题描述

我正在使用flutter_map插件搭配MapBox样式,尝试在应用中显示3D地球视图:

Globe

以下是我当前的FlutterMap代码:

FlutterMap(
                  mapController: controller,
                  options: MapOptions(
                    maxZoom: 19,
                    zoom: latestZoom,
                    center: userLocation ?? LatLng(lat, lon),
                  ),
                  children: [
                    TileLayer(
                      urlTemplate:   "https://api.mapbox.com/styles/v1/{username}/{mapStyleId}/tiles/256/{z}/{x}/{y}@2x?access_token={accessToken}",
                      additionalOptions: const {
                        'username': <username>,
                        'mapStyleId': <style.id>,
                        'accessToken': <access.token>,
                      },
                      maxZoom: 19,
                    ),

                      MarkerLayer(
                        markers: [
                          <markers>
                        ],
                      ),
                  ],
                ),

经研究我发现,MapOptions中的“crs”属性负责控制地图视图,正确的投影与变换可实现3D地球视图效果。

请问如何找到或创建带有地球投影的合适Crs类,以实现3D地球视图的同时,保留标记的显示能力?


解决方案

1. 使用内置EPSG4326球面投影

flutter_map内置了Epsg4326类,它基于WGS84球面投影,是实现地球视图的直接选择。只需在MapOptions中指定该CRS即可:

import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';

FlutterMap(
  mapController: controller,
  options: MapOptions(
    crs: const Epsg4326(), // 启用球面投影
    maxZoom: 19,
    zoom: latestZoom,
    center: userLocation ?? LatLng(lat, lon),
  ),
  // 其余代码保持不变
)

2. 适配MapBox瓦片资源

MapBox默认瓦片多基于Web墨卡托(EPSG3857),若要匹配EPSG4326投影,需使用MapBox的地球专用瓦片URL(替换为你的访问令牌):

TileLayer(
  urlTemplate: "https://api.mapbox.com/v4/mapbox.globe/{z}/{x}/{y}.webp?access_token={accessToken}",
  additionalOptions: const {
    'accessToken': <access.token>,
  },
  maxZoom: 19,
),

也可以在MapBox Studio中创建支持WGS84投影的自定义样式,使用对应样式的瓦片URL。

3. 确保标记正常显示

MarkerLayer会自动适配当前CRS的坐标转换逻辑,只要你的标记使用LatLng(基于WGS84坐标系),切换到EPSG4326投影后,标记会自动正确映射到地球视图上,无需修改标记代码。

4. 自定义CRS(按需)

如果需要更定制化的地球投影效果,可以继承CRS类实现自定义逻辑:

class CustomGlobeCRS extends CRS {
  const CustomGlobeCRS()
      : super(
          code: 'EPSG:4326',
          projection: const GeographicalProjection(),
          transformation: const Transformation(0.5 / pi, 0.5, -0.5 / pi, 0.5),
        );

  // 可重写scale、latLngToPoint等方法,实现特殊投影变换
}

之后在MapOptions中替换为这个自定义CRS即可。

内容的提问来源于stack exchange,提问作者Ahmed Eltabbal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 12:35:13