[Django]-Google Static Maps URL length limit

12πŸ‘

βœ…

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.

πŸ‘€scheffield

20πŸ‘

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

6πŸ‘

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
πŸ‘€Crow

5πŸ‘

πŸ‘€Edmhs

4πŸ‘

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

πŸ‘€Mehran Khan

3πŸ‘

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.

πŸ‘€Ville N.

2πŸ‘

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

Also see this post

πŸ‘€Steve Jalim

1πŸ‘

πŸ‘€Tomas

1πŸ‘

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));
}
πŸ‘€Andy Gee

1πŸ‘

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.

πŸ‘€jperelli

Leave a comment