Commit 12829a97 by Mário Rocco Pettinati

Merge remote-tracking branch 'upstream/release-5.5' into develop

2 parents 3eacc96f 1f9574bf
......@@ -895,7 +895,7 @@ if [ ! -f "$TERRALIB_DEPENDENCIES_DIR/lib/libspatialite.so" ]; then
cd libspatialite-4.3.0a
valid $? "Error: could not enter libspatialite-4.3.0a!"
CPPFLAGS="-DACCEPT_USE_OF_DEPRECATED_PROJ_API_H -I$TERRALIB_DEPENDENCIES_DIR -I$TERRALIB_DEPENDENCIES_DIR/include" LDFLAGS="-L$TERRALIB_DEPENDENCIES_DIR/lib" LIBXML2_CFLAGS="-I$TERRALIB_DEPENDENCIES_DIR/include/libxml2 -I$TERRALIB_DEPENDENCIES_DIR/include/libxml2/libxml" LIBXML2_LIBS="-L$TERRALIB_DEPENDENCIES_DIR/lib" ./configure --prefix=$TERRALIB_DEPENDENCIES_DIR --enable-geocallbacks --enable-examples=no --with-geosconfig=$TERRALIB_DEPENDENCIES_DIR/bin/geos-config
CPPFLAGS="-DACCEPT_USE_OF_DEPRECATED_PROJ_API_H -I$TERRALIB_DEPENDENCIES_DIR -I$TERRALIB_DEPENDENCIES_DIR/include" LDFLAGS="-L$TERRALIB_DEPENDENCIES_DIR/lib" LIBXML2_CFLAGS="-I$TERRALIB_DEPENDENCIES_DIR/include/libxml2 -I$TERRALIB_DEPENDENCIES_DIR/include/libxml2/libxml" LIBXML2_LIBS="-L$TERRALIB_DEPENDENCIES_DIR/lib -lxml2" ./configure --prefix=$TERRALIB_DEPENDENCIES_DIR --enable-geocallbacks --enable-examples=no --enable-libxml2 --with-geosconfig=$TERRALIB_DEPENDENCIES_DIR/bin/geos-config
valid $? "Error: could not configure libspatialite!"
make -j $THREADS
......
......@@ -875,81 +875,10 @@ namespace
executeFix(dataAccess.get(), 3, path + "fix_method_3.csv");
}
int calculatePlanarZone(te::gm::Envelope latLongBox)
{
const double TeCDR = 0.01745329251994329576; //!< Conversion factor: degrees to radians
const double TeCRD = 57.29577951308232087679; //!< Conversion factor: radians to degrees
double longitude = latLongBox.getCenter().x;
int meridiano = static_cast<int>(longitude / 6);
meridiano = meridiano * 6;
meridiano = abs(meridiano) + 3;
double long0 = -meridiano * TeCDR;
// TeUTM T4
int zone = (static_cast<int>((long0 * TeCRD + 183.0) / 6.0));
return zone;
}
std::string getUTMProj4FromZone(int zone)
{
/*
PROJ4
+proj Projection name
+datum Datum name
+lat_0 Latitude of origin
+lon_0 Central meridian
+x_0 False easting
+y_0 False northing
+lat_1 Latitude of first standard parallel
+lat_2 Latitude of second standard parallel
+units meters, US survey feet, etc.
+lat_ts Latitude of true scale
+south Denotes southern hemisphere UTM zone
+no_defs Don't use the /usr/share/proj/proj_def.dat defaults file
*/
std::stringstream szone;
szone << zone;
std::string proj4 = "+proj=utm";
proj4 += " +zone=" + szone.str();
proj4 += " +south"; // pode ser +north?
proj4 += " +ellps=aust_SA";
proj4 += " +towgs84=-57,1,-41,0,0,0,0";
proj4 += " +units=m";
proj4 += " +no_defs ";
return proj4;
}
int getPlanarSRID(const te::gm::Envelope& envelope)
{
//int srid = 3857;
int srid = 3395;
return srid;
int zone = calculatePlanarZone(envelope);
std::string proj4 = getUTMProj4FromZone(zone);
int planarSRID = TE_UNKNOWN_SRS;
if (te::srs::SpatialReferenceSystemManager::getInstance().isValidP4TxtID(proj4) == true)
{
// Get the id of the projection of destination
std::pair<std::string, unsigned int> projPlanar = te::srs::SpatialReferenceSystemManager::getInstance().getIdFromP4Txt(proj4);
planarSRID = projPlanar.second;
}
else
{
planarSRID = te::srs::SpatialReferenceSystemManager::getInstance().getNewUserDefinedSRID();
std::string newName = "USER:" + boost::lexical_cast<std::string>(planarSRID);
te::srs::SpatialReferenceSystemManager::getInstance().add(newName, proj4, "", planarSRID, "USER");
}
return planarSRID;
}
te::gm::Coord2D transform(const te::gm::Coord2D& coord, int oldsrid, int newsrid)
......@@ -987,7 +916,6 @@ namespace
coordLowerLeft = transform(coordLowerLeft, oldsrid, newsrid);
coordUpperRight = transform(coordUpperRight, oldsrid, newsrid);
//te::gm::Envelope newEnvelope = te::gm::CreateEnvelope(coordLowerLeft.x, coordLowerLeft.y, coordUpperRight.x, coordUpperRight.y);
te::gm::Envelope newEnvelope(envelope);
newEnvelope.transform(oldsrid, newsrid);
return newEnvelope;
......@@ -1011,48 +939,15 @@ namespace
double wdx = planarEnvelope.getWidth();
double wdy = planarEnvelope.getHeight();
/*
double centerX = envelope.getCenter().x;
double centerY = envelope.getCenter().y;
te::gm::Coord2D cx1(envelope.m_llx, centerY);
te::gm::Coord2D cx2(envelope.m_urx, centerY);
te::gm::Coord2D cx1 = envelope.getLowerLeft();
te::gm::Coord2D cx2 = envelope.getUpperRight();
cx1 = transform(cx1, envelopeSRID, planarSRID);
cx2 = transform(cx2, envelopeSRID, planarSRID);
te::gm::Coord2D cy1(centerX, envelope.m_lly);
te::gm::Coord2D cy2(centerX, envelope.m_ury);
cy1 = transform(cy1, envelopeSRID, planarSRID);
cy2 = transform(cy2, envelopeSRID, planarSRID);
double wdx = te::gm::Distance::CalculateDistance(cx1, cx2);
double wdy = te::gm::Distance::CalculateDistance(cy1, cy2);
*/
double scaleX = wdx / widthMeters;
double scaleY = wdy / heightMeters;
//std::cout << std::endl << "ScaleX = " << scaleX;
//std::cout << std::endl << "ScaleY = " << scaleY;
std::cout << std::endl << "Resulting ScaleX: " << scaleX;
std::cout << std::endl << "Resulting ScaleY: " << scaleY;
//scaleX = std::round(scaleX);
//scaleY = std::round(scaleY);
return scaleX > scaleY ? scaleY : scaleX;
}
double calculateErrorFactor(const te::gm::Envelope& referenceEnvelope, int referenceSRID, int testSRID)
{
te::gm::Coord2D referenceLowerLeft = referenceEnvelope.getLowerLeft();
//te::gm::Coord2D referenceUpperRight = referenceEnvelope.getUpperRight();
te::gm::Coord2D referenceUpperRight(referenceEnvelope.m_urx, referenceEnvelope.m_lly);
te::gm::Coord2D testLowerLeft = transform(referenceLowerLeft, referenceSRID, testSRID);
......@@ -1132,97 +1027,18 @@ namespace
if (unit == "DEGREE")
{
double distanceErrorFactor = calculateErrorFactor(resultEnvelope, planarSRID, envelopeSRID);
std::cout << std::endl << "Distance Error Factor: " << distanceErrorFactor;
//std::cout << std::endl << "Distance Error Factor: " << distanceErrorFactor;
//calculates the equivalent geographic envelope
resultEnvelope = transformEnvelope(resultEnvelope, planarSRID, envelopeSRID);
resultEnvelope = adjustEnvelopeAspectRatio(resultEnvelope, widthByHeightFactor);
/*
double newScale = getScale(widthMM, heightMM, resultEnvelope, envelopeSRID);
double scaleErrorFactor = newScale / scale;
std::cout << std::endl << "Scale Error Factor: " << scaleErrorFactor;
std::size_t attepts = 0;
while (std::fabs(1 - scaleErrorFactor) > 0.00000001)
{
double newWidth = resultEnvelope.getWidth() / scaleErrorFactor;
double newCenterX = resultEnvelope.getCenter().x;
resultEnvelope.m_llx = newCenterX - (newWidth / 2.);
resultEnvelope.m_urx = newCenterX + (newWidth / 2.);
resultEnvelope = adjustEnvelopeAspectRatio(resultEnvelope, widthByHeightFactor);
newScale = getScale(widthMM, heightMM, resultEnvelope, envelopeSRID);
double newScaleErrorFactor = newScale / scale;
std::cout << std::endl << attepts << " - Adjusting Scale Error Factor: " << newScaleErrorFactor;
if (++attepts > 50)
{
break;
}
if (newScaleErrorFactor > scaleErrorFactor)
{
// break;
}
scaleErrorFactor = newScaleErrorFactor;
}
*/
}
return resultEnvelope;
/*
{
te::gm::Coord2D c1Planar(centerX - halfWidth, centerY);
te::gm::Coord2D c2Planar(centerX + halfWidth, centerY);
double distancePlanar = te::gm::Distance::CalculateDistance(c1Planar, c2Planar);
te::gm::Coord2D c1Geographic = transform(c1Planar, planarSRID, envelopeSRID);
te::gm::Coord2D c2Geographic = transform(c2Planar, planarSRID, envelopeSRID);
te::gm::Coord2D c1PlanarErrorCheck = transform(c1Geographic, envelopeSRID, planarSRID);
te::gm::Coord2D c2PlanarErrorCheck = transform(c2Geographic, envelopeSRID, planarSRID);
double distancePlanarError = te::gm::Distance::CalculateDistance(c1PlanarErrorCheck, c2PlanarErrorCheck);
double errorFactor = distancePlanarError / distancePlanar;
envelopeWidthForScale = te::gm::Distance::CalculateDistance(c1Geographic, c2Geographic);
envelopeWidthForScale = envelopeWidthForScale * errorFactor;
}
{
te::gm::Coord2D c1Planar(centerX, centerY - halfHeight);
te::gm::Coord2D c2Planar(centerX, centerY + halfHeight);
double distancePlanar = te::gm::Distance::CalculateDistance(c1Planar, c2Planar);
te::gm::Coord2D c1Geographic = transform(c1Planar, planarSRID, envelopeSRID);
te::gm::Coord2D c2Geographic = transform(c2Planar, planarSRID, envelopeSRID);
envelopeHeightForScale = te::gm::Distance::CalculateDistance(c1Geographic, c2Geographic);
}*/
/*double factor = static_cast<double>(widthMM) / static_cast<double>(heightMM);
if (factor > 0)
{
envelopeHeightForScale = envelopeWidthForScale / factor;
}
else
{
envelopeWidthForScale = envelopeHeightForScale / factor;
}*/
/*
double halfWidthLL = envelopeWidthForScale / 2.;
double halfHeightLL = envelopeHeightForScale / 2.;
te::gm::Envelope newEnvelope(centerGeographic.x - halfWidthLL, centerGeographic.y - halfHeightLL, centerGeographic.x + halfWidthLL, centerGeographic.y + halfHeightLL);
return newEnvelope;
*/
}
TEST_F(ITsValidation, ScaleCalculation)
{
//double expectedScale = 200000.;
double x1 = -51.211752809306248;
double y1 = -20.321073215508001;
double x2 = -50.337769198313119;
......@@ -1244,21 +1060,12 @@ namespace
double factorMM = widthMM / heightMM;
double factorWorld = geographicEnvelope.getWidth() / geographicEnvelope.getHeight();
std::cout << std::setprecision(20) << std::fixed;
std::cout << std::endl << "factor = " << factor;
std::cout << std::endl << "factorMM = " << factorMM;
std::cout << std::endl << "factorWorld = " << factorWorld;
//ASSERT_EQ(factor, factorMM);
double power = 0;
double scale = 0;
while (scale <= 100000000)
while (scale <= 1000000)
{
//initializes the scale to be tested
scale = std::pow(2, power++);
std::cout << std::endl << "------------------------";
std::cout << std::endl << "Testing scale: " << scale;
//adjusts the envelope
te::gm::Envelope adjustedEnvelope = adjustEnvelopeForScale(scale, geographicEnvelope, geographicSRID, widthMM, heightMM);
......
......@@ -30,21 +30,17 @@
//boost include files
#include <boost/bind/bind.hpp>
te::common::ThreadGroup::ThreadGroup(std::size_t numberOfThreads)
: m_ioService(new boost::asio::io_service())
te::common::ThreadGroup::ThreadGroup(std::size_t threadCount)
: m_threadCount(threadCount)
, m_ioService(new boost::asio::io_service())
, m_threadGroup(new boost::thread_group())
{
m_work.reset(new boost::asio::io_service::work(*m_ioService.get()));
//the we add the threads to the pool
if (numberOfThreads == std::string::npos)
if (m_threadCount == 0)
{
numberOfThreads = static_cast<std::size_t>(boost::thread::hardware_concurrency());
}
for (std::size_t i = 0; i < numberOfThreads; ++i)
{
m_threadGroup->create_thread(boost::bind(&boost::asio::io_service::run, m_ioService.get()));
m_threadCount = static_cast<std::size_t>(boost::thread::hardware_concurrency());
}
}
......@@ -53,6 +49,11 @@ te::common::ThreadGroup::~ThreadGroup()
waitToFinish();
}
std::size_t te::common::ThreadGroup::getThreadCount()
{
return m_threadCount;
}
void te::common::ThreadGroup::waitToFinish()
{
if (m_ioService->stopped() == true)
......@@ -60,7 +61,20 @@ void te::common::ThreadGroup::waitToFinish()
return;
}
//we MUST add the threads AFTER all the jobs are added
//this ensures that all of them will be executed
run();
//wait for the jobs to be finished
m_ioService->stop();
m_work.reset();
m_threadGroup->join_all();
}
void te::common::ThreadGroup::run()
{
for (std::size_t i = 0; i < m_threadCount; ++i)
{
m_threadGroup->create_thread(boost::bind(&boost::asio::io_service::run, m_ioService.get()));
}
}
......@@ -51,12 +51,15 @@ namespace te
{
public:
//!< Constructor. If the number of thread is not especified, it will use all available threads
ThreadGroup(std::size_t numberOfThreads = std::string::npos);
//!< Constructor. If the given thread count is 0, it will detect and use all available threads
ThreadGroup(std::size_t threadCount = 0);
//!< Destructor
~ThreadGroup();
//!< Gets the number of threads that are defined to be used by this class
std::size_t getThreadCount();
//!< Creates a new job and binds it to the given function. Use std::bind(function, object, params...) as argument
template <typename Function>
void addJob(Function func);
......@@ -64,8 +67,14 @@ namespace te
//!< Waits for all threads to finish their jobs
void waitToFinish();
protected:
private:
//!< Starts the execution of the thread group. Note that the jobs must be added before the calling of this function
void run();
private:
std::size_t m_threadCount;
std::unique_ptr<boost::asio::io_service> m_ioService; //!< Boost IO service
std::unique_ptr<boost::thread_group> m_threadGroup; //!< Boost thread group
std::unique_ptr<boost::asio::io_service::work> m_work; //!< Boost work
......
......@@ -40,7 +40,6 @@
#include "Utils.h"
//Boost include files
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/mutex.hpp>
namespace
......@@ -235,7 +234,7 @@ te::vp::FeatureSet te::vp::AttributeGroupingDataHandler::getFeatureSet(std::size
//creates a scope so the locker can be used just in the query of data
{
boost::lock_guard<boost::mutex> lockGuard(m_impl->m_mutexRead);
boost::mutex::scoped_lock lockGuard(m_impl->m_mutexRead);
dataSet = dataAccess->query(*selectGroup);
}
......@@ -267,7 +266,7 @@ void te::vp::AttributeGroupingDataHandler::addFeatureSet(std::size_t groupIndex,
std::unique_ptr<te::da::DataSet> dataSet = te::vp::CreateDataSetFromFeatureSet(dataAccess->getDataSetName(), dataAccess->getDataSetType(), featureSet);
//the lock is only used in the saving of the geometries
boost::lock_guard<boost::mutex> lockGuard(m_impl->m_mutexWrite);
boost::mutex::scoped_lock lockGuard(m_impl->m_mutexWrite);
dataAccess->saveDataSet(dataSet.release(), false);
}
......
......@@ -66,7 +66,7 @@ namespace te
bool GroupThreadManager::getNextGroup(std::vector< te::mem::DataSetItem*>& nextGroup)
{
boost::lock_guard<boost::mutex> lock(m_mtx);
boost::mutex::scoped_lock lock(m_mtx);
if (m_groupsIterator == m_groups.end())
{
......@@ -96,7 +96,7 @@ namespace te
bool GroupThreadManager::getNextOutput(std::vector< te::mem::DataSetItem*>& nextOutput)
{
boost::lock_guard<boost::mutex> lock(m_mtxOutput);
boost::mutex::scoped_lock lock(m_mtxOutput);
if (m_outputQueue.empty())
{
......@@ -158,14 +158,14 @@ namespace te
void GroupThreadManager::addOutput(std::vector<te::mem::DataSetItem*>& itemGroup)
{
boost::lock_guard<boost::mutex> lock(m_mtxOutput);
boost::mutex::scoped_lock lock(m_mtxOutput);
m_outputQueue.push_back(itemGroup);
}
void GroupThreadManager::addWarning(const std::string& warning, const bool& appendIfExists)
{
boost::lock_guard<boost::mutex> lock(m_mtxWarning);
boost::mutex::scoped_lock lock(m_mtxWarning);
if (!appendIfExists)
{
......
......@@ -111,9 +111,6 @@ std::vector<te::vp::FeatureSet> te::vp::MakeValidOperation::executeImpl(const st
double changePercent = delta * 100 / originalArea;
if (changePercent >= 1.0)
{
std::string wkt1 = geometry->toString();
std::string wkt2 = fixedGeometry->toString();
addToErrorOutput = true;
}
}
......
......@@ -27,6 +27,7 @@
#include "GeometrySnapper.h"
#include "RTreeIndex.h"
#include "../common/STLUtils.h"
#include "../common/ThreadGroup.h"
#include "../geometry/CommonDataStructures.h"
#include "../geometry/Geometry.h"
#include "../geometry/GeometryFactory.h"
......@@ -36,11 +37,6 @@
#include "../geometry/Utils.h"
#include "../sam/rtree/Index.h"
//Boost
#include <boost/thread.hpp>
#include <boost/asio/io_service.hpp>
//STL include files
#include <memory>
#include <thread>
......@@ -202,16 +198,7 @@ te::gm::GeometryVector te::vp::OverlapFixer::detectOverlaps(const std::vector<Ge
}
// we create a thread pool so we can use all the available cores
boost::asio::io_service ioService;
boost::thread_group threadGroup;
boost::asio::io_service::work work(ioService);
//the we add the threads to the pool
std::size_t numThreads = static_cast<std::size_t>(boost::thread::hardware_concurrency());
for (std::size_t i = 0; i < numThreads; ++i)
{
threadGroup.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));
}
te::common::ThreadGroup threadGroup;
//then we detect the overlaps for each geometry
//for performance purposes, we want to first calculate the intersection fragments
......@@ -224,14 +211,13 @@ te::gm::GeometryVector te::vp::OverlapFixer::detectOverlaps(const std::vector<Ge
OverlapReport* overlapReport = new OverlapReport();
//adds the jobs to the manager
ioService.post(boost::bind(CalculateIntersectionThread, i, std::ref(vecGeometries), std::ref(rtree), overlapReport));
threadGroup.addJob(boost::bind(CalculateIntersectionThread, i, std::ref(vecGeometries), std::ref(rtree), overlapReport));
vecOverlapReports.push_back(overlapReport);
}
//wait for the jobs to be finished
ioService.stop();
threadGroup.join_all();
threadGroup.waitToFinish();
te::gm::GeometryVector vecAllFragments;
for (std::size_t index = 0; index < vecOverlapReports.size(); ++index)
......@@ -266,16 +252,7 @@ void te::vp::OverlapFixer::fixOverlaps(std::vector<GeometryInfoOverlap*>& vecGeo
rtreeIndex.insert(*mbr, geometry);
}
boost::asio::io_service ioService;
boost::thread_group threadGroup;
boost::asio::io_service::work work(ioService);
//the we add the threads to the pool
std::size_t numThreads = static_cast<std::size_t>(boost::thread::hardware_concurrency());
for (std::size_t i = 0; i < numThreads; ++i)
{
threadGroup.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));
}
te::common::ThreadGroup threadGroup;
//then we fix all overlaps
std::vector<SingleFixReport*> vecFixReports;
......@@ -302,15 +279,14 @@ void te::vp::OverlapFixer::fixOverlaps(std::vector<GeometryInfoOverlap*>& vecGeo
SingleFixReport* fixReport = new SingleFixReport();
//adds the jobs to the manager
ioService.post(boost::bind(FixOverlapThread, geometry, geometryVectorCandidates, fixReport));
threadGroup.addJob(boost::bind(FixOverlapThread, geometry, geometryVectorCandidates, fixReport));
vecIndexes.push_back(index);
vecFixReports.push_back(fixReport);
}
//wait for the jobs to be finished
ioService.stop();
threadGroup.join_all();
threadGroup.waitToFinish();
for (std::size_t i = 0; i < vecFixReports.size(); ++i)
{
......
......@@ -20,6 +20,7 @@
#include "PolygonSubdivider.h"
#include "../common/STLUtils.h"
#include "../common/ThreadGroup.h"
#include "../geometry/algorithms/SafeOverlay.h"
#include "../geometry/CommonDataStructures.h"
#include "../geometry/Geometry.h"
......@@ -39,11 +40,9 @@
#include "Utils.h"
//Boost
#include <boost/asio/io_service.hpp>
#include <boost/bimap.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/connected_components.hpp>
#include <boost/thread.hpp>
te::gm::GeometryVector te::vp::PolygonSubdivider::subdivide(const te::gm::Geometry* geometry, std::size_t maxCoordinates)
{
......@@ -414,16 +413,7 @@ te::gm::GeometryVector te::vp::PolygonSubdivider::dissolveFragments(const te::gm
vecDissolveResult.reserve(clusters.size());
// we create a thread pool so we can use all the available cores
boost::asio::io_service ioService;
boost::thread_group threadGroup;
boost::asio::io_service::work work(ioService);
//the we add the threads to the pool
std::size_t numThreads = static_cast<std::size_t>(boost::thread::hardware_concurrency());
for (std::size_t i = 0; i < numThreads; ++i)
{
threadGroup.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));
}
te::common::ThreadGroup threadGroup;
std::set<std::size_t> setUsed;
for(std::size_t i = 0; i < clusters.size(); ++i)
......@@ -447,7 +437,7 @@ te::gm::GeometryVector te::vp::PolygonSubdivider::dissolveFragments(const te::gm
dissolveResult->m_geometryVector = vecAllSingleGeometries;
//adds the jobs to the manager
ioService.post(boost::bind(DissolveThread, dissolveResult));
threadGroup.addJob(boost::bind(DissolveThread, dissolveResult));
//no thread
//DissolveThread(dissolveResult);
......@@ -456,8 +446,7 @@ te::gm::GeometryVector te::vp::PolygonSubdivider::dissolveFragments(const te::gm
}
//wait for the jobs to be finished
ioService.stop();
threadGroup.join_all();
threadGroup.waitToFinish();
//then we join the results
for (std::size_t i = 0; i < vecDissolveResult.size(); ++i)
......
......@@ -23,6 +23,7 @@
#include "SubdividerTilling.h"
#include "../common/StringUtils.h"
#include "../common/STLUtils.h"
#include "../common/ThreadGroup.h"
#include "../common/progress/TaskProgress.h"
#include "../core/filesystem/FileSystem.h"
#include "../core/logger/Logger.h"
......@@ -47,10 +48,6 @@
#include "GeometrySnapper.h"
#include "Utils.h"
//Boost
#include <boost/thread.hpp>
#include <boost/asio/io_service.hpp>
class SubdivideByBorderTillingStrategyImpl
{
public:
......@@ -251,7 +248,7 @@ void MultiClipFeatureThread(const te::vp::SubdividerTilling& tilling, te::da::Da
te::common::FreeContents(vecClipResult);
//the lock is only used in the saving of the geometries
boost::lock_guard<boost::mutex> lockGuard(m_mutex);
boost::mutex::scoped_lock lockGuard(m_mutex);
//this function also deletes the items referenced from 'vecFullClipResult'
try
......@@ -280,16 +277,7 @@ te::da::DataAccess* te::vp::SubdivideByBorderTillingStrategy::subdivide(const te
std::size_t geometryPos = te::da::GetFirstSpatialPropertyPos(inputDataSet.get());
// we create a thread pool so we can use all the available cores
boost::asio::io_service ioService;
boost::thread_group threadGroup;
boost::asio::io_service::work work(ioService);
//the we add the threads to the pool
std::size_t numThreads = static_cast<std::size_t>(boost::thread::hardware_concurrency());
for (std::size_t i = 0; i < numThreads; ++i)
{
threadGroup.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));
}
te::common::ThreadGroup threadGroup;
te::mem::PreparedItemCopy copy;
......@@ -305,7 +293,7 @@ te::da::DataAccess* te::vp::SubdivideByBorderTillingStrategy::subdivide(const te
//we create 10 tiles for each thread based on the dataSetSize
std::size_t dataSetSize = inputDataSet->size();
std::size_t jobSize = static_cast<std::size_t>(std::ceil(static_cast<double>(dataSetSize) / static_cast<double>(numThreads) / static_cast<double>(10)));
std::size_t jobSize = static_cast<std::size_t>(std::ceil(static_cast<double>(dataSetSize) / static_cast<double>(threadGroup.getThreadCount()) / static_cast<double>(10)));
if (jobSize == 0)
{
jobSize = dataSetSize;
......@@ -342,7 +330,7 @@ te::da::DataAccess* te::vp::SubdivideByBorderTillingStrategy::subdivide(const te
if (vecPartialClipResult.size() == jobSize)
{
//adds the jobs to the manager
ioService.post(boost::bind(MultiClipFeatureThread, m_impl->m_tilling, outputDataAccess, converter.get(), vecPartialClipResult, maxCoordinates, m_impl->m_taskProgress));
threadGroup.addJob(boost::bind(MultiClipFeatureThread, m_impl->m_tilling, outputDataAccess, converter.get(), vecPartialClipResult, maxCoordinates, m_impl->m_taskProgress));
//no thread. This code is used to run without using multithread. Useful for debug
//MultiClipFeatureThread(m_impl->m_tilling, outputDataAccess, converter.get(), vecPartialClipResult, maxCoordinates, m_impl->m_taskProgress);
......@@ -355,7 +343,7 @@ te::da::DataAccess* te::vp::SubdivideByBorderTillingStrategy::subdivide(const te
if (vecPartialClipResult.empty() == false)
{
//adds the jobs to the manager
ioService.post(boost::bind(MultiClipFeatureThread, m_impl->m_tilling, outputDataAccess, converter.get(), vecPartialClipResult, maxCoordinates, m_impl->m_taskProgress));
threadGroup.addJob(boost::bind(MultiClipFeatureThread, m_impl->m_tilling, outputDataAccess, converter.get(), vecPartialClipResult, maxCoordinates, m_impl->m_taskProgress));
//no thread. This code is used to run without using multithread. Useful for debug
//MultiClipFeatureThread(m_impl->m_tilling, outputDataAccess, converter.get(), vecPartialClipResult, maxCoordinates, m_impl->m_taskProgress);
......@@ -364,8 +352,7 @@ te::da::DataAccess* te::vp::SubdivideByBorderTillingStrategy::subdivide(const te
}
//wait for the jobs to be finished
ioService.stop();
threadGroup.join_all();
threadGroup.waitToFinish();
return outputDataAccess;
}
......@@ -448,7 +435,7 @@ void DissolveMultiThread(te::da::DataAccess* outputDataAccess, const std::vector
}
//the lock is only used in the saving of the geometries
boost::lock_guard<boost::mutex> lockGuard(m_mutex);
boost::mutex::scoped_lock lockGuard(m_mutex);
//this function also deletes the items referenced from 'vecFullClipResult'
try
......@@ -509,16 +496,7 @@ te::da::DataAccess* te::vp::SubdivideByBorderTillingStrategy::merge(te::da::Data
te::gm::GeomType outputGeomType = geometryProperty->getGeometryType();
// we create a thread pool so we can use all the available cores
boost::asio::io_service ioService;
boost::thread_group threadGroup;
boost::asio::io_service::work work(ioService);
//the we add the threads to the pool
std::size_t numThreads = static_cast<std::size_t>(boost::thread::hardware_concurrency());
for (std::size_t i = 0; i < numThreads; ++i)
{
threadGroup.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));
}
te::common::ThreadGroup threadGroup;
std::string query = "SELECT * FROM " + inputDataAccess->getDataSetName();
if (vecMergeColumns.empty() == false)
......@@ -533,7 +511,7 @@ te::da::DataAccess* te::vp::SubdivideByBorderTillingStrategy::merge(te::da::Data
//we create 10 tiles for each thread based on the dataSetSize
std::size_t dataSetSize = inputDataSet->size();
std::size_t jobSize = static_cast<std::size_t>(std::ceil(static_cast<double>(dataSetSize) / static_cast<double>(numThreads) / static_cast<double>(10)));
std::size_t jobSize = static_cast<std::size_t>(std::ceil(static_cast<double>(dataSetSize) / static_cast<double>(threadGroup.getThreadCount()) / static_cast<double>(10)));
if (jobSize == 0)
{
jobSize = dataSetSize;
......@@ -618,7 +596,7 @@ te::da::DataAccess* te::vp::SubdivideByBorderTillingStrategy::merge(te::da::Data
if (fsTile.size() == jobSize)
{
//adds the jobs to the manager
ioService.post(boost::bind(DissolveMultiThread, outputDataAccess, fsTile, m_impl->m_taskProgress, rowIndex, columnIndex, dissolveGeometryCoordinateSubdivision));
threadGroup.addJob(boost::bind(DissolveMultiThread, outputDataAccess, fsTile, m_impl->m_taskProgress, rowIndex, columnIndex, dissolveGeometryCoordinateSubdivision));
fsTile = std::vector<te::vp::FeatureSet>();
fsTile.reserve(jobSize);
}
......@@ -632,13 +610,12 @@ te::da::DataAccess* te::vp::SubdivideByBorderTillingStrategy::merge(te::da::Data
if (fsTile.empty() == false)
{
//adds the jobs to the manager
ioService.post(boost::bind(DissolveMultiThread, outputDataAccess, fsTile, m_impl->m_taskProgress, rowIndex, columnIndex, dissolveGeometryCoordinateSubdivision));
threadGroup.addJob(boost::bind(DissolveMultiThread, outputDataAccess, fsTile, m_impl->m_taskProgress, rowIndex, columnIndex, dissolveGeometryCoordinateSubdivision));
fsTile = std::vector<te::vp::FeatureSet>();
}
//wait for the jobs to be finished
ioService.stop();
threadGroup.join_all();
threadGroup.waitToFinish();
return outputDataAccess;
}
......
......@@ -73,7 +73,8 @@ public:
std::size_t m_chunckSize;
std::size_t m_groupCount;
std::vector<GroupInfo*> m_groupInfo;
boost::mutex m_mutex;
boost::mutex m_mutexRead;
boost::mutex m_mutexWrite;
};
te::vp::UnorderedGroupingDataHandler::UnorderedGroupingDataHandler()
......@@ -131,7 +132,7 @@ std::size_t te::vp::UnorderedGroupingDataHandler::getGroupCount() const
te::vp::FeatureSet te::vp::UnorderedGroupingDataHandler::getFeatureSet(std::size_t groupIndex, std::size_t inputIndex, const te::gm::Envelope& filter)
{
boost::lock_guard<boost::mutex> lockGuard(m_impl->m_mutex);
boost::mutex::scoped_lock lockGuard(m_impl->m_mutexRead);
GroupInfo* groupInfo = m_impl->m_groupInfo.at(inputIndex);
......@@ -152,7 +153,7 @@ te::vp::FeatureSet te::vp::UnorderedGroupingDataHandler::getFeatureSet(std::size
void te::vp::UnorderedGroupingDataHandler::addFeatureSet(std::size_t groupIndex, std::size_t outputIndex, const te::vp::FeatureSet& featureSet)
{
boost::lock_guard<boost::mutex> lockGuard(m_impl->m_mutex);
boost::mutex::scoped_lock lockGuard(m_impl->m_mutexWrite);
te::da::DataAccess* dataAccess = m_vecOutputData.at(outputIndex);
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!