source: inundation/geospatial_data/geospatial_data.py @ 3320

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

using tip from Ole

File size: 28.7 KB
Line 
1"""Class Geospatial_data - Manipulation of locations on the planet and
2associated attributes.
3
4"""
5
6from os import access, F_OK, R_OK
7from Numeric import concatenate, array, Float, shape, reshape, ravel
8
9
10from utilities.numerical_tools import ensure_numeric
11from coordinate_transforms.geo_reference import Geo_reference, TitleError
12from coordinate_transforms.redfearn import convert_lats_longs
13
14       
15class Geospatial_data:
16
17    def __init__(self,
18                 data_points = None,
19                 attributes = None,
20                 geo_reference = None,
21                 default_attribute_name = None,
22                 file_name = None,
23                 delimiter = None,
24                 latitudes = None,
25                 longitudes = None,
26                 points_are_lats_longs = False,
27                 verbose = False):
28
29       
30        """
31        Create instance from data points and associated attributes
32
33        data_points: x,y coordinates in meters. Type must be either a
34        sequence of 2-tuples or an Mx2 Numeric array of floats.
35
36        attributes: Associated values for each data point. The type
37        must be either a list or an array of length M or a dictionary
38        of lists (or arrays) of length M. In the latter case the keys
39        in the dictionary represent the attribute names, in the former
40        the attribute will get the default name "attribute".
41       
42        geo_reference: Object representing the origin of the data
43        points. It contains UTM zone, easting and northing and data
44        points are assumed to be relative to this origin.
45        If geo_reference is None, the default geo ref object is used
46
47        default_attribute_name: Name of default attribute to be used with
48        get_attribute_values. The idea is that the dataset can be
49        equipped with information about which attribute to return.
50        If None, the default is the "first"
51       
52        file_name: Name of input netCDF file or xya file. netCDF file must
53        have dimensions "points" etc.
54        xya file is a CVS file with lats(x), longs(y) and elevation(a).
55        first line must be attribute name eg elevation
56       
57        The format for a .xya file is:
58            1st line:     [attribute names]
59            other lines:  x y [attributes]
60
61            for example:
62            elevation, friction
63            0.6, 0.7, 4.9, 0.3
64            1.9, 2.8, 5, 0.3
65            2.7, 2.4, 5.2, 0.3
66
67        The first two columns are always implicitly assumed to be x, y coordinates.
68        Use the same delimiter for the attribute names and the data
69
70        An xya file can optionally end with
71            #geo reference
72            56
73            466600.0
74            8644444.0
75
76        When the 1st # is the zone,
77        2nd # the xllcorner and
78        3rd # the yllcorner
79       
80        The format for a Points dictionary is:
81
82          ['pointlist'] a 2 column array describing points. 1st column x, 2nd column y.
83          ['attributelist'], a dictionary of 1D arrays, representing attribute values
84          at the point.  The dictionary key is the attribute header.
85          ['geo_reference'] a Geo_refernece object. Use if the point information
86            is relative. This is optional.
87            eg
88            dic['pointlist'] = [[1.0,2.0],[3.0,5.0]]
89            dic['attributelist']['elevation'] = [[7.0,5.0]
90               
91        delimiter: is the file delimiter that will be used when
92            importing the file
93           
94        verbose:
95         
96        """
97
98        if isinstance(data_points, basestring):
99            # assume data point is really a file name
100            file_name = data_points
101
102        self.set_verbose(verbose)
103        self.geo_reference=None #create the attribute
104        if file_name is None:
105            if delimiter is not None:
106                msg = 'No file specified yet a delimiter is provided!'
107                raise ValueError, msg
108            file_name = None
109            if latitudes is not None or longitudes is not None or \
110                   points_are_lats_longs:
111                data_points, geo_reference =  \
112                             self._set_using_lat_long(latitudes=latitudes,
113                                  longitudes=longitudes,
114                                  geo_reference=geo_reference,
115                                  data_points=data_points,
116                                  points_are_lats_longs=points_are_lats_longs)
117            self.check_data_points(data_points)
118            self.set_attributes(attributes)
119            self.set_geo_reference(geo_reference)
120            self.set_default_attribute_name(default_attribute_name)
121
122        else:
123###                data = {}   
124                # watch for case where file name and points, attributes etc are provided!!
125                # if file name then all provided info will be removed!
126                self.import_points_file(file_name, delimiter, verbose)
127               
128                self.check_data_points(self.data_points)
129                self.set_attributes(self.attributes)
130                self.set_geo_reference(self.geo_reference)
131                self.set_default_attribute_name(default_attribute_name)
132
133    def __len__(self):
134        return len(self.data_points)
135   
136    def check_data_points(self, data_points):
137        """Checks data points
138        """
139       
140        if data_points is None:
141            self.data_points = None
142            msg = 'There is no data or file provided!'
143            raise ValueError, msg
144           
145        else:
146            self.data_points = ensure_numeric(data_points)
147            assert len(self.data_points.shape) == 2
148            assert self.data_points.shape[1] == 2
149
150    def set_attributes(self, attributes):
151        """Check and assign attributes dictionary
152        """
153       
154        from types import DictType
155       
156        if attributes is None:
157            self.attributes = None
158            return
159       
160        if not isinstance(attributes, DictType):
161            #Convert single attribute into dictionary
162            attributes = {'attribute': attributes}
163
164        #Check input attributes   
165        for key in attributes.keys():
166            try:
167                attributes[key] = ensure_numeric(attributes[key])
168            except:
169                msg = 'Attribute %s could not be converted' %key
170                msg += 'to a numeric vector'
171                raise msg
172
173        self.attributes = attributes   
174
175
176    def set_geo_reference(self, geo_reference):
177
178        from coordinate_transforms.geo_reference import Geo_reference
179
180        if geo_reference is None:
181            geo_reference = Geo_reference() # Use default
182        if not isinstance(geo_reference, Geo_reference):
183            msg = 'Argument geo_reference must be a valid Geo_reference \n'
184            msg += 'object or None.'
185            raise msg
186
187        # if a geo ref already exists, change the point data to
188        # represent the new geo-ref
189        if  self.geo_reference is not None:
190            #FIXME: Maybe put out a warning here...
191            self.data_points = self.get_data_points \
192                               (geo_reference=geo_reference)
193           
194        self.geo_reference = geo_reference
195
196
197    def set_default_attribute_name(self, default_attribute_name):
198        self.default_attribute_name = default_attribute_name
199
200    def set_verbose(self, verbose = False):
201        if verbose is not False:
202            verbose = True
203        else:
204            verbose = False
205   
206    def _set_using_lat_long(self,
207                            latitudes,
208                            longitudes,
209                            geo_reference,
210                            data_points,
211                            points_are_lats_longs):
212        if geo_reference is not None:
213            msg = """A georeference is specified yet latitude and longitude
214            are also specified!"""
215            raise ValueError, msg
216        if data_points is not None and not points_are_lats_longs:
217            msg = """Data points are specified yet latitude and
218            longitude are also specified!"""
219            raise ValueError, msg
220       
221        if points_are_lats_longs:
222            if data_points is None:
223                msg = """Data points are not specified !"""
224                raise ValueError, msg
225            lats_longs = ensure_numeric(data_points)
226            latitudes = ravel(lats_longs[:,0:1])
227            longitudes = ravel(lats_longs[:,1:])
228           
229        if latitudes is None and longitudes is None:
230            msg = """Latitudes and Longitudes are not."""
231            raise ValueError, msg
232       
233        if latitudes is None:
234            msg = """Longitudes are specified yet latitudes aren't!"""
235            raise ValueError, msg
236       
237        if longitudes is None:
238            msg = """Latitudes are specified yet longitudes aren't!"""
239            raise ValueError, msg
240       
241        zone, data_points = convert_lats_longs(latitudes, longitudes)
242       
243        return data_points, Geo_reference(zone=zone)
244   
245    def get_geo_reference(self):
246        return self.geo_reference
247       
248    def get_data_points(self, absolute = True, geo_reference=None):
249        """Get coordinates for all data points as an Nx2 array
250
251        If absolute is True absolute UTM coordinates are returned otherwise
252        returned coordinates are relative to the internal georeference's
253        xll and yll corners.
254
255        If a geo_reference is passed the points are returned relative
256        to that geo_reference.
257
258        Default: absolute is True.
259        """
260
261        if absolute is True and geo_reference is None:
262            return self.geo_reference.get_absolute(self.data_points)
263        elif geo_reference is not None:
264            return geo_reference.change_points_geo_ref \
265                               (self.data_points, 
266                                self.geo_reference)
267        else:
268            return self.data_points
269       
270   
271    def get_attributes(self, attribute_name = None):
272        """Return values for one named attribute.
273
274        If attribute_name is None, default_attribute_name is used
275        """
276
277        if attribute_name is None:
278            if self.default_attribute_name is not None:
279                attribute_name = self.default_attribute_name
280            else:
281                attribute_name = self.attributes.keys()[0] 
282                # above line takes the first one from keys
283               
284
285        msg = 'Attribute name %s does not exist in data set' %attribute_name
286        assert self.attributes.has_key(attribute_name), msg
287
288        return self.attributes[attribute_name]
289
290    def get_all_attributes(self):
291        """
292        Return values for all attributes.
293        """
294
295        return self.attributes
296
297    def __add__(self, other):
298        """
299        Returns the addition of 2 geospatical objects,
300        objects are concatencated to the end of each other
301           
302        NOTE: doesn't add if objects contain different
303        attributes 
304       
305        Always return relative points!
306        """
307
308        # find objects zone and checks if the same
309        geo_ref1 = self.get_geo_reference()
310        zone1 = geo_ref1.get_zone()
311       
312        geo_ref2 = other.get_geo_reference()
313        zone2 = geo_ref2.get_zone()
314
315        geo_ref1.reconcile_zones(geo_ref2)
316
317
318        # sets xll and yll as the smallest from self and other
319        # FIXME (Duncan and Ole): use lower left corner derived from absolute coordinates
320        if self.geo_reference.xllcorner <= other.geo_reference.xllcorner:
321            xll = self.geo_reference.xllcorner
322        else:
323            xll = other.geo_reference.xllcorner
324
325        if self.geo_reference.yllcorner <= other.geo_reference.yllcorner:
326            yll = self.geo_reference.yllcorner
327        else:
328            yll = other.geo_reference.yllcorner
329        new_geo_ref = Geo_reference(geo_ref1.get_zone(), xll, yll)
330
331        xll = yll = 0. 
332       
333        relative_points1 = self.get_data_points(absolute = False)
334        relative_points2 = other.get_data_points(absolute = False)
335
336       
337        new_relative_points1 = new_geo_ref.change_points_geo_ref(relative_points1, geo_ref1)
338        new_relative_points2 = new_geo_ref.change_points_geo_ref(relative_points2, geo_ref2)
339       
340        #Now both point sets are relative to new_geo_ref and zones have been reconciled
341
342        # Concatenate points
343        new_points = concatenate((new_relative_points1,
344                                  new_relative_points2),
345                                  axis = 0)
346     
347        # Concatenate attributes
348        new_attributes = {}
349        for x in self.attributes.keys():
350            if other.attributes.has_key(x):
351
352                attrib1 = self.attributes[x]
353                attrib2 = other.attributes[x]
354                new_attributes[x] = concatenate((attrib1, attrib2))
355
356            else:
357                msg = 'Both geospatial_data objects must have the same \n'
358                msg += 'attributes to allow addition.'
359                raise msg
360
361        # Instantiate new data object and return   
362        return Geospatial_data(new_points,
363                               new_attributes,
364                               new_geo_ref)
365   
366    ###
367    #  IMPORT/EXPORT POINTS FILES
368    ###
369
370    def import_points_file(self, file_name, delimiter = None, verbose = False):
371        """ load an .xya or .pts file
372        Note: will throw an IOError if it can't load the file.
373        Catch these!
374        """
375       
376        if access(file_name, F_OK) == 0 :
377            msg = 'File %s does not exist or is not accessible' %file_name
378            raise IOError, msg
379       
380        attributes = {}
381        if file_name[-4:]== ".xya":
382            try:
383                if delimiter == None:
384                    try:
385                        fd = open(file_name)
386                        data_points, attributes, geo_reference = _read_xya_file(fd, ',')
387                    except TitleError:
388                        fd.close()
389                        fd = open(file_name)
390                        data_points, attributes, geo_reference = _read_xya_file(fd, ' ')
391                else:
392                    fd = open(file_name)
393                    data_points, attributes, geo_reference = _read_xya_file(fd, delimiter)
394                fd.close()
395            except (IndexError,ValueError,SyntaxError):
396                fd.close()   
397                msg = 'Could not open file %s ' %file_name
398                raise IOError, msg
399            except IOError, e:
400                fd.close() 
401                # Catch this to add an error message
402                msg = 'Could not open file or incorrect file format %s:%s' %(file_name, e)
403                raise IOError, msg
404               
405        elif file_name[-4:]== ".pts":
406            try:
407                data_points, attributes, geo_reference = _read_pts_file(file_name, verbose)
408            except IOError, e:   
409                msg = 'Could not open file %s ' %file_name
410                raise IOError, msg       
411        else:     
412            msg = 'Extension %s is unknown' %file_name[-4:]
413            raise IOError, msg
414       
415#        print'in import data_points', data_points
416#        print'in import attributes', attributes
417#        print'in import data_points', geo_reference
418        self.data_points = data_points
419        self.attributes = attributes
420        self.geo_reference = geo_reference
421   
422#        return all_data
423   
424    def export_points_file(self, file_name, absolute=True):
425       
426        """
427        write a points file, file_name, as a text (.xya) or binary (.pts) file
428        file_name is the file name, including the extension
429        The point_dict is defined at the top of this file.
430       
431        If absolute is True data points at returned added to the xll and yll
432        and geo_reference as None
433       
434        If absolute is False data points at returned as relative to the xll
435        and yll and geo_reference remains uneffected
436        """
437   
438        if (file_name[-4:] == ".xya"):
439            if absolute is True:         
440                _write_xya_file(file_name, self.get_data_points(absolute=True), 
441                                   self.get_all_attributes())
442            else:
443                _write_xya_file(file_name, self.get_data_points(absolute=False), 
444                                   self.get_all_attributes(),
445                                   self.get_geo_reference())
446                                   
447        elif (file_name[-4:] == ".pts"):
448            if absolute is True:
449                _write_pts_file(file_name, self.get_data_points(absolute), 
450                                   self.get_all_attributes())
451            else:
452                _write_pts_file(file_name, self.get_data_points(absolute), 
453                                   self.get_all_attributes(),
454                                   self.get_geo_reference())
455        else:
456            msg = 'Unknown file type %s ' %file_name
457            raise IOError, msg
458   
459
460
461
462def _read_pts_file(file_name, verbose = False):
463    """Read .pts NetCDF file
464   
465    Return a dic of array of points, and dic of array of attribute
466    eg
467    dic['points'] = [[1.0,2.0],[3.0,5.0]]
468    dic['attributelist']['elevation'] = [[7.0,5.0]
469    """   
470
471    from Scientific.IO.NetCDF import NetCDFFile
472   
473    if verbose: print 'Reading ', file_name
474   
475       
476    # see if the file is there.  Throw a QUIET IO error if it isn't
477    fd = open(file_name,'r')
478    fd.close()
479   
480    #throws prints to screen if file not present
481    fid = NetCDFFile(file_name, 'r') 
482   
483#    point_atts = {} 
484        # Get the variables
485#    point_atts['pointlist'] = array(fid.variables['points'])
486    pointlist = array(fid.variables['points'])
487    keys = fid.variables.keys()
488    if verbose: print 'Got %d variables: %s' %(len(keys), keys)
489    try:
490        keys.remove('points')
491    except IOError, e:       
492        fid.close()   
493        msg = 'Expected keyword "points" but could not find it'
494        raise IOError, msg
495   
496    attributes = {}
497    for key in keys:
498        if verbose: print "reading attribute '%s'" %key
499           
500        attributes[key] = array(fid.variables[key])
501   
502#    point_atts['attributelist'] = attributes
503   
504    try:
505        geo_reference = Geo_reference(NetCDFObject=fid)
506#        point_atts['geo_reference'] = geo_reference
507    except AttributeError, e:
508        #geo_ref not compulsory
509#        point_atts['geo_reference'] = None
510        geo_reference = None
511   
512    fid.close()
513   
514    return pointlist, attributes, geo_reference
515
516
517def _read_xya_file( fd, delimiter):
518    points = []
519    pointattributes = []
520    title = fd.readline()
521    att_names = clean_line(title,delimiter)
522    att_dict = {}
523    line = fd.readline()
524    numbers = clean_line(line,delimiter)
525   
526    while len(numbers) > 1 and line[0] <> '#':
527        if numbers != []:
528            try:
529                x = float(numbers[0])
530                y = float(numbers[1])
531                points.append([x,y])
532                numbers.pop(0)
533                numbers.pop(0)
534                if len(att_names) != len(numbers):
535                    fd.close()
536                    # It might not be a problem with the title
537                    #raise TitleAmountError
538                    raise IOError
539                for i,num in enumerate(numbers):
540                    num.strip()
541                    if num != '\n' and num != '':
542                        #attributes.append(float(num))
543                        att_dict.setdefault(att_names[i],[]).append(float(num))
544            except ValueError:
545                raise SyntaxError
546        line = fd.readline()
547        numbers = clean_line(line,delimiter)
548   
549    if line == '':
550        geo_reference = None
551    else:
552        geo_reference = Geo_reference(ASCIIFile=fd,read_title=line)
553       
554   
555    pointlist = array(points).astype(Float)
556    for key in att_dict.keys():
557        att_dict[key] = array(att_dict[key]).astype(Float)
558   
559    return pointlist, att_dict, geo_reference
560
561def _write_pts_file(file_name, write_data_points,
562                                   write_attributes, 
563                                   write_geo_reference = None):
564    """
565    Write .pts NetCDF file   
566
567    NOTE: Below might not be valid ask Duncan : NB 5/2006
568   
569    WARNING: This function mangles the point_atts data structure
570    #F??ME: (DSG)This format has issues.
571    # There can't be an attribute called points
572    # consider format change
573    # method changed by NB not sure if above statement is correct
574   
575    should create new test for this
576    legal_keys = ['pointlist', 'attributelist', 'geo_reference']
577    for key in point_atts.keys():
578        msg = 'Key %s is illegal. Valid keys are %s' %(key, legal_keys)
579        assert key in legal_keys, msg
580    """   
581    from Scientific.IO.NetCDF import NetCDFFile
582    # NetCDF file definition
583    outfile = NetCDFFile(file_name, 'w')
584   
585    #Create new file
586    outfile.institution = 'Geoscience Australia'
587    outfile.description = 'NetCDF format for compact and portable storage ' +\
588                      'of spatial point data'
589   
590    # dimension definitions
591    shape = write_data_points.shape[0]
592    outfile.createDimension('number_of_points', shape) 
593    outfile.createDimension('number_of_dimensions', 2) #This is 2d data
594   
595    # variable definition
596    outfile.createVariable('points', Float, ('number_of_points',
597                                             'number_of_dimensions'))
598
599    #create variables 
600    outfile.variables['points'][:] = write_data_points #.astype(Float32)
601
602    for key in write_attributes.keys():
603        outfile.createVariable(key, Float, ('number_of_points',))
604        outfile.variables[key][:] = write_attributes[key] #.astype(Float32)
605       
606    if write_geo_reference is not None:
607        write_geo_reference.write_NetCDF(outfile)
608       
609    outfile.close() 
610 
611
612
613def _write_xya_file( file_name, write_data_points,
614                                    write_attributes, 
615                                    write_geo_reference = None, 
616                                    delimiter = ','):
617    """
618    export a file, file_name, with the xya format
619   
620    """
621    points = write_data_points
622    pointattributes = write_attributes
623   
624    fd = open(file_name,'w')
625    titlelist = ""
626    for title in pointattributes.keys():
627        titlelist = titlelist + title + delimiter
628    titlelist = titlelist[0:-len(delimiter)] # remove the last delimiter
629    fd.write(titlelist+"\n")
630    #<vertex #> <x> <y> [attributes]
631    for i,vert in enumerate( points):
632       
633        attlist = ","
634        for att in pointattributes.keys():
635            attlist = attlist + str(pointattributes[att][i])+ delimiter
636        attlist = attlist[0:-len(delimiter)] # remove the last delimiter
637        attlist.strip()
638        fd.write( str(vert[0]) + delimiter
639                  + str(vert[1])
640                  + attlist + "\n")
641
642    if  write_geo_reference is not None:
643        write_geo_reference.write_ASCII(fd)
644    fd.close()
645
646
647   
648def _point_atts2array(point_atts):
649    point_atts['pointlist'] = array(point_atts['pointlist']).astype(Float)
650   
651    for key in point_atts['attributelist'].keys():
652        point_atts['attributelist'][key]= array(point_atts['attributelist'][key]).astype(Float)
653    return point_atts
654
655   
656
657
658def geospatial_data2points_dictionary(geospatial_data):
659    """Convert geospatial data to points_dictionary
660    """
661
662    points_dictionary = {}
663    points_dictionary['pointlist'] = geospatial_data.data_points
664
665    points_dictionary['attributelist'] = {}
666
667    for attribute_name in geospatial_data.attributes.keys():
668        val = geospatial_data.attributes[attribute_name]
669        points_dictionary['attributelist'][attribute_name] = val
670
671    points_dictionary['geo_reference'] = geospatial_data.geo_reference
672
673    return points_dictionary
674
675   
676def points_dictionary2geospatial_data(points_dictionary):
677    """Convert points_dictionary to geospatial data object
678    """
679
680    msg = 'Points dictionary must have key pointlist' 
681    assert points_dictionary.has_key('pointlist'), msg
682
683    msg = 'Points dictionary must have key attributelist'     
684    assert points_dictionary.has_key('attributelist'), msg       
685
686    if points_dictionary.has_key('geo_reference'):
687        geo = points_dictionary['geo_reference']
688    else:
689        geo = None
690   
691    return Geospatial_data(points_dictionary['pointlist'],
692                           points_dictionary['attributelist'],
693                           geo_reference = geo)
694
695def clean_line(line,delimiter):     
696    """Remove whitespace
697    """
698    #print ">%s" %line
699    line = line.strip()
700    #print "stripped>%s" %line
701    numbers = line.split(delimiter)
702    i = len(numbers) - 1
703    while i >= 0:
704        if numbers[i] == '':
705            numbers.pop(i)
706        else:
707            numbers[i] = numbers[i].strip()
708       
709        i += -1
710    #for num in numbers:
711    #    print "num>%s<" %num
712    return numbers
713           
714def xxx_add_points_files(add_file1, add_file2, results_file):
715    """ adds the points and attruibutes of 2 pts or xya files and
716    writes it to a pts file
717   
718    NOTE will add the function to check and remove points from one set
719    that are shared. This will require some work and maybe __subtract__ function
720    """
721   
722    G1 = Geospatial_data(file_name = add_file1)
723    G2 = Geospatial_data(file_name = add_file2)
724    new_add_file2 = add_file2[:-4] + '.pts' 
725
726    G = G1 + G2
727   
728    #FIXME remove dependance on points to dict in export only!
729#    G_points_dict = geospatial_data2points_dictionary(G)
730#    export_points_file(results_file, G_points_dict)
731
732#    G_points_dict = geospatial_data2points_dictionary(G)
733
734    G.export_points_file(results_file)
735
736# '
737def ensure_absolute(points, geo_reference = None):
738    """
739    This function inputs several formats and
740    outputs one format. - a numeric array of absolute points.
741
742    Inputed formats are;
743    points: List or numeric array of coordinate pairs [xi, eta] of
744              points or geospatial object or points file name
745
746    mesh_origin: A geo_reference object or 3-tuples consisting of
747                 UTM zone, easting and northing.
748                 If specified vertex coordinates are assumed to be
749                 relative to their respective origins.
750    """
751    if isinstance(points,type('')):
752        #It's a string
753        #assume it is a point file
754        points = Geospatial_data(file_name = points)
755       
756    if isinstance(points,Geospatial_data):
757        points = points.get_data_points( \
758                absolute = True)
759        msg = "Use a Geospatial_data object or a mesh origin. Not both."
760        assert geo_reference == None, msg
761           
762    else:
763        points = ensure_numeric(points, Float)
764    if geo_reference is None:
765        geo = None #Geo_reference()
766    else:
767        if isinstance(geo_reference, Geo_reference):
768            geo = geo_reference
769        else:
770            geo = Geo_reference(geo_reference[0],
771                                geo_reference[1],
772                                geo_reference[2])
773        points = geo.get_absolute(points)
774    return points
775     
776
777def ensure_geospatial(points, geo_reference = None):
778    """
779    This function inputs several formats and
780    outputs one format. - a geospatial_data instance.
781
782    Inputed formats are;
783    points: List or numeric array of coordinate pairs [xi, eta] of
784              points or geospatial object
785
786    mesh_origin: A geo_reference object or 3-tuples consisting of
787                 UTM zone, easting and northing.
788                 If specified vertex coordinates are assumed to be
789                 relative to their respective origins.
790    """
791    if isinstance(points,Geospatial_data):
792        msg = "Use a Geospatial_data object or a mesh origin. Not both."
793        assert geo_reference == None, msg
794           
795    else:
796        points = ensure_numeric(points, Float)
797    if geo_reference is None:
798        geo = None
799    else:
800        if isinstance(geo_reference, Geo_reference):
801            geo = geo_reference
802        else:
803            geo = Geo_reference(geo_reference[0],
804                                geo_reference[1],
805                                geo_reference[2])
806        points = Geospatial_data(data_points=points, geo_reference=geo)       
807    return points
808             
Note: See TracBrowser for help on using the repository browser.