fixed dependencies

This commit is contained in:
nuknal
2024-10-24 15:46:01 +08:00
parent d16a5bd9c0
commit 1161e8d054
2005 changed files with 690883 additions and 0 deletions

132
vendor/github.com/paulmach/orb/geojson/README.md generated vendored Normal file
View File

@@ -0,0 +1,132 @@
# orb/geojson [![Godoc Reference](https://pkg.go.dev/badge/github.com/paulmach/orb)](https://pkg.go.dev/github.com/paulmach/orb/geojson)
This package **encodes and decodes** [GeoJSON](http://geojson.org/) into Go structs
using the geometries in the [orb](https://github.com/paulmach/orb) package.
Supports both the [json.Marshaler](https://pkg.go.dev/encoding/json#Marshaler) and
[json.Unmarshaler](https://pkg.go.dev/encoding/json#Unmarshaler) interfaces.
The package also provides helper functions such as `UnmarshalFeatureCollection` and `UnmarshalFeature`.
The types also support BSON via the [bson.Marshaler](https://pkg.go.dev/go.mongodb.org/mongo-driver/bson#Marshaler) and
[bson.Unmarshaler](https://pkg.go.dev/go.mongodb.org/mongo-driver/bson#Unmarshaler) interfaces.
These types can be used directly when working with MongoDB.
## Unmarshalling (JSON -> Go)
```go
rawJSON := []byte(`
{ "type": "FeatureCollection",
"features": [
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
"properties": {"prop0": "value0"}
}
]
}`)
fc, _ := geojson.UnmarshalFeatureCollection(rawJSON)
// or
fc := geojson.NewFeatureCollection()
err := json.Unmarshal(rawJSON, &fc)
// Geometry will be unmarshalled into the correct geo.Geometry type.
point := fc.Features[0].Geometry.(orb.Point)
```
## Marshalling (Go -> JSON)
```go
fc := geojson.NewFeatureCollection()
fc.Append(geojson.NewFeature(orb.Point{1, 2}))
rawJSON, _ := fc.MarshalJSON()
// or
blob, _ := json.Marshal(fc)
```
## Foreign/extra members in a feature collection
```go
rawJSON := []byte(`
{ "type": "FeatureCollection",
"generator": "myapp",
"timestamp": "2020-06-15T01:02:03Z",
"features": [
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
"properties": {"prop0": "value0"}
}
]
}`)
fc, _ := geojson.UnmarshalFeatureCollection(rawJSON)
fc.ExtraMembers["generator"] // == "myApp"
fc.ExtraMembers["timestamp"] // == "2020-06-15T01:02:03Z"
// Marshalling will include values in `ExtraMembers` in the
// base featureCollection object.
```
## Performance
For performance critical applications, consider a
third party replacement of "encoding/json" like [github.com/json-iterator/go](https://github.com/json-iterator/go)
This can be enabled with something like this:
```go
import (
jsoniter "github.com/json-iterator/go"
"github.com/paulmach/orb"
)
var c = jsoniter.Config{
EscapeHTML: true,
SortMapKeys: false,
MarshalFloatWith6Digits: true,
}.Froze()
CustomJSONMarshaler = c
CustomJSONUnmarshaler = c
```
The above change can have dramatic performance implications, see the benchmarks below
on a 100k feature collection file:
```
benchmark old ns/op new ns/op delta
BenchmarkFeatureMarshalJSON-12 2694543 733480 -72.78%
BenchmarkFeatureUnmarshalJSON-12 5383825 2738183 -49.14%
BenchmarkGeometryMarshalJSON-12 210107 62789 -70.12%
BenchmarkGeometryUnmarshalJSON-12 691472 144689 -79.08%
benchmark old allocs new allocs delta
BenchmarkFeatureMarshalJSON-12 7818 2316 -70.38%
BenchmarkFeatureUnmarshalJSON-12 23047 31946 +38.61%
BenchmarkGeometryMarshalJSON-12 2 3 +50.00%
BenchmarkGeometryUnmarshalJSON-12 2042 18 -99.12%
benchmark old bytes new bytes delta
BenchmarkFeatureMarshalJSON-12 794088 490251 -38.26%
BenchmarkFeatureUnmarshalJSON-12 766354 1068497 +39.43%
BenchmarkGeometryMarshalJSON-12 24787 18650 -24.76%
BenchmarkGeometryUnmarshalJSON-12 79784 51374 -35.61%
```
## Feature Properties
GeoJSON features can have properties of any type. This can cause issues in a statically typed
language such as Go. Included is a `Properties` type with some helper methods that will try to
force convert a property. An optional default, will be used if the property is missing or the wrong
type.
```go
f.Properties.MustBool(key string, def ...bool) bool
f.Properties.MustFloat64(key string, def ...float64) float64
f.Properties.MustInt(key string, def ...int) int
f.Properties.MustString(key string, def ...string) string
```

38
vendor/github.com/paulmach/orb/geojson/bbox.go generated vendored Normal file
View File

@@ -0,0 +1,38 @@
package geojson
import "github.com/paulmach/orb"
// BBox is for the geojson bbox attribute which is an array with all axes
// of the most southwesterly point followed by all axes of the more northeasterly point.
type BBox []float64
// NewBBox creates a bbox from a a bound.
func NewBBox(b orb.Bound) BBox {
return []float64{
b.Min[0], b.Min[1],
b.Max[0], b.Max[1],
}
}
// Valid checks if the bbox is present and has at least 4 elements.
func (bb BBox) Valid() bool {
if bb == nil {
return false
}
return len(bb) >= 4 && len(bb)%2 == 0
}
// Bound returns the orb.Bound for the BBox.
func (bb BBox) Bound() orb.Bound {
if !bb.Valid() {
return orb.Bound{}
}
mid := len(bb) / 2
return orb.Bound{
Min: orb.Point{bb[0], bb[1]},
Max: orb.Point{bb[mid], bb[mid+1]},
}
}

138
vendor/github.com/paulmach/orb/geojson/feature.go generated vendored Normal file
View File

@@ -0,0 +1,138 @@
package geojson
import (
"bytes"
"fmt"
"github.com/paulmach/orb"
"go.mongodb.org/mongo-driver/bson"
)
// A Feature corresponds to GeoJSON feature object
type Feature struct {
ID interface{} `json:"id,omitempty"`
Type string `json:"type"`
BBox BBox `json:"bbox,omitempty"`
Geometry orb.Geometry `json:"geometry"`
Properties Properties `json:"properties"`
}
// NewFeature creates and initializes a GeoJSON feature given the required attributes.
func NewFeature(geometry orb.Geometry) *Feature {
return &Feature{
Type: "Feature",
Geometry: geometry,
Properties: make(map[string]interface{}),
}
}
// Point implements the orb.Pointer interface so that Features can be used
// with quadtrees. The point returned is the center of the Bound of the geometry.
// To represent the geometry with another point you must create a wrapper type.
func (f *Feature) Point() orb.Point {
return f.Geometry.Bound().Center()
}
var _ orb.Pointer = &Feature{}
// MarshalJSON converts the feature object into the proper JSON.
// It will handle the encoding of all the child geometries.
// Alternately one can call json.Marshal(f) directly for the same result.
func (f Feature) MarshalJSON() ([]byte, error) {
return marshalJSON(newFeatureDoc(&f))
}
// MarshalBSON converts the feature object into the proper JSON.
// It will handle the encoding of all the child geometries.
// Alternately one can call json.Marshal(f) directly for the same result.
func (f Feature) MarshalBSON() ([]byte, error) {
return bson.Marshal(newFeatureDoc(&f))
}
func newFeatureDoc(f *Feature) *featureDoc {
doc := &featureDoc{
ID: f.ID,
Type: "Feature",
Properties: f.Properties,
BBox: f.BBox,
Geometry: NewGeometry(f.Geometry),
}
if len(doc.Properties) == 0 {
doc.Properties = nil
}
return doc
}
// UnmarshalFeature decodes the data into a GeoJSON feature.
// Alternately one can call json.Unmarshal(f) directly for the same result.
func UnmarshalFeature(data []byte) (*Feature, error) {
f := &Feature{}
err := f.UnmarshalJSON(data)
if err != nil {
return nil, err
}
return f, nil
}
// UnmarshalJSON handles the correct unmarshalling of the data
// into the orb.Geometry types.
func (f *Feature) UnmarshalJSON(data []byte) error {
if bytes.Equal(data, []byte(`null`)) {
*f = Feature{}
return nil
}
doc := &featureDoc{}
err := unmarshalJSON(data, &doc)
if err != nil {
return err
}
return featureUnmarshalFinish(doc, f)
}
// UnmarshalBSON will unmarshal a BSON document created with bson.Marshal.
func (f *Feature) UnmarshalBSON(data []byte) error {
doc := &featureDoc{}
err := bson.Unmarshal(data, &doc)
if err != nil {
return err
}
return featureUnmarshalFinish(doc, f)
}
func featureUnmarshalFinish(doc *featureDoc, f *Feature) error {
if doc.Type != "Feature" {
return fmt.Errorf("geojson: not a feature: type=%s", doc.Type)
}
var g orb.Geometry
if doc.Geometry != nil {
if doc.Geometry.Coordinates == nil && doc.Geometry.Geometries == nil {
return ErrInvalidGeometry
}
g = doc.Geometry.Geometry()
}
*f = Feature{
ID: doc.ID,
Type: doc.Type,
Properties: doc.Properties,
BBox: doc.BBox,
Geometry: g,
}
return nil
}
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"`
}

View File

@@ -0,0 +1,197 @@
/*
Package geojson is a library for encoding and decoding GeoJSON into Go structs
using the geometries in the orb package. Supports both the json.Marshaler and
json.Unmarshaler interfaces as well as helper functions such as
`UnmarshalFeatureCollection` and `UnmarshalFeature`.
*/
package geojson
import (
"bytes"
"fmt"
"go.mongodb.org/mongo-driver/bson"
)
const featureCollection = "FeatureCollection"
// A FeatureCollection correlates to a GeoJSON feature collection.
type FeatureCollection struct {
Type string `json:"type"`
BBox BBox `json:"bbox,omitempty"`
Features []*Feature `json:"features"`
// ExtraMembers can be used to encoded/decode extra key/members in
// the base of the feature collection. Note that keys of "type", "bbox"
// and "features" will not work as those are reserved by the GeoJSON spec.
ExtraMembers Properties `json:"-"`
}
// NewFeatureCollection creates and initializes a new feature collection.
func NewFeatureCollection() *FeatureCollection {
return &FeatureCollection{
Type: featureCollection,
Features: []*Feature{},
}
}
// Append appends a feature to the collection.
func (fc *FeatureCollection) Append(feature *Feature) *FeatureCollection {
fc.Features = append(fc.Features, feature)
return fc
}
// MarshalJSON converts the feature collection object into the proper JSON.
// It will handle the encoding of all the child features and geometries.
// Alternately one can call json.Marshal(fc) directly for the same result.
// Items in the ExtraMembers map will be included in the base of the
// feature collection object.
func (fc FeatureCollection) MarshalJSON() ([]byte, error) {
m := newFeatureCollectionDoc(fc)
return marshalJSON(m)
}
// MarshalBSON converts the feature collection object into a BSON document
// represented by bytes. It will handle the encoding of all the child features
// and geometries.
// Items in the ExtraMembers map will be included in the base of the
// feature collection object.
func (fc FeatureCollection) MarshalBSON() ([]byte, error) {
m := newFeatureCollectionDoc(fc)
return bson.Marshal(m)
}
func newFeatureCollectionDoc(fc FeatureCollection) map[string]interface{} {
var tmp map[string]interface{}
if fc.ExtraMembers != nil {
tmp = fc.ExtraMembers.Clone()
} else {
tmp = make(map[string]interface{}, 3)
}
tmp["type"] = featureCollection
delete(tmp, "bbox")
if fc.BBox != nil {
tmp["bbox"] = fc.BBox
}
if fc.Features == nil {
tmp["features"] = []*Feature{}
} else {
tmp["features"] = fc.Features
}
return tmp
}
// UnmarshalJSON decodes the data into a GeoJSON feature collection.
// Extra/foreign members will be put into the `ExtraMembers` attribute.
func (fc *FeatureCollection) UnmarshalJSON(data []byte) error {
if bytes.Equal(data, []byte(`null`)) {
*fc = FeatureCollection{}
return nil
}
tmp := make(map[string]nocopyRawMessage, 4)
err := unmarshalJSON(data, &tmp)
if err != nil {
return err
}
*fc = FeatureCollection{}
for key, value := range tmp {
switch key {
case "type":
err := unmarshalJSON(value, &fc.Type)
if err != nil {
return err
}
case "bbox":
err := unmarshalJSON(value, &fc.BBox)
if err != nil {
return err
}
case "features":
err := unmarshalJSON(value, &fc.Features)
if err != nil {
return err
}
default:
if fc.ExtraMembers == nil {
fc.ExtraMembers = Properties{}
}
var val interface{}
err := unmarshalJSON(value, &val)
if err != nil {
return err
}
fc.ExtraMembers[key] = val
}
}
if fc.Type != featureCollection {
return fmt.Errorf("geojson: not a feature collection: type=%s", fc.Type)
}
return nil
}
// UnmarshalBSON will unmarshal a BSON document created with bson.Marshal.
// Extra/foreign members will be put into the `ExtraMembers` attribute.
func (fc *FeatureCollection) UnmarshalBSON(data []byte) error {
tmp := make(map[string]bson.RawValue, 4)
err := bson.Unmarshal(data, &tmp)
if err != nil {
return err
}
*fc = FeatureCollection{}
for key, value := range tmp {
switch key {
case "type":
fc.Type, _ = bson.RawValue(value).StringValueOK()
case "bbox":
err := value.Unmarshal(&fc.BBox)
if err != nil {
return err
}
case "features":
err := value.Unmarshal(&fc.Features)
if err != nil {
return err
}
default:
if fc.ExtraMembers == nil {
fc.ExtraMembers = Properties{}
}
var val interface{}
err := value.Unmarshal(&val)
if err != nil {
return err
}
fc.ExtraMembers[key] = val
}
}
if fc.Type != featureCollection {
return fmt.Errorf("geojson: not a feature collection: type=%s", fc.Type)
}
return nil
}
// UnmarshalFeatureCollection decodes the data into a GeoJSON feature collection.
// Alternately one can call json.Unmarshal(fc) directly for the same result.
func UnmarshalFeatureCollection(data []byte) (*FeatureCollection, error) {
fc := &FeatureCollection{}
err := fc.UnmarshalJSON(data)
if err != nil {
return nil, err
}
return fc, nil
}

586
vendor/github.com/paulmach/orb/geojson/geometry.go generated vendored Normal file
View File

@@ -0,0 +1,586 @@
package geojson
import (
"errors"
"github.com/paulmach/orb"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsontype"
)
// ErrInvalidGeometry will be returned if a the json of the geometry is invalid.
var ErrInvalidGeometry = errors.New("geojson: invalid geometry")
// A Geometry matches the structure of a GeoJSON Geometry.
type Geometry struct {
Type string `json:"type"`
Coordinates orb.Geometry `json:"coordinates,omitempty"`
Geometries []*Geometry `json:"geometries,omitempty"`
}
// NewGeometry will create a Geometry object but will convert
// the input into a GoeJSON geometry. For example, it will convert
// Rings and Bounds into Polygons.
func NewGeometry(g orb.Geometry) *Geometry {
jg := &Geometry{}
switch g := g.(type) {
case orb.Ring:
jg.Coordinates = orb.Polygon{g}
case orb.Bound:
jg.Coordinates = g.ToPolygon()
case orb.Collection:
for _, c := range g {
jg.Geometries = append(jg.Geometries, NewGeometry(c))
}
jg.Type = g.GeoJSONType()
default:
jg.Coordinates = g
}
if jg.Coordinates != nil {
jg.Type = jg.Coordinates.GeoJSONType()
}
return jg
}
// Geometry returns the orb.Geometry for the geojson Geometry.
// This will convert the "Geometries" into a orb.Collection if applicable.
func (g *Geometry) Geometry() orb.Geometry {
if g.Coordinates != nil {
return g.Coordinates
}
c := make(orb.Collection, 0, len(g.Geometries))
for _, geom := range g.Geometries {
c = append(c, geom.Geometry())
}
return c
}
// MarshalJSON will marshal the geometry into the correct JSON structure.
func (g *Geometry) MarshalJSON() ([]byte, error) {
if g.Coordinates == nil && len(g.Geometries) == 0 {
return []byte(`null`), nil
}
ng := newGeometryMarshallDoc(g)
return marshalJSON(ng)
}
// MarshalBSON will convert the geometry into a BSON document with the structure
// of a GeoJSON Geometry. This function is used when the geometry is the top level
// document to be marshalled.
func (g *Geometry) MarshalBSON() ([]byte, error) {
ng := newGeometryMarshallDoc(g)
return bson.Marshal(ng)
}
// MarshalBSONValue will marshal the geometry into a BSON value
// with the structure of a GeoJSON Geometry.
func (g *Geometry) MarshalBSONValue() (bsontype.Type, []byte, error) {
// implementing MarshalBSONValue allows us to marshal into a null value
// needed to match behavior with the JSON marshalling.
if g.Coordinates == nil && len(g.Geometries) == 0 {
return bsontype.Null, nil, nil
}
ng := newGeometryMarshallDoc(g)
return bson.MarshalValue(ng)
}
func newGeometryMarshallDoc(g *Geometry) *geometryMarshallDoc {
ng := &geometryMarshallDoc{}
switch g := g.Coordinates.(type) {
case orb.Ring:
ng.Coordinates = orb.Polygon{g}
case orb.Bound:
ng.Coordinates = g.ToPolygon()
case orb.Collection:
ng.Geometries = make([]*Geometry, 0, len(g))
for _, c := range g {
ng.Geometries = append(ng.Geometries, NewGeometry(c))
}
ng.Type = g.GeoJSONType()
default:
ng.Coordinates = g
}
if ng.Coordinates != nil {
ng.Type = ng.Coordinates.GeoJSONType()
}
if len(g.Geometries) > 0 {
ng.Geometries = g.Geometries
ng.Type = orb.Collection{}.GeoJSONType()
}
return ng
}
// UnmarshalGeometry decodes the JSON data into a GeoJSON feature.
// Alternately one can call json.Unmarshal(g) directly for the same result.
func UnmarshalGeometry(data []byte) (*Geometry, error) {
g := &Geometry{}
err := unmarshalJSON(data, g)
if err != nil {
return nil, err
}
return g, nil
}
// UnmarshalJSON will unmarshal the correct geometry from the JSON structure.
func (g *Geometry) UnmarshalJSON(data []byte) error {
jg := &jsonGeometry{}
err := unmarshalJSON(data, jg)
if err != nil {
return err
}
switch jg.Type {
case "Point":
p := orb.Point{}
err = unmarshalJSON(jg.Coordinates, &p)
if err != nil {
return err
}
g.Coordinates = p
case "MultiPoint":
mp := orb.MultiPoint{}
err = unmarshalJSON(jg.Coordinates, &mp)
if err != nil {
return err
}
g.Coordinates = mp
case "LineString":
ls := orb.LineString{}
err = unmarshalJSON(jg.Coordinates, &ls)
if err != nil {
return err
}
g.Coordinates = ls
case "MultiLineString":
mls := orb.MultiLineString{}
err = unmarshalJSON(jg.Coordinates, &mls)
if err != nil {
return err
}
g.Coordinates = mls
case "Polygon":
p := orb.Polygon{}
err = unmarshalJSON(jg.Coordinates, &p)
if err != nil {
return err
}
g.Coordinates = p
case "MultiPolygon":
mp := orb.MultiPolygon{}
err = unmarshalJSON(jg.Coordinates, &mp)
if err != nil {
return err
}
g.Coordinates = mp
case "GeometryCollection":
g.Geometries = jg.Geometries
default:
return ErrInvalidGeometry
}
g.Type = g.Geometry().GeoJSONType()
return nil
}
// UnmarshalBSON will unmarshal a BSON document created with bson.Marshal.
func (g *Geometry) UnmarshalBSON(data []byte) error {
bg := &bsonGeometry{}
err := bson.Unmarshal(data, bg)
if err != nil {
return err
}
switch bg.Type {
case "Point":
p := orb.Point{}
err = bg.Coordinates.Unmarshal(&p)
if err != nil {
return err
}
g.Coordinates = p
case "MultiPoint":
mp := orb.MultiPoint{}
err = bg.Coordinates.Unmarshal(&mp)
if err != nil {
return err
}
g.Coordinates = mp
case "LineString":
ls := orb.LineString{}
err = bg.Coordinates.Unmarshal(&ls)
if err != nil {
return err
}
g.Coordinates = ls
case "MultiLineString":
mls := orb.MultiLineString{}
err = bg.Coordinates.Unmarshal(&mls)
if err != nil {
return err
}
g.Coordinates = mls
case "Polygon":
p := orb.Polygon{}
err = bg.Coordinates.Unmarshal(&p)
if err != nil {
return err
}
g.Coordinates = p
case "MultiPolygon":
mp := orb.MultiPolygon{}
err = bg.Coordinates.Unmarshal(&mp)
if err != nil {
return err
}
g.Coordinates = mp
case "GeometryCollection":
g.Geometries = bg.Geometries
default:
return ErrInvalidGeometry
}
g.Type = g.Geometry().GeoJSONType()
return nil
}
// A Point is a helper type that will marshal to/from a GeoJSON Point geometry.
type Point orb.Point
// Geometry will return the orb.Geometry version of the data.
func (p Point) Geometry() orb.Geometry {
return orb.Point(p)
}
// MarshalJSON will convert the Point into a GeoJSON Point geometry.
func (p Point) MarshalJSON() ([]byte, error) {
return marshalJSON(&Geometry{Coordinates: orb.Point(p)})
}
// MarshalBSON will convert the Point into a BSON value following the GeoJSON Point structure.
func (p Point) MarshalBSON() ([]byte, error) {
return bson.Marshal(&Geometry{Coordinates: orb.Point(p)})
}
// UnmarshalJSON will unmarshal the GeoJSON Point geometry.
func (p *Point) UnmarshalJSON(data []byte) error {
g := &Geometry{}
err := unmarshalJSON(data, &g)
if err != nil {
return err
}
point, ok := g.Coordinates.(orb.Point)
if !ok {
return errors.New("geojson: not a Point type")
}
*p = Point(point)
return nil
}
// UnmarshalBSON will unmarshal GeoJSON Point geometry.
func (p *Point) UnmarshalBSON(data []byte) error {
g := &Geometry{}
err := bson.Unmarshal(data, &g)
if err != nil {
return err
}
point, ok := g.Coordinates.(orb.Point)
if !ok {
return errors.New("geojson: not a Point type")
}
*p = Point(point)
return nil
}
// A MultiPoint is a helper type that will marshal to/from a GeoJSON MultiPoint geometry.
type MultiPoint orb.MultiPoint
// Geometry will return the orb.Geometry version of the data.
func (mp MultiPoint) Geometry() orb.Geometry {
return orb.MultiPoint(mp)
}
// MarshalJSON will convert the MultiPoint into a GeoJSON MultiPoint geometry.
func (mp MultiPoint) MarshalJSON() ([]byte, error) {
return marshalJSON(&Geometry{Coordinates: orb.MultiPoint(mp)})
}
// MarshalBSON will convert the MultiPoint into a GeoJSON MultiPoint geometry BSON.
func (mp MultiPoint) MarshalBSON() ([]byte, error) {
return bson.Marshal(&Geometry{Coordinates: orb.MultiPoint(mp)})
}
// UnmarshalJSON will unmarshal the GeoJSON MultiPoint geometry.
func (mp *MultiPoint) UnmarshalJSON(data []byte) error {
g := &Geometry{}
err := unmarshalJSON(data, &g)
if err != nil {
return err
}
multiPoint, ok := g.Coordinates.(orb.MultiPoint)
if !ok {
return errors.New("geojson: not a MultiPoint type")
}
*mp = MultiPoint(multiPoint)
return nil
}
// UnmarshalBSON will unmarshal the GeoJSON MultiPoint geometry.
func (mp *MultiPoint) UnmarshalBSON(data []byte) error {
g := &Geometry{}
err := bson.Unmarshal(data, &g)
if err != nil {
return err
}
multiPoint, ok := g.Coordinates.(orb.MultiPoint)
if !ok {
return errors.New("geojson: not a MultiPoint type")
}
*mp = MultiPoint(multiPoint)
return nil
}
// A LineString is a helper type that will marshal to/from a GeoJSON LineString geometry.
type LineString orb.LineString
// Geometry will return the orb.Geometry version of the data.
func (ls LineString) Geometry() orb.Geometry {
return orb.LineString(ls)
}
// MarshalJSON will convert the LineString into a GeoJSON LineString geometry.
func (ls LineString) MarshalJSON() ([]byte, error) {
return marshalJSON(&Geometry{Coordinates: orb.LineString(ls)})
}
// MarshalBSON will convert the LineString into a GeoJSON LineString geometry.
func (ls LineString) MarshalBSON() ([]byte, error) {
return bson.Marshal(&Geometry{Coordinates: orb.LineString(ls)})
}
// UnmarshalJSON will unmarshal the GeoJSON MultiPoint geometry.
func (ls *LineString) UnmarshalJSON(data []byte) error {
g := &Geometry{}
err := unmarshalJSON(data, &g)
if err != nil {
return err
}
lineString, ok := g.Coordinates.(orb.LineString)
if !ok {
return errors.New("geojson: not a LineString type")
}
*ls = LineString(lineString)
return nil
}
// UnmarshalBSON will unmarshal the GeoJSON MultiPoint geometry.
func (ls *LineString) UnmarshalBSON(data []byte) error {
g := &Geometry{}
err := bson.Unmarshal(data, &g)
if err != nil {
return err
}
lineString, ok := g.Coordinates.(orb.LineString)
if !ok {
return errors.New("geojson: not a LineString type")
}
*ls = LineString(lineString)
return nil
}
// A MultiLineString is a helper type that will marshal to/from a GeoJSON MultiLineString geometry.
type MultiLineString orb.MultiLineString
// Geometry will return the orb.Geometry version of the data.
func (mls MultiLineString) Geometry() orb.Geometry {
return orb.MultiLineString(mls)
}
// MarshalJSON will convert the MultiLineString into a GeoJSON MultiLineString geometry.
func (mls MultiLineString) MarshalJSON() ([]byte, error) {
return marshalJSON(&Geometry{Coordinates: orb.MultiLineString(mls)})
}
// MarshalBSON will convert the MultiLineString into a GeoJSON MultiLineString geometry.
func (mls MultiLineString) MarshalBSON() ([]byte, error) {
return bson.Marshal(&Geometry{Coordinates: orb.MultiLineString(mls)})
}
// UnmarshalJSON will unmarshal the GeoJSON MultiPoint geometry.
func (mls *MultiLineString) UnmarshalJSON(data []byte) error {
g := &Geometry{}
err := unmarshalJSON(data, &g)
if err != nil {
return err
}
multilineString, ok := g.Coordinates.(orb.MultiLineString)
if !ok {
return errors.New("geojson: not a MultiLineString type")
}
*mls = MultiLineString(multilineString)
return nil
}
// UnmarshalBSON will unmarshal the GeoJSON MultiPoint geometry.
func (mls *MultiLineString) UnmarshalBSON(data []byte) error {
g := &Geometry{}
err := bson.Unmarshal(data, &g)
if err != nil {
return err
}
multilineString, ok := g.Coordinates.(orb.MultiLineString)
if !ok {
return errors.New("geojson: not a MultiLineString type")
}
*mls = MultiLineString(multilineString)
return nil
}
// A Polygon is a helper type that will marshal to/from a GeoJSON Polygon geometry.
type Polygon orb.Polygon
// Geometry will return the orb.Geometry version of the data.
func (p Polygon) Geometry() orb.Geometry {
return orb.Polygon(p)
}
// MarshalJSON will convert the Polygon into a GeoJSON Polygon geometry.
func (p Polygon) MarshalJSON() ([]byte, error) {
return marshalJSON(&Geometry{Coordinates: orb.Polygon(p)})
}
// MarshalBSON will convert the Polygon into a GeoJSON Polygon geometry.
func (p Polygon) MarshalBSON() ([]byte, error) {
return bson.Marshal(&Geometry{Coordinates: orb.Polygon(p)})
}
// UnmarshalJSON will unmarshal the GeoJSON Polygon geometry.
func (p *Polygon) UnmarshalJSON(data []byte) error {
g := &Geometry{}
err := unmarshalJSON(data, &g)
if err != nil {
return err
}
polygon, ok := g.Coordinates.(orb.Polygon)
if !ok {
return errors.New("geojson: not a Polygon type")
}
*p = Polygon(polygon)
return nil
}
// UnmarshalBSON will unmarshal the GeoJSON Polygon geometry.
func (p *Polygon) UnmarshalBSON(data []byte) error {
g := &Geometry{}
err := bson.Unmarshal(data, &g)
if err != nil {
return err
}
polygon, ok := g.Coordinates.(orb.Polygon)
if !ok {
return errors.New("geojson: not a Polygon type")
}
*p = Polygon(polygon)
return nil
}
// A MultiPolygon is a helper type that will marshal to/from a GeoJSON MultiPolygon geometry.
type MultiPolygon orb.MultiPolygon
// Geometry will return the orb.Geometry version of the data.
func (mp MultiPolygon) Geometry() orb.Geometry {
return orb.MultiPolygon(mp)
}
// MarshalJSON will convert the MultiPolygon into a GeoJSON MultiPolygon geometry.
func (mp MultiPolygon) MarshalJSON() ([]byte, error) {
return marshalJSON(&Geometry{Coordinates: orb.MultiPolygon(mp)})
}
// MarshalBSON will convert the MultiPolygon into a GeoJSON MultiPolygon geometry.
func (mp MultiPolygon) MarshalBSON() ([]byte, error) {
return bson.Marshal(&Geometry{Coordinates: orb.MultiPolygon(mp)})
}
// UnmarshalJSON will unmarshal the GeoJSON MultiPolygon geometry.
func (mp *MultiPolygon) UnmarshalJSON(data []byte) error {
g := &Geometry{}
err := unmarshalJSON(data, &g)
if err != nil {
return err
}
multiPolygon, ok := g.Coordinates.(orb.MultiPolygon)
if !ok {
return errors.New("geojson: not a MultiPolygon type")
}
*mp = MultiPolygon(multiPolygon)
return nil
}
// UnmarshalBSON will unmarshal the GeoJSON MultiPolygon geometry.
func (mp *MultiPolygon) UnmarshalBSON(data []byte) error {
g := &Geometry{}
err := bson.Unmarshal(data, &g)
if err != nil {
return err
}
multiPolygon, ok := g.Coordinates.(orb.MultiPolygon)
if !ok {
return errors.New("geojson: not a MultiPolygon type")
}
*mp = MultiPolygon(multiPolygon)
return nil
}
type bsonGeometry struct {
Type string `json:"type" bson:"type"`
Coordinates bson.RawValue `json:"coordinates" bson:"coordinates"`
Geometries []*Geometry `json:"geometries,omitempty" bson:"geometries"`
}
type jsonGeometry struct {
Type string `json:"type"`
Coordinates nocopyRawMessage `json:"coordinates"`
Geometries []*Geometry `json:"geometries,omitempty"`
}
type geometryMarshallDoc struct {
Type string `json:"type" bson:"type"`
Coordinates orb.Geometry `json:"coordinates,omitempty" bson:"coordinates,omitempty"`
Geometries []*Geometry `json:"geometries,omitempty" bson:"geometries,omitempty"`
}

74
vendor/github.com/paulmach/orb/geojson/json.go generated vendored Normal file
View File

@@ -0,0 +1,74 @@
package geojson
import "encoding/json"
// CustomJSONMarshaler can be set to have the code use a different
// json marshaler than the default in the standard library.
// One use case in enabling `github.com/json-iterator/go`
// with something like this:
//
// import (
// jsoniter "github.com/json-iterator/go"
// "github.com/paulmach/orb"
// )
//
// var c = jsoniter.Config{
// EscapeHTML: true,
// SortMapKeys: false,
// MarshalFloatWith6Digits: true,
// }.Froze()
//
// orb.CustomJSONMarshaler = c
// orb.CustomJSONUnmarshaler = c
//
// Note that any errors encountered during marshaling will be different.
var CustomJSONMarshaler interface {
Marshal(v interface{}) ([]byte, error)
} = nil
// CustomJSONUnmarshaler can be set to have the code use a different
// json unmarshaler than the default in the standard library.
// One use case in enabling `github.com/json-iterator/go`
// with something like this:
//
// import (
// jsoniter "github.com/json-iterator/go"
// "github.com/paulmach/orb"
// )
//
// var c = jsoniter.Config{
// EscapeHTML: true,
// SortMapKeys: false,
// MarshalFloatWith6Digits: true,
// }.Froze()
//
// orb.CustomJSONMarshaler = c
// orb.CustomJSONUnmarshaler = c
//
// Note that any errors encountered during unmarshaling will be different.
var CustomJSONUnmarshaler interface {
Unmarshal(data []byte, v interface{}) error
} = nil
func marshalJSON(v interface{}) ([]byte, error) {
if CustomJSONMarshaler == nil {
return json.Marshal(v)
}
return CustomJSONMarshaler.Marshal(v)
}
func unmarshalJSON(data []byte, v interface{}) error {
if CustomJSONUnmarshaler == nil {
return json.Unmarshal(data, v)
}
return CustomJSONUnmarshaler.Unmarshal(data, v)
}
type nocopyRawMessage []byte
func (m *nocopyRawMessage) UnmarshalJSON(data []byte) error {
*m = data
return nil
}

112
vendor/github.com/paulmach/orb/geojson/properties.go generated vendored Normal file
View File

@@ -0,0 +1,112 @@
package geojson
import "fmt"
// Properties defines the feature properties with some helper methods.
type Properties map[string]interface{}
// 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))
// 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]
if b, ok := v.(bool); ok {
return b
}
if v != nil {
panic(fmt.Sprintf("not a bool, but a %T: %v", v, v))
}
if len(def) > 0 {
return def[0]
}
panic("property not found")
}
// 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))
// 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]
if i, ok := v.(int); ok {
return i
}
if f, ok := v.(float64); ok {
return int(f)
}
if v != nil {
panic(fmt.Sprintf("not a number, but a %T: %v", v, v))
}
if len(def) > 0 {
return def[0]
}
panic("property not found")
}
// 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))
// 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]
if f, ok := v.(float64); ok {
return f
}
if i, ok := v.(int); ok {
return float64(i)
}
if v != nil {
panic(fmt.Sprintf("not a number, but a %T: %v", v, v))
}
if len(def) > 0 {
return def[0]
}
panic("property not found")
}
// 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"))
// 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]
if s, ok := v.(string); ok {
return s
}
if v != nil {
panic(fmt.Sprintf("not a string, but a %T: %v", v, v))
}
if len(def) > 0 {
return def[0]
}
panic("property not found")
}
// Clone returns a shallow copy of the properties.
func (p Properties) Clone() Properties {
n := make(Properties, len(p)+3)
for k, v := range p {
n[k] = v
}
return n
}

11
vendor/github.com/paulmach/orb/geojson/types.go generated vendored Normal file
View File

@@ -0,0 +1,11 @@
package geojson
// A list of the geojson types that are currently supported.
const (
TypePoint = "Point"
TypeMultiPoint = "MultiPoint"
TypeLineString = "LineString"
TypeMultiLineString = "MultiLineString"
TypePolygon = "Polygon"
TypeMultiPolygon = "MultiPolygon"
)