@@ -225,19 +225,49 @@ _touches(
225
225
226
226
# # Geometries touch multi-geometry/geometry collections
227
227
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
+ =#
230
251
function _touches (
231
252
:: Union{GI.PointTrait, GI.AbstractCurveTrait, GI.PolygonTrait} , g1,
232
253
:: Union {
233
254
GI. MultiPointTrait, GI. AbstractMultiCurveTrait,
234
255
GI. MultiPolygonTrait, GI. GeometryCollectionTrait,
235
256
}, g2,
236
257
)
258
+ has_touched = false
237
259
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
239
269
end
240
- return true
270
+ return has_touched
241
271
end
242
272
243
273
# # Multi-geometry/geometry collections cross geometries
@@ -251,8 +281,16 @@ function _touches(
251
281
}, g1,
252
282
:: GI.AbstractGeometryTrait , g2,
253
283
)
284
+ has_touched = false
254
285
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
256
294
end
257
- return true
295
+ return has_touched
258
296
end
0 commit comments