Flutter地图展示插件flutter_ek_osm_map的使用
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
来替代 center
和 zoom
:
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/
文件夹中的示例应用。
运行步骤:
- 在终端中进入项目目录。
- 执行
ulimit -S -n 2048
。 - 使用
flutter run
启动应用(确保已启动模拟器或设备)。
离线地图下载与缓存
方法 1:使用 NetworkImage
和 NonCachingNetworkTileProvider
虽然名称可能误导,但它旨在防止您期望其缓存。它实际上不会缓存。
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 导入离线地图
此部分说明如何预配置和打包离线地图。有关动态下载和缓存的详细信息,请参阅“动态下载和缓存离线地图”部分。
步骤
- 安装 TileMill。
- 导出地图为
.mbtiles
文件。 - 使用工具将
.mbtiles
解压为/z/x/y.png
格式。 - 将文件移动到
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
更多关于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(),
));