You are here: Introduction > Architecture and Design

Architecture and Design

This section provides an overview of the architecture and some insight into the design philosophy of LizardTech's MrSID Decode SDK.

Basic Terminology

Point – A location in three-dimensional (3D) space with non-optional attributes (X,Y,Z) and optional attributes such as scan angle, pulse intensity, and color.

Channel – All the values for a given attribute. For example, the X channel is all the X values for a given point cloud.

Class Hierarchy

The MrSID Decode SDK is designed around two major classes: objects that are sources of LiDAR point data and objects that are destinations of LiDAR point data. The sources are derived from the PointSource class, and the destinations are derived from the PointWriter class. For the SDK, we deal mainly with he PointSource class.

The most interesting subclass of the PointSource class is MG4PointReader. The PointSource has two types of methods. The first is for getting properties about the point cloud, and the other type is for accessing the point cloud itself, either the entire cloud or subsets thereof.

Specifying a Region of Interest

When extracting points from the point cloud you must specify the region you wish to extract from, which we call the region of interest. The MrSID Decode SDK uses a bounding box to specify the region of interest.

If you wish to extract all the points in a point cloud, you may do it in either of two ways:

Using a bounding box generally defines far more points than a user needs, so when extracting points from a cloud, you must also specify the fraction of the point cloud that you wish to extract. For example if you only want every 20th point, specify 0.05 (1/20) as the fraction value. Use 1.0 when you want all the points.

Point Cloud Data Buffers

When extracting points we use the PointData class to pass around parts of the point cloud among functions. This class is a group of channel buffers for the channels that are to be extracted (see "The Buffer Management Classes").

Programming and Memory Model

The MrSID Decode SDK separates object allocation and object initialization. This means the constructors do not take arguments and classes have one or more init() methods. This makes it easier to work with exceptions and to chain object constructors.

The SDK chooses to use reference counting for objects with long or unknown life spans. The base class for reference counting is Object. Its methods, Object::retain() and Object::release() increment and decrement the reference counter. Functions and methods that start with “create” create a new reference counted object with a count of one. It is the responsibility of the “create” caller to release the object when done with it using Object::release(). When you retain a pointer to an Object you must retain the object using Object::retain(), until that pointer goes out of scope, at which time you must release the object.

See http://en.wikipedia.org/wiki/Reference_counting for more information on reference counting.

NOTE:  The SDKs naming conventions are patterned after those in Objective C.

Thread Safety

The MrSID Decode SDK is thread safe. Once the PointSource has been initialized any number of threads can use the PointSource instance. The stateful (thread-specific) information for the point extraction is stored in the PointIterator class.

Floating Point Quantization

Quantization is a way to convert floating point values to integer values. This facilitates lossless wavelet compression of LiDAR data. LAS files, which contain floating point values, are quantized as part of their storage. The MG4 format quantizes because it uses an integer wavelet transform to achieve lossless compression. The result is that, even with the quantization, LAS files can be compressed losslessly in MG4.

If you are doing any error analysis you must factor the quantization scale into the error bound calculation.

Quantization in the MrSID Decode SDK uses the following conversions between floating point and integer space:

<floating point value> = scale * <integer value> + offset

<index value> = floor((<floating point value> - offset) / scale + 0.5)

In going from integer space to floating point space and back again using the above methods, the index space values do not change. This stability minimizes the conversion error.