Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert SVG polygon to path

Tags:

svg

raphael

I have a fairly large SVG file of administrative subdivisions that I need to work with in Raphael.JS (it has 600 polygons and weights 1.2 Mb).

Now, I need to convert these polygons to paths so that it works in Raphael. The great poly2path tool does that, but it doesn't support any batch command, so that each polygon's position relative to the others is lost.

Do you know of any tool to convert SVG polygons to paths? (I also have the AI file which was used to export the SVG).

Many thanks

like image 566
nkb Avatar asked May 23 '12 09:05

nkb


People also ask

How does SVG path work?

It is often placed at the end of a path node, although not always. There is no difference between the uppercase and lowercase command. The path will move to point ( 10 , 10 ) and then move horizontally 80 points to the right, then 80 points down, then 80 points to the left, and then back to the start.

What is SVG polygon?

SVG Polygon - <polygon>The <polygon> element is used to create a graphic that contains at least three sides. Polygons are made of straight lines, and the shape is "closed" (all the lines connect up). Polygon comes from Greek. "Poly" means "many" and "gon" means "angle".

How do you draw a polygon in SVG?

Most of the web browsers can display SVG just like they can display PNG, GIF, and JPG. To draw a polygon in HTML SVG, use the SVG <polygon> element. The <polygon> element creates a graphic containing at least three sides. The points attribute is the x and y coordinates for each corner of the polygon.


2 Answers

  1. Open your SVG in a web browser.
  2. Run this 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. Using the Developer Tools (or Firebug) of the browser, use "Copy as HTML" (or Copy SVG) on the element to get the modified source onto the clipboard.

  4. Paste into a new file and enjoy.

I have a demo of the above method (slightly modified) on my website:
http://phrogz.net/svg/convert_polys_to_paths.svg

There are two methods in use on that page; one (like the above) uses string-based techniques to get and set the points; the other uses the SVG DOM for accessing points and setting path commands.


As noted by @Interactive in the comments, you can do this via text-only transformations by:

  1. Convert all <polyline and <polygon to <path
  2. Change all points=" to d="M
  3. For any elements that were <polygon>, you need to add z as the last character of the d attribute to connect the last point to the first. For example:

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

    becomes

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

This 'hack' works because the specifications declare that a moveto command (M or m) followed by multiple coordinates is legal, with all coordinates after the first interpreted as lineto commands.

like image 87
Phrogz Avatar answered Sep 19 '22 18:09

Phrogz


Little fix for polygon id, fill and stroke attributes 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); } 
like image 41
boooch Avatar answered Sep 19 '22 18:09

boooch