19

我有 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&......"

谢谢各位!

4

10 回答 10

20

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

于 2010-11-25T15:13:35.300 回答
13

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

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

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

于 2010-11-25T14:41:57.417 回答
5

官方可以使用 8192 个字符

这取决于浏览器和服务器,但一般来说 8192 个字符应该没问题。

服务器

谷歌地图静态服务器https://maps.googleapis.com/maps/api/staticmap2019 年 7 月 30 日

谷歌静态地图文档声称:

地图静态 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 位(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)

编码坐标

如果您有权访问编码器,则可以将 path 替换为编码路径(使用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/文档/javascript/几何#Encoding

处理错误

  • 使用占位符图片
  • 检查是否href.length > 8192在请求之前
  • 修剪坐标
  • 编码路径
  • 检查!res.ok && res.status === 413声称地图太详细的用户是否显示错误
  • 使用后备图片
于 2019-07-30T10:14:13.090 回答
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)  =  (atk{HtwqiTt^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:atk{HtwqiTt^FpLmhAgl@)

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

我希望它可以帮助别人

于 2013-08-16T15:14:53.780 回答
3

谷歌最近将 URL 限制扩展到8192,但如果您需要更多,您仍然需要简化您的地图或诉诸其他技巧

于 2016-09-09T09:58:45.680 回答
2

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

也可以看看这个帖子

于 2010-11-25T14:42:09.980 回答
1

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

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

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

于 2011-11-30T18:23:17.017 回答
1

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

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

$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));
}
于 2015-02-04T18:07:14.890 回答
0

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

免责声明:我是作者。

于 2020-03-28T15:51:02.083 回答