Opened 9 years ago

Closed 6 years ago

Last modified 6 years ago

#731 closed defect (fixed)

GEOSEqualsExact returns False where GEOSEquals returns True

Reported by: Mike Taves Owned by: dbaston
Priority: minor Milestone: 3.7.0
Component: Default Version: 3.4.2
Severity: Unassigned Keywords:
Cc: sirsigurd

Description

For example using Shapely with GEOS 3.4.2-CAPI-1.8.2 r3921,

from shapely.wkt import loads
A = loads('LINESTRING (20 20, 20 100, 100 20, 20 20)')
B = loads('MULTILINESTRING ((20 20, 20 100, 60 60), (60 60, 100 20, 20 20))')
A.almost_equals(B)  # False
A.disjoint(B) # False
A.equals(B)  # True
A.relate(B)  # 1FFFFFFF2

Note that Shapely calls GEOSEqualsExact using the method named almost_equals. Both almost_equals and equals should be True, but only almost_equals is False.

And for a test case with precision issues, where GEOSEqualsExact should ideally return True is as follows:

A = loads('LINESTRING (20 20, 20 150, 100 20, 20 20)')
B = loads('MULTILINESTRING ((20 20, 20 150, 69.52380952380952 69.52380952380952), (69.52380952380952 69.52380952380952, 100 20, 20 20))')
A.almost_equals(B)  # False
A.disjoint(B)  # False
A.equals(B)  # False
A.relate(B)  # 1F1FFF1F2

Change History (14)

comment:1 by Mike Taves, 8 years ago

Similar behaviour (from here):

Geometry g1 = LINESTRING (0 0, 1 1);
Geometry g2 = MULTILINESTRING ((0 0, 1 1));

g1.equals(g2) // true
g1.equalsExact(g2, 0) // false

comment:2 by strk, 8 years ago

EqualsExact checks equality of structure (type and vertex-by-vertex match). Only, it accepts a tolerance for the vertex-by-vertex match (tolerance about distance between the points being matched).

comment:3 by strk, 8 years ago

Milestone: 3.4.33.6.1

Ticket retargeted after milestone deleted

in reply to:  2 comment:4 by sirsigurd, 7 years ago

Cc: sirsigurd added

Replying to strk:

EqualsExact checks equality of structure (type and vertex-by-vertex match).

Is this the intended behavior or just the current implementation? I believe this info should be added to docs in either case.

comment:5 by strk, 7 years ago

Intended behavior. Patch welcome.

comment:6 by strk, 7 years ago

Milestone: 3.6.13.6.2

Ticket retargeted after milestone closed

comment:7 by strk, 7 years ago

Milestone: 3.6.23.6.3

Ticket retargeted after milestone closed

comment:8 by robe, 6 years ago

Resolution: wontfix
Status: newclosed

comment:9 by dbaston, 6 years ago

Milestone: 3.6.33.7.0
Resolution: wontfix
Status: closedreopened

Adding a note to the docs seems reasonable to me.

comment:10 by dbaston, 6 years ago

Owner: changed from geos-devel@… to dbaston
Status: reopenednew

comment:11 by dbaston, 6 years ago

Any thoughts about the following?

/**
 * Determine pointwise equivalence of two geometries, by checking if each vertex of g2 is
 * within tolerance of the corresponding vertex in g1.
 * Unlike GEOSEquals, geometries that are topologically equivalent but have different
 * representations (e.g., LINESTRING (0 0, 1 1) and MULTILINESTRING ((0 0, 1 1)) ) are not
 * considered equivalent by GEOSEqualsExact.
 */
extern char GEOS_DLL GEOSEqualsExact(const GEOSGeometry* g1, const GEOSGeometry* g2, double tolerance);

comment:12 by robe, 6 years ago

I'm okay with the wording. Just go ahead and commit to 3.7 and master. If you don't I will before I release.

comment:13 by Daniel Baston <dbaston@…>, 6 years ago

Resolution: fixed
Status: newclosed

In 1be02b3/git:

Add comment explaining GEOSEqualsExact

Closes #731

comment:14 by Daniel Baston <dbaston@…>, 6 years ago

In bad46e4/git:

Add comment explaining GEOSEqualsExact

Closes #731

Note: See TracTickets for help on using tickets.