Подтвердить что ты не робот

Преобразование полигона SVG в путь

У меня есть довольно большой файл SVG административных подразделений, с которым мне нужно работать в Raphael.JS(у него 600 полигонов и вес 1,2 Мб).

Теперь мне нужно преобразовать эти полигоны в пути, чтобы они работали в Рафаэле. Великий инструмент poly2path делает это, но не поддерживает какую-либо командную команду, так что каждая позиция многоугольника относительно остальных теряется.

Знаете ли вы о каком-либо инструменте для преобразования полигонов SVG в пути? (У меня также есть файл AI, который использовался для экспорта SVG).

Большое спасибо

4b9b3361

Ответ 1

  • Откройте ваш SVG в веб-браузере.
  • Запустите этот код:

    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);
    }
    
  • Используя средства разработчика (или Firebug) браузера, используйте "Скопировать как HTML" (или скопировать SVG) в элемент, чтобы получить измененный источник в буфер обмена.

  • Вставьте новый файл и наслаждайтесь.

У меня есть демонстрационный пример вышеупомянутого метода (слегка измененный) на моем сайте:
http://phrogz.net/svg/convert_polys_to_paths.svg

На этой странице используются два метода; один (как и выше) использует строковые методы для получения и установки точек; другой использует SVG DOM для доступа к точкам и установки команд пути.


Как отмечено @Interactive в комментариях, вы можете сделать это с помощью текстовых преобразований:

  • Преобразуйте все <polyline и <polygon в <path
  • Измените все points=" на d="M
  • Для любых элементов, которые были <polygon>, вам нужно добавить z в качестве последнего символа атрибута d для подключения последней точки к первой. Например:

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

    становится

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

Этот "взлом" работает, потому что спецификации объявляют, что команда moveto (M или M), за которой следуют несколько координат, является законной, причем все координаты после первого интерпретируются как команды lineto.

Ответ 2

Копирование всего из инструментов разработчика кажется довольно неудобным. Вы можете использовать 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)

Ответ 3

Маленькое исправление для атрибутов идентификатора многоугольника, заливки и штриха сохранения

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);
}

Ответ 4

Ответ на щелчок:

  • открыть svg в редакторе векторной графики inkscape
  • выберите все объекты (ctrl-a)
  • в выпадающем пункте меню "путь" выберите первую запись "объект в путь" (shift-ctrl-c)
  • сохранить svg и проверить свойства пути

Не может быть подходящего ответа (потому что с большими файлами программа нуждается в некотором времени).