virtual void FillLogEvent(TEventContainer & details) const { double lat, lon; GetLatLon(lat, lon); details["lat"] = strings::to_string(lat); details["lon"] = strings::to_string(lon); }
OGRFeature *OGRAeronavFAANAVAIDLayer::GetNextRawFeature() { char szBuffer[134]; while( true ) { const char* pszLine = CPLReadLine2L(fpAeronavFAA, 134, nullptr); if (pszLine == nullptr) { bEOF = true; return nullptr; } if (strlen(pszLine) != 132) continue; if ( !(pszLine[psRecordDesc->nLatStartCol-1] == 'N' || pszLine[psRecordDesc->nLatStartCol-1] == 'S') ) continue; if ( !(pszLine[psRecordDesc->nLonStartCol-1] == 'E' || pszLine[psRecordDesc->nLonStartCol-1] == 'W') ) continue; OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetFID(nNextFID ++); for( int i=0; i < psRecordDesc->nFields; i++ ) { int nWidth = psRecordDesc->pasFields[i].nLastCol - psRecordDesc->pasFields[i].nStartCol + 1; strncpy(szBuffer, pszLine + psRecordDesc->pasFields[i].nStartCol - 1, nWidth); szBuffer[nWidth] = 0; while(nWidth > 0 && szBuffer[nWidth - 1] == ' ') { szBuffer[nWidth - 1] = 0; nWidth --; } if (nWidth != 0) poFeature->SetField(i, szBuffer); } double dfLat = 0.0; double dfLon = 0.0; GetLatLon(pszLine + psRecordDesc->nLatStartCol - 1, pszLine + psRecordDesc->nLonStartCol - 1, dfLat, dfLon); OGRGeometry* poGeom = new OGRPoint(dfLon, dfLat); poGeom->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly( poGeom ); return poFeature; } }
string Info::GetFormattedCoordinate(bool isDMS) const { auto const & ll = GetLatLon(); return isDMS ? measurement_utils::FormatLatLon(ll.lat, ll.lon) : measurement_utils::FormatLatLonAsDMS(ll.lat, ll.lon, 2); }
OGRFeature *OGRSUALayer::GetNextRawFeature() { if( bEOF ) return nullptr; CPLString osTYPE; CPLString osCLASS; CPLString osTITLE; CPLString osTOPS; CPLString osBASE; OGRLinearRing oLR; double dfLastLat = 0.0; double dfLastLon = 0.0; bool bFirst = true; while( true ) { const char* pszLine = nullptr; if( bFirst && bHasLastLine ) { pszLine = osLastLine.c_str(); bFirst = false; } else { pszLine = CPLReadLine2L(fpSUA, 1024, nullptr); if (pszLine == nullptr) { bEOF = true; if (oLR.getNumPoints() == 0) return nullptr; break; } osLastLine = pszLine; bHasLastLine = true; } if (pszLine[0] == '#' || pszLine[0] == '\0') continue; if (STARTS_WITH_CI(pszLine, "TYPE=")) { if (!osTYPE.empty()) break; osTYPE = pszLine + 5; } else if (STARTS_WITH_CI(pszLine, "CLASS=")) { if (!osCLASS.empty()) break; osCLASS = pszLine + 6; } else if (STARTS_WITH_CI(pszLine, "TITLE=")) { if (!osTITLE.empty()) break; osTITLE = pszLine + 6; } else if (STARTS_WITH_CI(pszLine, "TOPS=")) osTOPS = pszLine + 5; else if (STARTS_WITH_CI(pszLine, "BASE=")) osBASE = pszLine + 5; else if (STARTS_WITH_CI(pszLine, "POINT=")) { pszLine += 6; if (strlen(pszLine) != 16) continue; double dfLat = 0.0; double dfLon = 0.0; if (!GetLatLon(pszLine, dfLat, dfLon)) continue; oLR.addPoint(dfLon, dfLat); dfLastLat = dfLat; dfLastLon = dfLon; } else if (STARTS_WITH_CI(pszLine, "CLOCKWISE") || STARTS_WITH_CI(pszLine, "ANTI-CLOCKWISE")) { if (oLR.getNumPoints() == 0) continue; int bClockWise = STARTS_WITH_CI(pszLine, "CLOCKWISE"); /*const char* pszRADIUS = strstr(pszLine, "RADIUS="); if (pszRADIUS == NULL) continue; double dfRADIUS = CPLAtof(pszRADIUS + 7) * 1852;*/ const char* pszCENTRE = strstr(pszLine, "CENTRE="); if (pszCENTRE == nullptr) continue; pszCENTRE += 7; if (strlen(pszCENTRE) < 17 || pszCENTRE[16] != ' ') continue; double dfCenterLat = 0.0; double dfCenterLon = 0.0; if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon)) continue; const char* pszTO = strstr(pszLine, "TO="); if (pszTO == nullptr) continue; pszTO += 3; if (strlen(pszTO) != 16) continue; double dfToLat = 0.0; double dfToLon = 0.0; if (!GetLatLon(pszTO, dfToLat, dfToLon)) continue; const double dfStartDistance = OGR_GreatCircle_Distance(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon); const double dfEndDistance = OGR_GreatCircle_Distance(dfCenterLat, dfCenterLon, dfToLat, dfToLon); const double dfStartAngle = OGR_GreatCircle_InitialHeading(dfCenterLat, dfCenterLon, dfLastLat, dfLastLon); double dfEndAngle = OGR_GreatCircle_InitialHeading(dfCenterLat, dfCenterLon, dfToLat, dfToLon); if( bClockWise && dfEndAngle < dfStartAngle ) dfEndAngle += 360; else if (!bClockWise && dfStartAngle < dfEndAngle) dfEndAngle -= 360; int nSign = (bClockWise) ? 1 : -1; for( double dfAngle = dfStartAngle; (dfAngle - dfEndAngle) * nSign < 0; dfAngle += nSign ) { const double pct = (dfAngle - dfStartAngle) / (dfEndAngle - dfStartAngle); const double dfDist = dfStartDistance * (1-pct) + dfEndDistance * pct; double dfLat = 0.0; double dfLon = 0.0; OGR_GreatCircle_ExtendPosition(dfCenterLat, dfCenterLon, dfDist, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } oLR.addPoint(dfToLon, dfToLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } else if (STARTS_WITH_CI(pszLine, "CIRCLE")) { const char* pszRADIUS = strstr(pszLine, "RADIUS="); if (pszRADIUS == nullptr) continue; double dfRADIUS = CPLAtof(pszRADIUS + 7) * 1852; const char* pszCENTRE = strstr(pszLine, "CENTRE="); if (pszCENTRE == nullptr) continue; pszCENTRE += 7; if (strlen(pszCENTRE) != 16) continue; double dfCenterLat = 0.0; double dfCenterLon = 0.0; if (!GetLatLon(pszCENTRE, dfCenterLat, dfCenterLon)) continue; double dfLat = 0.0; double dfLon = 0.0; for( double dfAngle = 0; dfAngle < 360; dfAngle += 1 ) { OGR_GreatCircle_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, dfAngle, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); } OGR_GreatCircle_ExtendPosition(dfCenterLat, dfCenterLon, dfRADIUS, 0, &dfLat, &dfLon); oLR.addPoint(dfLon, dfLat); dfLastLat = oLR.getY(oLR.getNumPoints() - 1); dfLastLon = oLR.getX(oLR.getNumPoints() - 1); } else if (STARTS_WITH_CI(pszLine, "INCLUDE") || STARTS_WITH_CI(pszLine, "END")) { } else { CPLDebug("SUA", "Unexpected content : %s", pszLine); } } OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetField(0, osTYPE.c_str()); poFeature->SetField(1, osCLASS.c_str()); poFeature->SetField(2, osTITLE.c_str()); poFeature->SetField(3, osTOPS.c_str()); poFeature->SetField(4, osBASE.c_str()); OGRPolygon* poPoly = new OGRPolygon(); poPoly->assignSpatialReference(poSRS); oLR.closeRings(); poPoly->addRing(&oLR); poFeature->SetGeometryDirectly(poPoly); poFeature->SetFID(nNextFID++); return poFeature; }
//---------------------------------------------------------- // Aquire a GPS $GPGGA signal and fill in the waypoint data. // return 1 if valid, zero if not. // wait up to max_wait milliseconds to get a valid signal. bool waypoint::AcquireGPGGA(unsigned long max_wait_ms) { uint8_t satelites_used, hdop; REAL HDOP, error_m, error_mm; char FixIndicator = '0'; char *parseptr; // a character pointer for parsing // value of millis() for GPS data unsigned long AcquisitionTime_ms; char* pTime; unsigned long TimeOut = millis() + max_wait_ms; sigmaE_mm = 10000; sigmaN_mm = 10000; // $GPGGA,161229.487,3723.2475,N,12158.3416,W,1,07,1.0,9.0,M,,,,0000*18 while (FixIndicator == '0') { if (!readline(3)) { // nothing to read; how long have we waited? if (millis() > TimeOut) return false; } // Serial.println(buffer); if (strncmp(buffer, "$GPGGA",6) == 0) { // Serial.println(buffer); AcquisitionTime_ms = millis(); pTime = parseptr = buffer+7; parseptr = strchr(parseptr, ',') + 1; // grab latitude & long data parseptr = GetLatLon(parseptr); parseptr = strchr(parseptr, ',') + 1; FixIndicator = parseptr[0]; // A = data valid; V = data not valid if (FixIndicator == '0') continue; parseptr += 2; // satelites used parseptr = strchr(parseptr, ',')+1; satelites_used = parsedecimal(parseptr); // HDOP parseptr = strchr(parseptr, ',')+1; hdop = parsedecimal(parseptr); hdop *= 10; parseptr = strchr(parseptr, '.')+1; hdop += parsedecimal(parseptr); // http://users.erols.com/dlwilson/gpshdop.htm uses the model // error = sqrt( (3.04*HDOP)^2 + (3.57)^2) // see http://en.wikipedia.org/wiki/Error_analysis_for_the_Global_Positioning_System // get Horizontal Dillution of Precision (HDOP). HDOP = (REAL) hdop / 10.; error_m = sqrt((3.04*HDOP)*(3.04*HDOP) + 3.57*3.57); error_mm = 1000 * error_m; sigmaE_mm = sigmaN_mm = error_mm; if (offset_ms == 0) { SetTime(pTime, "1205xx"); offset_ms = AcquisitionTime_ms; } time_ms = AcquisitionTime_ms; } } if (FixIndicator == '0') return false; return true; }
//---------------------------------------------------------- // Aquire a GPS GPRMC signal and fill in the waypoint data. // return 1 if valid, zero if not. // wait up to max_wait milliseconds to get a valid signal. bool waypoint::AcquireGPRMC(unsigned long max_wait_ms) { uint8_t groundspeed, trackangle; char status ='V'; // V = data invalid char *parseptr; // a character pointer for parsing // value of millis() for GPS data unsigned long AcquisitionTime_ms; char* pTime; char* pDate; unsigned long TimeOut = millis() + max_wait_ms; // $GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13,309.62,120598,,*10 sigmaE_mm = 10000; sigmaN_mm = 10000; // Serial.println("looking"); CosLatitude = cos(((double) LATITUDE_ORIGIN)/1000000. * TO_RADIANS); while (status != 'A') // A = data valid { if (!readline(3)) { // nothing to read; how long have we waited? if (millis() > TimeOut) { Serial.println("Timed out"); return false; } } // Serial.println("Read line"); Serial.println(buffer); // check if $GPRMC (global positioning fixed data) if (strncmp(buffer, "$GPRMC",6) == 0) { AcquisitionTime_ms = millis(); // hhmmss time data pTime = parseptr = buffer+7; parseptr = strchr(parseptr, ',') + 1; status = parseptr[0]; // A = data valid; V = data not valid if (status != 'A') continue; parseptr += 2; // grab latitude & long data parseptr = GetLatLon(parseptr); // groundspeed parseptr = strchr(parseptr, ',')+1; // Serial.println(parseptr); groundspeed = parsedecimal(parseptr); // track angle parseptr = strchr(parseptr, ',')+1; trackangle = parsedecimal(parseptr); // date parseptr = strchr(parseptr, ',')+1; pDate = parseptr; /* Serial.print("\tGroundspeed: "); Serial.print(groundspeed, DEC); Serial.print(","); Serial.print("\tHeading: "); Serial.print(trackangle, DEC); Serial.print(","); Serial.print("\tDate: "); Serial.println(pDate); */ if (offset_ms == 0) { SetTime(pTime, pDate); offset_ms = AcquisitionTime_ms; } time_ms = AcquisitionTime_ms; } } if (status == 'A') return true; return false; }
OGRFeature *OGRAeronavFAAIAPLayer::GetNextRawFeature() { char szBuffer[87]; int nCountUnderscoreLines = 0; while( true ) { const char* pszLine = CPLReadLine2L(fpAeronavFAA, 87, nullptr); if (pszLine == nullptr) { bEOF = true; return nullptr; } if (strlen(pszLine) != 85) continue; if (STARTS_WITH(pszLine, "DELETIONS")) { bEOF = true; return nullptr; } if (nNextFID == 0 && nCountUnderscoreLines < 2) { if (strcmp(pszLine, "_____________________________________________________________________________ 285285") == 0) nCountUnderscoreLines ++; continue; } if (pszLine[1] != ' ') continue; if (STARTS_WITH(pszLine, " ")) continue; if (strstr(pszLine, "NAVIGATIONAL AIDS") != nullptr) continue; if (strstr(pszLine, "TERMINAL INSTRUMENT FIXES") != nullptr) continue; const char* pszComma = strchr(pszLine, ','); if (pszComma) { const char* pszBegin = pszLine; while( *pszBegin == ' ') pszBegin ++; osCityName = pszBegin; osCityName.resize(pszComma - pszBegin); osStateName = pszComma + 2; osStateName.resize(78 - (pszComma + 2 - pszLine)); while(!osStateName.empty() && osStateName.back() == ' ') { osStateName.resize(osStateName.size()-1); } osAPTName = ""; osAPTId = ""; continue; } const char* pszLeftParenthesis = strstr(pszLine, " ("); if (pszLeftParenthesis) { const char* pszRightParenthesis = strchr(pszLeftParenthesis, ')'); if (pszRightParenthesis) { const char* pszBegin = pszLine; while( *pszBegin == ' ') pszBegin ++; osAPTName = pszBegin; osAPTName.resize(pszLeftParenthesis - pszBegin); osAPTId = pszLeftParenthesis + 2; osAPTId.resize(pszRightParenthesis - (pszLeftParenthesis + 2)); } continue; } OGRFeature* poFeature = new OGRFeature(poFeatureDefn); poFeature->SetFID(nNextFID ++); poFeature->SetField(0, osCityName); poFeature->SetField(1, osStateName); poFeature->SetField(2, osAPTName); poFeature->SetField(3, osAPTId); for( int i=0; i<psRecordDesc->nFields; i++) { int nWidth = psRecordDesc->pasFields[i].nLastCol - psRecordDesc->pasFields[i].nStartCol + 1; strncpy(szBuffer, pszLine + psRecordDesc->pasFields[i].nStartCol - 1, nWidth); szBuffer[nWidth] = 0; while(nWidth > 0 && szBuffer[nWidth - 1] == ' ') { szBuffer[nWidth - 1] = 0; nWidth --; } if (nWidth != 0) poFeature->SetField(i + 4, szBuffer); } double dfLat = 0.0; double dfLon = 0.0; GetLatLon(pszLine + 16 - 1, (pszLine[34 - 1] != ' ') ? pszLine + 34 - 1 : pszLine + 35 - 1, dfLat, dfLon); OGRGeometry* poGeom = new OGRPoint(dfLon, dfLat); poGeom->assignSpatialReference(poSRS); poFeature->SetGeometryDirectly( poGeom ); return poFeature; } }
OGRFeature *OGRAeronavFAARouteLayer::GetNextRawFeature() { OGRFeature* poFeature = nullptr; OGRLineString* poLS = nullptr; while( true ) { const char* pszLine = nullptr; if (!osLastReadLine.empty()) pszLine = osLastReadLine.c_str(); else pszLine = CPLReadLine2L(fpAeronavFAA, 87, nullptr); osLastReadLine = ""; if (pszLine == nullptr) { bEOF = true; break; } if (strlen(pszLine) != 85) continue; if (bIsDPOrSTARS && STARTS_WITH(pszLine, "===") && pszLine[3] != '=') { osAPTName = pszLine + 3; const char* pszComma = strchr(pszLine + 3, ','); if (pszComma) { osAPTName.resize(pszComma - (pszLine + 3)); osStateName = pszComma + 2; const char* pszEqual = strchr(pszComma + 2, '='); if (pszEqual) osStateName.resize(pszEqual - (pszComma + 2)); } else { const char* pszEqual = strchr(pszLine + 3, '='); if (pszEqual) osAPTName.resize(pszEqual - (pszLine + 3)); osStateName = ""; } } if (STARTS_WITH(pszLine + 2, "FACILITY OR")) continue; if (STARTS_WITH(pszLine + 2, "INTERSECTION")) continue; if (strcmp(pszLine, "================================DELETIONS LIST=================================198326") == 0) { bEOF = true; break; } if (poFeature == nullptr) { if (pszLine[2] == ' ' || pszLine[2] == '-' ) { continue; } if (STARTS_WITH(pszLine + 29, " ") || strchr(pszLine, '(') != nullptr) { CPLString osName = pszLine + 2; osName.resize(60); while(!osName.empty() && osName.back() == ' ') { osName.resize(osName.size()-1); } if (strcmp(osName.c_str(), "(DELETIONS LIST)") == 0) { bEOF = true; return nullptr; } poFeature = new OGRFeature(poFeatureDefn); poFeature->SetFID(nNextFID ++); if (bIsDPOrSTARS) { poFeature->SetField(0, osAPTName); poFeature->SetField(1, osStateName); poFeature->SetField(2, osName); } else poFeature->SetField(0, osName); poLS = new OGRLineString(); } continue; } if (STARTS_WITH(pszLine, " 0")) { if (poLS->getNumPoints() == 0) continue; else break; } if (pszLine[29 - 1] == ' ' && pszLine[42 - 1] == ' ') continue; if (strstr(pszLine, "RWY") || strchr(pszLine, '(')) { osLastReadLine = pszLine; break; } double dfLat = 0.0; double dfLon = 0.0; GetLatLon(pszLine + 29 - 1, pszLine + 42 - 1, dfLat, dfLon); poLS->addPoint(dfLon, dfLat); } if( poFeature != nullptr ) poFeature->SetGeometryDirectly(poLS); return poFeature; }