FlightGear next
poidb.cxx
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: (C) Christian Schmitt, March 2013
3 * SPDX_FileComment: points of interest management routines
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#include "config.h"
8
9#include <istream> // std::ws
10#include "poidb.hxx"
11
12#include <simgear/compiler.h>
13#include <simgear/debug/logstream.hxx>
14#include <simgear/math/sg_geodesy.hxx>
15#include <simgear/misc/sg_path.hxx>
16#include <simgear/structure/exception.hxx>
17#include <simgear/io/iostreams/sgstream.hxx>
18
20
21
22using std::string;
23
26{
27 switch (aTy) {
28 case 10: return FGPositioned::COUNTRY;
29 case 12: return FGPositioned::CITY;
30 case 13: return FGPositioned::TOWN;
31 case 14: return FGPositioned::VILLAGE;
32
34 case 1001: return FGPositioned::WAYPOINT;
35
36 default:
37 throw sg_range_exception("Unknown POI type", "FGNavDataCache::readPOIFromStream");
38 }
39}
40
41namespace flightgear
42{
43
44// Duplicate POIs with the same ident will be removed if the disance
45// between them is less than this.
46static const double DUPLICATE_DETECTION_RADIUS_NM = 10;
47
49
50static bool isNearby(const SGVec3d& pos1, const SGVec3d& pos2)
51{
52 const double d = distSqr(pos1, pos2);
54}
55
57 _cache(NavDataCache::instance())
58{
59
60}
61
62
64 std::size_t bytesReadSoFar,
65 std::size_t totalSizeOfAllDatFiles)
66{
67 _path = sceneryLocation.datPath;
68 sg_gzifstream in( _path );
69 const std::string utf8path = _path.utf8Str();
70
71 if ( !in.is_open() ) {
72 throw sg_io_exception(
73 "Cannot open file (" + simgear::strutils::error_string(errno) + ")",
74 sg_location(_path));
75 }
76
77 // Skip the first two lines
78 for (int i = 0; i < 2; i++) {
79 std::string line;
80 std::getline(in, line);
81 throwExceptionIfStreamError(in);
82 }
83
84
85 unsigned int lineNumber = 3;
86
87 // read in each remaining line of the file
88 for (std::string line; !in.eof(); lineNumber++) {
89
90 readPOIFromStream(in, lineNumber);
91
92 ++lineNumber;
93 if ((lineNumber % 100) == 0) {
94 // every 100 lines
95 unsigned int percent = ((bytesReadSoFar + in.approxOffset()) * 100)
96 / totalSizeOfAllDatFiles;
97 _cache->setRebuildPhaseProgress(NavDataCache::REBUILD_POIS, percent);
98 }
99 } // of line iteration
100
101 throwExceptionIfStreamError(in);
102}
103
104void POILoader::throwExceptionIfStreamError(const sg_gzifstream& input_stream)
105{
106 if (input_stream.bad()) {
107 const std::string errMsg = simgear::strutils::error_string(errno);
108
109 SG_LOG(SG_NAVAID, SG_ALERT,
110 "Error while reading '" << _path.utf8Str() << "': " << errMsg);
111 throw sg_io_exception("POILoader: error reading file (" + errMsg + ")",
112 sg_location(_path));
113 }
114}
115
116PositionedID POILoader::readPOIFromStream(std::istream& aStream,
117 unsigned int lineNumber,FGPositioned::Type type)
118{
119 if (aStream.eof()) {
120 return 0;
121 }
122
123 aStream >> std::ws;
124 if (aStream.peek() == '#') {
125 aStream >> skipeol;
126 return 0;
127 }
128
129 int rawType;
130 aStream >> rawType;
131 double lat, lon;
132 std::string name;
133 aStream >> lat >> lon;
134 getline(aStream, name);
135
136 SGGeod pos(SGGeod::fromDeg(lon, lat));
137 name = simgear::strutils::strip(name);
138
139 // the type can be forced by our caller, but normally we use the value
140 // supplied in the .dat file
141 if (type == FGPositioned::INVALID) {
142 type = mapPOITypeToFGPType(rawType);
143 }
144 if (type == FGPositioned::INVALID) {
145 return 0;
146 }
147
148 const auto cartPos = SGVec3d::fromGeod(pos);
149
150 // de-duplication
151 const auto key = std::make_tuple(type, name);
152 auto matching = _loadedPOIs.equal_range(key);
153 for (auto it = matching.first; it != matching.second; ++it) {
154 if (isNearby(cartPos, it->second)) {
155 SG_LOG(SG_NAVAID, SG_INFO,
156 _path.utf8Str() << ":" << lineNumber << ": skipping POI '" <<
157 name << "' (already defined nearby)");
158 return 0;
159 }
160 }
161
162 _loadedPOIs.emplace(key, cartPos);
163 return _cache->createPOI(type, name, pos, name, false);
164}
165
166
167} // of namespace flightgear
#define i(x)
void loadPOIs(const NavDataCache::SceneryLocation &sceneryLocation, std::size_t bytesReadSoFar, std::size_t totalSizeOfAllDatFiles)
Definition poidb.cxx:63
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
Definition Addon.cxx:53
static const double DUPLICATE_DETECTION_RADIUS_SQR_M
Definition poidb.cxx:48
static const double DUPLICATE_DETECTION_RADIUS_NM
Definition poidb.cxx:46
const char * name
static bool isNearby(const SGGeod &pos1, const SGGeod &pos2)
Definition navdb.cxx:116
static FGPositioned::Type mapPOITypeToFGPType(int aTy)
Definition poidb.cxx:25
int64_t PositionedID