@@ -15,6 +15,8 @@ import (
1515
1616 "github.com/cockroachdb/cockroach/pkg/geo"
1717 "github.com/cockroachdb/cockroach/pkg/geo/geomfn"
18+ "github.com/cockroachdb/cockroach/pkg/geo/geopb"
19+ "github.com/cockroachdb/cockroach/pkg/geo/geoprojbase"
1820 "github.com/cockroachdb/cockroach/pkg/geo/geos"
1921 "github.com/cockroachdb/errors"
2022 "github.com/golang/geo/r3"
@@ -32,15 +34,15 @@ type s2GeometryIndex struct {
3234
3335var _ GeometryIndex = (* s2GeometryIndex )(nil )
3436
37+ // We adjust the clipping bounds to be smaller by this fraction, since using
38+ // the endpoints of face 0 in S2 causes coverings to spill out of that face.
39+ const clippingBoundsDelta = 0.01
40+
3541// NewS2GeometryIndex returns an index with the given configuration. All reads and
3642// writes on this index must use the same config. Writes must use the same
3743// config to correctly process deletions. Reads must use the same config since
3844// the bounds affect when a read needs to look at the exceedsBoundsCellID.
3945func NewS2GeometryIndex (cfg S2GeometryConfig ) GeometryIndex {
40- // We adjust the clipping bounds to be smaller by this fraction, since using
41- // the endpoints of face 0 in S2 causes coverings to spill out of that face.
42- const boundsDelta = 0.01
43-
4446 // TODO(sumeer): Sanity check cfg.
4547 return & s2GeometryIndex {
4648 rc : & s2.RegionCoverer {
@@ -53,17 +55,19 @@ func NewS2GeometryIndex(cfg S2GeometryConfig) GeometryIndex {
5355 maxX : cfg .MaxX ,
5456 minY : cfg .MinY ,
5557 maxY : cfg .MaxY ,
56- deltaX : boundsDelta * (cfg .MaxX - cfg .MinX ),
57- deltaY : boundsDelta * (cfg .MaxY - cfg .MinY ),
58+ deltaX : clippingBoundsDelta * (cfg .MaxX - cfg .MinX ),
59+ deltaY : clippingBoundsDelta * (cfg .MaxY - cfg .MinY ),
5860 }
5961}
6062
63+ // TODO(sumeer): also support index config with parameters specified by CREATE
64+ // INDEX.
65+
6166// DefaultGeometryIndexConfig returns a default config for a geometry index.
6267func DefaultGeometryIndexConfig () * Config {
6368 return & Config {
6469 S2Geometry : & S2GeometryConfig {
6570 // Arbitrary bounding box.
66- // TODO(sumeer): replace with parameters specified by CREATE INDEX.
6771 MinX : - 10000 ,
6872 MaxX : 10000 ,
6973 MinY : - 10000 ,
@@ -72,6 +76,38 @@ func DefaultGeometryIndexConfig() *Config {
7276 }
7377}
7478
79+ // GeometryIndexConfigForSRID returns a geometry index config for srid.
80+ func GeometryIndexConfigForSRID (srid geopb.SRID ) * Config {
81+ p , exists := geoprojbase .Projection (srid )
82+ if ! exists || p .Bounds == nil {
83+ return DefaultGeometryIndexConfig ()
84+ }
85+ b := p .Bounds
86+ minX , maxX , minY , maxY := b .MinX , b .MaxX , b .MinY , b .MaxY
87+ // There are projections where the min and max are equal e.g. 3571.
88+ // We need to have a valid rectangle as the geometry index bounds.
89+ if maxX - minX < 1 {
90+ maxX ++
91+ }
92+ if maxY - minY < 1 {
93+ maxY ++
94+ }
95+ // Expand the bounds by 2x the clippingBoundsDelta, to
96+ // ensure that shapes touching the bounds don't get
97+ // clipped.
98+ boundsExpansion := 2 * clippingBoundsDelta
99+ deltaX := (maxX - minX ) * boundsExpansion
100+ deltaY := (maxY - minY ) * boundsExpansion
101+ return & Config {
102+ S2Geometry : & S2GeometryConfig {
103+ MinX : minX - deltaX ,
104+ MaxX : maxX + deltaX ,
105+ MinY : minY - deltaY ,
106+ MaxY : maxY + deltaY ,
107+ S2Config : defaultS2Config ()},
108+ }
109+ }
110+
75111// A cell id unused by S2. We use it to index geometries that exceed the
76112// configured bounds.
77113const exceedsBoundsCellID = s2 .CellID (^ uint64 (0 ))
0 commit comments