【问题标题】:SVG paths to KML polygonsKML 多边形的 SVG 路径
【发布时间】:2019-12-09 15:05:55
【问题描述】:

我想用 Java 创建一个 svg 到 kml 的转换器。我为此任务创建了一种翻译器,它接收 svg 格式的文本并打印出 kml 格式的文本。到目前为止,我能够处理 circlerect 标签。我无法处理路径

如何读取 svg 路径(d 属性)并在 kml 中重建它们?

主要问题源于 svg 路径不是简单的坐标序列,并且其中包含曲线。这是我需要处理的 svg 路径输入示例:

<html>
<body>

<svg width="10000" height="1000">
<path id="square" fill="#0000FF" 
d="M351.3,251 l-3.1-2.2c-0.3-0.2-0.3-0.5-0.1-0.8l2.2-3.1c0.2-0.3,0.5-0.3,0.8-0.1l3.1,2.2
c0.3,0.2,0.3,0.5,0.1,0.8l-2.2,3.1C355,251.1,354.6,251.2,354.3,251z"/>

</body>
</html>

如果我能弄清楚如何计算 d 属性中的字符串,那么唯一的另一个问题是如何使用从 d 属性中的字符串中提取的值来创建曲线。

这种路径格式在网上并不常见;它是由其他人使用 adobe illustrator 创建的,现在我无法访问该软件。由于没有空格或常规逗号,我无法理解如何正确读取字符串。

【问题讨论】:

  • 我不能使用现有的转换器,因为我正在处理我的项目独有的东西。
  • 有人可以再次激活这个问题吗?我已经完全改变了它,包括输入的细节和一个特定的问题。我只需要帮助评估路径的 d 属性中的值。
  • KML 不支持曲线,它只有直线几何。但这可以通过在曲线上有很多点来解决,这样它看起来像一条曲线,而实际上它是许多直线段。我已经为圆圈做了这个,我使用 64 个点均匀分布在圆周上,以实现一个看起来相当不错的圆圈。不过,我不太确定如何对贝塞尔曲线执行此操作。
  • 这就是我为圆所做的(我传递了一个点,它是一个具有 x 和 y 双值的对象;它是我创建的一个类;在这种情况下,它是圈子):for(int i = 0; i &lt; 64;i++) { output.println((center.x + r*Math.cos(Math.toRadians(5.625*i))) + "," + (center.y + r*Math.sin(Math.toRadians(5.625*i)))); }
  • 这是一个 C++ 解析器dxr.mozilla.org/mozilla-central/source/dom/svg/…。 Mozilla 在某处也有一个生锈的,如果你在 java 中的 Batik 中找到它,就会有一个。

标签: java svg kml converters


【解决方案1】:

我找到了一种在 JavaScript 中将 SVG 路径转换为 ​​SVG 多边形的简单方法。 SVG 多边形可以轻松转换为 KML 地标,因为两者都使用坐标列表。该脚本可以放置在 HTML 文件中,并且可以直接在浏览器上运行。它将从您的计算机中获取一个 SVG 文件并将修改后的文件保存为文本文件。我建议使用 Chrome,因为 SVG 在其上保持固定大小,从而确保坐标系保持完全相同。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Reader</title>
</head>
<body>
<h1>SVG paths to polygons</h1>
<input type="file" id="fileReader" />
<br>
<p id="Content"></p>
<script>
document.getElementById("fileReader").addEventListener('change',function(){
var fr = new FileReader();
fr.onload = function(){;
var d = new DOMParser().parseFromString( this.result.toString(), "image/svg+xml" );
var nodelist = d.querySelectorAll('path');
console.log("Number of paths: " + nodelist.length);
nodelist.forEach(function(path){//This replaces each path with a polygon, keeping the same id.
var polygon = d.createElementNS("http://www.w3.org/2000/svg", "polygon");
polygon.setAttribute("id", path.getAttribute("id"));
console.log("Converting " + path.getAttribute("id"));
var length = path.getTotalLength();
var p=path.getPointAtLength(0);
var stp=p.x+","+p.y;
for(var i=1; i<length; i++){
    p=path.getPointAtLength(i);
    stp=stp+" "+p.x+","+p.y;
    //This places points along the path at one unit distance apart.
}
polygon.setAttribute("points", stp);
path.replaceWith(polygon);
});
var text1 = new XMLSerializer().serializeToString(d);
document.write(text1);
function download(filename, text) {
  var element = document.createElement('a');
  element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
  element.setAttribute('download', filename);

  element.style.display = 'none';
  document.body.appendChild(element);

  element.click();

  document.body.removeChild(element);
}

// Starting file download.
download("output.txt", text1);
}
fr.readAsText(this.files[0]);
})
</script>
</body>
</html>

然后您可以直接将points 属性放在KML 中的坐标标签中。您只需用新行替换空格即可。

【讨论】:

    猜你喜欢
    • 2012-11-07
    • 2022-01-20
    • 1970-01-01
    • 2015-01-10
    • 1970-01-01
    • 2015-03-06
    • 1970-01-01
    • 2016-10-23
    • 2018-12-16
    相关资源
    最近更新 更多