Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

overload hash and equality #147

Merged
merged 12 commits into from
Feb 15, 2023
Merged

overload hash and equality #147

merged 12 commits into from
Feb 15, 2023

Conversation

jw3126
Copy link
Member

@jw3126 jw3126 commented Dec 1, 2022

Before this PR we had:

geo != deepcopy(geo)

etc.

src/geos_types.jl Outdated Show resolved Hide resolved
Comment on lines 351 to 355
function Base.:(==)(g1::AbstractGeometry, g2::AbstractGeometry)
(typeof(g1) == typeof(g2)) || return false
get_context(g1) == get_context(g2) || return false
g1.ptr == g2.ptr
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this more like === than ==? This is false for two different instances of the same geometry, right? I see the GEOS C API has GEOSEquals_r and GEOSEqualsExact_r. Might they be more suitable for ==?

https://libgeos.org/doxygen/geos__c_8h.html

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sadly

    pt1 = readgeom("POINT(0.12345 2.000 0.1)")
    pt2 = readgeom("POINT(0.12345 2.000 0.10000001)")

are reported as equal from these libgeos methods even with zero tolerance.

Another possibility would be to check if coordinates are equal. What do you think @visr ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that equal because it falls under the precision? See also #66.

If libgeos says it's equal I'm not sure I want to argue that in a libgeos wrapper package ;)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I refactored to use equals only to discover #152

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So considering #152 we probably should not use equals to define ==. Should we do something like

function Base.:(==)(g1::AbstractGeometry, g2::AbstractGeometry)
    coordinates(g1) == coordinates(g2)
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignoring the z is pretty weird behaviour for == and I would guess not what most Julia users will expect from base object comparison?

Shouldn't we encourage the use of LibGEOS.equals to mean geos equality, and Base.== to mean more regular Julia equality:

Generic equality operator. Falls back to ===. Should be implemented for all types with a notion of equality, based on the abstract value that an instance represents. For example, all numeric types are compared by numeric value, ignoring type. Strings are compared as sequences of characters, ignoring encoding. For collections, == is generally called recursively on all contents, though other properties (like the shape for arrays) may also be taken into account.

I also think rotated triangles shouldn't be the same with ==. Thats LibGEOS.equals.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be interesting to see what other wrappers do here. What are you proposing for ==? Comparing the coordinates as proposed above might be an option, especially if we can implement that in a somewhat fast way.

Copy link
Member Author

@jw3126 jw3126 Feb 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed equality to coordinate comparison. The current implementation is slow. The reason is that it materializes every Point in the geometries, which means lots of heap allocations. If we are happy with the semantics of this but are unhappy with the performance I can reimplement it by directly working with pointers and thus eliding the heap allocs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm fine with the semantics. If you prefer to optimize performance in a separate PR that is also fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressing performance in a follow-up PR sounds great.

@jw3126
Copy link
Member Author

jw3126 commented Feb 15, 2023

LGTY @visr ?

@visr
Copy link
Member

visr commented Feb 15, 2023

Would you be able to rebase it?

@visr visr merged commit ffe4d6e into JuliaGeo:master Feb 15, 2023
@visr
Copy link
Member

visr commented Feb 15, 2023

Sorry no need, I just squeezed it.

@jw3126 jw3126 mentioned this pull request Feb 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants