Working auth and photo json endpoint

Signed-off-by: Kris Nóva <kris@nivenly.com>
This commit is contained in:
Kris Nóva 2021-02-09 11:17:06 -08:00
parent ef275f97f4
commit e4323b6047
2032 changed files with 821464 additions and 52 deletions

13
vendor/github.com/paulmach/go.geojson/.travis.yml generated vendored Normal file
View file

@ -0,0 +1,13 @@
language: go
go:
- 1.7
- tip
after_script:
- FIXED=$(go vet ./... | wc -l); if [ $FIXED -gt 0 ]; then echo "go vet - $FIXED issues(s), please fix." && exit 2; fi
- FIXED=$(go fmt ./... | wc -l); if [ $FIXED -gt 0 ]; then echo "gofmt - $FIXED file(s) not formatted correctly, please run gofmt to fix this." && exit 2; fi
script:
- go test -v

18
vendor/github.com/paulmach/go.geojson/LICENSE generated vendored Normal file
View file

@ -0,0 +1,18 @@
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

108
vendor/github.com/paulmach/go.geojson/README.md generated vendored Normal file
View file

@ -0,0 +1,108 @@
go.geojson
==========
Go.geojson is a package for **encoding and decoding** [GeoJSON](http://geojson.org/) into Go structs.
Supports both the [json.Marshaler](http://golang.org/pkg/encoding/json/#Marshaler) and [json.Unmarshaler](http://golang.org/pkg/encoding/json/#Unmarshaler)
interfaces as well as [sql.Scanner](http://golang.org/pkg/database/sql/#Scanner) for directly scanning PostGIS query results.
The package also provides helper functions such as `UnmarshalFeatureCollection`, `UnmarshalFeature` and `UnmarshalGeometry`.
### Important
This package is best for lightweight interaction with GeoJSON. If you want to actually do
stuff with the geometry take a look at [orb/geojson](https://github.com/paulmach/orb/tree/master/geojson) which
decodes the geometries into [orb](https://github.com/paulmach/orb) types which you can do all sorts of things with.
#### To install
go get github.com/paulmach/go.geojson
#### To use, imports as package name `geojson`:
import "github.com/paulmach/go.geojson"
[![Build Status](https://travis-ci.org/paulmach/go.geojson.svg?branch=master)](https://travis-ci.org/paulmach/go.geojson)
[![Godoc Reference](https://godoc.org/github.com/paulmach/go.geojson?status.svg)](https://godoc.org/github.com/paulmach/go.geojson)
## Examples
* #### Unmarshalling (JSON -> Go)
go.geojson supports both the [json.Marshaler](http://golang.org/pkg/encoding/json/#Marshaler) and [json.Unmarshaler](http://golang.org/pkg/encoding/json/#Unmarshaler) interfaces as well as helper functions such as `UnmarshalFeatureCollection`, `UnmarshalFeature` and `UnmarshalGeometry`.
// Feature Collection
rawFeatureJSON := []byte(`
{ "type": "FeatureCollection",
"features": [
{ "type": "Feature",
"geometry": {"type": "Point", "coordinates": [102.0, 0.5]},
"properties": {"prop0": "value0"}
}
]
}`)
fc1, err := geojson.UnmarshalFeatureCollection(rawFeatureJSON)
fc2 := geojson.NewFeatureCollection()
err := json.Unmarshal(rawJSON, fc2)
// Geometry
rawGeometryJSON := []byte(`{"type": "Point", "coordinates": [102.0, 0.5]}`)
g, err := geojson.UnmarshalGeometry(rawGeometryJSON)
g.IsPoint() == true
g.Point == []float64{102.0, 0.5}
* #### Marshalling (Go -> JSON)
g := geojson.NewPointGeometry([]float64{1, 2})
rawJSON, err := g.MarshalJSON()
fc := geojson.NewFeatureCollection()
fc.AddFeature(geojson.NewPointFeature([]float64{1,2}))
rawJSON, err := fc.MarshalJSON()
* #### Scanning PostGIS query results
row := db.QueryRow("SELECT ST_AsGeoJSON(the_geom) FROM postgis_table)
var geometry *geojson.Geometry
row.Scan(&geometry)
* #### Dealing with different Geometry types
A geometry can be of several types, causing problems in a statically typed language.
Thus there is a separate attribute on Geometry for each type.
See the [Geometry object](https://godoc.org/github.com/paulmach/go.geojson#Geometry) for more details.
g := geojson.UnmarshalGeometry([]byte(`
{
"type": "LineString",
"coordinates": [
[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
]
}`))
switch {
case g.IsPoint():
// do something with g.Point
case g.IsLineString():
// do something with g.LineString
}
## Feature Properties
GeoJSON [Features](http://geojson.org/geojson-spec.html#feature-objects) can have properties of any type.
This can cause issues in a statically typed language such as Go.
So, included are some helper methods on the Feature object to ease the pain.
// functions to do the casting for you
func (f Feature) PropertyBool(key string) (bool, error) {
func (f Feature) PropertyInt(key string) (int, error) {
func (f Feature) PropertyFloat64(key string) (float64, error) {
func (f Feature) PropertyString(key string) (string, error) {
// functions that hide the error and let you define default
func (f Feature) PropertyMustBool(key string, def ...bool) bool {
func (f Feature) PropertyMustInt(key string, def ...int) int {
func (f Feature) PropertyMustFloat64(key string, def ...float64) float64 {
func (f Feature) PropertyMustString(key string, def ...string) string {

28
vendor/github.com/paulmach/go.geojson/boundingbox.go generated vendored Normal file
View file

@ -0,0 +1,28 @@
package geojson
import "fmt"
func decodeBoundingBox(bb interface{}) ([]float64, error) {
if bb == nil {
return nil, nil
}
switch f := bb.(type) {
case []float64:
return f, nil
case []interface{}:
bb := make([]float64, 0, 4)
for _, v := range f {
switch c := v.(type) {
case float64:
bb = append(bb, c)
default:
return nil, fmt.Errorf("bounding box coordinate not usable, got %T", v)
}
}
return bb, nil
default:
return nil, fmt.Errorf("bounding box property not usable, got %T", bb)
}
}

96
vendor/github.com/paulmach/go.geojson/feature.go generated vendored Normal file
View file

@ -0,0 +1,96 @@
package geojson
import (
"encoding/json"
)
// A Feature corresponds to GeoJSON feature object
type Feature struct {
ID interface{} `json:"id,omitempty"`
Type string `json:"type"`
BoundingBox []float64 `json:"bbox,omitempty"`
Geometry *Geometry `json:"geometry"`
Properties map[string]interface{} `json:"properties"`
CRS map[string]interface{} `json:"crs,omitempty"` // Coordinate Reference System Objects are not currently supported
}
// NewFeature creates and initializes a GeoJSON feature given the required attributes.
func NewFeature(geometry *Geometry) *Feature {
return &Feature{
Type: "Feature",
Geometry: geometry,
Properties: make(map[string]interface{}),
}
}
// NewPointFeature creates and initializes a GeoJSON feature with a point geometry using the given coordinate.
func NewPointFeature(coordinate []float64) *Feature {
return NewFeature(NewPointGeometry(coordinate))
}
// NewMultiPointFeature creates and initializes a GeoJSON feature with a multi-point geometry using the given coordinates.
func NewMultiPointFeature(coordinates ...[]float64) *Feature {
return NewFeature(NewMultiPointGeometry(coordinates...))
}
// NewLineStringFeature creates and initializes a GeoJSON feature with a line string geometry using the given coordinates.
func NewLineStringFeature(coordinates [][]float64) *Feature {
return NewFeature(NewLineStringGeometry(coordinates))
}
// NewMultiLineStringFeature creates and initializes a GeoJSON feature with a multi-line string geometry using the given lines.
func NewMultiLineStringFeature(lines ...[][]float64) *Feature {
return NewFeature(NewMultiLineStringGeometry(lines...))
}
// NewPolygonFeature creates and initializes a GeoJSON feature with a polygon geometry using the given polygon.
func NewPolygonFeature(polygon [][][]float64) *Feature {
return NewFeature(NewPolygonGeometry(polygon))
}
// NewMultiPolygonFeature creates and initializes a GeoJSON feature with a multi-polygon geometry using the given polygons.
func NewMultiPolygonFeature(polygons ...[][][]float64) *Feature {
return NewFeature(NewMultiPolygonGeometry(polygons...))
}
// NewCollectionFeature creates and initializes a GeoJSON feature with a geometry collection geometry using the given geometries.
func NewCollectionFeature(geometries ...*Geometry) *Feature {
return NewFeature(NewCollectionGeometry(geometries...))
}
// 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) {
type feature Feature
fea := &feature{
ID: f.ID,
Type: "Feature",
Geometry: f.Geometry,
}
if f.BoundingBox != nil && len(f.BoundingBox) != 0 {
fea.BoundingBox = f.BoundingBox
}
if f.Properties != nil && len(f.Properties) != 0 {
fea.Properties = f.Properties
}
if f.CRS != nil && len(f.CRS) != 0 {
fea.CRS = f.CRS
}
return json.Marshal(fea)
}
// 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 := json.Unmarshal(data, f)
if err != nil {
return nil, err
}
return f, nil
}

View file

@ -0,0 +1,70 @@
/*
Package geojson is a library for encoding and decoding GeoJSON into Go structs.
Supports both the json.Marshaler and json.Unmarshaler interfaces as well as helper functions
such as `UnmarshalFeatureCollection`, `UnmarshalFeature` and `UnmarshalGeometry`.
*/
package geojson
import (
"encoding/json"
)
// A FeatureCollection correlates to a GeoJSON feature collection.
type FeatureCollection struct {
Type string `json:"type"`
BoundingBox []float64 `json:"bbox,omitempty"`
Features []*Feature `json:"features"`
CRS map[string]interface{} `json:"crs,omitempty"` // Coordinate Reference System Objects are not currently supported
}
// NewFeatureCollection creates and initializes a new feature collection.
func NewFeatureCollection() *FeatureCollection {
return &FeatureCollection{
Type: "FeatureCollection",
Features: make([]*Feature, 0),
}
}
// AddFeature appends a feature to the collection.
func (fc *FeatureCollection) AddFeature(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.
func (fc FeatureCollection) MarshalJSON() ([]byte, error) {
type featureCollection FeatureCollection
fcol := &featureCollection{
Type: "FeatureCollection",
}
if fc.BoundingBox != nil && len(fc.BoundingBox) != 0 {
fcol.BoundingBox = fc.BoundingBox
}
fcol.Features = fc.Features
if fcol.Features == nil {
fcol.Features = make([]*Feature, 0) // GeoJSON requires the feature attribute to be at least []
}
if fc.CRS != nil && len(fc.CRS) != 0 {
fcol.CRS = fc.CRS
}
return json.Marshal(fcol)
}
// 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 := json.Unmarshal(data, fc)
if err != nil {
return nil, err
}
return fc, nil
}

347
vendor/github.com/paulmach/go.geojson/geometry.go generated vendored Normal file
View file

@ -0,0 +1,347 @@
package geojson
import (
"encoding/json"
"errors"
"fmt"
)
// A GeometryType serves to enumerate the different GeoJSON geometry types.
type GeometryType string
// The geometry types supported by GeoJSON 1.0
const (
GeometryPoint GeometryType = "Point"
GeometryMultiPoint GeometryType = "MultiPoint"
GeometryLineString GeometryType = "LineString"
GeometryMultiLineString GeometryType = "MultiLineString"
GeometryPolygon GeometryType = "Polygon"
GeometryMultiPolygon GeometryType = "MultiPolygon"
GeometryCollection GeometryType = "GeometryCollection"
)
// A Geometry correlates to a GeoJSON geometry object.
type Geometry struct {
Type GeometryType `json:"type"`
BoundingBox []float64 `json:"bbox,omitempty"`
Point []float64
MultiPoint [][]float64
LineString [][]float64
MultiLineString [][][]float64
Polygon [][][]float64
MultiPolygon [][][][]float64
Geometries []*Geometry
CRS map[string]interface{} `json:"crs,omitempty"` // Coordinate Reference System Objects are not currently supported
}
// NewPointGeometry creates and initializes a point geometry with the give coordinate.
func NewPointGeometry(coordinate []float64) *Geometry {
return &Geometry{
Type: GeometryPoint,
Point: coordinate,
}
}
// NewMultiPointGeometry creates and initializes a multi-point geometry with the given coordinates.
func NewMultiPointGeometry(coordinates ...[]float64) *Geometry {
return &Geometry{
Type: GeometryMultiPoint,
MultiPoint: coordinates,
}
}
// NewLineStringGeometry creates and initializes a line string geometry with the given coordinates.
func NewLineStringGeometry(coordinates [][]float64) *Geometry {
return &Geometry{
Type: GeometryLineString,
LineString: coordinates,
}
}
// NewMultiLineStringGeometry creates and initializes a multi-line string geometry with the given lines.
func NewMultiLineStringGeometry(lines ...[][]float64) *Geometry {
return &Geometry{
Type: GeometryMultiLineString,
MultiLineString: lines,
}
}
// NewPolygonGeometry creates and initializes a polygon geometry with the given polygon.
func NewPolygonGeometry(polygon [][][]float64) *Geometry {
return &Geometry{
Type: GeometryPolygon,
Polygon: polygon,
}
}
// NewMultiPolygonGeometry creates and initializes a multi-polygon geometry with the given polygons.
func NewMultiPolygonGeometry(polygons ...[][][]float64) *Geometry {
return &Geometry{
Type: GeometryMultiPolygon,
MultiPolygon: polygons,
}
}
// NewCollectionGeometry creates and initializes a geometry collection geometry with the given geometries.
func NewCollectionGeometry(geometries ...*Geometry) *Geometry {
return &Geometry{
Type: GeometryCollection,
Geometries: geometries,
}
}
// MarshalJSON converts the geometry object into the correct JSON.
// This fulfills the json.Marshaler interface.
func (g Geometry) MarshalJSON() ([]byte, error) {
// defining a struct here lets us define the order of the JSON elements.
type geometry struct {
Type GeometryType `json:"type"`
BoundingBox []float64 `json:"bbox,omitempty"`
Coordinates interface{} `json:"coordinates,omitempty"`
Geometries interface{} `json:"geometries,omitempty"`
CRS map[string]interface{} `json:"crs,omitempty"`
}
geo := &geometry{
Type: g.Type,
}
if g.BoundingBox != nil && len(g.BoundingBox) != 0 {
geo.BoundingBox = g.BoundingBox
}
switch g.Type {
case GeometryPoint:
geo.Coordinates = g.Point
case GeometryMultiPoint:
geo.Coordinates = g.MultiPoint
case GeometryLineString:
geo.Coordinates = g.LineString
case GeometryMultiLineString:
geo.Coordinates = g.MultiLineString
case GeometryPolygon:
geo.Coordinates = g.Polygon
case GeometryMultiPolygon:
geo.Coordinates = g.MultiPolygon
case GeometryCollection:
geo.Geometries = g.Geometries
}
return json.Marshal(geo)
}
// UnmarshalGeometry decodes the data into a GeoJSON geometry.
// Alternately one can call json.Unmarshal(g) directly for the same result.
func UnmarshalGeometry(data []byte) (*Geometry, error) {
g := &Geometry{}
err := json.Unmarshal(data, g)
if err != nil {
return nil, err
}
return g, nil
}
// UnmarshalJSON decodes the data into a GeoJSON geometry.
// This fulfills the json.Unmarshaler interface.
func (g *Geometry) UnmarshalJSON(data []byte) error {
var object map[string]interface{}
err := json.Unmarshal(data, &object)
if err != nil {
return err
}
return decodeGeometry(g, object)
}
// Scan implements the sql.Scanner interface allowing
// geometry structs to be passed into rows.Scan(...interface{})
// The columns must be received as GeoJSON Geometry.
// When using PostGIS a spatial column would need to be wrapped in ST_AsGeoJSON.
func (g *Geometry) Scan(value interface{}) error {
var data []byte
switch value.(type) {
case string:
data = []byte(value.(string))
case []byte:
data = value.([]byte)
default:
return errors.New("unable to parse this type into geojson")
}
return g.UnmarshalJSON(data)
}
func decodeGeometry(g *Geometry, object map[string]interface{}) error {
t, ok := object["type"]
if !ok {
return errors.New("type property not defined")
}
if s, ok := t.(string); ok {
g.Type = GeometryType(s)
} else {
return errors.New("type property not string")
}
bb, err := decodeBoundingBox(object["bbox"])
if err != nil {
return err
}
g.BoundingBox = bb
switch g.Type {
case GeometryPoint:
g.Point, err = decodePosition(object["coordinates"])
case GeometryMultiPoint:
g.MultiPoint, err = decodePositionSet(object["coordinates"])
case GeometryLineString:
g.LineString, err = decodePositionSet(object["coordinates"])
case GeometryMultiLineString:
g.MultiLineString, err = decodePathSet(object["coordinates"])
case GeometryPolygon:
g.Polygon, err = decodePathSet(object["coordinates"])
case GeometryMultiPolygon:
g.MultiPolygon, err = decodePolygonSet(object["coordinates"])
case GeometryCollection:
g.Geometries, err = decodeGeometries(object["geometries"])
}
return err
}
func decodePosition(data interface{}) ([]float64, error) {
coords, ok := data.([]interface{})
if !ok {
return nil, fmt.Errorf("not a valid position, got %v", data)
}
result := make([]float64, 0, len(coords))
for _, coord := range coords {
if f, ok := coord.(float64); ok {
result = append(result, f)
} else {
return nil, fmt.Errorf("not a valid coordinate, got %v", coord)
}
}
return result, nil
}
func decodePositionSet(data interface{}) ([][]float64, error) {
points, ok := data.([]interface{})
if !ok {
return nil, fmt.Errorf("not a valid set of positions, got %v", data)
}
result := make([][]float64, 0, len(points))
for _, point := range points {
if p, err := decodePosition(point); err == nil {
result = append(result, p)
} else {
return nil, err
}
}
return result, nil
}
func decodePathSet(data interface{}) ([][][]float64, error) {
sets, ok := data.([]interface{})
if !ok {
return nil, fmt.Errorf("not a valid path, got %v", data)
}
result := make([][][]float64, 0, len(sets))
for _, set := range sets {
if s, err := decodePositionSet(set); err == nil {
result = append(result, s)
} else {
return nil, err
}
}
return result, nil
}
func decodePolygonSet(data interface{}) ([][][][]float64, error) {
polygons, ok := data.([]interface{})
if !ok {
return nil, fmt.Errorf("not a valid polygon, got %v", data)
}
result := make([][][][]float64, 0, len(polygons))
for _, polygon := range polygons {
if p, err := decodePathSet(polygon); err == nil {
result = append(result, p)
} else {
return nil, err
}
}
return result, nil
}
func decodeGeometries(data interface{}) ([]*Geometry, error) {
if vs, ok := data.([]interface{}); ok {
geometries := make([]*Geometry, 0, len(vs))
for _, v := range vs {
g := &Geometry{}
vmap, ok := v.(map[string]interface{})
if !ok {
break
}
err := decodeGeometry(g, vmap)
if err != nil {
return nil, err
}
geometries = append(geometries, g)
}
if len(geometries) == len(vs) {
return geometries, nil
}
}
return nil, fmt.Errorf("not a valid set of geometries, got %v", data)
}
// IsPoint returns true with the geometry object is a Point type.
func (g *Geometry) IsPoint() bool {
return g.Type == GeometryPoint
}
// IsMultiPoint returns true with the geometry object is a MultiPoint type.
func (g *Geometry) IsMultiPoint() bool {
return g.Type == GeometryMultiPoint
}
// IsLineString returns true with the geometry object is a LineString type.
func (g *Geometry) IsLineString() bool {
return g.Type == GeometryLineString
}
// IsMultiLineString returns true with the geometry object is a LineString type.
func (g *Geometry) IsMultiLineString() bool {
return g.Type == GeometryMultiLineString
}
// IsPolygon returns true with the geometry object is a Polygon type.
func (g *Geometry) IsPolygon() bool {
return g.Type == GeometryPolygon
}
// IsMultiPolygon returns true with the geometry object is a MultiPolygon type.
func (g *Geometry) IsMultiPolygon() bool {
return g.Type == GeometryMultiPolygon
}
// IsCollection returns true with the geometry object is a GeometryCollection type.
func (g *Geometry) IsCollection() bool {
return g.Type == GeometryCollection
}

127
vendor/github.com/paulmach/go.geojson/properties.go generated vendored Normal file
View file

@ -0,0 +1,127 @@
package geojson
import (
"fmt"
)
// SetProperty provides the inverse of all the property functions
// and is here for consistency.
func (f *Feature) SetProperty(key string, value interface{}) {
if f.Properties == nil {
f.Properties = make(map[string]interface{})
}
f.Properties[key] = value
}
// PropertyBool type asserts a property to `bool`.
func (f *Feature) PropertyBool(key string) (bool, error) {
if b, ok := (f.Properties[key]).(bool); ok {
return b, nil
}
return false, fmt.Errorf("type assertion of `%s` to bool failed", key)
}
// PropertyInt type asserts a property to `int`.
func (f *Feature) PropertyInt(key string) (int, error) {
if i, ok := (f.Properties[key]).(int); ok {
return i, nil
}
if i, ok := (f.Properties[key]).(float64); ok {
return int(i), nil
}
return 0, fmt.Errorf("type assertion of `%s` to int failed", key)
}
// PropertyFloat64 type asserts a property to `float64`.
func (f *Feature) PropertyFloat64(key string) (float64, error) {
if i, ok := (f.Properties[key]).(float64); ok {
return i, nil
}
return 0, fmt.Errorf("type assertion of `%s` to float64 failed", key)
}
// PropertyString type asserts a property to `string`.
func (f *Feature) PropertyString(key string) (string, error) {
if s, ok := (f.Properties[key]).(string); ok {
return s, nil
}
return "", fmt.Errorf("type assertion of `%s` to string failed", key)
}
// PropertyMustBool guarantees the return of a `bool` (with optional default)
//
// useful when you explicitly want a `bool` in a single value return context:
// myFunc(f.PropertyMustBool("param1"), f.PropertyMustBool("optional_param", true))
func (f *Feature) PropertyMustBool(key string, def ...bool) bool {
var defaul bool
b, err := f.PropertyBool(key)
if err == nil {
return b
}
if len(def) > 0 {
defaul = def[0]
}
return defaul
}
// PropertyMustInt guarantees the return of a `bool` (with optional default)
//
// useful when you explicitly want a `bool` in a single value return context:
// myFunc(f.PropertyMustInt("param1"), f.PropertyMustInt("optional_param", 123))
func (f *Feature) PropertyMustInt(key string, def ...int) int {
var defaul int
b, err := f.PropertyInt(key)
if err == nil {
return b
}
if len(def) > 0 {
defaul = def[0]
}
return defaul
}
// PropertyMustFloat64 guarantees the return of a `bool` (with optional default)
//
// useful when you explicitly want a `bool` in a single value return context:
// myFunc(f.PropertyMustFloat64("param1"), f.PropertyMustFloat64("optional_param", 10.1))
func (f *Feature) PropertyMustFloat64(key string, def ...float64) float64 {
var defaul float64
b, err := f.PropertyFloat64(key)
if err == nil {
return b
}
if len(def) > 0 {
defaul = def[0]
}
return defaul
}
// PropertyMustString guarantees the return of a `bool` (with optional default)
//
// useful when you explicitly want a `bool` in a single value return context:
// myFunc(f.PropertyMustString("param1"), f.PropertyMustString("optional_param", "default"))
func (f *Feature) PropertyMustString(key string, def ...string) string {
var defaul string
b, err := f.PropertyString(key)
if err == nil {
return b
}
if len(def) > 0 {
defaul = def[0]
}
return defaul
}