#!/usr/bin/python# -*- coding: utf-8 -*-# IMPORTSimport sysimport xml.dom.minidomimport math# ARGV / Parameternamenfilename_std = "Plan1.svg"path_std = "path15471"path_std = "path2979"factor_std = 3543.314if len(sys.argv) == 1: print "Aufruf auch mit Parametern möglich: main.py FILE.SVG PATHNAME FACTOR N"# Nonverbose-Modeverbose = Trueif len(sys.argv) > 4: if sys.argv[4] == "n": verbose = False# Dateiname benutzenif 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 herausfindenif 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önnenif len(sys.argv) > 3: factor = float(sys.argv[3]) if verbose: print "Use Factor: %f" % factorelse: print "Die Längenangaben der SVG-Datei sind in keiner wirklichen Einheit angegeben. ", "Du musst den 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 breakelse: print "Pfad nicht gefunden. Exit!" sys.exit(0)# Nach nicht supporteten Transformationen suchenn = pathnodewhile 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 Pathdataif 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 teilenparts = d[1:-1].split()# Liste mit den Float-Koordinatenpaarenvec = []# 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 skalierenfor 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 vorhergehendencurrent = vec[0]# Alle ab dem 2. durchgehenfor 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ächenberehcnungA = 0for 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ächeninhaltA = A / 2# Betragif A < 0: A = -A# Fläche:print A