Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
port the basic renderer from Martin's prototype
- Loading branch information
1 parent
13ecb8c
commit 8a42c57
Showing
16 changed files
with
766 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# CMake module to search for laz-perf | ||
# | ||
# Once done this will define | ||
# | ||
# LazPerf_FOUND - system has the zip library | ||
# LazPerf_INCLUDE_DIRS - the zip include directories | ||
# | ||
# Copyright (c) 2020, Peter Petrik, <zilolv@gmail.com> | ||
# | ||
# Redistribution and use is allowed according to the terms of the BSD license. | ||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file. | ||
|
||
FIND_PATH(LazPerf_INCLUDE_DIR | ||
laz-perf/io.hpp | ||
"$ENV{LIB_DIR}/include" | ||
"$ENV{INCLUDE}" | ||
/usr/local/include | ||
/usr/include | ||
) | ||
|
||
INCLUDE(FindPackageHandleStandardArgs) | ||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LazPerf DEFAULT_MSG LazPerf_INCLUDE_DIR) | ||
|
||
MARK_AS_ADVANCED(LazPerf_INCLUDE_DIR) | ||
|
||
IF (LazPerf_FOUND) | ||
MESSAGE(STATUS "Found laz-perf: ${LazPerf_INCLUDE_DIR}") | ||
ELSE (LazPerf_FOUND) | ||
MESSAGE(FATAL_ERROR "Could not find laz-perf") | ||
ENDIF (LazPerf_FOUND) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# CMake module to search for libzstd | ||
# | ||
# Once done this will define | ||
# | ||
# ZSTD_FOUND - system has the zip library | ||
# ZSTD_INCLUDE_DIRS - the zip include directories | ||
# ZSTD_LIBRARY - Link this to use the zip library | ||
# | ||
# Copyright (c) 2020, Peter Petrik, <zilolv@gmail.com> | ||
# | ||
# Redistribution and use is allowed according to the terms of the BSD license. | ||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file. | ||
|
||
FIND_PATH(ZSTD_INCLUDE_DIR | ||
zstd.h | ||
"$ENV{LIB_DIR}/include" | ||
"$ENV{INCLUDE}" | ||
/usr/local/include | ||
/usr/include | ||
) | ||
|
||
FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd PATHS "$ENV{LIB_DIR}/lib" "$ENV{LIB}" /usr/local/lib /usr/lib ) | ||
|
||
INCLUDE(FindPackageHandleStandardArgs) | ||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZSTD DEFAULT_MSG | ||
ZSTD_LIBRARY ZSTD_INCLUDE_DIR) | ||
|
||
MARK_AS_ADVANCED(ZSTD_LIBRARY ZSTD_INCLUDE_DIR) | ||
|
||
IF (ZSTD_FOUND) | ||
MESSAGE(STATUS "Found ZSTD: ${ZSTD_LIBRARY}") | ||
ELSE (ZSTD_FOUND) | ||
MESSAGE(FATAL_ERROR "Could not find ZSTD") | ||
ENDIF (ZSTD_FOUND) |
44 changes: 0 additions & 44 deletions
44
python/core/auto_generated/pointcloud/qgspointcloudindex.sip.in
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
/*************************************************************************** | ||
qgspointcloudrenderer.cpp | ||
-------------------- | ||
begin : October 2020 | ||
copyright : (C) 2020 by Peter Petrik | ||
email : zilolv at gmail dot com | ||
***************************************************************************/ | ||
|
||
/*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#include "qgspointclouddecoder.h" | ||
#include "qgspointcloudindex.h" | ||
#include "qgsvector3d.h" | ||
|
||
#include <zstd.h> | ||
#include <QFile> | ||
#include <iostream> | ||
|
||
#include "laz-perf/io.hpp" | ||
#include "laz-perf/common/common.hpp" | ||
|
||
QVector<qint32> QgsPointCloudDecoder::decompressBinary(const QString& filename, QgsPointCloudDataBounds &db) | ||
{ | ||
Q_ASSERT( QFile::exists( filename ) ); | ||
|
||
QFile f( filename ); | ||
bool r = f.open(QIODevice::ReadOnly); | ||
Q_ASSERT(r); | ||
|
||
// WHY??? per-record should be 18 based on schema, not 46 | ||
int stride = 46; //18; | ||
int count = f.size() / stride; | ||
qint32 xMin = -999999999, yMin = -999999999, zMin = -999999999; | ||
qint32 xMax = 999999999, yMax = 999999999, zMax = 999999999; | ||
QVector<qint32> data( count * 3 ); | ||
for ( int i = 0; i < count; ++i ) | ||
{ | ||
QByteArray bytes = f.read( stride ); | ||
// WHY??? X,Y,Z are int32 values stored as doubles | ||
double *bytesD = (double*) bytes.constData(); | ||
data[i*3+0] = (bytesD[0]); | ||
data[i*3+1] = (bytesD[1]); | ||
data[i*3+2] = (bytesD[2]); | ||
|
||
xMin = std::min( xMin, data[i*3+0]); | ||
xMax = std::max( xMax, data[i*3+0]); | ||
yMin = std::min( yMin, data[i*3+1]); | ||
yMax = std::max( yMax, data[i*3+1]); | ||
zMin = std::min( zMin, data[i*3+2]); | ||
zMax = std::max( zMax, data[i*3+2]); | ||
} | ||
db = QgsPointCloudDataBounds(xMin, xMax, yMin, yMax, zMin, zMax); | ||
return data; | ||
} | ||
|
||
/* *************************************************************************************** */ | ||
|
||
QByteArray decompressZtdStream( const QByteArray &dataCompressed ) | ||
{ | ||
// NOTE: this is very primitive implementation because we expect the uncompressed | ||
// data will be always less than 10 MB | ||
|
||
const int MAXSIZE=10000000; | ||
QByteArray dataUncompressed; | ||
dataUncompressed.resize( MAXSIZE ); | ||
|
||
ZSTD_DStream *strm = ZSTD_createDStream(); | ||
ZSTD_initDStream(strm); | ||
|
||
ZSTD_inBuffer m_inBuf; | ||
m_inBuf.src = reinterpret_cast<const void *>(dataCompressed.constData()); | ||
m_inBuf.size = dataCompressed.size(); | ||
m_inBuf.pos = 0; | ||
|
||
ZSTD_outBuffer outBuf { reinterpret_cast<void *>(dataUncompressed.data()), MAXSIZE, 0 }; | ||
size_t ret = ZSTD_decompressStream(strm, &outBuf, &m_inBuf); | ||
Q_ASSERT (!ZSTD_isError(ret)); | ||
Q_ASSERT( outBuf.pos ); | ||
Q_ASSERT( outBuf.pos < outBuf.size ); | ||
|
||
ZSTD_freeDStream(strm); | ||
dataUncompressed.resize(outBuf.pos); | ||
return dataUncompressed; | ||
} | ||
|
||
QVector<qint32> QgsPointCloudDecoder::decompressZStandard(const QString& filename, QgsPointCloudDataBounds &db) | ||
{ | ||
Q_ASSERT( QFile::exists( filename ) ); | ||
|
||
QFile f( filename ); | ||
bool r = f.open(QIODevice::ReadOnly); | ||
Q_ASSERT(r); | ||
|
||
QByteArray dataCompressed = f.readAll(); | ||
QByteArray dataUncompressed = decompressZtdStream( dataCompressed ); | ||
|
||
// from here it's the same as "binary" | ||
|
||
// WHY??? per-record should be 18 based on schema, not 46 | ||
int stride = 46; //18; | ||
int count = dataUncompressed.size() / stride; | ||
qint32 xMin = -999999999, yMin = -999999999, zMin = -999999999; | ||
qint32 xMax = 999999999, yMax = 999999999, zMax = 999999999; | ||
|
||
QVector<qint32> data( count * 3 ); | ||
const char *ptr = dataUncompressed.constData(); | ||
for ( int i = 0; i < count; ++i ) | ||
{ | ||
// WHY??? X,Y,Z are int32 values stored as doubles | ||
double *bytesD = (double*) (ptr+stride*i); | ||
data[i*3+0] = (bytesD[0]); | ||
data[i*3+1] = (bytesD[1]); | ||
data[i*3+2] = (bytesD[2]); | ||
|
||
xMin = std::min( xMin, data[i*3+0]); | ||
xMax = std::max( xMax, data[i*3+0]); | ||
yMin = std::min( yMin, data[i*3+1]); | ||
yMax = std::max( yMax, data[i*3+1]); | ||
zMin = std::min( zMin, data[i*3+2]); | ||
zMax = std::max( zMax, data[i*3+2]); | ||
} | ||
db = QgsPointCloudDataBounds(xMin, xMax, yMin, yMax, zMin, zMax); | ||
return data; | ||
} | ||
|
||
/* *************************************************************************************** */ | ||
|
||
QVector<qint32> QgsPointCloudDecoder::decompressLaz(const QString& filename, QgsPointCloudDataBounds &db) | ||
{ | ||
std::ifstream file(filename.toLatin1().constData(), std::ios::binary); | ||
Q_ASSERT (file.good()); | ||
|
||
auto start = common::tick(); | ||
|
||
laszip::io::reader::file f(file); | ||
|
||
size_t count = f.get_header().point_count; | ||
char buf[256]; // a buffer large enough to hold our point | ||
|
||
qint32 xMin = -999999999, yMin = -999999999, zMin = -999999999; | ||
qint32 xMax = 999999999, yMax = 999999999, zMax = 999999999; | ||
QVector<qint32> data( count * 3 ); | ||
|
||
for(size_t i = 0 ; i < count ; i ++) { | ||
f.readPoint(buf); // read the point out | ||
laszip::formats::las::point10 p = laszip::formats::packers<laszip::formats::las::point10>::unpack(buf); | ||
|
||
data[i*3+0] = p.x ; | ||
data[i*3+1] = p.y ; | ||
data[i*3+2] = p.z ; | ||
|
||
xMin = std::min( xMin, data[i*3+0]); | ||
xMax = std::max( xMax, data[i*3+0]); | ||
yMin = std::min( yMin, data[i*3+1]); | ||
yMax = std::max( yMax, data[i*3+1]); | ||
zMin = std::min( zMin, data[i*3+2]); | ||
zMax = std::max( zMax, data[i*3+2]); | ||
} | ||
db = QgsPointCloudDataBounds(xMin, xMax, yMin, yMax, zMin, zMax); | ||
float t = common::since(start); | ||
std::cout << "LAZ-PERF Read through the points in " << t << " seconds." << std::endl; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/*************************************************************************** | ||
qgspointclouddecoder.h | ||
-------------------- | ||
begin : October 2020 | ||
copyright : (C) 2020 by Peter Petrik | ||
email : zilolv at gmail dot com | ||
***************************************************************************/ | ||
|
||
/*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#ifndef QGSPOINTCLOUDDECODER_H | ||
#define QGSPOINTCLOUDDECODER_H | ||
|
||
|
||
#include "qgis_core.h" | ||
#include "qgis_sip.h" | ||
|
||
#define SIP_NO_FILE | ||
|
||
#include <QVector> | ||
#include <QString> | ||
|
||
class QgsPointCloudDataBounds; | ||
class QgsVector3D; | ||
|
||
namespace QgsPointCloudDecoder | ||
{ | ||
QVector<qint32> decompressBinary(const QString& filename, QgsPointCloudDataBounds &db); | ||
QVector<qint32> decompressZStandard(const QString& filename, QgsPointCloudDataBounds &db); | ||
QVector<qint32> decompressLaz(const QString& filename, QgsPointCloudDataBounds &db); | ||
}; | ||
|
||
|
||
#endif // QGSPOINTCLOUDDECODER_H |
Oops, something went wrong.