#!/usr/bin/python # -*- coding: utf-8 -*- # IMPORTS import sys import xml.dom.minidom import mathi # 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 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 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