Quelltext blumenimgarten.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

# IMPORTS
import sys
import xml.dom.minidom
import math

# ARGV / Parameternamen
filename_std = "Plan1.svg"
path_std = "path15471"
path_std = "path2979"
factor_std = 3543.314

if len(sys.argv) == 1:
    print "Aufruf auch mit Parametern möglich: main.py FILE.SVG PATHNAME FACTOR N"

# Nonverbose-Mode
verbose = True
if len(sys.argv) > 4:
    if sys.argv[4] == "n":
        verbose = False

# Dateiname benutzen
if len(sys.argv) > 1:
    filename = sys.argv[1]
else:
    print "Datei: %s ? [Yn]" % filename_std,  
    filename = raw_input()
    if filename == "" or filename == "Y":
        filename = filename_std
    if filename == "n":
        print "Type filename:"
        filename = raw_input()

if verbose:
    print "Use file: %s" % filename

# Pfadnamen herausfinden
if len(sys.argv) > 2:
    path = sys.argv[2]
else:
    print "Pfad: %s ? [Yn]" % path_std,
    path = raw_input()
    if path == "" or path == "Y":
        path = path_std
    if path == "n":
        print "Type pathname:"
        path = raw_input()
if verbose:
    print "Search for path: %s" % path

# Den Factor herausfinden, mit dem die SVG-Angaben in Meter umgerechnet werden können
if len(sys.argv) > 3:
    factor = float(sys.argv[3])
    if verbose:
        print "Use Factor: %f" % factor
else:
    print "Die Längenangaben der SVG-Datei sind in keiner wirklichen Einheit angegeben. ", "Du musst herausfinden, wieviel Inkscape-Einheiten einem cm/m entsprechen.", "Drücke in diesem Fall ?"  
    print "Faktor: %s ? [Yn?]" % factor_std ,
    factor = raw_input()
    if factor == "" or factor == "Y":
        factor = factor_std
    if factor == "n":
        print "Type equivalent of 1 m/cm:"
        factor = raw_input()
    if factor == "?":
        print "Draw a line of 1 cm/m in Inkskape. Save. Type in the name of that path and I will tell you how many Inkscape-Units it has"
        factor_path = raw_input()
    else:
        print "Use Factor: %f" % factor

# XML/SVG öffnen
doc = xml.dom.minidom.parse(filename)

# Alle Pfad-Einträge durchlaufen...
for node in doc.getElementsByTagName('path'):
    # FACTOR-BESTIMMUNG (wenn der Faktor unklar ist)
    # und nach der richtigen ID für die 1 cm/m-Strecke ausschau halten
    if factor == "?":
        if node.getAttribute("id") == factor_path:
            d = node.getAttribute("d")
            # Das z am Ende simulieren
            d = d + " z"
            pathnode = node
            break
    else:    
        # und nach der richtigen ID ausschau halten
        if node.getAttribute("id") == path:
            if verbose:
                print "Path found"
            d = node.getAttribute("d")
            pathnode = node
            break
else:
    print "Pfad nicht gefunden. Exit!"
    sys.exit(0)

# Nach nicht supporteten Transformationen suchen
n = pathnode
while n is None:
    print type(n)
    if n.hasAttributes() and n.hasAttribute("transform"):
        transformstring = n.getAttribute("transform")
        for forbiddenstring in ["matrix", "scale", "skewX", "skewY"]:
            if transformstring.find(forbiddenstring) >= 0:
                print "Auf Pfad wird eine Transformation angewendet. Dieses Script unterstützt die Berechnung der Fläche mit dieser Transformation nicht (%s)" % forbiddenstring
                sys.exit(0)
    n = n.parentNode

# Fehlermeldung wenn keine Pathdata
if not d:
    print "Keinen Pfad mit der ID %s gefunden" % path
    sys.exit(0)

if verbose:
    print "Koordinaten:", d

