Skip to content

DOC: describe geometry_area_perimeter size limit concretely - #1611

Open
Htet-Kaung-San wants to merge 2 commits into
pyproj4:mainfrom
Htet-Kaung-San:doc/geometry-area-perimeter-limits
Open

DOC: describe geometry_area_perimeter size limit concretely#1611
Htet-Kaung-San wants to merge 2 commits into
pyproj4:mainfrom
Htet-Kaung-San:doc/geometry-area-perimeter-limits

Conversation

@Htet-Kaung-San

Copy link
Copy Markdown

Closes #1592.

The note on Geod.geometry_area_perimeter said only:

There are a few limitations :

  • only works with areas up to half the size of the globe ;
  • certain large polygons may return negative values.

As #1592 points out, that doesn't say what "large" or "certain" mean — whether it's city-sized or continent-sized, and whether shape, poles or the antimeridian are involved.

Both bullets turn out to be the same rule. The area is reduced modulo the total area of the ellipsoid into (-A/2, A/2], so a region covering more than half the ellipsoid is reported as the negated area of its complement:

from pyproj import Geod
from shapely.geometry import Polygon

geod = Geod(ellps="WGS84")
nearly_global = Polygon([(-179, -89), (179, -89), (179, 89), (-179, 89)])
print(geod.geometry_area_perimeter(nearly_global)[0])
# -2833262901265.9062

That polygon is wound counter-clockwise and encloses 99.4% of the globe, but comes back as roughly -0.56% — the thin strip left outside it, negated.

So the answers to the two questions in the issue are concrete:

  • "large" means precisely "encloses more than half the ellipsoid" — about 2.55e14 m² on WGS84.
  • "certain" isn't about shape, proximity to a pole, or crossing the antimeridian. Size alone decides it.

I checked the (-A/2, A/2] bound holds across a grid of boxes spanning ±10° to ±179.9° longitude and ±10° to ±89.9° latitude.

The docstring already carries a separate warning that traversal direction is signed, CCW positive. That's the other reason a result can be negative, and unlike the size limit it applies at any size, so I cross-referenced the two rather than describing them independently.

Changes

  • Replace the vague note with the modulo rule, the WGS84 numbers, and an explicit statement of what does not matter.
  • Cross-reference the traversal-direction warning as the other, size-independent cause.
  • Add doctests for the wraparound and for recovering the enclosed area by adding the total ellipsoid area back.
  • Changelog entry.

Documentation only — no behavior change.

Testing

flake8, ruff and codespell are clean on the changed files, and blacken-docs --skip-errors leaves them unchanged. The docstring's doctests pass (14 examples, 0 failures), including the two new ones. The 99.4% figure is 99.4445% before rounding, so it isn't sitting on a rounding boundary.

@Htet-Kaung-San

Copy link
Copy Markdown
Author

Gentle nudge on this one — it's a docs-only change and the workflow is sitting at "action_required" (the first-time-contributor gate), so it hasn't run since I pushed the fixup.

Two things to save a review round:

  • The earlier CI failure was mine: the new examples are shapely-based, so on environments without shapely the doctest count went 6 → 10 and test_doctest_wrapper tripped. Fixed in 0db4de4 by trimming one example and updating the expected count to 8. Verified against a source build with PROJ 9.8.1 — passes at 8 without shapely, 0 with, and unmodified main still passes at 6.
  • The Conda ubuntu-latest job fails on an EPSG-name mismatch (RGF93 v1 to WGS 84 (1) vs ETRS89-FRA…), which is the pre-existing TST Fix tests after PROJ 9.8.1 EPSG database revert #1588 breakage also red on main, not something from this PR.

Happy to rebase or adjust wording if you'd prefer.

Htet-Kaung-San and others added 2 commits August 24, 2026 12:58
The note said only that the function "only works with areas up to half
the size of the globe" and that "certain large polygons may return
negative values", which does not say what "large" or "certain" mean.

Both are the same rule: the area is reduced modulo the total area of the
ellipsoid into (-A/2, A/2]. A region covering more than half the
ellipsoid therefore comes back as the negated area of its complement --
a polygon enclosing 99% of the globe returns about -1%, not +99%. So
"large" means precisely "more than half the ellipsoid" (about 2.55e14
m^2 on WGS84), and shape, proximity to a pole and crossing the
antimeridian do not matter on their own.

Also cross-reference the existing traversal-direction warning, since
that is the other, size-independent reason a result can be negative.

Adds a doctest for the wraparound and for recovering the enclosed area.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
test_doctest_wrapper asserts an exact number of expected doctest
failures, which is 6 when shapely is missing because the examples in
Geod.geometry_length and Geod.geometry_area_perimeter cannot build their
geometries. The examples added here are shapely-based too, so the count
rose to 10 and the assertion failed on every environment without
shapely -- the Docker python 3.12, 3.13 and 3.14 jobs. The 3.11 job has
shapely, expects 0 failures, and passed, which confirms the examples
themselves are correct.

Drop the ellipsoid-area arithmetic, which was a lot of docstring for one
point, and keep the sign demonstration. That takes the addition from
four failures to two, so the missing-shapely count becomes 8.

Verified against a source build with PROJ 9.8.1: with shapely absent the
wrapper passes at 8, with shapely present it passes at 0, and unmodified
main still passes at 6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@djhoese
djhoese force-pushed the doc/geometry-area-perimeter-limits branch from 0db4de4 to d4c28ed Compare August 24, 2026 17:58
@djhoese

djhoese commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

I just rebased your branch (be careful pulling locally, may need git reset --hard origin/geometry-area-perimeter-limits. This rebase should have pulled in the latest CI fixes and kept the git history pretty clean.

@djhoese djhoese added the documentation Docs need updating label Aug 24, 2026

@djhoese djhoese left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks reasonable to me. We'll wait for CI. Thanks!

Note: I won't pretend to fully understand the details here so if another maintainer wants to comment on this it would be appreciated.

Comment thread pyproj/geod.py
.. note:: | There are a few limitations :
| - only works with areas up to half the size of the globe ;
| - certain large polygons may return negative values.
.. note:: The area is reduced modulo the total area of the ellipsoid,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this reads very difficult (at least for the non-native speaker that I am), what does "reduced modulo" mean?

Comment thread pyproj/geod.py
Comment on lines +1038 to +1040
-1% of the total area, not +99%. Size is the only reason a
correctly oriented polygon comes back negative, and "large"
means precisely "more than half the ellipsoid" -- shape,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is no need to refer to "large" and explaining what it means, since the actual text using that word has now been removed (this now rather makes it confusing)

Comment thread pyproj/geod.py
... ])
... )
>>> geod.geometry_area_perimeter(nearly_global)[0] < 0
True

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not actually a "nearly global" polygon in practice, because for geodesic edges, it takes the shortest path on the sphere, so this is actually connecting -179 to 179 crossing the anti-meridian, i.e. an edge of 2 degrees long, and not 358 degrees long. As a consequence of that interpretation, this polygon is actually oriented clock-wise (although shapely, which is not using geodesic logic, will indicate this is CCW), and that is the reason this is giving a negative result

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Docs need updating

Projects

None yet

Development

Successfully merging this pull request may close these issues.

geometry_area_perimeter limitations not documented properly

3 participants