Пример #1
0
	void checkPolylineProperties()
	{
		const GeoLib::PolylineVec *line_vec = geo_objects.getPolylineVecObj(geo_name);
		auto const readerLines = geo_objects.getPolylineVec(geo_name);
		EXPECT_EQ(5u, readerLines->size());

		auto checkPolylineProperty = [this](GeoLib::PolylineVec const* line_vec,
			std::size_t ply_id, std::vector<std::size_t> pnt_ids,
			std::string const& name)
		{
			auto const lines = geo_objects.getPolylineVec(geo_name);
			GeoLib::Polyline* line = (*lines)[ply_id];
			EXPECT_EQ(pnt_ids.size(), line->getNumberOfPoints());
			for (std::size_t k(0); k<pnt_ids.size(); ++k)
				EXPECT_EQ(pnt_ids[k], line->getPointID(k));
			std::string line_name;
			line_vec->getNameOfElementByID(ply_id, line_name);
			EXPECT_EQ(name, line_name);
		};

		checkPolylineProperty(line_vec, 0, {0, 1, 2}, "left");
		checkPolylineProperty(line_vec, 1, {3, 4, 5}, "center");
		checkPolylineProperty(line_vec, 2, {0, 3}, "line1");
		checkPolylineProperty(line_vec, 3, {3, 6}, "line2");
		checkPolylineProperty(line_vec, 4, {6, 7, 8}, "right");
	}
