如何将形状多边形转换为SVG?

时间:2018-03-07 08:56:28

标签: svg shapely

我可以通过以下方式创建一个Polygon:

#!/usr/bin/env python

from shapely.geometry import Polygon

area = Polygon(((52, 13), (57, 14), (58, 12)))

with open('test.svg', 'w') as f:
    f.write(area.svg())

返回

<path fill-rule="evenodd" fill="#66cc99" stroke="#555555" stroke-width="2.0" opacity="0.6" d="M 52.0,13.0 L 57.0,14.0 L 58.0,12.0 L 52.0,13.0 z" />

这不是有效的SVG文件。我怎样才能获得有效的SVG?

我试过

#!/usr/bin/env python

from shapely.geometry import Polygon

area = Polygon(((52, 13), (57, 14), (58, 12)))

with open('test.svg', 'w') as f:
    f.write('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">')
    f.write(area.svg())
    f.write('</svg>')

当我查看此视图​​时,视口对多边形来说是大的。使用Inkscape手动编辑它并调整其大小给出:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   version="1.1"
   id="svg2"
   inkscape:version="0.91 r13725"
   sodipodi:docname="test.svg"
   width="7.9687681"
   height="4.4396091">
  <metadata
     id="metadata10">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <defs
     id="defs8" />
  <sodipodi:namedview
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1"
     objecttolerance="10"
     gridtolerance="10"
     guidetolerance="10"
     inkscape:pageopacity="0"
     inkscape:pageshadow="2"
     inkscape:window-width="2560"
     inkscape:window-height="1364"
     id="namedview6"
     showgrid="false"
     inkscape:zoom="2.36"
     inkscape:cx="-1.8038839"
     inkscape:cy="-34.869627"
     inkscape:window-x="0"
     inkscape:window-y="24"
     inkscape:window-maximized="1"
     inkscape:current-layer="svg2"
     fit-margin-top="0"
     fit-margin-left="0"
     fit-margin-right="0"
     fit-margin-bottom="0" />
  <path
     d="m 0.19611614,2.3092357 4.99999996,1 1,-2 -5.99999996,1 z"
     id="path4"
     inkscape:connector-curvature="0"
     style="opacity:0.6;fill:#66cc99;fill-rule:evenodd;stroke:#555555;stroke-width:2" />
</svg>

有没有办法自动获取?

2 个答案:

答案 0 :(得分:2)

您需要指定生成图像的大小和viewBox。例如:

#!/usr/bin/env python

from shapely.geometry import Polygon
import textwrap

area = Polygon(((52, 13), (57, 14), (58, 12)))

with open('test.svg', 'w') as f:
    #specify margin in coordinate units
    margin = 5

    bbox = list(area.bounds)
    bbox[0] -= margin
    bbox[1] -= margin
    bbox[2] += margin
    bbox[3] += margin

    width = bbox[2] - bbox[0]
    height = bbox[3] - bbox[1]

    #transform each coordinate unit into "scale" pixels
    scale = 10

    props = {
        'version': '1.1',
        'baseProfile': 'full',
        'width': '{width:.0f}px'.format(width = width*scale),
        'height': '{height:.0f}px'.format(height = height*scale),
        'viewBox': '%.1f,%.1f,%.1f,%.1f' % (bbox[0], bbox[1], width, height),
        'xmlns': 'http://www.w3.org/2000/svg',
        'xmlns:ev': 'http://www.w3.org/2001/xml-events',
        'xmlns:xlink': 'http://www.w3.org/1999/xlink'
    }

    f.write(textwrap.dedent(r'''
        <?xml version="1.0" encoding="utf-8" ?>
        <svg {attrs:s}>
        {data:s}
        </svg>
    ''').format(
        attrs = ' '.join(['{key:s}="{val:s}"'.format(key = key, val = props[key]) for key in props]),
        data = area.svg()
    ).strip())

答案 1 :(得分:1)

尝试:

with open('test.svg', 'w') as f:
    f.write(area._repr_svg_())

BaseGeometry._repr_svg_函数用于IPython / Jupyter集成,以便在Jupyter笔记本中内联渲染Shapely对象。因此,“内部”命名在这里定义: http://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html

有效地,它会产生有效的SVG输出。