[Liblas-commits] hg-main-tree: SRS bugs all stomped out
liblas-commits at liblas.org
liblas-commits at liblas.org
Wed Apr 27 13:51:27 EDT 2011
details: http://hg.libpc.orghg-main-tree/rev/7ca4284e61a9
changeset: 675:7ca4284e61a9
user: Michael P. Gerlek <mpg at flaxen.com>
date: Wed Apr 27 10:51:18 2011 -0700
description:
SRS bugs all stomped out
diffstat:
include/libpc/drivers/las/VariableLengthRecord.hpp | 5 +-
src/drivers/las/VariableLengthRecord.cpp | 167 ++++++++++++--------
test/unit/SpatialReferenceTest.cpp | 18 +-
3 files changed, 108 insertions(+), 82 deletions(-)
diffs (truncated from 436 to 300 lines):
diff -r 83d65a4a4707 -r 7ca4284e61a9 include/libpc/drivers/las/VariableLengthRecord.hpp
--- a/include/libpc/drivers/las/VariableLengthRecord.hpp Wed Apr 27 10:58:33 2011 -0500
+++ b/include/libpc/drivers/las/VariableLengthRecord.hpp Wed Apr 27 10:51:18 2011 -0700
@@ -73,7 +73,8 @@
};
static void clearVLRs(GeoVLRType eType, std::vector<VariableLengthRecord>& vlrs);
- bool compareUserId(const std::string& str) const;
+ bool isMatch(const std::string& userId) const;
+ bool isMatch(const std::string& userId, boost::uint16_t recordId) const;
bool operator==(const VariableLengthRecord&) const;
VariableLengthRecord& operator=(const VariableLengthRecord&);
@@ -86,7 +87,7 @@
static void setSRSFromVLRs(const std::vector<VariableLengthRecord>& vlrs, SpatialReference& srs);
static void setVLRsFromSRS(const SpatialReference& srs, std::vector<VariableLengthRecord>& vlrs);
- static std::string bytes2string(boost::uint8_t* bytes, boost::uint32_t len);
+ static std::string bytes2string(const boost::uint8_t* bytes, boost::uint32_t len);
// bytes array is return, user responsible for deleting
// len is the size of the array he wants, it will be padded with zeros if str.length() < len
diff -r 83d65a4a4707 -r 7ca4284e61a9 src/drivers/las/VariableLengthRecord.cpp
--- a/src/drivers/las/VariableLengthRecord.cpp Wed Apr 27 10:58:33 2011 -0500
+++ b/src/drivers/las/VariableLengthRecord.cpp Wed Apr 27 10:51:18 2011 -0700
@@ -41,6 +41,18 @@
namespace libpc { namespace drivers { namespace las {
+static const std::string s_geotiffUserId = "LASF_Projection";
+static const boost::uint16_t s_geotiffRecordId_directory = 34735;
+static const boost::uint16_t s_geotiffRecordId_doubleparams = 34736;
+static const boost::uint16_t s_geotiffRecordId_asciiparams = 34737;
+static const std::string s_geotiffDescriptionId_directory = "GeoTIFF GeoKeyDirectoryTag";
+static const std::string s_geotiffDescriptionId_doubleparams = "GeoTIFF GeoDoubleParamsTag";
+static const std::string s_geotiffDescriptionId_asciiparams = "GeoTIFF GeoAsciiParamsTag";
+
+static const std::string s_wktUserId = "liblas";
+static const boost::uint16_t s_wktRecordId = 2112;
+static const std::string s_wktDescription = "OGR variant of OpenGIS WKT SRS";
+
VariableLengthRecord::VariableLengthRecord(boost::uint16_t reserved,
std::string userId,
@@ -78,7 +90,7 @@
VariableLengthRecord::~VariableLengthRecord()
{
- delete m_bytes;
+ delete[] m_bytes;
m_bytes = 0;
m_length = 0;
return;
@@ -92,6 +104,7 @@
m_length = rhs.m_length;
delete[] m_bytes;
m_bytes = new boost::uint8_t[m_length];
+ memcpy(m_bytes, rhs.m_bytes, m_length);
m_reserved = rhs.m_reserved;
m_recordId = rhs.m_recordId;
@@ -122,7 +135,7 @@
}
-std::string VariableLengthRecord::bytes2string(boost::uint8_t* bytes, boost::uint32_t len)
+std::string VariableLengthRecord::bytes2string(const boost::uint8_t* bytes, boost::uint32_t len)
{
std::string s = "";
for (boost::uint32_t i=0; i<len; i++)
@@ -160,38 +173,56 @@
}
-bool VariableLengthRecord::compareUserId(const std::string& userId) const
+bool VariableLengthRecord::isMatch(const std::string& userId) const
{
- const std::string& p = m_userId;
- const std::string& q = userId;
-
- return p==q;
+ return (userId == m_userId);
}
-void VariableLengthRecord::setSRSFromVLRs(const std::vector<VariableLengthRecord>& vlrs, SpatialReference& srs)
+bool VariableLengthRecord::isMatch(const std::string& userId, boost::uint16_t recordId) const
{
- if (vlrs.size() == 0)
+ return (userId == m_userId && recordId == m_recordId);
+}
+
+
+static bool setSRSFromVLRs_wkt(const std::vector<VariableLengthRecord>& vlrs, SpatialReference& srs)
+{
+ for (std::size_t i = 0; i < vlrs.size(); ++i)
{
- srs.setWKT("");
- return;
+ const VariableLengthRecord& vlr = vlrs[i];
+
+ if (vlr.isMatch(s_wktUserId, s_wktRecordId))
+ {
+ const boost::uint8_t* data = vlr.getBytes();
+ std::size_t length = vlr.getLength();
+
+ const std::string wkt = VariableLengthRecord::bytes2string(data, length);
+ srs.setWKT(wkt);
+ return true;
+ }
}
+ return false;
+}
+
+
+static bool setSRSFromVLRs_geotiff(const std::vector<VariableLengthRecord>& vlrs, SpatialReference& srs)
+{
GeotiffSupport geotiff;
geotiff.resetTags();
- const std::string uid("LASF_Projection");
-
bool gotSomething = false;
+ // first we try to get the 2212 VLR
+
// nothing is going to happen here if we don't have any vlrs describing
// srs information on the spatialreference.
for (std::size_t i = 0; i < vlrs.size(); ++i)
{
const VariableLengthRecord& vlr = vlrs[i];
- if (!vlr.compareUserId(uid))
+ if (!vlr.isMatch(s_geotiffUserId))
continue;
const boost::uint8_t* datax = vlr.getBytes();
@@ -203,7 +234,7 @@
switch (vlr.getRecordId())
{
- case 34735:
+ case s_geotiffRecordId_directory:
{
int count = length / sizeof(short);
// discard invalid "zero" geotags some software emits.
@@ -217,23 +248,23 @@
data[3] -= 1;
}
- geotiff.setKey(34735, count, GeotiffSupport::Geotiff_KeyType_SHORT, data);
+ geotiff.setKey(s_geotiffRecordId_directory, count, GeotiffSupport::Geotiff_KeyType_SHORT, data);
}
gotSomething = true;
break;
- case 34736:
+ case s_geotiffRecordId_doubleparams:
{
int count = length / sizeof(double);
- geotiff.setKey(34736, count, GeotiffSupport::Geotiff_KeyType_DOUBLE, data);
+ geotiff.setKey(s_geotiffRecordId_doubleparams, count, GeotiffSupport::Geotiff_KeyType_DOUBLE, data);
}
gotSomething = true;
break;
- case 34737:
+ case s_geotiffRecordId_asciiparams:
{
int count = length/sizeof(uint8_t);
- geotiff.setKey(34737, count, GeotiffSupport::Geotiff_KeyType_ASCII, data);
+ geotiff.setKey(s_geotiffRecordId_asciiparams, count, GeotiffSupport::Geotiff_KeyType_ASCII, data);
}
gotSomething = true;
break;
@@ -248,8 +279,7 @@
if (!gotSomething)
{
- srs.setWKT("");
- return;
+ return false;
}
geotiff.setTags();
@@ -258,6 +288,31 @@
srs.setFromUserInput(wkt);
+ return true;
+}
+
+
+void VariableLengthRecord::setSRSFromVLRs(const std::vector<VariableLengthRecord>& vlrs, SpatialReference& srs)
+{
+ srs.setWKT("");
+
+ if (vlrs.size() == 0)
+ {
+ return;
+ }
+
+ bool ok = setSRSFromVLRs_wkt(vlrs, srs);
+ if (ok)
+ {
+ return;
+ }
+
+ ok = setSRSFromVLRs_geotiff(vlrs, srs);
+ if (ok)
+ {
+ return;
+ }
+
return;
}
@@ -280,22 +335,13 @@
int acount = 0;
int atype =0;
- const std::string userId123 = "LASF_Projection";
- const std::string description1 = "GeoTIFF GeoKeyDirectoryTag";
- const std::string description2 = "GeoTIFF GeoDoubleParamsTag";
- const std::string description3 = "GeoTIFF GeoAsciiParamsTag";
-
- const std::string userId4 = "liblas";
- const std::string description4 = "OGR variant of OpenGIS WKT SRS";
-
GeotiffSupport geotiff;
{
const std::string wkt = srs.getWKT(SpatialReference::eCompoundOK, false);
geotiff.setWkt(wkt);
}
- //GTIFF_GEOKEYDIRECTORY == 34735
- ret = geotiff.getKey(34735, &kcount, &ktype, (void**)&kdata);
+ ret = geotiff.getKey(s_geotiffRecordId_directory, &kcount, &ktype, (void**)&kdata);
if (ret)
{
uint16_t length = 2 * static_cast<uint16_t>(kcount);
@@ -313,12 +359,11 @@
data.push_back(v[1]);
}
- VariableLengthRecord record(0, userId123, 34735, description1, &data[0], length);
+ VariableLengthRecord record(0, s_geotiffUserId, s_geotiffRecordId_directory, s_geotiffDescriptionId_directory, &data[0], length);
vlrs.push_back(record);
}
- // GTIFF_DOUBLEPARAMS == 34736
- ret = geotiff.getKey(34736, &dcount, &dtype, (void**)&ddata);
+ ret = geotiff.getKey(s_geotiffRecordId_doubleparams, &dcount, &dtype, (void**)&ddata);
if (ret)
{
uint16_t length = 8 * static_cast<uint16_t>(dcount);
@@ -342,13 +387,12 @@
data.push_back(v[7]);
}
- VariableLengthRecord record(0, userId123, 34736, description2, &data[0], length);
+ VariableLengthRecord record(0, s_geotiffUserId, s_geotiffRecordId_doubleparams, s_geotiffDescriptionId_doubleparams, &data[0], length);
vlrs.push_back(record);
}
- // GTIFF_ASCIIPARAMS == 34737
- ret = geotiff.getKey(34737, &acount, &atype, (void**)&adata);
+ ret = geotiff.getKey(s_geotiffRecordId_asciiparams, &acount, &atype, (void**)&adata);
if (ret)
{
uint16_t length = static_cast<uint16_t>(acount);
@@ -375,7 +419,7 @@
data.push_back(v[0]);
}
- VariableLengthRecord record(0, userId123, 34737, description3, &data[0], length);
+ VariableLengthRecord record(0, s_geotiffUserId, s_geotiffRecordId_asciiparams, s_geotiffDescriptionId_asciiparams, &data[0], length);
if (data.size() > (std::numeric_limits<boost::uint16_t>::max()))
@@ -412,7 +456,7 @@
throw std::runtime_error(oss.str());
}
- VariableLengthRecord wkt_record(0, userId4, 2112, description4, wkt_bytes, len);
+ VariableLengthRecord wkt_record(0, s_wktUserId, s_wktRecordId, s_wktDescription, wkt_bytes, len);
vlrs.push_back( wkt_record );
}
@@ -424,22 +468,20 @@
void VariableLengthRecord::clearVLRs(GeoVLRType eType, std::vector<VariableLengthRecord>& vlrs)
{
std::vector<VariableLengthRecord>::iterator it;
- std::string const liblas_id("liblas");
for (it = vlrs.begin(); it != vlrs.end(); )
{
More information about the Liblas-commits
mailing list