OGS
ConvertSHPToGLI.cpp
Go to the documentation of this file.
1
15#include <tclap/CmdLine.h>
16
17#ifdef USE_PETSC
18#include <mpi.h>
19#endif
20
21// STL
22#include <fstream>
23#include <vector>
24
25// ShapeLib
26#include <shapefil.h>
27
28#include "GeoLib/GEOObjects.h"
31#include "GeoLib/Point.h"
32#include "GeoLib/Station.h"
33#include "InfoLib/GitInfo.h"
34
35void convertPoints(DBFHandle dbf_handle,
36 std::string const& out_fname,
37 std::size_t x_id,
38 std::size_t y_id,
39 std::size_t z_id,
40 std::vector<std::size_t> const& name_component_ids,
41 std::string& points_group_name,
42 bool station)
43{
44 int n_records(DBFGetRecordCount(dbf_handle));
45 INFO("Reading {:d} records.", n_records);
46
47 std::vector<GeoLib::Point*> points;
48 points.reserve(n_records);
49
50 std::string name;
51 for (int k = 0; k < n_records; k++)
52 {
53 double x(DBFReadDoubleAttribute(dbf_handle, k, x_id));
54 double y(DBFReadDoubleAttribute(dbf_handle, k, y_id));
55 double z(0.0);
56 if (z_id != std::numeric_limits<std::size_t>::max())
57 {
58 z = DBFReadDoubleAttribute(dbf_handle, k, z_id);
59 }
60
61 name.clear();
62 if (!name_component_ids.empty())
63 {
64 for (unsigned long name_component_id : name_component_ids)
65 {
66 if (name_component_id !=
67 std::numeric_limits<std::size_t>::max())
68 {
69 name += DBFReadStringAttribute(dbf_handle, k,
70 name_component_id);
71 name += " ";
72 }
73 }
74 }
75 else
76 {
77 name = std::to_string(k);
78 }
79
80 if (station)
81 {
83 points.push_back(pnt);
84 }
85 else
86 {
87 GeoLib::Point* pnt(new GeoLib::Point(x, y, z));
88 points.push_back(pnt);
89 }
90 }
91
92 GeoLib::GEOObjects geo_objs;
93 if (station)
94 {
95 geo_objs.addStationVec(std::move(points), points_group_name);
96 }
97 else
98 {
99 geo_objs.addPointVec(std::move(points), points_group_name,
101 }
102
103 if (station)
104 {
105 GeoLib::IO::XmlStnInterface xml(geo_objs);
106 xml.export_name = points_group_name;
108 }
109 else
110 {
111 GeoLib::IO::XmlGmlInterface xml(geo_objs);
112 xml.export_name = points_group_name;
114 }
115}
116
117void printFieldInformationTable(DBFHandle const& dbf_handle,
118 std::size_t n_fields)
119{
120 char* field_name(new char[256]);
121 int width(0);
122 int n_decimals(0);
123 std::stringstream out;
124 out << std::endl;
125 out << "************************************************" << std::endl;
126 out << "field idx | name of field | data type of field " << std::endl;
127 out << "------------------------------------------------" << std::endl;
128 for (std::size_t field_idx(0); field_idx < n_fields; field_idx++)
129 {
130 DBFGetFieldInfo(dbf_handle, field_idx, field_name, &width, &n_decimals);
131 if (field_idx < 10)
132 {
133 out << " " << field_idx << " |";
134 }
135 else
136 {
137 out << " " << field_idx << " |";
138 }
139 std::string field_name_str(field_name);
140 for (int k(0); k < (14 - static_cast<int>(field_name_str.size())); k++)
141 {
142 out << " ";
143 }
144 out << field_name_str << " |";
145
146 char native_field_type(DBFGetNativeFieldType(dbf_handle, field_idx));
147 switch (native_field_type)
148 {
149 case 'C':
150 out << " string" << std::endl;
151 break;
152 case 'F':
153 out << " float" << std::endl;
154 break;
155 case 'N':
156 out << " numeric" << std::endl;
157 break;
158 default:
159 out << " n_decimal " << n_decimals << std::endl;
160 break;
161 }
162 }
163 delete[] field_name;
164 out << "************************************************" << std::endl;
165 INFO("{:s}", out.str());
166}
167
168int main(int argc, char* argv[])
169{
170 TCLAP::CmdLine cmd(
171 "Converts points contained in shape file\n\n"
172 "OpenGeoSys-6 software, version " +
174 ".\n"
175 "Copyright (c) 2012-2024, OpenGeoSys Community "
176 "(http://www.opengeosys.org)",
178 TCLAP::ValueArg<std::string> shapefile_arg("s",
179 "shape-file",
180 "the name of the shape file ",
181 true,
182 "",
183 "shape file");
184 cmd.add(shapefile_arg);
185
186 cmd.parse(argc, argv);
187
188#ifdef USE_PETSC
189 MPI_Init(&argc, &argv);
190#endif
191
192 std::string fname(shapefile_arg.getValue());
193
194 int shape_type;
195 int number_of_elements;
196
197 SHPHandle hSHP = SHPOpen(fname.c_str(), "rb");
198 if (hSHP)
199 {
200 SHPGetInfo(hSHP, &number_of_elements, &shape_type,
201 nullptr /*padfMinBound*/, nullptr /*padfMinBound*/);
202
203 if ((shape_type - 1) % 10 == 0)
204 INFO("Shape file contains {:d} points.", number_of_elements);
205 if (((shape_type - 3) % 10 == 0 || (shape_type - 5) % 10 == 0))
206 {
207 ERR("Shape file contains {:d} polylines.", number_of_elements);
208 ERR("This programme only handles only files containing points.");
209 SHPClose(hSHP);
210#ifdef USE_PETSC
211 MPI_Finalize();
212#endif
213 return EXIT_SUCCESS;
214 }
215 SHPClose(hSHP);
216 }
217 else
218 {
219 ERR("Could not open shapefile {:s}.", fname);
220 }
221
222 DBFHandle dbf_handle = DBFOpen(fname.c_str(), "rb");
223 if (dbf_handle)
224 {
225 std::size_t n_fields(DBFGetFieldCount(dbf_handle));
226 printFieldInformationTable(dbf_handle, n_fields);
227
228 std::size_t x_id;
229 std::size_t y_id;
230 std::size_t z_id;
231 INFO(
232 "Please give the field idx that should be used for reading the x "
233 "coordinate: ");
234 std::cin >> x_id;
235 INFO(
236 "Please give the field idx that should be used for reading the y "
237 "coordinate: ");
238 std::cin >> y_id;
239 INFO(
240 "Please give the field idx that should be used for reading the z "
241 "coordinate: ");
242 std::cin >> z_id;
243
244 if (z_id > n_fields)
245 {
246 z_id = std::numeric_limits<std::size_t>::max();
247 }
248
249 std::size_t n_name_components;
250 INFO("Please give the number of fields that should be added to name: ");
251 std::cin >> n_name_components;
252
253 std::vector<std::size_t> name_component_ids(
254 n_name_components, std::numeric_limits<std::size_t>::max());
255 if (n_name_components != 0)
256 {
257 for (std::size_t j(0); j < n_name_components; j++)
258 {
259 INFO(
260 "- please give the field idx that should be used for "
261 "reading the name: ");
262 std::cin >> name_component_ids[j];
263 }
264 }
265 for (std::size_t j(0); j < n_name_components; j++)
266 {
267 if (name_component_ids[j] > n_fields)
268 {
269 name_component_ids[j] = std::numeric_limits<std::size_t>::max();
270 }
271 }
272
273 std::size_t station(0);
274
275 INFO(
276 "Should I read the information as GeoLib::Station (0) or as "
277 "GeoLib::Point (1)? Please give the number: ");
278 std::cin >> station;
279
280 std::string fname_base(fname);
281 if (station == 0)
282 {
283 fname += ".stn";
284 }
285 else
286 {
287 fname += ".gml";
288 }
289
290 INFO("Writing to {:s}.", fname);
291 convertPoints(dbf_handle,
292 fname,
293 x_id,
294 y_id,
295 z_id,
296 name_component_ids,
297 fname_base,
298 station == 0);
299 DBFClose(dbf_handle);
300 INFO("\tok.");
301 }
302 else
303 {
304 ERR("Could not open the database file.");
305 }
306
307#ifdef USE_PETSC
308 MPI_Finalize();
309#endif
310 return EXIT_SUCCESS;
311}
int main(int argc, char *argv[])
void convertPoints(DBFHandle dbf_handle, std::string const &out_fname, std::size_t x_id, std::size_t y_id, std::size_t z_id, std::vector< std::size_t > const &name_component_ids, std::string &points_group_name, bool station)
void printFieldInformationTable(DBFHandle const &dbf_handle, std::size_t n_fields)
Definition of the GEOObjects class.
Definition of the Point class.
Git information.
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
Definition of the Station class.
Definition of the XmlGmlInterface class.
Definition of the XmlStnInterface class.
std::string writeToString()
Writes the object to a string.
Definition Writer.cpp:31
Container class for geometric objects.
Definition GEOObjects.h:57
void addPointVec(std::vector< Point * > &&points, std::string &name, PointVec::NameIdMap &&pnt_id_name_map, double const eps=std::sqrt(std::numeric_limits< double >::epsilon()))
void addStationVec(std::vector< Point * > &&stations, std::string &name)
Adds a vector of stations with the given name and colour to GEOObjects.
Reads and writes GeoObjects to and from XML files.
Reads and writes Observation Sites to and from XML files.
A Station (observation site) is basically a Point with some additional information.
Definition Station.h:37
static Station * createStation(const std::string &line)
Definition Station.cpp:46
std::map< std::string, std::size_t > NameIdMap
Definition TemplateVec.h:41
int writeStringToFile(std::string_view content, std::filesystem::path const &file_path)
Definition Writer.cpp:45
GITINFOLIB_EXPORT const std::string ogs_version