fixed dependencies
This commit is contained in:
60
vendor/github.com/paulmach/orb/geo/README.md
generated
vendored
Normal file
60
vendor/github.com/paulmach/orb/geo/README.md
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
# orb/geo [](https://pkg.go.dev/github.com/paulmach/orb/geo)
|
||||
|
||||
The geometries defined in the `orb` package are generic 2d geometries.
|
||||
Depending on what projection they're in, e.g. lon/lat or flat on the plane,
|
||||
area and distance calculations are different. This package implements methods
|
||||
that assume the lon/lat or WGS84 projection.
|
||||
|
||||
## Examples
|
||||
|
||||
Area of the [San Francisco Main Library](https://www.openstreetmap.org/way/24446086):
|
||||
|
||||
```go
|
||||
poly := orb.Polygon{
|
||||
{
|
||||
{ -122.4163816, 37.7792782 },
|
||||
{ -122.4162786, 37.7787626 },
|
||||
{ -122.4151027, 37.7789118 },
|
||||
{ -122.4152143, 37.7794274 },
|
||||
{ -122.4163816, 37.7792782 },
|
||||
},
|
||||
}
|
||||
|
||||
a := geo.Area(poly)
|
||||
|
||||
fmt.Printf("%f m^2", a)
|
||||
// Output:
|
||||
// 6073.368008 m^2
|
||||
```
|
||||
|
||||
Distance between two points:
|
||||
|
||||
```go
|
||||
oakland := orb.Point{-122.270833, 37.804444}
|
||||
sf := orb.Point{-122.416667, 37.783333}
|
||||
|
||||
d := geo.Distance(oakland, sf)
|
||||
|
||||
fmt.Printf("%0.3f meters", d)
|
||||
// Output:
|
||||
// 13042.047 meters
|
||||
```
|
||||
|
||||
Circumference of the [San Francisco Main Library](https://www.openstreetmap.org/way/24446086):
|
||||
|
||||
```go
|
||||
poly := orb.Polygon{
|
||||
{
|
||||
{ -122.4163816, 37.7792782 },
|
||||
{ -122.4162786, 37.7787626 },
|
||||
{ -122.4151027, 37.7789118 },
|
||||
{ -122.4152143, 37.7794274 },
|
||||
{ -122.4163816, 37.7792782 },
|
||||
},
|
||||
}
|
||||
l := geo.Length(poly)
|
||||
|
||||
fmt.Printf("%0.0f meters", l)
|
||||
// Output:
|
||||
// 325 meters
|
||||
```
|
||||
112
vendor/github.com/paulmach/orb/geo/area.go
generated
vendored
Normal file
112
vendor/github.com/paulmach/orb/geo/area.go
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
// Package geo computes properties on geometries assuming they are lon/lat data.
|
||||
package geo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/paulmach/orb"
|
||||
)
|
||||
|
||||
// Area returns the area of the geometry on the earth.
|
||||
func Area(g orb.Geometry) float64 {
|
||||
if g == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
switch g := g.(type) {
|
||||
case orb.Point, orb.MultiPoint, orb.LineString, orb.MultiLineString:
|
||||
return 0
|
||||
case orb.Ring:
|
||||
return math.Abs(ringArea(g))
|
||||
case orb.Polygon:
|
||||
return polygonArea(g)
|
||||
case orb.MultiPolygon:
|
||||
return multiPolygonArea(g)
|
||||
case orb.Collection:
|
||||
return collectionArea(g)
|
||||
case orb.Bound:
|
||||
return Area(g.ToRing())
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("geometry type not supported: %T", g))
|
||||
}
|
||||
|
||||
// SignedArea will return the signed area of the ring.
|
||||
// Will return negative if the ring is in the clockwise direction.
|
||||
// Will implicitly close the ring.
|
||||
func SignedArea(r orb.Ring) float64 {
|
||||
return ringArea(r)
|
||||
}
|
||||
|
||||
func ringArea(r orb.Ring) float64 {
|
||||
if len(r) < 3 {
|
||||
return 0
|
||||
}
|
||||
var lo, mi, hi int
|
||||
|
||||
l := len(r)
|
||||
if r[0] != r[len(r)-1] {
|
||||
// if not a closed ring, add an implicit calc for that last point.
|
||||
l++
|
||||
}
|
||||
|
||||
// To support implicit closing of ring, replace references to
|
||||
// the last point in r to the first 1.
|
||||
|
||||
area := 0.0
|
||||
for i := 0; i < l; i++ {
|
||||
if i == l-3 { // i = N-3
|
||||
lo = l - 3
|
||||
mi = l - 2
|
||||
hi = 0
|
||||
} else if i == l-2 { // i = N-2
|
||||
lo = l - 2
|
||||
mi = 0
|
||||
hi = 0
|
||||
} else if i == l-1 { // i = N-1
|
||||
lo = 0
|
||||
mi = 0
|
||||
hi = 1
|
||||
} else { // i = 0 to N-3
|
||||
lo = i
|
||||
mi = i + 1
|
||||
hi = i + 2
|
||||
}
|
||||
|
||||
area += (deg2rad(r[hi][0]) - deg2rad(r[lo][0])) * math.Sin(deg2rad(r[mi][1]))
|
||||
}
|
||||
|
||||
return -area * orb.EarthRadius * orb.EarthRadius / 2
|
||||
}
|
||||
|
||||
func polygonArea(p orb.Polygon) float64 {
|
||||
if len(p) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
sum := math.Abs(ringArea(p[0]))
|
||||
for i := 1; i < len(p); i++ {
|
||||
sum -= math.Abs(ringArea(p[i]))
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
|
||||
func multiPolygonArea(mp orb.MultiPolygon) float64 {
|
||||
sum := 0.0
|
||||
for _, p := range mp {
|
||||
sum += polygonArea(p)
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
|
||||
func collectionArea(c orb.Collection) float64 {
|
||||
area := 0.0
|
||||
for _, g := range c {
|
||||
area += Area(g)
|
||||
}
|
||||
|
||||
return area
|
||||
}
|
||||
97
vendor/github.com/paulmach/orb/geo/bound.go
generated
vendored
Normal file
97
vendor/github.com/paulmach/orb/geo/bound.go
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
package geo
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/paulmach/orb"
|
||||
)
|
||||
|
||||
// NewBoundAroundPoint creates a new bound given a center point,
|
||||
// and a distance from the center point in meters.
|
||||
func NewBoundAroundPoint(center orb.Point, distance float64) orb.Bound {
|
||||
radDist := distance / orb.EarthRadius
|
||||
radLat := deg2rad(center[1])
|
||||
radLon := deg2rad(center[0])
|
||||
minLat := radLat - radDist
|
||||
maxLat := radLat + radDist
|
||||
|
||||
var minLon, maxLon float64
|
||||
if minLat > minLatitude && maxLat < maxLatitude {
|
||||
deltaLon := math.Asin(math.Sin(radDist) / math.Cos(radLat))
|
||||
minLon = radLon - deltaLon
|
||||
if minLon < minLongitude {
|
||||
minLon += 2 * math.Pi
|
||||
}
|
||||
maxLon = radLon + deltaLon
|
||||
if maxLon > maxLongitude {
|
||||
maxLon -= 2 * math.Pi
|
||||
}
|
||||
} else {
|
||||
minLat = math.Max(minLat, minLatitude)
|
||||
maxLat = math.Min(maxLat, maxLatitude)
|
||||
minLon = minLongitude
|
||||
maxLon = maxLongitude
|
||||
}
|
||||
|
||||
return orb.Bound{
|
||||
Min: orb.Point{rad2deg(minLon), rad2deg(minLat)},
|
||||
Max: orb.Point{rad2deg(maxLon), rad2deg(maxLat)},
|
||||
}
|
||||
}
|
||||
|
||||
// BoundPad expands the bound in all directions by the given amount of meters.
|
||||
func BoundPad(b orb.Bound, meters float64) orb.Bound {
|
||||
dy := meters / 111131.75
|
||||
dx := dy / math.Cos(deg2rad(b.Max[1]))
|
||||
dx = math.Max(dx, dy/math.Cos(deg2rad(b.Min[1])))
|
||||
|
||||
b.Min[0] -= dx
|
||||
b.Min[1] -= dy
|
||||
|
||||
b.Max[0] += dx
|
||||
b.Max[1] += dy
|
||||
|
||||
b.Min[0] = math.Max(b.Min[0], -180)
|
||||
b.Min[1] = math.Max(b.Min[1], -90)
|
||||
|
||||
b.Max[0] = math.Min(b.Max[0], 180)
|
||||
b.Max[1] = math.Min(b.Max[1], 90)
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// BoundHeight returns the approximate height in meters.
|
||||
func BoundHeight(b orb.Bound) float64 {
|
||||
return 111131.75 * (b.Max[1] - b.Min[1])
|
||||
}
|
||||
|
||||
// BoundWidth returns the approximate width in meters
|
||||
// of the center of the bound.
|
||||
func BoundWidth(b orb.Bound) float64 {
|
||||
c := (b.Min[1] + b.Max[1]) / 2.0
|
||||
|
||||
s1 := orb.Point{b.Min[0], c}
|
||||
s2 := orb.Point{b.Max[0], c}
|
||||
|
||||
return Distance(s1, s2)
|
||||
}
|
||||
|
||||
//MinLatitude is the minimum possible latitude
|
||||
var minLatitude = deg2rad(-90)
|
||||
|
||||
//MaxLatitude is the maxiumum possible latitude
|
||||
var maxLatitude = deg2rad(90)
|
||||
|
||||
//MinLongitude is the minimum possible longitude
|
||||
var minLongitude = deg2rad(-180)
|
||||
|
||||
//MaxLongitude is the maxiumum possible longitude
|
||||
var maxLongitude = deg2rad(180)
|
||||
|
||||
func deg2rad(d float64) float64 {
|
||||
return d * math.Pi / 180.0
|
||||
}
|
||||
|
||||
func rad2deg(r float64) float64 {
|
||||
return 180.0 * r / math.Pi
|
||||
}
|
||||
119
vendor/github.com/paulmach/orb/geo/distance.go
generated
vendored
Normal file
119
vendor/github.com/paulmach/orb/geo/distance.go
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
package geo
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/paulmach/orb"
|
||||
)
|
||||
|
||||
// Distance returns the distance between two points on the earth.
|
||||
func Distance(p1, p2 orb.Point) float64 {
|
||||
dLat := deg2rad(p1[1] - p2[1])
|
||||
dLon := deg2rad(p1[0] - p2[0])
|
||||
|
||||
dLon = math.Abs(dLon)
|
||||
if dLon > math.Pi {
|
||||
dLon = 2*math.Pi - dLon
|
||||
}
|
||||
|
||||
// fast way using pythagorean theorem on an equirectangular projection
|
||||
x := dLon * math.Cos(deg2rad((p1[1]+p2[1])/2.0))
|
||||
return math.Sqrt(dLat*dLat+x*x) * orb.EarthRadius
|
||||
}
|
||||
|
||||
// DistanceHaversine computes the distance on the earth using the
|
||||
// more accurate haversine formula.
|
||||
func DistanceHaversine(p1, p2 orb.Point) float64 {
|
||||
dLat := deg2rad(p1[1] - p2[1])
|
||||
dLon := deg2rad(p1[0] - p2[0])
|
||||
|
||||
dLat2Sin := math.Sin(dLat / 2)
|
||||
dLon2Sin := math.Sin(dLon / 2)
|
||||
a := dLat2Sin*dLat2Sin + math.Cos(deg2rad(p2[1]))*math.Cos(deg2rad(p1[1]))*dLon2Sin*dLon2Sin
|
||||
|
||||
return 2.0 * orb.EarthRadius * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))
|
||||
}
|
||||
|
||||
// Bearing computes the direction one must start traveling on earth
|
||||
// to be heading from, to the given points.
|
||||
func Bearing(from, to orb.Point) float64 {
|
||||
dLon := deg2rad(to[0] - from[0])
|
||||
|
||||
fromLatRad := deg2rad(from[1])
|
||||
toLatRad := deg2rad(to[1])
|
||||
|
||||
y := math.Sin(dLon) * math.Cos(toLatRad)
|
||||
x := math.Cos(fromLatRad)*math.Sin(toLatRad) - math.Sin(fromLatRad)*math.Cos(toLatRad)*math.Cos(dLon)
|
||||
|
||||
return rad2deg(math.Atan2(y, x))
|
||||
}
|
||||
|
||||
// Midpoint returns the half-way point along a great circle path between the two points.
|
||||
func Midpoint(p, p2 orb.Point) orb.Point {
|
||||
dLon := deg2rad(p2[0] - p[0])
|
||||
|
||||
aLatRad := deg2rad(p[1])
|
||||
bLatRad := deg2rad(p2[1])
|
||||
|
||||
x := math.Cos(bLatRad) * math.Cos(dLon)
|
||||
y := math.Cos(bLatRad) * math.Sin(dLon)
|
||||
|
||||
r := orb.Point{
|
||||
deg2rad(p[0]) + math.Atan2(y, math.Cos(aLatRad)+x),
|
||||
math.Atan2(math.Sin(aLatRad)+math.Sin(bLatRad), math.Sqrt((math.Cos(aLatRad)+x)*(math.Cos(aLatRad)+x)+y*y)),
|
||||
}
|
||||
|
||||
// convert back to degrees
|
||||
r[0] = rad2deg(r[0])
|
||||
r[1] = rad2deg(r[1])
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// PointAtBearingAndDistance returns the point at the given bearing and distance in meters from the point
|
||||
func PointAtBearingAndDistance(p orb.Point, bearing, distance float64) orb.Point {
|
||||
aLat := deg2rad(p[1])
|
||||
aLon := deg2rad(p[0])
|
||||
|
||||
bearingRadians := deg2rad(bearing)
|
||||
|
||||
distanceRatio := distance / orb.EarthRadius
|
||||
bLat := math.Asin(math.Sin(aLat)*math.Cos(distanceRatio) + math.Cos(aLat)*math.Sin(distanceRatio)*math.Cos(bearingRadians))
|
||||
bLon := aLon +
|
||||
math.Atan2(
|
||||
math.Sin(bearingRadians)*math.Sin(distanceRatio)*math.Cos(aLat),
|
||||
math.Cos(distanceRatio)-math.Sin(aLat)*math.Sin(bLat),
|
||||
)
|
||||
|
||||
return orb.Point{rad2deg(bLon), rad2deg(bLat)}
|
||||
}
|
||||
|
||||
func PointAtDistanceAlongLine(ls orb.LineString, distance float64) (orb.Point, float64) {
|
||||
if len(ls) == 0 {
|
||||
panic("empty LineString")
|
||||
}
|
||||
|
||||
if distance < 0 || len(ls) == 1 {
|
||||
return ls[0], 0.0
|
||||
}
|
||||
|
||||
var (
|
||||
travelled = 0.0
|
||||
from, to orb.Point
|
||||
)
|
||||
|
||||
for i := 1; i < len(ls); i++ {
|
||||
from, to = ls[i-1], ls[i]
|
||||
|
||||
actualSegmentDistance := DistanceHaversine(from, to)
|
||||
expectedSegmentDistance := distance - travelled
|
||||
|
||||
if expectedSegmentDistance < actualSegmentDistance {
|
||||
bearing := Bearing(from, to)
|
||||
return PointAtBearingAndDistance(from, bearing, expectedSegmentDistance), bearing
|
||||
}
|
||||
travelled += actualSegmentDistance
|
||||
}
|
||||
|
||||
return to, Bearing(from, to)
|
||||
}
|
||||
26
vendor/github.com/paulmach/orb/geo/length.go
generated
vendored
Normal file
26
vendor/github.com/paulmach/orb/geo/length.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
package geo
|
||||
|
||||
import (
|
||||
"github.com/paulmach/orb"
|
||||
"github.com/paulmach/orb/internal/length"
|
||||
)
|
||||
|
||||
// Length returns the length of the boundary of the geometry
|
||||
// using the geo distance function.
|
||||
func Length(g orb.Geometry) float64 {
|
||||
return length.Length(g, Distance)
|
||||
}
|
||||
|
||||
// LengthHaversign returns the length of the boundary of the geometry
|
||||
// using the geo haversine formula
|
||||
//
|
||||
// Deprecated: misspelled, use correctly spelled `LengthHaversine` instead.
|
||||
func LengthHaversign(g orb.Geometry) float64 {
|
||||
return length.Length(g, DistanceHaversine)
|
||||
}
|
||||
|
||||
// LengthHaversine returns the length of the boundary of the geometry
|
||||
// using the geo haversine formula
|
||||
func LengthHaversine(g orb.Geometry) float64 {
|
||||
return length.Length(g, DistanceHaversine)
|
||||
}
|
||||
Reference in New Issue
Block a user