github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/geo/geomfn/binary_predicates.go (about)

     1  // Copyright 2020 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package geomfn
    12  
    13  import (
    14  	"github.com/cockroachdb/cockroach/pkg/geo"
    15  	"github.com/cockroachdb/cockroach/pkg/geo/geos"
    16  )
    17  
    18  // Covers returns whether geometry A covers geometry B.
    19  func Covers(a *geo.Geometry, b *geo.Geometry) (bool, error) {
    20  	if a.SRID() != b.SRID() {
    21  		return false, geo.NewMismatchingSRIDsError(a, b)
    22  	}
    23  	if !a.BoundingBoxIntersects(b) {
    24  		return false, nil
    25  	}
    26  	return geos.Covers(a.EWKB(), b.EWKB())
    27  }
    28  
    29  // CoveredBy returns whether geometry A is covered by geometry B.
    30  func CoveredBy(a *geo.Geometry, b *geo.Geometry) (bool, error) {
    31  	if a.SRID() != b.SRID() {
    32  		return false, geo.NewMismatchingSRIDsError(a, b)
    33  	}
    34  	if !a.BoundingBoxIntersects(b) {
    35  		return false, nil
    36  	}
    37  	return geos.CoveredBy(a.EWKB(), b.EWKB())
    38  }
    39  
    40  // Contains returns whether geometry A contains geometry B.
    41  func Contains(a *geo.Geometry, b *geo.Geometry) (bool, error) {
    42  	if a.SRID() != b.SRID() {
    43  		return false, geo.NewMismatchingSRIDsError(a, b)
    44  	}
    45  	if !a.BoundingBoxIntersects(b) {
    46  		return false, nil
    47  	}
    48  	return geos.Contains(a.EWKB(), b.EWKB())
    49  }
    50  
    51  // ContainsProperly returns whether geometry A properly contains geometry B.
    52  func ContainsProperly(a *geo.Geometry, b *geo.Geometry) (bool, error) {
    53  	if a.SRID() != b.SRID() {
    54  		return false, geo.NewMismatchingSRIDsError(a, b)
    55  	}
    56  	if !a.BoundingBoxIntersects(b) {
    57  		return false, nil
    58  	}
    59  	return geos.RelatePattern(a.EWKB(), b.EWKB(), "T**FF*FF*")
    60  }
    61  
    62  // Crosses returns whether geometry A crosses geometry B.
    63  func Crosses(a *geo.Geometry, b *geo.Geometry) (bool, error) {
    64  	if a.SRID() != b.SRID() {
    65  		return false, geo.NewMismatchingSRIDsError(a, b)
    66  	}
    67  	if !a.BoundingBoxIntersects(b) {
    68  		return false, nil
    69  	}
    70  	return geos.Crosses(a.EWKB(), b.EWKB())
    71  }
    72  
    73  // Equals returns whether geometry A equals geometry B.
    74  func Equals(a *geo.Geometry, b *geo.Geometry) (bool, error) {
    75  	if a.SRID() != b.SRID() {
    76  		return false, geo.NewMismatchingSRIDsError(a, b)
    77  	}
    78  	// Empty items are equal to each other.
    79  	// Do this check before the BoundingBoxIntersects check, as we would otherwise
    80  	// return false.
    81  	if a.Empty() && b.Empty() {
    82  		return true, nil
    83  	}
    84  	if !a.BoundingBoxIntersects(b) {
    85  		return false, nil
    86  	}
    87  	return geos.Equals(a.EWKB(), b.EWKB())
    88  }
    89  
    90  // Intersects returns whether geometry A intersects geometry B.
    91  func Intersects(a *geo.Geometry, b *geo.Geometry) (bool, error) {
    92  	if a.SRID() != b.SRID() {
    93  		return false, geo.NewMismatchingSRIDsError(a, b)
    94  	}
    95  	if !a.BoundingBoxIntersects(b) {
    96  		return false, nil
    97  	}
    98  	return geos.Intersects(a.EWKB(), b.EWKB())
    99  }
   100  
   101  // Overlaps returns whether geometry A overlaps geometry B.
   102  func Overlaps(a *geo.Geometry, b *geo.Geometry) (bool, error) {
   103  	if a.SRID() != b.SRID() {
   104  		return false, geo.NewMismatchingSRIDsError(a, b)
   105  	}
   106  	if !a.BoundingBoxIntersects(b) {
   107  		return false, nil
   108  	}
   109  	return geos.Overlaps(a.EWKB(), b.EWKB())
   110  }
   111  
   112  // Touches returns whether geometry A touches geometry B.
   113  func Touches(a *geo.Geometry, b *geo.Geometry) (bool, error) {
   114  	if a.SRID() != b.SRID() {
   115  		return false, geo.NewMismatchingSRIDsError(a, b)
   116  	}
   117  	if !a.BoundingBoxIntersects(b) {
   118  		return false, nil
   119  	}
   120  	return geos.Touches(a.EWKB(), b.EWKB())
   121  }
   122  
   123  // Within returns whether geometry A is within geometry B.
   124  func Within(a *geo.Geometry, b *geo.Geometry) (bool, error) {
   125  	if a.SRID() != b.SRID() {
   126  		return false, geo.NewMismatchingSRIDsError(a, b)
   127  	}
   128  	if !a.BoundingBoxIntersects(b) {
   129  		return false, nil
   130  	}
   131  	return geos.Within(a.EWKB(), b.EWKB())
   132  }