OwnWeb / flutter_map_tappable_polyline

A tappable Polyline plugin for flutter_map
https://pub.dev/packages/flutter_map_tappable_polyline
MIT License
54 stars 44 forks source link

Detect taps between way points #4

Closed Mkohm closed 4 years ago

Mkohm commented 4 years ago

Hi ! My use case is that I have many polylines close to each other, but not too many points on each polyline. How can I detect taps on the polyline with high precision without introducing new points and have to increase the radius of each point?

If I have to generate more points for this to work- any idea on how it will work with the order of 100.000-1.000.000 points in total? Will the performance still be good?

tuarrep commented 4 years ago

As the algorithm to detect taps works, you can't.

The polylines are drawn using their way points. Each point is positioned on the map, next straight line are drawn between them by the Canvas. For the moment we only base the tap detection on polyline way points as we can get their coordinates on screen. But we cannot do the same with straight lines in between because they are inferred by the Flutter Canvas system and not calculated by the plugin.

The only option for you now is to add more points on your polylines.

About performances, I haven't tested. But, as we use the flutter_map default Polyline as back end, perhaps you can grab some info from the official repo

I agree having a way to detect taps on straight lines between point could be a great addition. For now I really haven't the time to investigate this.

I've tried something here https://github.com/OwnWeb/flutter_map_tappable_polyline/commit/f606d5832f57e2396096c91e87fc3e634d316df8 to rewrite gesture detection (and allow double tap on the underlying map) but it completely breaks lots of maps features, so I've reverted it. But it could be a good base to start enhancing the gesture detection

Mkohm commented 4 years ago

Thanks, I will investigate the performance and see how it works out. I am very new to flutter so probably need some time before I could help out with this issue. But this feature is important for the use-case of the app so it is worth spending some time on. Will report my findings :)

Mkohm commented 4 years ago

Tested it out, and the results are not good. Drawing 100 polylines with ~50 points each was causing bad performance.

However, I just found out that flutter_map (version 0.10.1) supports polyline culling (https://github.com/fleaflet/flutter_map/pull/611) (only rendering visible polylines). If your plugin is updated to use the latest version I think it would fix most of the performance problems ! I could then add more points to the polylines to support better clicking on the polylines.

tuarrep commented 4 years ago

Good news. I'll try to update the dependency today

tuarrep commented 4 years ago

I've pushed v0.3.3 which depends on flutter_map v0.10.1.

@Mkohm could you try if it performs better in your use case?

Mkohm commented 4 years ago

@tuarrep i am not able to enable that option because TappablePolylineLayerOptions extends LayerOptions. If we extend PolylineLayerOptions instead we would have access to the polyline-culling functionality :)

tuarrep commented 4 years ago

Crap! I'll try to find spare time to do this. Perhaps you can give it a try by crafting a PR?

Mkohm commented 4 years ago

I'll see what i can do 👍

Mkohm commented 4 years ago

Using polylineCulling drastically improves polyline performance. However, i am not able to get this performance benefit when using TappablePolylineLayerOptions. I have simply extended PolylineLayerOptions instead of LayerOptions and enabled polylineCulling. For some reason the StreamBuilder is not called. I will continue have a look at this, but if you have any input i would be very glad for help :)

tuarrep commented 4 years ago

The package implements his own StreamBuilder to inject gesture detection. See https://github.com/OwnWeb/flutter_map_tappable_polyline/blob/master/lib/flutter_map_tappable_polyline.dart#L72

Mkohm commented 4 years ago

Okay, performance is okay for now. What i am looking for next is to be able to detect taps in between waypoints. I think an easy (but limited) solution is to generate more points based on what is initially given to the TaggablePolyline. Ideally, it should generate as many points that is needed so that the distance between each point is lower than the pointerDistanceTolerance. My expertise in Flutter is currently limited so i guess i will look into this solution. Would it be of value to this plugin? If so i could create another PR with it.

HugoHeneault commented 4 years ago

Sure it would! That's a great idea.

tuarrep commented 4 years ago

No.

Adding points in Polylines is a no-go for me. Too much overhead on performance even with new culling. A prefer doing mathematics when a tap occurs.

My idea is :

The formula should be :

p1 = points[n]
p2 = points[n+1]

distance(p1, p2) - distance(p1, tap) - distance(p2, tap) <= pointerDistanceTolerance

That will tell us if the tap is between two points.

Mkohm commented 4 years ago

No.

Adding points in Polylines is a no-go for me. Too much overhead on performance even with new culling. A prefer doing mathematics when a tap occurs.

My idea is :

  • Polylines draw straight lines between points ;
  • The Distance package can calculate distance between two geo point rapidly ;
  • It's easy and fast to detect mathematically if 3 points are aligned.

The formula should be :

p1 = points[n]
p2 = points[n+1]

distance(p1, p2) - distance(p1, tap) - distance(p2, tap) <= pointerDistanceTolerance

That will tell us if the tap is between two points.

I did'nt think of that solution, that would be a lot better! I will look into doing it that way instead!