Flutter地图展示插件flutter_ek_osm_map的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter地图展示插件flutter_ek_osm_map的使用

插件简介

flutter_ek_osm_map 是一个用于 Flutter 应用的地图展示插件,并支持多边形点击功能。通过该插件,您可以轻松地在应用中集成地图功能。


安装

pubspec.yaml 文件中添加以下依赖:

dependencies:
  flutter_ek_osm_map: any # 或者使用最新版本

Android 配置

确保您的应用具有网络权限。在 <project root>/android/app/src/main/AndroidManifest.xml 中添加以下权限:

<uses-permission android:name="android.permission.INTERNET" />

使用方法

基本配置

使用 MapOptions 和图层选项来配置地图:

import 'package:flutter/material.dart';
import 'package:flutter_ek_osm_map/flutter_ek_osm_map.dart';

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FlutterMap(
      options: MapOptions(
        center: LatLng(51.5, -0.09), // 地图中心点
        zoom: 13.0, // 缩放级别
      ),
      layers: [
        TileLayerOptions(
          urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", // 图块URL模板
          subdomains: ['a', 'b', 'c'], // 子域
          attributionBuilder: (_) {
            return Text("© OpenStreetMap contributors"); // 地图版权信息
          },
        ),
        MarkerLayerOptions(
          markers: [
            Marker(
              width: 80.0, // 标记宽度
              height: 80.0, // 标记高度
              point: LatLng(51.5, -0.09), // 标记位置
              builder: (ctx) => Container(
                child: FlutterLogo(), // 标记内容
              ),
            ),
          ],
        ),
      ],
    );
  }
}

指定边界范围

可以通过指定 bounds 来替代 centerzoom

MapOptions(
  bounds: LatLngBounds(
    LatLng(58.8, 6.1), // 左下角坐标
    LatLng(59, 6.2), // 右上角坐标
  ),
  boundsOptions: FitBoundsOptions(
    padding: EdgeInsets.all(8.0), // 边界填充
  ),
)

使用 Azure Maps 提供商

要配置 Azure Maps,请使用以下 MapOptions 和图层选项:

Widget build(BuildContext context) {
  return FlutterMap(
    options: MapOptions(
      center: LatLng(51.5, -0.09),
      zoom: 13.0,
    ),
    layers: [
      TileLayerOptions(
        urlTemplate: "https://atlas.microsoft.com/map/tile/png?api-version=1&layer=basic&style=main&tileSize=256&view=Auto&zoom={z}&x={x}&y={y}&subscription-key={subscriptionKey}",
        additionalOptions: {
          'subscriptionKey': '<YOUR_AZURE_MAPS_SUBSCRIPTION_KEY>', // 替换为您的订阅密钥
        },
      ),
      MarkerLayerOptions(
        markers: [
          Marker(
            width: 80.0,
            height: 80.0,
            point: LatLng(51.5, -0.09),
            builder: (ctx) => Container(
              child: FlutterLogo(),
            ),
          ),
        ],
      ),
    ],
  );
}

请确保您已在 Azure 上注册账户并获取订阅密钥。


使用 OpenStreetMap 提供商

配置 OpenStreetMap 地图:

Widget build(BuildContext context) {
  return FlutterMap(
    options: MapOptions(
      center: LatLng(51.5, -0.09),
      zoom: 13.0,
    ),
    layers: [
      TileLayerOptions(
        urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
        subdomains: ['a', 'b', 'c'],
      ),
      MarkerLayerOptions(
        markers: [
          Marker(
            width: 80.0,
            height: 80.0,
            point: LatLng(51.5, -0.09),
            builder: (ctx) => Container(
              child: FlutterLogo(),
            ),
          ),
        ],
      ),
    ],
  );
}

自定义图层

推荐使用新的方式创建图层(兼容旧版本):

Widget build(BuildContext context) {
  return FlutterMap(
    options: MapOptions(
      center: LatLng(51.5, -0.09),
      zoom: 13.0,
    ),
    layers: [
      MarkerLayerOptions(
        markers: [
          Marker(
            width: 80.0,
            height: 80.0,
            point: LatLng(51.5, -0.09),
            builder: (ctx) => Container(
              child: FlutterLogo(),
            ),
          ),
        ],
      ),
    ],
    children: <Widget>[
      TileLayerWidget(
        options: TileLayerOptions(
          urlTemplate: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
          subdomains: ['a', 'b', 'c'],
        ),
      ),
      MarkerLayerWidget(
        options: MarkerLayerOptions(
          markers: [
            Marker(
              width: 80.0,
              height: 80.0,
              point: LatLng(51.5, -0.09),
              builder: (ctx) => Container(
                child: FlutterLogo(),
              ),
            ),
          ],
        ),
      ),
    ],
  );
}

自定义 CRS

默认情况下,flutter_ek_osm_map 支持 WGS84 (EPSG:4326) 和 Google Mercator (EPSG:3857) 投影。若需要其他投影,可以使用 proj4dart 包:

var resolutions = [32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128];
var maxZoom = (resolutions.length - 1).toDouble();

var epsg3413CRS = Proj4Crs.fromFactory(
  code: 'EPSG:3413',
  proj4Projection: proj4.Projection.add('EPSG:3413', '+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'),
  resolutions: resolutions,
);

// 使用自定义 CRS
child: FlutterMap(
  options: MapOptions(
    crs: epsg3413CRS,
    center: LatLng(65.05166470332148, -19.171744826394896),
    maxZoom: maxZoom,
  ),
  layers: [
    TileLayerOptions(
      wmsOptions: WMSTileLayerOptions(
        crs: epsg3413CRS,
        baseUrl: 'https://www.gebco.net/data_and_products/gebco_web_services/north_polar_view_wms/mapserv?',
        layers: ['gebco_north_polar_view'],
      ),
    ),
  ],
);

更多详情请参阅 custom CRS README


示例运行

查看 example/ 文件夹中的示例应用。

运行步骤:

  1. 在终端中进入项目目录。
  2. 执行 ulimit -S -n 2048
  3. 使用 flutter run 启动应用(确保已启动模拟器或设备)。

离线地图下载与缓存

方法 1:使用 NetworkImageNonCachingNetworkTileProvider

虽然名称可能误导,但它旨在防止您期望其缓存。它实际上不会缓存。

TileLayerOptions(
  urlTemplate: 'https://example.com/{x}/{y}/{z}',
  tileProvider: NonCachingNetworkTileProvider(),
)

方法 2:使用 cached_network_image 依赖

此依赖项提供了缓存图像到磁盘的功能。首先在 pubspec.yaml 中添加:

dependencies:
  cached_network_image: ^3.0.0

然后创建自定义提供程序:

import 'package:cached_network_image/cached_network_image.dart';

class CachedTileProvider extends TileProvider {
  const CachedTileProvider();

  @override
  ImageProvider getImage(Coords<num> coords, TileLayerOptions options) {
    return CachedNetworkImageProvider(
      getTileUrl(coords, options),
      // 设置缓存选项
    );
  }
}

// 添加到 TileLayerOptions
TileLayerOptions(
  urlTemplate: 'https://example.com/{x}/{y}/{z}',
  tileProvider: const CachedTileProvider(),
)

使用 TileMill 导入离线地图

此部分说明如何预配置和打包离线地图。有关动态下载和缓存的详细信息,请参阅“动态下载和缓存离线地图”部分。

步骤

  1. 安装 TileMill
  2. 导出地图为 .mbtiles 文件。
  3. 使用工具将 .mbtiles 解压为 /z/x/y.png 格式。
  4. 将文件移动到 assets 文件夹,并更新 pubspec.yaml
