5

由于 get 请求中限制为 2048 个字符,因此您无法使用 Google 静态地图生成包含具有大量多边形点的多边形的图像。

特别是如果您尝试在一张地图上绘制许多复杂的多边形。如果您使用 Google Maps API,您不会有任何问题 - 它工作得非常好!但我想要一张图片(jpg或png)......

那么,是否有机会从 Google Maps API 创建图像?或者有什么方法可以“欺骗” 204​​8 字符限制?

谢谢!

4

3 回答 3

6

没有办法“欺骗”字符限制,但可以简化您的折线,使编码的折线字符串低于字符限制。这可能会或可能不会产生适合您需求的保真度多边形。

另外一个警告是(据我所知)静态地图 API 只允许在地图上绘制一条编码折线(这可能看起来像一个多边形,如果你自己关闭它或填充它,但它仍然折线,而不是多边形)。

简化折线的一种选择是Douglas Peucker算法。下面是一个使用方法扩展google.maps.Polyline对象的实现simplify

这依赖于加载 Google Maps JS API,如果您使用的是静态地图,您可能不需要,但下面的代码可以很容易地重写。

google.maps.Polyline.prototype.simplify = function(tolerance) {

    var points = this.getPath().getArray(); // An array of google.maps.LatLng objects
    var keep = []; // The simplified array of points

    // Check there is something to simplify.
    if (points.length <= 2) {
        return points;
    }

    function distanceToSegment(p, v, w) {

        function distanceSquared(v, w) {
            return Math.pow((v.x - w.x),2) + Math.pow((v.y - w.y),2) 
        }
        function distanceToSegmentSquared(p, v, w) {

            var l2 = distanceSquared(v, w);
            if (l2 === 0) return distanceSquared(p, v);

            var t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2;
            if (t < 0) return distanceSquared(p, v);
            if (t > 1) return distanceSquared(p, w);
            return distanceSquared(p, { x: v.x + t * (w.x - v.x), y: v.y + t * (w.y - v.y) });
        }

        // Lat/Lng to x/y
        function ll2xy(p){
            return {x:p.lat(),y:p.lng()};
        }

        return Math.sqrt(distanceToSegmentSquared(ll2xy(p), ll2xy(v), ll2xy(w))); 
    }

    function dp( points, tolerance ) {

        // If the segment is too small, just keep the first point. 
        // We push the final point on at the very end.
        if ( points.length <= 2 ) {
            return [points[0]];
        }

        var keep = [],  // An array of points to keep
            v = points[0], // Starting point that defines a segment
            w = points[points.length-1], // Ending point that defines a segment
            maxDistance = 0, // Distance of farthest point
            maxIndex = 0; // Index of said point

        // Loop over every intermediate point to find point greatest distance from segment
        for ( var i = 1, ii = points.length - 2; i <= ii; i++ ) {
            var distance = distanceToSegment(points[i], points[0], points[points.length-1]);
            if( distance > maxDistance ) {
                maxDistance = distance;
                maxIndex = i;
            }
        }

        // check if the max distance is greater than our tollerance allows 
        if ( maxDistance >= tolerance ) {

            // Recursivly call dp() on first half of points
            keep = keep.concat( dp( points.slice( 0, maxIndex + 1 ), tolerance ) );

            // Then on second half
            keep = keep.concat( dp( points.slice( maxIndex, points.length ), tolerance ) );

        } else {
            // Discarding intermediate point, keep the first
            keep = [points[0]];
        }
        return keep;
    };

    // Push the final point on
    keep = dp(points, tolerance);
    keep.push(points[points.length-1]);
    return keep;

};

这是在几个例子的帮助下拼凑起来的(这里这里)。

现在,您可以获取原始折线并通过此函数以增加容差的方式将其输入,直到生成的编码折线低于 URL 长度限制(这将取决于您传递给静态地图的其他参数)。

像这样的东西应该工作:

var line = new google.maps.Polyline({path: path});
var encoded = google.maps.geometry.encoding.encodePath(line.getPath());
var tol = 0.0001;
while (encoded.length > 1800) {
    path = line.simplify(tol);
    line = new google.maps.Polyline({path: path});
    encoded = google.maps.geometry.encoding.encodePath(path);
    tol += .005;
}
于 2013-08-07T08:52:56.450 回答
0

另一种方法是使用可以将画布内容转换为图像的 javascript 库。就像是

虽然我不确定它对带有叠加层的 googlemaps 的性能。

编辑:如果您使用的是 html2canvas,请务必查看此问题: https ://stackoverflow.com/a/17816195/2279924

于 2013-12-11T21:03:57.267 回答
0

自 2016 年 9 月起,URL 限制已更改为 8192 个字符。

https://developers.google.com/maps/documentation/static-maps/intro#url-size-restriction

公共问题跟踪器中还有一个功能请求被标记为已修复。

于 2016-09-13T13:16:05.900 回答