[某些多边形尝试通过google_maps_flutter动态加载时不显示

问题描述 投票:0回答:1

我想要实现的是仅在屏幕范围内加载多边形。只有边界内的某些多边形会被加载,而其他多边形则不会。我使用提供程序进行状态管理,并将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)

仍然不知道如何解决。感谢您的帮助。

flutter provider
1个回答
0
投票

最终解决了问题。我的模型类(Pola Ruang)的构造方式可以为不同的多边形意外创建两个相同的多边形ID。我已经修复它,现在它可以工作了。谢谢。

© www.soinside.com 2019 - 2024. All rights reserved.