Skip to content

Commit

Permalink
Python 3. All tests pass.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidcaron committed Mar 21, 2017
1 parent 3dca50f commit 9768be6
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 141 deletions.
2 changes: 1 addition & 1 deletion .gitignore
@@ -1,4 +1,4 @@
laspy.egg-info/
*.pyc
docs/build
build/
build/
8 changes: 4 additions & 4 deletions laspy/base.py
Expand Up @@ -472,8 +472,8 @@ def _read_words(self, fmt, num, bytes):
unpacked = unpacked.decode('ascii')
except UnicodeDecodeError:
# this is often NULs and random data that occurs after the
# ending NUL. Just ignore it.
unpacked = ''
# ending NUL.
unpacked = '\x00'
outData.append(unpacked)
if len(outData) > 1:
return(outData)
Expand Down Expand Up @@ -932,7 +932,7 @@ def set_evlrs(self, value):
self.data_provider.open("w+b")
self.data_provider.fileref.write(dat_part_1)
total_evlrs = sum([len(x) for x in value])
self.data_provider.fileref.write("\x00"*total_evlrs)
self.data_provider.fileref.write(b"\x00"*total_evlrs)
self.data_provider.fileref.close()
self.data_provider.open("r+b")
self.data_provider.map()
Expand Down Expand Up @@ -979,7 +979,7 @@ def set_vlrs(self, value):
for vlr in value:
byte_string = vlr.to_byte_string()
self.data_provider.fileref.write(byte_string)
self.data_provider.fileref.write("\x00"*current_padding)
self.data_provider.fileref.write(b"\x00"*current_padding)
self.data_provider.fileref.write(dat_part_2)
self.data_provider.fileref.close()
self.data_provider.open("r+b")
Expand Down
6 changes: 3 additions & 3 deletions laspy/file.py
Expand Up @@ -85,7 +85,7 @@ def open(self):
## Wire up API for extra dimensions
if self._reader.extra_dimensions != []:
for dimension in self._reader.extra_dimensions:
dimname = dimension.name.replace("\x00", "").replace(" ", "_").lower()
dimname = dimension.name.decode().replace("\x00", "").replace(" ", "_").lower()
self.addProperty(dimname)


Expand All @@ -97,7 +97,7 @@ def open(self):
## Wire up API for any extra Dimensions
if self._writer.extra_dimensions != []:
for dimension in self._writer.extra_dimensions:
dimname = dimension.name.replace("\x00", "").replace(" ", "_").lower()
dimname = dimension.name.decode().replace("\x00", "").replace(" ", "_").lower()
self.addProperty(dimname)
else:
raise util.LaspyException("Headers must currently be stored in the file, you provided: " + str(self._header))
Expand Down Expand Up @@ -125,7 +125,7 @@ def open(self):
## Wire up API for any extra Dimensions
if self._writer.extra_dimensions != []:
for dimension in self._writer.extra_dimensions:
dimname = dimension.name.replace("\x00", "").replace(" ", "_").lower()
dimname = dimension.name.decode().replace("\x00", "").replace(" ", "_").lower()
self.addProperty(dimname)

if self._mode == 'w+':
Expand Down
72 changes: 41 additions & 31 deletions laspy/header.py
Expand Up @@ -52,7 +52,7 @@ def parse_data(self):
print("WARNING: Invalid body length for GeoKeyDictionaryTag, Not parsing.")
self.body_fmt = None
return
for sKeyEntry in xrange(bytes_left/8):
for sKeyEntry in xrange(int(bytes_left/8)):
self.body_fmt.add("wKeyId_%i" % sKeyEntry, "ctypes.c_ushort", 1)
self.body_fmt.add("wTIFFTagLocation_%i" % sKeyEntry, "ctypes.c_ushort", 1)
self.body_fmt.add("wCount_%i" % sKeyEntry, "ctypes.c_ushort", 1)
Expand All @@ -64,40 +64,40 @@ def parse_data(self):
if self.rec_len_after_header % 8 != 0:
print("WARNING: Invalid body length for GeoDoubleParamsTag, not parsing.")
return
for i in xrange(self.rec_len_after_header/8):
for i in xrange(int(self.rec_len_after_header/8)):
self.body_fmt.add("param_%i" % i, "ctypes.c_double", 1)

elif "LASF_Projection" in self.user_id and self.record_id == 34737:
# GeoAsciiParamsTagRecord
self.body_fmt = util.Format(None)
self.body_fmt.add("GeoASCIIParamsTag", "ctypes.c_char", self.rec_len_after_header)

elif "LASF_Spec" in self.user_id and self.record_id == 0:
elif "LASF_Spec" in self.user_id and self.record_id == 0:
# Classification Lookup
self.body_fmt = util.Format(None)
if self.rec_len_after_header % 16 != 0:
print("WARNING: Invalid body length for classification lookup, not parsing.")
return
for i in xrange(self.rec_len_after_header / 16):
for i in xrange(int(self.rec_len_after_header / 16)):
self.body_fmt.add("ClassNumber_%i", "ctypes.c_ubyte", 1)
self.body_fmt.add("Description_%i", "ctypes.c_char", 15)

