Seite 1 von 1

Streckenberechnung über Koordinatenlisten

Verfasst: Montag 3. Mai 2010, 08:59
von frabron
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

Verfasst: Montag 3. Mai 2010, 09:21
von 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. :-)

Verfasst: Montag 3. Mai 2010, 10:27
von hendrikS
Poste doch mal eine komplette Applikation. Könnte zum Verständnis beitragen. Mir ist der Nutzen der Funktion nicht so ohne weiteres klar.

Verfasst: Montag 3. Mai 2010, 11:06
von frabron
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.

Verfasst: Montag 3. Mai 2010, 11:43
von gkuhl
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

Verfasst: Montag 3. Mai 2010, 13:22
von frabron
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