iT邦幫忙

2025 iThome 鐵人賽

DAY 25
0
Mobile Development

《30 天 Flutter:跨平台 AI 行程規劃 App》系列 第 25

Day 25 - 地圖實戰:告別制式地圖,自己的地圖自己定義

  • 分享至 

  • xImage
  •  

在行程規劃 App 裡,地圖不只是背景,而是資訊承載的重要介面。今天要動手實作 Google Map 在 Flutter 中的客製化應用,重點在於「地圖樣式切換」,以及如何根據主題自動呈現不同的外觀。

透過 google_maps_flutterMap Style 功能,我們可以自由調整地圖的顏色、道路樣式、建築顏色,甚至決定哪些元素要顯示或隱藏,讓地圖更符合使用場景。

使用 Map Style 工具

取得 Map Style JSON

Google 提供了 Map Style 工具,能夠直覺地設計地圖樣式,例如道路顏色、建築外觀,最後會產生對應的 JSON。

Map Style JSON 結構

Google Map 的樣式設定是由一組 JSON 陣列控制,每個物件代表一種「元素(featureType)」與「子元素(elementType)」的設定,並透過 stylers 修改顏色、可見性等屬性。

官方文件可參考 Google Maps Styling Reference

範例 JSON

[
  {
    "featureType": "road.local",
    "elementType": "geometry.fill",
    "stylers": [
      { "color": "#ffcc00" },
      { "visibility": "on" }
    ]
  }
]

主要參數說明

  • featureType:要調整的地圖類別,例如:

    • road.local → 小路
    • road.highway → 高速公路
    • poi.park → 公園
    • water → 河流、湖泊
  • elementType:細分類別,例如:

    • geometry.fill → 填滿顏色
    • geometry.stroke → 邊框線條
    • labels.text.fill → 文字顏色
    • labels.icon → 標籤圖示
  • stylers:實際樣式修改,例如:

    • color → HEX 色碼
    • visibilityon / off / simplified
    • lightnesssaturation → 調整亮度、飽和度

在 Flutter 中套用樣式

google_maps_flutter 提供了 style 屬性,只要讀取 JSON 並套用,就能切換地圖外觀。這也意味著我們可以根據 App 的「日夜模式」自動切換不同的地圖主題。

1. 建立樣式檔案

assets/
 └─ maps/
     ├─ light_map.json
     └─ dark_map.json

2. 在 pubspec.yaml 註冊

flutter:
  assets:
    - assets/maps/light_map.json
    - assets/maps/dark_map.json

3. 建立 Provider 載入 JSON

final mapStyleProvider = FutureProvider.family<String, String>((ref, assetPath) async {
  return await rootBundle.loadString(assetPath);
});

4. 在 GoogleMap 套用樣式

class MapScreen extends ConsumerWidget {
  final List<LatLng> locations;

  const MapScreen({super.key, required this.locations});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final isDark = Theme.of(context).brightness == Brightness.dark;

    final assetPath = isDark
        ? 'assets/maps/dark_map.json'
        : 'assets/maps/light_map.json';

    final mapStyleAsync = ref.watch(mapStyleProvider(assetPath));

    return mapStyleAsync.when(
      data: (mapStyle) => GoogleMap(
        initialCameraPosition: CameraPosition(
          target: locations.isNotEmpty ? locations.first : LatLng(25.0340, 121.5645),
          zoom: 14,
        ),
        style: mapStyle,
      ),
      loading: () => const Center(child: CircularProgressIndicator()),
      error: (err, stack) => Center(child: Text('載入失敗: $err')),
    );
  }
}

這樣就能讓地圖依據主題自動切換樣式,實現日夜模式或自訂風格。


今日調整成果

今天的客製化,目標是讓使用者專注於「當日行程」與「交通資訊」,同時保留必要的地理參考。

主要調整方向:

  1. 道路淡化:簡化線條,避免干擾 Marker。
  2. 山區顯示landscape.natural 開啟,方便戶外行程參考。
  3. 水域淡化:低飽和度顯示河流與湖泊,保留定位感。
  4. 交通元素保留:停車場、捷運、公車站等資訊維持顯示。
  5. 城市顯示:台中市、高雄市邊界清晰,利於定位。
  6. 干擾元素隱藏:關閉商家 POI、土地邊界,避免雜訊。
  7. 日夜模式切換:自動根據主題套用不同 JSON,保持一致性。

最終效果是:重點清楚、資訊乾淨、視覺簡潔,更符合行程規劃 App 的需求。

淺色 深色
https://ithelp.ithome.com.tw/upload/images/20250908/20178195je9Rzdr1qU.png https://ithelp.ithome.com.tw/upload/images/20250908/20178195N6m045zr6d.png

上一篇
Day 24 - 地圖實戰:客製地圖 Marker 讓行程一看就懂
系列文
《30 天 Flutter:跨平台 AI 行程規劃 App》25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言