我想要实现的是仅在屏幕范围内加载多边形。只有边界内的某些多边形会被加载,而其他多边形则不会。我使用提供程序进行状态管理,并将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:\Android\sdk
• Platform android-29, build-tools 29.0.3
• ANDROID_SDK_ROOT = E:\Android\sdk
• Java binary at: D:\Program Files\Android\jre\bin\java
• 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)\Google\Chrome\Application\chrome.exe
[√] Visual Studio - develop for Windows (Visual Studio Community 2019 16.4.4)
• Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
• 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 Files\Android
• 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:\Users\datun\AppData\Local\Programs\Microsoft 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。我已经修复它,现在它可以工作了。谢谢。