~ubuntu-branches/ubuntu/trusty/liblas/trusty-proposed

« back to all changes in this revision

Viewing changes to python/liblas/point.py

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2014-01-05 17:00:29 UTC
  • mfrom: (7.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20140105170029-ddtp0j63x5jvck2u
Tags: 1.7.0+dfsg-2
Fixed missing linking of system boost component.
(closes: #733282)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
/******************************************************************************
 
3
 * $Id$
 
4
 *
 
5
 * Project:  libLAS - http://liblas.org - A BSD library for LAS format data.
 
6
 * Purpose:  Python Point implementation
 
7
 * Author:   Howard Butler, hobu.inc@gmail.com
 
8
 *
 
9
 ******************************************************************************
 
10
 * Copyright (c) 2009, Howard Butler
 
11
 *
 
12
 * All rights reserved.
 
13
 *
 
14
 * Redistribution and use in source and binary forms, with or without
 
15
 * modification, are permitted provided that the following
 
16
 * conditions are met:
 
17
 *
 
18
 *     * Redistributions of source code must retain the above copyright
 
19
 *       notice, this list of conditions and the following disclaimer.
 
20
 *     * Redistributions in binary form must reproduce the above copyright
 
21
 *       notice, this list of conditions and the following disclaimer in
 
22
 *       the documentation and/or other materials provided
 
23
 *       with the distribution.
 
24
 *     * Neither the name of the Martin Isenburg or Iowa Department
 
25
 *       of Natural Resources nor the names of its contributors may be
 
26
 *       used to endorse or promote products derived from this software
 
27
 *       without specific prior written permission.
 
28
 *
 
29
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
30
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
31
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 
32
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 
33
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 
34
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 
35
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 
36
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 
37
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 
38
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 
39
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 
40
 * OF SUCH DAMAGE.
 
41
 ****************************************************************************/
 
42
 """
 
43
 
 
44
import core
 
45
import datetime
 
46
import time
 
47
import math
 
48
import color
 
49
import ctypes
 
50
 
 
51
import header
 
52
 
 
53
class Point(object):
 
54
    def __init__(self, owned=True, handle=None, copy=False):
 
55
        """Instantiates a :obj:`liblas.point.Point` object.  If you are \
 
56
        creating and working with your own instances, you should normally \
 
57
        not need to use any of the parameters.
 
58
 
 
59
        :param owned: boolean
 
60
            A flag to denote whether or not the point owns itself and can
 
61
            destroy itself upon going out of scope. There are instances where
 
62
            :obj:`liblas.file.File` may actually own the point as it is read
 
63
            from or written to files.
 
64
 
 
65
        :param handle: ctypes object reference
 
66
            A handle to an existing ctypes LASPointH object reference. Only
 
67
            internal liblas code should have to worry about using this.
 
68
 
 
69
        :param copy: boolean
 
70
            A flag to denote whether or not to copy the point upon creation.
 
71
            Used in coordination with the :obj:`handle` parameter, and it
 
72
            should not normally be used.
 
73
 
 
74
        :rtype: :obj:`liblas.point.Point` object
 
75
        """
 
76
        if handle:
 
77
            if copy:
 
78
                self.handle = core.las.LASPoint_Copy(handle)
 
79
                self._owned = True
 
80
            else:
 
81
                self.handle = handle
 
82
                self._owned = False
 
83
        else:
 
84
            self.handle = core.las.LASPoint_Create()
 
85
            self._owned = True
 
86
 
 
87
    def __del__(self):
 
88
        if self._owned:
 
89
            if self.handle and core:
 
90
                core.las.LASPoint_Destroy(self.handle)
 
91
 
 
92
    def get_x(self):
 
93
        return core.las.LASPoint_GetX(self.handle)
 
94
 
 
95
    def set_x(self, value):
 
96
        """Sets the X coordinate of the LAS point to a floating point
 
97
        value. 
 
98
        
 
99
        ..note:: 
 
100
            The point will be descaled according to the :obj:`liblas.point.Point.header`'s  
 
101
            scale value for the X dimension.
 
102
        """
 
103
 
 
104
        return core.las.LASPoint_SetX(self.handle, value)
 
105
 
 
106
    doc = """X coordinate of the LAS point as a double (scale applied).
 
107
 
 
108
    .. note::
 
109
        Use obj:`liblas.point.Point.raw_x` if you want the unscaled ``x`` data.
 
110
    """
 
111
 
 
112
    def get_raw_x(self):
 
113
        return core.las.LASPoint_GetRawX(self.handle)
 
114
 
 
115
    def set_raw_x(self, value):
 
116
        """Sets the X coordinate of the LAS point to an integer value
 
117
        value. 
 
118
        
 
119
        ..note:: 
 
120
            The point will be scaled according to the obj:`liblas.point.Point.header`'s 
 
121
            scale value for the X dimension when returned as a double obj:`liblas.point.Point.x`.
 
122
        """
 
123
        return core.las.LASPoint_SetRawX(self.handle, value)
 
124
 
 
125
    doc = """The raw X coordinate of the point without its header's scaling
 
126
            applied.
 
127
 
 
128
    .. note::
 
129
        Use obj:`liblas.point.Point.x` if you want the scaled ``x`` data.
 
130
    """
 
131
    raw_x = property(get_raw_x, set_raw_x, None, doc)
 
132
 
 
133
    x = property(get_x, set_x, None, doc)
 
134
 
 
135
    def get_y(self):
 
136
        return core.las.LASPoint_GetY(self.handle)
 
137
 
 
138
    def set_y(self, value):
 
139
        """Sets the Y coordinate of the LAS point to a floating point
 
140
        value. 
 
141
        
 
142
        ..note:: 
 
143
            The point will be descaled according to the :obj:`liblas.point.Point.header`'s 
 
144
            scale value for the Y dimension.
 
145
        """
 
146
        return core.las.LASPoint_SetY(self.handle, value)
 
147
 
 
148
    doc = """Y coordinate of the LAS point as a double (scale applied).
 
149
 
 
150
    .. note::
 
151
        Use obj:`liblas.point.Point.raw_y` if you want the unscaled ``y`` data.
 
152
    """
 
153
 
 
154
    y = property(get_y, set_y, None, doc)
 
155
 
 
156
    def get_raw_y(self):
 
157
        return core.las.LASPoint_GetRawY(self.handle)
 
158
 
 
159
    def set_raw_y(self, value):
 
160
        """Sets the Y coordinate of the LAS point to an integer value
 
161
        value. 
 
162
        
 
163
        ..note:: 
 
164
            The point will be scaled according to the obj:`liblas.point.Point.header`'s 
 
165
            scale value for the Y dimension when returned as a double obj:`liblas.point.Point.y`.
 
166
        """
 
167
        return core.las.LASPoint_SetRawY(self.handle, value)
 
168
 
 
169
    doc = """The raw Y coordinate of the point without its header's scaling
 
170
            applied.
 
171
 
 
172
    .. note::
 
173
        Use obj:`liblas.point.Point.y` if you want the scaled ``y`` data.
 
174
    """
 
175
    raw_y = property(get_raw_y, set_raw_y, None, doc)
 
176
 
 
177
    def get_z(self):
 
178
        return core.las.LASPoint_GetZ(self.handle)
 
179
 
 
180
    def set_z(self, value):
 
181
        """Sets the Z coordinate of the LAS point to a floating point
 
182
        value. 
 
183
        
 
184
        ..note:: 
 
185
            The point will be descaled according to the obj:`liblas.point.Point.header`'s 
 
186
            scale value for the Z dimension.
 
187
        """
 
188
        return core.las.LASPoint_SetZ(self.handle, value)
 
189
 
 
190
    doc = """Z coordinate of the LAS point as a double (scale applied).
 
191
 
 
192
    .. note::
 
193
        Use obj:`liblas.point.Point.raw_z` if you want the unscaled ``z`` data.
 
194
    """
 
195
    z = property(get_z, set_z, None, doc)
 
196
 
 
197
    def get_raw_z(self):
 
198
        return core.las.LASPoint_GetRawZ(self.handle)
 
199
 
 
200
    def set_raw_z(self, value):
 
201
        """Sets the Z coordinate of the LAS point to an integer value
 
202
        value. 
 
203
        
 
204
        ..note:: 
 
205
            The point will be scaled according to the obj:`liblas.point.Point.header`'s 
 
206
            scale value for the Z dimension when returned as a double obj:`liblas.point.Point.y`.
 
207
        """
 
208
        return core.las.LASPoint_SetRawZ(self.handle, value)
 
209
 
 
210
    doc = """The raw Z coordinate of the point without its header's scaling
 
211
            applied.
 
212
 
 
213
    .. note::
 
214
        Use obj:`liblas.point.Point.z` if you want the scaled ``z`` data.
 
215
    """
 
216
    raw_z = property(get_raw_z, set_raw_z, None, doc)
 
217
    
 
218
    def get_return_number(self):
 
219
        """Returns the return number of the point"""
 
220
        return core.las.LASPoint_GetReturnNumber(self.handle)
 
221
 
 
222
    def set_return_number(self, value):
 
223
        """Sets the return number of the point to an integer"""
 
224
        core.las.LASPoint_SetReturnNumber(self.handle, value)
 
225
    doc = """The pulse return number for a given laser pulse.
 
226
 
 
227
    From the specification_:
 
228
 
 
229
        The Return Number is the pulse return number for a given output pulse.
 
230
        A given output laser pulse can have many returns, and they must be
 
231
        marked in sequence of return. The first return will have a Return
 
232
        Number of one, the second a Return Number of two, and so on up to five
 
233
        returns.
 
234
    """
 
235
    return_number = property(get_return_number, set_return_number, None, doc)
 
236
 
 
237
    def get_number_of_returns(self):
 
238
        """Returns the number of returns for the point"""
 
239
        return core.las.LASPoint_GetNumberOfReturns(self.handle)
 
240
 
 
241
    def set_number_of_returns(self, value):
 
242
        """Sets the number of returns for the point"""
 
243
        core.las.LASPoint_SetNumberOfReturns(self.handle, value)
 
244
    doc = """The number of returns for a given laser pulse.
 
245
 
 
246
    From the specification_:
 
247
 
 
248
        The Number of Returns is the total number of returns for a given
 
249
        pulse. For example, a laser data point may be return two (Return
 
250
        Number) within a total number of five returns.
 
251
    """
 
252
    number_of_returns = property(get_number_of_returns,
 
253
                                 set_number_of_returns,
 
254
                                 None,
 
255
                                 doc)
 
256
 
 
257
    def get_scan_direction(self):
 
258
        """Returns the scan direction for the point"""
 
259
        return core.las.LASPoint_GetScanDirection(self.handle)
 
260
 
 
261
    def set_scan_direction(self, value):
 
262
        """Sets the scan direction as an integer for the point"""
 
263
        core.las.LASPoint_SetScanDirection(self.handle, value)
 
264
    doc = """Scan direction for the point
 
265
 
 
266
    From the specification_:
 
267
 
 
268
        The Scan Direction Flag denotes the direction at which the scanner
 
269
        mirror was traveling at the time of the output pulse. A bit value of 1
 
270
        is a positive scan direction, and a bit value of 0 is a negative scan
 
271
        direction (where positive scan direction is a scan moving from the
 
272
        left side of the in-track direction to the right side and negative the
 
273
        opposite).
 
274
 
 
275
    """
 
276
    scan_direction = property(get_scan_direction,
 
277
                              set_scan_direction,
 
278
                              None,
 
279
                              doc)
 
280
 
 
281
    def get_flightline_edge(self):
 
282
        """Denotes whether the point is a flight line edge"""
 
283
        return core.las.LASPoint_GetFlightLineEdge(self.handle)
 
284
 
 
285
    def set_flightline_edge(self, value):
 
286
        """Sets the flightline edge as an integer for the point. Must be 0
 
287
        (not an edge) or 1 (an edge)"""
 
288
        core.las.LASPoint_SetFlightLineEdge(self.handle, value)
 
289
    doc = """Flightline edge flag for the point
 
290
 
 
291
    From the specification_:
 
292
 
 
293
        The Edge of Flight Line data bit has a value of 1 only when the point
 
294
        is at the end of a scan. It is the last point on a given scan line
 
295
        before it changes direction.
 
296
    """
 
297
    flightline_edge = property(get_flightline_edge,
 
298
                               set_flightline_edge,
 
299
                               None,
 
300
                               doc)
 
301
 
 
302
    def get_scan_flags(self):
 
303
        """Returns the raw scan flags for the point.
 
304
        See the LAS 1.0 or 1.1 specification for information how to interpret
 
305
        """
 
306
        return core.las.LASPoint_GetScanFlags(self.handle)
 
307
 
 
308
    def set_scan_flags(self, value):
 
309
        """Sets the raw scan flags for the point. See the LAS 1.0 or 1.1
 
310
        specification for information how to interpret or use the convenience
 
311
        functions like flightline_edge, scan_direction, etc.
 
312
        """
 
313
        core.las.LASPoint_SetScanFlags(self.handle, value)
 
314
    doc = """Scan flags for the point. This is a combination of the
 
315
    :obj:`flightline_edge` \ :obj:`return_number` :obj:`number_of_returns` and
 
316
    :obj:`scan_direction`. Use the individual methods for setting these values
 
317
    for convenience.
 
318
    """
 
319
    scan_flags = property(get_scan_flags, set_scan_flags, None, doc)
 
320
 
 
321
    def get_classification(self):
 
322
        return core.las.LASPoint_GetClassification(self.handle)
 
323
 
 
324
    def set_classification(self, value):
 
325
        core.las.LASPoint_SetClassification(self.handle, value)
 
326
    doc = """The point's classification as a raw byte value.
 
327
 
 
328
        The following large section of information is verboten from the
 
329
        specification_ for your convenience:
 
330
 
 
331
        This filed represents the "class" attributes of a point. If a point
 
332
        has never been classified, this byte must be set to zero. There are no
 
333
        user defined classes since all point formats 0 supply 8 bits per point
 
334
        for user defined operations.
 
335
 
 
336
        .. csv-table:: Classification Bit Field Encoding
 
337
            :header: "Bits", "Field Name", "Description"
 
338
            :widths: 5, 15, 60
 
339
 
 
340
            0:4, "Classification", "Standard ASPRS classification as defined
 
341
            in the following classification table."
 
342
            5, "Synthetic", "If set then this point was created by a technique
 
343
            other than LIDAR collection such as digitized from a
 
344
            photogrammetric stereo model or by traversing a waveform."
 
345
            6, "Key-point", "If set, this point is considered to be a model
 
346
            key- point and thus generally should not be withheld in a thinning
 
347
            algorithm."
 
348
            7, "Witheld", "If set, this point should not be included in
 
349
            processing (synonymous with Deleted)."
 
350
 
 
351
        .. note::
 
352
            Bits 5, 6 and 7 are treated as flags and can be set or clear in
 
353
            any combination. For example, a point with bits 5 and 6 both set
 
354
            to one and the lower five bits set to 2 (see table below) would be
 
355
            a ground point that had been Synthetically collected and marked as
 
356
            a model key-point.
 
357
 
 
358
        .. csv-table:: ASPRS Standard LiDAR Point Classes
 
359
            :header: "Classification", "Meaning"
 
360
            :widths: 20, 60
 
361
 
 
362
            0, "Created, never classified"
 
363
            1, "Unclassified"
 
364
            2, "Ground"
 
365
            3, "Low Vegetation"
 
366
            4, "Medium Vegetation"
 
367
            5, "High Vegetation"
 
368
            6, "Building"
 
369
            7, "Low Point (noise)"
 
370
            8, "Model Key-point (mass point)"
 
371
            9, "Water"
 
372
            10, "Reserved for ASPRS Definition"
 
373
            11, "Reserved for ASPRS Definition"
 
374
            12, "Overlap Points"
 
375
            13-31, "Reserved for ASPRS Definition"
 
376
 
 
377
        .. note::
 
378
            We are using both 0 and 1 as Unclassified to maintain
 
379
            compatibility with current popular classification software such as
 
380
            TerraScan. We extend the idea of classification value 1 to include
 
381
            cases in which data have been subjected to a classification
 
382
            algorithm but emerged in an undefined state. For example, data
 
383
            with class 0 is sent through an algorithm to detect man-made
 
384
            structures -- points that emerge without having been assigned as
 
385
            belonging to structures could be remapped from class 0 to class 1
 
386
 
 
387
        .. note::
 
388
            Overlap Points are those points that were immediately culled
 
389
            during the merging of overlapping flight lines. In general, the
 
390
            Withheld bit should be set since these points are not subsequently
 
391
            classified.
 
392
 
 
393
    """
 
394
    classification = property(get_classification,
 
395
                              set_classification,
 
396
                              None,
 
397
                              doc)
 
398
 
 
399
    def get_scan_angle_rank(self):
 
400
        """Returns the scan angle rank of the point. It will be between -90
 
401
        and 90"""
 
402
        return core.las.LASPoint_GetScanAngleRank(self.handle)
 
403
 
 
404
    def set_scan_angle_rank(self, value):
 
405
        """Sets the scan angle rank of the point. It must be between -90 and
 
406
        90"""
 
407
        core.las.LASPoint_SetScanAngleRank(self.handle, value)
 
408
 
 
409
    doc = """Scan angle of the point.
 
410
 
 
411
    From the specification_:
 
412
        The Scan Angle Rank is a signed one-byte number with a valid range
 
413
        from -90 to +90. The Scan Angle Rank is the angle (rounded to the
 
414
        nearest integer in the absolute value sense) at which the laser point
 
415
        was output from the laser system including the roll of the aircraft.
 
416
        The scan angle is within 1 degree of accuracy from +90 to -90 degrees.
 
417
        The scan angle is an angle based on 0 degrees being nadir, and -90
 
418
        degrees to the left side of the aircraft in the direction of flight.
 
419
    """
 
420
    scan_angle = property(get_scan_angle_rank, set_scan_angle_rank, None, doc)
 
421
 
 
422
    def get_user_data(self):
 
423
        return core.las.LASPoint_GetUserData(self.handle)
 
424
 
 
425
    def set_user_data(self, value):
 
426
        core.las.LASPoint_SetUserData(self.handle, value)
 
427
    doc = """User Data for the point.  This is a single byte of data and \
 
428
    and can be anything the software wants to attach to the point"""
 
429
    user_data = property(get_user_data, set_user_data, None, doc)
 
430
 
 
431
    def get_point_source_id(self):
 
432
        return core.las.LASPoint_GetPointSourceId(self.handle)
 
433
 
 
434
    def set_point_source_id(self, value):
 
435
        core.las.LASPoint_SetUserData(self.handle, value)
 
436
    doc = """Point Source ID for the point.
 
437
 
 
438
    From the specification_:
 
439
 
 
440
        This value indicates the file from which this point originated. Valid
 
441
        values for this field are 1 to 65,535 inclusive with zero being used
 
442
        for a special case discussed below. The numerical value corresponds to
 
443
        the File Source ID from which this point originated. Zero is reserved
 
444
        as a convenience to system implementers. A Point Source ID of zero
 
445
        implies that this point originated in this file. This implies that
 
446
        processing software should set the Point Source ID equal to the File
 
447
        Source ID of the file containing this point at some time during
 
448
        processing.
 
449
        """
 
450
    point_source_id = property(get_user_data, set_user_data, None, doc)
 
451
 
 
452
    def get_intensity(self):
 
453
        return core.las.LASPoint_GetIntensity(self.handle)
 
454
 
 
455
    def set_intensity(self, value):
 
456
        core.las.LASPoint_SetIntensity(self.handle, value)
 
457
    doc = """Intensity value as an short integer for the point
 
458
 
 
459
    From the specification_:
 
460
 
 
461
        The intensity value is the integer representation of the pulse return
 
462
        magnitude. This value is optional and system specific. However, it
 
463
        should always be included if available.
 
464
    """
 
465
    intensity = property(get_intensity, set_intensity, None, doc)
 
466
 
 
467
    def get_time(self):
 
468
        t = core.las.LASPoint_GetTime(self.handle)
 
469
        floor = math.floor(t)
 
470
        ms = float(t) - floor
 
471
 
 
472
        # clip to 999999
 
473
        ms = int(round(ms * 1000000))
 
474
        if ms > 999999:
 
475
            ms = 999999
 
476
 
 
477
        lt = time.gmtime(t)
 
478
        value = datetime.datetime(lt[0], lt[1], lt[2],
 
479
                                  lt[3], lt[4], lt[5], ms)
 
480
        return value
 
481
 
 
482
    def set_time(self, value):
 
483
        t = time.mktime(value.timetuple())
 
484
 
 
485
        ms = value.microsecond
 
486
        t = float(t) + ms * 0.000001
 
487
        core.las.LASPoint_SetTime(self.handle, t)
 
488
 
 
489
    doc = """Interpeted (:class:`datetime.datetime` instance) time value for
 
490
    the point.
 
491
 
 
492
        Example:
 
493
 
 
494
        >>> td = datetime.timedelta(hours=6) # my timezone is -6
 
495
        >>> t = datetime.datetime(2008,3,19) - td
 
496
        >>> p.time = t
 
497
        >>> p.time
 
498
        datetime.datetime(2008, 3, 19, 0, 0)
 
499
 
 
500
        .. note::
 
501
            Because no header is available, no coordination is done with
 
502
            respect to the allowable LAS time types. You must coordinate with
 
503
            the :obj:`liblas.header.Header.global_encoding` to determine the
 
504
            actual time value for the point. If you want to merely preserve
 
505
            existing point data, use :obj:`liblas.point.Point.raw_time`
 
506
 
 
507
        """
 
508
    time = property(get_time, set_time, None, doc)
 
509
 
 
510
    def get_raw_time(self):
 
511
        t = core.las.LASPoint_GetTime(self.handle)
 
512
        return t
 
513
 
 
514
    def set_raw_time(self, value):
 
515
        core.las.LASPoint_SetTime(self.handle, value)
 
516
 
 
517
    doc = """Uninterpeted time value for the point.
 
518
 
 
519
        .. note::
 
520
            Because no header is available, no coordination is done with
 
521
            respect to the allowable LAS time types. You must coordinate with
 
522
            the :obj:`liblas.header.Header.global_encoding` to determine the
 
523
            actual time value for the point. See the ASPRS LAS 1.1-1.3
 
524
            specifications for more detail.
 
525
        """
 
526
    raw_time = property(get_raw_time, set_raw_time, None, doc)
 
527
 
 
528
    def get_color(self):
 
529
        return color.Color(handle=core.las.LASPoint_GetColor(self.handle))
 
530
 
 
531
    def set_color(self, value):
 
532
        return core.las.LASPoint_SetColor(self.handle, value.handle)
 
533
    doc = """Raw color value for the point as an :obj:`liblas.color.Color`
 
534
    instance.
 
535
 
 
536
    .. note::
 
537
        RGB values should always be normalized to 16 bit values. For example,
 
538
        when encoding an 8 bit per channel pixel, multiply each channel value
 
539
        by 256 prior to storage in these fields. This normalization allows
 
540
        color values from different camera bit depths to be accurately merged.
 
541
 
 
542
        """
 
543
    color = property(get_color, set_color, None, doc)
 
544
 
 
545
    def get_header(self):
 
546
        return header.Header(handle=core.las.LASPoint_GetHeader(self.handle))
 
547
    
 
548
    def set_header(self, value):
 
549
        return core.las.LASPoint_SetHeader(self.handle, value.handle)
 
550
    header = property(get_header, set_header, None, None)
 
551
 
 
552
 
 
553
    def get_xml(self):
 
554
        return core.las.LASPoint_GetXML(self.handle)
 
555
        
 
556
    xml = property(get_xml, None, None, None)
 
557
 
 
558
 
 
559
    def get_data(self):
 
560
        length = self.header.data_record_length
 
561
        d = (ctypes.c_ubyte*length)()
 
562
        d2 = ctypes.cast(d, ctypes.POINTER(ctypes.c_ubyte))
 
563
        core.las.LASPoint_GetData(self.handle, d2)
 
564
        return d
 
565
    
 
566
    def set_data(self, data):
 
567
        d = ctypes.cast(data, ctypes.POINTER(ctypes.c_ubyte))
 
568
    
 
569
        core.las.LASPoint_SetData(self.handle, d, len(data))
 
570
    
 
571
    doc = """Raw data for the point. Shoot yourself in the foot if you must!
 
572
    """
 
573
    data = property(get_data, set_data, None, doc)