diff --git a/bound.go b/bound.go index 9c545ae..9ecc3df 100644 --- a/bound.go +++ b/bound.go @@ -8,6 +8,7 @@ var emptyBound = Bound{Min: Point{1, 1}, Max: Point{-1, -1}} // A Bound represents a closed box or rectangle. // To create a bound with two points you can do something like: +// // orb.MultiPoint{p1, p2}.Bound() type Bound struct { Min, Max Point diff --git a/clip/smartclip/smart.go b/clip/smartclip/smart.go index 1e2f4c0..82c8c0c 100644 --- a/clip/smartclip/smart.go +++ b/clip/smartclip/smart.go @@ -338,11 +338,11 @@ func smartWrap(box orb.Bound, input []orb.LineString, o orb.Orientation) orb.Mul const notOnSide = 0xFF -// 4 -// +-+ -// 1 | | 3 -// +-+ -// 2 +// : 4 +// : +-+ +// : 1 | | 3 +// : +-+ +// : 2 func pointSide(b orb.Bound, p orb.Point) uint8 { if p[1] == b.Max[1] { return 4 diff --git a/encoding/ewkb/scanner.go b/encoding/ewkb/scanner.go index 77ce8ba..c3af128 100644 --- a/encoding/ewkb/scanner.go +++ b/encoding/ewkb/scanner.go @@ -28,7 +28,7 @@ var ( // } type GeometryScanner struct { sridInPrefix bool - g interface{} + g any SRID int Geometry orb.Geometry Valid bool // Valid is true if the geometry is not NULL @@ -56,7 +56,7 @@ type GeometryScanner struct { // } else { // // NULL value // } -func Scanner(g interface{}) *GeometryScanner { +func Scanner(g any) *GeometryScanner { return &GeometryScanner{g: g} } @@ -75,20 +75,20 @@ func Scanner(g interface{}) *GeometryScanner { // Scan(&srid, wkb.Scanner(&p)) // // https://dev.mysql.com/doc/refman/5.7/en/gis-data-formats.html -func ScannerPrefixSRID(g interface{}) *GeometryScanner { +func ScannerPrefixSRID(g any) *GeometryScanner { return &GeometryScanner{sridInPrefix: true, g: g} } // Scan will scan the input []byte data into a geometry. // This could be into the orb geometry type pointer or, if nil, // the scanner.Geometry attribute. -func (s *GeometryScanner) Scan(d interface{}) error { +func (s *GeometryScanner) Scan(d any) error { s.Geometry = nil s.Valid = false var ( srid int - data interface{} + data any ) data = d diff --git a/encoding/ewkb/scanner_test.go b/encoding/ewkb/scanner_test.go index a3619d1..ba7d238 100644 --- a/encoding/ewkb/scanner_test.go +++ b/encoding/ewkb/scanner_test.go @@ -329,7 +329,7 @@ func TestScanPoint_errors(t *testing.T) { // error conditions cases := []struct { name string - data interface{} + data any err error }{ { @@ -496,7 +496,7 @@ func TestScanMultiPoint(t *testing.T) { func TestScanMultiPoint_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -590,7 +590,7 @@ func TestScanLineString(t *testing.T) { func TestScanLineString_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -684,7 +684,7 @@ func TestScanMultiLineString(t *testing.T) { func TestScanMultiLineString_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -772,7 +772,7 @@ func TestScanRing(t *testing.T) { func TestScanRing_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -866,7 +866,7 @@ func TestScanPolygon(t *testing.T) { func TestScanPolygon_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -966,7 +966,7 @@ func TestScanMultiPolygon(t *testing.T) { func TestScanMultiPolygon_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -1054,7 +1054,7 @@ func TestScanCollection(t *testing.T) { func TestScanCollection_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -1148,7 +1148,7 @@ func TestScanBound(t *testing.T) { func TestScanBound_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { diff --git a/encoding/internal/wkbcommon/scan.go b/encoding/internal/wkbcommon/scan.go index dea0a08..ff0927b 100644 --- a/encoding/internal/wkbcommon/scan.go +++ b/encoding/internal/wkbcommon/scan.go @@ -34,7 +34,7 @@ var ( // Scan will scan the input []byte data into a geometry. // This could be into the orb geometry type pointer or, if nil, // the scanner.Geometry attribute. -func Scan(g, d interface{}) (orb.Geometry, int, bool, error) { +func Scan(g, d any) (orb.Geometry, int, bool, error) { if d == nil { return nil, 0, false, nil } diff --git a/encoding/mvt/geometry.go b/encoding/mvt/geometry.go index fe754a6..db2342e 100644 --- a/encoding/mvt/geometry.go +++ b/encoding/mvt/geometry.go @@ -137,7 +137,7 @@ type keyValueEncoder struct { keyMap map[string]uint32 Values []*vectortile.Tile_Value - valueMap map[interface{}]uint32 + valueMap map[any]uint32 keySortBuffer []string } @@ -145,7 +145,7 @@ type keyValueEncoder struct { func newKeyValueEncoder() *keyValueEncoder { return &keyValueEncoder{ keyMap: make(map[string]uint32), - valueMap: make(map[interface{}]uint32), + valueMap: make(map[any]uint32), } } @@ -161,7 +161,7 @@ func (kve *keyValueEncoder) Key(s string) uint32 { return i } -func (kve *keyValueEncoder) Value(v interface{}) (uint32, error) { +func (kve *keyValueEncoder) Value(v any) (uint32, error) { // If a type is not comparable we can't figure out uniqueness in the hash, // we also can't encode it into a vectortile.Tile_Value. // So we encoded it as a json string, which is what other encoders @@ -191,7 +191,7 @@ func (kve *keyValueEncoder) Value(v interface{}) (uint32, error) { return i, nil } -func encodeValue(v interface{}) (*vectortile.Tile_Value, error) { +func encodeValue(v any) (*vectortile.Tile_Value, error) { tv := &vectortile.Tile_Value{} switch t := v.(type) { case string: @@ -242,7 +242,7 @@ func encodeValue(v interface{}) (*vectortile.Tile_Value, error) { return tv, nil } -func decodeValue(v *vectortile.Tile_Value) interface{} { +func decodeValue(v *vectortile.Tile_Value) any { if v == nil { return nil } diff --git a/encoding/mvt/geometry_test.go b/encoding/mvt/geometry_test.go index e4f628d..34b987a 100644 --- a/encoding/mvt/geometry_test.go +++ b/encoding/mvt/geometry_test.go @@ -208,8 +208,8 @@ func (s stringer) String() string { func TestEncodeValue(t *testing.T) { cases := []struct { name string - input interface{} - output interface{} + input any + output any }{ { name: "string", @@ -303,7 +303,7 @@ func TestEncodeValue(t *testing.T) { } // error if a weird type, but typical json decode result - input := map[string]interface{}{ + input := map[string]any{ "a": 1, "b": 2, } diff --git a/encoding/mvt/marshal.go b/encoding/mvt/marshal.go index 22640f2..2e4a7f8 100644 --- a/encoding/mvt/marshal.go +++ b/encoding/mvt/marshal.go @@ -96,7 +96,7 @@ func addFeature(layer *vectortile.Tile_Layer, kve *keyValueEncoder, f *geojson.F return addSingleGeometryFeature(layer, kve, f.Geometry, f.Properties, f.ID) } -func addSingleGeometryFeature(layer *vectortile.Tile_Layer, kve *keyValueEncoder, g orb.Geometry, p geojson.Properties, id interface{}) error { +func addSingleGeometryFeature(layer *vectortile.Tile_Layer, kve *keyValueEncoder, g orb.Geometry, p geojson.Properties, id any) error { geomType, encodedGeometry, err := encodeGeometry(g) if err != nil { return err @@ -141,7 +141,7 @@ func encodeProperties(kve *keyValueEncoder, properties geojson.Properties) ([]ui return tags, nil } -func convertID(id interface{}) *uint64 { +func convertID(id any) *uint64 { if id == nil { return nil } diff --git a/encoding/mvt/marshal_test.go b/encoding/mvt/marshal_test.go index 2c14d8c..aa464b1 100644 --- a/encoding/mvt/marshal_test.go +++ b/encoding/mvt/marshal_test.go @@ -284,11 +284,11 @@ func compareProperties(t testing.TB, result, expected geojson.Properties) { t.Helper() // properties - fr := map[string]interface{}(result) - fe := map[string]interface{}(expected) + fr := map[string]any(result) + fe := map[string]any(expected) for k, v := range fe { - if _, ok := v.([]interface{}); ok { + if _, ok := v.([]any); ok { // arrays are not included delete(fr, k) delete(fe, k) @@ -414,7 +414,7 @@ func loadGeoJSON(t testing.TB, tile maptile.Tile) map[string]*geojson.FeatureCol func TestMarshal_ID(t *testing.T) { cases := []struct { name string - id interface{} + id any val float64 }{ { diff --git a/encoding/mvt/unmarshal.go b/encoding/mvt/unmarshal.go index 7749419..968f433 100644 --- a/encoding/mvt/unmarshal.go +++ b/encoding/mvt/unmarshal.go @@ -45,7 +45,7 @@ func Unmarshal(data []byte) (Layers, error) { // decoder is here to reuse objects to save allocations/memory. type decoder struct { keys []string - values []interface{} + values []any features [][]byte valMsg *protoscan.Message @@ -429,7 +429,7 @@ func (gd *geomDecoder) done() bool { return !gd.iter.HasNext() } -func decodeValueMsg(msg *protoscan.Message) (interface{}, error) { +func decodeValueMsg(msg *protoscan.Message) (any, error) { for msg.Next() { switch msg.FieldNumber() { case 1: diff --git a/encoding/wkb/scanner.go b/encoding/wkb/scanner.go index a59a6e7..c4c462f 100644 --- a/encoding/wkb/scanner.go +++ b/encoding/wkb/scanner.go @@ -25,7 +25,7 @@ var ( // // NULL value // } type GeometryScanner struct { - g interface{} + g any Geometry orb.Geometry Valid bool // Valid is true if the geometry is not NULL } @@ -59,14 +59,14 @@ type GeometryScanner struct { // first 4 bytes and try again. This works for most use cases. // // For supported behavior see `ewkb.ScannerPrefixSRID` -func Scanner(g interface{}) *GeometryScanner { +func Scanner(g any) *GeometryScanner { return &GeometryScanner{g: g} } // Scan will scan the input []byte data into a geometry. // This could be into the orb geometry type pointer or, if nil, // the scanner.Geometry attribute. -func (s *GeometryScanner) Scan(d interface{}) error { +func (s *GeometryScanner) Scan(d any) error { if d == nil { return nil } diff --git a/encoding/wkb/scanner_test.go b/encoding/wkb/scanner_test.go index cd124f4..79481cb 100644 --- a/encoding/wkb/scanner_test.go +++ b/encoding/wkb/scanner_test.go @@ -191,7 +191,7 @@ func TestScanPoint_errors(t *testing.T) { // error conditions cases := []struct { name string - data interface{} + data any err error }{ { @@ -293,7 +293,7 @@ func TestScanMultiPoint(t *testing.T) { func TestScanMultiPoint_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -385,7 +385,7 @@ func TestScanLineString(t *testing.T) { func TestScanLineString_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -482,7 +482,7 @@ func TestScanMultiLineString(t *testing.T) { func TestScanMultiLineString_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -564,7 +564,7 @@ func TestScanRing(t *testing.T) { func TestScanRing_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -656,7 +656,7 @@ func TestScanPolygon(t *testing.T) { func TestScanPolygon_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -753,7 +753,7 @@ func TestScanMultiPolygon(t *testing.T) { func TestScanMultiPolygon_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -835,7 +835,7 @@ func TestScanCollection(t *testing.T) { func TestScanCollection_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { @@ -957,7 +957,7 @@ func TestScanBound(t *testing.T) { func TestScanBound_errors(t *testing.T) { cases := []struct { name string - data interface{} + data any err error }{ { diff --git a/encoding/wkt/benchmarks_test.go b/encoding/wkt/benchmarks_test.go index 07339ce..9935d49 100644 --- a/encoding/wkt/benchmarks_test.go +++ b/encoding/wkt/benchmarks_test.go @@ -102,7 +102,7 @@ func BenchmarkUnmarshalMultiPolygon(b *testing.B) { } } -func loadJSON(tb testing.TB, filename string, obj interface{}) { +func loadJSON(tb testing.TB, filename string, obj any) { data, err := os.ReadFile(filename) if err != nil { tb.Fatalf("failed to load mvt file: %v", err) diff --git a/geo/bound.go b/geo/bound.go index c3a8821..29494d3 100644 --- a/geo/bound.go +++ b/geo/bound.go @@ -76,16 +76,16 @@ func BoundWidth(b orb.Bound) float64 { return Distance(s1, s2) } -//MinLatitude is the minimum possible latitude +// MinLatitude is the minimum possible latitude var minLatitude = deg2rad(-90) -//MaxLatitude is the maximum possible latitude +// MaxLatitude is the maximum possible latitude var maxLatitude = deg2rad(90) -//MinLongitude is the minimum possible longitude +// MinLongitude is the minimum possible longitude var minLongitude = deg2rad(-180) -//MaxLongitude is the maximum possible longitude +// MaxLongitude is the maximum possible longitude var maxLongitude = deg2rad(180) func deg2rad(d float64) float64 { diff --git a/geojson/feature.go b/geojson/feature.go index acb5ca1..e595193 100644 --- a/geojson/feature.go +++ b/geojson/feature.go @@ -10,7 +10,7 @@ import ( // A Feature corresponds to GeoJSON feature object type Feature struct { - ID interface{} `json:"id,omitempty"` + ID any `json:"id,omitempty"` Type string `json:"type"` BBox BBox `json:"bbox,omitempty"` Geometry orb.Geometry `json:"geometry"` @@ -28,7 +28,7 @@ func NewFeature(geometry orb.Geometry) *Feature { return &Feature{ Type: "Feature", Geometry: geometry, - Properties: make(map[string]interface{}), + Properties: make(map[string]any), } } @@ -59,7 +59,7 @@ func (f Feature) MarshalBSON() ([]byte, error) { return bson.Marshal(newFeatureDoc(&f)) } -func newFeatureDoc(f *Feature) interface{} { +func newFeatureDoc(f *Feature) any { if len(f.ExtraMembers) == 0 { doc := &featureDoc{ ID: f.ID, @@ -76,11 +76,11 @@ func newFeatureDoc(f *Feature) interface{} { return doc } - var tmp map[string]interface{} + var tmp map[string]any if f.ExtraMembers != nil { tmp = f.ExtraMembers.Clone() } else { - tmp = make(map[string]interface{}, 3) + tmp = make(map[string]any, 3) } delete(tmp, "id") @@ -170,7 +170,7 @@ func (f *Feature) UnmarshalJSON(data []byte) error { f.ExtraMembers = Properties{} } - var val interface{} + var val any err := unmarshalJSON(value, &val) if err != nil { return err @@ -230,7 +230,7 @@ func (f *Feature) UnmarshalBSON(data []byte) error { f.ExtraMembers = Properties{} } - var val interface{} + var val any err := value.Unmarshal(&val) if err != nil { return err @@ -247,9 +247,9 @@ func (f *Feature) UnmarshalBSON(data []byte) error { } type featureDoc struct { - ID interface{} `json:"id,omitempty" bson:"id"` - Type string `json:"type" bson:"type"` - BBox BBox `json:"bbox,omitempty" bson:"bbox,omitempty"` - Geometry *Geometry `json:"geometry" bson:"geometry"` - Properties Properties `json:"properties" bson:"properties"` + ID any `json:"id,omitempty" bson:"id"` + Type string `json:"type" bson:"type"` + BBox BBox `json:"bbox,omitempty" bson:"bbox,omitempty"` + Geometry *Geometry `json:"geometry" bson:"geometry"` + Properties Properties `json:"properties" bson:"properties"` } diff --git a/geojson/feature_collection.go b/geojson/feature_collection.go index 72ef472..61113ce 100644 --- a/geojson/feature_collection.go +++ b/geojson/feature_collection.go @@ -61,12 +61,12 @@ func (fc FeatureCollection) MarshalBSON() ([]byte, error) { return bson.Marshal(m) } -func newFeatureCollectionDoc(fc FeatureCollection) map[string]interface{} { - var tmp map[string]interface{} +func newFeatureCollectionDoc(fc FeatureCollection) map[string]any { + var tmp map[string]any if fc.ExtraMembers != nil { tmp = fc.ExtraMembers.Clone() } else { - tmp = make(map[string]interface{}, 3) + tmp = make(map[string]any, 3) } tmp["type"] = featureCollection @@ -121,7 +121,7 @@ func (fc *FeatureCollection) UnmarshalJSON(data []byte) error { fc.ExtraMembers = Properties{} } - var val interface{} + var val any err := unmarshalJSON(value, &val) if err != nil { return err @@ -167,7 +167,7 @@ func (fc *FeatureCollection) UnmarshalBSON(data []byte) error { fc.ExtraMembers = Properties{} } - var val interface{} + var val any err := value.Unmarshal(&val) if err != nil { return err diff --git a/geojson/feature_collection_test.go b/geojson/feature_collection_test.go index 5b58813..232c73d 100644 --- a/geojson/feature_collection_test.go +++ b/geojson/feature_collection_test.go @@ -84,7 +84,7 @@ func TestUnmarshalFeatureCollection(t *testing.T) { } // check unmarshal/marshal loop - var expected interface{} + var expected any err = unmarshalJSON([]byte(rawJSON), &expected) if err != nil { t.Fatalf("unmarshal error: %v", err) @@ -95,7 +95,7 @@ func TestUnmarshalFeatureCollection(t *testing.T) { t.Fatalf("unmarshal error: %v", err) } - var raw interface{} + var raw any err = unmarshalJSON(data, &raw) if err != nil { t.Fatalf("unmarshal error: %v", err) @@ -487,7 +487,7 @@ func TestFeatureCollection_MarshalBSON_extraMembers(t *testing.T) { fc := NewFeatureCollection() fc.Append(NewFeature(orb.Point{1, 2})) - fc.ExtraMembers = map[string]interface{}{ + fc.ExtraMembers = map[string]any{ "a": 1.0, "b": 2.0, } diff --git a/geojson/feature_test.go b/geojson/feature_test.go index fb15be2..c2393a3 100644 --- a/geojson/feature_test.go +++ b/geojson/feature_test.go @@ -384,7 +384,7 @@ func TestMarshalRing(t *testing.T) { func TestFeature_MarshalBSON_extraMembers(t *testing.T) { f := NewFeature(orb.Point{1, 2}) - f.ExtraMembers = map[string]interface{}{ + f.ExtraMembers = map[string]any{ "a": 1.0, "b": 2.0, } diff --git a/geojson/geometry_test.go b/geojson/geometry_test.go index 5426589..91d9ba4 100644 --- a/geojson/geometry_test.go +++ b/geojson/geometry_test.go @@ -277,8 +277,8 @@ func TestHelperTypes(t *testing.T) { cases := []struct { name string geom orb.Geometry - helper interface{} - output interface{} + helper any + output any }{ { name: "point", diff --git a/geojson/json.go b/geojson/json.go index 4e2bea5..0d39db3 100644 --- a/geojson/json.go +++ b/geojson/json.go @@ -24,7 +24,7 @@ import "encoding/json" // // Note that any errors encountered during marshaling will be different. var CustomJSONMarshaler interface { - Marshal(v interface{}) ([]byte, error) + Marshal(v any) ([]byte, error) } = nil // CustomJSONUnmarshaler can be set to have the code use a different @@ -49,10 +49,10 @@ var CustomJSONMarshaler interface { // // Note that any errors encountered during unmarshaling will be different. var CustomJSONUnmarshaler interface { - Unmarshal(data []byte, v interface{}) error + Unmarshal(data []byte, v any) error } = nil -func marshalJSON(v interface{}) ([]byte, error) { +func marshalJSON(v any) ([]byte, error) { if CustomJSONMarshaler == nil { return json.Marshal(v) } @@ -60,7 +60,7 @@ func marshalJSON(v interface{}) ([]byte, error) { return CustomJSONMarshaler.Marshal(v) } -func unmarshalJSON(data []byte, v interface{}) error { +func unmarshalJSON(data []byte, v any) error { if CustomJSONUnmarshaler == nil { return json.Unmarshal(data, v) } diff --git a/geojson/properties.go b/geojson/properties.go index 0e0eca9..ea27c55 100644 --- a/geojson/properties.go +++ b/geojson/properties.go @@ -3,12 +3,14 @@ package geojson import "fmt" // Properties defines the feature properties with some helper methods. -type Properties map[string]interface{} +type Properties map[string]any // MustBool guarantees the return of a `bool` (with optional default). // This function useful when you explicitly want a `bool` in a single // value return context, for example: -// myFunc(f.Properties.MustBool("param1"), f.Properties.MustBool("optional_param", true)) +// +// myFunc(f.Properties.MustBool("param1"), f.Properties.MustBool("optional_param", true)) +// // This function will panic if the value is present but not a bool. func (p Properties) MustBool(key string, def ...bool) bool { v := p[key] @@ -30,7 +32,9 @@ func (p Properties) MustBool(key string, def ...bool) bool { // MustInt guarantees the return of an `int` (with optional default). // This function useful when you explicitly want a `int` in a single // value return context, for example: -// myFunc(f.Properties.MustInt("param1"), f.Properties.MustInt("optional_param", 123)) +// +// myFunc(f.Properties.MustInt("param1"), f.Properties.MustInt("optional_param", 123)) +// // This function will panic if the value is present but not a number. func (p Properties) MustInt(key string, def ...int) int { v := p[key] @@ -56,7 +60,9 @@ func (p Properties) MustInt(key string, def ...int) int { // MustFloat64 guarantees the return of a `float64` (with optional default) // This function useful when you explicitly want a `float64` in a single // value return context, for example: -// myFunc(f.Properties.MustFloat64("param1"), f.Properties.MustFloat64("optional_param", 10.1)) +// +// myFunc(f.Properties.MustFloat64("param1"), f.Properties.MustFloat64("optional_param", 10.1)) +// // This function will panic if the value is present but not a number. func (p Properties) MustFloat64(key string, def ...float64) float64 { v := p[key] @@ -82,7 +88,9 @@ func (p Properties) MustFloat64(key string, def ...float64) float64 { // MustString guarantees the return of a `string` (with optional default) // This function useful when you explicitly want a `string` in a single // value return context, for example: -// myFunc(f.Properties.MustString("param1"), f.Properties.MustString("optional_param", "default")) +// +// myFunc(f.Properties.MustString("param1"), f.Properties.MustString("optional_param", "default")) +// // This function will panic if the value is present but not a string. func (p Properties) MustString(key string, def ...string) string { v := p[key] diff --git a/go.mod b/go.mod index 97ce625..0a86856 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/paulmach/orb -go 1.25 +go 1.18 require ( github.com/gogo/protobuf v1.3.2