[Liblas-commits] hg-main-tree: support serializing a libpc::Schema
to XML -- will...
liblas-commits at liblas.org
liblas-commits at liblas.org
Fri Apr 29 15:17:38 EDT 2011
details: http://hg.libpc.orghg-main-tree/rev/bfbd4b432f77
changeset: 696:bfbd4b432f77
user: Howard Butler <hobu.inc at gmail.com>
date: Fri Apr 29 14:17:25 2011 -0500
description:
support serializing a libpc::Schema to XML -- will move this into libpc::Schema proper soon
diffstat:
src/drivers/oci/Schema.cpp | 41 +++++++--
test/data/schemas/8-dimension-schema.xml | 116 ++++++++++++++++++++++++++++
test/data/schemas/LAS.xsd | 126 +++++++++++++++++++++++++++++++
test/unit/OCITest.cpp | 8 +-
4 files changed, 274 insertions(+), 17 deletions(-)
diffs (truncated from 408 to 300 lines):
diff -r 0cd35b45b269 -r bfbd4b432f77 src/drivers/oci/Schema.cpp
--- a/src/drivers/oci/Schema.cpp Thu Apr 28 10:23:21 2011 -0700
+++ b/src/drivers/oci/Schema.cpp Fri Apr 29 14:17:25 2011 -0500
@@ -41,6 +41,7 @@
#include <list>
#include <cstdlib>
#include <map>
+#include <algorithm>
#include <string.h>
@@ -81,7 +82,10 @@
}
};
-
+static bool sort_dimensions(libpc::DimensionLayout const& a, libpc::DimensionLayout const& b)
+{
+ return a < b;
+}
namespace libpc { namespace drivers { namespace oci {
@@ -271,7 +275,7 @@
}
void Schema::LoadSchema()
{
- std::map<boost::uint32_t, libpc::Dimension> layouts;
+ std::vector<libpc::DimensionLayout> layouts;
xmlDocPtr doc = static_cast<xmlDocPtr>(m_doc.get());
xmlNode* root = xmlDocGetRootElement(doc);
@@ -282,15 +286,19 @@
throw schema_error("First node of document was not named 'PointCloudSchema'");
xmlNode* dimension = root->children;
+
while(dimension != NULL)
{
- if (dimension->type != XML_ELEMENT_NODE)
+ // printf("node name: %s\n", (const char*)dimension->name);
+ if (dimension->type != XML_ELEMENT_NODE || compare_no_case((const char*)dimension->name, "dimension"))
{
dimension = dimension->next;
continue;
}
+
+
xmlNode* properties = dimension->children;
std::string name;
@@ -317,7 +325,7 @@
if (!n) throw schema_error("Unable to fetch name!");
name = std::string((const char*)n);
xmlFree(n);
- std::cout << "Dimension name: " << name << std::endl;
+ // std::cout << "Dimension name: " << name << std::endl;
}
if (!compare_no_case((const char*)properties->name, "size"))
@@ -331,7 +339,7 @@
}
xmlFree(n);
size = static_cast<boost::uint32_t>(s);
- std::cout << "Dimension size: " << size << std::endl;
+ // std::cout << "Dimension size: " << size << std::endl;
}
if (!compare_no_case((const char*)properties->name, "position"))
@@ -345,7 +353,7 @@
}
xmlFree(n);
position = static_cast<boost::uint32_t>(p);
- std::cout << "Dimension position: " << position << std::endl;
+ // std::cout << "Dimension position: " << position << std::endl;
}
if (!compare_no_case((const char*)properties->name, "description"))
{
@@ -369,7 +377,7 @@
minimum = std::atof((const char*)n);
xmlFree(n);
- std::cout << "Dimension minimum: " << minimum << std::endl;
+ // std::cout << "Dimension minimum: " << minimum << std::endl;
}
if (!compare_no_case((const char*)properties->name, "maximum"))
@@ -379,7 +387,7 @@
maximum = std::atof((const char*)n);
xmlFree(n);
- std::cout << "Dimension maximum: " << maximum << std::endl;
+ // std::cout << "Dimension maximum: " << maximum << std::endl;
}
if (!compare_no_case((const char*)properties->name, "offset"))
@@ -389,7 +397,7 @@
offset = std::atof((const char*)n);
xmlFree(n);
- std::cout << "Dimension offset: " << offset << std::endl;
+ // std::cout << "Dimension offset: " << offset << std::endl;
}
if (!compare_no_case((const char*)properties->name, "scale"))
{
@@ -398,7 +406,7 @@
scale = std::atof((const char*)n);
xmlFree(n);
- std::cout << "Dimension scale: " << scale << std::endl;
+ // std::cout << "Dimension scale: " << scale << std::endl;
}
// printf("property name: %s\n", properties->name);
@@ -409,11 +417,22 @@
Dimension::Field f = GetDimensionField(name, position);
Dimension d(f, t);
+ DimensionLayout l(d);
+ l.setPosition(position);
+ layouts.push_back(l);
- layouts.insert(std::pair<boost::uint32_t, libpc::Dimension>(position, d));
dimension = dimension->next;
}
+ std::sort(layouts.begin(), layouts.end(), sort_dimensions);
+
+ std::vector<DimensionLayout>::const_iterator i;
+ for (i = layouts.begin(); i!= layouts.end(); ++i)
+ {
+ m_schema.addDimension(i->getDimension());
+ }
+
+ // m_schema.dump();
}
Dimension::DataType Schema::GetDimensionType(std::string const& interpretation)
diff -r 0cd35b45b269 -r bfbd4b432f77 test/data/schemas/8-dimension-schema.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/data/schemas/8-dimension-schema.xml Fri Apr 29 14:17:25 2011 -0500
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<pc:PointCloudSchema xmlns:pc="http://libpc.org/schemas/PC/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <pc:dimension>
+ <pc:position>1</pc:position>
+ <pc:size>8</pc:size>
+ <pc:name>X</pc:name>
+ <pc:interpretation>double</pc:interpretation>
+ <pc:description>x coordinate as a double</pc:description>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>2</pc:position>
+ <pc:size>8</pc:size>
+ <pc:name>Y</pc:name>
+ <pc:interpretation>double</pc:interpretation>
+ <pc:description>y coordinate as a double</pc:description>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>3</pc:position>
+ <pc:size>8</pc:size>
+ <pc:name>Z</pc:name>
+ <pc:interpretation>double</pc:interpretation>
+ <pc:description>z coordinate as a double</pc:description>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>4</pc:position>
+ <pc:size>8</pc:size>
+ <pc:name>Time</pc:name>
+ <pc:description>The GPS Time is the double floating point time tag value at which the point was acquired. It is GPS Week Time if the Global Encoding low bit is clear and Adjusted Standard GPS Time if the Global Encoding low bit is set (see Global Encoding in the Public Header Block description).</pc:description>
+ <pc:interpretation>double</pc:interpretation>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>5</pc:position>
+ <pc:size>8</pc:size>
+ <pc:name>Classification</pc:name>
+ <pc:description>Classification in LAS 1.0 was essentially user defined and optional. LAS 1.1 defines a standard set of ASPRS classifications. In addition, the field is now mandatory. If a point has never been classified, this byte must be set to zero. There are no user defined classes since both point format 0 and point format 1 supply 8 bits per point for user defined operations. Note that the format for classification is a bit encoded field with the lower five bits used for class and the three high bits used for flags.</pc:description>
+ <pc:interpretation>uint8_t</pc:interpretation>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>6</pc:position>
+ <pc:size>8</pc:size>
+ <pc:name>Intensity</pc:name>
+ <pc:description>The intensity value is the integer representation of the pulse return magnitude. This value is optional and system specific. However, it should always be included if available.</pc:description>
+ <pc:interpretation>int16_t</pc:interpretation>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>7</pc:position>
+ <pc:size>1</pc:size>
+ <pc:interpretation>uint8_t</pc:interpretation>
+ <pc:name>Return Number</pc:name>
+ <pc:description>Return Number: The Return Number is the pulse return number for a given output pulse. A given output laser pulse can have many returns, and they must be marked in sequence of return. The first return will have a Return Number of one, the second a Return Number of two, and so on up to five returns.</pc:description>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>8</pc:position>
+ <pc:size>1</pc:size>
+ <pc:interpretation>uint8_t</pc:interpretation>
+ <pc:name>Number of Returns</pc:name>
+ <pc:description>Number of Returns (for this emitted pulse): The Number of Returns is the total number of returns for a given pulse. For example, a laser data point may be return two (Return Number) within a total number of five returns.</pc:description>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>9</pc:position>
+ <pc:size>1</pc:size>
+ <pc:interpretation>uint8_t</pc:interpretation>
+ <pc:name>Scan Direction</pc:name>
+ <pc:description>The Scan Direction Flag denotes the direction at which the scanner mirror was traveling at the time of the output pulse. A bit value of 1 is a positive scan direction, and a bit value of 0 is a negative scan direction (where positive scan direction is a scan moving from the left side of the in-track direction to the right side and negative the opposite). </pc:description>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>10</pc:position>
+ <pc:size>1</pc:size>
+ <pc:interpretation>uint8_t</pc:interpretation>
+ <pc:name>Flightline Edge</pc:name>
+ <pc:description>The Edge of Flight Line data bit has a value of 1 only when the point is at the end of a scan. It is the last point on a given scan line before it changes direction.</pc:description>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>11</pc:position>
+ <pc:size>1</pc:size>
+ <pc:name>Scan Angle Rank</pc:name>
+ <pc:description>The Scan Angle Rank is a signed one-byte number with a valid range from -90 to +90. The Scan Angle Rank is the angle (rounded to the nearest integer in the absolute value sense) at which the laser point was output from the laser system including the roll of the aircraft. The scan angle is within 1 degree of accuracy from +90 to â90 degrees. The scan angle is an angle based on 0 degrees being nadir, and â90 degrees to the left side of the aircraft in the direction of flight.</pc:description>
+ <pc:interpretation>int8_t</pc:interpretation>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>12</pc:position>
+ <pc:size>1</pc:size>
+ <pc:name>User Data</pc:name>
+ <pc:interpretation>uint8_t</pc:interpretation>
+ <pc:description>This field may be used at the users discretion</pc:description>
+ <pc:active>false</pc:active>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>13</pc:position>
+ <pc:size>2</pc:size>
+ <pc:name>Point Source ID</pc:name>
+ <pc:description>This value indicates the file from which this point originated. Valid values for this field are 1 to 65,535 inclusive with zero being used for a special case discussed below. The numerical value corresponds to the File Source ID from which this point originated. Zero is reserved as a convenience to system implementers. A Point Source ID of zero implies that this point originated in this file. This implies that processing software should set the Point Source ID equal to the File Source ID of the file containing this point at some time during processing.</pc:description>
+ <pc:interpretation>uint16_t</pc:interpretation>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>14</pc:position>
+ <pc:size>2</pc:size>
+ <pc:name>Red</pc:name>
+ <pc:description>The red image channel value associated with this point</pc:description>
+ <pc:interpretation>uint16_t</pc:interpretation>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>15</pc:position>
+ <pc:size>2</pc:size>
+ <pc:name>Green</pc:name>
+ <pc:description>The green image channel value associated with this point</pc:description>
+ <pc:interpretation>uint16_t</pc:interpretation>
+ </pc:dimension>
+ <pc:dimension>
+ <pc:position>16</pc:position>
+ <pc:size>2</pc:size>
+ <pc:name>Blue</pc:name>
+ <pc:description>The blue image channel value associated with this point</pc:description>
+ <pc:interpretation>uint16_t</pc:interpretation>
+ </pc:dimension>
+</pc:PointCloudSchema>
diff -r 0cd35b45b269 -r bfbd4b432f77 test/data/schemas/LAS.xsd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/data/schemas/LAS.xsd Fri Apr 29 14:17:25 2011 -0500
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<xs:schema xmlns:pc="http://libpc.org/schemas/PC/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://libpc.org/schemas/PC/1.0" version="1.0">
+
+ <xs:simpleType name="interpretationType">
+ <xs:annotation>
+ <xs:documentation>
+ Common interpretations of the data that may be used. This
+ type may be extended under the expectation that clients
+ know how to consume the data. In the case of string-like
+ data, use uint8_t (common byte) as the interpretation
+ and transform accordingly. Because nulls (or even
+ multi-byte strings) might be allowed, there are
+ no common string interpretations provided by default.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="int8_t"/>
+ <xs:enumeration value="uint8_t"/>
+ <xs:enumeration value="int16_t"/>
+ <xs:enumeration value="uint16_t"/>
+ <xs:enumeration value="int32_t"/>
+ <xs:enumeration value="uint32_t"/>
+ <xs:enumeration value="int64_t"/>
+ <xs:enumeration value="uint64_t"/>
+ <xs:enumeration value="double"/>
+ <xs:enumeration value="float"/>
+ <xs:enumeration value="unknown"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="rangeType">
+ <xs:attribute name="units" type="pc:interpretationType"/>
+ <xs:attribute name="value" type="xs:decimal"/>
+ </xs:complexType>
+
+ <xs:complexType name="dimensionType">
More information about the Liblas-commits
mailing list