Skip to content

[Bug]: Polygon areas around a pole: 0 km² for a cap written as a box, the rest of the Earth for a loop around the North Pole #1353

Closed

Description

@flight1973

Before you start

  • I searched the existing issues and did not find a duplicate.
  • This is a bug report, not a usage question (questions belong in Discussions).

What happened?

A polygon around a pole gets a different area, and in some tools a wrong one, depending on which tool measures it. Measured on main (8ebc4ce) for a cap above 80°N, whose true area on the WGS 84 ellipsoid (the zone formula) is 3.909 million km²:

Ring Attribute table's Calculate Geometry, Measure Area panel Calculate Geometry Attributes tool
Cut at ±180° and closed along the pole, with one edge from (-180°, 80°N) to (180°, 80°N) 3.875 M km² (the sphere's), perimeter 2,224 km 0 km², perimeter 2,234 km
The same with a vertex every degree along 80°N 3.875 M km² (the sphere's, 0.9% low), perimeter 9,175 km 3.908 M km², perimeter 9,215 km
A loop at 80°N, from 0° to 359°, not cut at ±180° 506 M km² (the rest of the Earth), either winding 3.908 M km²
A loop of 12 points every 30° at 80°N 506 M km² 3.736 M km² (the geodesic 12-gon)

This corrects my #1033 comment, which put the 0 km² on the attribute table's Calculate Geometry and called a cap with vertices along the parallel right: the 0 km² is the Calculate Geometry Attributes tool's, and the attribute table is 0.9% low either way.

Tabulate Intersection's area_km2 uses the same routine as the Calculate Geometry Attributes tool, on each clipped part. Spatial Join's Largest overlap uses a third, the sphere's geodesic_ring_area_m2.

The causes:

Steps to reproduce

  1. Save boxcap.geojson: {"type":"FeatureCollection","features":[{"type":"Feature","properties":{"name":"box"},"geometry":{"type":"Polygon","coordinates":[[[-180,80],[180,80],[180,90],[-180,90],[-180,80]]]}}]}
  2. Run both measures and export the result:
    rustgis-cli run --data boxcap.geojson \
      --cmd 'gp.run={"tool":"calculateGeometry","params":{"input":"boxcap"}}' \
      --cmd 'edit.calculateGeometry={"layer":"boxcap","field":"table_km2","create":true,"overwrite":true,"property":"area","unit":"km2","scope":"all"}' \
      --cmd 'share.exportLayer={"layer":"boxcap","path":"out_box.geojson"}'
    
    out_box.geojson has area_km2 0 (the Calculate Geometry Attributes tool) and table_km2 3,874,523 (the attribute table's Calculate Geometry).
  3. The same with the 12-point loop [[0,80],[30,80],[60,80],[90,80],[120,80],[150,80],[180,80],[210,80],[240,80],[270,80],[300,80],[330,80],[0,80]]: area_km2 3,736,196 and table_km2 506,329,425.

Expected behavior

#1033 settled the form for polygons around a pole: cut at ±180° and closed along the pole ("Pole-enclosing form: yes, keep it as the canonical form"). A cap written that way should measure the same in every tool: 3.909 M km² with its 80°N edge read as the parallel, and within 0.001 M km² of that with a vertex every degree, whichever line its edges follow. Two fixes need no wider decision, and the third only the choice of side for a loop around a pole (#1354):

  • a 360° edge isn't unwrapped to nothing;
  • an edge along the pole doesn't send the ring to the sphere;
  • a ring winding a full turn gets the same side at either pole.

A way to make the non-geodesic measures exact: add the authalic latitude ξ and radius R_q to rustgis_geom. proj4rs has them only inside the crate. Then any ring whose edges are paths in longitude and latitude has the exact area R_q² ∮ sin ξ dλ: in closed form along a parallel, and by quadrature along an edge straight in longitude and latitude or on the map. Geodesic edges keep GeographicLib's PolygonArea. Which line an edge follows is a wider question (issue to follow). Tabulate Intersection's shares must still add up, so they need measuring along the lines the overlay cuts along.

How are you running RustGIS?

Command line (rustgis-cli)

Version

main at 8ebc4ce, built from source

Operating system, browser and graphics

macOS (Apple silicon)

Sample data

The files in the steps above. I can take the three fixes and the authalic helpers after #1347–#1349 land.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions