开发者

Google Static Maps URL length limit

开发者 https://www.devze.com 2023-01-27 10:48 出处:网络
I have 153 markers and need to generate a static map with them, but when put them in the url I get an error like this:

I have 153 markers and need to generate a static map with them, but when put them in the url I get an error like this:

414 Request-Uri Too Large

My url is something like this

"http://maps.google.com/开发者_C百科maps/api/staticmap?center=13.00,-85.00&size=600x500&maptype=roadmap&markers=13.305,-86.18636&markers=13.72326,-86.13705&......"

Thanks folks!


The way i see it is either you reduce precision of your markers in order to gain space in the URL. (i.e. markers=13.72326,-86.13705---->markers=13.73,-86.14) resulting in placing the markers in a grid...
Or you go with a non static api


This response came from the Server (google). So you're not allowed to request such long URLs.

See the google api doc for more infos:

Static Map URLs are restricted to 2048 characters in size. In practice, you will probably not have need for URLs longer than this, unless you produce complicated maps with a high number of markers and paths.


I had same problem,

i used link like this, and reduced position precision:

http://maps.googleapis.com/maps/api/staticmap?center=61.52401,105.318756&zoom=2&size=710x400&markers=|59,30|48,44|55,37|55,37|55,37|56,44|56,60|55,49|47,39|57,39|55,37|55,82|47,39|55,37|53,50|51,36|55,37|54,73|45,38|48,44|50,43|46,44|51,42|56,53|59,32|59,30|60,30|59,30|59,28|59,32|59,29|58,31|68,33|56,92|59,38|57,56|55,37|55,36|55,38|55,37|55,38|56,38|55,38|51,46|55,38|45,41|53,49|55,61|50,36|50,36|55,48|55,48|55,49|56,50|56,47|53,91|47,39|57,61|44,37|56,86|55,43|44,41|43,13|43,13|42,13|42,13|57,61|64,40|46,48|55,45|52,47|56,43|54,19|53,83|48,40|54,54|53,58|54,83|59,56|52,85|48,13|55,55|50,12|51,40|56,43|49,40|59,33|37,34|58,33|53,34|54,42|56,30|58,54|54,33|56,60|58,60|57,46|43,44|56,40|49,36|49,32|47,42|59,39|56,35|51,39|55,38|57,45|55,42|56,43|56,43|57,13|56,43|56,44|55,42|55,44|55,42|55,43|54,43|54,44|54,43|56,44|55,45|55,43|57,45|56,43|55,44|57,46|56,45|57,53|60,28&sensor=false


Officially you can use 8192 characters

This depends on browser and server, but as a thumb rule 8192 characters should be OK.

Server

Google Maps Static server https://maps.googleapis.com/maps/api/staticmap at 30 July 2019.

Google Static Maps Docs claims that:

Maps Static API URLs are restricted to 8192 characters in size. In practice, you will probably not have need for URLs longer than this, unless you produce complicated maps with a high number of markers and paths. Note, however, that certain characters may be URL-encoded by browsers and/or services before sending them off to the API, resulting in increased character usage.

But in practice, I'm getting errors (413 Payload Too Large) after 15k~ characters mark (30 July 2019):

╔═════════╦═════════════════╦══════════════════╗
║ Browser ║ Browser Version ║ Valid URL Length ║
╠═════════╬═════════════════╬══════════════════╣
║ Chrome  ║ 75              ║            15489 ║
║ Firefox ║ 68              ║            15761 ║
║ Safari  ║ 12.1            ║            15690 ║
╚═════════╩═════════════════╩══════════════════╝

This is based on data got by using fetch() in browser console. I'd assume that Google Static Maps server accepts requests (whole request, not just path) no larger than 16k in size.

Solutions

Reduce Precision

Our company policy is that coordinate data below 6 decimal places (111.32 mm) is useless (considering our market share uses phones and commercial GPS devices).

const decimalPlaces = 6 // decimal places count
const decimalPowered = 10 ** decimalPlaces // 1_000_000
const trim = number => Math.round(number * decimalPowered) / decimalPowered // function that trims number
const coordinates = [
  [51.838245, -111.834991],
  [51.8331, -111.835],
  [51.831007022306, -111.8232751234],
  [51.838244686875, -111.82327418214]
]
const trimmedCoordinates = coordinates.map(coordinate => coordinate.map(trim))
console.log(trimmedCoordinates)

Encode coordinates

If you have access to encoder you can replace path with an encoded path (use String manipulation instead of URLSearchParams, because searchParams automatically uses encodeURI, which would break your encoded path):

const coordinates = [
  [51.838245, -111.834991],
  [51.8331, -111.835],
  [51.831007022306, -111.8232751234],
  [51.838244686875, -111.82327418214]
].map(([lng, lat]) => ({ lng, lat }))

