尝试使用 google_maps_flutter 动态加载某些多边形时,不会显示它们



我想要实现的是仅在屏幕边界内加载多边形。只有一些在边界内的多边形被加载,而其他多边形则没有。 我使用提供程序进行状态管理,google_maps_flutter用于地图...

这是应该执行动态加载的代码。

//this is used to load layers only within screen bounds
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:simtaru/models/polaruang.dart';
import 'package:simtaru/utils/warna.dart';
class PolyProvider with ChangeNotifier {
Set<Polygon> _visiblePolygons = new Set();
Set<Polygon> get visiblePolygon => _visiblePolygons;
List<Feature> features;
PolyProvider({@required this.features});
void refreshVisiblePolygons(GoogleMapController controller) async {
var bounds = await controller.getVisibleRegion();
List<Feature> featureToLoad = new List();
//check which feature is inside screen bounds...
features.forEach((feature) {
var id = feature.attributes.fid;
var listOfPolyDef = feature.geometry.rings.map((e) {
List<LatLng> polyDef = new List();
e.forEach((x) {
polyDef.add(LatLng(x[1], x[0]));
});
return polyDef;
}).toList();
for (var polyDef in listOfPolyDef) {
if (isPolyInsideBounds(polyDef, bounds, id.toString())) {
featureToLoad.add(feature);
break;
}
}
});
//then update the _visiblePolygons with the value;
_visiblePolygons = _loadPoly(featureToLoad);
//then notify the listeners...
notifyListeners();
}
Set<Polygon> _loadPoly(List<Feature> featureToLoad) {
Set<Polygon> polygons = new Set();
featureToLoad.forEach((feature) {
var rings = feature.geometry.rings;
var id = feature.attributes.fid;
var namaKawasan = feature.attributes.rencanaOk;
Color warnaLayer = layerColor(namaKawasan);
rings.forEach((element) {
var points = element.map((e) => LatLng(e[1], e[0])).toList();
polygons.add(
Polygon(
geodesic: false,
visible: true,
polygonId: PolygonId(id.toString()),
points: points,
fillColor: warnaLayer,
strokeColor: Colors.blue[50],
strokeWidth: 1,
consumeTapEvents: true,
onTap: () => print(namaKawasan + " " + id.toString()),
),
);
});
});
//TODO: remove these diagnostic lines when not needed anymore...
print("succesfully created following polygons: ");
polygons.forEach((element) {
print(element.polygonId.value);
});
return polygons;
}
bool isPolyInsideBounds(
List<LatLng> polyPoints, LatLngBounds bounds, String id) {
bool isInBound = false;
//DO NOT DELETE THESE CODE! IT'S ANOTHER (SLOWER!!) METHOD TO CHECK POLY
// var sw = bounds.southwest;
// var ne = bounds.northeast;
// var se = LatLng(ne.latitude, sw.longitude);
// var nw = LatLng(sw.latitude, ne.longitude);
// if (isPointInsidePoly(polyPoints, sw) ||
//     isPointInsidePoly(polyPoints, ne) ||
//     isPointInsidePoly(polyPoints, se) ||
//     isPointInsidePoly(polyPoints, nw)) {
//   isInBound = true;
// }
for (var x in polyPoints) {
if (bounds.contains(x)) {
isInBound = true;
break;
}
}
return isInBound;
}
bool isPointInsidePoly(List<LatLng> polyPoints, LatLng pos) {
List<String> isInside = [];
int count = 0;
while (count < (polyPoints.length - 1)) {
//bool isIn;
var currentPointLat = polyPoints[count].latitude;
var currentPointLng = polyPoints[count].longitude;
var nextPointLat = polyPoints[count + 1].latitude;
var nextPointLng = polyPoints[count + 1].longitude;
bool isIntersect = ((currentPointLng > pos.longitude) !=
(nextPointLng > pos.longitude)) &&
(pos.latitude <
(nextPointLat - currentPointLat) *
(pos.longitude - currentPointLng) /
(nextPointLng - currentPointLng) +
currentPointLat);
isInside.add(isIntersect.toString());
count++;
}
var trueCount = 0;
isInside.forEach((f) {
if (f == 'true') {
trueCount++;
}
});
return trueCount.isOdd;
}
}

