From 68c71d5787f2a0309e35c3e05939950113618cb7 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sat, 2 Mar 2013 13:44:20 +0000 Subject: [PATCH] Positioned/Cache tweaks to support PoIs. In preparation for adding POI data, extend the FGPositioned type enum, and the cache code to handle arbitrary POI types. (Adding more in the future is straightforward now) Also support removing user waypoints, which was requested by the Garmin G196 developers. --- src/Navaids/NavDataCache.cxx | 26 +++++++++++++++++++++++--- src/Navaids/NavDataCache.hxx | 4 +++- src/Navaids/positioned.cxx | 30 ++++++++++++++++++++++++++++-- src/Navaids/positioned.hxx | 6 ++++++ 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/Navaids/NavDataCache.cxx b/src/Navaids/NavDataCache.cxx index ee7b90d95..aeb70cc30 100644 --- a/src/Navaids/NavDataCache.cxx +++ b/src/Navaids/NavDataCache.cxx @@ -573,6 +573,8 @@ public: " VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)"); runwayLengthFtQuery = prepare("SELECT length_ft FROM runway WHERE rowid=?1"); + removePOIQuery = prepare("DELETE FROM positioned WHERE type=?1 AND ident=?2"); + // query statement findClosestWithIdent = prepare("SELECT rowid FROM positioned WHERE ident=?1 " AND_TYPED " ORDER BY distanceCartSqr(cart_x, cart_y, cart_z, ?4, ?5, ?6)"); @@ -921,6 +923,14 @@ public: deferredOctreeUpdates.clear(); } + + void removePositionedWithIdent(FGPositioned::Type ty, const std::string& aIdent) + { + sqlite3_bind_int(removePOIQuery, 1, ty); + sqlite_bind_stdstring(removePOIQuery, 2, aIdent); + execUpdate(removePOIQuery); + reset(removePOIQuery); + } NavDataCache* outer; sqlite3* db; @@ -952,6 +962,7 @@ public: insertCommStation, insertNavaid; sqlite3_stmt_ptr setAirportMetar, setRunwayReciprocal, setRunwayILS, setAirportPos, updateRunwayThreshold, updateILS; + sqlite3_stmt_ptr removePOIQuery; sqlite3_stmt_ptr findClosestWithIdent; // octree (spatial index) related queries @@ -1056,8 +1067,11 @@ FGPositioned* NavDataCache::NavDataCachePrivate::loadById(sqlite3_int64 rowid) return new FGFix(rowid, ident, pos); case FGPositioned::WAYPOINT: + case FGPositioned::COUNTRY: + case FGPositioned::CITY: + case FGPositioned::TOWN: { - FGPositioned* wpt = new FGPositioned(rowid, FGPositioned::WAYPOINT, ident, pos); + FGPositioned* wpt = new FGPositioned(rowid, ty, ident, pos); return wpt; } @@ -1629,11 +1643,17 @@ PositionedID NavDataCache::insertFix(const std::string& ident, const SGGeod& aPo return d->insertPositioned(FGPositioned::FIX, ident, string(), aPos, 0, true); } -PositionedID NavDataCache::createUserWaypoint(const std::string& ident, const SGGeod& aPos) +PositionedID NavDataCache::createPOI(FGPositioned::Type ty, const std::string& ident, const SGGeod& aPos) { - return d->insertPositioned(FGPositioned::WAYPOINT, ident, string(), aPos, 0, + return d->insertPositioned(ty, ident, string(), aPos, 0, true /* spatial index */); } + +void NavDataCache::removePOI(FGPositioned::Type ty, const std::string& aIdent) +{ + d->removePositionedWithIdent(ty, aIdent); + // should remove from the live cache too? +} void NavDataCache::setAirportMetar(const string& icao, bool hasMetar) { diff --git a/src/Navaids/NavDataCache.hxx b/src/Navaids/NavDataCache.hxx index dc78d8be5..93ef318c7 100644 --- a/src/Navaids/NavDataCache.hxx +++ b/src/Navaids/NavDataCache.hxx @@ -116,8 +116,10 @@ public: PositionedID apt); PositionedID insertFix(const std::string& ident, const SGGeod& aPos); - PositionedID createUserWaypoint(const std::string& ident, const SGGeod& aPos); + PositionedID createPOI(FGPositioned::Type ty, const std::string& ident, const SGGeod& aPos); + void removePOI(FGPositioned::Type ty, const std::string& aIdent); + void dropGroundnetFor(PositionedID aAirport); PositionedID insertParking(const std::string& name, const SGGeod& aPos, diff --git a/src/Navaids/positioned.cxx b/src/Navaids/positioned.cxx index 92250b906..ee60aca80 100644 --- a/src/Navaids/positioned.cxx +++ b/src/Navaids/positioned.cxx @@ -73,10 +73,25 @@ FGPositioned::~FGPositioned() FGPositioned* FGPositioned::createUserWaypoint(const std::string& aIdent, const SGGeod& aPos) { - PositionedID id = NavDataCache::instance()->createUserWaypoint(aIdent, aPos); - return NavDataCache::instance()->loadById(id); + NavDataCache* cache = NavDataCache::instance(); + TypeFilter filter(WAYPOINT); + FGPositioned::List existing = cache->findAllWithIdent(aIdent, &filter, true); + if (!existing.empty()) { + SG_LOG(SG_NAVAID, SG_WARN, "attempt to insert duplicate WAYPOINT:" << aIdent); + return existing.front().ptr(); + } + + PositionedID id = cache->createPOI(WAYPOINT, aIdent, aPos); + return cache->loadById(id); +} + +void FGPositioned::deleteUserWaypoint(const std::string& aIdent) +{ + NavDataCache* cache = NavDataCache::instance(); + cache->removePOI(WAYPOINT, aIdent); } + const SGVec3d& FGPositioned::cart() const { @@ -111,12 +126,19 @@ FGPositioned::Type FGPositioned::typeFromName(const std::string& aName) {"ground", FREQ_GROUND}, {"approach", FREQ_APP_DEP}, {"departure", FREQ_APP_DEP}, + {"runway", RUNWAY}, + {"helipad", HELIPAD}, + {"country", COUNTRY}, + {"city", CITY}, + {"town", TOWN}, + // aliases {"gnd", FREQ_GROUND}, {"twr", FREQ_TOWER}, {"waypoint", WAYPOINT}, {"apt", AIRPORT}, {"arpt", AIRPORT}, + {"rwy", RUNWAY}, {"any", INVALID}, {"all", INVALID}, @@ -139,6 +161,7 @@ const char* FGPositioned::nameForType(Type aTy) { switch (aTy) { case RUNWAY: return "runway"; + case HELIPAD: return "helipad"; case TAXIWAY: return "taxiway"; case PAVEMENT: return "pavement"; case PARKING: return "parking stand"; @@ -165,6 +188,9 @@ const char* FGPositioned::nameForType(Type aTy) case FREQ_UNICOM: return "unicom"; case FREQ_APP_DEP: return "approach-departure"; case TAXI_NODE: return "taxi-node"; + case COUNTRY: return "country"; + case CITY: return "city"; + case TOWN: return "town"; default: return "unknown"; } diff --git a/src/Navaids/positioned.hxx b/src/Navaids/positioned.hxx index 7aaaf22ad..aeaea6f12 100644 --- a/src/Navaids/positioned.hxx +++ b/src/Navaids/positioned.hxx @@ -81,6 +81,11 @@ public: // groundnet items PARKING, ///< parking position - might be a gate, or stand TAXI_NODE, +// POI items + COUNTRY, + CITY, + TOWN, + LAST_TYPE } Type; @@ -230,6 +235,7 @@ public: static const char* nameForType(Type aTy); static FGPositioned* createUserWaypoint(const std::string& aIdent, const SGGeod& aPos); + static void deleteUserWaypoint(const std::string& aIdent); protected: friend class flightgear::NavDataCache; -- 2.39.5