Browse Source

some changes

Patrick Brosi 4 years ago
parent
commit
4ad506c78b
5 changed files with 438 additions and 101 deletions
  1. 181 33
      src/osmfixer/index/StatIdx.cpp
  2. 6 1
      src/osmfixer/index/StatIdx.h
  3. 109 42
      src/osmfixer/server/StatServer.cpp
  4. 1 1
      web/index.html
  5. 141 24
      web/script.js

+ 181 - 33
src/osmfixer/index/StatIdx.cpp

@@ -68,8 +68,14 @@ void StatIdx::readFromFile(const std::string& path) {
68
       }
68
       }
69
     }
69
     }
70
 
70
 
71
+    if (geom.size() != 1 && util::geo::dist(geom.front(), geom.back()) > 1) {
72
+      // transform lines into polygons
73
+      geom = hull(geom, 2).getOuter();
74
+    }
75
+
71
     if (geom.size() > 1) geom = util::geo::simplify(geom, 0.5);
76
     if (geom.size() > 1) geom = util::geo::simplify(geom, 0.5);
72
-    for (const auto& p : geom) latLngs.push_back(util::geo::webMercToLatLng<double>(p.getX(), p.getY()));
77
+    for (const auto& p : geom)
78
+      latLngs.push_back(util::geo::webMercToLatLng<double>(p.getX(), p.getY()));
73
 
79
 
74
     addStation(osmid, geom, latLngs, origGroup, group, attrs);
80
     addStation(osmid, geom, latLngs, origGroup, group, attrs);
75
   }
81
   }
@@ -87,13 +93,21 @@ void StatIdx::readFromFile(const std::string& path) {
87
 
93
 
88
     rec >> osmid;
94
     rec >> osmid;
89
 
95
 
96
+    std::string key;
97
+    std::getline(rec, key, '\t');
98
+    while (std::getline(rec, key, '\t')) {
99
+      std::string val;
100
+      std::getline(rec, val, '\t');
101
+      attrs[key].push_back(val);
102
+    }
103
+
90
     addGroup(osmid, attrs);
104
     addGroup(osmid, attrs);
91
   }
105
   }
92
 
106
 
93
   LOG(INFO) << "Done.";
107
   LOG(INFO) << "Done.";
94
 
108
 
95
   // third, parse attr errs
109
   // third, parse attr errs
96
-  LOG(INFO) << "Parsing errors... ";
110
+  LOG(INFO) << "Parsing station errors... ";
97
   while (std::getline(f, line)) {
111
   while (std::getline(f, line)) {
98
     // empty line is separator between blocks
112
     // empty line is separator between blocks
99
     if (line.size() == 0) break;
113
     if (line.size() == 0) break;
@@ -102,7 +116,7 @@ void StatIdx::readFromFile(const std::string& path) {
102
     size_t id;
116
     size_t id;
103
     std::string attr, otherAttr;
117
     std::string attr, otherAttr;
104
     double conf;
118
     double conf;
105
-    int64_t otherId;
119
+    int64_t otherIdRaw;
106
 
120
 
107
     rec >> id;
121
     rec >> id;
108
 
122
 
@@ -111,9 +125,48 @@ void StatIdx::readFromFile(const std::string& path) {
111
     std::getline(rec, otherAttr, '\t');
125
     std::getline(rec, otherAttr, '\t');
112
 
126
 
113
     rec >> conf;
127
     rec >> conf;
114
-    rec >> otherId;
128
+    rec >> otherIdRaw;
115
 
129
 
116
-    _stations[id].attrErrs.push_back({attr, otherAttr, conf, otherId});
130
+    size_t otherId;
131
+    bool fromRel = false;
132
+
133
+    if (otherIdRaw < 0) fromRel = true;
134
+
135
+    otherId = labs(otherIdRaw);
136
+
137
+    _stations[id].attrErrs.push_back({attr, otherAttr, conf, otherId, fromRel});
138
+  }
139
+  LOG(INFO) << "Done.";
140
+
141
+  // fourth, parse attr errs in groups
142
+  LOG(INFO) << "Parsing group errors... ";
143
+  while (std::getline(f, line)) {
144
+    // empty line is separator between blocks
145
+    if (line.size() == 0) break;
146
+
147
+    std::stringstream rec(line);
148
+    size_t id;
149
+    std::string attr, otherAttr;
150
+    double conf;
151
+    int64_t otherIdRaw;
152
+
153
+    rec >> id;
154
+
155
+    std::getline(rec, attr, '\t');
156
+    std::getline(rec, attr, '\t');
157
+    std::getline(rec, otherAttr, '\t');
158
+
159
+    rec >> conf;
160
+    rec >> otherIdRaw;
161
+
162
+    size_t otherId;
163
+    bool fromRel = false;
164
+
165
+    if (otherIdRaw < 0) fromRel = true;
166
+
167
+    otherId = labs(otherIdRaw);
168
+
169
+    _groups[id].attrErrs.push_back({attr, otherAttr, conf, otherId, fromRel});
117
   }
170
   }
118
   LOG(INFO) << "Done.";
171
   LOG(INFO) << "Done.";
119
 
172
 
@@ -175,24 +228,17 @@ void StatIdx::initGroups() {
175
     }
228
     }
176
   }
