Liebe Community,
ich versuche gerade ein Programm zu schreiben, welches auf einer Deutschlandkarte die Brücken geordnet nach Zustandsnote anzeigen soll. Ich habe dafür eine .csv Datei bekommen, in welcher die einzelnen Zustandsnoten (1.0 - 4.0) gelistet sind, wobei daneben dann in einer anderen Spalte die jeweiligen Koordinaten gelistet sind. Eine andere Datei enthält die Werte für die Umrisse der Deutschlandkarte.
Ich habe es schon geschafft alle Brücken auf der Karte anzeigen zu lassen, jedoch hab ich die Aufgabe den Benutzer im Programm eine Zustandsnote eingeben zu lassen. Je nachdem welche er angibt sollen genau nur die Brücken angezeigt werden, welche auch diese Zustandsnote haben. Ich kenne mich leider echt nicht aus, trotzdem schicke ich mal den Code rein den ich bis jetzt habe. Die farbliche Unterteilung ist jetzt noch nicht wichtig. Wäre über jede Hilfe dankbar, vielen Dank im Voraus!
# Module importieren
import matplotlib.pyplot as plt
import csv
# Listen erstellen:
ZN_komplett = []
ZN_sehrgut = []
ZN_gut = []
ZN_befriedigend = []
ZN_ausreichend = []
ZN_nichtausreichend = []
ZN_schlecht = []
NB_komplett = []
OL_komplett = []
ZN = []
NB = []
OL = []
# Kartenumriss erstellen
with open("Deutschlandkarte.txt", "r") as datei:
X = []
Y = []
for zeiletxt in datei:
x, y = zeiletxt.split()
X.append(float(x))
Y.append(float(y))
# CSV-Datei importieren
with open("Zustandsnoten.csv") as csvdatei:
reader = csv.reader(csvdatei, delimiter='\t')
kopfzeile = next(reader)
# Gruppen zuordnen
for row in reader:
ZN_komplett.append(float(row[6].replace(',', '.')))
NB_komplett.append(float(row[10].replace(',', '.')))
OL_komplett.append(float(row[11].replace(',', '.')))
# Nullwerte aus Koordinaten rausnehmen
for value in NB_komplett:
if value > 3:
NB.append(value)
for value in OL_komplett:
if value > 3:
OL.append(value)
# Einzelne Gruppen für farbliche Unterteilung erstellen
for value in ZN_komplett:
if value <= 1.4:
ZN_sehrgut.append(value)
for value in ZN_komplett:
if 1.4 < value <= 1.9:
ZN_gut.append(value)
for value in ZN_komplett:
if 1.9 < value <= 2.4:
ZN_befriedigend.append(value)
for value in ZN_komplett:
if 2.4 < value <= 2.9:
ZN_ausreichend.append(value)
for value in ZN_komplett:
if 2.9 < value <= 3.4:
ZN_nichtausreichend.append(value)
for value in ZN_komplett:
if 3.4 < value <= 4.0:
ZN_schlecht.append(value)
def safeint(s):
try:
return int(s)
except ValueError:
return 0
Wunsch = safeint(input("Zustandsnote: "))
# if 1 <= Wunsch <= 1.4:
# if 1.4 < Wunsch <= 1.9:
# Grafikgröße anpassen
mm = 1 / 25.4 # Zoll
A4 = (210 * mm, 297 * mm)
plt.figure(figsize=A4)
# diagramm erzeugen
plt.plot(X, Y, color="black", linewidth=4, )
# Gitter erzeugen
plt.grid(True)
# Achsen beschriften
plt.xlabel("Östliche Länge")
plt.ylabel("Nördliche Breite")
# Überschrift
plt.title("""Karte der "Anzahl" deutschen Fernstraßenbrücken
mit der Zustandsnote "ZN" ("Zustand")""")
# Markierung der Orte
H = NB
F = OL
plt.scatter(F, H, color="red", marker="o")
Programm zum Anzeigen von bestimmten Werten auf Karte
- __blackjack__
- User
- Beiträge: 14078
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@cali81: Anmerkungen zum Quelltext: Kommentare sollen dem Leser einen Mehrwert über den Code geben. Faustregel: Kommentare beschreiben nicht *was* der Code macht, denn das steht da bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in aller Regel auch was in der Dokumentation von Python und den verwendeten Bibliotheken steht.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).
Namen sollten keine kryptischen Abkürzungen enthalten oder gar nur daraus bestehen. Wenn man `zustandsnote` meint, sollte man nicht nur `zn` schreiben. `H`? `F`? `NB`? `OL`? WTF?
Nirgendwo kommt das Wort Brücke vor — um die geht's doch aber‽
Man definiert nicht am Anfang mal alle Namen die man vielleicht mal braucht, die dann aber erst später in der Funktion verwendet werden. Oder auch nicht, denn mindestens `ZN` wird zwar definiert, aber nirgends verwendet.
Unter dem zweiten ``with`` ist eine Menge Code eingerückt der die Datei beziehungsweise den `reader` gar nicht mehr verwendet.
Textdateien sollte man immer explizit mit einer Kodierungsangabe öffnen und bei CSV-Dateien muss man das `newline`-Argument passend übergeben wie in der Dokumentation beschrieben.
Diese vielen Listen sind Mist. Man steckt keine zusammengehörenden Daten in verschiedene ”parallele” Listen wo immer Werte am gleichen Index zusammengehören. Auch wenn das zum plotten praktisch erscheint — die Vorverarbeitung wird dadurch erschwert, weil man immer darauf achten muss, dass sich die Inhalte der Listen nicht verschieben. Das macht das Programm nicht. Nichts im Programm garantiert, dass `NB` und `OL` nach dem sie befüllt sind a) gleich lang sind und b) die Werte am gleichen Index auch tatsächlich zusammengehören. Du verlässt Dich da komplett darauf das die Filterbedingung entweder immer für beide Komponenten gilt oder für keine von beiden.
Und die ganzen `zn_*`-Namen die eine Bewertung enthalten stehen für Listen mit Notenwerten, die aber überhaupt keinen Bezug mehr zu den dazugehörigen Koordinaten haben. Das macht überhaupt gar keinen Sinn. Zudem sind die Bewertungsstufen die Du da in Namen kodierst eigentlich *Daten* die Du letztlich hier für jede Stufe als Code ausdrückst was dazu führt, dass auch bei der Auswahl wieder Code für jede Stufe geschrieben werden muss. Das ist unnötig Arbeit und fehleranfällig, weil die Grenzwerte dann auch wieder im Code wiederholt werden müssen.
Ungetestet:
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).
Namen sollten keine kryptischen Abkürzungen enthalten oder gar nur daraus bestehen. Wenn man `zustandsnote` meint, sollte man nicht nur `zn` schreiben. `H`? `F`? `NB`? `OL`? WTF?
Nirgendwo kommt das Wort Brücke vor — um die geht's doch aber‽
Man definiert nicht am Anfang mal alle Namen die man vielleicht mal braucht, die dann aber erst später in der Funktion verwendet werden. Oder auch nicht, denn mindestens `ZN` wird zwar definiert, aber nirgends verwendet.
Unter dem zweiten ``with`` ist eine Menge Code eingerückt der die Datei beziehungsweise den `reader` gar nicht mehr verwendet.
Textdateien sollte man immer explizit mit einer Kodierungsangabe öffnen und bei CSV-Dateien muss man das `newline`-Argument passend übergeben wie in der Dokumentation beschrieben.
Diese vielen Listen sind Mist. Man steckt keine zusammengehörenden Daten in verschiedene ”parallele” Listen wo immer Werte am gleichen Index zusammengehören. Auch wenn das zum plotten praktisch erscheint — die Vorverarbeitung wird dadurch erschwert, weil man immer darauf achten muss, dass sich die Inhalte der Listen nicht verschieben. Das macht das Programm nicht. Nichts im Programm garantiert, dass `NB` und `OL` nach dem sie befüllt sind a) gleich lang sind und b) die Werte am gleichen Index auch tatsächlich zusammengehören. Du verlässt Dich da komplett darauf das die Filterbedingung entweder immer für beide Komponenten gilt oder für keine von beiden.
Und die ganzen `zn_*`-Namen die eine Bewertung enthalten stehen für Listen mit Notenwerten, die aber überhaupt keinen Bezug mehr zu den dazugehörigen Koordinaten haben. Das macht überhaupt gar keinen Sinn. Zudem sind die Bewertungsstufen die Du da in Namen kodierst eigentlich *Daten* die Du letztlich hier für jede Stufe als Code ausdrückst was dazu führt, dass auch bei der Auswahl wieder Code für jede Stufe geschrieben werden muss. Das ist unnötig Arbeit und fehleranfällig, weil die Grenzwerte dann auch wieder im Code wiederholt werden müssen.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
import csv
from collections import namedtuple
import matplotlib.pyplot as plt
Coordinates = namedtuple("Coordinates", "longitude latitude")
Bridge = namedtuple("Bridge", "mark coordinates")
def parse_float(text):
return float(text.replace(",", "."))
def ensure_integer(text):
try:
return int(text)
except ValueError:
return 0
def main():
with open("Deutschlandkarte.txt", "r", encoding="ascii") as file:
country_outline = []
for line in file:
longitude_text, latitude_text = line.split()
country_outline.append(
Coordinates(float(longitude_text), float(latitude_text))
)
with open("Zustandsnoten.csv", encoding="ascii", newline="") as file:
reader = csv.reader(file, delimiter="\t")
next(reader) # Kopfzeile überlesen.
bridges = [
Bridge(
parse_float(row[6]),
Coordinates(parse_float(row[11]), parse_float(row[10])),
)
for row in reader
]
#
# Nullwerte aus Koordinaten rausnehmen.
#
bridges = [
bridge
for bridge in bridges
if bridge.coordinates.longitude > 3 and bridge.coordinates.latitude > 3
]
levels = [
(1.4, "sehr gut"),
(1.9, "gut"),
(2.4, "befriedigend"),
(2.9, "ausreichend"),
(3.4, "nicht ausreichend"),
(4, "schlecht"),
]
chosen_mark = ensure_integer(input("Zustandsnote: "))
one_millimeter = 1 / 25.4 # Zoll
plt.figure(figsize=(210 * one_millimeter, 297 * one_millimeter))
plt.plot(
[coordinates.longitude for coordinates in country_outline],
[coordinates.latitude for coordinates in country_outline],
color="black",
linewidth=4,
)
plt.grid(True)
plt.xlabel("Östliche Länge")
plt.ylabel("Nördliche Breite")
plt.title(
"Karte der 'Anzahl' deutschen Fernstraßenbrücken\n"
"mit der Zustandsnote 'ZN' ('Zustand')"
)
plt.scatter(
[bridge.coordinates.longitude for bridge in bridges],
[bridge.coordinates.latitude for bridge in bridges],
color="red",
marker="o",
)
if __name__ == "__main__":
main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
- __blackjack__
- User
- Beiträge: 14078
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Die Daten scheint es bei der Bundesanstalt für Straßenwesen (BASt) auf der Seite Fokus: Brücken als Excel-Datei zu geben. Habe ich als CSV gespeichert und die Indizes in Deinem Skript angepasst, weil Du anscheinend mehr Spalten hast und habe das hier heraus bekommen:

Die Linie ist ein bisschen dick und die Punkte viel zu gross um da sinnvoll was erkennen zu können. Die Achsenbeschriftungen kann man sich IMHO sparen, weil die meisten damit wahrscheinlich eh nichts anfangen können. Sinnvoller Informationsgehalt wäre vielleicht eher, wenn man die Grenzen der Bundesländer einzeichnen würde.

Die Linie ist ein bisschen dick und die Punkte viel zu gross um da sinnvoll was erkennen zu können. Die Achsenbeschriftungen kann man sich IMHO sparen, weil die meisten damit wahrscheinlich eh nichts anfangen können. Sinnvoller Informationsgehalt wäre vielleicht eher, wenn man die Grenzen der Bundesländer einzeichnen würde.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari