/gdal-1.9.1-fedora/ogr/ogrsf_frmts/xplane/ogr_xplane_awy_reader.cpp
C++ | 421 lines | 263 code | 67 blank | 91 comment | 28 complexity | ba25fff9acb365984b3567af070a029d MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.0
- /******************************************************************************
- * $Id: ogr_xplane_awy_reader.cpp
- *
- * Project: X-Plane awy.dat file reader
- * Purpose: Implements OGRXPlaneAwyReader class
- * Author: Even Rouault, even dot rouault at mines dash paris dot org
- *
- ******************************************************************************
- * Copyright (c) 2008, Even Rouault
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- ****************************************************************************/
- #include "ogr_xplane_awy_reader.h"
- CPL_CVSID("$Id: ogr_xplane_awy_reader.cpp 21634 2011-02-06 14:45:00Z rouault $");
- /************************************************************************/
- /* OGRXPlaneCreateAwyFileReader */
- /************************************************************************/
- OGRXPlaneReader* OGRXPlaneCreateAwyFileReader( OGRXPlaneDataSource* poDataSource )
- {
- OGRXPlaneReader* poReader = new OGRXPlaneAwyReader(poDataSource);
- return poReader;
- }
- /************************************************************************/
- /* OGRXPlaneAwyReader() */
- /************************************************************************/
- OGRXPlaneAwyReader::OGRXPlaneAwyReader()
- {
- poAirwaySegmentLayer = NULL;
- poAirwayIntersectionLayer = NULL;
- }
- /************************************************************************/
- /* OGRXPlaneAwyReader() */
- /************************************************************************/
- OGRXPlaneAwyReader::OGRXPlaneAwyReader( OGRXPlaneDataSource* poDataSource )
- {
- poAirwaySegmentLayer = new OGRXPlaneAirwaySegmentLayer();
- poAirwayIntersectionLayer = new OGRXPlaneAirwayIntersectionLayer();
- poDataSource->RegisterLayer(poAirwaySegmentLayer);
- poDataSource->RegisterLayer(poAirwayIntersectionLayer);
- }
- /************************************************************************/
- /* CloneForLayer() */
- /************************************************************************/
- OGRXPlaneReader* OGRXPlaneAwyReader::CloneForLayer(OGRXPlaneLayer* poLayer)
- {
- OGRXPlaneAwyReader* poReader = new OGRXPlaneAwyReader();
- poReader->poInterestLayer = poLayer;
- SET_IF_INTEREST_LAYER(poAirwaySegmentLayer);
- SET_IF_INTEREST_LAYER(poAirwayIntersectionLayer);
- if (pszFilename)
- {
- poReader->pszFilename = CPLStrdup(pszFilename);
- poReader->fp = VSIFOpenL( pszFilename, "rt" );
- }
- return poReader;
- }
- /************************************************************************/
- /* IsRecognizedVersion() */
- /************************************************************************/
- int OGRXPlaneAwyReader::IsRecognizedVersion( const char* pszVersionString)
- {
- return EQUALN(pszVersionString, "640 Version", 11);
- }
- /************************************************************************/
- /* Read() */
- /************************************************************************/
- void OGRXPlaneAwyReader::Read()
- {
- const char* pszLine;
- while((pszLine = CPLReadLineL(fp)) != NULL)
- {
- papszTokens = CSLTokenizeString(pszLine);
- nTokens = CSLCount(papszTokens);
- nLineNumber ++;
- if (nTokens == 1 && strcmp(papszTokens[0], "99") == 0)
- {
- CSLDestroy(papszTokens);
- papszTokens = NULL;
- bEOF = TRUE;
- return;
- }
- else if (nTokens == 0 || assertMinCol(10) == FALSE)
- {
- CSLDestroy(papszTokens);
- papszTokens = NULL;
- continue;
- }
- ParseRecord();
- CSLDestroy(papszTokens);
- papszTokens = NULL;
- if (poInterestLayer && poInterestLayer->IsEmpty() == FALSE)
- return;
- }
- papszTokens = NULL;
- bEOF = TRUE;
- }
- /************************************************************************/
- /* ParseRecord() */
- /************************************************************************/
- void OGRXPlaneAwyReader::ParseRecord()
- {
- const char* pszFirstPointName;
- const char* pszSecondPointName;
- const char* pszAirwaySegmentName;
- double dfLat1, dfLon1;
- double dfLat2, dfLon2;
- int bIsHigh;
- int nBaseFL, nTopFL;
- pszFirstPointName = papszTokens[0];
- RET_IF_FAIL(readLatLon(&dfLat1, &dfLon1, 1));
- pszSecondPointName = papszTokens[3];
- RET_IF_FAIL(readLatLon(&dfLat2, &dfLon2, 4));
- bIsHigh = atoi(papszTokens[6]) == 2;
- nBaseFL = atoi(papszTokens[7]);
- nTopFL = atoi(papszTokens[8]);
- pszAirwaySegmentName = papszTokens[9];
- if (poAirwayIntersectionLayer)
- {
- poAirwayIntersectionLayer->AddFeature(pszFirstPointName, dfLat1, dfLon1);
- poAirwayIntersectionLayer->AddFeature(pszSecondPointName, dfLat2, dfLon2);
- }
- if (poAirwaySegmentLayer)
- {
- /*
- poAirwaySegmentLayer->AddFeature(pszAirwaySegmentName,
- pszFirstPointName,
- pszSecondPointName,
- dfLat1, dfLon1, dfLat2, dfLon2,
- bIsHigh, nBaseFL, nTopFL);
- */
- if (strchr(pszAirwaySegmentName, '-'))
- {
- char** papszSegmentNames = CSLTokenizeString2( pszAirwaySegmentName, "-", CSLT_HONOURSTRINGS );
- int i = 0;
- while(papszSegmentNames[i])
- {
- poAirwaySegmentLayer->AddFeature(papszSegmentNames[i],
- pszFirstPointName,
- pszSecondPointName,
- dfLat1, dfLon1, dfLat2, dfLon2,
- bIsHigh, nBaseFL, nTopFL);
- i++;
- }
- CSLDestroy(papszSegmentNames);
- }
- else
- {
- poAirwaySegmentLayer->AddFeature(pszAirwaySegmentName,
- pszFirstPointName,
- pszSecondPointName,
- dfLat1, dfLon1, dfLat2, dfLon2,
- bIsHigh, nBaseFL, nTopFL);
- }
- }
- }
- /************************************************************************/
- /* OGRXPlaneAirwaySegmentLayer() */
- /************************************************************************/
- OGRXPlaneAirwaySegmentLayer::OGRXPlaneAirwaySegmentLayer() : OGRXPlaneLayer("AirwaySegment")
- {
- poFeatureDefn->SetGeomType( wkbLineString );
- OGRFieldDefn oFieldSegmentName("segment_name", OFTString );
- poFeatureDefn->AddFieldDefn( &oFieldSegmentName );
- OGRFieldDefn oFieldPoint1Name("point1_name", OFTString );
- poFeatureDefn->AddFieldDefn( &oFieldPoint1Name );
- OGRFieldDefn oFieldPoint2Name("point2_name", OFTString );
- poFeatureDefn->AddFieldDefn( &oFieldPoint2Name );
- OGRFieldDefn oFieldIsHigh("is_high", OFTInteger );
- oFieldIsHigh.SetWidth( 1 );
- poFeatureDefn->AddFieldDefn( &oFieldIsHigh );
- OGRFieldDefn oFieldBase("base_FL", OFTInteger );
- oFieldBase.SetWidth( 3 );
- poFeatureDefn->AddFieldDefn( &oFieldBase );
- OGRFieldDefn oFieldTop("top_FL", OFTInteger );
- oFieldTop.SetWidth( 3 );
- poFeatureDefn->AddFieldDefn( &oFieldTop );
- }
- /************************************************************************/
- /* AddFeature() */
- /************************************************************************/
- OGRFeature*
- OGRXPlaneAirwaySegmentLayer::AddFeature(const char* pszAirwaySegmentName,
- const char* pszFirstPointName,
- const char* pszSecondPointName,
- double dfLat1,
- double dfLon1,
- double dfLat2,
- double dfLon2,
- int bIsHigh,
- int nBaseFL,
- int nTopFL)
- {
- int nCount = 0;
- OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
- if (fabs(dfLon1 - dfLon2) < 270)
- {
- OGRLineString* lineString = new OGRLineString();
- lineString->addPoint(dfLon1, dfLat1);
- lineString->addPoint(dfLon2, dfLat2);
- poFeature->SetGeometryDirectly( lineString );
- }
- else
- {
- /* Crossing antemeridian */
- OGRMultiLineString* multiLineString = new OGRMultiLineString();
- OGRLineString* lineString1 = new OGRLineString();
- OGRLineString* lineString2 = new OGRLineString();
- double dfLatInt;
- lineString1->addPoint(dfLon1, dfLat1);
- if (dfLon1 < dfLon2)
- {
- dfLatInt = dfLat1 + (dfLat2 - dfLat1) * (-180 - dfLon1) / ((dfLon2 - 360) - dfLon1);
- lineString1->addPoint(-180, dfLatInt);
- lineString2->addPoint(180, dfLatInt);
- }
- else
- {
- dfLatInt = dfLat1 + (dfLat2 - dfLat1) * (180 - dfLon1) / ((dfLon2 + 360) - dfLon1);
- lineString1->addPoint(180, dfLatInt);
- lineString2->addPoint(-180, dfLatInt);
- }
- lineString2->addPoint(dfLon2, dfLat2);
- multiLineString->addGeometryDirectly( lineString1 );
- multiLineString->addGeometryDirectly( lineString2 );
- poFeature->SetGeometryDirectly( multiLineString );
- }
- poFeature->SetField( nCount++, pszAirwaySegmentName );
- poFeature->SetField( nCount++, pszFirstPointName );
- poFeature->SetField( nCount++, pszSecondPointName );
- poFeature->SetField( nCount++, bIsHigh );
- poFeature->SetField( nCount++, nBaseFL );
- poFeature->SetField( nCount++, nTopFL );
- RegisterFeature(poFeature);
- return poFeature;
- }
- /************************************************************************/
- /* EqualAirwayIntersectionFeature */
- /************************************************************************/
- static int EqualAirwayIntersectionFeatureFunc(const void* _feature1, const void* _feature2)
- {
- OGRFeature* feature1 = (OGRFeature*)_feature1;
- OGRFeature* feature2 = (OGRFeature*)_feature2;
- if (strcmp(feature1->GetFieldAsString(0), feature2->GetFieldAsString(0)) == 0)
- {
- OGRPoint* point1 = (OGRPoint*) feature1->GetGeometryRef();
- OGRPoint* point2 = (OGRPoint*) feature2->GetGeometryRef();
- return (point1->getX() == point2->getX() && point1->getY() == point2->getY());
- }
- return FALSE;
- }
- /************************************************************************/
- /* OGRXPlaneAirwayHashDouble() */
- /************************************************************************/
- static unsigned long OGRXPlaneAirwayHashDouble(const double& dfVal)
- {
- /* To make a long story short, we must copy the double into */
- /* an array in order to respect C strict-aliasing rule */
- /* We can't directly cast into an unsigned int* */
- /* See #2521 for the longer version */
- unsigned int anValue[2];
- memcpy(anValue, &dfVal, sizeof(double));
- return anValue[0] ^ anValue[1];
- }
- /************************************************************************/
- /* HashAirwayIntersectionFeatureFunc */
- /************************************************************************/
- static unsigned long HashAirwayIntersectionFeatureFunc(const void* _feature)
- {
- OGRFeature* feature = (OGRFeature*)_feature;
- OGRPoint* point = (OGRPoint*) feature->GetGeometryRef();
- unsigned long hash = CPLHashSetHashStr((unsigned char*)feature->GetFieldAsString(0));
- const double x = point->getX();
- const double y = point->getY();
- return hash ^ OGRXPlaneAirwayHashDouble(x) ^ OGRXPlaneAirwayHashDouble(y);
- }
- /************************************************************************/
- /* FreeAirwayIntersectionFeatureFunc */
- /************************************************************************/
- static void FreeAirwayIntersectionFeatureFunc(void* _feature)
- {
- delete (OGRFeature*)_feature;
- }
- /************************************************************************/
- /* OGRXPlaneAirwayIntersectionLayer() */
- /************************************************************************/
- OGRXPlaneAirwayIntersectionLayer::OGRXPlaneAirwayIntersectionLayer() : OGRXPlaneLayer("AirwayIntersection")
- {
- poFeatureDefn->SetGeomType( wkbPoint );
- OGRFieldDefn oFieldName("name", OFTString );
- poFeatureDefn->AddFieldDefn( &oFieldName );
- poSet = CPLHashSetNew(HashAirwayIntersectionFeatureFunc,
- EqualAirwayIntersectionFeatureFunc,
- FreeAirwayIntersectionFeatureFunc);
- }
- /************************************************************************/
- /* ~OGRXPlaneAirwayIntersectionLayer() */
- /************************************************************************/
- OGRXPlaneAirwayIntersectionLayer::~OGRXPlaneAirwayIntersectionLayer()
- {
- CPLHashSetDestroy(poSet);
- }
- /************************************************************************/
- /* AddFeature() */
- /************************************************************************/
- OGRFeature*
- OGRXPlaneAirwayIntersectionLayer::AddFeature(const char* pszIntersectionName,
- double dfLat,
- double dfLon)
- {
- OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
- poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) );
- poFeature->SetField( 0, pszIntersectionName );
- if (CPLHashSetLookup(poSet, poFeature) == NULL)
- {
- CPLHashSetInsert(poSet, poFeature->Clone());
- RegisterFeature(poFeature);
- return poFeature;
- }
- else
- {
- delete poFeature;
- return NULL;
- }
- }
- /************************************************************************/
- /* ResetReading() */
- /************************************************************************/
- void OGRXPlaneAirwayIntersectionLayer::ResetReading()
- {
- if (poReader)
- {
- CPLHashSetDestroy(poSet);
- poSet = CPLHashSetNew(HashAirwayIntersectionFeatureFunc,
- EqualAirwayIntersectionFeatureFunc,
- FreeAirwayIntersectionFeatureFunc);
- }
- OGRXPlaneLayer::ResetReading();
- }