将 Google 地图折线转换为 SVG

问题描述 投票:0回答:2

我正在使用上一个问题中的 JavaScript(将 Google 地图多边形路径转换为 SVG 路径)来显示坐标列表中的 SVG。请参阅 JsFiddle:http://jsfiddle.net/londonfed/9xhsL39u/51/

但是,这无法正确渲染(它显示红色斑点)。它应该显示一条直线,如屏幕截图所示:

上面的图片取自https://developers.google.com/maps/documentation/utilities/polylineutility?csw=1

您可以将多段线复制粘贴到编码的多段线输入字段中,以查看 SVG 应如何呈现:

ofkyHluWg@?EyDQi@}ByFJMcAgCeAyCeAiDu@iC`@_@??a@^IY{@{Cu@aDSg@KQSq@m@kCYgAIc@QJKYc@{@W{@Ga@C_@SkBQcA??GaAMuASwAS_BGo@GWQ]c@i@GMKWGCCAUuA[sBSaBKm@E]OaB

非常感谢任何想法。

javascript google-maps svg
2个回答
5
投票

有几件事是错误的。主要:

  • 您的坐标很小,因此默认的笔画宽度“1”太大了。 0.0001 更接近您想要的比例。
  • 您想要一条开放路径,而不是封闭路径,因此不要包含“z”。

function latLng2point(latLng) {

    return {
        x: (latLng.lng + 180) * (256 / 360),
        y: (256 / 2) - (256 * Math.log(Math.tan((Math.PI / 4) + ((latLng.lat * Math.PI / 180) / 2))) / (2 * Math.PI))
    };
}

function poly_gm2svg(gmPaths, fx) {

    var point,
    gmPath,
    svgPath,
    svgPaths = [],
        minX = 256,
        minY = 256,
        maxX = 0,
        maxY = 0;

    for (var pp = 0; pp < gmPaths.length; ++pp) {
        gmPath = gmPaths[pp], svgPath = [];
        for (var p = 0; p < gmPath.length; ++p) {
            point = latLng2point(fx(gmPath[p]));
            minX = Math.min(minX, point.x);
            minY = Math.min(minY, point.y);
            maxX = Math.max(maxX, point.x);
            maxY = Math.max(maxY, point.y);
            svgPath.push([point.x, point.y].join(','));
        }


        svgPaths.push(svgPath.join(' '))


    }
    return {
        path: 'M' + svgPaths.join(' M'),
        x: minX,
        y: minY,
        width: maxX - minX,
        height: maxY - minY
    };

}

function drawPoly(node, props) {

    var svg = node.cloneNode(false),
        g = document.createElementNS("http://www.w3.org/2000/svg", 'g'),
        path = document.createElementNS("http://www.w3.org/2000/svg", 'path');
    node.parentNode.replaceChild(svg, node);
    path.setAttribute('d', props.path);
    g.appendChild(path);
    svg.appendChild(g);
    svg.setAttribute('viewBox', [props.x, props.y, props.width, props.height].join(' '));


}


function init() {

    for (var i = 0; i < paths.length; ++i) {
        paths[i] = google.maps.geometry.encoding.decodePath(paths[i]);
    }

    svgProps = poly_gm2svg(paths, function (latLng) {
        return {
            lat: latLng.lat(),
            lng: latLng.lng()
        }
    });
    drawPoly(document.getElementById('svg'), svgProps)
}

//array with encoded paths, will be decoded later
var paths = ["ofkyHluWg@?EyDQi@}ByFJMcAgCeAyCeAiDu@iC`@_@??a@^IY{@{Cu@aDSg@KQSq@m@kCYgAIc@QJKYc@{@W{@Ga@C_@SkBQcA??GaAMuASwAS_BGo@GWQ]c@i@GMKWGCCAUuA[sBSaBKm@E]OaB"];

init();
#svg {
    background:silver;
}
path {
    stroke: red;
    stroke-width: 0.0001;
    fill: none;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3&libraries=geometry"></script>
<svg id="svg" height="400" width="400" viewport="0 0 400 400" preserveAspectRatio="xMinYMin meet"></svg>


0
投票

上面发布的答案效果很好,但我在使用不同的、更复杂的输入进行测试时发现了一个小问题。描边宽度随当前边界框缩放。

我们可以通过将 vector-effect css-property 应用于

path
的样式并使用常见的呈现值来防止这种情况。

path {
  /* ...the other stuff */
  vector-effect: non-scaling-stroke;   
  stroke-width: 5px; /* common presentation values */
}

这是一个小提琴示例

© www.soinside.com 2019 - 2024. All rights reserved.