source: branches/numpy/anuga/lib/order_boundary/order_boundary.py @ 6883

Last change on this file since 6883 was 6213, checked in by ole, 16 years ago

Ross and Ole discovered reasons for maxasc and order_boundary not being included in test_all.py - the assumption made in test_all.py was a flat structure under anuga. This should be rewritten using os.walk('.') as in clean_all.py

File size: 3.3 KB
Line 
1#!/usr/bin/env python
2'''Routine to automatically order boundary points'''
3
4################################################################################
5# This routine is used to automatically order boundary points in a CSV file.
6#
7# usage: order_boundary(infile, outfile)
8#
9# where infile  is the string path of the input CSV file,
10#   and outfile is the string path of the output CSV file.
11#
12# The input file is expected to have the format:
13#        longitude,latitude,index
14#        150.0833,-37.5,2758
15#        150.1,-37.4667,2765
16#        150.1167,-37.3833,2769
17#        150.1333,-36.7167,2771
18#        150.1333,-36.7667,2774
19#        150.15,-36.5833,2777
20#        150.15,-36.6333,2780
21#        150.15,-36.6833,2783
22#        150.15,-36.8167,2787
23#
24# The first point in the ordered output file is assumed to be the first point in
25# the input file (ie, line 2).  The header line is preserved, as are all fields
26#following the first two fields in each data line.
27################################################################################
28
29import csv
30
31
32##
33# @brief Order a CSV file of boundary points.
34# @param Path to input file.
35# @param Path to output file.
36# @note Input file will have a header line that must be preserved.
37# @note File format is: (longitude, latitude, <other_fields>)
38# @note Fields after long+lat must be preserved.
39def order_boundary(infile, outfile):
40
41    ##
42    # @brief Recursive routine to sort a list of point tuples: (x, y, ...).
43    # @param unordered Unordered list of points.
44    # @param ordered Return list of ordered points.
45    # @param is index into 'unordered' of point to put into 'ordered'.
46    # @note This code:
47    #         . moves 'id' point from 'unordered' into 'ordered'
48    #         . finds 'id' of next point to be moved
49    #         . if more points, recurse
50    def sort_points(unordered, ordered, id):
51        # move 'id' point from unordered to ordered, get x0, y0
52        ordered.append(unordered[id])
53        x0 = unordered[id][0]
54        y0 = unordered[id][1]
55        del unordered[id]
56
57        # find nearest point to 'id' point in 'unordered'
58        nearest = None
59        for i, p in enumerate(unordered):
60            x1 = p[0]
61            y1 = p[1]
62            # get square of distance between the 2 points
63            d2 = (x1-x0)*(x1-x0) + (y1-y0)*(y1-y0)
64            if nearest is None or d2 < nearest:
65                next = i
66                nearest = d2
67
68        # if there are more points in 'unordered', recurse
69        if nearest is not None:
70            sort_points(unordered, ordered, next)
71           
72        return ordered
73
74    # read file into list of tuples, convert first 2 fields to floats.
75    fd = open(infile, 'r')
76    data = []
77    for row in csv.reader(fd):
78        try:
79            row[0] = float(row[0])
80        except:
81            pass
82        try:
83            row[1] = float(row[1])
84        except:
85            pass
86        data.append(tuple(row))
87    fd.close()
88
89    # preserve header row
90    header = data[0]
91    del data[0]
92
93    # order the data
94    ordered_data = sort_points(data, [], 0)
95
96    # write ordered data to output file
97    fd = open(outfile, 'wb')
98    w = csv.writer(fd)
99    w.writerow(header)
100   
101    for d in ordered_data:
102        w.writerow(d)
103    fd.close()
104
Note: See TracBrowser for help on using the repository browser.