Convertir SVG polygon en chemin

j'ai un assez grand fichier SVG de subdivisions administratives avec lesquelles je dois travailler dans Raphael.JS (il a 600 polygones et Poids 1,2 Mb).

maintenant, je dois convertir ces polygones en chemins pour qu'ils fonctionnent en Raphaël. Le grand poly2path tool fait cela, mais il ne supporte aucune commande batch, de sorte que la position de chaque polygone par rapport aux autres est perdue.

connaissez-vous un outil pour convertir SVG les polygones tracés? (J'ai aussi le fichier AI qui a été utilisé pour exporter la SVG).

merci Beaucoup

22
demandé sur nkb 2012-05-23 13:32:43

4 réponses

  1. ouvrez votre SVG dans un navigateur web.
  2. Exécuter ce code:

    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. à l'aide des outils de développement (ou Firebug) du navigateur, utilisez" copier en HTML " (ou copier SVG) sur l'élément pour obtenir la source modifiée sur le bloc-notes.

  4. Coller dans un nouveau fichier et d'en profiter.

j'ai une démo de la méthode ci-dessus (légèrement modifiée) sur mon site web:

http://phrogz.net/svg/convert_polys_to_paths.svg

il y a deux méthodes utilisées sur cette page; l'une (comme ci-dessus) utilise des techniques basées sur les chaînes de caractères pour obtenir et définir les points; l'autre utilise le DOM SVG pour accéder aux points et définir les commandes path.


comme noté par @Interactive en les commentaires, vous pouvez le faire via des transformations texte seulement par:

  1. Convertir tous les <polyline et <polygon à <path
  2. changer toutes points=" en d="M
  3. pour tous les éléments qui étaient <polygon> , vous devez ajouter z comme dernier caractère de l'attribut d pour relier le dernier point au premier. Par exemple:

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

    devient

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

ce "hack" fonctionne parce que les spécifications déclarent qu'une commande moveto ( M ou m ) suivie de coordonnées multiples est légale, avec toutes les coordonnées après la première interprété comme lineto commandes.

68
répondu Phrogz 2016-11-29 16:38:20

copier tout des outils de développement semble assez incommode. Vous pouvez utiliser un XSLT pour transformer les polygones et les polylines en chemins:

<?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>

tout attribut des éléments polygones/polylignes sera transféré à l'élément path. C'est également adapté pour le traitement par lot. Vous pouvez l'exécuter avec n'importe quel processeur XSLT (Saxon, Xalan, xsltproc, Altova...) ou même dans le navigateur, en utilisant l'objet XSLTProcessor , comme:

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

(question similaire: exemples de polygones dessinés par chemin vs polygone dans SVG )

4
répondu Thomas W 2017-05-23 12:17:26

petit correctif pour les attributs polygon id, fill et stroke save

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);
}
3
répondu boooch 2012-12-09 13:58:40

clicky-bunty réponse:

  1. ouvrir le svg inkscape éditeur de graphiques vectoriels
  2. sélectionner tous les objets (ctrl-A)
  3. au point de menu déroulant" chemin "sélectionner la première entrée " objet vers le chemin" (shift-ctrl-c)
  4. enregistrer le svg et de vérifier les propriétés du chemin

pourrait ne pas être une réponse appropriée (parce qu'avec de grands fichiers le le programme a besoin d'un certain temps).

3
répondu jaminka evening 2013-02-03 03:19:16