package polylines import ( "github.com/paulmach/orb" "github.com/twpayne/go-polyline" ) // // 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 { preparedLine := [][]float64{} for _, point := range line { preparedLine = append(preparedLine, []float64{point.Lat(), point.Lon()}) } return string(polyline.EncodeCoords(preparedLine)) }