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: `TopologyException: found non-noded intersection` error from overlay

See original GitHub issue

This question is the same, but hasn’t been answered

No because already asked and unanswered.


Does anyone have experience fixing TopologyException: found non-noded intersection error in an overlay? My understanding is that it comes from floating point errors and nearly parallel lines, but I can’t find a way to play with floating point precision tolerances in geopandas.

The usual .buffer(0) trick doesn’t seem to be helping either.

Full traceback if helpful:

TopologyException: found non-noded intersection between LINESTRING (-193712 361959, -193779 362021) and LINESTRING (-193712 361959, -193712 361959) at -193712.19705318063 361958.71668422205
---------------------------------------------------------------------------
TopologicalError                          Traceback (most recent call last)
<ipython-input-7-84d76b98e9c5> in <module>
----> 1 county_overlay = gp.overlay(county_rp, dist_rp, how="identity")

~/miniconda3/lib/python3.7/site-packages/geopandas/tools/overlay.py in overlay(df1, df2, how, make_valid, keep_geom_type)
    217             result = _overlay_union(df1, df2)
    218         elif how == "identity":
--> 219             dfunion = _overlay_union(df1, df2)
    220             result = dfunion[dfunion["__idx1"].notnull()].copy()
    221 

~/miniconda3/lib/python3.7/site-packages/geopandas/tools/overlay.py in _overlay_union(df1, df2)
    129     """
    130     dfinter = _overlay_intersection(df1, df2)
--> 131     dfsym = _overlay_symmetric_diff(df1, df2)
    132     dfunion = pd.concat([dfinter, dfsym], ignore_index=True, sort=False)
    133     # keep geometry column last

~/miniconda3/lib/python3.7/site-packages/geopandas/tools/overlay.py in _overlay_symmetric_diff(df1, df2)
     99     Overlay Symmetric Difference operation used in overlay function
    100     """
--> 101     dfdiff1 = _overlay_difference(df1, df2)
    102     dfdiff2 = _overlay_difference(df2, df1)
    103     dfdiff1["__idx1"] = range(len(dfdiff1))

~/miniconda3/lib/python3.7/site-packages/geopandas/tools/overlay.py in _overlay_difference(df1, df2)
     83     for geom, neighbours in zip(df1.geometry, sidx):
     84         new = reduce(
---> 85             lambda x, y: x.difference(y), [geom] + list(df2.geometry.iloc[neighbours])
     86         )
     87         new_g.append(new)

~/miniconda3/lib/python3.7/site-packages/geopandas/tools/overlay.py in <lambda>(x, y)
     83     for geom, neighbours in zip(df1.geometry, sidx):
     84         new = reduce(
---> 85             lambda x, y: x.difference(y), [geom] + list(df2.geometry.iloc[neighbours])
     86         )
     87         new_g.append(new)

~/miniconda3/lib/python3.7/site-packages/shapely/geometry/base.py in difference(self, other)
    670     def difference(self, other):
    671         """Returns the difference of the geometries"""
--> 672         return geom_factory(self.impl['difference'](self, other))
    673 
    674     def intersection(self, other):

~/miniconda3/lib/python3.7/site-packages/shapely/topology.py in __call__(self, this, other, *args)
     68             err = TopologicalError(
     69                     "This operation could not be performed. Reason: unknown")
---> 70             self._check_topology(err, this, other)
     71         return product
     72 

~/miniconda3/lib/python3.7/site-packages/shapely/topology.py in _check_topology(self, err, *geoms)
     37                     "Likely cause is invalidity of the geometry %s" % (
     38                         self.fn.__name__, repr(geom)))
---> 39         raise err
     40 
     41 

TopologicalError: This operation could not be performed. Reason: unknown

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:11 (8 by maintainers)

github_iconTop GitHub Comments

3reactions
brendan-wardcommented, Dec 7, 2020

It looks this can be corrected by reducing the precision of the geometries.

We currently have a PR in pygeos to set precision: https://github.com/pygeos/pygeos/pull/257 If possible, you may be able to check out that branch, build pygeos, and use the fix below.

It looks like this is an open issue to resolve in shapely: https://github.com/Toblerity/Shapely/issues/110

Overlap appears to function correctly after setting the precision.

>>> import pygeos as pg
>>> a.geometry = pg.set_precision(a.geometry.values.data, 1e-6)
>>> b.geometry = pg.set_precision(b.geometry.values.data, 1e-6)
>>> gp.overlay(a, b, how='identity')
     STATENAME            ID DISTRICT  ...   GISJOIN    pre_county                                           geometry
0   California  006083087001        1  ...  G0600150  2.627101e+09  MULTIPOLYGON (((-2171984.527 520516.198, -2171...
1   California  006083087002        2  ...  G0600150  2.627101e+09  MULTIPOLYGON (((-2144585.027 478787.108, -2144...
...

It may also be possible to round the coordinates in the geometries using the [apply](https://pygeos.readthedocs.io/en/latest/coordinates.html#pygeos.coordinates.apply) function in pygeos: (untested!)

>>> import numpy as np
>>>import pygeos as pg

# define a function that rounds the coordinates of every geometry in the array
>>> round = np.vectorize(lambda geom: pg.apply(geom, lambda g: g.round(3)))

>>> a.geometry = round(a.geometry.values.data)
>>> b.geometry = round(b.geometry.values.data)
1reaction
sankalpsharmaacommented, Feb 7, 2022

The solution given by @brendan-ward did not work for me, but the following seemed to work:

import shapely.wkt
df["geometry"] = df["geometry"].apply(lambda x: shapely.wkt.loads(shapely.wkt.dumps(x, rounding_precision=4)))

Cheers!

Read more comments on GitHub >

github_iconTop Results From Across the Web

found non-noded intersection between LINESTRING - Usage ...
Bug report Describe the bug Attempting to interact with an image in "this state" causes a popup with the title error followed by......
Read more >
Fixing non-noded intersection problem using PostGIS
Error performing intersection: TopologyException: found non-noded intersection between LINESTRING (571304 310990, 568465 264611) and LINESTRING (568465 ...
Read more >
NetTopology 'found non-noded intersection' Exception when ...
This partially works for me but now I am getting NetTopologySuite.Geometries.TopologyException: side location conflict: arg 0 [ (- ...
Read more >
488 (TopologyException unioning valid geometries [JTS fails])
union fail (3023[16]): TopologyException: found non-noded intersection between ... cause of robustness failure in the current JTS/GEOS overlay algorithm.
Read more >
[geos-devel] TopologyException: found non-noded intersection
... the following error: NOTICE: TopologyException: found non-noded intersection between ... Unfortunately the polygon overlay operations in GEOS/JTS aren't
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