Flutter矢量地图展示插件vector_map的使用

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

Flutter矢量地图展示插件vector_map的使用

简介

vector_map 是一个用于Flutter的矢量地图展示插件,支持GeoJSON格式的地图数据,具有多分辨率、高可定制性、高性能和交互性强等特点。它完全基于Flutter实现,不依赖于WebView或JavaScript。

主要功能

  • 兼容GeoJSON
  • 多分辨率与几何简化
  • 高度可定制
  • 高性能
  • 交互性强
  • 纯Flutter实现(无WebView/JavaScript)

使用示例

加载GeoJSON数据

首先,我们需要从字符串中读取GeoJSON数据并创建地图数据源:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:vector_map/vector_map.dart';

class ExampleWidget extends StatefulWidget {
  @override
  State<ExampleWidget> createState() => ExampleState();
}

class ExampleState extends State<ExampleWidget> {
  VectorMapController? _controller;

  @override
  void initState() {
    super.initState();
    _loadDataSources();
  }

  void _loadDataSources() async {
    String geoJson = await rootBundle.loadString('assets/polygons.json');
    MapDataSource dataSource = await MapDataSource.geoJson(geoJson: geoJson);
    MapLayer layer = MapLayer(dataSource: dataSource);

    setState(() {
      _controller = VectorMapController(layers: [layer]);
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_controller == null) {
      return Center(child: Text('Loading...'));
    }

    VectorMap map = VectorMap(controller: _controller!);

    return MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(scaffoldBackgroundColor: Colors.blue[800]!),
        home: Scaffold(
            body: SafeArea(
                child: Padding(child: map, padding: EdgeInsets.all(8)))));
  }
}

创建地图小部件

接下来,我们创建一个VectorMap小部件,并将其添加到应用中:

@override
Widget build(BuildContext context) {
  if (_controller == null) {
    return Center(child: Text('Loading...'));
  }

  VectorMap map = VectorMap(controller: _controller!);

  return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(scaffoldBackgroundColor: Colors.blue[800]!),
      home: Scaffold(
          body: SafeArea(
              child: Padding(child: map, padding: EdgeInsets.all(8)))));
}

地图主题设置

可以通过设置不同的主题来改变地图的外观:

MapLayer layer = MapLayer(
    dataSource: dataSource,
    theme: MapTheme(color: Colors.yellow, contourColor: Colors.red));

标签显示

可以控制标签的可见性和样式:

MapLayer layer = MapLayer(
    dataSource: dataSource,
    theme: MapTheme(
        labelVisibility: (feature) => true,
        labelStyleBuilder: (feature, featureColor, labelColor) {
          if (feature.label == 'Darwin') {
            return TextStyle(
              color: labelColor,
              fontWeight: FontWeight.bold,
              fontSize: 11,
            );
          }
          return TextStyle(
            color: labelColor,
            fontSize: 11,
          );
        }));

添加按钮进行操作

为了方便用户操作,我们可以添加一些按钮来调整地图视图:

Widget _buildFitButton() {
  return ElevatedButton(child: Text('Fit'), onPressed: _onFit);
}

void _onFit() {
  _controller?.fit();
}

Widget _buildModeButton() {
  return ElevatedButton(child: Text('Change mode'), onPressed: _onMode);
}

void _onMode() {
  VectorMapMode mode = _controller!.mode == VectorMapMode.autoFit
      ? VectorMapMode.panAndZoom
      : VectorMapMode.autoFit;
  _controller!.mode = mode;
}

Widget _buildZoomInButton() {
  return ElevatedButton(child: Text('Zoom in'), onPressed: _onZoomIn);
}

void _onZoomIn() {
  _controller!.zoomOnCenter(true);
}

Widget _buildZoomOutButton() {
  return ElevatedButton(child: Text('Zoom out'), onPressed: _onZoomOut);
}

void _onZoomOut() {
  _controller!.zoomOnCenter(false);
}

完整示例

将上述代码整合起来,形成一个完整的示例:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:vector_map/vector_map.dart';

void main() {
  runApp(ExampleWidget());
}

class ExampleWidget extends StatefulWidget {
  @override
  State<ExampleWidget> createState() => ExampleState();
}

class ExampleState extends State<ExampleWidget> {
  VectorMapController? _controller;

  @override
  void initState() {
    super.initState();
    _loadDataSources();
  }

  void _loadDataSources() async {
    String geoJson = await rootBundle.loadString('assets/polygons.json');
    MapDataSource dataSource = await MapDataSource.geoJson(geoJson: geoJson);
    MapLayer layer = MapLayer(dataSource: dataSource);

    setState(() {
      _controller = VectorMapController(layers: [layer]);
    });
  }

