parser.cpp
Go to the documentation of this file.
1 //=============================================================================
2 // Copyright (C) 2021-2024 Wageningen University - All Rights Reserved
3 // Author: Gonzalo Mier
4 // BSD-3 License
5 //=============================================================================
6 
7 #include <tinyxml2.h>
8 #include <boost/optional.hpp>
9 #include <nlohmann/json.hpp>
12 
14 
15 namespace f2c {
16 
17 void Parser::importGml(const std::string& file, F2CFields& fields) {
18  fields.emplace_back(importFieldGml(file));
19 }
20 
22  const std::string& file, bool coord_frame_fail_silently) {
23  // Tinyxml2 depends on locale when parsing files. It may expect float numbers
24  // as "1,5" instead of "1.5", which is parsed as "1". The next line solves
25  // the issue.
26  std::locale::global(std::locale::classic());
27 
28  tinyxml2::XMLDocument doc;
29  doc.LoadFile(file.c_str());
30  auto* p_parcel = doc.RootElement();
31 
32  if (p_parcel == nullptr) {
33  throw std::invalid_argument("File not found");
34  }
35 
36  std::string id {""};
37 
38  auto e_result = p_parcel->Attribute("id");
39  if (e_result != nullptr) {
40  id = e_result;
41  }
42 
43  auto* p_field = p_parcel->FirstChildElement("Field");
44 
45  auto* p_polygon = p_field\
46  ->FirstChildElement("geometry")\
47  ->FirstChildElement("gml:Polygon");
48 
49  std::string coord_sys = p_polygon->Attribute("srsName");
50 
51  std::string p_coords = std::string(
52  p_polygon->FirstChildElement("gml:outerBoundaryIs")\
53  ->FirstChildElement("gml:LinearRing")\
54  ->FirstChildElement("gml:coordinates")\
55  ->GetText());
56  auto findAndReplaceAll =
57  [](std::string& data, std::string toSearch, std::string replaceStr) {
58  size_t pos = data.find(toSearch);
59  while (pos != std::string::npos) {
60  data.replace(pos, toSearch.size(), replaceStr);
61  pos = data.find(toSearch, pos + replaceStr.size());
62  }
63  return;
64  };
65  findAndReplaceAll(p_coords, ",", ";");
66  findAndReplaceAll(p_coords, " ", ", ");
67  findAndReplaceAll(p_coords, ";", " ");
68  p_coords = "POLYGON ((" + p_coords + "))";
69  OGRGeometry* new_geom{};
70  auto spt_ref = Transform::createSptRef(coord_sys, coord_frame_fail_silently);
71  OGRGeometryFactory::createFromWkt(p_coords.c_str(), spt_ref.get(), &new_geom);
72 
73  F2CField field(F2CCells(new_geom), id);
74  field.setCRS(coord_sys);
75  OGRGeometryFactory::destroyGeometry(new_geom);
76 
77  return field;
78 }
79 
80 
82  if (ps.size() == 3) {
83  return F2CPoint(ps[0], ps[1], ps[2]);
84  } else if (ps.size() == 2) {
85  return F2CPoint(ps[0], ps[1]);
86  }
87  return F2CPoint();
88 }
89 
90 F2CCell getCellFromJson(const json& imported_cell) {
91  auto jsonToF2CRing = [] (const json& json_ring) {
93  for (auto&& ps : json_ring) {
94  ring.addPoint(getPointFromJson(ps));
95  }
96  return ring;
97  };
98  F2CCell cell;
99  auto json_rings = imported_cell["geometry"]["coordinates"];
100  for (int i = 0; i < json_rings.size(); ++i) {
101  cell.addRing(jsonToF2CRing(json_rings[i]));
102  }
103  return cell;
104 }
105 
106 
107 int Parser::importJson(const std::string& file, F2CFields& fields) {
108  std::ifstream f(file);
109  json imported_field = json::parse(f);
110 
111  for (auto&& imported_cell : imported_field["features"]) {
112  fields.emplace_back(
113  F2CField(F2CCells(getCellFromJson(imported_cell)),
114  imported_cell["properties"]["Name"]));
115  }
116  return 0;
117 }
118 
119 F2CCell Parser::importCellJson(const std::string& file) {
120  std::ifstream f(file);
121  json imported_field = json::parse(f);
122  return getCellFromJson(imported_field["features"][0]);
123 }
124 
125 F2CSwaths Parser::importSwathsJson(const std::string& file) {
126  std::ifstream f(file);
127  json imported_swaths = json::parse(f);
129  for (auto&& imported_swath : imported_swaths["features"]) {
130  F2CLineString line;
131  for (auto&& ps : imported_swath["geometry"]["coordinates"]) {
133  }
134  swaths.emplace_back(line,
135  imported_swath["properties"]["width"],
136  imported_swath["properties"]["path_id"]);
137  }
138  return swaths;
139 }
140 
141 F2CStrips Parser::importStripsJson(const std::string& file) {
142  std::ifstream f(file);
143  json imported_strips = json::parse(f);
144  F2CStrips strips;
145  for (auto&& imported_strip : imported_strips["features"]) {
146  F2CStrip strip;
147  strip.setName(imported_strip["properties"]["crop_id"]);
148  strip.setCell(getCellFromJson(imported_strip));
149  strips.emplace_back(strip);
150  }
151  return strips;
152 }
153 
154 } // namespace f2c
5_route_planning.swaths
swaths
Definition: 5_route_planning.py:58
json
nlohmann::json json
Definition: parser.cpp:13
transformation.h
f2c::types::Field
Definition: Field.h:18
f2c::Transform::createSptRef
static std::unique_ptr< OGRSpatialReference, void(*)(OGRSpatialReference *)> createSptRef(const std::string &coord_sys, bool fail_silently=false)
Definition: transformation.cpp:242
f2c::getPointFromJson
F2CPoint getPointFromJson(const json &ps)
Definition: parser.cpp:81
1_basic_types.cell
cell
Definition: 1_basic_types.py:88
F2CStrips
std::vector< F2CStrip > F2CStrips
Definition: types.h:57
f2c::types::Strip::setCell
void setCell(const Cell &cell)
Definition: Strip.cpp:19
F2CCells
f2c::types::Cells F2CCells
Definition: types.h:44
f2c::Parser::importGml
static void importGml(const std::string &file, F2CFields &fields)
Definition: parser.cpp:17
f2c::Parser::importStripsJson
static F2CStrips importStripsJson(const std::string &file)
Definition: parser.cpp:141
f2c::types::LinearRing
Definition: LinearRing.h:18
f2c::types::Strip
Definition: Strip.h:16
f2c::types::Cell
Definition: Cell.h:32
1_basic_types.ring
ring
Definition: 1_basic_types.py:68
f2c::Parser::importSwathsJson
static F2CSwaths importSwathsJson(const std::string &file)
Definition: parser.cpp:125
f2c::types::LineString
Definition: LineString.h:19
8_complete_flow.ps
list ps
Definition: 8_complete_flow.py:43
f2c::types::Strip::setName
void setName(const std::string &str)
Definition: Strip.cpp:27
f2c::Parser::importJson
static int importJson(const std::string &file, F2CFields &fields)
Definition: parser.cpp:107
f2c::types::LineString::addPoint
void addPoint(double x, double y, double z=0)
Definition: LineString.cpp:107
f2c::types::Point
Definition: Point.h:21
F2CFields
std::vector< F2CField > F2CFields
Definition: types.h:58
F2CField
f2c::types::Field F2CField
Definition: types.h:46
f2c::getCellFromJson
F2CCell getCellFromJson(const json &imported_cell)
Definition: parser.cpp:90
parser.h
2_objective_functions.field
field
Definition: 2_objective_functions.py:16
f2c
Main namespace of the fields2cover library.
Definition: boustrophedon_decomp.h:14
f2c::Parser::importFieldGml
static F2CField importFieldGml(const std::string &file, bool fail_silently=false)
Definition: parser.cpp:21
f2c::Parser::importCellJson
static F2CCell importCellJson(const std::string &file)
Definition: parser.cpp:119
f2c::types::Swaths
Definition: Swaths.h:20
F2CPoint
f2c::types::Point F2CPoint
Definition: types.h:38


fields2cover
Author(s):
autogenerated on Fri Apr 25 2025 02:18:31