41{
42 TCLAP::CmdLine cmd(
43 "Remove points from geometry that are not used in any polyline nor "
44 "surface. Attention: Names of points are not handled correctly in "
45 "every case.\n\n"
46 "OpenGeoSys-6 software, version " +
48 ".\n"
49 "Copyright (c) 2012-2024, OpenGeoSys Community "
50 "(http://www.opengeosys.org)",
52
53 TCLAP::ValueArg<std::string> geo_output_arg(
54 "o", "output", "output geometry", true, "", "gml file");
55 cmd.add(geo_output_arg);
56 TCLAP::ValueArg<std::string> geo_input_arg(
57 "i", "input", "input geometry", true, "conceptual model", "gml file");
58 cmd.add(geo_input_arg);
59 cmd.parse(argc, argv);
60
63 try
64 {
65 if (!xml.readFile(geo_input_arg.getValue()))
66 {
67 ERR(
"Failed to read file `{:s}'.", geo_input_arg.getValue());
68 return EXIT_FAILURE;
69 }
70 }
71 catch (std::runtime_error const& err)
72 {
73 ERR(
"Failed to read file `{:s}'.", geo_input_arg.getValue());
74 ERR(
"{:s}", err.what());
75 return EXIT_FAILURE;
76 }
77
79 auto* points = const_cast<std::vector<GeoLib::Point*>*>(
83
84
85 auto used_points = std::vector<bool>(points->size(), false);
86
87 auto mark = [&](auto const* const object)
89
90 if (polylines)
91 {
92 ranges::for_each(*polylines, mark);
93 }
94 if (surfaces)
95 {
96 ranges::for_each(*surfaces, mark);
97 }
98
99 auto const number_of_used_points = static_cast<std::size_t>(
100 std::count(used_points.begin(), used_points.end(), true));
101 if (number_of_used_points == 0)
102 {
104 "Geometry consists of points only. A new geometry file won't "
105 "be written.");
106 return EXIT_SUCCESS;
107 }
109 "{} points in this geometry file are not used in any polyline or "
110 "surface",
111 points->size() - number_of_used_points);
112
114
115 auto reset = [&mapping](auto* object)
117
118
119 if (polylines)
120 {
121 ranges::for_each(*polylines, reset);
122 }
123
124 if (surfaces)
125 {
126 ranges::for_each(*surfaces, reset);
127 }
128
129 std::stringstream unused_points_info;
130 unused_points_info << std::fixed;
131
132
134 ranges::views::zip(*points, used_points) |
135 ranges::views::
filter([](auto&& pair) {
return !pair.second; }) |
136 ranges::views::keys)
137 {
138 unused_points_info << point->getID() << " " << *point << '\n';
139 delete point;
140 point = nullptr;
141 }
142
143 std::erase(*points, nullptr);
144 if (!unused_points_info.str().empty())
145 {
146 INFO(
"Removed the following points:\n{}", unused_points_info.str());
147 }
148
149 WARN(
"Names of points are not handled correctly in every case.");
150
153 geo_output_arg.getValue());
154
155 return EXIT_SUCCESS;
156}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
auto createMapping(std::vector< bool > const &used_points)
Container class for geometric objects.
std::vector< std::string > getGeometryNames() const
Returns the names of all geometry vectors.
const std::vector< Point * > * getPointVec(const std::string &name) const
const std::vector< Surface * > * getSurfaceVec(const std::string &name) const
Returns the surface vector with the given name as a const.
const std::vector< Polyline * > * getPolylineVec(const std::string &name) const
int writeStringToFile(std::string_view content, std::filesystem::path const &file_path)
constexpr List filter(Pred, SomeListOfTypes<> *)
void markUsedPoints(Polyline const &polyline, std::vector< bool > &used_points)
Resets the point IDs of the polyline corresponding to the mapping.
void resetPointIDs(Polyline &polyline, std::vector< std::size_t > const &mapping)
Resets the point IDs of the polyline corresponding to the mapping.
GITINFOLIB_EXPORT const std::string ogs_version