229
   }
177
 
230
 
231
+
178
   // build hull polygon
232
   // build hull polygon
179
   for (size_t i = 0; i < _groups.size(); i++) {
233
   for (size_t i = 0; i < _groups.size(); i++) {
180
     util::geo::MultiPoint<double> mp;
234
     util::geo::MultiPoint<double> mp;
181
     for (size_t stid : _groups[i].polyStations) {
235
     for (size_t stid : _groups[i].polyStations) {
182
-      double rad = 11.0;
183
-      int n = 20;
184
-      for (int i = 0; i < n; i++) {
185
-        double x = rad * cos((2.0 * M_PI / static_cast<double>(n)) *
186
-                             static_cast<double>(i));
187
-        double y = rad * sin((2.0 * M_PI / static_cast<double>(n)) *
188
-                             static_cast<double>(i));
189
-
190
-        for (const auto& geom : _stations[stid].pos) {
191
-          mp.push_back(util::geo::DPoint(geom.getX() + x, geom.getY() + y));
192
-        }
236
+      for (const auto& geom : _stations[stid].pos) {
237
+        mp.push_back(util::geo::DPoint(geom.getX(), geom.getY()));
193
       }
238
       }
194
     }
239
     }
195
-    _groups[i].poly = util::geo::simplify(util::geo::convexHull(mp).getOuter(), 0.5);
240
+
241
+    _groups[i].poly = hull(mp, 11);
196
 
242
 
197
     for (auto p : _groups[i].poly.getOuter()) {
243
     for (auto p : _groups[i].poly.getOuter()) {
198
       _groups[i].llPoly.getOuter().push_back(
244
       _groups[i].llPoly.getOuter().push_back(
@@ -204,6 +250,28 @@ void StatIdx::initGroups() {
204
 }
250
 }
205
 
251
 
206
 // _____________________________________________________________________________
252
 // _____________________________________________________________________________
253
+util::geo::Polygon<double> StatIdx::hull(
254
+    const util::geo::MultiPoint<double>& imp, double rad) const {
255
+  util::geo::MultiPoint<double> mp;
256
+  util::geo::Polygon<double> ret;
257
+  for (const auto& geom : imp) {
258
+    // double rad = 11.0;
259
+    int n = 20;
260
+    for (int i = 0; i < n; i++) {
261
+      double x = rad * cos((2.0 * M_PI / static_cast<double>(n)) *
262
+                           static_cast<double>(i));
263
+      double y = rad * sin((2.0 * M_PI / static_cast<double>(n)) *
264
+                           static_cast<double>(i));
265
+
266
+      mp.push_back(util::geo::DPoint(geom.getX() + x, geom.getY() + y));
267
+    }
268
+  }
269
+  ret = util::geo::simplify(util::geo::convexHull(mp).getOuter(), 0.5);
270
+
271
+  return ret;
272
+}
273
+
274
+// _____________________________________________________________________________
207
 void StatIdx::initIndex() {
275
 void StatIdx::initIndex() {
208
   double gSize = 10000;
276
   double gSize = 10000;
209
   _sgrid = util::geo::Grid<size_t, util::geo::Polygon, double>(gSize, gSize,
277
   _sgrid = util::geo::Grid<size_t, util::geo::Polygon, double>(gSize, gSize,
@@ -465,21 +533,80 @@ std::vector<osmfixer::Cluster> StatIdx::getHeatGridSugg(
465
 }
533
 }
466
 // _____________________________________________________________________________
534
 // _____________________________________________________________________________
467
 void StatIdx::initSuggestions() {
535
 void StatIdx::initSuggestions() {
536
+  // group suggestions
537
+  for (size_t i = 0; i < _groups.size(); i++) {
538
+    auto& group = _groups[i];
539
+
540
+    if (group.attrs.size() == 0) {
541
+      Suggestion sug;
542
+      sug.station = i;
543
+      sug.type = 7;
544
+      _suggestions.push_back(sug);
545
+      group.suggestions.push_back(_suggestions.size() - 1);
546
+    }
547
+
548
+    Suggestion sug;
549
+    sug.station = i;
550
+
551
+    std::set<std::pair<std::string, uint16_t>> suggested;
552
+    for (auto attrErr : group.attrErrs) {
553
+      if (!attrErr.fromRel) continue;
554
+
555
+      const auto otherGrp = getGroup(attrErr.otherId);
556
+      if (group.id == attrErr.otherId && attrErr.attr == attrErr.otherAttr) {
557
+        if (suggested.count({attrErr.attr, 8})) continue;
558
+        // fix track number as name
559
+        suggested.insert({attrErr.attr, 8});
560
+        sug.type = 8;
561
+        sug.orig_gid = 0;
562
+        sug.orig_osm_rel_id = 0;
563
+        sug.target_gid = 0;
564
+        sug.target_osm_rel_id = 0;
565
+        sug.attrErrName = attrErr.attr;
566
+
567
+        _suggestions.push_back(sug);
568
+        group.suggestions.push_back(_suggestions.size() - 1);
569
+      } else if (otherGrp->osmid == group.osmid) {
570
+        if (suggested.count({attrErr.attr, 6})) continue;
571
+        // fix attributes
572
+        suggested.insert({attrErr.attr, 6});
573
+        sug.type = 6;
574
+        sug.orig_gid = 0;
575
+        sug.orig_osm_rel_id = 0;
576
+        sug.target_gid = 0;
577
+        sug.target_osm_rel_id = 0;
578
+        sug.attrErrName = attrErr.attr;
579
+
580
+        _suggestions.push_back(sug);
581
+        group.suggestions.push_back(_suggestions.size() - 1);
582
+      }
583
+    }
584
+  }
585
+
586
+  // station suggestions
468
   for (size_t i = 0; i < _stations.size(); i++) {
587
   for (size_t i = 0; i < _stations.size(); i++) {
469
     auto& stat = _stations[i];
588
     auto& stat = _stations[i];
589
+
590
+    if (stat.attrs.size() == 0) {
591
+      Suggestion sug;
592
+      sug.station = i;
593
+      sug.type = 7;
594
+      _suggestions.push_back(sug);
595
+      stat.suggestions.push_back(_suggestions.size() - 1);
596
+    }
597
+
470
     if (stat.group != stat.origGroup || getGroup(stat.group)->osmid == 1) {
598
     if (stat.group != stat.origGroup || getGroup(stat.group)->osmid == 1) {
471
       Suggestion sug;
599
       Suggestion sug;
472
       sug.station = i;
600
       sug.station = i;
473
       auto centroid = util::geo::centroid(stat.pos);
601
       auto centroid = util::geo::centroid(stat.pos);
474
       sug.arrow = util::geo::DLine{centroid, centroid};
602
       sug.arrow = util::geo::DLine{centroid, centroid};
603
+
475
       if (getGroup(stat.origGroup)->osmid < 2) {
604
       if (getGroup(stat.origGroup)->osmid < 2) {
476
         if (getGroup(stat.group)->osmid == 1) {
605
         if (getGroup(stat.group)->osmid == 1) {
477
           // move orphan into new group
606
           // move orphan into new group
478
           sug.type = 1;
607
           sug.type = 1;
479
           sug.target_gid = stat.group;
608
           sug.target_gid = stat.group;
480
 
609
 
481
-          // sug.arrow = getGroupArrow(i, stat.group);
482
-
483
           _suggestions.push_back(sug);
610
           _suggestions.push_back(sug);
484
           stat.suggestions.push_back(_suggestions.size() - 1);
611
           stat.suggestions.push_back(_suggestions.size() - 1);
485
 
612
 
@@ -539,21 +666,42 @@ void StatIdx::initSuggestions() {
539
           stat.suggestions.push_back(_suggestions.size() - 1);
666
           stat.suggestions.push_back(_suggestions.size() - 1);
540
         }
667
         }
541
       }
668
       }
669
+    }
542
 
670
 
543
-      for (auto attrErr : stat.attrErrs) {
544
-        const auto otherStat = getStation(attrErr.otherId);
545
-        if (otherStat->osmid == stat.osmid) {
546
-          // fix attributes
547
-          sug.type = 6;
548
-          sug.orig_gid = 0;
549
-          sug.orig_osm_rel_id = 0;
550
-          sug.target_gid = 0;
551
-          sug.target_osm_rel_id = 0;
552
-          sug.attrErrName = attrErr.attr;
553
-
554
-          _suggestions.push_back(sug);
555
-          stat.suggestions.push_back(_suggestions.size() - 1);
556
-        }
671
+    Suggestion sug;
672
+    sug.station = i;
673
+
674
+    std::set<std::pair<std::string, uint16_t>> suggested;
675
+    for (auto attrErr : stat.attrErrs) {
676
+      if (attrErr.fromRel) continue;
677
+
678
+      const auto otherStat = getStation(attrErr.otherId);
679
+      if (stat.id == attrErr.otherId && attrErr.attr == attrErr.otherAttr) {
680
+        if (suggested.count({attrErr.attr, 8})) continue;
681
+        suggested.insert({attrErr.attr, 8});
682
+        // fix track number as name
683
+        sug.type = 8;
684
+        sug.orig_gid = 0;
685
+        sug.orig_osm_rel_id = 0;
686
+        sug.target_gid = 0;
687
+        sug.target_osm_rel_id = 0;
688
+        sug.attrErrName = attrErr.attr;
689
+
690
+        _suggestions.push_back(sug);
691
+        stat.suggestions.push_back(_suggestions.size() - 1);
692
+      } else if (otherStat->osmid == stat.osmid) {
693
+        if (suggested.count({attrErr.attr, 6})) continue;
694
+        suggested.insert({attrErr.attr, 6});
695
+        // fix attributes
696
+        sug.type = 6;
697
+        sug.orig_gid = 0;
698
+        sug.orig_osm_rel_id = 0;
699
+        sug.target_gid = 0;
700
+        sug.target_osm_rel_id = 0;
701
+        sug.attrErrName = attrErr.attr;
702
+
703
+        _suggestions.push_back(sug);
704
+        stat.suggestions.push_back(_suggestions.size() - 1);
557
       }
705
       }
558
     }
706
     }
559
   }
707
   }

+ 6 - 1
src/osmfixer/index/StatIdx.h

@@ -19,7 +19,8 @@ struct AttrErr {
19
   std::string attr;
19
   std::string attr;
20
   std::string otherAttr;
20
   std::string otherAttr;
21
   double conf;
21
   double conf;
22
-  int64_t otherId;
22
+  size_t otherId;
23
+  bool fromRel;
23
 };
24
 };
24
 
25
 
25
 struct Suggestion {
26
 struct Suggestion {
@@ -53,6 +54,8 @@ struct Group {
53
   OsmAttrs attrs;
54
   OsmAttrs attrs;
54
   std::vector<size_t> stations;
55
   std::vector<size_t> stations;
55
   std::vector<size_t> polyStations;
56
   std::vector<size_t> polyStations;
57
+  std::vector<AttrErr> attrErrs;
58
+  std::vector<size_t> suggestions;
56
 };
59
 };
57
 
60
 
58
 struct Cluster {
61
 struct Cluster {
@@ -102,6 +105,8 @@ class StatIdx {
102
 
105
 
103
   util::geo::DLine getGroupArrow(size_t stat, const util::geo::DPoint& p) const;
106
   util::geo::DLine getGroupArrow(size_t stat, const util::geo::DPoint& p) const;
104
 
107
 
108
+  util::geo::Polygon<double> hull(const util::geo::MultiPoint<double>& imp, double rad) const;
109
+
105
   std::vector<Station> _stations;
110
   std::vector<Station> _stations;
106
   std::vector<Group> _groups;
111
   std::vector<Group> _groups;
107
   std::vector<Suggestion> _suggestions;
112
   std::vector<Suggestion> _suggestions;

+ 109 - 42
src/osmfixer/server/StatServer.cpp

@@ -181,7 +181,6 @@ util::http::Answer StatServer::handleMapReq(const Params& pars) const {
181
   if (z < 9) p = 2;
181
   if (z < 9) p = 2;
182
   if (z < 7) p = 1;
182
   if (z < 7) p = 1;
183
 
183
 
184
-
185
   std::stringstream json;
184
   std::stringstream json;
186
 
185
 
187
   json << std::fixed << std::setprecision(p);
186
   json << std::fixed << std::setprecision(p);
@@ -243,7 +242,6 @@ util::http::Answer StatServer::handleMapReq(const Params& pars) const {
243
 // _____________________________________________________________________________
242
 // _____________________________________________________________________________
244
 void StatServer::printStation(const Station* stat, size_t did, bool simple,
243
 void StatServer::printStation(const Station* stat, size_t did, bool simple,
245
                               std::ostream* out) const {
244
                               std::ostream* out) const {
246
-  const auto& idx = _idxs[did].second;
247
   const auto& range = _idxs[did].first;
245
   const auto& range = _idxs[did].first;
248
 
246
 
249
   (*out) << "{\"i\":" << stat->id + range.sidStart << ",\"g\":[";
247
   (*out) << "{\"i\":" << stat->id + range.sidStart << ",\"g\":[";
@@ -261,7 +259,7 @@ void StatServer::printStation(const Station* stat, size_t did, bool simple,
261
 
259
 
262
   (*out) << "]";
260
   (*out) << "]";
263
 
261
 
264
-  if (stat->origGroup != stat->group || idx.getGroup(stat->group)->osmid == 1)
262
+  if (stat->suggestions.size() > 0)
265
     (*out) << ",\"s\":1";
263
     (*out) << ",\"s\":1";
266
 
264
 
267
   if (stat->attrErrs.size())
265
   if (stat->attrErrs.size())
@@ -309,6 +307,12 @@ void StatServer::printGroup(const Group* group, size_t did, bool simple,
309
   }
307
   }
310
   (*out) << "]";
308
   (*out) << "]";
311
   if (group->osmid == 1) (*out) << ",\"n\":1";
309
   if (group->osmid == 1) (*out) << ",\"n\":1";
310
+
311
+  if (group->suggestions.size() > 0)
312
+    (*out) << ",\"s\":1";
313
+
314
+  if (group->attrErrs.size())
315
+    (*out) << ",\"e\":" << group->attrErrs.size();
312
   (*out) << "}";
316
   (*out) << "}";
313
 }
317
 }
314
 
318
 
@@ -411,7 +415,39 @@ util::http::Answer StatServer::handleGroupReq(const Params& pars) const {
411
     json << "]";
415
     json << "]";
412
   }
416
   }
413
 
417
 
414
-  json << "},\"stations\":[";
418
+  json << "},\"attrerrs\":[";
419
+
420
+  sep = ' ';
421
+  for (const auto& err : group->attrErrs) {
422
+    // self errors denote names named as tracks
423
+    if (err.fromRel && err.otherId == group->id && err.attr == err.otherAttr) continue;
424
+
425
+    json << sep;
426
+    sep = ',';
427
+    json << "{";
428
+    json << "\"attr\":[\"" << err.attr << "\",\"" << group->attrs.at(err.attr)[0]
429
+         << "\"]";
430
+    json << ",\"conf\":" << err.conf;
431
+
432
+    if (err.fromRel) {
433
+      const auto otherGroup = idx.getGroup(err.otherId);
434
+      json << ",\"other_attr\":[\"" << err.otherAttr << "\",\""
435
+           << otherGroup->attrs.at(err.otherAttr)[0] << "\"]";
436
+      json << ",\"other_grp\":" << err.otherId + range.gidStart;
437
+      json << ",\"other_osmid\":" << otherGroup->osmid;
438
+    } else {
439
+      const auto otherStat = idx.getStation(err.otherId);
440
+      json << ",\"other_attr\":[\"" << err.otherAttr << "\",\""
441
+           << otherStat->attrs.at(err.otherAttr)[0] << "\"]";
442
+      json << ",\"other\":" << err.otherId + range.sidStart;
443
+      json << ",\"other_osmid\":" << otherStat->osmid;
444
+    }
445
+    json << "}";
446
+  }
447
+
448
+  json << "]";
449
+
450
+  json << ",\"stations\":[";
415
 
451
 
416
   sep = ' ';
452
   sep = ' ';
417
   for (const auto& sid : group->stations) {
453
   for (const auto& sid : group->stations) {
@@ -439,11 +475,39 @@ util::http::Answer StatServer::handleGroupReq(const Params& pars) const {
439
       }
475
       }
440
       json << "]";
476
       json << "]";
441
     }
477
     }
442
-    json << "}}";
478
+    json << "}";
479
+    if (stat->suggestions.size() > 0)
480
+      json << ",\"s\":1";
481
+
482
+    if (stat->attrErrs.size())
483
+      json << ",\"e\":" << stat->attrErrs.size();
484
+    json << "}";
443
   }
485
   }
444
 
486
 
445
   json << "]";
487
   json << "]";
446
 
488
 
489
+  json << ",\"su\":[";
490
+
491
+  std::string seper = "";
492
+
493
+  for (size_t sid : group->suggestions) {
494
+      const auto* sugg = idx.getSuggestion(sid);
495
+      if (sugg->type == 6) {
496
+       json << seper << "{\"type\":6,\"attr\":\"" << sugg->attrErrName << "\""
497
+            << "}";
498
+      } else if (sugg->type == 7) {
499
+        json << seper << "{\"type\":7}";
500
+      } else if (sugg->type == 8) {
501
+       json << seper << "{\"type\":8,\"attr\":\"" << sugg->attrErrName << "\""
502
+            << "}";
503
+      } else {
504
+        json << seper << "{\"type\":" << sugg->type << "}";
505
+      }
506
+      seper = ',';
507
+    }
508
+
509
+  json << "]";
510
+
447
   json << "}";
511
   json << "}";
448
 
512
 
449
   if (cb.size()) json << ")";
513
   if (cb.size()) json << ")";
@@ -506,17 +570,29 @@ util::http::Answer StatServer::handleStatReq(const Params& pars) const {
506
 
570
 
507
   sep = ' ';
571
   sep = ' ';
508
   for (const auto& err : stat->attrErrs) {
572
   for (const auto& err : stat->attrErrs) {
573
+    // self errors denote names named as tracks
574
+    if (!err.fromRel && err.otherId == stat->id && err.attr == err.otherAttr) continue;
509
     json << sep;
575
     json << sep;
510
     sep = ',';
576
     sep = ',';
511
-    const auto& otherStat = idx.getStation(err.otherId);
512
     json << "{";
577
     json << "{";
513
     json << "\"attr\":[\"" << err.attr << "\",\"" << stat->attrs.at(err.attr)[0]
578
     json << "\"attr\":[\"" << err.attr << "\",\"" << stat->attrs.at(err.attr)[0]
514
          << "\"]";
579
          << "\"]";
515
-    json << ",\"other_attr\":[\"" << err.otherAttr << "\",\""
516
-         << otherStat->attrs.at(err.otherAttr)[0] << "\"]";
517
     json << ",\"conf\":" << err.conf;
580
     json << ",\"conf\":" << err.conf;
518
-    json << ",\"other\":" << err.otherId + range.sidStart;
519
-    json << ",\"other_osmid\":" << otherStat->osmid;
581
+
582
+    if (err.fromRel) {
583
+      const auto otherGroup = idx.getGroup(err.otherId);
584
+      json << ",\"other_attr\":[\"" << err.otherAttr << "\",\""
585
+           << otherGroup->attrs.at(err.otherAttr)[0] << "\"]";
586
+      json << ",\"other_grp\":" << err.otherId + range.gidStart;
587
+      json << ",\"other_osmid\":" << otherGroup->osmid;
588
+    } else {
589
+      const auto otherStat = idx.getStation(err.otherId);
590
+      json << ",\"other_attr\":[\"" << err.otherAttr << "\",\""
591
+           << otherStat->attrs.at(err.otherAttr)[0] << "\"]";
592
+      json << ",\"other\":" << err.otherId + range.sidStart;
593
+      json << ",\"other_osmid\":" << otherStat->osmid;
594
+    }
595
+
520
     json << "}";
596
     json << "}";
521
   }
597
   }
522
 
598
 
@@ -524,54 +600,45 @@ util::http::Answer StatServer::handleStatReq(const Params& pars) const {
524
 
600
 
525
   json << ",\"su\":[";
601
   json << ",\"su\":[";
526
 
602
 
527
-  char seper = ' ';
603
+  std::string seper = "";
528
 
604
 
529
-  // suggestions
530
-  if (stat->group != stat->origGroup || idx.getGroup(stat->group)->osmid == 1) {
531
-    if (idx.getGroup(stat->origGroup)->osmid < 2) {
532
-      if (idx.getGroup(stat->group)->osmid == 1) {
533
-        json << "{\"type\": 1, \"target_gid\":" << stat->group + range.gidStart
605
+  for (size_t sid : stat->suggestions) {
606
+      const auto* sugg = idx.getSuggestion(sid);
607
+      if (sugg->type == 1) {
608
+        json << seper << "{\"type\":1, \"target_gid\":" << stat->group + range.gidStart
534
              << "}";
609
              << "}";
535
-        seper = ',';
536
-      } else if (idx.getGroup(stat->group)->osmid > 1) {
537
-        json << "{\"type\": 2, \"target_gid\":" << stat->group + range.gidStart
610
+      } else if (sugg->type == 2) {
611
+        json << seper << "{\"type\":2, \"target_gid\":" << stat->group + range.gidStart
538
              << ",\"target_osm_rel_id\":" << idx.getGroup(stat->group)->osmid
612
              << ",\"target_osm_rel_id\":" << idx.getGroup(stat->group)->osmid
539
              << "}";
613
              << "}";
540
-        seper = ',';
541
-      }
542
-    } else {
543
-      if (idx.getGroup(stat->group)->osmid == 1 &&
544
-          idx.getGroup(stat->group)->stations.size() > 1) {
545
-        json << "{\"type\": 3,\"orig_gid\":" << stat->origGroup + range.gidStart
614
+      } else if (sugg->type == 3) {
615
+        json << seper << "{\"type\":3,\"orig_gid\":" << stat->origGroup + range.gidStart
546
              << ",\"orig_osm_rel_id\":" << idx.getGroup(stat->origGroup)->osmid
616
              << ",\"orig_osm_rel_id\":" << idx.getGroup(stat->origGroup)->osmid
547
              << ",\"target_gid\":" << stat->group + range.gidStart << "}";
617
              << ",\"target_gid\":" << stat->group + range.gidStart << "}";
548
-        seper = ',';
549
-      } else if (idx.getGroup(stat->group)->osmid > 1) {
550
-        json << "{\"type\": 4,\"orig_gid\":" << stat->origGroup + range.gidStart
618
+      } else if (sugg->type == 4) {
619
+        json << seper << "{\"type\":4,\"orig_gid\":" << stat->origGroup + range.gidStart
551
              << ",\"orig_osm_rel_id\":" << idx.getGroup(stat->origGroup)->osmid
620
              << ",\"orig_osm_rel_id\":" << idx.getGroup(stat->origGroup)->osmid
552
              << ",\"target_gid\":" << stat->group << ",\"target_osm_rel_id\":"
621
              << ",\"target_gid\":" << stat->group << ",\"target_osm_rel_id\":"
553
              << idx.getGroup(stat->group)->osmid + range.gidStart << "}";
622
              << idx.getGroup(stat->group)->osmid + range.gidStart << "}";
554
-        seper = ',';
555
-      } else {
556
-        json << "{\"type\": 5,\"orig_gid\":" << stat->origGroup + range.gidStart
623
+      } else if (sugg->type == 5) {
624
+        json << seper << "{\"type\":5,\"orig_gid\":" << stat->origGroup + range.gidStart
557
              << ",\"orig_osm_rel_id\":" << idx.getGroup(stat->origGroup)->osmid
625
              << ",\"orig_osm_rel_id\":" << idx.getGroup(stat->origGroup)->osmid
558
              << ",\"target_gid\":" << stat->group + range.gidStart
626
              << ",\"target_gid\":" << stat->group + range.gidStart
559
              << ",\"target_osm_rel_id\":" << idx.getGroup(stat->group)->osmid
627
              << ",\"target_osm_rel_id\":" << idx.getGroup(stat->group)->osmid
560
              << "}";
628
              << "}";
561
-        seper = ',';
629
+      } else if (sugg->type == 6) {
630
+       json << seper << "{\"type\":6,\"attr\":\"" << sugg->attrErrName << "\""
631
+            << "}";
632
+      } else if (sugg->type == 7) {
633
+        json << seper << "{\"type\":7}";
634
+      } else if (sugg->type == 8) {
635
+       json << seper << "{\"type\":8,\"attr\":\"" << sugg->attrErrName << "\""
636
+            << "}";
637
+      } else {
638
+        json << seper << "{\"type\":" << sugg->type << "}";
562
       }
639
       }
563
-    }
564
-  }
565
-
566
-  for (const auto& attrErr : stat->attrErrs) {
567
-    const auto otherStat = idx.getStation(attrErr.otherId);
568
-    if (otherStat->osmid == stat->osmid) {
569
-      // fix attributes
570
-      json << seper << "{\"type\": 6,\"attr\":\"" << attrErr.attr << "\""
571
-           << "}";
572
       seper = ',';
640
       seper = ',';
573
     }
641
     }
574
-  }
575
 
642
 
576
   json << "]";
643
   json << "]";
577
 
644
 

File diff suppressed because it is too large
+ 1 - 1
web/index.html


File diff suppressed because it is too large
+ 141 - 24
web/script.js