  @override
  Widget build(BuildContext context) {
    Widget? content;
    if (_controller != null) {
      VectorMap map = VectorMap(controller: _controller!);

      Widget buttons = SingleChildScrollView(
          child: Row(children: [
        _buildFitButton(),
        SizedBox(width: 8),
        _buildModeButton(),
        SizedBox(width: 8),
        _buildZoomInButton(),
        SizedBox(width: 8),
        _buildZoomOutButton()
      ]));

      Widget buttonsAndMap = Column(children: [
        Padding(child: buttons, padding: EdgeInsets.only(bottom: 8)),
        Expanded(child: map)
      ]);

      content = buttonsAndMap;
    } else {
      content = Center(child: Text('Loading...'));
    }

    return MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(scaffoldBackgroundColor: Colors.blue[800]!),
        home: Scaffold(
            body: SafeArea(
                child: Padding(child: content, padding: EdgeInsets.all(8)))));
  }

  Widget _buildFitButton() {
    return ElevatedButton(child: Text('Fit'), onPressed: _onFit);
  }

  void _onFit() {
    _controller?.fit();
  }

  Widget _buildModeButton() {
    return ElevatedButton(child: Text('Change mode'), onPressed: _onMode);
  }

  void _onMode() {
    VectorMapMode mode = _controller!.mode == VectorMapMode.autoFit
        ? VectorMapMode.panAndZoom
        : VectorMapMode.autoFit;
    _controller!.mode = mode;
  }

  Widget _buildZoomInButton() {
    return ElevatedButton(child: Text('Zoom in'), onPressed: _onZoomIn);
  }

  void _onZoomIn() {
    _controller!.zoomOnCenter(true);
  }

  Widget _buildZoomOutButton() {
    return ElevatedButton(child: Text('Zoom out'), onPressed: _onZoomOut);
  }

  void _onZoomOut() {
    _controller!.zoomOnCenter(false);
  }
}

通过这个完整的示例,您可以快速上手并使用vector_map插件来展示和操作矢量地图。


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

1 回复

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


当然,下面是一个关于如何使用Flutter的vector_map插件来展示矢量地图的示例代码。vector_map插件允许你在Flutter应用中嵌入和显示矢量地图。由于vector_map并非一个广为人知的官方或流行插件,以下示例将基于一个假设的插件接口和常见的地图展示逻辑来构建。如果你使用的是某个具体的第三方库,请查阅其官方文档以获取准确的使用方法和API。

首先,确保你已经在pubspec.yaml文件中添加了vector_map依赖(这里以假设的插件名为例):

dependencies:
  flutter:
    sdk: flutter
  vector_map: ^x.y.z  # 替换为实际的版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter应用中,你可以按照以下步骤来展示矢量地图:

  1. 导入插件
import 'package:flutter/material.dart';
import 'package:vector_map/vector_map.dart'; // 假设的包路径
  1. 定义地图数据:通常,矢量地图数据以GeoJSON等格式提供。这里我们假设有一个GeoJSON字符串作为地图数据。
const String geoJsonData = '''
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [-100.0, 40.0], [-104.0, 40.0], [-104.0, 36.0], [-100.0, 36.0], [-100.0, 40.0]
          ]
        ]
      },
      "properties": {
        "name": "Sample Polygon"
      }
    }
  ]
}
''';
  1. 创建地图组件
class MapScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Vector Map Example'),
      ),
      body: Center(
        child: VectorMap(
          geoJsonData: geoJsonData,
          style: MapStyle(
            polygonFillColor: Colors.blue.withOpacity(0.5),
            polygonStrokeColor: Colors.blue,
            polygonStrokeWidth: 2.0,
          ),
          onTap: (feature) {
            // 处理地图上的点击事件
            print('Feature tapped: ${feature.properties['name']}');
          },
        ),
      ),
    );
  }
}
  1. 在应用中使用地图组件
void main() {
  runApp(MaterialApp(
    home: MapScreen(),
  ));
}

注意

  • 上述代码是一个简化的示例,实际使用中VectorMapMapStyle等类的API可能会有所不同。
  • geoJsonData应该是一个有效的GeoJSON字符串,这里仅提供了一个简单的多边形示例。
  • onTap回调是一个假设的接口,用于处理地图上的点击事件,具体实现取决于vector_map插件的实际功能。

由于vector_map并非一个公认的Flutter插件名,如果这是一个特定第三方库,请查阅其官方文档和示例代码来获取准确的实现方法。如果这是一个自定义插件或你正在寻找一个具体的库,请提供更多细节以便给出更精确的指导。

回到顶部