19#include <simgear/timing/timestamp.hxx>
20#include <simgear/debug/logstream.hxx>
21#include <simgear/structure/exception.hxx>
22#include <simgear/math/SGGeometry.hxx>
23#include <simgear/sg_inlines.h>
32 if (SGMisc<double>::isNaN(geod.getLatitudeDeg()) ||
33 SGMisc<double>::isNaN(geod.getLongitudeDeg()))
35 throw sg_range_exception(
"position is invalid, NaNs");
42 SG_LOG(SG_GENERAL, SG_WARN,
"invalid positioned filter specified");
53 const std::string& aIdent,
59 mCart(SGVec3d::fromGeod(mPosition))
91 switch (pos->
type()) {
121 const std::string& aName)
126 throw std::logic_error(std::string{
"Create waypoint: not allowed for type:"} +
nameForType(aType));
133 auto distanceNm = SGGeodesy::distanceNm(existing->geod(), aPos);
134 if (distanceNm < 100) {
135 SG_LOG(SG_NAVAID, SG_WARN,
"attempt to insert duplicate waypoint:" << aIdent <<
" within 100nm of existing waypoint with same ident");
147 const auto ty = ref->type();
149 SG_LOG(SG_NAVAID, SG_DEV_WARN,
"attempt to remove non-POI waypoint:" << ref->ident());
165 if (aName.empty() || (aName ==
"")) {
174 const NameTypeEntry names[] = {
222 {
"outer-marker",
OM},
223 {
"middle-marker",
MM},
224 {
"inner-marker",
IM},
230 std::string lowerName = simgear::strutils::lowercase(aName);
232 for (
const NameTypeEntry* n = names; (n->_name != NULL); ++n) {
233 if (::strcmp(n->_name, lowerName.c_str()) == 0) {
238 SG_LOG(SG_NAVAID, SG_WARN,
"FGPositioned::typeFromName: couldn't match:" << aName);
245 case RUNWAY:
return "runway";
246 case HELIPAD:
return "helipad";
247 case TAXIWAY:
return "taxiway";
249 case PARKING:
return "parking stand";
250 case FIX:
return "fix";
251 case VOR:
return "VOR";
252 case NDB:
return "NDB";
253 case ILS:
return "ILS";
254 case LOC:
return "localizer";
255 case GS:
return "glideslope";
256 case OM:
return "outer-marker";
257 case MM:
return "middle-marker";
258 case IM:
return "inner-marker";
259 case AIRPORT:
return "airport";
261 case SEAPORT:
return "seaport";
263 case DME:
return "dme";
264 case TACAN:
return "tacan";
273 case COUNTRY:
return "country";
274 case CITY:
return "city";
275 case TOWN:
return "town";
276 case VILLAGE:
return "village";
298 if (aIdent.empty()) {
322 aRangeNm * SG_NM_TO_METER, aFilter, result, 0xffffff);
338 aRangeNm * SG_NM_TO_METER, aFilter, result,
377 assert(l.size() == 1);
387 int limitMsec = 0xffff;
388 Octree::findNearestN(SGVec3d::fromGeod(aPos), aN, aCutoffNm * SG_NM_TO_METER, aFilter, result, limitMsec);
399 aPartial =
Octree::findNearestN(SGVec3d::fromGeod(aPos), aN, aCutoffNm * SG_NM_TO_METER, aFilter, result,
409 SGVec3d cartPos(SGVec3d::fromGeod(aPos));
412 FGPositionedList::iterator it = aResult.begin(), lend = aResult.end();
413 for (; it != lend; ++it) {
414 double d2 = distSqr((*it)->cart(), cartPos);
419 std::sort(r.begin(), r.end());
422 unsigned int count = aResult.size();
423 for (
unsigned int i=0;
i<count; ++
i) {
424 aResult[
i] = r[
i].get();
431 const_cast<SGGeod&
>(mPosition) = newPos;
432 const_cast<SGVec3d&
>(mCart) = SGVec3d::fromGeod(newPos);
438 const_cast<SGGeod&
>(mPosition) = SGGeod::fromDeg(999,999);
439 const_cast<SGVec3d&
>(mCart) = SGVec3d::zeros();
455 for (
auto t : types) {
462 for (
int t = aMinType; t <= aMaxType; t++) {
474 types.push_back(aTy);
475 mMinType = std::min(mMinType, aTy);
476 mMaxType = std::max(mMaxType, aTy);
482 if (aFilterSpec.empty()) {
483 throw sg_format_exception(
"empty filter spec:", aFilterSpec);
486 string_list parts = simgear::strutils::split(aFilterSpec,
",");
489 for (std::string token : parts) {
503 std::vector<Type>::const_iterator it = types.begin(),
505 for (; it != end; ++it) {
506 if (aPos->
type() == *it) {
Predicate class to support custom filtering of FGPositioned queries Default implementation of this pa...
virtual Type maxType() const
virtual Type minType() const
bool pass(FGPositioned *aPos) const override
Over-rideable filter method.
TypeFilter(Type aTy=INVALID)
static TypeFilter fromString(const std::string &aFilterSpec)
static Type typeFromName(const std::string &aName)
Map a candidate type string to a real type.
static FGPositionedList findAllWithName(const std::string &aName, Filter *aFilter=NULL, bool aExact=true)
As above, but searches names instead of idents.
static bool isRunwayType(FGPositioned *pos)
FGPositioned(PositionedID aGuid, Type ty, const std::string &aIdent, const SGGeod &aPos)
static FGPositionedRef createWaypoint(FGPositioned::Type aType, const std::string &aIdent, const SGGeod &aPos, bool isTemporary=false, const std::string &aName={})
friend class flightgear::NavDataCache
static FGPositionedRef findClosestWithIdent(const std::string &aIdent, const SGGeod &aPos, Filter *aFilter=NULL)
void modifyPosition(const SGGeod &newPos)
static FGPositionedList findWithinRange(const SGGeod &aPos, double aRangeNm, Filter *aFilter)
static FGPositionedList findClosestNPartial(const SGGeod &aPos, unsigned int aN, double aCutoffNm, Filter *aFilter, bool &aPartial)
Same as above, but with a time-bound in msec too.
virtual const SGVec3d & cart() const
The cartesian position associated with this object.
static FGPositionedRef findFirstWithIdent(const std::string &aIdent, Filter *aFilter)
static void sortByRange(FGPositionedList &, const SGGeod &aPos)
Sort an FGPositionedList by distance from a position.
static FGPositionedRef loadByIdImpl(PositionedID id)
void invalidatePosition()
static bool isAirportType(FGPositioned *pos)
@ PARKING
parking position - might be a gate, or stand
@ DME
important that DME & TACAN are adjacent to keep the TacanFilter efficient - DMEs are proxies for TACA...
static FGPositionedList findAllWithIdent(const std::string &aIdent, Filter *aFilter=NULL, bool aExact=true)
Find all items with the specified ident.
static const char * nameForType(Type aTy)
Map a type to a human-readable string.
static bool isNavaidType(FGPositioned *pos)
static FGPositionedList findClosestN(const SGGeod &aPos, unsigned int aN, double aCutoffNm, Filter *aFilter=NULL)
Find the closest N items to a position, which pass the specified filter A cutoff range in NM must be ...
static FGPositionedList findWithinRangePartial(const SGGeod &aPos, double aRangeNm, Filter *aFilter, bool &aPartial)
static bool deleteWaypoint(FGPositionedRef aWpt)
static FGPositionedRef findClosest(const SGGeod &aPos, double aCutoffNm, Filter *aFilter=NULL)
Find the closest item to a position, which pass the specified filter A cutoff range in NM must be spe...
static bool isType(FGPositioned::Type ty)
POI(PositionedID aGuid, Type ty, const std::string &aIdent, const SGGeod &aPos, const std::string &aName)
PositionedID createPOI(FGPositioned::Type ty, const std::string &ident, const SGGeod &aPos, const std::string &aName, bool transient)
FGPositionedRef findClosestWithIdent(const std::string &aIdent, const SGGeod &aPos, FGPositioned::Filter *aFilter)
FGPositionedList findAllWithIdent(const std::string &ident, FGPositioned::Filter *filter, bool exact)
bool removePOI(FGPositionedRef wpt)
FGPositionedRef loadById(PositionedID guid)
retrieve an FGPositioned from the cache.
static NavDataCache * instance()
FGPositionedList findAllWithName(const std::string &ident, FGPositioned::Filter *filter, bool exact)
std::vector< std::string > string_list
Ordered< FGPositioned * > OrderedPositioned
bool findAllWithinRange(const SGVec3d &aPos, double aRangeM, FGPositioned::Filter *aFilter, FGPositionedList &aResults, int aCutoffMsec)
std::vector< OrderedPositioned > FindNearestResults
bool findNearestN(const SGVec3d &aPos, unsigned int aN, double aCutoffM, FGPositioned::Filter *aFilter, FGPositionedList &aResults, int aCutoffMsec)
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
SGSharedPtr< FGPositioned > FGPositionedRef
static bool validateFilter(FGPositioned::Filter *filter)
static void validateSGGeod(const SGGeod &geod)
static bool isValidCustomWaypointType(FGPositioned::Type ty)
SGSharedPtr< FGPositioned > FGPositionedRef
std::vector< FGPositionedRef > FGPositionedList