darktable icon indicating copy to clipboard operation
darktable copied to clipboard

Occasional geolocation assignment errors involving polygon-shaped locations

Open codecrusher64 opened this issue 1 month ago • 0 comments

Is there an existing issue for this?

  • [x] I checked and did not find my issue in the already reported ones

Describe the bug

In the map view, I rarely observed assignment errors in darktable's locations module if the location's shape is a polygon. On the one hand, images located inside a polygon-shaped geolocation were sometimes not assigned to that location, and on the other hand, images were sometimes assigned to a geolocation they don't belong to.

Steps to reproduce

This issue is hard to reproduce.

Expected behavior

No response

Logfile | Screenshot | Screencast

No response

Commit

No response

Where did you obtain darktable from?

self compiled

darktable version

5.2.0

What OS are you using?

Linux

What is the version of your OS?

Ubuntu 25.10

Describe your system

No response

Are you using OpenCL GPU in darktable?

No

If yes, what is the GPU card and driver?

No response

Please provide additional context if applicable. You can attach files too, but might need to rename to .txt or .zip

I analyzed these errors and could isolate the problem to function _is_point_in_polygon() (src/common/map_locations.c). This function does not handle the following corner case correctly:

AFAIKS function _is_point_in_polygon() implements the ray casting algorithm. The observed assignment errors occurred when the latitude of one of the polygon's corners was identical to the latitude of the image's GPS location, i.e., when the cast ray intersected the polygon exactly through this corner. In this case, the current ray casting algorithm implementation counts this intersection twice for both line segments connected at this corner, instead of only counting it once. This inverts the final result of the ray casting algorithm, i.e., if the point lies inside a polygon, the function _is_point_in_polygon() returns false, and the other way round, as described above.

In detail, if there are two consecutive line segments of the polygon's edge represented by three consecutive corners and the intermediate corner has the same latitude lat as the point pt to be checked, i.e., pt->lat == lat, the condition in lines 266 - 267 is true for both line segments.

In fact, this condition should only be true for one of the two line segments. In other words, it should only be true if the point's latitude pt->lat is equal to either lat1 or lat2, but not both. The condition in lines 266 - 267 could be modified, for instance, to ((lat1 > pt->lat) != (lat2 > pt->lat)). A possible implementation example can be found here.

In addition, I recommend modifying line 269 to avoid division by very small values lat2 - lat1, in case lat1 ≈ lat2. An alternative implementation can also be found in the aforementioned implementation example.

codecrusher64 avatar Nov 30 '25 22:11 codecrusher64