@@ -69,6 +69,37 @@ inline void sort_keys_inplace(RapidjsonValue &json)
6969 }
7070}
7171
72+ inline std::optional<std::string> locate_nan_inf (const RapidjsonValue &json,
73+ const std::string &path = " " )
74+ {
75+ if (json.IsObject ()) {
76+ for (auto &kv : json.GetObject ()) {
77+ auto p = locate_nan_inf (kv.value );
78+ if (p) {
79+ return path + " [\" " +
80+ std::string (kv.name .GetString (),
81+ kv.name .GetStringLength ()) +
82+ " \" ]" + *p;
83+ }
84+ }
85+ } else if (json.IsArray ()) {
86+ int index = -1 ;
87+ for (auto &m : json.GetArray ()) {
88+ ++index;
89+ auto p = locate_nan_inf (m);
90+ if (p) {
91+ return path + " [" + std::to_string (index) + " ]" + *p;
92+ }
93+ }
94+ } else if (json.IsDouble ()) {
95+ double d = json.GetDouble ();
96+ if (std::isnan (d) || std::isinf (d)) {
97+ return path;
98+ }
99+ }
100+ return {};
101+ }
102+
72103inline void round_rapidjson (RapidjsonValue &json, double scale, int depth = 1 ,
73104 const std::vector<std::string> &skip_keys = {})
74105{
@@ -97,6 +128,30 @@ inline void round_rapidjson(RapidjsonValue &json, double scale, int depth = 1,
97128 }
98129}
99130
131+ inline void round_non_geojson (RapidjsonValue &json, double scale)
132+ {
133+ if (json.IsObject ()) {
134+ auto itr = json.FindMember (" type" );
135+ if (itr != json.MemberEnd () && itr->value .IsString ()) {
136+ const auto type = std::string (itr->value .GetString (),
137+ itr->value .GetStringLength ());
138+ if ( //
139+ type == " FeatureCollection" //
140+ || type == " Feature" //
141+ || type == " Point" //
142+ || type == " MultiPoint" //
143+ || type == " LineString" //
144+ || type == " MultiLineString" //
145+ || type == " Polygon" //
146+ || type == " MultiPolygon" //
147+ || type == " GeometryCollection" ) {
148+ return ;
149+ }
150+ }
151+ }
152+ round_rapidjson (json, scale, INT_MAX);
153+ }
154+
100155inline void round_geojson_non_geometry (RapidjsonValue &json, double scale)
101156{
102157 if (!json.IsObject ()) {
@@ -284,8 +339,9 @@ normalize_json(RapidjsonValue &json, //
284339 bool sort_keys = true , //
285340 std::optional<int > round_geojson_non_geometry = 3 , //
286341 const std::optional<std::array<int , 3 >> &round_geojson_geometry =
287- std::array<int , 3 >{8 , 8 , 3 }, //
288- bool denoise_double_0 = true , //
342+ std::array<int , 3 >{8 , 8 , 3 }, //
343+ std::optional<int > round_non_geojson = 3 , //
344+ bool denoise_double_0 = true , //
289345 bool strip_geometry_z_0 = true )
290346{
291347 if (sort_keys) {
@@ -301,6 +357,10 @@ normalize_json(RapidjsonValue &json, //
301357 std::pow (10.0 , precision[1 ]),
302358 std::pow (10.0 , precision[2 ])});
303359 }
360+ if (round_non_geojson) {
361+ double scale = std::pow (10.0 , *round_non_geojson);
362+ cubao::round_non_geojson (json, scale);
363+ }
304364 if (strip_geometry_z_0) {
305365 cubao::strip_geometry_z_0 (json);
306366 }
@@ -341,24 +401,25 @@ inline bool dump_json(const std::string &path, const RapidjsonValue &json,
341401 }
342402 using namespace rapidjson ;
343403 char writeBuffer[65536 ];
404+ bool succ = false ;
344405 FileWriteStream os (fp, writeBuffer, sizeof (writeBuffer));
345406 if (indent) {
346407 PrettyWriter<FileWriteStream> writer (os);
347408 if (sort_keys) {
348- cubao::sort_keys (json).Accept (writer);
409+ succ = cubao::sort_keys (json).Accept (writer);
349410 } else {
350- json.Accept (writer);
411+ succ = json.Accept (writer);
351412 }
352413 } else {
353414 Writer<FileWriteStream> writer (os);
354415 if (sort_keys) {
355- cubao::sort_keys (json).Accept (writer);
416+ succ = cubao::sort_keys (json).Accept (writer);
356417 } else {
357- json.Accept (writer);
418+ succ = json.Accept (writer);
358419 }
359420 }
360421 fclose (fp);
361- return true ;
422+ return succ ;
362423}
363424
364425inline RapidjsonValue loads (const std::string &json)
@@ -508,11 +569,6 @@ inline RapidjsonValue to_rapidjson(const mapbox::geojson::value &json)
508569 return to_rapidjson (json, allocator);
509570}
510571
511- // inline mapbox::geojson::value to_geojson_value(const RapidjsonValue &json)
512- // {
513- // return mapbox::geojson::convert<mapbox::geojson::value>(json);
514- // }
515-
516572inline bool is_subset_of (const RapidjsonValue &a, const RapidjsonValue &b)
517573{
518574 if (a.IsArray ()) {
0 commit comments