mapnik / python-mapnik

Python bindings for mapnik
GNU Lesser General Public License v2.1
157 stars 90 forks source link

Projection.inverse only returns infinities (proj 7.0, mapnik master) #246

Open craigds opened 2 years ago

craigds commented 2 years ago

On mapnik 3.0.24 and proj 4.x I can do this:

>>> from mapnik import Projection, Coord
>>> proj.inverse(Coord(1172741.5121814408, 4999945.322510758))
Coord(167.57662616547188,-45.02500691788448)

However, on mapnik master with proj 7.0 and our fork of python-mapnik with the proj6 branch merged in, I only get infinities:

ipdb> proj = Projection('EPSG:2193')
ipdb> proj.inverse(Coord(4999945.322510758, 1172741.5121814408))
Coord(inf,inf)

We thought this might be an axis order issue (EPSG:2193 is y,x) but reversing the order doesn't help:

ipdb> proj.inverse(Coord(1172741.5121814408, 4999945.322510758))
Coord(inf,inf)

Thanks

donno commented 1 year ago

I've observed test_wgs84_inverse_forward in projection_test.py fails for the same reason with the proj6 branch merged in.

AssertionError: inf != 43.3333092669 within 7 places (inf difference)
  Traceback:
    File "S:\python-mapnik\test\python_tests\projection_test.py", line 34, in test_wgs84_inverse_forward
      assert_almost_equal(p.inverse(c).y, c.y)
    File "unittest\case.py", line 899, in assertAlmostEqual
HotPepperDaddy commented 11 months ago

I'm using mapnik master, python-mapnik proj6 branch, proj 9.1 all on Centos 9 stream.

Projection.forward also has this problem with infinites. I don't know what's wrong with mapnik internally but as a workaround I did this:

google_projection = "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over"
prj_google = mapnik.Projection(google_projection)
prj_4326 = mapnik.Projection('epsg:4326')
prj_4326_to_google = mapnik.ProjTransform(prj_4326, prj_google)

c = prj_4326_to_google.forward(mapnik.Coord(lng, lat))

I hope this helps someone!

hholzgra commented 3 months ago

I applied the ProjTransform workround to get my stuff working on both Debian 11 and 12, but while that worked fine for test cases on both it segfaults in actual code on Debian 11 with the old libproj.

The ProjTransform object can be used just fine in the method that creates it, but later in a different method, with same object reference and same input coordinates, the forward() call on Debian 11 just crashes.

This happens with the MapOSMatic renderer right now, so it's a non-trivial use case that I can't easily create a self contained minimal test case from, although I'm trying.

I'm also not really getting a good gdb backtrace for this as for some strange reason there doesn't seem to be a Debian dbgsym package for the Mapnik library or the Python bindings ...

hholzgra commented 3 months ago

Turns out with the older proj version the mapnik.Projection instances the mapnik.ProjectionTransfromation need to be kept in scope to prevent crashes

Will create a separate report for that.