question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

BUG: Why does a remote polygon with no touching edge get affected by difference?

See original GitHub issue
  • I have checked that this issue has not already been reported.

  • I have confirmed this bug exists on the latest version of geopandas.

  • (optional) I have confirmed this bug exists on the master branch of geopandas.


A polygon’s coordinates located on the top right gets affected by a difference operation on the bottom left. I expect that the upper right polygon shouldn’t be affected.

import pandas as pd
import geopandas as gpd

df = pd.DataFrame({"coords": [
    'POLYGON ((-100.5378104 45.175, -100.54 45.1712889, -100.5439257 45.175, -100.545 45.1776854, -100.5453305 45.18, -100.545 45.1803472, -100.5427045 45.18, -100.54 45.1789127, -100.5378104 45.175))',
    'POLYGON ((-101.9053297 44.3, -101.91 44.2978065, -101.9114672 44.3, -101.91 44.3012996, -101.9053297 44.3))',
    'POLYGON ((-101.9034962 44.295, -101.905 44.2944638, -101.91 44.2940891, -101.9126333 44.295, -101.915 44.2982986, -101.9158031 44.3, -101.915 44.3038377, -101.9132229 44.305, -101.91 44.3052182, -101.9090659 44.305, -101.905 44.3029345, -101.9001957 44.3, -101.9034962 44.295))'
]})
gdf = gpd.GeoSeries.from_wkt(df["coords"], name="geometry").to_frame()
gdf["value"] = ["a", "b", "a"]

gdf.plot()

diff = gdf.loc[gdf["value"] == "a"].difference(gdf.loc[gdf["value"] == "b"].unary_union)

print(gdf.iloc[0]["geometry"])
print(diff.iloc[0])

The coordinates change a bit; is this expected?

# original
POLYGON ((-100.5378104 45.175, -100.54 45.1712889, -100.5439257 45.175, -100.545 45.1776854, -100.5453305 45.18, -100.545 45.1803472, -100.5427045 45.18, -100.54 45.1789127, -100.5378104 45.175))

# difference
POLYGON ((-100.54 45.1712889, -100.5439257 45.175, -100.545 45.1776854, -100.5453305 45.18, -100.545 45.1803472, -100.5427045 45.18, -100.54 45.1789127, -100.5378104 45.175, -100.54 45.1712889))

image

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
brendan-wardcommented, Aug 23, 2021

The original and difference geometries are equal but start from a different vertex, and are completely equal once each has been normalized (start from consistent vertex). It is not unexpected that GEOS returns a geometry starting from a different vertex from an operation like difference.

>>> import pygeos as pg
>>> original = pg.Geometry('POLYGON ((-100.5378104 45.175, -100.54 45.1712889, -100.5439257 45.175, -100.545 45.1776854, -100.5453305 45.18, -100.545 45.1803472, -100.5427045 45.18, -100.54 45.1789127, -100.5378104 45.175))')
>>> difference = pg.Geometry('POLYGON ((-100.54 45.1712889, -100.5439257 45.175, -100.545 45.1776854, -100.5453305 45.18, -100.545 45.1803472, -100.5427045 45.18, -100.54 45.1789127, -100.5378104 45.175, -100.54 45.1712889))')
>>> pg.equals(original, difference)
True
>>> pg.equals_exact(original, difference)
False
>>> pg.equals_exact(pg.normalize(original), pg.normalize(difference))
True

However, the best approach is as @martinfleis suggests - first use a spatial index and only calculate the difference for those geometries that intersect; those that don’t intersect can be copied directly from the input (left side of difference operation). This will also be much better for performance, since difference can be an expensive spatial operation for many or complex geometries.

0reactions
martinfleiscommented, Aug 23, 2021

Thanks @brendan-ward!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Polygons beyond the edge of the screen cause confusing ...
I'd propose the following: Render polygon fillings only if the object is (a) completely loaded and (b) at least some percentage of its...
Read more >
27 Differences Between ArcGIS and QGIS - The Most Epic ...
QGIS Browser and ArcCatalog are stand-alone GIS data management applications. ArcCatalog ... But QGIS deserves an edge for remote sensing.
Read more >
Boundary Vertex - an overview
Boundary edges are edges in the mesh that belong to one triangle only; all other edges, being part of two triangles, are called...
Read more >
Normal map (Bump mapping) - Unity - Manual
Why is this? The reason is that the surface normal at each point used for reflecting light gradually varies across the width of...
Read more >
How Intersect works—Help | ArcGIS for Desktop
Cracking inserts vertices at the intersection of feature edges; clustering snaps together vertices that are within the xy tolerance. Discovers geometric ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found