MathLib::PiecewiseLinearInterpolation LinearInterpolationAlongPolyline::createInterpolation(
		const GeoLib::Polyline& ply,
		const std::vector<std::size_t>& vec_interpolate_point_ids,
		const std::vector<double>& vec_interpolate_point_values)
{
	std::vector<double> vec_known_dist;
	std::vector<double> vec_known_values;
	vec_known_dist.reserve(vec_interpolate_point_ids.size());
	vec_known_values.reserve(vec_interpolate_point_ids.size());
	for (std::size_t i=0; i<vec_interpolate_point_ids.size(); i++)
	{
		const std::size_t pnt_id = vec_interpolate_point_ids[i];
		if (!ply.isPointIDInPolyline(pnt_id))
			continue;

		for (std::size_t j=0; j<ply.getNumberOfPoints(); j++)
		{
			if (pnt_id == ply.getPointID(j))
			{
				vec_known_dist.push_back(ply.getLength(j));
				vec_known_values.push_back(vec_interpolate_point_values[i]);
				break;
			}
		}
	}

	return MathLib::PiecewiseLinearInterpolation(vec_known_dist, vec_known_values);
}
Пример #3
0
PolylineWithSegmentMarker::PolylineWithSegmentMarker(
    GeoLib::Polyline const& polyline)
    : GeoLib::Polyline(polyline), _marker(polyline.getNumberOfSegments(), false)
{
}
Пример #4
0
PolygonWithSegmentMarker::PolygonWithSegmentMarker(
    GeoLib::Polyline const& polyline)
    : GeoLib::Polygon(polyline, true),
      _marker(polyline.getNumberOfPoints(), false)
{
}
Пример #5
0
void GeoMapper::advancedMapOnMesh(const MeshLib::Mesh* mesh, const std::string &new_geo_name)
{
	const std::vector<GeoLib::Point*> *points (this->_geo_objects.getPointVec(this->_geo_name));
	const std::vector<GeoLib::Polyline*> *org_lines (this->_geo_objects.getPolylineVec(this->_geo_name));

	const GeoLib::AABB<GeoLib::Point> aabb(points->begin(), points->end());
	const double eps = sqrt(std::numeric_limits<float>::epsilon()) *
		               sqrt( MathLib::sqrDist(aabb.getMinPoint(),aabb.getMaxPoint())) ;

	// copy geometry (and set z=0 for all points)
	unsigned nGeoPoints ( points->size() );
	std::vector<GeoLib::Point*> *new_points = new std::vector<GeoLib::Point*>(nGeoPoints);
	for (size_t i=0; i<nGeoPoints; ++i)
		(*new_points)[i] = new GeoLib::Point((*(*points)[i])[0],(*(*points)[i])[1],0.0);
	std::vector<GeoLib::Polyline*> *new_lines (copyPolylinesVector(this->_geo_objects.getPolylineVec(this->_geo_name), new_points));

	GeoLib::Grid<GeoLib::Point> grid(new_points->begin(), new_points->end());
	double max_segment_length (this->getMaxSegmentLength(*new_lines));
	max_segment_length *= max_segment_length; // squared so it can be compared to the squared distances calculated later
	
	const unsigned nMeshNodes ( mesh->getNNodes() );	
	std::vector<int> closest_geo_point(nMeshNodes); // index of closest geo point for each mesh node in (x,y)-plane
	std::vector<double> dist(nMeshNodes);  // distance between geo points and mesh nodes in (x,y)-plane
	for (size_t i=0; i<nMeshNodes; ++i)
	{
		const double zero_coords[3] = {(* mesh->getNode(i))[0], (* mesh->getNode(i))[1], 0.0};
		GeoLib::Point* pnt = grid.getNearestPoint(zero_coords);
		dist[i] = MathLib::sqrDist(pnt->getCoords(), zero_coords);
		closest_geo_point[i] = (dist[i]<=max_segment_length) ? getIndexInPntVec(pnt, new_points) : -1;
	}
	
	// store for each point the line segment to which it was added.
	const size_t nLines (new_lines->size());
	std::vector< std::vector<unsigned> > line_segment_map(nLines);
	for (std::size_t i=0; i<nLines; ++i)
	{
		line_segment_map[i] = std::vector<unsigned>((*new_lines)[i]->getNumberOfPoints(),0);
		std::iota(line_segment_map[i].begin(), line_segment_map[i].end(), 0);
	}

	for (std::size_t i=0; i<nMeshNodes; ++i)
	{
		// if mesh node too far away or exactly at point position
		if (closest_geo_point[i] == -1 || dist[i] < eps) continue; 

		const MeshLib::Node* node (mesh->getNode(i));
		for (std::size_t l=0; l<nLines; ++l)
		{
			// find relevant polylines
			if (!(*org_lines)[l]->isPointIDInPolyline(closest_geo_point[i])) continue;
			
			// find point position of closest geo point in original polyline
			GeoLib::Polyline* ply ((*org_lines)[l]);
			std::size_t nLinePnts ( ply->getNumberOfPoints() );
			std::size_t node_index_in_ply (0);
			for (node_index_in_ply=0; node_index_in_ply<nLinePnts; ++node_index_in_ply)
				if (ply->getPoint(node_index_in_ply) == (*points)[closest_geo_point[i]])
					break;
			const GeoLib::Point* geo_point (ply->getPoint(node_index_in_ply));

			// check if line segments connected to closest geo point intersect connected elements of current node
			const std::vector<MeshLib::Element*> elements (node->getElements());
			const std::size_t nElems = elements.size();
			for (std::size_t e=0; e<nElems; ++e)
			{
				const unsigned nEdges (elements[e]->getNEdges());
				unsigned intersection_count (0);

				for (unsigned n=0; n<nEdges; ++n)
				{
					if (intersection_count>1) break; //already two intersections

					const MeshLib::Element* line = elements[e]->getEdge(n);
					unsigned index_offset(0); // default: add to first line segment
					GeoLib::Point* intersection (NULL);
					if (node_index_in_ply>0) // test line segment before closest point
						intersection = calcIntersection(line->getNode(0), line->getNode(1), geo_point, ply->getPoint(node_index_in_ply-1));
					if (intersection == NULL && node_index_in_ply<(nLinePnts-1)) // test line segment after closest point
					{
						intersection = calcIntersection(line->getNode(0), line->getNode(1), geo_point, ply->getPoint(node_index_in_ply+1));
						index_offset = 1; // add to second segment
					}
					if (intersection)
					{
						intersection_count++;
						unsigned start_point_idx = static_cast<unsigned>(std::distance(line_segment_map[l].begin(), std::find_if(line_segment_map[l].begin(), line_segment_map[l].end(), [&node_index_in_ply, &index_offset](unsigned a){return a==node_index_in_ply+index_offset-1;})));
						unsigned end_point_idx   = static_cast<unsigned>(std::distance(line_segment_map[l].begin(), std::find_if(line_segment_map[l].begin(), line_segment_map[l].end(), [&node_index_in_ply, &index_offset](unsigned a){return a==node_index_in_ply+index_offset;})));
						std::size_t pos = getPointPosInLine((*new_lines)[l], start_point_idx, end_point_idx, intersection, eps);

						if (pos)
						{
							const std::size_t pnt_pos (new_points->size());
							new_points->push_back(intersection);
							(*new_lines)[l]->insertPoint(pos, pnt_pos);
							line_segment_map[l].insert(line_segment_map[l].begin()+pos, node_index_in_ply+index_offset-1);
						}
					}
				}
			}
		}
	}

	this->_geo_objects.addPointVec(new_points, const_cast<std::string&>(new_geo_name));
	std::vector<size_t> pnt_id_map = this->_geo_objects.getPointVecObj(new_geo_name)->getIDMap();
	for (std::size_t i=0; i<new_lines->size(); ++i)
		(*new_lines)[i]->updatePointIDs(pnt_id_map);
	this->_geo_objects.addPolylineVec(new_lines, new_geo_name);

	// map new geometry incl. additional point using the normal mapping method
	this->_geo_name = new_geo_name;
	this->mapOnMesh(mesh);
}
Пример #6
0
TEST(FileIO, XmlGmlWriterReaderTest)
{
	// Writer test
	std::string test_data_file(BaseLib::BuildInfo::source_path + "/Tests/FileIO/xmlgmltestdata.gml");

	GeoLib::GEOObjects geo_objects;

	//setup test data
	std::string geo_name("TestData");

	{   // Create points.
		auto points = std::unique_ptr<std::vector<GeoLib::Point*>>(
		    new std::vector<GeoLib::Point*>(10));

		(*points)[0] = new GeoLib::Point(1, 1, 0);
		(*points)[1] = new GeoLib::Point(1, 1, 0);
		(*points)[2] = new GeoLib::Point(1, 2, 0);
		(*points)[3] = new GeoLib::Point(1, 3, 0);
		(*points)[4] = new GeoLib::Point(2, 1, 0);
		(*points)[5] = new GeoLib::Point(2, 2, 0);
		(*points)[6] = new GeoLib::Point(2, 3, 0);
		(*points)[7] = new GeoLib::Point(3, 1, 0);
		(*points)[8] = new GeoLib::Point(3, 2, 0);
		(*points)[9] = new GeoLib::Point(3, 3, 0);
		geo_objects.addPointVec(std::move(points), geo_name);
	}
	auto const points = geo_objects.getPointVec(geo_name);

	const std::vector<std::size_t> pnt_id_map (geo_objects.getPointVecObj(geo_name)->getIDMap());

	{   // Create polylines.
		auto lines = std::unique_ptr<std::vector<GeoLib::Polyline*>>(
		    new std::vector<GeoLib::Polyline*>(5));
		std::map<std::string, std::size_t>* ply_names =
		    new std::map<std::string, std::size_t>;
		(*lines)[0] = new GeoLib::Polyline(*points);
		(*lines)[0]->addPoint(pnt_id_map[0]);
		(*lines)[0]->addPoint(pnt_id_map[2]);
		(*lines)[0]->addPoint(pnt_id_map[3]);
		ply_names->insert(std::pair<std::string, std::size_t>("left", 0));
		(*lines)[1] = new GeoLib::Polyline(*points);
		(*lines)[1]->addPoint(pnt_id_map[4]);
		(*lines)[1]->addPoint(pnt_id_map[5]);
		(*lines)[1]->addPoint(pnt_id_map[6]);
		ply_names->insert(std::pair<std::string, std::size_t>("center", 1));
		(*lines)[2] = new GeoLib::Polyline(*points);
		(*lines)[2]->addPoint(pnt_id_map[1]);
		(*lines)[2]->addPoint(pnt_id_map[4]);
		(*lines)[3] = new GeoLib::Polyline(*points);
		(*lines)[3]->addPoint(pnt_id_map[4]);
		(*lines)[3]->addPoint(pnt_id_map[7]);
		(*lines)[4] = new GeoLib::Polyline(*points);
		(*lines)[4]->addPoint(pnt_id_map[7]);
		(*lines)[4]->addPoint(pnt_id_map[8]);
		(*lines)[4]->addPoint(pnt_id_map[9]);
		ply_names->insert(std::pair<std::string, std::size_t>("right", 4));
		geo_objects.addPolylineVec(std::move(lines), geo_name, ply_names);
	}

	{   // Create surfaces.
		auto sfcs = std::unique_ptr<std::vector<GeoLib::Surface*>>(
		    new std::vector<GeoLib::Surface*>(2));
		(*sfcs)[0] = new GeoLib::Surface(*points);
		(*sfcs)[0]->addTriangle(pnt_id_map[1], pnt_id_map[4], pnt_id_map[2]);
		(*sfcs)[0]->addTriangle(pnt_id_map[2], pnt_id_map[4], pnt_id_map[5]);
		(*sfcs)[0]->addTriangle(pnt_id_map[2], pnt_id_map[5], pnt_id_map[3]);
		(*sfcs)[0]->addTriangle(pnt_id_map[3], pnt_id_map[5], pnt_id_map[6]);
		(*sfcs)[1] = new GeoLib::Surface(*points);
		(*sfcs)[1]->addTriangle(pnt_id_map[4], pnt_id_map[7], pnt_id_map[9]);
		(*sfcs)[1]->addTriangle(pnt_id_map[4], pnt_id_map[9], pnt_id_map[6]);
		geo_objects.addSurfaceVec(std::move(sfcs), geo_name);
	}

	FileIO::XmlGmlInterface xml(geo_objects);
	xml.setNameForExport(geo_name);
	int result = xml.writeToFile(test_data_file);
	ASSERT_EQ(result, 1);

	// Reader test
	result = xml.readFile(QString::fromStdString(test_data_file));
	ASSERT_EQ(result, 1);

	const std::vector<GeoLib::Point*> *readerPoints = geo_objects.getPointVec(geo_name);
	const GeoLib::PolylineVec *line_vec = geo_objects.getPolylineVecObj(geo_name);
	const std::vector<GeoLib::Polyline*> *readerLines = geo_objects.getPolylineVec(geo_name);
	const std::vector<GeoLib::Surface*> *readerSfcs = geo_objects.getSurfaceVec(geo_name);
	ASSERT_EQ(9u, readerPoints->size());
	ASSERT_EQ(5u, readerLines->size());
	ASSERT_EQ(2u, readerSfcs->size());

	GeoLib::Point* pnt = (*readerPoints)[7];
	ASSERT_EQ(3.0, (*pnt)[0]);
	ASSERT_EQ(2.0, (*pnt)[1]);
	ASSERT_EQ(0.0, (*pnt)[2]);

	GeoLib::Polyline* line = (*readerLines)[4];
	ASSERT_EQ(3u, line->getNumberOfPoints());
	ASSERT_EQ(6u, line->getPointID(0));
	ASSERT_EQ(7u, line->getPointID(1));
	ASSERT_EQ(8u, line->getPointID(2));
	std::string line_name("");
	line_vec->getNameOfElementByID(4, line_name);
	ASSERT_EQ("right", line_name);

	GeoLib::Surface* sfc = (*readerSfcs)[1];
	ASSERT_EQ(2u, sfc->getNTriangles());
	const GeoLib::Triangle* tri = (*sfc)[1];
	ASSERT_EQ(3u, (*tri)[0]);
	ASSERT_EQ(8u, (*tri)[1]);
	ASSERT_EQ(5u, (*tri)[2]);

	boost::filesystem::remove(test_data_file);
	test_data_file += ".md5";
	boost::filesystem::remove(test_data_file);
}