fleaflet / flutter_map

A versatile mapping package for Flutter. Simple and easy to learn, yet completely customizable and configurable, it's the best choice for mapping in your Flutter app.
https://pub.dev/packages/flutter_map
BSD 3-Clause "New" or "Revised" License
2.73k stars 860 forks source link

[FEATURE] Improve `Scalebar` at low zoom levels #1950

Open S-Man42 opened 3 weeks ago

S-Man42 commented 3 weeks ago

What is the bug?

I really love to see this feature. However, it seems not to be correct.

The scale shows a distance of 1000km in the horizontal distance.

Screenshot_20240819_210047_Brave

In fact, it is not more than 650km.

I guess it results from the problem, that the mercator projection yield different distances throughout the map for same pixel distances depending on latitude.

But in this case it is not quite clear which latitude it shows. Does it measures the rhumb line or geodetic lengths? Currently it may show wring results as you can see.

I guess it could be a good idea to configure the scale this way, that it shows the distance of the start and end points lying exactly under the bar.

Second point would be to decide which length you really display. The shortest length (geodetic) between start and end point of the scale, but in that case it is not a straight line and the half marker would not be at the drawed position. If one would show the length of the straight line as the scale bar shows, you would need the length of the rhumb line. (in mercator projection).

Funny enough: Googles scale is also not that precise, I believe:

Screenshot_20240821_073423_Maps

How can we reproduce it?

Add ScaleBar layer and scroll to any area you know its diameter

Do you have a potential solution?

I would tried following, I don't know if it works

(for left alignment, others are similar)

Take the pixel position of the starting point of the scale. Convert it to the coordinate exactly below it. Calculate the rhumb line length exactly <currently. displayed scale unit/meters, i.e. 200km> east. Convert this back to the current pixel coords as end point, draw line.

In my opinion this should ensure that the scale exactly shows the length of the rhumbline which is exactly below it. So one could do measuring by panning the map right under the scale. If would choose rhumbline over geodetic's length because it shows a straight line on a mercator projection and hence it should not calc a "curved" geodetic's length in my opinion. It's relevant for huge distances. For smaller ones one could think about switching to geodetics since the performance could be probably increased and difference is very small.

Platforms

Tested in web demo

Severity

Minimum: Allows normal functioning

S-Man42 commented 3 weeks ago

Other solution could be offering a vertical scale with two or even three sections (halfs, thirds) which show that then scale change when going north or south.

ibrierley commented 3 weeks ago

Not quite sure if this is possibly related to https://github.com/fleaflet/flutter_map/issues/1314

JaffaKetchup commented 3 weeks ago

I believe it shows the scale at the center of the viewport, so I guess it makes sense that it's out when the center of the viewport is much closer to latitude 0 than Germany at this zoom level - I assume the center of the screen is in the South Atlantic Ocean somewhere. I guess it could make sense for the scale bar to actually measure the scale where it is, but then it gives a less accurate overview at these low zoom levels.

At higher zoom levels the problem won't be as large. When I place it over a place I use to calibrate exactly, it still reads correct because at that scale there's probably less than 10km between scale bar and viewport center.

josxha commented 3 weeks ago

I agree that the scale bar can be misleading on smaller zoom levels. However, I don't think much can be done to improve this. (and for example Google Maps on mobile has the same behavior). I agree with @JaffaKetchup and I believe the scale bar is a useful tool to give an idea about distances but to have it 100% accurate for all of the visible viewport is not possible with all projections.

S-Man42 commented 3 weeks ago

Since the scale bar length depends on the latitude, it could be an interesting feature to add a vertical scale with increasing sectors which show the same actual length but grow on increasing lat. I believe it would be a great and afaik unique feature. Screenshot_20240823_082707_Locus Map Classic

josxha commented 3 weeks ago

@S-Man42 this would be a feature not a bug, wouldn't it? There has been some discussion in the past about enhancing the scale bar, like show it in miles or a combined meter/miles scale bar similar to what google maps has. Pull request are welcome.

S-Man42 commented 3 weeks ago

Hm, maybe. It could be seen as a feature, I believe. It depends on how you classify this issue. If you say: Well, it is not a bug since it does what it should do in your opinion and the issue is... well... one couldn't do anything. Then it is a new feature. Otherwise one could see it as probable workaround to enhance the usability and go around the described issue ;)

It's just brainstorming. Maybe I'll find some time to add this to the project. :)

monsieurtanuki commented 3 weeks ago

The notion of ScaleBar for low zoom levels makes no sense anyway: what would be the scale on zoom 0? I would suggest not displaying the ScaleBar for low zoom levels. If really needed, the more relevant option would be some kind of flat ellipse (e.g. 100km wide), draggable and depending on the latitude.

JaffaKetchup commented 2 weeks ago

I'm going to sort this as a feature request, as it's impossible to get a single behaviour that will work right for everyone with the current scale bar.

S-Man42 commented 1 week ago

Created a precise scalebar vor my own map based on this code here. It is not currently for merging due major changes. Maybe one could merge the codes into one using several new options. One has to be extremely careful with pixels and positions. For example: The current code takes a position on the map (center) , calculates the bar length, draws it as a new widget and positions it afterwards with padding. Making the measuring precisely at the drawed line the padding position must be taken into account during calculation. One cannot use the bottom left pixel when the scalebar will be drawn 30 pixels higher instead. These 30px are important for length calculations on low zoom. levels... Such things...

Take this as a PoC. If I find the time, I will make a more generalized version but of course this can be done by anybody else :)

https://github.com/S-Man42/GCWizard/tree/3.2.0/lib/tools/coords/map_view/widget/scalebar

Screenshot_20240831_235751

monsieurtanuki commented 1 week ago

@S-Man42 A scale grid would even make more sense:

S-Man42 commented 1 week ago

Yes, indeed, it would be a nice feature too. However since we discussed a bar not a grid, I implemented the first one.

monsieurtanuki commented 1 week ago

@S-Man42 Fair enough. It's just that the OP was about a horizontal scale bar. Your scale bar is vertical. And I believe the solution is a grid.

S-Man42 commented 1 week ago

I did this because it demonstrates the increasing scale and therefore the used precision which is not necessary/possible in horizontal orientation

josxha commented 1 week ago

I like the idea of enhancing the scale bar in general. But I struggle a bit at the moment to think of a use case where the exact scale at every pixel of the screen is crucial and where a measure-distance-tool won't be used. @S-Man42 could you describe some example use case where this is mandatory please?

S-Man42 commented 1 week ago

I simply don't like wrong information ;) Well, as shown aboveb The current scales are not useful on low zoom scales. I think, one should show correct or no information. ;)