Я использую картопию, чтобы нарисовать несколько карт. В некоторых ситуациях при вызове .set_extent()
на моих осях я получаю такую ошибку:
Traceback (most recent call last):
File "<pyshell#315>", line 1, in <module>
ax.set_extent([bounds.X1.min(), bounds.X2.max(), bounds.Y1.min(), bounds.Y2.max()], cartopy.crs.AlbersEqualArea())
File "C:\FakeProgs\Python27\lib\site-packages\cartopy\mpl\geoaxes.py", line 587, in set_extent
projected = self.projection.project_geometry(domain_in_crs, crs)
File "C:\FakeProgs\Python27\lib\site-packages\cartopy\crs.py", line 172, in project_geometry
return getattr(self, method_name)(geometry, src_crs)
File "C:\FakeProgs\Python27\lib\site-packages\cartopy\crs.py", line 178, in _project_line_string
return cartopy.trace.project_linear(geometry, src_crs, self)
File "lib\cartopy\trace.pyx", line 109, in cartopy.trace.project_linear (lib/cartopy\trace.cpp:1135)
File "lib\cartopy\trace.pyx", line 71, in cartopy.trace.geos_from_shapely (lib/cartopy\trace.cpp:838)
OverflowError: Python int too large to convert to C long
Дело в том, что поведение несколько случайное. Не каждый вызов .set_extent()
делает это. Вот отрывок из одного сеанса интерпретатора (bounds
- это фрейм данных pandas, содержащий координаты ограничивающих прямоугольников для различных форм, которые я собираюсь позже добавить к осям).
>>> ax = pyplot.axes(projection=cartopy.crs.AlbersEqualArea())
... ax.set_extent([bounds.X1.min(), bounds.X2.max(), bounds.Y1.min(), bounds.Y2.max()], cartopy.crs.AlbersEqualArea())
# result is exception shown above
>>> [bounds.X1.min(), bounds.X2.max(), bounds.Y1.min(), bounds.Y2.max()]
[-2218681.0391451684,
-2103178.2838086924,
-195096.93292225525,
7468.2970529943705]
>>> [int(x) for x in [bounds.X1.min(), bounds.X2.max(), bounds.Y1.min(), bounds.Y2.max()]]
[-2218681, -2103178, -195096, 7468]
>>> [long(x) for x in [bounds.X1.min(), bounds.X2.max(), bounds.Y1.min(), bounds.Y2.max()]]
[-2218681L, -2103178L, -195096L, 7468L]
>>> ax = pyplot.axes(projection=cartopy.crs.AlbersEqualArea())
... ax.set_extent([bounds.X1.min(), bounds.X2.max(), bounds.Y1.min(), bounds.Y2.max()], cartopy.crs.AlbersEqualArea())
# works without problem!
Тот же код работал без изменения каких-либо переменных между ними.
Ошибка возникает из-за этой строки в trace,pyx
:
cdef ptr geos_geom = shapely_geom._geom
Я немного поискал и нашел старую фиксацию, связанную с аналогичной проблемой, возникшей на список рассылки.
Насколько я понимаю, проблема заключается в том, что атрибут _geom
этих объектов Shapely хранит своего рода указатель на объект в некоторой библиотеке C. Если целочисленное значение этого указателя слишком велико для C long, возникает ошибка. Ошибка не воспроизводится, потому что новый _geom
создается каждый раз, когда я создаю новый GeoAxes
, а новый _geom
может быть или не быть слишком большим.
Однако одна загадочная вещь заключается в том, что большая часть того, что я могу найти об этой ошибке (например, сообщение о фиксации вышеупомянутой фиксации), предполагает, что она должна быть проблемой только для 32-битных систем, но я использую 64-битную Python 2.7 с 64-битными версиями всех библиотек.
Итак, мой вопрос: прав ли я в том, что происходит? Если да, то почему я все еще получаю эти ошибки в 64-битной системе? И есть ли способ обойти это?