Modify

Opened 6 months ago

Last modified 2 days ago

#13124 reopened enhancement

[PATCH] Enhanced GPS data rendering - heatmaps instead of dozens of lines

Reported by: transmit-receive Owned by: team
Priority: major Milestone: 17.01
Component: Core Version:
Keywords: gps track, rendering, colormap, visualization Cc: Don-vip, michael2402

Description

Problem: If many GPS tracks are available for a region, dozens of lines are rendered on top of each other. It is hard to discern where the density of lines is highest, i.e. where the track most likely is centered.

Solution: Draw a heatmap of the GPS track data instead of many lines (something similar to e.g. http://labs.strava.com/heatmap/#6/-120.90000/38.36000/blue/bike)

Proposed Algorithm:

  • Create array of dimension x*y as big as current field of view
  • For each line segment of GPS tracks in view, check which pixels of the current field of view are touched by this line segment, increase counter in these array cells by one
  • add semitransparent colormapped layer to display from array where 0=transparent, [1 .. max(array)] = color

Additional thoughts:

Attachments (15)

josm_ticket_13124_gpx_heat_map_by_kidelo.patch (62.8 KB) - added by kidelo 2 weeks ago.
GPX Heat Map Extension by kidelo
sample.gpx (352.4 KB) - added by Don-vip 2 weeks ago.
before.png (150.7 KB) - added by Don-vip 2 weeks ago.
after.png (4.2 KB) - added by Don-vip 2 weeks ago.
josm_ticket_13124_gpx_heat_map_by_kidelo_v2.patch (59.5 KB) - added by kidelo 13 days ago.
GPX Heat Map Extension by kidelo, version 2
sample_inferneo_line_width_1.png (66.6 KB) - added by kidelo 13 days ago.
sample_inferneo_line_width_4.png (56.0 KB) - added by kidelo 13 days ago.
heatmap_v3_line_width_1.png (266.1 KB) - added by kidelo 8 days ago.
heatmap_v3_line_width_2.png (162.0 KB) - added by kidelo 8 days ago.
heatmap_v3_line_width_3.png (122.8 KB) - added by kidelo 8 days ago.
heatmap_v3_line_width_5.png (71.2 KB) - added by kidelo 8 days ago.
heatmap_v3_line_width_5_zoom_20m.png (74.4 KB) - added by kidelo 8 days ago.
heatmap_v3_line_width_5_zoom_20m_with_lower_layer_and_transparency.png (308.0 KB) - added by kidelo 8 days ago.
josm_ticket_13124_gpx_heat_map_by_kidelo_v3.patch (9.7 KB) - added by kidelo 8 days ago.
GPX Heat Map Extension by kidelo, version 3
josm_ticket_13124_gpx_heat_map_by_kidelo_v4.patch (4.6 KB) - added by kidelo 2 days ago.
GPX Heat Map Extension by kidelo, version 4

Download all attachments as: .zip

Change History (42)

comment:1 Changed 6 months ago by Klumbumbus

Can you give an example region, please?

comment:2 Changed 6 months ago by stoecker

A German "Autobahn" and neraby area, e.g. in the Ruhrgebiet should fit the requirements :-)

comment:3 Changed 6 months ago by transmit-receive

See e.g. here http://imgur.com/a/sKDPC
A heatmap would alleviate this mess of lines.

Maybe calculate a density of lines heatmap with e.g. 1m resolution for all the GPS traces after downloading them and store that in cache, so the calculation has not to be done every time the window is moved.

Changed 2 weeks ago by kidelo

GPX Heat Map Extension by kidelo

comment:4 Changed 2 weeks ago by kidelo

Happy New Year JOSM-Developers,

during my holiday at the end of last year, i had some hours / days left for realization of the requested feature, see the attached patch file.

If it looks acceptable, please merge it into the JOSM development branch.

Regards Kidelo

Features

  • HeatMap for GPS traces
    • dynamic adjustment of GPS trace visibility based on zoom level
    • block size depends on zoom level and line width ( normal adjustment via line width possible )
    • background becomes visible for higher zoom levels automatically ( borders of block are drawn only )
    • 4x color maps and 1x user adjustable color map
    • can't combined with GPX Alpha Blending mode
  • GPX Alpha Blending mode
    • Another alpha blending mode as alternative to the heat map or normal layer transparency
    • use the normal GPX color settings
    • can be used with bigger GPS trace points and with direction arrows
    • Only in "Expert Mode"

ColorMap

User : Derived Color Map based on user color ( use same layer / global color for GPS traces )
Inferno : Similar to "Inferno" Color Map ( more brighter values )
Viridis : Similar to "Viridis" Color Map ( more brighter values )
Wood : Brown-Green Color map
Heat : Red-White-Blue Color map