elif "LASF_Spec" in self.user_id and self.record_id == 1:
elif "LASF_Spec" in self.user_id and self.record_id == 1:
# Header Flight line lookup
self.body_fmt = util.Format(None)
if self.rec_len_after_header % 257 != 0:
print("WARNING: Invalid body length for header flight line lookup, not parsing.")
return
for i in xrange(self.rec_len_after_header / 257):
for i in xrange(int(self.rec_len_after_header / 257)):
self.body_fmt.add("FileMarkerNumber_%i", "ctypes.c_ubyte", 1)
self.body_fmt.add("Filename_%i", "ctypes.c_char", 256)

elif "LASF_Spec" in self.user_id and self.record_id == 3:
elif "LASF_Spec" in self.user_id and self.record_id == 3:
#Text Area Description
self.body_fmt = util.Format(None)
self.body_fmt.add("text_area_description", "ctypes.c_char", self.rec_len_after_header)

elif "LASF_Spec" in self.user_id and self.record_id == 4:
elif "LASF_Spec" in self.user_id and self.record_id == 4:
# Extra Bytes, currently handled by VLR constructor
pass

Expand All @@ -112,7 +112,7 @@ def parse_data(self):
self.body_fmt.add("digitizer_offset", "ctypes.c_double",1)

if self.body_fmt != None:
self.parsed_body = np.array(struct.unpack(self.body_fmt.pt_fmt_long, self.VLR_body))
self.parsed_body = struct.unpack(self.body_fmt.pt_fmt_long, self.VLR_body)
else:
self.parsed_body = None

