1
0
Fork 0

httpd: extend the NavDbUriHandler

- add more details for airports
- add "q=airports" query to get the airport list
- add "q=airport&id=abcd" query to get airport details
This commit is contained in:
Torsten Dreyer 2015-03-28 00:34:28 +01:00
parent 32f4fdfaf7
commit 8f9df6940f

View 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 );
cJSON_AddItemToArray( geometryCollection, createRunwayPolygon(*it) );
}
// 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()) );
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;
}