Non c'è modo di "ingannare" il limite di caratteri, ma è possibile semplificare la polilinea per portare la stringa polilinea codificata al di sotto del limite di caratteri. Questo può o non può risultare in un poligono di fedeltà adeguata alle tue esigenze.
Un ulteriore avvertimento è che (per quanto ne so io, l'API di mappe statiche consente di disegnare sulla mappa una sola polilinea codificata (questo può sembrare un poligono, se lo si chiude o lo si riempie) , ma è ancora una polilinea, non un poligono).
Un'opzione per semplificare la polilinea è l'algoritmo Douglas Peucker. Di seguito è riportata un'implementazione che estende l'oggetto google.maps.Polyline
con un metodo simplify
.
Questo si basa sull'avere caricato l'API JS di Google Maps, che potrebbe non essere utile se si utilizzano le mappe statiche, ma il codice riportato di seguito potrebbe facilmente essere riscritto.
google.maps.Polyline.prototype.simplify = function(tolerance) {
var points = this.getPath().getArray(); // An array of google.maps.LatLng objects
var keep = []; // The simplified array of points
// Check there is something to simplify.
if (points.length <= 2) {
return points;
}
function distanceToSegment(p, v, w) {
function distanceSquared(v, w) {
return Math.pow((v.x - w.x),2) + Math.pow((v.y - w.y),2)
}
function distanceToSegmentSquared(p, v, w) {
var l2 = distanceSquared(v, w);
if (l2 === 0) return distanceSquared(p, v);
var t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y))/l2;
if (t < 0) return distanceSquared(p, v);
if (t > 1) return distanceSquared(p, w);
return distanceSquared(p, { x: v.x + t * (w.x - v.x), y: v.y + t * (w.y - v.y) });
}
// Lat/Lng to x/y
function ll2xy(p){
return {x:p.lat(),y:p.lng()};
}
return Math.sqrt(distanceToSegmentSquared(ll2xy(p), ll2xy(v), ll2xy(w)));
}
function dp(points, tolerance) {
// If the segment is too small, just keep the first point.
// We push the final point on at the very end.
if (points.length <= 2) {
return [points[0]];
}
var keep = [], // An array of points to keep
v = points[0], // Starting point that defines a segment
w = points[points.length-1], // Ending point that defines a segment
maxDistance = 0, // Distance of farthest point
maxIndex = 0; // Index of said point
// Loop over every intermediate point to find point greatest distance from segment
for (var i = 1, ii = points.length - 2; i <= ii; i++) {
var distance = distanceToSegment(points[i], points[0], points[points.length-1]);
if(distance > maxDistance) {
maxDistance = distance;
maxIndex = i;
}
}
// check if the max distance is greater than our tollerance allows
if (maxDistance >= tolerance) {
// Recursivly call dp() on first half of points
keep = keep.concat(dp(points.slice(0, maxIndex + 1), tolerance));
// Then on second half
keep = keep.concat(dp(points.slice(maxIndex, points.length), tolerance));
} else {
// Discarding intermediate point, keep the first
keep = [points[0]];
}
return keep;
};
// Push the final point on
keep = dp(points, tolerance);
keep.push(points[points.length-1]);
return keep;
};
Ciò è stato messo insieme con l'aiuto di un paio di esempi (here e here).
Ora è possibile prendere la polilinea originale e alimentarla attraverso questa funzione con tolleranza crescente fino a quando la polilinea codificata risultante scende al di sotto del limite di lunghezza dell'URL (che dipenderà dagli altri parametri che si passano a Mappe statiche).
Qualcosa del genere dovrebbe funzionare:
var line = new google.maps.Polyline({path: path});
var encoded = google.maps.geometry.encoding.encodePath(line.getPath());
var tol = 0.0001;
while (encoded.length > 1800) {
path = line.simplify(tol);
line = new google.maps.Polyline({path: path});
encoded = google.maps.geometry.encoding.encodePath(path);
tol += .005;
}
Fare riferimento all'url seguente, questo aiuterà molto https://developers.google.com/maps/documentation/staticmaps/?hl=fr#EncodedPolylines – user3364541