source: branches/inundation-numpy-branch/geospatial_data/geospatial_data.py @ 6689

Last change on this file since 6689 was 3514, checked in by duncan, 19 years ago

Hi all,
I'm doing a change in the anuga structure, moving the code to

\anuga_core\source\anuga

After you have done an svn update, the PYTHONPATH has to be changed to;
PYTHONPATH = anuga_core/source/

This is part of changes required to make installation of anuga quicker and reducing the size of our sandpits.

If any imports are broken, try fixing them. With adding anuga. to them for example. If this seems to have really broken things, email/phone me.

Cheers
Duncan

File size: 7.6 KB
Line 
1"""Class Geospatial_data - Manipulation of locations on the planet and
2associated attributes.
3
4"""
5
6
7from anuga.utilities.numerical_tools import ensure_numeric
8
9from numpy import concatenate
10
11from coordinate_transforms.geo_reference import Geo_reference
12       
13class Geospatial_data:
14
15    def __init__(self,
16                 data_points,
17                 attributes = None,
18                 geo_reference = None,
19                 default_attribute_name = None):
20
21        """Create instance from data points and associated attributes
22
23
24        data_points: x,y coordinates in meters. Type must be either a
25        sequence of 2-tuples or an Mx2 Numeric array of floats.
26
27        attributes: Associated values for each data point. The type
28        must be either a list or an array of length M or a dictionary
29        of lists (or arrays) of length M. In the latter case the keys
30        in the dictionary represent the attribute names, in the former
31        the attribute will get the default name 'attribute'.
32       
33        geo_reference: Object representing the origin of the data
34        points. It contains UTM zone, easting and northing and data
35        points are assumed to be relative to this origin.
36        If geo_reference is None, the default geo ref object is used
37
38        default_attribute_name: Name of default attribute to be used with
39        get_attribute_values. The idea is that the dataset can be
40        equipped with information about which attribute to return.
41        If None, the default is the 'first'
42       
43        """
44
45        self.data_points = ensure_numeric(data_points)
46        self.set_attributes(attributes)
47        self.set_geo_reference(geo_reference)
48        self.set_default_attribute_name(default_attribute_name)
49       
50
51
52
53    def set_attributes(self, attributes):
54        """Check and assign attributes dictionary
55        """
56       
57        from types import DictType
58       
59        if attributes is None:
60            self.attributes = None
61            return
62       
63        if not isinstance(attributes, DictType):
64            #Convert single attribute into dictionary
65            attributes = {'attribute': attributes}
66
67        #Check input attributes   
68        for key in attributes.keys():
69            try:
70                attributes[key] = ensure_numeric(attributes[key])
71            except:
72                msg = 'Attribute %s could not be converted' %key
73                msg += 'to a numeric vector'
74                raise msg
75
76        self.attributes = attributes   
77
78
79    def set_geo_reference(self, geo_reference):
80
81        from coordinate_transforms.geo_reference import Geo_reference
82
83
84        if geo_reference is None:
85            self.geo_reference = Geo_reference() # Use default
86        elif isinstance(geo_reference, Geo_reference):
87            self.geo_reference = geo_reference
88        else:
89            msg = 'Argument geo_reference must be a valid Geo_reference \n'
90            msg += 'object or None.'
91            raise msg
92
93
94    def set_default_attribute_name(self, default_attribute_name):
95        self.default_attribute_name = default_attribute_name
96
97
98    def get_geo_reference(self):
99        return self.geo_reference
100       
101    def get_data_points(self, absolute = True):
102        if absolute is True:
103            xll = self.geo_reference.xllcorner
104            yll = self.geo_reference.yllcorner
105            return self.data_points + [xll, yll]
106           
107        else: 
108            return self.data_points
109   
110    def get_attributes(self, attribute_name = None):
111        """Return values for one named attribute.
112
113        If attribute_name is None, default_attribute_name is used
114        """
115
116        if attribute_name is None:
117            if self.default_attribute_name is not None:
118                attribute_name = self.default_attribute_name
119            else:
120                attribute_name = self.attributes.keys()[0] 
121                # above line takes the first one from keys
122               
123
124        msg = 'Attribute name %s does not exist in data set' %attribute_name
125        assert self.attributes.has_key(attribute_name), msg
126
127        return self.attributes[attribute_name]
128
129    def __add__(self,other):
130        """
131        returns the addition of 2 geospatical objects,
132        objects are concatencated to the end of each other
133           
134        NOTE: doesn't add if objects contain different
135        attributes 
136        """
137
138        # sets xll and yll as the smallest from self and other
139        if self.geo_reference.xllcorner <= other.geo_reference.xllcorner:
140            xll = self.geo_reference.xllcorner
141        else:
142            xll = other.geo_reference.xllcorner
143
144        if self.geo_reference.yllcorner <= other.geo_reference.yllcorner:
145            yll = self.geo_reference.yllcorner
146        else:
147            yll = other.geo_reference.yllcorner
148
149        # find objects zone and checks if the same
150        geo_ref1 = self.get_geo_reference()
151        zone1 = geo_ref1.get_zone()
152       
153        geo_ref2 = other.get_geo_reference()
154        zone2 = geo_ref2.get_zone()
155       
156        geo_ref = Geo_reference(zone1, xll, yll)
157       
158        if zone1 == zone2: 
159            a_rel_points = self.get_data_points()
160            b_rel_points = other.get_data_points()
161           
162            # subtracts xll and yll from self's and other's
163            # reletive data point and concatenates
164            c_points = concatenate((a_rel_points-[xll, yll],
165                                    b_rel_points-[xll, yll]), axis = 0)
166
167            new_dictionary = {}
168            for x in self.attributes.keys():
169                if other.attributes.has_key(x):
170
171                    a_attrib = self.attributes[x]
172                    b_attrib = other.attributes[x]
173                    new_dictionary[x] = concatenate((a_attrib, b_attrib))
174
175                else:
176                    msg = 'Both geospatial_data objects must have the same \n'
177                    msg += 'attributes to allow addition.'
178                    raise msg
179 
180            return Geospatial_data(c_points, new_dictionary, geo_ref)
181           
182        else:
183            msg = 'Both geospatial_data objects must be in the same \
184            ZONE to allow addition.'
185            raise msg
186     
187
188
189def geospatial_data2points_dictionary(geospatial_data):
190    """Convert geospatial data to points_dictionary
191    """
192
193    points_dictionary = {}
194    points_dictionary['pointlist'] = geospatial_data.data_points
195
196    points_dictionary['attributelist'] = {}
197
198    for attribute_name in geospatial_data.attributes.keys():
199        val = geospatial_data.attributes[attribute_name]
200        points_dictionary['attributelist'][attribute_name] = val
201
202    points_dictionary['geo_reference'] = geospatial_data.geo_reference
203
204    return points_dictionary
205
206   
207   
208
209
210
211
212def points_dictionary2geospatial_data(points_dictionary):
213    """Convert points_dictionary to geospatial data object
214    """
215
216    msg = 'Points dictionary must have key pointlist' 
217    assert points_dictionary.has_key('pointlist'), msg
218
219    msg = 'Points dictionary must have key attributelist'     
220    assert points_dictionary.has_key('attributelist'), msg       
221
222    if points_dictionary.has_key('geo_reference'):
223        geo = points_dictionary['geo_reference']
224    else:
225        geo = None
226   
227    return Geospatial_data(points_dictionary['pointlist'],
228                           points_dictionary['attributelist'],
229                           geo_reference = geo)
230
231
232           
233           
234       
Note: See TracBrowser for help on using the repository browser.