std::shared_ptr<FieldHeights> FieldExporter::FieldExporterCSV::loadHeights(std::string filename) { try { FileReader br(filename); int linen = 0; std::set<double> xset; std::set<double> yset; auto poinycomparator = [](const glm::vec2 v1, const glm::vec2 v2) -> bool { return v1.y < v2.y ? true : v1.x == v2.x && v1.y < v2.y ? true : false; }; std::map<glm::vec2, glm::vec2, decltype(poinycomparator)> pointmap(poinycomparator); while (!br.eof()) { std::string line = br.readLine(); if (linen++ == 0) continue; std::vector<std::string> linevalues = Utils::tokenize(line, "\t"); if (linevalues.size() < 3) continue; const double x = std::stod(linevalues[0]); const double y = std::stod(linevalues[1]); const double vmin = std::stod(linevalues[2]); const double vmax = std::stod(linevalues[3]); xset.insert(x); yset.insert(y); pointmap[glm::vec2(x, y)] = glm::vec2(vmin, vmax); } const std::vector<double> xs = adjustDeltas(doubleSetToSortedArray(xset)); const std::vector<double> ys = adjustDeltas(doubleSetToSortedArray(yset)); yMatrix<double> vmin(xs.size(), ys.size()); yMatrix<double> vmax(xs.size(), ys.size()); for (unsigned y = 0; y<ys.size(); y++) for (unsigned x = 0; x<xs.size(); x++) { const auto& v = glm::vec2(xs[x], ys[y]); if (pointmap.find(v) == pointmap.end()) { vmin.set(x, y, FieldHeights::UNUSED); vmax.set(x, y, FieldHeights::UNUSED); } else { vmin.set(x, y, v.x); vmax.set(x, y, v.y); } } const glm::vec2 spacing(xs[1] - xs[0], ys[1] - ys[0]); const glm::vec2 center((xs[xs.size() - 1] + xs[0]) / 2, (ys[ys.size() - 1] + ys[0]) / 2); return std::make_shared<FieldHeights>(vmin, vmax, center, spacing); } catch (...) { return std::shared_ptr<FieldHeights>(nullptr); } }
std::shared_ptr<FieldHorizontalPlane> FieldExporter::FieldExporterCSV::loadHorizontalPlane(std::string filename) { try { FileReader br(filename); int linen = 0; std::set<double> xset; std::set<double> yset; auto poinycomparator = [](const glm::vec2 v1, const glm::vec2 v2) -> bool { return v1.y < v2.y ? true : v1.x == v2.x && v1.y < v2.y ? true : false; }; std::map<glm::vec2, double, decltype(poinycomparator)> pointmap(poinycomparator); while (!br.eof()) { const std::string line = br.readLine(); if (linen++ == 0) continue; const std::vector<std::string> linevalues = Utils::tokenize(line, "\t"); if (linevalues.size() < 3) continue; const double x = std::stod(linevalues[0]); const double y = std::stod(linevalues[1]); const double v = std::stod(linevalues[2]); xset.insert(x); yset.insert(y); pointmap[glm::vec2(x, y)] = v; } const std::vector<double> xs = adjustDeltas(doubleSetToSortedArray(xset)); const std::vector<double> ys = adjustDeltas(doubleSetToSortedArray(yset)); yMatrix<double> mat(xs.size(), ys.size()); for (unsigned y = 0; y<ys.size(); y++) for (unsigned x = 0; x<xs.size(); x++) { const double v = pointmap[glm::vec2(xs[x], ys[y])]; mat.set(x, y, v); } const glm::vec2 spacing(xs[1] - xs[0], ys[1] - ys[0]); const glm::vec3 center((xs[xs.size() - 1] + xs[0]) / 2, (ys[ys.size() - 1] + ys[0]) / 2, 0); return std::make_shared<FieldHorizontalPlane>(mat, center, spacing); } catch (...) { return std::shared_ptr<FieldHorizontalPlane>(nullptr); } }
TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL( ThyraBlockedOperator, XpetraBlockedCrsMatConstructor, Scalar, LO, GO, Node ) { #ifdef HAVE_XPETRA_THYRA #ifdef HAVE_XPETRA_EPETRAEXT Teuchos::RCP<const Teuchos::Comm<int> > comm = Teuchos::DefaultComm<int>::getComm(); const Teuchos::RCP<const Epetra_Comm> epComm = Xpetra::toEpetra(comm); // 1) load all matrices Epetra_Map pointmap(36,0,*epComm); // generate local maps for loading matrices std::vector<int> velgidvec; // global strided maps std::vector<int> pregidvec; std::vector<int> fullgidvec; // full global map for (int i=0; i<pointmap.NumMyElements(); i++) { // loop over all local ids in pointmap // get corresponding global id int gid = pointmap.GID(i); // store global strided gids velgidvec.push_back(3*gid); velgidvec.push_back(3*gid+1); pregidvec.push_back(3*gid+2); // gid for full map fullgidvec.push_back(3*gid); fullgidvec.push_back(3*gid+1); fullgidvec.push_back(3*gid+2); } // generate strided maps Teuchos::RCP<const Epetra_Map> velmap = Teuchos::rcp(new const Epetra_Map(-1, velgidvec.size(), &velgidvec[0], 0, *epComm)); Teuchos::RCP<const Epetra_Map> premap = Teuchos::rcp(new const Epetra_Map(-1, pregidvec.size(), &pregidvec[0], 0, *epComm)); // generate full map const Teuchos::RCP<const Epetra_Map> fullmap = Teuchos::rcp(new const Epetra_Map(-1, fullgidvec.size(), &fullgidvec[0], 0, *epComm)); // read in matrices Epetra_CrsMatrix* ptrA = 0; EpetraExt::MatrixMarketFileToCrsMatrix("A.mat",*fullmap,*fullmap,*fullmap,ptrA); Teuchos::RCP<Epetra_CrsMatrix> fullA = Teuchos::rcp(ptrA); Teuchos::RCP<Epetra_Vector> x = Teuchos::rcp(new Epetra_Vector(*fullmap)); x->PutScalar(1.0); // split fullA into A11,..., A22 Teuchos::RCP<Epetra_CrsMatrix> A11; Teuchos::RCP<Epetra_CrsMatrix> A12; Teuchos::RCP<Epetra_CrsMatrix> A21; Teuchos::RCP<Epetra_CrsMatrix> A22; TEST_EQUALITY(SplitMatrix2x2(fullA,*velmap,*premap,A11,A12,A21,A22),true); // build Xpetra objects from Epetra_CrsMatrix objects Teuchos::RCP<Xpetra::CrsMatrix<Scalar,LO,GO,Node> > xfuA = Teuchos::rcp(new Xpetra::EpetraCrsMatrixT<GO,Node>(fullA)); Teuchos::RCP<Xpetra::CrsMatrix<Scalar,LO,GO,Node> > xA11 = Teuchos::rcp(new Xpetra::EpetraCrsMatrixT<GO,Node>(A11)); Teuchos::RCP<Xpetra::CrsMatrix<Scalar,LO,GO,Node> > xA12 = Teuchos::rcp(new Xpetra::EpetraCrsMatrixT<GO,Node>(A12)); Teuchos::RCP<Xpetra::CrsMatrix<Scalar,LO,GO,Node> > xA21 = Teuchos::rcp(new Xpetra::EpetraCrsMatrixT<GO,Node>(A21)); Teuchos::RCP<Xpetra::CrsMatrix<Scalar,LO,GO,Node> > xA22 = Teuchos::rcp(new Xpetra::EpetraCrsMatrixT<GO,Node>(A22)); // build map extractor Teuchos::RCP<Xpetra::EpetraMapT<GO,Node> > xfullmap = Teuchos::rcp(new Xpetra::EpetraMapT<GO,Node>(fullmap)); Teuchos::RCP<Xpetra::EpetraMapT<GO,Node> > xvelmap = Teuchos::rcp(new Xpetra::EpetraMapT<GO,Node>(velmap )); Teuchos::RCP<Xpetra::EpetraMapT<GO,Node> > xpremap = Teuchos::rcp(new Xpetra::EpetraMapT<GO,Node>(premap )); std::vector<Teuchos::RCP<const Xpetra::Map<LO,GO,Node> > > xmaps; xmaps.push_back(xvelmap); xmaps.push_back(xpremap); Teuchos::RCP<const Xpetra::MapExtractor<Scalar,LO,GO,Node> > map_extractor = Xpetra::MapExtractorFactory<Scalar,LO,GO,Node>::Build(xfullmap,xmaps); // build blocked operator Teuchos::RCP<Xpetra::BlockedCrsMatrix<Scalar,LO,GO,Node> > bOp = Teuchos::rcp(new Xpetra::BlockedCrsMatrix<Scalar,LO,GO,Node>(map_extractor,map_extractor,10)); bOp->setMatrix(0,0,xA11); bOp->setMatrix(0,1,xA12); bOp->setMatrix(1,0,xA21); bOp->setMatrix(1,1,xA22); bOp->fillComplete(); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(bOp)); // create Thyra operator Teuchos::RCP<Thyra::LinearOpBase<Scalar> > thOp = Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(bOp); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thOp)); Teuchos::RCP<Thyra::BlockedLinearOpBase<Scalar> > thbOp = Teuchos::rcp_dynamic_cast<Thyra::BlockedLinearOpBase<Scalar> >(thOp); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thbOp)); Teuchos::RCP<const Thyra::ProductVectorSpaceBase<Scalar> > productRange = thbOp->productRange(); Teuchos::RCP<const Thyra::ProductVectorSpaceBase<Scalar> > productDomain = thbOp->productDomain(); TEST_EQUALITY(productRange->numBlocks() ,2); TEST_EQUALITY(productDomain->numBlocks() ,2); TEST_EQUALITY(Teuchos::as<Xpetra::global_size_t>(productRange->dim()) ,xfullmap->getGlobalNumElements()); TEST_EQUALITY(Teuchos::as<Xpetra::global_size_t>(productDomain->dim()) ,xfullmap->getGlobalNumElements()); TEST_EQUALITY(Teuchos::as<Xpetra::global_size_t>(productRange->getBlock(0)->dim()) ,xvelmap->getGlobalNumElements()); TEST_EQUALITY(Teuchos::as<Xpetra::global_size_t>(productDomain->getBlock(0)->dim()) ,xvelmap->getGlobalNumElements()); TEST_EQUALITY(Teuchos::as<Xpetra::global_size_t>(productRange->getBlock(1)->dim()) ,xpremap->getGlobalNumElements()); TEST_EQUALITY(Teuchos::as<Xpetra::global_size_t>(productDomain->getBlock(1)->dim()) ,xpremap->getGlobalNumElements()); //construct a Xpetra::BlockedCrsMatrix object Teuchos::RCP<Xpetra::BlockedCrsMatrix<Scalar, LO, GO, Node> > bOp2 = Teuchos::rcp(new Xpetra::BlockedCrsMatrix<Scalar, LO, GO, Node>(thbOp,comm)); TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(bOp2)); TEST_EQUALITY(bOp2->getGlobalNumRows(),bOp->getGlobalNumRows()); TEST_EQUALITY(bOp2->getGlobalNumCols(),bOp->getGlobalNumCols()); TEST_EQUALITY(bOp2->getNodeNumRows(),bOp->getNodeNumRows()); TEST_EQUALITY(bOp2->getGlobalNumEntries(),bOp->getGlobalNumEntries()); TEST_EQUALITY(bOp2->getNodeNumEntries(),bOp->getNodeNumEntries()); TEST_EQUALITY(bOp2->isFillComplete(),bOp->isFillComplete()); TEST_EQUALITY(bOp2->getDomainMap()->isCompatible(*bOp->getDomainMap()),true); TEST_EQUALITY(bOp2->getRangeMap()->isCompatible(*bOp->getRangeMap()),true); TEST_EQUALITY(bOp2->getDomainMap(0)->isCompatible(*bOp->getDomainMap(0)),true); TEST_EQUALITY(bOp2->getRangeMap(0)->isCompatible(*bOp->getRangeMap(0)),true); TEST_EQUALITY(bOp2->getDomainMap(1)->isCompatible(*bOp->getDomainMap(1)),true); TEST_EQUALITY(bOp2->getRangeMap(1)->isCompatible(*bOp->getRangeMap(1)),true); TEST_EQUALITY(bOp2->getDomainMap()->isSameAs(*bOp->getDomainMap()),true); TEST_EQUALITY(bOp2->getRangeMap()->isSameAs(*bOp->getRangeMap()),true); TEST_EQUALITY(bOp2->getDomainMap(0)->isSameAs(*bOp->getDomainMap(0)),true); TEST_EQUALITY(bOp2->getRangeMap(0)->isSameAs(*bOp->getRangeMap(0)),true); TEST_EQUALITY(bOp2->getDomainMap(1)->isSameAs(*bOp->getDomainMap(1)),true); TEST_EQUALITY(bOp2->getRangeMap(1)->isSameAs(*bOp->getRangeMap(1)),true); #endif // end HAVE_XPETRA_EPETRAEXT #endif // end HAVE_XPETRA_THYRA }
int process( boost::shared_ptr<Logger> qLogger, boost::shared_ptr<ProcessingSettings> qSettings, std::string sLayer, bool bVerbose, bool bLock, int epsg, std::string sPointFile, bool bFill, int& out_lod, int64& out_x0, int64& out_y0, int64& out_z0, int64& out_x1, int64& out_y1, int64& out_z1) { clock_t t0,t1; t0 = clock(); if (!ProcessingUtils::init_gdal()) { qLogger->Error("gdal-data directory not found!"); return ERROR_GDAL; } boost::shared_ptr<CoordinateTransformation> qCT; qCT = boost::shared_ptr<CoordinateTransformation>(new CoordinateTransformation(epsg, 4326)); //--------------------------------------------------------------------------- // Retrieve PointLayerSettings: std::ostringstream oss; std::string sPointLayerDir = FilenameUtils::DelimitPath(qSettings->GetPath()) + sLayer; std::string sTileDir = FilenameUtils::DelimitPath(FilenameUtils::DelimitPath(sPointLayerDir) + "tiles"); std::string sTempDir = FilenameUtils::DelimitPath(FilenameUtils::DelimitPath(sPointLayerDir) + "temp/tiles"); std::string sIndexFile = FilenameUtils::DelimitPath(sPointLayerDir) + "temp/" + FilenameUtils::ExtractBaseFileName(sPointFile) + ".idx"; boost::shared_ptr<PointLayerSettings> qPointLayerSettings = PointLayerSettings::Load(sPointLayerDir); if (!qPointLayerSettings) { qLogger->Error("Failed retrieving point layer settings! Make sure to create it using 'createlayer'."); ProcessingUtils::exit_gdal(); return ERROR_ELVLAYERSETTINGS; } int lod = qPointLayerSettings->GetMaxLod(); double x0, y0, z0, x1, y1, z1; qPointLayerSettings->GetBoundary(x0, y0, z0, x1, y1, z1); if (bVerbose) { oss << "Point Layer:\n"; oss << " name = " << qPointLayerSettings->GetLayerName() << "\n"; oss << " maxlod = " << lod << "\n"; oss << " boundary = (" << x0 << ", " << y0 << ", " << z0 << ")-(" << x1 << ", " << y1 << ", " << z1 << ")\n"; qLogger->Info(oss.str()); oss.str(""); } double lodlen = pow(2.0,lod); //------------------------------------------------------------------------ // Calculate matrix for octree voxel data transformation double xcenter, ycenter, zcenter; xcenter = x0 + fabs(x1-x0)*0.5; ycenter = y0 + fabs(y1-y0)*0.5; zcenter = z0 + fabs(z1-z0)*0.5; // elevation is currently ignored and set to 0 double len = OCTREE_CUBE_SIZE; // octree cube size mat4<double> L, Linv; // center to radiant double lng = DEG2RAD(xcenter); double lat = DEG2RAD(ycenter); // center to cartesian coord vec3<double> vCenter; GeoCoord geoCenter(xcenter, ycenter, zcenter); geoCenter.GetCartesian(vCenter); // create orthonormal basis // (and create 4x4 matrix with translation to vCenter) // scale to normalized geozentric cartesian coordinates (scaled meters) double scalelen = CARTESIAN_SCALE_INV * len; // translate to center (lng,lat) mat4<double> matTrans; matTrans.SetTranslation(vCenter); mat4<double> matNavigation; //matNavigation.CalcNavigationFrame(lng, lat); // Navigation frame with z-axis up! matNavigation.Set( -sin(lng), -sin(lat)*cos(lng), cos(lat)*cos(lng), 0, cos(lng), -sin(lat)*sin(lng), cos(lat)*sin(lng), 0, 0, cos(lat), sin(lat), 0, 0, 0, 0, 1); // scale to range [-0.5,0.5] (local coordinates) mat4<double> matScale; matScale.SetScale(scalelen); // translate to range [0,1] mat4<double> matTrans2; matTrans2.SetTranslation(-0.5, -0.5, -0.5); L = matTrans; // translate to vCenter L *= matNavigation; // rotate to align ellipsoid normal L *= matScale; // scale to [-0.5, 0.5] L *= matTrans2; // translate [0.5, 0.5, 0.5] to have range [0,1] Linv = L.Inverse(); // create inverse of this transformation //------------------------------------------------------------------------ size_t numpts = 0; size_t totalpoints = 0; CloudPoint pt; CloudPoint pt_octree; // point in octree coords PointCloudReader pr; PointMap pointmap(lod); if (pr.Open(sPointFile)) { GeoCoord in_geopt; vec3<double> in_pt_cart; // point in geocentric cartesian coordinates (WGS84) vec3<double> out_pt_octree; // point in local octree coordinates while (pr.ReadPoint(pt)) { qCT->Transform(&pt.x, &pt.y); in_geopt.SetLongitude(pt.x); in_geopt.SetLatitude(pt.y); in_geopt.SetEllipsoidHeight(pt.elevation); in_geopt.ToCartesian(&in_pt_cart.x, &in_pt_cart.y, &in_pt_cart.z); out_pt_octree = Linv.vec3mul(in_pt_cart); pt_octree.r = pt.r; pt_octree.g = pt.g; pt_octree.b = pt.b; pt_octree.a = pt.a; pt_octree.intensity = pt.intensity; pt_octree.x = out_pt_octree.x; pt_octree.y = out_pt_octree.y; pt_octree.elevation = out_pt_octree.z; int64 octreeX = int64(out_pt_octree.x * lodlen); int64 octreeY = int64(out_pt_octree.y * lodlen); int64 octreeZ = int64(out_pt_octree.z * lodlen); // now we have the octree coordinate (octreeX,Y,Z) of the point // -> add the point to pointmap (which is actually a hash map) // -> note: don't calculate the octocode for each point, it would be way too slow. pointmap.AddPoint(octreeX, octreeY, octreeZ, pt_octree); if (pointmap.GetNumPoints()>membuffer) { totalpoints+=pointmap.GetNumPoints(); pointmap.ExportData(sTempDir); pointmap.Clear(); } numpts++; } } else { return -1; } if (pointmap.GetNumPoints()>0) pointmap.ExportData(sTempDir); totalpoints+=pointmap.GetNumPoints(); // export list of all written tiles (for future processing) if (bVerbose) { oss << "Exporting index...\n"; qLogger->Info(oss.str()); oss.str(""); } pointmap.ExportIndex(sIndexFile); //------------------------------------------------------------------------ ProcessingUtils::exit_gdal(); std::cout << "Pointmap Stats:\n"; std::cout << " numpoints: " << totalpoints << "\n"; t1 = clock(); std::cout << "calculated in: " << double(t1-t0)/double(CLOCKS_PER_SEC) << " s \n"; return 0; }