routing-service/encoding/polylines/encoding.go

85 lines
2.3 KiB
Go
Raw Normal View History

2023-03-27 18:57:28 +00:00
package polylines
import (
"github.com/paulmach/orb"
"github.com/twpayne/go-polyline"
)
2023-03-29 22:45:55 +00:00
// // Encode encodes coordinates to the "Encoded Polyline Algorithm Format"
// // More info: https://developers.google.com/maps/documentation/utilities/polylinealgorithm
// // points: points of the polyline
// // precision: usually 5 or 6; Google's original algorithm uses 5 digits of decimal precision,
// // which is accurate to about a meter. A precision of 6 gives you an accuracy of about 10cm
// // more info: https://mapzen.com/blog/polyline-precision/
// func Encode(linestring orb.LineString, precision uint32) string {
// encoded := ""
// latitude := 0.0
// longitude := 0.0
// for _, point := range linestring {
// polyLatitude := encodeElement(point.Lat()-latitude, precision)
// encoded += polyLatitude
// polyLongitude := encodeElement(point.Lon()-longitude, precision)
// encoded += polyLongitude
// // to conserve space, points only include the offset from the previous point
// latitude = point.Lat()
// longitude = point.Lon()
// }
// return encoded
// }
// // Encode5 is a short call for Encode with precision set to 5
// // Accuracy is about one meter
// func Encode5(linestring orb.LineString) string {
// return Encode(linestring, 5)
// }
// // Encode6 is a short call for Encode with precision set to 6
// // Accuracy is about ten centimeters
// func Encode6(linestring orb.LineString) string {
// return Encode(linestring, 6)
// }
// // encodeElement encodes an coordinate element (i.e. latitude or longitude)
// // to the "Encoded Polyline Algorithm Format"
// func encodeElement(element float64, precision uint32) string {
// elementInt := int32(math.Round(element * math.Pow10(int(precision))))
// elementInt = elementInt << 1
// if element < 0 {
// elementInt = ^elementInt
// }
// var c chunks
// c.Parse(elementInt)
// return c.String()
// }
// // round n to precision digits
// func round(n float64, precision uint32) float64 {
// factor := math.Pow10(int(precision))
// return math.Round(n*factor) / factor
// }
func Encode(line orb.LineString, precision uint32) string {
2023-03-27 18:57:28 +00:00
preparedLine := [][]float64{}
for _, point := range line {
2023-03-29 22:45:55 +00:00
preparedLine = append(preparedLine, []float64{point.Lat(), point.Lon()})
2023-03-27 18:57:28 +00:00
}
return string(polyline.EncodeCoords(preparedLine))
}