@@ -225,19 +225,49 @@ _touches(
225225
226226# # Geometries touch multi-geometry/geometry collections
227227
228- #= Geometry touch a multi-geometry or a collection if the geometry touches at
229- least one of the elements of the collection. =#
228+ #=
229+
230+ A geometry touches a multi-geometry or a collection if the geometry touches at
231+ least one of the elements of the collection.
232+
233+ This is a bit tricky to implement - we have to actually check every geometry,
234+ and make sure that each geom is either disjoint or touching.
235+
236+ Problem here is that we would end up doing double the work.
237+
238+ Either you check disjointness first, and then check touches - in which case
239+ you have already done the work for the touches check, but can't take advantage of it.
240+
241+ Or you check touches first, and if that is false, you check disjointness. But if touches failed,
242+ and you don't know _why_ it was false (disjoint or contained / intersecting), you have to iterate
243+ over every point twice -- again!
244+
245+
246+ At this point we actually need a fast return function...or some more detail returned from the process functions.
247+
248+ That's a project for later though. Right now we need to get this correct, so I'm going to do the dumb thing.
249+
250+ =#
230251function _touches (
231252 :: Union{GI.PointTrait, GI.AbstractCurveTrait, GI.PolygonTrait} , g1,
232253 :: Union {
233254 GI. MultiPointTrait, GI. AbstractMultiCurveTrait,
234255 GI. MultiPolygonTrait, GI. GeometryCollectionTrait,
235256 }, g2,
236257)
258+ has_touched = false
237259 for sub_g2 in GI. getgeom (g2)
238- ! touches (g1, sub_g2) && return false
260+ if touches (g1, sub_g2)
261+ has_touched = true
262+ else
263+ # if not touching, they are either intersecting or disjoint
264+ # if disjoint, then we can continue
265+ # else, we can short circuit, since the geoms are not touching and not disjoint
266+ # i.e. they are intersecting
267+ disjoint (g1, sub_g2) || return false
268+ end
239269 end
240- return true
270+ return has_touched
241271end
242272
243273# # Multi-geometry/geometry collections cross geometries
@@ -251,8 +281,16 @@ function _touches(
251281 }, g1,
252282 :: GI.AbstractGeometryTrait , g2,
253283)
284+ has_touched = false
254285 for sub_g1 in GI. getgeom (g1)
255- ! touches (sub_g1, g2) && return false
286+ if touches (sub_g1, g2)
287+ has_touched = true
288+ else
289+ # if not touching, they are either intersecting or disjoint
290+ # if disjoint, then we can continue
291+ # else, we can short circuit, since the geoms are not touching and not disjoint
292+ disjoint (sub_g1, g2) || return false
293+ end
256294 end
257- return true
295+ return has_touched
258296end
0 commit comments