Loading...
Loading...
Compare original and translation side by side
SfMapsThemeSfMapsTheme| Feature | MapShapeLayer | MapTileLayer |
|---|---|---|
| Data Source | GeoJSON files | Web tile services (URLs) |
| Offline Support | ✅ Yes (embedded GeoJSON) | ❌ Requires internet |
| Data Binding | ✅ Full support | ❌ Limited to markers |
| Choropleth Maps | ✅ Yes | ❌ No |
| Bubble Visualization | ✅ Yes | ❌ No |
| Data Labels | ✅ Yes | ❌ No |
| Shape Selection | ✅ Yes | ❌ No |
| Color Mapping | ✅ Yes | ❌ No |
| Legend | ✅ Yes | ❌ No |
| Markers | ✅ Yes | ✅ Yes |
| Zoom & Pan | ✅ Yes | ✅ Yes |
| Street Maps | ❌ No | ✅ Yes |
| Sublayers | ✅ Yes | ✅ Yes |
| Vector Layers | ✅ Yes (arc, circle, line, etc.) | ✅ Yes (arc, circle, line, etc.) |
| Tooltips | ✅ Yes (shapes & bubbles) | ❌ Limited |
| Real-world Detail | ❌ Limited | ✅ High detail |
| 功能 | MapShapeLayer | MapTileLayer |
|---|---|---|
| 数据源 | GeoJSON文件 | web瓦片服务(URL) |
| 离线支持 | ✅ 支持(内嵌GeoJSON) | ❌ 需要联网 |
| 数据绑定 | ✅ 完全支持 | ❌ 仅支持标记 |
| 分级统计图 | ✅ 支持 | ❌ 不支持 |
| 气泡可视化 | ✅ 支持 | ❌ 不支持 |
| 数据标签 | ✅ 支持 | ❌ 不支持 |
| 形状选择 | ✅ 支持 | ❌ 不支持 |
| 颜色映射 | ✅ 支持 | ❌ 不支持 |
| 图例 | ✅ 支持 | ❌ 不支持 |
| 标记 | ✅ 支持 | ✅ 支持 |
| 缩放平移 | ✅ 支持 | ✅ 支持 |
| 街道地图 | ❌ 不支持 | ✅ 支持 |
| 子图层 | ✅ 支持 | ✅ 支持 |
| 矢量图层 | ✅ 支持(弧线、圆形、线条等) | ✅ 支持(弧线、圆形、线条等) |
| 提示框 | ✅ 支持(形状和气泡) | ❌ 支持有限 |
| 真实世界细节 | ❌ 有限 | ✅ 高细节 |
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_maps/maps.dart';
class MyShapeMap extends StatefulWidget {
_MyShapeMapState createState() => _MyShapeMapState();
}
class _MyShapeMapState extends State<MyShapeMap> {
late MapShapeSource _dataSource;
void initState() {
super.initState();
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('World Map')),
body: Padding(
padding: EdgeInsets.all(15),
child: SfMaps(
layers: [
MapShapeLayer(
source: _dataSource,
color: Colors.blue[100],
strokeColor: Colors.blue,
strokeWidth: 0.5,
),
],
),
),
);
}
}import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_maps/maps.dart';
class MyShapeMap extends StatefulWidget {
_MyShapeMapState createState() => _MyShapeMapState();
}
class _MyShapeMapState extends State<MyShapeMap> {
late MapShapeSource _dataSource;
void initState() {
super.initState();
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('World Map')),
body: Padding(
padding: EdgeInsets.all(15),
child: SfMaps(
layers: [
MapShapeLayer(
source: _dataSource,
color: Colors.blue[100],
strokeColor: Colors.blue,
strokeWidth: 0.5,
),
],
),
),
);
}
}import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_maps/maps.dart';
class MyTileMap extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('OpenStreetMap')),
body: SfMaps(
layers: [
MapTileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
initialFocalLatLng: MapLatLng(27.1751, 78.0421),
initialZoomLevel: 5,
),
],
),
);
}
}import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_maps/maps.dart';
class MyTileMap extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('OpenStreetMap')),
body: SfMaps(
layers: [
MapTileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
initialFocalLatLng: MapLatLng(27.1751, 78.0421),
initialZoomLevel: 5,
),
],
),
);
}
}class ChoroplethMap extends StatefulWidget {
_ChoroplethMapState createState() => _ChoroplethMapState();
}
class _ChoroplethMapState extends State<ChoroplethMap> {
late List<Model> _data;
late MapShapeSource _dataSource;
void initState() {
super.initState();
_data = [
Model('India', 280),
Model('United States of America', 190),
Model('Brazil', 120),
];
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
dataCount: _data.length,
primaryValueMapper: (int index) => _data[index].country,
shapeColorValueMapper: (int index) => _data[index].value,
shapeColorMappers: [
MapColorMapper(from: 0, to: 100, color: Colors.red),
MapColorMapper(from: 101, to: 300, color: Colors.green),
],
);
}
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: _dataSource,
legend: MapLegend(MapElement.shape),
showDataLabels: true,
),
],
),
);
}
}
class Model {
Model(this.country, this.value);
final String country;
final double value;
}class ChoroplethMap extends StatefulWidget {
_ChoroplethMapState createState() => _ChoroplethMapState();
}
class _ChoroplethMapState extends State<ChoroplethMap> {
late List<Model> _data;
late MapShapeSource _dataSource;
void initState() {
super.initState();
_data = [
Model('India', 280),
Model('United States of America', 190),
Model('Brazil', 120),
];
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
dataCount: _data.length,
primaryValueMapper: (int index) => _data[index].country,
shapeColorValueMapper: (int index) => _data[index].value,
shapeColorMappers: [
MapColorMapper(from: 0, to: 100, color: Colors.red),
MapColorMapper(from: 101, to: 300, color: Colors.green),
],
);
}
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: _dataSource,
legend: MapLegend(MapElement.shape),
showDataLabels: true,
),
],
),
);
}
}
class Model {
Model(this.country, this.value);
final String country;
final double value;
}class MapWithMarkers extends StatefulWidget {
_MapWithMarkersState createState() => _MapWithMarkersState();
}
class _MapWithMarkersState extends State<MapWithMarkers> {
late List<MarkerData> _markers;
late MapShapeSource _dataSource;
void initState() {
super.initState();
_markers = [
MarkerData('New York', 40.7128, -74.0060),
MarkerData('London', 51.5074, -0.1278),
MarkerData('Tokyo', 35.6762, 139.6503),
];
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
);
}
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: _dataSource,
initialMarkersCount: _markers.length,
markerBuilder: (BuildContext context, int index) {
return MapMarker(
latitude: _markers[index].latitude,
longitude: _markers[index].longitude,
iconColor: Colors.red,
iconType: MapIconType.circle,
size: Size(15, 15),
child: null,
);
},
),
],
),
);
}
}
class MarkerData {
MarkerData(this.city, this.latitude, this.longitude);
final String city;
final double latitude;
final double longitude;
}class MapWithMarkers extends StatefulWidget {
_MapWithMarkersState createState() => _MapWithMarkersState();
}
class _MapWithMarkersState extends State<ChoroplethMapState> {
late List<MarkerData> _markers;
late MapShapeSource _dataSource;
void initState() {
super.initState();
_markers = [
MarkerData('New York', 40.7128, -74.0060),
MarkerData('London', 51.5074, -0.1278),
MarkerData('Tokyo', 35.6762, 139.6503),
];
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
);
}
Widget build(BuildContext context) {
return Scaffold(
body: SfMaps(
layers: [
MapShapeLayer(
source: _dataSource,
initialMarkersCount: _markers.length,
markerBuilder: (BuildContext context, int index) {
return MapMarker(
latitude: _markers[index].latitude,
longitude: _markers[index].longitude,
iconColor: Colors.red,
iconType: MapIconType.circle,
size: Size(15, 15),
child: null,
);
},
),
],
),
);
}
}
class MarkerData {
MarkerData(this.city, this.latitude, this.longitude);
final String city;
final double latitude;
final double longitude;
}// Common pattern for election results, sales data by region, etc.
late MapShapeSource _dataSource;
int? _selectedIndex;
_dataSource = MapShapeSource.asset(
'assets/usa_states.json',
shapeDataField: 'name',
dataCount: _statesData.length,
primaryValueMapper: (index) => _statesData[index].state,
shapeColorValueMapper: (index) => _statesData[index].value,
shapeColorMappers: [
MapColorMapper(from: 0, to: 50, color: Colors.red),
MapColorMapper(from: 51, to: 100, color: Colors.blue),
],
);
MapShapeLayer(
source: _dataSource,
legend: MapLegend(MapElement.shape),
showDataLabels: true,
onSelectionChanged: (int index) {
setState(() {
_selectedIndex = index;
});
},
selectionSettings: MapSelectionSettings(
color: Colors.yellow,
strokeColor: Colors.black,
strokeWidth: 2,
),
)// 适用于选举结果、区域销售数据等场景
late MapShapeSource _dataSource;
int? _selectedIndex;
_dataSource = MapShapeSource.asset(
'assets/usa_states.json',
shapeDataField: 'name',
dataCount: _statesData.length,
primaryValueMapper: (index) => _statesData[index].state,
shapeColorValueMapper: (index) => _statesData[index].value,
shapeColorMappers: [
MapColorMapper(from: 0, to: 50, color: Colors.red),
MapColorMapper(from: 51, to: 100, color: Colors.blue),
],
);
MapShapeLayer(
source: _dataSource,
legend: MapLegend(MapElement.shape),
showDataLabels: true,
onSelectionChanged: (int index) {
setState(() {
_selectedIndex = index;
});
},
selectionSettings: MapSelectionSettings(
color: Colors.yellow,
strokeColor: Colors.black,
strokeWidth: 2,
),
)// Common pattern for store locator, delivery tracking
late List<LocationData> _locations;
late MapTileLayerController _controller;
void initState() {
_controller = MapTileLayerController();
_locations = [/* your location data */];
super.initState();
}
MapTileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
initialFocalLatLng: MapLatLng(37.7749, -122.4194),
initialZoomLevel: 10,
controller: _controller,
initialMarkersCount: _locations.length,
markerBuilder: (context, index) {
return MapMarker(
latitude: _locations[index].latitude,
longitude: _locations[index].longitude,
child: Icon(Icons.location_pin, color: Colors.red, size: 30),
);
},
zoomPanBehavior: MapZoomPanBehavior(
enableDoubleTapZooming: true,
enablePinching: true,
enablePanning: true,
),
)// 适用于门店定位、配送跟踪等场景
late List<LocationData> _locations;
late MapTileLayerController _controller;
void initState() {
_controller = MapTileLayerController();
_locations = [/* 你的位置数据 */];
super.initState();
}
MapTileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
initialFocalLatLng: MapLatLng(37.7749, -122.4194),
initialZoomLevel: 10,
controller: _controller,
initialMarkersCount: _locations.length,
markerBuilder: (context, index) {
return MapMarker(
latitude: _locations[index].latitude,
longitude: _locations[index].longitude,
child: Icon(Icons.location_pin, color: Colors.red, size: 30),
);
},
zoomPanBehavior: MapZoomPanBehavior(
enableDoubleTapZooming: true,
enablePinching: true,
enablePanning: true,
),
)// Common pattern for population density, sales volume visualization
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
dataCount: _data.length,
primaryValueMapper: (index) => _data[index].country,
bubbleSizeMapper: (index) => _data[index].population,
bubbleColorValueMapper: (index) => _data[index].density,
);
MapShapeLayer(
source: _dataSource,
showDataLabels: true,
legend: MapLegend.bar(MapElement.bubble),
bubbleSettings: MapBubbleSettings(
maxRadius: 50,
minRadius: 10,
color: Colors.blue,
),
shapeTooltipBuilder: (context, index) {
return Padding(
padding: EdgeInsets.all(8),
child: Text(
'${_data[index].country}: ${_data[index].population}M',
style: TextStyle(color: Colors.white),
),
);
},
bubbleTooltipBuilder: (context, index) {
return Padding(
padding: EdgeInsets.all(8),
child: Text(
'Density: ${_data[index].density}/km²',
style: TextStyle(color: Colors.white),
),
);
},
)// 适用于人口密度、销售额可视化等场景
_dataSource = MapShapeSource.asset(
'assets/world_map.json',
shapeDataField: 'name',
dataCount: _data.length,
primaryValueMapper: (index) => _data[index].country,
bubbleSizeMapper: (index) => _data[index].population,
bubbleColorValueMapper: (index) => _data[index].density,
);
MapShapeLayer(
source: _dataSource,
showDataLabels: true,
legend: MapLegend.bar(MapElement.bubble),
bubbleSettings: MapBubbleSettings(
maxRadius: 50,
minRadius: 10,
color: Colors.blue,
),
shapeTooltipBuilder: (context, index) {
return Padding(
padding: EdgeInsets.all(8),
child: Text(
'${_data[index].country}: ${_data[index].population}M',
style: TextStyle(color: Colors.white),
),
);
},
bubbleTooltipBuilder: (context, index) {
return Padding(
padding: EdgeInsets.all(8),
child: Text(
'密度: ${_data[index].density}/km²',
style: TextStyle(color: Colors.white),
),
);
},
)// Show specific region with markers
late MapZoomPanBehavior _zoomPanBehavior;
void initState() {
_zoomPanBehavior = MapZoomPanBehavior(
enableDoubleTapZooming: true,
enablePinching: true,
enablePanning: true,
);
super.initState();
}
// Button to fit bounds
void _fitToMarkers() {
setState(() {
// Define bounds to show all markers
_zoomPanBehavior.latLngBounds = MapLatLngBounds(
MapLatLng(southwestLat, southwestLng),
MapLatLng(northeastLat, northeastLng),
);
});
}
MapShapeLayer(
source: _dataSource,
zoomPanBehavior: _zoomPanBehavior,
// ... markers
)// 展示包含所有标记的特定区域
late MapZoomPanBehavior _zoomPanBehavior;
void initState() {
_zoomPanBehavior = MapZoomPanBehavior(
enableDoubleTapZooming: true,
enablePinching: true,
enablePanning: true,
);
super.initState();
}
// 适配边界的按钮事件
void _fitToMarkers() {
setState(() {
// 定义展示所有标记的边界
_zoomPanBehavior.latLngBounds = MapLatLngBounds(
MapLatLng(southwestLat, southwestLng),
MapLatLng(northeastLat, northeastLng),
);
});
}
MapShapeLayer(
source: _dataSource,
zoomPanBehavior: _zoomPanBehavior,
// ... 标记配置
)// Add markers where user taps
late MapLatLng _markerPosition;
late MapShapeLayerController _controller;
late CustomZoomPanBehavior _zoomPanBehavior;
void initState() {
_controller = MapShapeLayerController();
_zoomPanBehavior = CustomZoomPanBehavior()
..onTap = _handleTap;
super.initState();
}
void _handleTap(Offset position) {
_markerPosition = _controller.pixelToLatLng(position);
if (_controller.markersCount > 0) {
_controller.clearMarkers();
}
_controller.insertMarker(0);
}
MapShapeLayer(
source: _dataSource,
controller: _controller,
zoomPanBehavior: _zoomPanBehavior,
markerBuilder: (context, index) {
return MapMarker(
latitude: _markerPosition.latitude,
longitude: _markerPosition.longitude,
child: Icon(Icons.location_on, color: Colors.red),
);
},
)
class CustomZoomPanBehavior extends MapZoomPanBehavior {
late Function(Offset) onTap;
void handleEvent(PointerEvent event) {
if (event is PointerUpEvent) {
onTap(event.localPosition);
}
super.handleEvent(event);
}
}// 在用户点击的位置添加标记
late MapLatLng _markerPosition;
late MapShapeLayerController _controller;
late CustomZoomPanBehavior _zoomPanBehavior;
void initState() {
_controller = MapShapeLayerController();
_zoomPanBehavior = CustomZoomPanBehavior()
..onTap = _handleTap;
super.initState();
}
void _handleTap(Offset position) {
_markerPosition = _controller.pixelToLatLng(position);
if (_controller.markersCount > 0) {
_controller.clearMarkers();
}
_controller.insertMarker(0);
}
MapShapeLayer(
source: _dataSource,
controller: _controller,
zoomPanBehavior: _zoomPanBehavior,
markerBuilder: (context, index) {
return MapMarker(
latitude: _markerPosition.latitude,
longitude: _markerPosition.longitude,
child: Icon(Icons.location_on, color: Colors.red),
);
},
)
class CustomZoomPanBehavior extends MapZoomPanBehavior {
late Function(Offset) onTap;
void handleEvent(PointerEvent event) {
if (event is PointerUpEvent) {
onTap(event.localPosition);
}
super.handleEvent(event);
}
}sourcecolorstrokeColorstrokeWidthlegendshowDataLabelsinitialMarkersCountmarkerBuildercontrollerzoomPanBehavioronSelectionChangedselectionSettingsshapeTooltipBuilderbubbleTooltipBuildermarkerTooltipBuildertooltipSettingsbubbleSettingsdataLabelSettingslegendSettingssublayersloadingBuildersourcecolorstrokeColorstrokeWidthlegendshowDataLabelsinitialMarkersCountmarkerBuildercontrollerzoomPanBehavioronSelectionChangedselectionSettingsshapeTooltipBuilderbubbleTooltipBuildermarkerTooltipBuildertooltipSettingsbubbleSettingsdataLabelSettingslegendSettingssublayersloadingBuilderurlTemplateinitialFocalLatLnginitialZoomLevelinitialMarkersCountmarkerBuildercontrollerzoomPanBehaviormarkerTooltipBuilderinitialLatLngBoundsurlTemplateinitialFocalLatLnginitialZoomLevelinitialMarkersCountmarkerBuildercontrollerzoomPanBehaviormarkerTooltipBuilderinitialLatLngBoundsshapeDataFielddataCountprimaryValueMapperdataLabelMappershapeColorValueMappershapeColorMappersbubbleSizeMapperbubbleColorValueMapperbubbleColorMappersshapeDataFielddataCountprimaryValueMapperdataLabelMappershapeColorValueMappershapeColorMappersbubbleSizeMapperbubbleColorValueMapperbubbleColorMappersenableDoubleTapZoomingenablePinchingenablePanningenableMouseWheelZoomingshowToolbartoolbarSettingszoomLevelfocalLatLnglatLngBoundsminZoomLevelmaxZoomLevelonZoomingonPanningenableDoubleTapZoomingenablePinchingenablePanningenableMouseWheelZoomingshowToolbartoolbarSettingszoomLevelfocalLatLnglatLngBoundsminZoomLevelmaxZoomLevelonZoomingonPanning