【问题标题】:Google Static Maps URL length limitGoogle 静态地图 URL 长度限制
【发布时间】: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&......"

谢谢各位!

【问题讨论】:

    标签: javascript django google-maps google-maps-api-3 google-static-maps


    【解决方案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】:

    【讨论】:

    • 你是怎么做到的?我不知道如何操作多边形生成的链接。
    【解决方案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,该库也可用于其他语言。

    希望对别人有帮助

    【讨论】:

      【解决方案5】:

      官方可以使用8192个字符

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

      服务器

      Google 地图静态服务器 https://maps.googleapis.com/maps/api/staticmap2019 年 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】:
            【解决方案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

              免责声明:我是作者。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-07-06
                • 1970-01-01
                • 1970-01-01
                • 2013-02-21
                • 2015-11-22
                • 1970-01-01
                • 1970-01-01
                • 2011-12-15
                相关资源
                最近更新 更多