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