这是地图页面...

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:provider/provider.dart';
import 'package:simtaru/providers/polyprovider.dart';
class MainMap extends StatefulWidget {
final LatLng _initPos = LatLng(0.880496, 123.550585);
@override
_MainMapState createState() => _MainMapState();
}
class _MainMapState extends State<MainMap> {
GoogleMapController _mapController;
@override
Widget build(BuildContext context) {
var polyProvider = context.watch<PolyProvider>();
return Scaffold(
body: GoogleMap(
initialCameraPosition:
CameraPosition(target: widget._initPos, zoom: 15),
polygons: polyProvider.visiblePolygon,
liteModeEnabled: false,
onMapCreated: _onMapCreated,
onCameraIdle: () {
polyProvider.refreshVisiblePolygons(_mapController);
},
),
);
}
void _onMapCreated(GoogleMapController controller) {
_mapController = controller;
setState(() {});
}
}

这是颤振医生-v结果

[√] Flutter (Channel master, 1.20.0-1.0.pre.15, on Microsoft Windows [Version 10.0.18363.900], locale en-US)
• Flutter version 1.20.0-1.0.pre.15 at E:Flutter
• Framework revision daddc914c7 (2 days ago), 2020-06-11 01:35:01 +0200
• Engine revision e8c13aa012
• Dart version 2.9.0 (build 2.9.0-14.0.dev 5c1376615e)

[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
• Android SDK at E:Androidsdk
• Platform android-29, build-tools 29.0.3
• ANDROID_SDK_ROOT = E:Androidsdk
• Java binary at: D:Program FilesAndroidjrebinjava
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)
• All Android licenses accepted.
[√] Chrome - develop for the web
• Chrome at C:Program Files (x86)GoogleChromeApplicationchrome.exe
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.4.4)
• Visual Studio at C:Program Files (x86)Microsoft Visual Studio2019Community
• Visual Studio Community 2019 version 16.4.29728.190
• Windows 10 SDK version 10.0.18362.0
[√] Android Studio (version 3.5)
• Android Studio at D:Program FilesAndroid
• Flutter plugin version 42.1.1
• Dart plugin version 191.8593
• Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)
[√] VS Code
• VS Code at C:UsersdatunAppDataLocalProgramsMicrosoft VS Code
• Flutter extension version 3.11.0
[√] Connected device (5 available)
• Android SDK built for x86 64 • emulator-5554 • android-x64    • Android 10 (API 29) (emulator)
• Windows                      • Windows       • windows-x64    • Microsoft Windows [Version 10.0.18363.900]
• Web Server                   • web-server    • web-javascript • Flutter Tools
• Chrome                       • chrome        • web-javascript • Google Chrome 83.0.4103.97
• Edge                         • edge          • web-javascript • Microsoft Edge 83.0.478.45
• No issues found!

*编辑:添加polygons.single后,我得到的异常如下:

Exception has occurred.
StateError (Bad state: Too many elements)

仍然不知道如何解决。任何帮助不胜感激。

终于想通了问题所在。我的模型类 (Pola Ruang( 的结构方式使得意外地为不同的多边形创建两个相同的多边形 ID 成为可能。我已经修复了它,现在它正在工作。谢谢我。

你能试试这个代码吗?

// declare
final Set<Polygon> _polygons = HashSet<Polygon>();
// init 
_polygons.add(
Polygon(
polygonId: PolygonId('1'),
visible: true,
points: [LatLng(11.577365979599334, 104.85581662505865), LatLng(11.577357439774342, 104.85589172691107), LatLng(11.577293719533515, 104.85585048794746)],
consumeTapEvents: true,
strokeWidth: 3,
fillColor: Colors.red.withOpacity(0.3),
strokeColor: Colors.red,
),
);
_polygons.add(
Polygon(
polygonId: PolygonId('2'),
visible: true,
points: [LatLng(11.57722047408411, 104.85577102750541), LatLng(11.577153469261589, 104.85587563365698), LatLng(11.577136718053453, 104.85578544437885)],
consumeTapEvents: true,
strokeWidth: 3,
fillColor: Colors.red.withOpacity(0.3),
strokeColor: Colors.red,
),
);
//setup
GoogleMap(
...
polygons: _polygons,
)

最新更新