29

我有一个相当大的 SVG 行政分区文件,我需要在 Raphael.JS 中使用它(它有 600 个多边形和 1.2 Mb 的权重)。

现在,我需要将这些多边形转换为路径,以便它在 Raphael 中工作。伟大的poly2path 工具可以做到这一点,但它不支持任何批处理命令,因此每个多边形相对于其他多边形的位置都会丢失。

您知道将 SVG 多边形转换为路径的任何工具吗?(我也有用于导出 SVG 的 AI 文件)。

非常感谢

4

4 回答 4

88
  1. 在网络浏览器中打开您的 SVG。
  2. 运行此代码:

    var polys = document.querySelectorAll('polygon,polyline');
    [].forEach.call(polys,convertPolyToPath);
    
    function convertPolyToPath(poly){
      var svgNS = poly.ownerSVGElement.namespaceURI;
      var path = document.createElementNS(svgNS,'path');
      var pathdata = 'M '+poly.getAttribute('points');
      if (poly.tagName=='polygon') pathdata+='z';
      path.setAttribute('d',pathdata);
      poly.parentNode.replaceChild(path,poly);
    }
    
  3. 使用浏览器的开发者工具(或 Firebug),在元素上使用“复制为 HTML”(或复制 SVG)将修改后的源代码放到剪贴板上。

  4. 粘贴到新文件中并享受。

我的网站上有上述方法的演示(稍作修改):http:
//phrogz.net/svg/convert_polys_to_paths.svg

该页面上使用了两种方法;一个(如上)使用基于字符串的技术来获取和设置点;另一个使用 SVG DOM 访问点和设置路径命令。


正如@Interactive 在评论中指出的那样,您可以通过纯文本转换来做到这一点:

  1. 全部转换<polyline<polygon<path
  2. 全部更改points="d="M
  3. 对于之前的任何元素<polygon>,您需要添加z作为d属性的最后一个字符以将最后一个点连接到第一个点。例如:

    <polygon points="1,2 3,-4 5,6"/> 
    

    变成

    <path d="M1,2 3,-4 5,6z"/> 
    

这种'hack'之所以有效,是因为规范声明后跟多个坐标的moveto命令(M或)是合法的,第一个坐标之后的所有坐标都被解释为命令。mlineto

于 2012-05-24T02:09:36.680 回答
4

多边形 id、填充和描边属性保存的小修复

var polys = document.querySelectorAll('polygon,polyline');
[].forEach.call(polys,convertPolyToPath);

function convertPolyToPath(poly){
  var svgNS = poly.ownerSVGElement.namespaceURI;
  var path = document.createElementNS(svgNS,'path');
  var points = poly.getAttribute('points').split(/\s+|,/);
  var x0=points.shift(), y0=points.shift();
  var pathdata = 'M'+x0+','+y0+'L'+points.join(' ');
  if (poly.tagName=='polygon') pathdata+='z';
  path.setAttribute('id',poly.getAttribute('id'));
  path.setAttribute('fill',poly.getAttribute('fill'));
  path.setAttribute('stroke',poly.getAttribute('stroke'));
  path.setAttribute('d',pathdata);

  poly.parentNode.replaceChild(path,poly);
}
于 2012-12-09T13:32:18.717 回答
4

从开发人员工具中复制所有内容似乎很不方便。您可以使用 XSLT 将多边形和折线转换为路径:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" exclude-result-prefixes="svg"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:svg="http://www.w3.org/2000/svg">

  <!-- Identity transform: Copy everything 
       (except for polygon/polyline, handled below) -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- Turn polygons/polylines into paths, 
       copy all attributes and content 
       (except for @points: Will be matched
       by template below) -->
  <xsl:template match="svg:polygon|svg:polyline">
    <path>
      <xsl:apply-templates select="@*|node()"/>
    </path>
  </xsl:template>

  <!-- Turn the points attribute into a d attribute -->
  <xsl:template match="@points">
    <xsl:attribute name="d">
      <xsl:value-of select="concat('M',.)"/>
      <!-- If we have a polygon, we need to make 
           this a closed path by appending "z" -->
      <xsl:if test="parent::svg:polygon">
        <xsl:value-of select="'z'"/>
      </xsl:if>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

多边形/折线元素的任何属性都将被传递到路径元素。这也适用于批处理。您可以使用任何 XSLT 处理器(Saxon、Xalan、xsltproc、Altova...)甚至在浏览器中使用XSLTProcessor对象来运行它,例如:

var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(stylesheet);
var transformedSVG = xsltProcessor.transformToFragment(svgDocument).firstChild

(类似问题:SVG 中由路径与多边形绘制的多边形示例

于 2012-12-09T14:21:35.960 回答
4

A clicky-bunty answer:

  1. open the svg in inkscape vector graphics editor
  2. select all objects (ctrl-a)
  3. at the drop down menu point "path" select first entry "object to path" (shift-ctrl-c)
  4. save the svg and check out the path properties

Might be not an appropriate answer (because with large files the program needs some time).

于 2013-02-03T03:09:10.557 回答