v.to.rast: Fix crash when rasterizing points with the dense flag - #7837
v.to.rast: Fix crash when rasterizing points with the dense flag#7837Pranav-error wants to merge 2 commits into
Conversation
configure_plot() calls setup_plot() in dense mode and G_setup_plot() otherwise, but plot_points() always plotted through G_plot_point(), which uses the move and cont routines that only G_setup_plot() sets. Rasterizing a point map with -d therefore called a null function pointer. plot_points() now branches on dense the way plot_lines() already does, and dense_line.c gains plot_point_dense() for that path. The dot routines bound check the cell before writing, so a point outside the region is dropped rather than clipped by the caller. Fixes OSGeo#3105
|
Same fix, reached independently — I missed #3440 when I opened this, and it has priority. Two differences, one of which matters. Rounding. #3440's Dense mode sets up a different frame, cell edges: so in dense mode the That is from reading the two Tests. This adds a pytest module asserting a point map rasterises identically with and without Two things on my side either way: Happy for this to be closed in favour of #3440 with the rounding and the test folded in — it is 18 months older and I would rather not duplicate work again (I did that on #7839 last week). Just say which way you want it. |
The coordinates the test used were whole numbers, which land on cell edges where rounding to the nearest cell and truncating to the containing cell agree, so the test could not tell the two apart. Move the points inside cells and compare the cells themselves rather than only the count and sum. Also move plot_point_dense() above dense_line()'s comment block, which it was splitting, and say in its own comment why it truncates.
|
I built both versions and measured it, so here is the concrete answer to "how does this compare to #3440". The code fix is the same. Same three files, same The rounding differs, and #3440's is wrong in dense mode. #3440 copies Measured on the three points now in the test (region
All three land in the wrong cell — one shifted in column, one in row, one in both. This PR truncates, which is what The test now actually checks that. You were right that this adds tests, but the ones I pushed first were weak: they used whole-numbered coordinates, which sit on cell edges where both roundings agree, so they would have passed against #3440 too. Also fixed in that commit: I have no attachment to which PR carries this. If you would rather take #3440, I am happy for this to be closed and to send the rounding correction and the test as a follow-up to it — that seems fairer to @HuidaeCho, who got there first. Just say which. |
Fixes #3105.
configure_plot()inraster.ccallssetup_plot()in dense mode andG_setup_plot()otherwise, butplot_points()always plotted throughG_plot_point(). That function uses themoveandcontroutines which onlyG_setup_plot()sets, so rasterizing a point map with-dcalled a null function pointer:That matches the backtrace in the issue, where frame #0 is
0x0, frame #1 isG_plot_pointanddense=1.plot_points()now branches ondensethe wayplot_lines()already does, anddense_line.cgainsplot_point_dense()for that path. It converts with the dense state's ownX/Ymacros and truncates the waydense_line()does, so both paths agree on which cell a coordinate belongs to.cell_dot()anddcell_dot()already bound check before writing, so a point outside the region is dropped there rather than needing a check in the caller.Tests:
vector/v.to.rast/tests/v_to_rast_dense_test.pyrasterizes a three point map with and without the flag and checks the results match. Without the fix the test fails with return code -11; with it, it passes.Verified locally as well:
v.to.rast -don a point map exits 245 (SIGSEGV) before the change and produces the three expected cells after it.I used an AI assistant while investigating and writing this. I understand the change and can explain it.