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

如何通过Flutter Map/osm_plugin/sfmap从MySQL获取标记点列表

解决方案:从MySQL导入标记点到指定Flutter地图组件

核心逻辑

MySQL数据无法直接供Flutter调用,需通过后端接口中转:

  1. 后端从MySQL查询标记点数据(含经纬度、标题等字段),返回JSON格式结果
  2. Flutter端请求接口获取数据,解析为本地实体类
  3. 用指定地图组件渲染标记点

步骤1:后端接口实现(以Node.js + Express为例)

假设MySQL表结构:

CREATE TABLE map_markers (
  id INT AUTO_INCREMENT PRIMARY KEY,
  lat DECIMAL(10,8) NOT NULL,
  lng DECIMAL(11,8) NOT NULL,
  title VARCHAR(100) NOT NULL,
  description TEXT
);

后端接口代码:

const express = require('express');
const mysql = require('mysql2');
const app = express();

const db = mysql.createConnection({
  host: 'localhost',
  user: 'your_username',
  password: 'your_password',
  database: 'your_db'
});

db.connect();

app.get('/api/markers', (req, res) => {
  db.query('SELECT * FROM map_markers', (err, results) => {
    if (err) throw err;
    res.json(results);
  });
});

app.listen(3000, () => console.log('Server running on port 3000'));

步骤2:Flutter端数据解析

定义标记点实体类:

class MapMarker {
  final int id;
  final double lat;
  final double lng;
  final String title;
  final String? description;

  MapMarker({
    required this.id,
    required this.lat,
    required this.lng,
    required this.title,
    this.description,
  });

  factory MapMarker.fromJson(Map<String, dynamic> json) {
    return MapMarker(
      id: json['id'],
      lat: double.parse(json['lat'].toString()),
      lng: double.parse(json['lng'].toString()),
      title: json['title'],
      description: json['description'],
    );
  }
}

请求接口获取数据:

import 'package:http/http.dart' as http;
import 'dart:convert';

Future<List<MapMarker>> fetchMarkers() async {
  final response = await http.get(Uri.parse('http://your-server-ip:3000/api/markers'));
  if (response.statusCode == 200) {
    List<dynamic> data = json.decode(response.body);
    return data.map((json) => MapMarker.fromJson(json)).toList();
  } else {
    throw Exception('Failed to load markers');
  }
}

步骤3:各地图组件标记渲染实现

Flutter Map

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

// 在State类中处理数据与渲染
List<MapMarker> markers = [];

@override
void initState() {
  super.initState();
  fetchMarkers().then((data) {
    setState(() {
      markers = data;
    });
  });
}

@override
Widget build(BuildContext context) {
  return FlutterMap(
    options: MapOptions(
      initialCenter: LatLng(30.033333, 31.233334),
      initialZoom: 10,
    ),
    children: [
      TileLayer(
        urlTemplate: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        subdomains: const ['a', 'b', 'c'],
      ),
      MarkerLayer(
        markers: markers.map((marker) => Marker(
          point: LatLng(marker.lat, marker.lng),
          width: 80,
          height: 80,
          child: GestureDetector(
            onTap: () {
              // 标记点击逻辑
            },
            child: Column(
              children: [
                const Icon(Icons.location_pin, color: Colors.red, size: 40),
                Text(marker.title, style: const TextStyle(color: Colors.black)),
              ],
            ),
          ),
        )).toList(),
      ),
    ],
  );
}

osm_plugin

import 'package:osm_plugin/osm_plugin.dart';

// 在State类中处理数据与渲染
MapController mapController = MapController(
  initMapWithUserPosition: false,
  initPosition: GeoPoint(latitude: 30.033333, longitude: 31.233334),
);
List<GeoPoint> geoMarkers = [];

@override
void initState() {
  super.initState();
  fetchMarkers().then((data) {
    setState(() {
      geoMarkers = data.map((m) => GeoPoint(latitude: m.lat, longitude: m.lng)).toList();
    });
    mapController.addMarkerMultiple(geoMarkers);
  });
}

@override
Widget build(BuildContext context) {
  return OSMFlutter(
    controller: mapController,
    trackMyPosition: false,
    initZoom: 10,
    markerOption: MarkerOption(
      defaultMarker: const MarkerIcon(
        icon: Icon(Icons.location_on, color: Colors.red, size: 40),
      ),
    ),
  );
}

sfmap(基于flutter_map适配SF瓦片)

标记渲染逻辑与Flutter Map一致,仅需替换瓦片图层地址:

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

// 替换TileLayer为SF兼容的瓦片地址
TileLayer(
  urlTemplate: 'https://your-sf-tile-server/{z}/{x}/{y}.png',
),
// 标记部分代码与Flutter Map的MarkerLayer完全一致

内容的提问来源于stack exchange,提问作者hamid mido

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:13:24