Expand Down Expand Up @@ -145,7 +145,7 @@ class ExtraBytesStruct(object):
lives in the VLR_body property of a laspy.header.VLR instance, and multiple
ExtraByteStruct records can be present together. Each ExtraBytesStruct instance
describes an additional dimension present at the end of each point record. '''
def __init__(self, data_type = 0, options = 0, name = "\x00"*32,
def __init__(self, data_type = 0, options = 0, name = "\x00"*32,
unused = [0]*4, no_data = [0.0]*3, min = [0.0]*3,
max = [0.0]*3, scale = [1.0]*3, offset = [0.0]*3,
description = "\x00"*32):
Expand All @@ -155,10 +155,10 @@ def __init__(self, data_type = 0, options = 0, name = "\x00"*32,
self.vlr_parent = False
self.names = [x.name for x in self.fmt.specs]

self.data = "\x00"*192
self.data = b"\x00"*192
self.set_property("data_type" , data_type)
self.set_property("options" , options)
self.set_property("name" , name + "\x00"*(32-len(description)))
self.set_property("name" , name + "\x00"*(32-len(name)))
self.set_property("unused" , unused )
self.set_property("no_data" , no_data)
self.set_property("min" , min)
Expand Down Expand Up @@ -205,12 +205,15 @@ def to_byte_string(self):
def set_property(self, name, value):
self.assertWriteable()
fmt = self.fmt.specs[self.get_property_idx(name)]
if isinstance(value, int) or isinstance(value, str):
if isinstance(value, int):
packed = struct.pack(fmt.full_fmt, value)
self.data = self.data[0:fmt.offs] + packed + self.data[fmt.offs + len(packed):len(self.data)]
else:
elif isinstance(value, bytes):
packed = value
elif isinstance(value, str):
packed = value.encode()
else:
packed = struct.pack(fmt.full_fmt, *value)
self.data = self.data[0:fmt.offs] + packed + self.data[fmt.offs + len(packed):len(self.data)]
self.data = self.data[0:fmt.offs] + packed + self.data[fmt.offs + len(packed):len(self.data)]

if self.vlr_parent != False:
idx_start = 192*self.body_offset
Expand Down Expand Up @@ -306,7 +309,7 @@ def __init__(self, user_id, record_id, VLR_body, **kwargs):
self.fmt = util.Format("EVLR")
self.isEVLR = True
self.type = 0
if self.user_id == "LASF_Spec" and self.record_id == 4:
if "LASF_Spec" in self.user_id and self.record_id == 4:
self.setup_extra_bytes_spec(self.VLR_body)
try:
self.parse_data()
Expand Down Expand Up @@ -336,7 +339,7 @@ def build_from_reader(self, reader):
self.rec_len_after_header = reader.read_words("rec_len_after_header", "evlr")
self.description = "".join(reader.read_words("description", "evlr"))
self.VLR_body = reader.read(self.rec_len_after_header)
if self.user_id == "LASF_Spec" and self.record_id == 4:
if "LASF_Spec" in self.user_id and self.record_id == 4:
self.setup_extra_bytes_spec(self.VLR_body)

### LOGICAL CONTENT ###
Expand All @@ -357,7 +360,11 @@ def __len__(self):
def pack(self, name, val):
'''Pack an EVLR field into bytes.'''
spec = self.fmt.lookup[name]
if spec.num == 1:
if isinstance(val, bytes):
return val
elif isinstance(val, str):
return val.encode()
elif spec.num == 1:
return(struct.pack(spec.full_fmt, val))
return(struct.pack(spec.fmt[0]+spec.fmt[1]*len(val), *val))

Expand All @@ -373,7 +380,7 @@ def to_byte_string(self):
self.VLR_body)
diff = (self.rec_len_after_header - len(self.VLR_body))
if diff > 0:
out += "\x00"*diff
out += b"\x00"*diff
elif diff < 0:
raise util.LaspyException("Invalid Data in EVLR: too long for specified rec_len." +
" rec_len_after_header = " + str(self.rec_len_after_header) +
Expand Down Expand Up @@ -404,11 +411,10 @@ def __init__(self, user_id, record_id, VLR_body, **kwargs):
if "reserved" in kwargs:
self.reserved = kwargs["reserved"]
else:
self.reserved = 0
self.reserved = 0
self.reserved = 0
self.isVLR = True
self.fmt = util.Format("VLR")
if self.user_id == "LASF_Spec" and self.record_id == 4:
if "LASF_Spec" in self.user_id and self.record_id == 4:
self.setup_extra_bytes_spec(self.VLR_body)
try:
self.parse_data()
Expand All @@ -435,7 +441,7 @@ def build_from_reader(self, reader):
try:
self.parse_data()
except Exception as err:
print("Error Parsing EVLR Body Data:")
print("Error Parsing VLR Body Data:")
print(err)


Expand All @@ -449,13 +455,13 @@ def setup_extra_bytes_spec(self, VLR_body):
specification, must be multiple of 192.""")
else:
recs = self.rec_len_after_header / 192
for i in xrange(recs):
for i in xrange(int(recs)):
new_rec = ExtraBytesStruct()
new_rec.build_from_vlr(self, i)
new_rec.build_from_vlr(self, i)
self.add_extra_dim(new_rec)

def add_extra_dim(self, new_rec):
new_name = new_rec.name.replace("\x00", "").replace(" ", "_").lower()
new_name = new_rec.name.decode().replace("\x00", "").replace(" ", "_").lower()
self.__dict__[new_name] = new_rec
self.extra_dimensions.append(new_rec)

Expand All @@ -467,23 +473,27 @@ def __len__(self):
def pack(self, name, val):
'''Pack a VLR field into bytes.'''
spec = self.fmt.lookup[name]
if spec.num == 1:
if isinstance(val, bytes):
return val
elif isinstance(val, str):
return val.encode()
elif spec.num == 1:
return(struct.pack(spec.fmt, val))
return(struct.pack(spec.fmt[0]+spec.fmt[1]*len(val), *val))

def to_byte_string(self):
'''Pack the entire VLR into a byte string.'''
if type(self.parsed_body) != type(None):
self.pack_data()
out = (self.pack("reserved", self.reserved) +
self.pack("user_id", self.user_id) +
self.pack("user_id", self.user_id) +
self.pack("record_id", self.record_id) +
self.pack("rec_len_after_header", self.rec_len_after_header) +
self.pack("description", self.description) +
self.VLR_body)
diff = (self.rec_len_after_header - len(self.VLR_body))
if diff > 0:
out += "\x00"*diff
out += b"\x00"*diff
elif diff < 0:
raise util.LaspyException("Invalid Data in VLR: too long for specified rec_len." +
" rec_len_after_header = " + str(self.rec_len_after_header) +
Expand Down
6 changes: 3 additions & 3 deletions laspy/util.py
Expand Up @@ -141,7 +141,7 @@ def __init__(self, fmt, overwritable = False, extra_bytes = False, extradims = [
compression_bit_6 = (fmt & 0x40) >> 6
if (not compression_bit_6 and compression_bit_7):
self.compressed = True
fmt &= 0x3f;
fmt &= 0x3f
fmt = str(fmt)
except ValueError:
pass
Expand Down Expand Up @@ -351,13 +351,13 @@ def etree(self):

def translate_extra_spec(self, extra_dim):
if extra_dim.data_type == 0:
name = extra_dim.name.replace("\x00", "").replace(" ", "_").lower()
name = extra_dim.name.decode().replace("\x00", "").replace(" ", "_").lower()
fmt = "ctypes.c_ubyte"
num = extra_dim.options
return((name, fmt, num))
else:
spec = edim_fmt_dict[extra_dim.data_type]
return(extra_dim.name.replace("\x00", "").replace(" ", "_").lower(), spec[0], spec[1])
return(extra_dim.name.decode().replace("\x00", "").replace(" ", "_").lower(), spec[0], spec[1])

def __getitem__(self, index):
'''Provide slicing functionality: return specs[index]'''
Expand Down
2 changes: 1 addition & 1 deletion laspytest/__init__.py
@@ -1 +1 @@
from test_laspy import test_laspy
from laspytest.test_laspy import test_laspy

0 comments on commit 9768be6

Please sign in to comment.