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 > 8192
修剪坐标
编码路径
检查!res.ok && 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 长度限制的主要内容,如果未能解决你的问题,请参考以下文章