Skip to content

Commit e39fedb

Browse files
committed
send dist in KM
1 parent a823462 commit e39fedb

File tree

6 files changed

+65
-15
lines changed

6 files changed

+65
-15
lines changed

bin/main

9.7 KB
Binary file not shown.

geojson-cleaner/geojson-cleaner.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,12 @@ func main() {
6565
isHighway := geojson.Features[i].Properties.Highway != ""
6666
hasSidewalk := geojson.Features[i].Properties.Sidewalk == "" || geojson.Features[i].Properties.Sidewalk != "none"
6767
isPath := geojson.Features[i].Properties.Highway == "path"
68-
isValidPath := geojson.Features[i].Properties.Highway == "path" && (geojson.Features[i].Properties.Access == "no" || geojson.Features[i].Properties.Access == "private")
69-
isNotPathOrIsValidPath := !isPath || isValidPath
68+
isPathWithAccess := geojson.Features[i].Properties.Highway == "path" && (geojson.Features[i].Properties.Access == "no" || geojson.Features[i].Properties.Access == "private")
69+
isNotPathOrIsValidPath := !isPath || isPathWithAccess
7070
isLit := geojson.Features[i].Properties.Lit != "" || geojson.Features[i].Properties.Lit == "yes"
7171
shouldInclude := isHighway && isLineString && hasSidewalk && isNotPathOrIsValidPath && isLit
72+
// TODO: exclude footways for cycling
73+
// isFootway := geojson.Features[i].Properties.Highway == "footway"
7274
// shouldInclude := true
7375
var feature = geojson.Features[i]
7476
if shouldInclude && len(feature.Geometry.Coordinates) > 0 {

graph.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,13 @@ type Route struct {
157157
Distance float64
158158
}
159159

160+
// calcDistance between coords in coords unit
161+
func calcDistance(src, dest *Node) float64 {
162+
dx := src[0] - dest[0]
163+
dy := src[1] - dest[1]
164+
return math.Sqrt(dx*dx + dy*dy)
165+
}
166+
160167
/*
161168
FindPath Uses A* routing to find shortest path
162169
(Keeps a min heap sorted by elapsed + remaing distance).
@@ -188,14 +195,8 @@ func (graph *Graph) FindPath(src, dest Node) Route {
188195
visited[node] = true
189196

190197
for child := range graph.edges[*node] {
191-
// TODO: Calculate in km
192-
// https://stackoverflow.com/a/1253545/1376627
193-
dx := (node[0] - child[0])
194-
dy := (node[1] - child[1])
195-
remaingDx := (dest[0] - child[0])
196-
remainingDy := (dest[1] - child[1])
197-
elapsed := math.Sqrt(dx*dx+dy*dy) + cur.Distance
198-
remaining := math.Sqrt(remaingDx*remaingDx + remainingDy*remainingDy)
198+
elapsed := calcDistance(node, child) + cur.Distance
199+
remaining := calcDistance(child, &dest)
199200

200201
if *child == dest {
201202
path := append(cur.Path, *child)

parse-geojson.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type Property struct {
1717
Sidewalk string `json:"sidewalk"`
1818
}
1919

20-
// Coordinate pair of lat, lng
20+
// Coordinate pair of lng, lat
2121
type Coordinate [2]float64
2222

2323
// Geometry Geojson Geometry

routing_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func TestPaths(t *testing.T) {
8787
t.Errorf("Incorrect path. Got: %v Expected: %v -- %s", path, expected.ShortestPath, filenames[i])
8888
}
8989
if route.Distance != expected.Distance {
90-
t.Errorf("Incorrect distance. Got: %f Want: %f -- %s", route.Distance, expected.Distance, filenames[i])
90+
t.Errorf("Incorrect distance. Got: %.11f Want: %.11f -- %s", route.Distance, expected.Distance, filenames[i])
9191
}
9292
}
9393

travel-api.go

+50-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"io/ioutil"
77
"log"
8+
"math"
89
"net/http"
910
"os"
1011

@@ -25,6 +26,53 @@ func getCoordinates(nodes []Node) []Coordinate {
2526
return result
2627
}
2728

29+
//::: unit = the unit you desire for results :::
30+
//::: where: 'M' is statute miles (default) :::
31+
//::: 'K' is kilometers :::
32+
//::: 'N' is nautical miles :::
33+
func distance(coord1 Coordinate, coord2 Coordinate, unit ...string) float64 {
34+
lng1 := coord1[0]
35+
lat1 := coord1[1]
36+
lng2 := coord2[0]
37+
lat2 := coord2[1]
38+
const PI float64 = 3.141592653589793
39+
radlat1 := float64(PI * lat1 / 180)
40+
radlat2 := float64(PI * lat2 / 180)
41+
42+
theta := float64(lng1 - lng2)
43+
radtheta := float64(PI * theta / 180)
44+
45+
dist := math.Sin(radlat1)*math.Sin(radlat2) + math.Cos(radlat1)*math.Cos(radlat2)*math.Cos(radtheta)
46+
47+
if dist > 1 {
48+
dist = 1
49+
}
50+
51+
dist = math.Acos(dist)
52+
dist = dist * 180 / PI
53+
dist = dist * 60 * 1.1515
54+
55+
if len(unit) > 0 {
56+
if unit[0] == "K" {
57+
dist = dist * 1.609344
58+
} else if unit[0] == "N" {
59+
dist = dist * 0.8684
60+
}
61+
}
62+
63+
return dist
64+
}
65+
66+
func calcTotalDistance(coords []Coordinate) float64 {
67+
sum := 0.0
68+
for i := 0; i < len(coords); i++ {
69+
if i > 0 {
70+
sum += distance(coords[i-1], coords[i], "K")
71+
}
72+
}
73+
return sum
74+
}
75+
2876
func setJSONHeader(w *http.ResponseWriter) {
2977
(*w).Header().Set("Content-Type", "application/json")
3078
}
@@ -50,6 +98,7 @@ func findpathHandler(w http.ResponseWriter, r *http.Request) {
5098

5199
route := graph.CalculatePath(newRequestBody.FromLocation, newRequestBody.ToLocation)
52100
coords := getCoordinates(route.Path)
101+
distance := calcTotalDistance(coords)
53102

54103
geometry := Geometry{Type: "LineString", Coordinates: coords}
55104
featureOut := Feature{Type: "Feature", ID: "1234", Properties: Property{}, Geometry: geometry}
@@ -62,9 +111,7 @@ func findpathHandler(w http.ResponseWriter, r *http.Request) {
62111
Features: features,
63112
}
64113

65-
response := FindPathResponse{
66-
Data: data,
67-
Distance: route.Distance}
114+
response := FindPathResponse{data, distance}
68115

69116
geojsonDataInJSON, _ := json.Marshal(&response)
70117

0 commit comments

Comments
 (0)