mirror of https://github.com/tidwall/tile38.git
Updated geojson package
This commit is contained in:
parent
37d64f0466
commit
85b70e0d26
|
@ -221,7 +221,8 @@
|
|||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:cdab3bce90a53a124ac3982719abde77d779e961d9c180e55c23fb74fc62563a"
|
||||
branch = "master"
|
||||
digest = "1:16a87d3d8d3808f3206c4992d1fb50440bb7d5508fbe5bfab7d899b516c7f3b8"
|
||||
name = "github.com/tidwall/geojson"
|
||||
packages = [
|
||||
".",
|
||||
|
@ -229,8 +230,7 @@
|
|||
"geometry",
|
||||
]
|
||||
pruneopts = ""
|
||||
revision = "eaf6e0a55a79c1e879bbbcc879a3176c720d99cd"
|
||||
version = "v1.1.3"
|
||||
revision = "ff8d554639ee72ffa650eca1e02f03ab51193c7f"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3ddca2bd5496c6922a2a9e636530e178a43c2a534ea6634211acdc7d10222794"
|
||||
|
|
|
@ -34,8 +34,8 @@ required = [
|
|||
name = "github.com/tidwall/boxtree"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/tidwall/geojson"
|
||||
version = "1.1.3"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/Shopify/sarama"
|
||||
|
|
|
@ -93,75 +93,60 @@ func BearingTo(latA, lonA, latB, lonB float64) float64 {
|
|||
func RectFromCenter(lat, lon, meters float64) (
|
||||
minLat, minLon, maxLat, maxLon float64,
|
||||
) {
|
||||
|
||||
// see http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates#Latitude
|
||||
// convert degrees to radians
|
||||
lat *= radians
|
||||
lon *= radians
|
||||
|
||||
r := meters / earthRadius // angular radius
|
||||
// Calculate ANGULAR RADIUS
|
||||
// see http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates#UsingIndex
|
||||
r := meters / earthRadius
|
||||
|
||||
// Calculate LATITUDE min and max
|
||||
// see http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates#Latitude
|
||||
minLat = lat - r
|
||||
maxLat = lat + r
|
||||
|
||||
// Calculate LONGITUDE min and max
|
||||
// see http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates#Longitude
|
||||
latT := math.Asin(math.Sin(lat) / math.Cos(r))
|
||||
lonΔ := math.Acos((math.Cos(r) - math.Sin(latT)*math.Sin(lat)) / (math.Cos(latT) * math.Cos(lat)))
|
||||
|
||||
minLon = lon - lonΔ
|
||||
maxLon = lon + lonΔ
|
||||
|
||||
// Adjust for north poll
|
||||
// ADJUST mins and maxes for edge-of-map cases
|
||||
// see http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates#PolesAnd180thMeridian
|
||||
|
||||
// adjust for NORTH POLE
|
||||
if maxLat > math.Pi/2 {
|
||||
minLon = -math.Pi
|
||||
maxLat = math.Pi / 2
|
||||
maxLon = math.Pi
|
||||
}
|
||||
|
||||
// Adjust for south poll
|
||||
// adjust for SOUTH POLE
|
||||
if minLat < -math.Pi/2 {
|
||||
minLat = -math.Pi / 2
|
||||
minLon = -math.Pi
|
||||
maxLon = math.Pi
|
||||
}
|
||||
|
||||
// Adjust for wraparound. Remove this if the commented-out condition below this block is added.
|
||||
/* adjust for WRAPAROUND
|
||||
|
||||
Creates a bounding box that wraps around the Earth like a belt, which
|
||||
results in returning false positive candidates (candidates that are
|
||||
farther away from the center than the distance of the search radius).
|
||||
|
||||
An alternative method, possibly to be implemented in the future, would be
|
||||
to split the bounding box into two boxes. This would return fewer (or no)
|
||||
false positives, but will require significant changes to the API's of
|
||||
geoJSON and any of its dependents. */
|
||||
if minLon < -math.Pi || maxLon > math.Pi {
|
||||
minLon = -math.Pi
|
||||
maxLon = math.Pi
|
||||
}
|
||||
|
||||
/*
|
||||
// Consider splitting area into two bboxes, using the below checks, and erasing above block for performance. See http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates#PolesAnd180thMeridian
|
||||
// Adjust for wraparound if minimum longitude is less than -180 degrees.
|
||||
if lonMin < -math.Pi {
|
||||
// box 1:
|
||||
latMin = latMin
|
||||
latMax = latMax
|
||||
lonMin += 2*math.Pi
|
||||
lonMax = math.Pi
|
||||
// box 2:
|
||||
latMin = latMin
|
||||
latMax = latMax
|
||||
lonMin = -math.Pi
|
||||
lonMax = lonMax
|
||||
}
|
||||
// Adjust for wraparound if maximum longitude is greater than 180 degrees.
|
||||
if lonMax > math.Pi {
|
||||
// box 1:
|
||||
latMin = latMin
|
||||
latMax = latMax
|
||||
lonMin = lonMin
|
||||
lonMax = -math.Pi
|
||||
// box 2:
|
||||
latMin = latMin
|
||||
latMax = latMax
|
||||
lonMin = -math.Pi
|
||||
lonMax -= 2*math.Pi
|
||||
}
|
||||
*/
|
||||
|
||||
minLon = math.Mod(minLon+3*math.Pi, 2*math.Pi) - math.Pi // normalise to -180..+180°
|
||||
maxLon = math.Mod(maxLon+3*math.Pi, 2*math.Pi) - math.Pi
|
||||
|
||||
// convert radians to degrees
|
||||
minLat *= degrees
|
||||
minLon *= degrees
|
||||
maxLat *= degrees
|
||||
|
|
|
@ -41,6 +41,68 @@ func TestGeoCalc(t *testing.T) {
|
|||
if value2 != lonB {
|
||||
t.Fatalf("expected '%v', got '%v'", lonB, value2)
|
||||
}
|
||||
// RectFromCenter
|
||||
// expected mins and maxes for wraparound and pole tests
|
||||
expMinLat := -90.0
|
||||
expMinLon := -180.0
|
||||
expMaxLat := 90.0
|
||||
expMaxLon := 180.0
|
||||
|
||||
dist1 := 1600000.0
|
||||
|
||||
wraparoundTests := []struct {
|
||||
name string
|
||||
lat, lon, searchRadius float64
|
||||
}{
|
||||
{name: "Wraparound E", lat: 0.0, lon: 179.0, searchRadius: dist1}, // at equator near 180th meridian East
|
||||
{name: "Wraparound W", lat: 0.0, lon: -179.0, searchRadius: dist1}, // at equator near 180th meridian West
|
||||
}
|
||||
|
||||
for _, tt := range wraparoundTests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, minLon, _, maxLon := RectFromCenter(tt.lat, tt.lon, tt.searchRadius)
|
||||
if !(minLon == expMinLon && maxLon == expMaxLon) {
|
||||
t.Errorf("\nexpected minLon = '%v', maxLon = '%v'"+"\ngot minLon = '%v', maxLon = '%v'\n",
|
||||
expMinLon, expMaxLon,
|
||||
minLon, maxLon)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
northPoleTests := []struct {
|
||||
name string
|
||||
lat, lon, searchRadius float64
|
||||
}{
|
||||
{name: "North Pole", lat: 89.0, lon: 90.0, searchRadius: dist1}, // near North Pole
|
||||
{name: "North Pole: Tile38 iss422", lat: 13.0257553, lon: 77.6672509, searchRadius: 9000000.0},
|
||||
}
|
||||
for _, tt := range northPoleTests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, minLon, maxLat, maxLon := RectFromCenter(tt.lat, tt.lon, tt.searchRadius)
|
||||
if !(minLon == expMinLon && maxLat == expMaxLat && maxLon == expMaxLon) {
|
||||
t.Errorf("\nexpected minLon = '%v', maxLat = '%v', maxLon = '%v'"+"\ngot minLon = '%v', maxLat = '%v', maxLon = '%v'",
|
||||
expMinLon, expMaxLat, expMaxLon,
|
||||
minLon, maxLat, maxLon)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
southPoleTests := []struct {
|
||||
name string
|
||||
lat, lon, searchRadius float64
|
||||
}{
|
||||
{name: "South Pole", lat: -89.0, lon: 90.0, searchRadius: dist1}, // near South Pole
|
||||
}
|
||||
for _, tt := range southPoleTests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
minLat, minLon, _, maxLon := RectFromCenter(tt.lat, tt.lon, tt.searchRadius)
|
||||
if !(minLat == expMinLat && minLon == expMinLon && maxLon == expMaxLon) {
|
||||
t.Errorf("\nexpected minLat = '%v', minLon = '%v', maxLon = '%v'"+"\ngot minLat = '%v', minLon = '%v', maxLon = '%v'",
|
||||
expMinLat, expMinLon, expMaxLon,
|
||||
minLat, minLon, maxLon)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHaversine(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue