Streckenberechnung über Koordinatenlisten

Code-Stücke können hier veröffentlicht werden.
Antworten
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Hallo,

Damit meine Matplotlib - Höhenprofile eine vernünftige X-Achsenbeschriftung bekommen, habe ich eine Funktion geschrieben, die mir aus Koordinaten im kartesischen System die Gesamtstrecke der Koordinaten berechnet. Dabei sind die Koordinaten als Stützpunkte einer Linie zu verstehen.

Code: Alles auswählen

#!/usr/bin/env python

from math import sqrt


def abs_distance(minuend, subtrahend):
    return abs(float(minuend) - float(subtrahend))


def distance_2d(geo_points):
    """
    Expects a list of dicts containing east and north keys
    """
    
    distance = 0
    
    for index, point in enumerate(geo_points):
        
        try:
            next_point = geo_points[index + 1]
            
            east_distance = abs_distance(point['east'], next_point['east'])
            north_distance = abs_distance(point['north'], next_point['north'])
            distance += sqrt(east_distance**2 + north_distance**2)
        except IndexError:
            pass
        
    return distance
Unschön meiner Meinung nach ist zum Einen die Krücke mit dem Index (index+1) um das folgende Koordinatenpaar zur Streckenberechnung heranzuziehen und zum Anderen das Abbrechen der Schleife mittels Exception.
Schöner wäre eine Lösung, die genau so lange läuft, wie Paare vorhanden sind und natürlich etwas, was den Index+1, ... ähm ..., anders formuliert.

Mir schwebt da etwas vor, was Koordinaten paarweise sammelt und erst, wenn ein Paar sich gefunden hat, die Substrecke berechnet. Mal sehen, ob sich so etwas realisieren lässt ...

Gruss

Frank
BlackJack

@fabron: Was zum Nachdenken:

Code: Alles auswählen

In [331]: xs = range(5)

In [332]: import itertools

In [333]: a, b = itertools.tee(xs)

In [334]: b.next()
Out[334]: 0

In [335]: list(itertools.izip(a, b))
Out[335]: [(0, 1), (1, 2), (2, 3), (3, 4)]
Funktioniert mit jedem "iterable", auch solche bei denen man nicht mit Indexen arbeiten kann. :-)
Benutzeravatar
hendrikS
User
Beiträge: 420
Registriert: Mittwoch 24. Dezember 2008, 22:44
Wohnort: Leipzig

Poste doch mal eine komplette Applikation. Könnte zum Verständnis beitragen. Mir ist der Nutzen der Funktion nicht so ohne weiteres klar.
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Cheesy :!: Das meiste scheint schon getan, wenn man die richtigen Module kennt ...
Nachdem ich nachgeschlagen habe, was die Funktionalität von tee und izip sind, ist die Umsetzung eigentlich nur noch Abschreiben ;)

Code: Alles auswählen

def point_iterator(iterable):
    a, b = tee(iterable)
    b.next()
    return izip(a, b)


def distance_2d(geo_points):
    """
    Expects a list of dicts containing east and north keys
    """
    
    distance = 0
    
    for point, next_point in point_iterator(geo_points):
        east_distance = abs_distance(point['east'], next_point['east'])
        north_distance = abs_distance(point['north'], next_point['north'])
        distance += sqrt(east_distance**2 + north_distance**2)
        
    return distance

hendrikS:
Es gibt noch keine Applikation, geschweige denn etwas Komplettes. Ziel ist es, mittels Matplotlib dynamisch Höhenprofile von (Wander)strecken zu berechnen. Solche Strecken definieren sich über eine Liste von Koordinatenpunkten mit Ost-, Nord- und Höhenwerten, oder mathematisch x, y und z Werten. Um nun die Länge einer solchen Strecke zu ermitteln habe ich diese Funktion geschrieben, die mittels Pythagoras die Distanz zwischen zwei Punkten in einem kartesischen System berechnet. Dazu iteriert man halt über jeweils zwei Punkte n, und n+1 und summiert die Teilstrecken dann auf.

Gebraucht wird der Wert in Matplotlib zum Einen, um die X-Achse zu beschriften mit einem Längenwert und um evt. die Achse zu skalieren um zwischen zwei oder mehreren Diagrammen einen Vergleich ziehen zu können.
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Matplotlib kann das bereits:

Code: Alles auswählen

Type:           function
Base Class:     <type 'function'>
String Form:    <function distances_along_curve at 0x9fd210c>
Namespace:      Interactive
File:           /usr/lib/pymodules/python2.6/matplotlib/mlab.py
Definition:     distances_along_curve(X)
Docstring:
    Computes the distance between a set of successive points in *N* dimensions.
    
    Where *X* is an *M* x *N* array or matrix.  The distances between
    successive rows is computed.  Distance is the standard Euclidean
    distance.
Grüße
Gerrit
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Prima, danke für den Tipp. Die Doku von Matplotlib ist für mich irgendwie zu chaotisch, das hätte ich selber wahrscheinlich nie gefunden, oder erst viel später :D
Antworten