JuliaGeo / GeometryOps.jl

GeoInterface-based geometry operations
https://juliageo.org/GeometryOps.jl/
MIT License
29 stars 4 forks source link

Issue with `intersects` predicate for spatial joins #147

Open pierrethiriet opened 5 months ago

pierrethiriet commented 5 months ago

I am currently testing GeometryOps package to move away from R and the sf package for GIS work. I am facing a minor issue (misusage or bug ?) while using the spatial join function. The following example with GO.within is working as expected :

using FlexiJoins, DataFrames
import GeoInterface as GI
import GeometryOps as GO

pl = GI.Polygon([GI.LinearRing([(0, 0), (1, 0), (1, 1), (0, 0)])])
pu = GI.Polygon([GI.LinearRing([(0, 0), (0, 1), (1, 1), (0, 0)])])
poly_df = DataFrame(geometry = [pl, pu], color = [:red, :blue])
points = tuple.(rand(1000), rand(1000))
points_df = DataFrame(geometry = points)

joined_df_within = FlexiJoins.innerjoin(
 (points_df, poly_df),
    by_pred(:geometry, GO.within, :geometry)
)

But the GO.intersects predicate fails :

joined_df_intersects = FlexiJoins.innerjoin(
 (points_df, poly_df),
    by_pred(:geometry, GO.intersects, :geometry)
)

Giving the following error:

ERROR: MethodError: no method matching 
swap_sides(::typeof(GeometryOps.intersects))

While the predicate is otherwise working as expected

[GO.intersects(g1, g2) for g1 in points_df.geometry for g2 in poly_df.geometry]

The versions used are the following :

Julia 1.10
  [e37f2e79] FlexiJoins v0.1.33       
  [cf35fbd7] GeoInterface v1.3.4      
  [3251bfac] GeometryOps v0.1.5  

Thanks

asinghvi17 commented 5 months ago

This looks like we didn't define a method for FlexiJoins. Will take a look.

asinghvi17 commented 5 months ago

I should have a fix for this today or tomorrow. In the meanwhile, you can define the following functions:

FlexiJoins.swap_sides(::typeof(GO.intersects)) = !GO.disjoint
FlexiJoins.swap_sides(::typeof(!(GO.disjoint))) = GO.intersects
FlexiJoins.swap_sides(::typeof(GO.disjoint)) = !GO.intersects
FlexiJoins.swap_sides(::typeof(!(GO.intersects))) = GO.disjoint
pierrethiriet commented 5 months ago

Thanks a lot.