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.

Quirky behaviour with predicates

See original GitHub issue

I have noticed some behaviour which does not seem to match with the Shapely documents. I don’t know if it is a bug, if the documentation is wrong, or I’m misunderstanding something about the package.

The manual says: The interior, boundary, and exterior sets of a feature are mutually exclusive and their union coincides with the entire plane.

It additionally says, of the .touches() method: Returns True if the objects have at least one point in common and their interiors do not intersect with any part of the other.

I’m going to set up three linestrings:

>>> Square = shapely.geometry.LineString([(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)])
>>> Triangle = shapely.geometry.LineString([(1, 0), (0.5, 1), (1.5, 1), (1, 0)])
>>> TriangleMinusClosure = shapely.geometry.LineString([(1, 0), (0.5, 1), (1.5, 1)])

The triangle intersects the square in the middle of the bottommost segment. The TriangleMinusClosure is simply two legs of the triangle without the closing segment; it still intersects the square in the middle of the bottommost segment.

>>> Int1 = Square.intersection(Triangle)
>>> Int2 = Square.intersection(TriangleMinusClosure)
>>> type(Int1)
<class 'shapely.geometry.point.Point'>
>>> type(Int2)
<class 'shapely.geometry.point.Point'>
>>> Int1 == Int2
True

So far, so good. It falls apart when I try to apply .touches():

>>> Triangle.touches(Square)
False
>>> TriangleMinusClosure.touches(Square)
True

Both Triangle and TriangleMinusClosure have at least one point in common with Square. To fulfill the other half of the .touches() requirement, they must not have interior points intersecting with Square. Since the interior, boundary, and exterior of a given object are mutually exclusive, and the boundary of a linestring is its two endpoints, I would expect both to touch the square–their only interaction with the square is a boundary point.

I see that the closed linestring is reporting an empty boundary, which would imply (?) that the interior is is everything on the triangle, which would explain the False touch result.

>>> list(Triangle.boundary)
[]
>>> list(TriangleMinusClosure.boundary)
[<shapely.geometry.point.Point object at 0x00000223AC54A880>, <shapely.geometry.point.Point object at 0x00000223AC54A7F0>]

The DE-9IM code does seem to indicate a pointwise intersection of the triangle’s interior with the square’s interior:

>>> Triangle.relate(Square)
'0F1FFF1F2'
>>> TriangleMinusClosure.relate(Square)
'FF10F01F2'

Windows 10 Home 21H1

Shapely version 1.8.1.post1 via pip

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
jorisvandenbosschecommented, Sep 27, 2022

Thanks! I see, and indeed a Point also doesn’t touch another identical Point (shapely.Point(1, 1).touches(shapely.Point(1, 1)) gives False), because in those case it are the interiors that intersect.

0reactions
dr-jtscommented, Sep 27, 2022

Something else I am wondering on this topic: our manual says that a Point is considered to have an interior of that single point, and an empty boundary. But if you follow that logic, a Point should never touch another geometry? (since the intersecting point will always lie in the interior) In practice, Points do touch other geometries (eg shapely.box(0, 0, 1, 1).touches(shapely.Point(0, 0)) gives True), so that is maybe special cases to give more sensible behaviour?

Here’s the definition of Touches from the SFS: image It requires that the geometries intersect, but their interiors are disjoint. This is the case in the Polygon/Point case above - the Interior of the Point intersects the Boundary of the Polygon, but not its Interior.

Read more comments on GitHub >

github_iconTop Results From Across the Web

List (exhaustive-ish) of predicates with “quirky subject ...
I'm trying to find an exhaustive-ish list of predicates with quirky subjects (Lexikalischer Kasus) to get a better idea of how many of...
Read more >
Quirky alternations of transitivity: The case of ingestive ...
We argue that the crucial property of ingestive predicates that is responsible for some of their marked transitivity behaviour is that the Agent...
Read more >
Derivation of Heard-of Predicates from Elementary Behavioral ...
A set of sequences, called a heard-of predicate, defines the legal communication behaviors – that is to say, a model of communication.
Read more >
Unusual behaviour of findall - prolog - Stack Overflow
In general, succeeding predicates bind some variables. When at some later point something fails (or, equivalently, the user presses ...
Read more >
Writing flexible filters for your data using Predicates
In lambda calculus, a predicate is an expression that evaluates to either true of false. ... To filter the data we would use...
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