[Liblas-commits] hg: move liblas::Chipper into the library
liblas-commits at liblas.org
liblas-commits at liblas.org
Fri Nov 19 10:58:58 EST 2010
changeset e542d506da05 in /Volumes/Data/www/liblas.org/hg
details: http://hg.liblas.orghg?cmd=changeset;node=e542d506da05
summary: move liblas::Chipper into the library
diffstat:
apps/CMakeLists.txt | 13 +-
apps/chipper.cpp | 331 ---------------------------------------------
apps/chipper.hpp | 136 ------------------
apps/kdx_util.hpp | 2 +-
apps/lasblock.cpp | 3 +-
include/liblas/chipper.hpp | 136 ++++++++++++++++++
src/CMakeLists.txt | 3 +
src/chipper.cpp | 330 ++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 476 insertions(+), 478 deletions(-)
diffs (truncated from 1044 to 300 lines):
diff -r 8d0a1e312bb6 -r e542d506da05 apps/CMakeLists.txt
--- a/apps/CMakeLists.txt Thu Nov 18 15:13:09 2010 -0600
+++ b/apps/CMakeLists.txt Fri Nov 19 09:58:48 2010 -0600
@@ -82,17 +82,12 @@
link_directories(${Boost_LIBRARY_DIRS})
-set (LASCHIP_SOURCES chipper.cpp)
-add_library(${LASCHIP_LIB_NAME} SHARED ${LASCHIP_SOURCES})
-target_link_libraries(${LASCHIP_LIB_NAME}
- ${LIBLAS_LIB_NAME})
-
set (LASKERNEL_SOURCES laskernel.cpp)
add_library(${LASKERNEL_LIB_NAME} SHARED ${LASKERNEL_SOURCES})
target_link_libraries(${LASKERNEL_LIB_NAME}
${LIBLAS_LIB_NAME})
-install(TARGETS ${LASKERNEL_LIB_NAME} ${LASCHIP_LIB_NAME}
+install(TARGETS ${LASKERNEL_LIB_NAME}
RUNTIME DESTINATION ${LIBLAS_BIN_DIR}
LIBRARY DESTINATION ${LIBLAS_LIB_DIR}
ARCHIVE DESTINATION ${LIBLAS_LIB_DIR})
@@ -113,7 +108,7 @@
if(LAS2LAS)
add_executable(${LAS2LAS} las2las.cpp )
- target_link_libraries(${LAS2LAS} ${APPS_CPP_DEPENDENCIES} ${LASCHIP_LIB_NAME} ${LASKERNEL_LIB_NAME})
+ target_link_libraries(${LAS2LAS} ${APPS_CPP_DEPENDENCIES} ${LASKERNEL_LIB_NAME})
endif()
if(LASINFO)
@@ -151,7 +146,7 @@
if(LASBLOCK)
set(LASBLOCK_SRC lasblock.cpp )
add_executable(${LASBLOCK} ${LASBLOCK_SRC})
- target_link_libraries(${LASBLOCK} ${APPS_CPP_DEPENDENCIES} ${LASCHIP_LIB_NAME})
+ target_link_libraries(${LASBLOCK} ${APPS_CPP_DEPENDENCIES} )
endif()
# Build las2ogr
@@ -163,7 +158,7 @@
# Build las2oci
if(LAS2OCI)
add_executable(${LAS2OCI} las2oci.cpp oci_wrapper.cpp kdx_util.cpp oci_util.cpp )
- target_link_libraries(${LAS2OCI} ${APPS_CPP_DEPENDENCIES} ${ORACLE_LIBRARY} ${LASCHIP_LIB_NAME} ${LASKERNEL_LIB_NAME})
+ target_link_libraries(${LAS2OCI} ${APPS_CPP_DEPENDENCIES} ${ORACLE_LIBRARY} ${LASKERNEL_LIB_NAME})
endif()
if(BIGFILE_TEST)
diff -r 8d0a1e312bb6 -r e542d506da05 apps/chipper.cpp
--- a/apps/chipper.cpp Thu Nov 18 15:13:09 2010 -0600
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,331 +0,0 @@
-/******************************************************************************
- * $Id$
- *
- * Project: libLAS - http://liblas.org - A BSD library for LAS format data.
- * Purpose: Point Partitioning/blocking for OPC
- * Author: Andrew Bell andrew.bell.ia at gmail.com
- *
- ******************************************************************************
- * Copyright (c) 2010, Andrew Bell
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following
- * conditions are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of the Andrew Bell or libLAS nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- ****************************************************************************/
-
-#include "chipper.hpp"
-// boost
-#include <boost/cstdint.hpp>
-// std
-#include <cmath>
-
-using namespace boost;
-using namespace std;
-
-/**
-The objective is to split the region into non-overlapping blocks, each
-containing approximately the same number of points, as specified by the
-user.
-
-First, the points are read into arrays - one for the x direction, and one for
-the y direction. The arrays are sorted and are initialized with indices into
-the other array of the location of the other coordinate of the same point.
-
-Partitions are created that place the maximum number of points in a
-block, subject to the user-defined threshold, using a cumulate and round
-procedure.
-
-The distance of the point-space is checked in each direction and the
-wider dimension is chosen for splitting at an appropriate partition point.
-The points in the narrower direction are copied to locations in the spare
-array at one side or the other of the chosen partition, and that portion
-of the spare array then becomes the active array for the narrow direction.
-This avoids resorting of the arrays, which are already sorted.
-
-This procedure is then recursively applied to the created blocks until
-they contains only one or two partitions. In the case of one partition,
-we are done, and we simply store away the contents of the block. If there are
-two partitions in a block, we avoid the recopying the narrow array to the
-spare since the wide array already contains the desired points partitioned
-into two blocks. We simply need to locate the maximum and minimum values
-from the narrow array so that the approriate extrema of the block can
-be stored.
-**/
-
-namespace liblas { namespace chipper {
-
-vector<uint32_t> Block::GetIDs() const
-{
- vector<uint32_t> ids;
-
- for (uint32_t i = m_left; i <= m_right; ++i)
- ids.push_back((*m_list_p)[i].m_ptindex);
- return ids;
-}
-
-void Chipper::Chip()
-{
- Load(m_xvec, m_yvec, m_spare);
- Partition(m_xvec.size());
- DecideSplit(m_xvec, m_yvec, m_spare, 0, m_partitions.size() - 1);
-}
-
-void Chipper::Load(RefList& xvec, RefList& yvec, RefList& spare )
-{
- PtRef ref;
- uint32_t idx;
- uint32_t count;
- vector<PtRef>::iterator it;
-
- count = m_reader->GetHeader().GetPointRecordsCount();
- xvec.reserve(count);
- yvec.reserve(count);
- spare.resize(count);
-
- count = 0;
- while (m_reader->ReadNextPoint()) {
- const liblas::Point& pt = m_reader->GetPoint();
-
- ref.m_pos = pt.GetX();
- ref.m_ptindex = count;
- xvec.push_back(ref);
-
- ref.m_pos = pt.GetY();
- yvec.push_back(ref);
- count++;
- }
- // Sort xvec and assign other index in yvec to sorted indices in xvec.
- sort(xvec.begin(), xvec.end());
- for (uint32_t i = 0; i < xvec.size(); ++i) {
- idx = xvec[i].m_ptindex;
- yvec[idx].m_oindex = i;
- }
-
- // Sort yvec.
- sort(yvec.begin(), yvec.end());
-
- //Iterate through the yvector, setting the xvector appropriately.
- for (uint32_t i = 0; i < yvec.size(); ++i)
- xvec[yvec[i].m_oindex].m_oindex = i;
-}
-
-void Chipper::Partition(uint32_t size)
-{
- boost::uint32_t num_partitions;
-
- num_partitions = size / m_threshold;
- if ( size % m_threshold )
- num_partitions++;
- double total = 0;
- double partition_size = static_cast<double>(size) / num_partitions;
- m_partitions.push_back(0);
- for (boost::uint32_t i = 0; i < num_partitions; ++i) {
- total += partition_size;
- m_partitions.push_back(static_cast<uint32_t>(detail::sround(total)));
- }
-}
-
-void Chipper::DecideSplit(RefList& v1, RefList& v2, RefList& spare,
- uint32_t pleft, uint32_t pright)
-{
- double v1range;
- double v2range;
- uint32_t left = m_partitions[pleft];
- uint32_t right = m_partitions[pright] - 1;
-
- // Decide the wider direction of the block, and split in that direction
- // to maintain squareness.
- v1range = v1[right].m_pos - v1[left].m_pos;
- v2range = v2[right].m_pos - v2[left].m_pos;
- if (v1range > v2range)
- Split(v1, v2, spare, pleft, pright);
- else
- Split(v2, v1, spare, pleft, pright);
-}
-
-void Chipper::Split(RefList& wide, RefList& narrow, RefList& spare,
- uint32_t pleft, uint32_t pright)
-{
- uint32_t lstart;
- uint32_t rstart;
- uint32_t pcenter;
- uint32_t left;
- uint32_t right;
- uint32_t center;
-
- left = m_partitions[pleft];
- right = m_partitions[pright] - 1;
-
- // There are two cases in which we are done.
- // 1) We have a distance of two between left and right.
- // 2) We have a distance of three between left and right.
-
- if (pright - pleft == 1)
- Emit(wide, left, right, narrow, left, right);
- else if (pright - pleft == 2)
- FinalSplit(wide, narrow, pleft, pright);
- else
- {
- pcenter = (pleft + pright) / 2;
- center = m_partitions[pcenter];
-
- // We are splitting in the wide direction - split elements in the
- // narrow array by copying them to the spare array in the correct
- // partition. The spare array then becomes the active narrow array
- // for the [left,right] partition.
- lstart = left;
- rstart = center;
- for (uint32_t i = left; i <= right; ++i)
- {
- if (narrow[i].m_oindex < center)
- {
- spare[lstart] = narrow[i];
- wide[narrow[i].m_oindex].m_oindex = lstart;
- lstart++;
- }
- else
- {
- spare[rstart] = narrow[i];
- wide[narrow[i].m_oindex].m_oindex = rstart;
- rstart++;
- }
- }
-
- // Save away the direction so we know which array is X and which is Y
- // so that when we emit, we can properly label the max/min points.
- Direction dir = narrow.m_dir;
- spare.m_dir = dir;
- DecideSplit(wide, spare, narrow, pleft, pcenter);
- DecideSplit(wide, spare, narrow, pcenter, pright);
- narrow.m_dir = dir;
- }
-}
-
-// In this case the wide array is like we want it. The narrow array is
-// ordered, but not for our split, so we have to find the max/min entries
-// for each partition in the final split.
-void Chipper::FinalSplit(RefList& wide, RefList& narrow,
- uint32_t pleft, uint32_t pright)
-{
-
- boost::int64_t left1 = -1;
- boost::int64_t left2 = -1;
- boost::int64_t right1 = -1;
- boost::int64_t right2 = -1;
-
- // It appears we're using int64_t here because we're using -1 as
- // an indicator. I'm not 100% sure that i ends up <0, but I don't
- // think so. These casts will at least shut up the compiler, but
- // I think this code should be revisited to use std::vector<boost::uint32_t>::const_iterator
- // or std::vector<boost::uint32_t>::size_type instead of this int64_t stuff -- hobu 11/15/10
- boost::int64_t left = static_cast<boost::int64_t>(m_partitions[pleft]);
- boost::int64_t right = static_cast<boost::int64_t>(m_partitions[pright] - 1);
More information about the Liblas-commits
mailing list