unir una polilineas polilinea para multiple lineas linea ingles hacer definicion convertir como comando c# .net algorithm google-maps gis

c# - una - convertir polilinea a linea multiple



Implementación de C#del ''Algoritmo de polilínea codificada'' de Google (3)

Aquí está la implementación que establecí:

public static string Encode(IEnumerable<GeoLocation> points) { var str = new StringBuilder(); var encodeDiff = (Action<int>)(diff => { int shifted = diff << 1; if (diff < 0) shifted = ~shifted; int rem = shifted; while (rem >= 0x20) { str.Append((char)((0x20 | (rem & 0x1f)) + 63)); rem >>= 5; } str.Append((char)(rem + 63)); }); int lastLat = 0; int lastLng = 0; foreach (var point in points) { int lat = (int)Math.Round(point.Latitude * 1E5); int lng = (int)Math.Round(point.Longitude * 1E5); encodeDiff(lat - lastLat); encodeDiff(lng - lastLng); lastLat = lat; lastLng = lng; } return str.ToString(); }

Espero que ayude a alguien más.

¿Alguien tiene una implementación concisa y robusta del algoritmo de polilínea codificada de Google en C #?

Básicamente quiero la implementación de esta firma:

public string Encode(IEnumerable<Point> points);


Implementación de Javascript, en caso de que alguien esté interesado:

var polyline_encoder = (function() { var _ = {}; var invert_bits = function(str) { var ret = ""; for(var i=0; i<str.length; i++) { if(str.charAt(i) == "1") ret += "0"; else ret += "1"; } return ret; }; var get_binary = function(num) { var binary = parseInt(num).toString(2); var bit_difference = 32 - binary.length; for(var i=0; i<bit_difference; i++) binary = "0" + binary; if(num < 0) { binary = invert_bits(binary); binary = parseInt(binary, 2); binary++; return parseInt(binary).toString(2); } return binary; }; _.encode_polyline = function(points) { var ret = ""; var last_point, val_1, val_2; for(var i=0; i<points.length; i++) { if(!last_point) { val_1 = points[i][0]; val_2 = points[i][1]; } else { val_1 = points[i][0] - last_point[0]; val_2 = points[i][1] - last_point[1]; } last_point = points[i]; ret += _.encode_polyline_value(val_1) + _.encode_polyline_value(val_2); } return ret; }; _.encode_polyline_value = function(value) { var ret = ""; value = Math.round(value * 100000); var shifted = value << 1; if(shifted < 0) shifted = ~shifted; var rem = shifted; while(rem >= 32) { ret += get_ascii_value(((0x20 | (rem & 0x1f)) + 63)); rem >>= 5; } ret += get_ascii_value(rem + 63); return ret; }; var get_ascii_value = function(num) { var ascii_table = // 0 thru 9 "??????????" + // 10 thru 19 "??????????" + // 20 thru 29 "??????????" + // 30 thru 39 "?? !/"#$%&''" + // 40 thru 49 "()*+,-./01" + // 50 thru 59 "23456789:;" + // 60 thru 69 "<=>?@ABCDE" + // 70 thru 79 "FGHIJKLMNO" + // 80 thru 89 "PQRSTUVWXY" + // 90 thru 99 "Z[//]^_`abc" + // 100 thru 109 "defghijklm" + // 110 thru 119 "nopqrstuvw" + // 120 thru 127 "xyz{|}~?"; var value = ascii_table.substr(num, 1); if(value == "?") value = ""; return value; }; return _; })();


Quizás es tarde pero acabo de resolver el mismo problema, pero para codificar la lista de ubicaciones y las polilíneas Decode, utilicé http://json2csharp.com/ para generar las clases correspondientes en C # para deserializar la respuesta con JsonConvert como:

var googleDirectionsResponse = JsonConvert.DeserializeObject<RootObject>(responseString);

Esto me dio esta definición de Ubicación (lo limpiaré tarde o temprano):

public class Location { public double lat { get; set; } public double lng { get; set; } }

Y creé una clase de convertidor para hacer el truco en ambas direcciones (no es original, es solo un refactor de esta clase: https://gist.github.com/shinyzhu/4617989 ):

/// <summary> /// Google Polyline Converter (Encoder and Decoder) /// </summary> public static class GooglePolylineConverter { /// <summary> /// Decodes the specified polyline string. /// </summary> /// <param name="polylineString">The polyline string.</param> /// <returns>A list with Locations</returns> public static IEnumerable<Location> Decode(string polylineString) { if (string.IsNullOrEmpty(polylineString)) throw new ArgumentNullException(nameof(polylineString)); var polylineChars = polylineString.ToCharArray(); var index = 0; var currentLat = 0; var currentLng = 0; while (index < polylineChars.Length) { // Next lat var sum = 0; var shifter = 0; int nextFiveBits; do { nextFiveBits = polylineChars[index++] - 63; sum |= (nextFiveBits & 31) << shifter; shifter += 5; } while (nextFiveBits >= 32 && index < polylineChars.Length); if (index >= polylineChars.Length) break; currentLat += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1); // Next lng sum = 0; shifter = 0; do { nextFiveBits = polylineChars[index++] - 63; sum |= (nextFiveBits & 31) << shifter; shifter += 5; } while (nextFiveBits >= 32 && index < polylineChars.Length); if (index >= polylineChars.Length && nextFiveBits >= 32) break; currentLng += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1); yield return new Location { lat = Convert.ToDouble(currentLat) / 1E5, lng = Convert.ToDouble(currentLng) / 1E5 }; } } /// <summary> /// Encodes the specified locations list. /// </summary> /// <param name="locations">The locations.</param> /// <returns>The polyline string.</returns> public static string Encode(IEnumerable<Location> locations) { var str = new StringBuilder(); var encodeDiff = (Action<int>)(diff => { var shifted = diff << 1; if (diff < 0) shifted = ~shifted; var rem = shifted; while (rem >= 0x20) { str.Append((char)((0x20 | (rem & 0x1f)) + 63)); rem >>= 5; } str.Append((char)(rem + 63)); }); var lastLat = 0; var lastLng = 0; foreach (var point in locations) { var lat = (int)Math.Round(point.lat * 1E5); var lng = (int)Math.Round(point.lng * 1E5); encodeDiff(lat - lastLat); encodeDiff(lng - lastLng); lastLat = lat; lastLng = lng; } return str.ToString(); } }

Espero que ayude.