Example images

GPX View Normal:
https://i.imgsafe.org/e5d442ba59.jpg
Heatmap - Colormap: Inferno - Zoom 400m
https://i.imgsafe.org/e5d4633fae.jpg

Last edited 12 days ago by Don-vip (previous) (diff)

comment:5 Changed 2 weeks ago by stoecker

  • Cc Don-vip added
  • Milestone set to 17.01
  • Priority changed from normal to major
  • Summary changed from Enhanced GPS data rendering - heatmaps instead of dozens of lines to [PATCH] Enhanced GPS data rendering - heatmaps instead of dozens of lines

Looks really cool.

Comments about the code from the others?

I see that JavaDoc is missing (should also been done properly for the private functions), but otherwise the code seems good on first view.

comment:6 Changed 2 weeks ago by Don-vip

waw this looks awesome!
The code is very clean, I'm going to test and apply the patch right now.
Thank you for this gift!

comment:7 Changed 2 weeks ago by Don-vip

The patch doesn't work nice with the attached sample:


Then some remarks before applying the patch:

  1. the color map modes take a lot of lines, it would be cleaner to extract them to resource text files in a new folder data/gpx (data/gpx/inferno.txt, etc.) and load them at runtime
  2. Some code conventions:
  • don't use default values: replace private boolean heatMapEnabled = false; by private boolean heatMapEnabled;, private int heatMapDrawColorTableIdx = 0; by private int heatMapDrawColorTableIdx;, etc.
  • use diamond operator, replace new ArrayList<Integer>() by new ArrayList<>()
  • use proper javadoc format for added methods
  1. drawHeatMap() is huge (221 lines), it could probably be refactored into smaller methods
Last edited 2 weeks ago by Don-vip (previous) (diff)

Changed 2 weeks ago by Don-vip

Changed 2 weeks ago by Don-vip

Changed 2 weeks ago by Don-vip

comment:8 Changed 2 weeks ago by kidelo

Please check the width of line in configuration settings. The method drawHeatMap() does nothing when line width is 0.
I will harmonize the behavior in next step.

comment:9 Changed 2 weeks ago by kidelo

Feedback to remarks:

  1. a good idea, i will check it
  2. ok, i must just something learn about your style.
  3. yes i know. I think it is possible to move the processing parts of code into separated methods

Changed 13 days ago by kidelo

GPX Heat Map Extension by kidelo, version 2

comment:10 Changed 13 days ago by kidelo

I have reworks some parts of the patch, see attached version 2

  • add javadoc to new and old functions
  • fix some issues with coding style
  • move lookup tables for color maps from class code to resources /data/gpx/
  • Remove of some debug logs
  • restructure code of drawHeatmap()
  • adjust behavior for line width = 0

Changed 13 days ago by kidelo

Changed 13 days ago by kidelo

comment:11 Changed 13 days ago by kidelo

Now its works with default configuration settings:

comment:12 Changed 12 days ago by Don-vip

  • Resolution set to fixed
  • Status changed from new to closed

In 11431/josm:

fix #13124 - Enhanced GPS data rendering: add new heatmap mode (patch by kidelo)

comment:13 Changed 12 days ago by Don-vip

It's perfect! Thanks a lot for this really good stuff :)

comment:14 Changed 11 days ago by stoecker

Played with it a bit. Really, really nice.

Two things I noticed:

a) The heatmap ends before the window border resulting in an strange effect at the border when moving the window. Probably it should take a bit larger area into account for the calculations? Tried with a German motorway, where lots of data exists.

b) When you zoom in you loose the overview. E.g. properly separated lanes get a bunch of tracks again. Maybe a minimum setting would be good idea below which the automatic does no longer gets more detailed? For me that was when about 200m was displayed as zoom factor for a German highway and 50m for a third level road. Or a "keep zoom" (or better a "no deeper zoom") feature like for WMS?

Changed 8 days ago by kidelo

Changed 8 days ago by kidelo

Changed 8 days ago by kidelo

Changed 8 days ago by kidelo

Changed 8 days ago by kidelo

Changed 8 days ago by kidelo

GPX Heat Map Extension by kidelo, version 3

comment:15 Changed 8 days ago by kidelo

Some news:

a.) There was several small bugs. I have fixed them, now it works as expected.
b.) The idea behind the automatic algorithm is to get similar results at any zoom layer.

The amount of details for each zoom layer can be adjusted by the normal GPX line width parameter.

  • line width = 1 : more separate lines in zoom window. This is useful if you like to separate traffic lanes from each other.
  • line width = 2..4 : the average area becomes bigger therefore the tracks are merged.
  • line width = > 5 : more overview, very few details

