]> git.mxchange.org Git - flightgear.git/commitdiff
httpd: extend the NavDbUriHandler
authorTorsten Dreyer <torsten@ŧ3r.de>
Fri, 27 Mar 2015 23:34:28 +0000 (00:34 +0100)
committerTorsten Dreyer <torsten@ŧ3r.de>
Fri, 27 Mar 2015 23:34:28 +0000 (00:34 +0100)
- add more details for airports
- add "q=airports" query to get the airport list
- add "q=airport&id=abcd" query to get airport details

src/Network/http/NavdbUriHandler.cxx

index 9b0265e888b511e9f07e5fcad413c778b8891e3b..f9a5f65b357be075a9fd03772121bfd77202ee26 100644 (file)
@@ -22,6 +22,7 @@
 #include <simgear/debug/logstream.hxx>
 #include <Navaids/navrecord.hxx>
 #include <Airports/airport.hxx>
+#include <ATC/CommStation.hxx>
 #include <3rdparty/cjson/cJSON.h>
 #include <boost/lexical_cast.hpp>
 
@@ -30,6 +31,15 @@ using std::string;
 namespace flightgear {
 namespace http {
 
+static cJSON * createPositionArray(double x, double y, double z)
+{
+  cJSON * p = cJSON_CreateArray();
+  cJSON_AddItemToArray(p, cJSON_CreateNumber(x));
+  cJSON_AddItemToArray(p, cJSON_CreateNumber(y));
+  cJSON_AddItemToArray(p, cJSON_CreateNumber(z));
+  return p;
+}
+
 static cJSON * createPositionArray(double x, double y)
 {
   cJSON * p = cJSON_CreateArray();
@@ -75,14 +85,38 @@ static cJSON * createLOCGeometry(FGNavRecord * navRecord)
   return geometry;
 }
 
-static cJSON * createPointGeometry(FGPositionedRef positioned )
+static cJSON * createPointGeometry(FGPositioned * positioned )
 {
   cJSON * geometry = cJSON_CreateObject();
   cJSON_AddItemToObject(geometry, "type", cJSON_CreateString("Point"));
-  cJSON_AddItemToObject(geometry, "coordinates", createPositionArray(positioned ->longitude(), positioned->latitude()));
+  cJSON_AddItemToObject(geometry, "coordinates", 
+    createPositionArray(positioned ->longitude(), positioned->latitude(), positioned->elevationM()));
   return geometry;
 }
 
+static cJSON * createRunwayPolygon( FGRunwayBase * rwy )
+{
+  cJSON * polygon = cJSON_CreateObject(); 
+  cJSON_AddItemToObject(polygon, "type", cJSON_CreateString("Polygon"));
+  cJSON * coordinates = cJSON_CreateArray();
+  cJSON_AddItemToObject(polygon, "coordinates", coordinates );
+  cJSON * linearRing = cJSON_CreateArray();
+  cJSON_AddItemToArray( coordinates, linearRing );
+
+  // compute the four corners of the runway
+  SGGeod p1 = rwy->pointOffCenterline( 0.0, rwy->widthM()/2 );
+  SGGeod p2 = rwy->pointOffCenterline( 0.0, -rwy->widthM()/2 );
+  SGGeod p3 = rwy->pointOffCenterline( rwy->lengthM(), -rwy->widthM()/2 );
+  SGGeod p4 = rwy->pointOffCenterline( rwy->lengthM(), rwy->widthM()/2 );
+  cJSON_AddItemToArray( linearRing, createPositionArray(p1.getLongitudeDeg(), p1.getLatitudeDeg()) );
+  cJSON_AddItemToArray( linearRing, createPositionArray(p2.getLongitudeDeg(), p2.getLatitudeDeg()) );
+  cJSON_AddItemToArray( linearRing, createPositionArray(p3.getLongitudeDeg(), p3.getLatitudeDeg()) );
+  cJSON_AddItemToArray( linearRing, createPositionArray(p4.getLongitudeDeg(), p4.getLatitudeDeg()) );
+  // close the ring
+  cJSON_AddItemToArray( linearRing, createPositionArray(p1.getLongitudeDeg(), p1.getLatitudeDeg()) );
+  return polygon;
+}
+
 static cJSON * createAirportGeometry(FGAirport * airport )
 {
   assert( airport != NULL );
@@ -105,39 +139,27 @@ static cJSON * createAirportGeometry(FGAirport * airport )
 
   // followed by the runway polygons
   for( FGRunwayList::iterator it = runways.begin(); it != runways.end(); ++it ) {
-    cJSON * polygon = cJSON_CreateObject(); 
-    cJSON_AddItemToArray( geometryCollection, polygon );
-    cJSON_AddItemToObject(polygon, "type", cJSON_CreateString("Polygon"));
-    cJSON * coordinates = cJSON_CreateArray();
-    cJSON_AddItemToObject(polygon, "coordinates", coordinates );
-    cJSON * linearRing = cJSON_CreateArray();
-    cJSON_AddItemToArray( coordinates, linearRing );
-
-    // compute the four corners of the runway
-    SGGeod p1 = (*it)->pointOffCenterline( 0.0, (*it)->widthM()/2 );
-    SGGeod p2 = (*it)->pointOffCenterline( 0.0, -(*it)->widthM()/2 );
-    SGGeod p3 = (*it)->pointOffCenterline( (*it)->lengthM(), -(*it)->widthM()/2 );
-    SGGeod p4 = (*it)->pointOffCenterline( (*it)->lengthM(), (*it)->widthM()/2 );
-    cJSON_AddItemToArray( linearRing, createPositionArray(p1.getLongitudeDeg(), p1.getLatitudeDeg()) );
-    cJSON_AddItemToArray( linearRing, createPositionArray(p2.getLongitudeDeg(), p2.getLatitudeDeg()) );
-    cJSON_AddItemToArray( linearRing, createPositionArray(p3.getLongitudeDeg(), p3.getLatitudeDeg()) );
-    cJSON_AddItemToArray( linearRing, createPositionArray(p4.getLongitudeDeg(), p4.getLatitudeDeg()) );
-    // close the ring
-    cJSON_AddItemToArray( linearRing, createPositionArray(p1.getLongitudeDeg(), p1.getLatitudeDeg()) );
+    cJSON_AddItemToArray( geometryCollection, createRunwayPolygon(*it) );
+  }
+
+  FGTaxiwayList taxiways = airport->getTaxiways();
+  // followed by the taxiway polygons
+  for( FGTaxiwayList::iterator it = taxiways.begin(); it != taxiways.end(); ++it ) {
+    cJSON_AddItemToArray( geometryCollection, createRunwayPolygon(*it) );
   }
 
   return geometry;
 }
 
-static cJSON * createGeometryFor(FGPositionedRef positioned)
+static cJSON * createGeometryFor(FGPositioned * positioned)
 {
   switch( positioned->type() ) {
     case FGPositioned::LOC:
     case FGPositioned::ILS:
-      return createLOCGeometry( dynamic_cast<FGNavRecord*>(positioned.get()) );
+      return createLOCGeometry( dynamic_cast<FGNavRecord*>(positioned) );
 
     case FGPositioned::AIRPORT:
-      return createAirportGeometry( dynamic_cast<FGAirport*>(positioned.get()) );
+      return createAirportGeometry( dynamic_cast<FGAirport*>(positioned) );
 
     default:
       return createPointGeometry( positioned );
@@ -147,12 +169,32 @@ static cJSON * createGeometryFor(FGPositionedRef positioned)
 static void addAirportProperties(cJSON * json, FGAirport * airport )
 {
   if( NULL == airport ) return;
-  FGRunwayList runways = airport->getRunwaysWithoutReciprocals();
   double longestRunwayLength = 0.0;
   double longestRunwayHeading = 0.0;
   const char * longestRunwaySurface = "";
+
+  cJSON_AddItemToObject(json, "name", cJSON_CreateString(airport->getName().c_str()));
+  cJSON * runwaysJson = cJSON_CreateArray();
+  cJSON_AddItemToObject(json, "runways", runwaysJson);
+
+  FGRunwayList runways = airport->getRunways();
   for( FGRunwayList::iterator it = runways.begin(); it != runways.end(); ++it ) {
-    FGRunwayRef runway = *it;
+    FGRunway * runway = *it;
+    cJSON * runwayJson = cJSON_CreateObject();
+    cJSON_AddItemToArray( runwaysJson, runwayJson );
+    cJSON_AddItemToObject(runwayJson, "id", cJSON_CreateString(runway->ident().c_str()));
+    cJSON_AddItemToObject(runwayJson, "length_m", cJSON_CreateNumber(runway->lengthM()));
+    cJSON_AddItemToObject(runwayJson, "width_m", cJSON_CreateNumber(runway->widthM()));
+    cJSON_AddItemToObject(runwayJson, "surface", cJSON_CreateString(runway->surfaceName()));
+    cJSON_AddItemToObject(runwayJson, "heading_deg", cJSON_CreateNumber(runway->headingDeg()));
+    double d = runway->displacedThresholdM();
+    if( d > .0 )
+      cJSON_AddItemToObject(runwayJson, "dispacedThreshold_m", cJSON_CreateNumber(d));
+
+    d = runway->stopwayM();
+    if( d > .0 )
+      cJSON_AddItemToObject(runwayJson, "stopway_m", cJSON_CreateNumber(d));
+
     if( runway->lengthM() > longestRunwayLength ) {
       longestRunwayLength = runway->lengthM();
       longestRunwayHeading = runway->headingDeg();
@@ -165,6 +207,17 @@ static void addAirportProperties(cJSON * json, FGAirport * airport )
   if( airport->getMetar() ) {
     cJSON_AddItemToObject(json, "metar", cJSON_CreateTrue());
   }
+
+  cJSON * commsJson = cJSON_CreateArray();
+  cJSON_AddItemToObject(json, "comm", commsJson);
+  flightgear::CommStationList comms = airport->commStations();
+  for( flightgear::CommStationList::iterator it = comms.begin(); it != comms.end(); ++it ) {
+    flightgear::CommStation * comm = *it;
+    cJSON * commJson = cJSON_CreateObject();
+    cJSON_AddItemToArray( commsJson, commJson );
+    cJSON_AddItemToObject(commJson, "id", cJSON_CreateString(comm->ident().c_str()));
+    cJSON_AddItemToObject(commJson, "mhz", cJSON_CreateNumber(comm->freqMHz()));
+  }
 }
 
 static void addNAVProperties(cJSON * json, FGNavRecord * navRecord )
@@ -187,7 +240,7 @@ static void addNAVProperties(cJSON * json, FGNavRecord * navRecord )
   }
 }
 
-static cJSON * createPropertiesFor(FGPositionedRef positioned)
+static cJSON * createPropertiesFor(FGPositioned * positioned)
 {
   cJSON * properties = cJSON_CreateObject();
 
@@ -196,12 +249,12 @@ static cJSON * createPropertiesFor(FGPositionedRef positioned)
   cJSON_AddItemToObject(properties, "id", cJSON_CreateString(positioned->ident().c_str()));
   cJSON_AddItemToObject(properties, "type", cJSON_CreateString(positioned->typeString()));
   cJSON_AddItemToObject(properties, "elevation-m", cJSON_CreateNumber(positioned->elevationM()));
-  addNAVProperties( properties, dynamic_cast<FGNavRecord*>(positioned.get()) );
-  addAirportProperties( properties, dynamic_cast<FGAirport*>(positioned.get()) );
+  addNAVProperties( properties, dynamic_cast<FGNavRecord*>(positioned) );
+  addAirportProperties( properties, dynamic_cast<FGAirport*>(positioned) );
   return properties;
 }
 
-static cJSON * createFeatureFor(FGPositionedRef positioned)
+static cJSON * createFeatureFor(FGPositioned * positioned)
 {
   cJSON * feature = cJSON_CreateObject();
 
@@ -273,6 +326,21 @@ bool NavdbUriHandler::handleRequest(const HTTPRequest & request, HTTPResponse &
     }
 
     result = FGPositioned::findWithinRange(pos, range, &filter);
+  } else if (query == "airports") {
+    cJSON * json = cJSON_CreateArray();
+    for( char ** airports = FGAirport::searchNamesAndIdents(""); *airports; airports++ ) {
+      cJSON_AddItemToArray(json, cJSON_CreateString(*airports));
+    }
+    char * jsonString = indent ? cJSON_Print(json) : cJSON_PrintUnformatted(json);
+    cJSON_Delete(json);
+    response.Content = jsonString;
+    free(jsonString);
+    return true;
+
+  } else if (query == "airport") {
+    FGAirportRef airport = FGAirport::findByIdent(request.RequestVariables.get("id"));
+    if( airport.valid() )
+      result.push_back( airport );
   } else {
     goto fail;
   }