#Parse path
# Nur eine Bestimmte Art von Pfaden erlauben (m am Anfang und z am Ende)
# m: erstes Koordinatenpaar als absolut, alle weiteren in Paaren als relativ
# z: Geschlossener Pfad. (Linie zum Anfangspunkt denken)
# Das bedeutet, dass keine anderen Buchstaben vorkommen dürfen

# Beispiel:
#m 56214.989,-9978.506
# -2474.874,-2474.874 -4560.838,0 -3678.861,-3678.861 -9650.102,0
#  -2746.032,4756.266 -7592.471,0 -1813.979,-2763.979 -9484.986,0     

if not d[0] == "m":
    print "Nicht unterstützter Pfad: kein m am Anfang! (Es sind keine Kurven erlaubt. Nur gerade Linien)"
    sys.exit(0)

if not d[-1] == "z":
    print "Nicht unterstützte Pfad-Art: kein z Am Ende (Dh es liegt kein geschlossener Pfad vor. Man kann einen Pfad schließen, in dem man ihn makiert, dann mit dem 'Bezier und gerade Linien'-Werkzeug die kleinen Punkte am Anfang und am Ende des Pfades je einmal anklickt um sie zu verbinden) Exit!"
    sys.exit(0)

for char in "MmZzLlHhVvCcSsQqTtAa":
    if not d[1:-1].find(char) == -1:
        print "Der Buchstabe %s kommt mitten in den Pfad-Daten vor. Das bedeutet, dass eventuell eine Kurve oder ein anderes nicht-gerades Element im Pfad vorhanden ist. Dieses Script kann das nicht ausrechnen. Exit!" % char

# Den Pfad vom 2. bis zum vorletzten Buchstaben bei allen Leerzeichen teilen
parts = d[1:-1].split()
# Liste mit den Float-Koordinatenpaaren
vec = []

# FACTOR-BESTIMMUNG (+ EXIT)
if factor == "?":
    # Erstes (absolutes) Koordinatenpaar ist egal. Es zählt das relative 2.
    part2 = parts[1].split(",")
    part2[0] = float(part2[0])
    part2[1] = float(part2[1])
    # Pythargoras
    lenght = math.sqrt(part2[0] *  part2[0] +  part2[1] *  part2[1])
    print "Der Pfad %s hat eine Länge von %f Inkskape-Einheiten. Dies entspricht dem Faktor, der bei der Flächenberechnung anzugeben ist." % (factor_path, lenght)
    sys.exit(0)

# Jedes Koordinatenpaar in float umwandeln und mit dem Faktor skalieren
for part in parts:
    # Die 2 Koordinaten sind durch ein Komma getrennt
    part2 = part.split(",")
    # In float umwandeln und in metrische Einheiten skalieren
    part2[0] = float(part2[0]) / factor
    part2[1] = float(part2[1]) / factor
    vec.append(part2)

# 1. Koordinatenpaar ist absolut, alle weiteren relativ zum vorhergehenden
current = vec[0]
# Alle ab dem 2. durchgehen
for v in vec[1:]:
    # und die relativen Koordinaten durch absolute ersetzen
    v[0] = v[0] + current[0]
    v[1] = v[1] + current[1]
    current = v

# eigentliche Flächenberehcnung
A = 0

for index in range(0, len(vec)):
    # indexp1 = index plus 1
    indexp1 = index + 1
    # bei i > n : i = i % n
    # dh Indexe überhalb von n wieder von vorne zählen
    if index > (len(vec) - 1):
        index = index % len(vec)
    if indexp1 > (len(vec) - 1):
        indexp1 = indexp1 % len(vec)
    A = A + ( vec[index][1] + vec[indexp1][1] ) * ( vec[index][0] - vec[indexp1][0] )

# Aus der obrigen Formel ergibt sich der doppelte Flächeninhalt
A = A / 2
# Betrag
if A < 0:
    A = -A

# Fläche:
print A

Ein Kommentar

  1. Ciel sagt:

    Ciel sagt “ Da sind keine Blumen “
    Ciel fragt “ Lebt der Blog noch ?“
    Ciel wünscht sich mit Ihnen im Garten zu sein !

Schreibe einen Kommentar zu Ciel Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert