[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