1
/******************************************************************************
2
* $Id: ogrsualayer.cpp 23066 2011-09-05 21:10:19Z rouault $
4
* Project: SUA Translator
5
* Purpose: Implements OGRSUALayer class.
6
* Author: Even Rouault, <even dot rouault at mines dash paris dot org>
8
******************************************************************************
9
* Copyright (c) 2010, Even Rouault <even dot rouault at mines dash paris dot org>
11
* Permission is hereby granted, free of charge, to any person obtaining a
12
* copy of this software and associated documentation files (the "Software"),
13
* to deal in the Software without restriction, including without limitation
14
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
15
* and/or sell copies of the Software, and to permit persons to whom the
16
* Software is furnished to do so, subject to the following conditions:
18
* The above copyright notice and this permission notice shall be included
19
* in all copies or substantial portions of the Software.
21
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27
* DEALINGS IN THE SOFTWARE.
28
****************************************************************************/
32
#include "cpl_string.h"
34
#include "ogr_xplane_geo_utils.h"
35
#include "ogr_srs_api.h"
37
CPL_CVSID("$Id: ogrsualayer.cpp 23066 2011-09-05 21:10:19Z rouault $");
39
/************************************************************************/
41
/************************************************************************/
43
OGRSUALayer::OGRSUALayer( VSILFILE* fp )
51
poSRS = new OGRSpatialReference(SRS_WKT_WGS84);
53
poFeatureDefn = new OGRFeatureDefn( "layer" );
54
poFeatureDefn->Reference();
55
poFeatureDefn->SetGeomType( wkbPolygon );
57
OGRFieldDefn oField1( "TYPE", OFTString);
58
poFeatureDefn->AddFieldDefn( &oField1 );
59
OGRFieldDefn oField2( "CLASS", OFTString);
60
poFeatureDefn->AddFieldDefn( &oField2 );
61
OGRFieldDefn oField3( "TITLE", OFTString);
62
poFeatureDefn->AddFieldDefn( &oField3 );
63
OGRFieldDefn oField4( "TOPS", OFTString);
64
poFeatureDefn->AddFieldDefn( &oField4 );
65
OGRFieldDefn oField5( "BASE", OFTString);
66
poFeatureDefn->AddFieldDefn( &oField5 );
69
/************************************************************************/
71
/************************************************************************/
73
OGRSUALayer::~OGRSUALayer()
79
poFeatureDefn->Release();
85
/************************************************************************/
87
/************************************************************************/
89
void OGRSUALayer::ResetReading()
95
VSIFSeekL( fpSUA, 0, SEEK_SET );
99
/************************************************************************/
100
/* GetNextFeature() */
101
/************************************************************************/
103
OGRFeature *OGRSUALayer::GetNextFeature()
105
OGRFeature *poFeature;
109
poFeature = GetNextRawFeature();
110
if (poFeature == NULL)
113
if((m_poFilterGeom == NULL
114
|| FilterGeometry( poFeature->GetGeometryRef() ) )
115
&& (m_poAttrQuery == NULL
116
|| m_poAttrQuery->Evaluate( poFeature )) )
127
/************************************************************************/
129
/************************************************************************/
131
static int GetLatLon(const char* pszStr, double& dfLat, double& dfLon)
133
if (pszStr[7] != ' ')
135
if (pszStr[0] != 'N' && pszStr[0] != 'S')
137
if (pszStr[8] != 'E' && pszStr[8] != 'W')
140
char szDeg[4], szMin[3], szSec[3];
141
szDeg[0] = pszStr[1];
142
szDeg[1] = pszStr[2];
144
szMin[0] = pszStr[3];
145
szMin[1] = pszStr[4];
147
szSec[0] = pszStr[5];
148
szSec[1] = pszStr[6];
151
dfLat = atoi(szDeg) + atoi(szMin) / 60. + atoi(szSec) / 3600.;
152
if (pszStr[0] == 'S')
155
szDeg[0] = pszStr[9];
156
szDeg[1] = pszStr[10];
157
szDeg[2] = pszStr[11];
159
szMin[0] = pszStr[12];
160
szMin[1] = pszStr[13];
162
szSec[0] = pszStr[14];
163
szSec[1] = pszStr[15];
166
dfLon = atoi(szDeg) + atoi(szMin) / 60. + atoi(szSec) / 3600.;
167
if (pszStr[8] == 'W')
173
/************************************************************************/
174
/* GetNextRawFeature() */
175
/************************************************************************/
177
OGRFeature *OGRSUALayer::GetNextRawFeature()
180
CPLString osTYPE, osCLASS, osTITLE, osTOPS, osBASE;
182
double dfLastLat = 0, dfLastLon = 0;
190
if (bFirst && bHasLastLine)
192
pszLine = osLastLine.c_str();
197
pszLine = CPLReadLine2L(fpSUA, 1024, NULL);
201
if (oLR.getNumPoints() == 0)
205
osLastLine = pszLine;
209
if (pszLine[0] == '#' || pszLine[0] == '\0')
212
if (EQUALN(pszLine, "TYPE=", 5))
214
if (osTYPE.size() != 0)
216
osTYPE = pszLine + 5;
218
else if (EQUALN(pszLine, "CLASS=", 6))
220
if (osCLASS.size() != 0)
222
osCLASS = pszLine + 6;
224
else if (EQUALN(pszLine, "TITLE=", 6))
226
if (osTITLE.size() != 0)
228
osTITLE = pszLine + 6;
230
else if (EQUALN(pszLine, "TOPS=", 5))
231
osTOPS = pszLine + 5;
232
else if (EQUALN(pszLine, "BASE=", 5))
233
osBASE = pszLine + 5;
234
else if (EQUALN(pszLine, "POINT=", 6))
237
if (strlen(pszLine) != 16)
241
if (!GetLatLon(pszLine, dfLat, dfLon))
244
oLR.addPoint(dfLon, dfLat);
248
else if (EQUALN(pszLine, "CLOCKWISE", 9) || EQUALN(pszLine, "ANTI-CLOCKWISE", 14))
250
if (oLR.getNumPoints() == 0)
253
int bClockWise = EQUALN(pszLine, "CLOCKWISE", 9);
255
/*const char* pszRADIUS = strstr(pszLine, "RADIUS=");
256
if (pszRADIUS == NULL)
258
double dfRADIUS = atof(pszRADIUS + 7) * 1852;*/
260
const char* pszCENTRE = strstr(pszLine, "CENTRE=");
261
if (pszCENTRE == NULL)
264
if (strlen(pszCENTRE) < 17 || pszCENTRE[16] != ' ')
266
double dfCenterLat, dfCenterLon;
267
if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon))
270
const char* pszTO = strstr(pszLine, "TO=");
274
if (strlen(pszTO) != 16)
276
double dfToLat, dfToLon;
277
if (!GetLatLon(pszTO, dfToLat, dfToLon))
280
double dfStartDistance = OGRXPlane_Distance(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon);
281
double dfEndDistance = OGRXPlane_Distance(dfCenterLat, dfCenterLon, dfToLat, dfToLon);
282
double dfStartAngle = OGRXPlane_Track(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon);
283
double dfEndAngle = OGRXPlane_Track(dfCenterLat, dfCenterLon, dfToLat, dfToLon);
284
if (bClockWise && dfEndAngle < dfStartAngle)
286
else if (!bClockWise && dfStartAngle < dfEndAngle)
289
int nSign = (bClockWise) ? 1 : -1;
291
for(dfAngle = dfStartAngle; (dfAngle - dfEndAngle) * nSign < 0; dfAngle += nSign)
294
double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle);
295
double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct;
296
OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon);
297
oLR.addPoint(dfLon, dfLat);
299
oLR.addPoint(dfToLon, dfToLat);
301
dfLastLat = oLR.getY(oLR.getNumPoints() - 1);
302
dfLastLon = oLR.getX(oLR.getNumPoints() - 1);
304
else if (EQUALN(pszLine, "CIRCLE", 6))
306
const char* pszRADIUS = strstr(pszLine, "RADIUS=");
307
if (pszRADIUS == NULL)
309
double dfRADIUS = atof(pszRADIUS + 7) * 1852;
311
const char* pszCENTRE = strstr(pszLine, "CENTRE=");
312
if (pszCENTRE == NULL)
315
if (strlen(pszCENTRE) != 16)
317
double dfCenterLat, dfCenterLon;
318
if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon))
323
for(dfAngle = 0; dfAngle < 360; dfAngle += 1)
325
OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, dfAngle, &dfLat, &dfLon);
326
oLR.addPoint(dfLon, dfLat);
328
OGRXPlane_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, 0, &dfLat, &dfLon);
329
oLR.addPoint(dfLon, dfLat);
331
dfLastLat = oLR.getY(oLR.getNumPoints() - 1);
332
dfLastLon = oLR.getX(oLR.getNumPoints() - 1);
334
else if (EQUALN(pszLine, "INCLUDE", 7) || EQUALN(pszLine, "END", 3))
339
CPLDebug("SUA", "Unexpected content : %s", pszLine);
343
OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
344
poFeature->SetField(0, osTYPE.c_str());
345
poFeature->SetField(1, osCLASS.c_str());
346
poFeature->SetField(2, osTITLE.c_str());
347
poFeature->SetField(3, osTOPS.c_str());
348
poFeature->SetField(4, osBASE.c_str());
350
OGRPolygon* poPoly = new OGRPolygon();
351
poPoly->assignSpatialReference(poSRS);
353
poPoly->addRing(&oLR);
354
poFeature->SetGeometryDirectly(poPoly);
355
poFeature->SetFID(nNextFID++);
359
/************************************************************************/
360
/* TestCapability() */
361
/************************************************************************/
363
int OGRSUALayer::TestCapability( const char * pszCap )