In addition i have enabled an feature again, that was lost during refactoring. If the rectangles become very large with a higher zoom level, only the contour is drawn. So it is possible to see behind" the heat map, with an additional zoom-in. See the example pictures
Last but not least, i have slightly adjusted the parameters of the blending algorithm.

line width 1 / line width 2

line width 3 / line width 5

line width 5 + Zoom in / line width 5 + extra layer

comment:16 Changed 8 days ago by stoecker

  • Resolution fixed deleted
  • Status changed from closed to reopened

comment:17 Changed 7 days ago by Don-vip

  • Resolution set to fixed
  • Status changed from reopened to closed

In 11451/josm:

fix #13124 - Heat Map Extension (patch by kidelo)

comment:18 Changed 7 days ago by Don-vip

thanks! :)

comment:19 follow-up: Changed 5 days ago by aceman

Is the space after "(alpha blending)" needed?

comment:20 follow-up: Changed 5 days ago by bastiK

  • Cc michael2402 added
  • Resolution fixed deleted
  • Status changed from closed to reopened

Pretty impressive!

Some issues I see: Even after [11451], the heat map will not fill the entire mapview. In particular, the call

final Rectangle screenBounds = g.getDeviceConfiguration().getBounds();

returns the same value throughout a session, even when the window size is changed.

Another thing is that in

        final boolean imageRecalc = heatMapCacheVisibleSegments != visibleSegments.size() ||
                                    heatMapCacheZoomScale != zoomScale ||
                                    heatMapCacheLineWith != globalLineWidth;

the comparison heatMapCacheLineWith != globalLineWidth is always true, because in the default settings heatMapCacheLineWith and lineWidth is 0 but globalLineWidth is 1. This means imageRecalc will also be true each time.

How it is done with MapView.offscreenBuffer might be worth a look.

comment:21 in reply to: ↑ 19 Changed 5 days ago by kidelo

Replying to aceman:

Is the space after "(alpha blending)" needed?

Not really, we are free to change it. Some other opinions ?

comment:22 Changed 2 days ago by bastiK

See #14244, #14247.

comment:23 in reply to: ↑ 20 Changed 2 days ago by kidelo

Replying to bastiK:

Pretty impressive!

Some issues I see: Even after [11451], the heat map will not fill the entire mapview. In particular, the call

final Rectangle screenBounds = g.getDeviceConfiguration().getBounds();

returns the same value throughout a session, even when the window size is changed.

Another thing is that in

        final boolean imageRecalc = heatMapCacheVisibleSegments != visibleSegments.size() ||
                                    heatMapCacheZoomScale != zoomScale ||
                                    heatMapCacheLineWith != globalLineWidth;

the comparison heatMapCacheLineWith != globalLineWidth is always true, because in the default settings heatMapCacheLineWith and lineWidth is 0 but globalLineWidth is 1. This means imageRecalc will also be true each time.

How it is done with MapView.offscreenBuffer might be worth a look.

some changes:

1.) fixed, i have found an additional algorithm error where the gray images are mapped to the target image
2.) globalLineWidth != lineWidth -> fixed

Changed 2 days ago by kidelo

GPX Heat Map Extension by kidelo, version 4

comment:24 Changed 2 days ago by bastiK

In 11469/josm:

see #13124 - fix some Heat Map issues (patch by kidelo)

comment:25 Changed 2 days ago by bastiK

In 11470/josm:

see #13124 - better cache invalidation

Fixes a problem when zoomed out, so all gpx data is in the center of the mapview.
Then moving the map did not update the gpx layer.

comment:26 follow-up: Changed 2 days ago by bastiK

Thanks, I've changed the cache invalidation a bit.

One more issue is that it doesn't seem to work in WGS84 projection. You may find mv.getDist100Pixel() useful to replace mv.getScale() in the calculations.

comment:27 in reply to: ↑ 26 Changed 2 days ago by kidelo

Replying to bastiK:

Thanks, I've changed the cache invalidation a bit.

equalsInWindow(MapViewState other) -> really the better solution to ask the mapview. it knowns it when it was changed;

One more issue is that it doesn't seem to work in WGS84 projection. You may find mv.getDist100Pixel() useful to replace mv.getScale() in the calculations.

i will investigate it in next time

Add Comment

Modify Ticket

Change Properties
Set your email in Preferences
Action
as reopened The owner will remain team.
as The resolution will be set. Next status will be 'closed'.
to The owner will be changed from team to the specified user. Next status will be 'new'.
Next status will be 'needinfo'.The owner will change to transmit-receive
as duplicate The resolution will be set to duplicate. Next status will be 'closed'.The specified ticket will be cross-referenced with this ticket
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.