// path should be MVCArray<LatLng>|Array<LatLng>, if you have Polygon or Polyline, getPath() method should be fine
const path = coordinates.map(coordinate => new google.maps.LatLng(coordinate)) 

const encoded = google.maps.geometry.encoding.encodePath(
  path
);

return (
  url.href +
  `&path=fillcolor:${color}|color:${color}|enc:${encoded}`
);

https://developers.google.com/maps/documentation/maps-static/dev-guide https://developers.google.com/maps/documentation/utilities/polylinealgorithm https://developers.google.com/maps/documentation/javascript/geometry#Encoding

Handle Errors

  • Use placeholder image
  • Check if href.length > 8192 before request
  • Trim coordinates
  • Encode path
  • Check if !res.ok && res.status === 413 and display error for user which claims that map is too detailed
  • Use fallback image


You can encode your Polylines and make them shorter .

Here is the example which can help you how to short your Polylines

I am using the php library to short the length here is the link of library https://github.com/danmandle/encoded-polyline-stitcher

if you use this library

(51.838245,-111.834991|51.833179,-111.83503|51.831007022306,-111.8232751234|51.838244686875,-111.82327418214)  =  (atk{HtwqiTt^FpLmhAgl@)

Here important point is if you use short url you have to use "enc:" keyword

(fillcolor:0xAA000033|color:0xFFFFFF00|51.838245,-111.834991|51.833179,-111.83503|51.831007022306,-111.8232751234|51.838244686875,-111.82327418214)  =   (fillcolor:0xAA000033|color:0xFFFFFF00|enc:atk{HtwqiTt^FpLmhAgl@)

The Library is available for other languages as well if you are not using php .

I hope that it helps others


Google recently extended the URL limit to 8192, but if you need more than that, you still need to simplify your map or resort to other tricks.


URLs over 2000-ish characters aren't valid. Is your querystring longer than that?

Also see this post


You might also use marker clustering on a static map:

http://www.appelsiini.net/projects/php_google_maps/cluster.html

http://www.appelsiini.net/2008/11/introduction-to-marker-clustering-with-google-maps


Very old thread but I had to cobble together something to tackle this very problem in a hurry. Sharing here in case anyone else had the same problem.

It takes an array of markers in the form:

$points =
        [0] => Array
            (
                [lat] => 52.1916312
                [lng] => -1.7083109
            )

        [1] => Array
            (
                [lat] => 50.2681918
                [lng] => 2.5616710
            )
            ...
            ...
            ...
        [500] => Array
            (
                [lat] => 49.1821968
                [lng] => 2.1671056
            )

Max url length is 2048 chars so it first reduces accuracy of the lat lng to $marker_accuracy (4) then starts removing markers from the middle. Removing markers from the middle could be improved a lot as it does it one at a time

$map_url = make_static_map($points);

function make_static_map($points,$reduce_len=false,$reduce_count=false){
    $grp_points = array();
    $grps = array();
    $url = array();
    $max_len = 0;
    $width = 640;   //max 640 :(
    $height = 640;  //max 640 :(
    $marker_accuracy = 4;   //Lat lng to 4 decimal places minimum, 3 would be less accurate

    $url[] = 'http://maps.googleapis.com/maps/api/staticmap?';
    $url[] = '&size='.$width.'x'.$height.'&scale=2';
    $url[] = '&markers=';

    if($reduce_count){  //Last resort to shortening this
        array_splice($points, ceil(count($points)/2), 1);
    }

    foreach($points as $i => $point){
        if($reduce_len){
            $point['lat'] = number_format($point['lat'], $reduce_len, '.', '');
            $points[$i]['lat'] = $point['lat'];
            $point['lng'] = number_format($point['lng'], $reduce_len, '.', '');
            $points[$i]['lng'] = $point['lng'];
        }else{
            $t_len = max(strlen($point['lat']),strlen($point['lng']));
            if($t_len>$max_len){
                $max_len = $t_len;
            }
        }
        $grps[] = array($point['lat'],$point['lng']);
    }
    $grps = remove_duplicate_points($grps);
    foreach($grps as $grp){
        $grp_points[] = implode(',',$grp);
    }
    $url[] = implode('|',$grp_points);
    $url[] = '&sensor=false';
    $url = implode('',$url);
    if(strlen($url) > 2048){
        // Bugger, too long for google
        if($max_len>$marker_accuracy){
            // Reduce the length of lat lng decimal places
            return(make_static_map($points,$max_len-1,false));
        }else{
            // Reduce the number of lat lng markers (from center)
            return(make_static_map($points,false,true));
        }
    }else{
        return($url);
    }
}


function remove_duplicate_points($points){
    $points = array_map('serialize', $points);
    $points = array_unique($points);
    return(array_map('unserialize', $points));
}


Use osm-static-maps, it's a clone of google static maps but you can send any amount of data to it. https://github.com/jperelli/osm-static-maps

Disclaimer: I'm the author.

0

精彩评论

暂无评论...
验证码 换一张
取 消