Google 静态地图 URL 长度限制

Posted

技术标签:

【中文标题】Google 静态地图 URL 长度限制【英文标题】:Google Static Maps URL length limit 【发布时间】:2011-05-15 18:01:18 【问题描述】:

我有 153 个标记,需要用它们生成一个静态地图,但是当把它们放在 url 中时,我收到如下错误:

414 Request-Uri Too Large

我的网址是这样的

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

谢谢各位!

【问题讨论】:

【参考方案1】:

我看到的方式是您降低标记的精度,以便在 URL 中获得空间。 (即标记=13.72326,-86.13705---->标记=13.73,-86.14)导致将标记放置在网格中... 或者你使用非静态 api

【讨论】:

这就是我最终做的事情 - 在 php 中使用精确到小数点后 6 位的舍入确实缩短了我的时间。【参考方案2】:

此响应来自服务器 (google)。所以你不能请求这么长的 URL。

有关更多信息,请参阅 google api 文档:

静态地图 URL 的大小限制为 2048 个字符。实际上,您可能不需要比这更长的 URL,除非您生成具有大量标记和路径的复杂地图。

【讨论】:

如果您需要生成具有大量位置的图像怎么办? (即如果我想生成一个代表美国几个县的多边形) 我厌倦了人们愚蠢的、毫无意义的回答。为什么这个答案得到了赞成?很明显,有些地图的点数超过了 URL 所能容纳的点数。这不是答案。 @Hill 回答和投票可以伪造。你知道你能看到的大部分东西都是假的,而不是真的:D【参考方案3】:

我有同样的问题,

我使用了这样的链接, 并降低定位精度:

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

【讨论】:

你是怎么做到的?我不知道如何操作多边形生成的链接。【参考方案4】:

您可以对折线进行编码并使它们更短。

以下示例可帮助您缩短折线

我正在使用 php 库来缩短长度 这是图书馆的链接https://github.com/danmandle/encoded-polyline-stitcher

如果你使用这个库

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

这里重要的一点是,如果你使用短网址,你必须使用 "enc:" 关键字

(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:atkHtwqiTt^FpLmhAgl@)

如果您不使用 php,该库也可用于其他语言。

希望对别人有帮助

【讨论】:

【参考方案5】:

官方可以使用8192个字符

这取决于browser 和服务器,但根据经验,8192 个字符应该没问题。

服务器

Google 地图静态服务器 https://maps.googleapis.com/maps/api/staticmap 于 2019 年 7 月 30 日

Google Static Maps Docs 声称:

地图静态 API 网址的大小限制为 8192 个字符。实际上,您可能不需要比这更长的 URL,除非您生成具有大量标记和路径的复杂地图。但是请注意,某些字符可能会在将它们发送到 API 之前由浏览器和/或服务进行 URL 编码,从而导致字符使用量增加。

在实践中,在 15k~ 个字符标记(2019 年 7 月 30 日)后出现错误(413 Payload Too Large):

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

这是基于在浏览器控制台中使用fetch() 获得的数据。我假设 Google Static Maps 服务器接受大小不超过 16k 的请求(整个请求,而不仅仅是路径)。

解决方案

降低精度

我们公司的政策是,6 decimal places(111.32 毫米)以下的坐标数据是无用的(考虑到我们使用手机和商用 GPS 设备的市场份额)。

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)

编码坐标

如果您有权访问编码器,则可以将路径替换为编码路径(使用String 操作而不是URLSearchParams,因为searchParams 自动使用encodeURI,这会破坏您的编码路径):

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

处理错误

使用占位符图片 在请求之前检查href.length &gt; 8192 修剪坐标 编码路径 检查!res.ok &amp;&amp; res.status === 413 并为声称地图太详细的用户显示错误 使用后备图片

【讨论】:

【参考方案6】:

Google 最近将 URL 限制扩展到 8192,但如果您需要更多,您仍然需要简化地图或求助于其他 tricks。

【讨论】:

【参考方案7】:

超过 2000 个字符的 URL 无效。你的查询字符串比那个长吗?

另见post

【讨论】:

【参考方案8】:

您也可以在静态地图上使用标记聚类:

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

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

【讨论】:

【参考方案9】:

非常旧的线程,但我不得不拼凑一些东西来快速解决这个问题。在这里分享,以防其他人有同样的问题。

它采用以下形式的标记数组:

$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
            )

最大 url 长度为 2048 个字符,因此它首先将 lat lng 的准确性降低到 $marker_accuracy (4) 然后开始从中间删除标记。 从中间删除标记可以改善很多 一次一个

$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));

【讨论】:

【参考方案10】:

使用 osm-static-maps,它是 google 静态地图的克隆,但您可以向其发送任意数量的数据。 https://github.com/jperelli/osm-static-maps

免责声明:我是作者。

【讨论】:

以上是关于Google 静态地图 URL 长度限制的主要内容,如果未能解决你的问题,请参考以下文章

Google静态地图api与密钥和无密钥之间的区别?

Google 地图切片URL地址解析

浏览器后退按钮跳转到最后一个位置(如 maps.google.com)

在 Google 地图上重新排序控件

将 Google json 地图标记限制为可查看的地图

使用 Google 静态地图检索经度/纬度的问题