Widget build(ctx) {
  return FlutterMap(
    options: MapOptions(
      center: LatLng(56.704173, 11.543808),
      zoom: 13.0,
      swPanBoundary: LatLng(56.6877, 11.5089),
      nePanBoundary: LatLng(56.7378, 11.6644),
    ),
    layers: [
      TileLayerOptions(
        tileProvider: AssetTileProvider(),
        urlTemplate: "assets/offlineMap/{z}/{x}/{y}.png",
      ),
    ],
  );
}

更多关于Flutter地图展示插件flutter_ek_osm_map的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter地图展示插件flutter_ek_osm_map的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


flutter_ek_osm_map 是一个基于 OpenStreetMap 的 Flutter 插件,用于在 Flutter 应用中展示地图。它提供了丰富的功能,如地图展示、标记、路线绘制等。以下是使用 flutter_ek_osm_map 的基本步骤和示例代码。

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 flutter_ek_osm_map 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_ek_osm_map: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 导入包

在 Dart 文件中导入 flutter_ek_osm_map 包:

import 'package:flutter_ek_osm_map/flutter_ek_osm_map.dart';

3. 基本使用

3.1 展示地图

class MapScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('OSM Map'),
      ),
      body: OSMFlutter(
        controller: MapController(
          initPosition: GeoPoint(latitude: 37.7749, longitude: -122.4194), // 初始位置(旧金山)
        ),
      ),
    );
  }
}

3.2 添加标记

class MapScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('OSM Map with Marker'),
      ),
      body: OSMFlutter(
        controller: MapController(
          initPosition: GeoPoint(latitude: 37.7749, longitude: -122.4194),
        ),
        markers: [
          Marker(
            point: GeoPoint(latitude: 37.7749, longitude: -122.4194),
            icon: MarkerIcon(
              assetPath: 'assets/marker.png', // 标记图标路径
            ),
          ),
        ],
      ),
    );
  }
}

3.3 绘制路线

class MapScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('OSM Map with Route'),
      ),
      body: OSMFlutter(
        controller: MapController(
          initPosition: GeoPoint(latitude: 37.7749, longitude: -122.4194),
        ),
        polylines: [
          Polyline(
            points: [
              GeoPoint(latitude: 37.7749, longitude: -122.4194),
              GeoPoint(latitude: 34.0522, longitude: -118.2437),
            ],
            color: Colors.blue,
            width: 5.0,
          ),
        ],
      ),
    );
  }
}

4. 高级功能

flutter_ek_osm_map 还支持更多高级功能,如:

  • 自定义地图样式:通过 MapController 设置自定义地图样式。
  • 交互事件:监听地图的点击、拖动等事件。
  • 地理位置:获取用户当前位置并在地图上显示。

5. 示例代码

以下是一个完整的示例,展示了如何在地图上添加标记和绘制路线:

import 'package:flutter/material.dart';
import 'package:flutter_ek_osm_map/flutter_ek_osm_map.dart';

class MapScreen extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('OSM Map Example'),
      ),
      body: OSMFlutter(
        controller: MapController(
          initPosition: GeoPoint(latitude: 37.7749, longitude: -122.4194),
        ),
        markers: [
          Marker(
            point: GeoPoint(latitude: 37.7749, longitude: -122.4194),
            icon: MarkerIcon(
              assetPath: 'assets/marker.png',
            ),
          ),
          Marker(
            point: GeoPoint(latitude: 34.0522, longitude: -118.2437),
            icon: MarkerIcon(
              assetPath: 'assets/marker.png',
            ),
          ),
        ],
        polylines: [
          Polyline(
            points: [
              GeoPoint(latitude: 37.7749, longitude: -122.4194),
              GeoPoint(latitude: 34.0522, longitude: -118.2437),
            ],
            color: Colors.blue,
            width: 5.0,
          ),
        ],
      ),
    );
  }
}

void main() => runApp(MaterialApp(
  home: MapScreen(),
));
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!