github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/geo/geoprojbase/geoprojbase.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 geoprojbase is a minimal dependency package that contains 12 // basic metadata and data structures for SRIDs and their CRS 13 // transformations. 14 package geoprojbase 15 16 import ( 17 "bytes" 18 "sort" 19 20 "github.com/cockroachdb/cockroachdb-parser/pkg/geo/geopb" 21 "github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgcode" 22 "github.com/cockroachdb/cockroachdb-parser/pkg/sql/pgwire/pgerror" 23 "github.com/cockroachdb/errors" 24 "github.com/golang/geo/s1" 25 "github.com/golang/geo/s2" 26 ) 27 28 // Proj4Text is the text representation of a PROJ4 transformation. 29 type Proj4Text struct { 30 cStr []byte 31 } 32 33 // MakeProj4Text returns a new Proj4Text with spec based on the given string. 34 func MakeProj4Text(str string) Proj4Text { 35 return Proj4Text{ 36 cStr: []byte(str + "\u0000"), 37 } 38 } 39 40 // String returns the string representation of the given proj text. 41 func (p *Proj4Text) String() string { 42 return string(p.cStr[:len(p.cStr)-1]) 43 } 44 45 // Bytes returns the raw bytes for the given proj text. 46 func (p *Proj4Text) Bytes() []byte { 47 return p.cStr 48 } 49 50 // Equal returns whether the two Proj4Texts are equal. 51 func (p *Proj4Text) Equal(o Proj4Text) bool { 52 return bytes.Equal(p.cStr, o.cStr) 53 } 54 55 // Bounds represents the projected or lat/lng bounds. 56 type Bounds struct { 57 MinX float64 58 MaxX float64 59 MinY float64 60 MaxY float64 61 } 62 63 // ProjInfo is a struct containing metadata related to a given SRID. 64 type ProjInfo struct { 65 // SRID is the SRID of the projection. 66 SRID geopb.SRID 67 // AuthName is the authority who has provided this projection (e.g. ESRI, EPSG). 68 AuthName string 69 // AuthSRID is the SRID the given AuthName interprets the SRID as. 70 AuthSRID int 71 // SRText is the WKT representation of the projection. 72 SRText string 73 // Proj4Text is the PROJ4 text representation of the projection. 74 Proj4Text Proj4Text 75 // Bounds defines the bounds (projected or lat/lng) of the given coordinate system. 76 Bounds Bounds 77 78 // Denormalized fields. 79 80 // IsLatLng stores whether the projection is a LatLng based projection (denormalized from above) 81 IsLatLng bool 82 // The spheroid represented by the SRID. 83 Spheroid Spheroid 84 } 85 86 // Spheroid represents a spheroid object. 87 type Spheroid interface { 88 Inverse(a, b s2.LatLng) (s12, az1, az2 float64) 89 InverseBatch(points []s2.Point) float64 90 AreaAndPerimeter(points []s2.Point) (area float64, perimeter float64) 91 Project(point s2.LatLng, distance float64, azimuth s1.Angle) s2.LatLng 92 Radius() float64 93 Flattening() float64 94 SphereRadius() float64 95 } 96 97 // ErrProjectionNotFound indicates a project was not found. 98 var ErrProjectionNotFound error = errors.Newf("projection not found") 99 100 // Projection returns the ProjInfo for the given SRID, as well as an 101 // error if the projection does not exist. 102 func Projection(srid geopb.SRID) (ProjInfo, error) { 103 projections := getProjections() 104 p, exists := projections[srid] 105 if !exists { 106 return ProjInfo{}, errors.Mark( 107 pgerror.Newf(pgcode.InvalidParameterValue, "projection for SRID %d does not exist", srid), 108 ErrProjectionNotFound, 109 ) 110 } 111 return p, nil 112 } 113 114 // MustProjection returns the ProjInfo for the given SRID, panicking if the 115 // projection does not exist. 116 func MustProjection(srid geopb.SRID) ProjInfo { 117 ret, err := Projection(srid) 118 if err != nil { 119 panic(err) 120 } 121 return ret 122 } 123 124 // AllProjections returns a sorted list of all projections. 125 func AllProjections() []ProjInfo { 126 projections := getProjections() 127 ret := make([]ProjInfo, 0, len(projections)) 128 for _, p := range projections { 129 ret = append(ret, p) 130 } 131 sort.Slice(ret, func(i, j int) bool { 132 return ret[i].SRID < ret[j].SRID 133 }) 134 return ret 135 }