-
-
Notifications
You must be signed in to change notification settings - Fork 860
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEATURE] Interactive Polygon
s
#385
Comments
We are also looking at a onTap of a polygon / live. Would be very helpful to us We have some developers here also, so if someone can point us in the right direction we are happy to contribute |
From what I found it exist a |
Just for anyone interested, I just translated in dart a function to find if a position is inside a Polygon
|
This lib can do it as well. The problem is that this kind of brute force geofencing is really slow so not user friendly. If you have a lot of polygons it is not appropriate. It would be much better to have an on tap callback. |
It would be great to have onTap event for polygons and polylines. I also need that feature but I have not be able to find a good way to implemented. |
Interestingly enough the same authors created map_view plugin which uses static Google Maps and provide listeners for polygon layers. @johnpryan how difficult it to add to flutter_map ? |
I used diffrent trick. Each polygon in lat/lng space I convert into a path in x/y space. Then using 2d geometry functions of path I can check if given point is inside specific path (which I can connect to specific polygon). Works pretty fast. |
Interesting. Do you have some code that we could see? I'm trying to do more or less the same thing using the geohex encoding format |
So I am using some classes from actual map plugin to convert points from lat/lng to x/y.
and then:
|
PSA getPolygonWithPosition does not compile, you need to convert to the classic for(var path in _polygonPaths) loop. |
I just changed code in answer from original. Let me fix it. Fixed. |
I do not enjoy being pedantic but using return does not stop functional forEach, the intent is clear tho. |
Hello, @spvalencia, this library has been implemented https://github.com/synw/geodraw, sometimes it helps you in some way. |
Hi @aleffabricio. Thank you so much. I'm going to check it out. |
I found this useful plugin for flutter_map: |
@joandervieira Thank you |
check this package geodesy it have a method to check if a given geo point is in the a polygon |
I have done ontap of polygon and show info window using map controller
|
you can use my code i used to know if point is inside polygon i hope it help you. soon i'll share `class PolylinePage extends StatelessWidget {
} |
thank you
*With Regards,Anupam DasMobile Application DeveloperSPARC Pvt. Ltd.*
…On Mon, Oct 19, 2020 at 3:48 AM RabieEL ***@***.***> wrote:
you can use my code i used to know if point is inside polygon i hope it
help you. soon i'll share
i code that show you a pop up on map if point is inside polygon:
inside pubspec.yaml: flutter_map and geodesy
`class PolylinePage extends StatelessWidget {
static const String route = 'polyline';
Geodesy geodesy = Geodesy();
@OverRide <https://github.com/override>
Widget build(BuildContext context) {
// List of point to draw polygon
var points = [
LatLng(51.5, -0.09),
LatLng(53.3498, -6.2603),
LatLng(48.8566, 2.3522),
];
//List of point to draw second polygon
var pointsGradient = [
LatLng(55.5, -0.09),
LatLng(54.3498, -6.2603),
LatLng(52.8566, 2.3522),
LatLng(55.5, -0.09),
LatLng(55.5, -0.09),
];
var polygones = <Polygon>[
Polygon(points: points, color: Colors.red),
Polygon(points: pointsGradient)
];
void onPolygon(LatLng point) {
polygones.forEach((element) {
// if point is on the polygon isGeoPointInPolygon if true
bool isGeoPointInPolygon =
geodesy.isGeoPointInPolygon(point, element.points);
if (isGeoPointInPolygon == true) {
print(element.points);
}
});
}
return Scaffold(
appBar: AppBar(title: Text('Polylines')),
drawer: buildDrawer(context, PolylinePage.route),
body: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
children: [
Padding(
padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Text('Polylines'),
),
Flexible(
child: FlutterMap(
options: MapOptions(
///use on tap to get point coordinates
onTap: onPolygon,
plugins: [
/// import plugin
TappablePolylineMapPlugin(),
],
center: LatLng(51.5, -0.09),
zoom: 5.0,
),
layers: [
TileLayerOptions(
urlTemplate:
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png <http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png>',
subdomains: ['a', 'b', 'c']),
// to draw polygon on map
PolygonLayerOptions(polygons: polygones),
],
),
),
],
),
),
);
}
}`
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#385 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AJ2HXFGBY5QMPBWTBI5SWGDSLNSUBANCNFSM4ILA5RIQ>
.
|
@iRELGE Thank you so much for this! You saved me a lot of time and energy. If you have more publications on this issue, please, share them with me. |
@kotrotko your welcome ill share it soon ,ill share how to show popup if you clock on polygon if you need it |
@kotrotko please can you marke this issue as closed |
I'm so sorry status closed is not available now(( |
@kotrotko its ok bro my its about Agriculture draw field and follow the interventions if you have any question contact me |
👍🏻
… On 28 Feb 2021, at 19:32, RabieEL ***@***.***> wrote:
marke
|
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days. |
In terms of performance, the solutions I've seen took a while to determine the correct polygon - however, I now realize that may have been to do with something I 'fixed' in #1532, where the double tap gesture delayed receipt of the single tap gesture for 250ms (now, if you specify to disallow the double tap gesture, there is no delay). So maybe we need to double check this. I wonder, would it help to triangulate the polygons? This would help with handling holes (as @ignatz mentioned is a pain point), and from my basic understanding, this is one step of many algorithms anyway. If so, I just so happened to have recently ported a very performant triangulation library to Dart: https://pub.dev/packages/dart_earcut. Interestingly, the original came from the mapbox org - interesting loop back to mapping there :D. |
It doesn't. It was someones 1:1 javascript to dart robo conversion, which didn't care much for nullability. Unfortunately, the owner has admitted to not be comfortable touching the implementation and only maintains the project's README. So I just spend some non-trivial amount of time going through the entire implementation. In the process I did some research and credit goes to:
If you wanted to go down the polybool route, which I'd be careful with*, I would consider at least forking the code. (* mostly regarding the state of the project. The algorithm itself is pretty rad and battle tested)
Sorry, I didn't want to make it sound like a huge problem (that's why I put it in parenthesis). I just didn't care for it myself, since airspaces typically don't have holes. With polybool, this can be trivially handled as a set-operation. I'm sure the raycasting can account for it too by running both on the hull and the holes separately.
I've implemented plygon/marker culling with r-trees before. It felt more worthwhile since culling runs on every frame (unlike on-tap) but in practice it wasn't worth it for me... maybe if you have orders of magnitude, i.e. 1 millions, more objects 🤷. For more common numbers the impact is more likely to be negative. |
:D I honestly am not sure what to do here (ping @TesteurManiak @mootw). Leaving it for a plugin is a good way to allow for a massive, performant implementation. Adding to core means more users more happy more quicker. We can see how @b-cancel's solution works. @ignatz, would you mind sharing your implementation in some way? |
Sorry, if I caused confusion. I was trying to say:
Any algorithm/implementation that meets #3 will do. I do like the polybool algorithm because I haven't encountered any false postives/negatives and I'm probably also suffering from a good amount of Stockholm syndrome.
I'm not very protective, I just haven't gotten around to open sourcing it plus a few quirks. I pulled out and cleaned up the relevant part, which is just as straight forward as you'd expect: List<Polygon> findPolygonCollisions(
FlutterMapState map,
List<Polygon> polygons,
CustomPoint<double> point,
) {
final latlng = map.pointToLatLng(point)!;
final hits = <Polygon>[];
for (final polygon in polygons) {
// First do a quick pass on the rough bounding box envelope to find candidate hits.
final bounds = LatLngBounds.fromPoints(polygon.points);
if (bounds.contains(latlng)) {
final coordinates =
polygon.points.map((c) => polybool.Coordinate(c.longitude, c.latitude)).toList()
// NOTE: Polybool requires polygons to be closed loops, i.e.: c.first == c.last.
if (coordinates.first != coordinates.last) {
coordinates.add(coordinates.first);
}
final p = polybool.Polygon(regions: [coordinates]);
const eps = 1e-7;
final touch = polybool.Polygon(regions: [
[
polybool.Coordinate(latlng.longitude, latlng.latitude),
polybool.Coordinate(latlng.longitude + eps, latlng.latitude),
polybool.Coordinate(latlng.longitude + eps, latlng.latitude + eps),
polybool.Coordinate(latlng.longitude, latlng.latitude + eps),
polybool.Coordinate(latlng.longitude, latlng.latitude),
]
]);
final match = p.intersect(touch).regions.isNotEmpty;
if (match) {
hits.add(polygon);
}
}
}
return hits;
} Note that I'm returning a list of hits, since polygons are over-lapping and I want to show a list of stacked airspaces under the tap area. More traditionally, a on-tap handler would probably only handle |
Absolutely no confusion at all :). "Performance" as in accuracy as well as speed. Thanks for sharing, very much appriciated :) Maybe I can piece together all the different implementations from this thread and benchmark them without the complications of flutter_map. |
As someone who likes to experiment and play around, you have my full support. However, I also want to be mindful of your time so let me point this out once and then get off you lawn and let you have fun :)
You can see how its running at 30fps with plenty of head-room on the UI thread solely being throttled by raster performance: |
Nah, no "lawns" here! You guys are much more in the know about this stuff than me, so I'm happy for the advice :) Anyway, I've got some other high priority stuff to experiment with - like getting FM v6 ready & debugging why one algorithm generates 30,000 tiles in one area and another generates 2,000,000 in the same area for no apparent reason. So who knows if I'll actually get round to this any time soon. Anyways, thanks for the code again :) |
@ignatz thanks for your function! I can't wait to use it I only have roughly 100 polygons on the screen at any given point given your performances test |
My intuition is that for N=100 traversing the tree has likely more overhead than going through the list. More importantly, FlutterMap is traversing the full list on every frame anyways. Whatever ends up being faster in any particular case, you're paying the cost of a full scan... (which I've never seen to cost a frame, since rasterization will always push your frame deadlines first) |
Is there any chance we will see this implemented in the v6 ? |
Hit detectable PS. Apologies for the notifications! |
I don't understand, the issue/PR linked is for |
Hi @V3ntus, |
Gotcha, much appreciated! Well that is exciting, glad to see development there. I've been using third-party plugins to achieve polygon uses, so if I can do it "natively" here in the future, that would be awesome. |
Ok, as we're looking into implementing it in the next version, I'm trying to find an implementation we can use by reading through the history again here.
|
Polygon
sPolygon
s
We've implemented this! Experiment with it and all the other features we've been hard at work implementing on the 'master' branch: we'd love to hear your feedback! Documentation is available at https://docs.fleaflet.dev/v/v7-beta/layers/layer-interactivity. If you've been waiting for this for a while, please consider donating https://docs.fleaflet.dev/supporters#support-us! |
Hi,
I'm trying to reimplement an existing Leaflet-based app using flutter. In that app, the developer used Polygons to display the outline of a building, which when clicked/tapped shows additional information. and changes the polygon.
I'm trying to replicate that function, however I noticed there is no onTap Listener, at least for Polygons. Is there a different way to listen to tap events?
The text was updated successfully, but these errors were encountered: