diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 578e8f8a5..fd578d714 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: Build DLL on: pull_request: - branches: [main] + branches: [main,master,dev,develop] release: types: [published] diff --git a/vSMR/Constant.hpp b/vSMR/Constant.hpp index 2bfc7ed80..a9cda5784 100644 --- a/vSMR/Constant.hpp +++ b/vSMR/Constant.hpp @@ -311,6 +311,10 @@ const int RIMCAS_UPDATE_APP_TRAIL = 8032; const int RIMCAS_UPDATE_PTL = 8033; const int RIMCAS_UPDATE_RELEASE = 8034; const int RIMCAS_UPDATE_ACQUIRE = 8035; +const int RIMCAS_TOGGLE_AIRCRAFT_TYPE = 8036; +const int RIMCAS_TOGGLE_SID = 8037; +const int RIMCAS_TOGGLE_WAKE_TURB = 8038; +const int RIMCAS_UPDATE_DETAILED = 8039; const int RIMCAS_IAW = 7000; diff --git a/vSMR/InsetWindow.cpp b/vSMR/InsetWindow.cpp index 002f78790..0a22c79af 100644 --- a/vSMR/InsetWindow.cpp +++ b/vSMR/InsetWindow.cpp @@ -396,7 +396,7 @@ void CInsetWindow::render(HDC hDC, CSMRRadar * radar_screen, Graphics* gdi, POIN // Drawing the tags, what a mess // ----- Generating the replacing map ----- - map TagReplacingMap = CSMRRadar::GenerateTagData(rt, fp, radar_screen->IsCorrelated(fp, rt), radar_screen->CurrentConfig->getActiveProfile()["filters"]["pro_mode"]["enable"].GetBool(), radar_screen->GetPlugIn()->GetTransitionAltitude(), radar_screen->CurrentConfig->getActiveProfile()["labels"]["use_aspeed_for_gate"].GetBool(), icao); + map TagReplacingMap = CSMRRadar::GenerateTagData(rt, fp, radar_screen->IsCorrelated(fp, rt), radar_screen->CurrentConfig->getActiveProfile()["filters"]["pro_mode"]["enable"].GetBool(), radar_screen->GetPlugIn()->GetTransitionAltitude(), radar_screen->CurrentConfig->getActiveProfile()["labels"]["use_aspeed_for_gate"].GetBool(), icao, radar_screen->showAircraftType, radar_screen->showSID, radar_screen->showWakeTurb); // ----- Generating the clickable map ----- map TagClickableMap; @@ -688,7 +688,7 @@ void CInsetWindow::render(HDC hDC, CSMRRadar * radar_screen, Graphics* gdi, POIN bearings = bearings.substr(0, decimal_pos + 2); string text = bearings; - text += "° / "; + text += "� / "; text += distances; text += "nm"; COLORREF old_color = dc.SetTextColor(RGB(0, 0, 0)); diff --git a/vSMR/Rimcas.cpp b/vSMR/Rimcas.cpp index 7ff84eff1..a7725555e 100644 --- a/vSMR/Rimcas.cpp +++ b/vSMR/Rimcas.cpp @@ -30,10 +30,10 @@ void CRimcas::OnRefreshBegin(bool isLVP) { this->IsLVP = isLVP; } -void CRimcas::OnRefresh(CRadarTarget Rt, CRadarScreen *instance, bool isCorrelated) { +void CRimcas::OnRefresh(CRadarTarget Rt, CRadarScreen *instance, bool isCorrelated, string acType, string acStand) { Logger::info(string(__FUNCSIG__)); GetAcInRunwayArea(Rt, instance); - GetAcInRunwayAreaSoon(Rt, instance, isCorrelated); + GetAcInRunwayAreaSoon(Rt, instance, isCorrelated, acType, acStand); } void CRimcas::AddRunwayArea(CRadarScreen *instance, string runway_name1, string runway_name2, vector Definition) { @@ -79,7 +79,7 @@ string CRimcas::GetAcInRunwayArea(CRadarTarget Ac, CRadarScreen *instance) { return string_false; } -string CRimcas::GetAcInRunwayAreaSoon(CRadarTarget Ac, CRadarScreen *instance, bool isCorrelated) { +string CRimcas::GetAcInRunwayAreaSoon(CRadarTarget Ac, CRadarScreen *instance, bool isCorrelated, string acType, string acStand) { Logger::info(string(__FUNCSIG__)); int AltitudeDif = Ac.GetPosition().GetFlightLevel() - Ac.GetPreviousPosition(Ac.GetPosition()).GetFlightLevel(); if (!Ac.GetPosition().GetTransponderC()) @@ -164,7 +164,11 @@ string CRimcas::GetAcInRunwayAreaSoon(CRadarTarget Ac, CRadarScreen *instance, b } if (t < PreviousTime && t >= Time) { - TimeTable[it->first][Time] = Ac.GetCallsign(); + AircraftInfo info; + info.callsign = Ac.GetCallsign(); + info.type = acType; + info.stand = acStand; + TimeTable[it->first][Time] = info; break; } } diff --git a/vSMR/Rimcas.hpp b/vSMR/Rimcas.hpp index 2bbb2568c..b9e852490 100644 --- a/vSMR/Rimcas.hpp +++ b/vSMR/Rimcas.hpp @@ -34,12 +34,18 @@ class CRimcas { enum RimcasAlertTypes { NoAlert, StageOne, StageTwo }; + struct AircraftInfo { + string callsign = ""; + string type = ""; + string stand = ""; + }; + map RunwayAreas; multimap AcOnRunway; vector CountdownDefinition; vector CountdownDefinitionLVP; multimap ApproachingAircrafts; - map> TimeTable; + map> TimeTable; map MonitoredRunwayDep; map MonitoredRunwayArr; map AcColor; @@ -104,7 +110,7 @@ class CRimcas { } string GetAcInRunwayArea(CRadarTarget Ac, CRadarScreen *instance); - string GetAcInRunwayAreaSoon(CRadarTarget Ac, CRadarScreen *instance, bool isCorrelated); + string GetAcInRunwayAreaSoon(CRadarTarget Ac, CRadarScreen *instance, bool isCorrelated, string acType = "", string acStand = ""); void AddRunwayArea(CRadarScreen *instance, string runway_name1, string runway_name2, vector Definition); Color GetAircraftColor(string AcCallsign, Color StandardColor, Color OnRunwayColor, Color RimcasStageOne, Color RimcasStageTwo); Color GetAircraftColor(string AcCallsign, Color StandardColor, Color OnRunwayColor); @@ -114,7 +120,7 @@ class CRimcas { vector GetRunwayArea(CPosition Left, CPosition Right, float hwidth = 92.5f); void OnRefreshBegin(bool isLVP); - void OnRefresh(CRadarTarget Rt, CRadarScreen *instance, bool isCorrelated); + void OnRefresh(CRadarTarget Rt, CRadarScreen *instance, bool isCorrelated, string acType = "", string acStand = ""); void OnRefreshEnd(CRadarScreen *instance, int threshold); void Reset(); diff --git a/vSMR/SMRPlugin.cpp b/vSMR/SMRPlugin.cpp index ca90d6de2..e8d27da47 100644 --- a/vSMR/SMRPlugin.cpp +++ b/vSMR/SMRPlugin.cpp @@ -54,6 +54,7 @@ string ttype; int messageId = 0; clock_t timer; +int pollInterval = 45 + rand() % 31; // Random interval between 45-75 seconds string myfrequency; @@ -66,6 +67,18 @@ char recv_buf[1024]; vector RadarScreensOpened; +static void formatNowTimeDate(string & timeStr, string &dateStr) +{ + time_t now = time(NULL); + tm tmnow; + gmtime_s(&tmnow, &now); // use UTC + char buf[64]; + strftime(buf, sizeof(buf), "%H%MZ", &tmnow); + timeStr = buf; + strftime(buf, sizeof(buf), "%d%m%y", &tmnow); + dateStr = buf; +} + void createPlainCpdlcMessage(const char *message, const char *responses) { ttype = "CPDLC"; tmessage = "/data2/"; @@ -177,11 +190,28 @@ void pollMessages(void * arg) { PlaySound(MAKEINTRESOURCE(IDR_WAVE1), AfxGetInstanceHandle(), SND_RESOURCE | SND_ASYNC); } AircraftDemandingClearance.push_back(message.from); + string timeS, dateS; + formatNowTimeDate(timeS, dateS); + // Send ack + string reqAck = "DEPART MESSAGE REQUEST RECEIVED "; + reqAck += timeS + " " + dateS; + reqAck += " REQUEST BEING PROCESSED"; + createPlainCpdlcMessage(reqAck.c_str(), "NE"); + tdest = message.from; + _beginthread(sendDatalinkMessage, 0, NULL); } } else if (message.message.find("WILCO") != std::string::npos || message.message.find("ROGER") != std::string::npos || message.message.find("RGR") != std::string::npos || message.message.find("ACCEPT") != std::string::npos) { if (std::find(AircraftMessageSent.begin(), AircraftMessageSent.end(), message.from) != AircraftMessageSent.end()) { AircraftWilco.push_back(message.from); + string timeS, dateS; + formatNowTimeDate(timeS, dateS); + // send ack + string clearanceAck = "DEPART MESSAGE ACK RECEIVED "; + clearanceAck += timeS + " " + dateS; + clearanceAck += " CLEARANCE CONFIRMED"; + createPlainCpdlcMessage(clearanceAck.c_str(), "NE"); + _beginthread(sendDatalinkMessage, 0, NULL); } } else if (message.message.length() != 0 ){ @@ -634,9 +664,10 @@ void CSMRPlugin::OnTimer(int Counter) HoppieConnected = false; } - if (((clock() - timer) / CLOCKS_PER_SEC) > 10 && HoppieConnected) { + if (((clock() - timer) / CLOCKS_PER_SEC) > pollInterval && HoppieConnected) { _beginthread(pollMessages, 0, NULL); timer = clock(); + pollInterval = 45 + rand() % 31; // Next random interval between 45-75 seconds } for (auto &ac : AircraftWilco) diff --git a/vSMR/SMRRadar.cpp b/vSMR/SMRRadar.cpp index dfbf93480..a015a3235 100644 --- a/vSMR/SMRRadar.cpp +++ b/vSMR/SMRRadar.cpp @@ -283,6 +283,15 @@ void CSMRRadar::OnAsrContentLoaded(bool Loaded) if ((p_value = GetDataFromAsr("WIPareas")) != NULL) wipAreasActive = atoi(p_value); + if ((p_value = GetDataFromAsr("ShowAircraftType")) != NULL) + showAircraftType = atoi(p_value) == 1 ? true : false; + + if ((p_value = GetDataFromAsr("ShowSID")) != NULL) + showSID = atoi(p_value) == 1 ? true : false; + + if ((p_value = GetDataFromAsr("ShowWakeTurb")) != NULL) + showWakeTurb = atoi(p_value) == 1 ? true : false; + string temp; for (int i = 1; i < 3; i++) @@ -362,6 +371,12 @@ void CSMRRadar::OnAsrContentToBeSaved() SaveDataToAsr("WIPareas", "vSMR WIP Areas", std::to_string(wipAreasActive).c_str()); + SaveDataToAsr("ShowAircraftType", "Show Aircraft Type", std::to_string(showAircraftType).c_str()); + + SaveDataToAsr("ShowSID", "Show SID", std::to_string(showSID).c_str()); + + SaveDataToAsr("ShowWakeTurb", "Show Wake Turbulence", std::to_string(showWakeTurb).c_str()); + string temp = ""; for (int i = 1; i < 3; i++) @@ -662,6 +677,9 @@ void CSMRRadar::OnClickScreenObject(int ObjectType, const char * sObjectId, POIN GetPlugIn()->AddPopupListElement("SRW 1", "", APPWINDOW_ONE, false, int(appWindowDisplays[1])); GetPlugIn()->AddPopupListElement("SRW 2", "", APPWINDOW_TWO, false, int(appWindowDisplays[2])); GetPlugIn()->AddPopupListElement("WIP Areas", "", WIP_AREAS, false, int(wipAreasActive)); + GetPlugIn()->AddPopupListElement("Show Aircraft Type", "", RIMCAS_TOGGLE_AIRCRAFT_TYPE, false, int(showAircraftType)); + GetPlugIn()->AddPopupListElement("Show SID", "", RIMCAS_TOGGLE_SID, false, int(showSID)); + GetPlugIn()->AddPopupListElement("Show Wake Catagory", "", RIMCAS_TOGGLE_WAKE_TURB, false, int(showWakeTurb)); GetPlugIn()->AddPopupListElement("Profiles", "", RIMCAS_OPEN_LIST); GetPlugIn()->AddPopupListElement("Close", "", RIMCAS_CLOSE, false, 2, false, true); } @@ -710,6 +728,7 @@ void CSMRRadar::OnClickScreenObject(int ObjectType, const char * sObjectId, POIN GetPlugIn()->AddPopupListElement("Conflict Alert DEP", "", RIMCAS_OPEN_LIST); GetPlugIn()->AddPopupListElement("Runway closed", "", RIMCAS_OPEN_LIST); GetPlugIn()->AddPopupListElement("Visibility", "", RIMCAS_OPEN_LIST); + GetPlugIn()->AddPopupListElement("RIMCAS Detail", "", RIMCAS_OPEN_LIST); GetPlugIn()->AddPopupListElement("Close", "", RIMCAS_CLOSE, false, 2, false, true); } @@ -1040,6 +1059,21 @@ void CSMRRadar::OnFunctionCall(int FunctionId, const char * sItemString, POINT P RequestRefresh(); } + if (FunctionId == RIMCAS_TOGGLE_AIRCRAFT_TYPE) { + showAircraftType = !showAircraftType; + SaveDataToAsr("ShowAircraftType", "Show Aircraft Type", std::to_string(showAircraftType).c_str()); + } + + if (FunctionId == RIMCAS_TOGGLE_SID) { + showSID = !showSID; + SaveDataToAsr("ShowSID", "Show SID", std::to_string(showSID).c_str()); + } + + if (FunctionId == RIMCAS_TOGGLE_WAKE_TURB) { + showWakeTurb = !showWakeTurb; + SaveDataToAsr("ShowWakeTurb", "Show Wake Turbulence", std::to_string(showWakeTurb).c_str()); + } + if (FunctionId == RIMCAS_UPDATE_LVP) { if (strcmp(sItemString, "Normal") == 0) isLVP = false; @@ -1047,6 +1081,15 @@ void CSMRRadar::OnFunctionCall(int FunctionId, const char * sItemString, POINT P isLVP = true; ShowLists["Visibility"] = true; + } + + if (FunctionId == RIMCAS_UPDATE_DETAILED) { + if (strcmp(sItemString, "Detailed") == 0) + detailedRIMCAS = true; + if (strcmp(sItemString, "Simple") == 0) + detailedRIMCAS = false; + + ShowLists["RIMCAS Detail"] = true; RequestRefresh(); } @@ -1369,7 +1412,7 @@ bool CSMRRadar::OnCompileCommand(const char * sCommandLine) return false; } -map CSMRRadar::GenerateTagData(CRadarTarget rt, CFlightPlan fp, bool isAcCorrelated, bool isProMode, int TransitionAltitude, bool useSpeedForGates, string ActiveAirport) +map CSMRRadar::GenerateTagData(CRadarTarget rt, CFlightPlan fp, bool isAcCorrelated, bool isProMode, int TransitionAltitude, bool useSpeedForGates, string ActiveAirport, bool showAircraftType, bool showSID, bool showWakeTurb) { Logger::info(string(__FUNCSIG__)); // ---- @@ -1623,8 +1666,8 @@ map CSMRRadar::GenerateTagData(CRadarTarget rt, CFlightPlan fp, } TagReplacingMap["callsign"] = callsign; - TagReplacingMap["actype"] = actype; - TagReplacingMap["sctype"] = sctype; + TagReplacingMap["actype"] = showAircraftType ? actype : ""; + TagReplacingMap["sctype"] = showAircraftType ? sctype : ""; TagReplacingMap["sqerror"] = sqerror; TagReplacingMap["deprwy"] = deprwy; TagReplacingMap["seprwy"] = seprwy; @@ -1635,10 +1678,10 @@ map CSMRRadar::GenerateTagData(CRadarTarget rt, CFlightPlan fp, TagReplacingMap["flightlevel"] = flightlevel; TagReplacingMap["gs"] = speed; TagReplacingMap["tendency"] = tendency; - TagReplacingMap["wake"] = wake; + TagReplacingMap["wake"] = showWakeTurb ? wake : ""; TagReplacingMap["ssr"] = tssr; - TagReplacingMap["asid"] = dep; - TagReplacingMap["ssid"] = ssid; + TagReplacingMap["asid"] = showSID ? dep : ""; + TagReplacingMap["ssid"] = showSID ? ssid : ""; TagReplacingMap["origin"] = origin; TagReplacingMap["dest"] = dest; TagReplacingMap["groundstatus"] = gstat; @@ -1964,7 +2007,18 @@ void CSMRRadar::OnRefresh(HDC hDC, int Phase) if (!isAcDisplayed) continue; - RimcasInstance->OnRefresh(rt, this, IsCorrelated(GetPlugIn()->FlightPlanSelect(rt.GetCallsign()), rt)); + // Get aircraft type and stand for RIMCAS + CFlightPlan fp = GetPlugIn()->FlightPlanSelect(rt.GetCallsign()); + string acType = ""; + string acStand = ""; + if (fp.IsValid() && fp.GetFlightPlanData().IsReceived()) { + acType = fp.GetFlightPlanData().GetAircraftFPType(); + acStand = fp.GetControllerAssignedData().GetFlightStripAnnotation(3); + if (acStand.length() == 0) + acStand = ""; + } + + RimcasInstance->OnRefresh(rt, this, IsCorrelated(fp, rt), acType, acStand); CRadarTargetPositionData RtPos = rt.GetPosition(); @@ -2245,7 +2299,7 @@ void CSMRRadar::OnRefresh(HDC hDC, int Phase) ColorTagType = TagTypes::Uncorrelated; } - map TagReplacingMap = GenerateTagData(rt, fp, IsCorrelated(fp, rt), CurrentConfig->getActiveProfile()["filters"]["pro_mode"]["enable"].GetBool(), GetPlugIn()->GetTransitionAltitude(), CurrentConfig->getActiveProfile()["labels"]["use_aspeed_for_gate"].GetBool(), getActiveAirport()); + map TagReplacingMap = GenerateTagData(rt, fp, IsCorrelated(fp, rt), CurrentConfig->getActiveProfile()["filters"]["pro_mode"]["enable"].GetBool(), GetPlugIn()->GetTransitionAltitude(), CurrentConfig->getActiveProfile()["labels"]["use_aspeed_for_gate"].GetBool(), getActiveAirport(), showAircraftType, showSID, showWakeTurb); // ----- Generating the clickable map ----- map TagClickableMap; @@ -2290,6 +2344,7 @@ void CSMRRadar::OnRefresh(HDC hDC, int Phase) const Value& LabelsSettings = CurrentConfig->getActiveProfile()["labels"]; const Value& LabelLines = LabelsSettings[Utils::getEnumString(TagType).c_str()]["definition"]; vector> ReplacedLabelLines; + vector LineWidths; // Store width of each line if (!LabelLines.IsArray()) return; @@ -2300,10 +2355,8 @@ void CSMRRadar::OnRefresh(HDC hDC, int Phase) const Value& line = LabelLines[i]; vector lineStringArray; - // Adds one line height - TagHeight += oneLineHeight; - int TempTagWidth = 0; + bool lineHasContent = false; for(unsigned int j = 0; j < line.Size(); j++) { @@ -2315,21 +2368,46 @@ void CSMRRadar::OnRefresh(HDC hDC, int Phase) lineStringArray.push_back(element); + // Check if this element has actual content + if (!element.empty()) { + lineHasContent = true; + } + wstring wstr = wstring(element.begin(), element.end()); graphics.MeasureString(wstr.c_str(), wcslen(wstr.c_str()), customFonts[currentFontSize], PointF(0, 0), &Gdiplus::StringFormat(), &mesureRect); TempTagWidth += (int) mesureRect.GetRight(); - if (j != line.Size() - 1) - TempTagWidth += (int) blankWidth; + // Only add blank space if this element is not empty AND there's a next element that's not empty + if (!element.empty() && j != line.Size() - 1) { + // Check if any subsequent element has content + bool hasNextContent = false; + for (unsigned int k = j + 1; k < line.Size(); k++) { + string nextElement = line[k].GetString(); + for (auto& kv : TagReplacingMap) + replaceAll(nextElement, kv.first, kv.second); + if (!nextElement.empty()) { + hasNextContent = true; + break; + } + } + if (hasNextContent) { + TempTagWidth += (int) blankWidth; + } + } } + // Only add height for lines that have actual content + if (lineHasContent) { + TagHeight += oneLineHeight; + } + + LineWidths.push_back(TempTagWidth); // Store actual line width TagWidth = max(TagWidth, TempTagWidth); ReplacedLabelLines.push_back(lineStringArray); } - TagHeight = TagHeight - 2; Color definedBackgroundColor = CurrentConfig->getConfigColor(LabelsSettings[Utils::getEnumString(ColorTagType).c_str()]["background_color"]); @@ -2435,9 +2513,28 @@ void CSMRRadar::OnRefresh(HDC hDC, int Phase) // Clickable zones int heightOffset = 0; + int lineIndex = 0; for (auto&& line : ReplacedLabelLines) { + // Check if line has any content + bool lineHasContent = false; + for (auto&& element : line) { + if (!element.empty()) { + lineHasContent = true; + break; + } + } + + // Skip empty lines + if (!lineHasContent) { + lineIndex++; + continue; + } + + // Left-align all text int widthOffset = 0; + int elementIndex = 0; + for (auto&& element : line) { SolidBrush* color = &FontColor; @@ -2473,10 +2570,25 @@ void CSMRRadar::OnRefresh(HDC hDC, int Phase) AddScreenObject(TagClickableMap[element], rt.GetCallsign(), ItemRect, true, GetBottomLine(rt.GetCallsign()).c_str()); widthOffset += (int)mRect.GetRight(); - widthOffset += blankWidth; + + // Only add blank space if this element is not empty AND there's a next element with content + if (!element.empty() && elementIndex < line.size() - 1) { + bool hasNextContent = false; + for (size_t k = elementIndex + 1; k < line.size(); k++) { + if (!line[k].empty()) { + hasNextContent = true; + break; + } + } + if (hasNextContent) { + widthOffset += blankWidth; + } + } + elementIndex++; } heightOffset += oneLineHeight; + lineIndex++; } @@ -2491,6 +2603,7 @@ void CSMRRadar::OnRefresh(HDC hDC, int Phase) COLORREF oldColor = dc.SetTextColor(RGB(33, 33, 33)); int TextHeight = dc.GetTextExtent("60").cy; + int LineSpacing = TextHeight + 3; // Add 3 pixels between lines Logger::info("RIMCAS Loop"); for (std::map::iterator it = RimcasInstance->MonitoredRunwayArr.begin(); it != RimcasInstance->MonitoredRunwayArr.end(); ++it) { @@ -2501,8 +2614,44 @@ void CSMRRadar::OnRefresh(HDC hDC, int Phase) if (isLVP) TimeDefinition = RimcasInstance->CountdownDefinitionLVP; + // Calculate box dimensions based on content + int maxWidth = 0; + char buffer[256]; + for (auto &Time : TimeDefinition) + { + if (RimcasInstance->TimeTable[it->first].find(Time) != RimcasInstance->TimeTable[it->first].end()) + { + auto acInfo = RimcasInstance->TimeTable[it->first][Time]; + if (detailedRIMCAS) + { + sprintf_s(buffer, "%2d: %-10s %-8s %s", + Time, + acInfo.callsign.c_str(), + acInfo.type.empty() ? "" : acInfo.type.c_str(), + acInfo.stand.empty() ? "" : acInfo.stand.c_str()); + } + else + { + sprintf_s(buffer, "%2d: %s", Time, acInfo.callsign.c_str()); + } + } + else + { + sprintf_s(buffer, "%2d: ", Time); + } + int textWidth = dc.GetTextExtent(buffer).cx; + if (textWidth > maxWidth) + maxWidth = textWidth; + } + + int boxPadding = detailedRIMCAS ? 15 : 10; // Smaller padding for simple mode + int boxWidth = maxWidth + boxPadding; + int boxHeight = LineSpacing * (TimeDefinition.size() + 1) + 5; // +1 for runway name, +5px total padding + if (TimePopupAreas.find(it->first) == TimePopupAreas.end()) - TimePopupAreas[it->first] = { 300, 300, 430, 300+LONG(TextHeight*(TimeDefinition.size()+1)) }; + TimePopupAreas[it->first] = { 300, 300, 300 + boxWidth, 300 + boxHeight }; + else + TimePopupAreas[it->first] = { TimePopupAreas[it->first].left, TimePopupAreas[it->first].top, TimePopupAreas[it->first].left + boxWidth, TimePopupAreas[it->first].top + boxHeight }; CRect CRectTime = TimePopupAreas[it->first]; CRectTime.NormalizeRect(); @@ -2511,34 +2660,60 @@ void CSMRRadar::OnRefresh(HDC hDC, int Phase) // Drawing the runway name string tempS = it->first; - dc.TextOutA(CRectTime.left + CRectTime.Width() / 2 - dc.GetTextExtent(tempS.c_str()).cx / 2, CRectTime.top, tempS.c_str()); + dc.TextOutA(CRectTime.left + CRectTime.Width() / 2 - dc.GetTextExtent(tempS.c_str()).cx / 2, CRectTime.top + 2, tempS.c_str()); - int TopOffset = TextHeight; + int TopOffset = LineSpacing; // Drawing the times for (auto &Time : TimeDefinition) { dc.SetTextColor(RGB(33, 33, 33)); - tempS = std::to_string(Time) + ": " + RimcasInstance->TimeTable[it->first][Time]; - if (RimcasInstance->AcColor.find(RimcasInstance->TimeTable[it->first][Time]) != RimcasInstance->AcColor.end()) + // Get aircraft info from TimeTable + if (RimcasInstance->TimeTable[it->first].find(Time) != RimcasInstance->TimeTable[it->first].end()) { - CBrush RimcasBrush(RimcasInstance->GetAircraftColor(RimcasInstance->TimeTable[it->first][Time], - Color::Black, - Color::Black, - CurrentConfig->getConfigColor(CurrentConfig->getActiveProfile()["rimcas"]["background_color_stage_one"]), - CurrentConfig->getConfigColor(CurrentConfig->getActiveProfile()["rimcas"]["background_color_stage_two"])).ToCOLORREF() - ); - - CRect TempRect = { CRectTime.left, CRectTime.top + TopOffset, CRectTime.right, CRectTime.top + TopOffset + TextHeight }; - TempRect.NormalizeRect(); - - dc.FillRect(TempRect, &RimcasBrush); - dc.SetTextColor(RGB(238, 238, 208)); - } + auto acInfo = RimcasInstance->TimeTable[it->first][Time]; + + // Build formatted string with fixed spacing + char buffer[256]; + if (detailedRIMCAS) + { + sprintf_s(buffer, "%2d: %-10s %-8s %s", + Time, + acInfo.callsign.c_str(), + acInfo.type.empty() ? "" : acInfo.type.c_str(), + acInfo.stand.empty() ? "" : acInfo.stand.c_str()); + } + else + { + sprintf_s(buffer, "%2d: %s", Time, acInfo.callsign.c_str()); + } + tempS = buffer; - dc.TextOutA(CRectTime.left, CRectTime.top + TopOffset, tempS.c_str()); + if (RimcasInstance->AcColor.find(acInfo.callsign) != RimcasInstance->AcColor.end()) + { + CBrush RimcasBrush(RimcasInstance->GetAircraftColor(acInfo.callsign, + Color::Black, + Color::Black, + CurrentConfig->getConfigColor(CurrentConfig->getActiveProfile()["rimcas"]["background_color_stage_one"]), + CurrentConfig->getConfigColor(CurrentConfig->getActiveProfile()["rimcas"]["background_color_stage_two"])).ToCOLORREF() + ); + + CRect TempRect = { CRectTime.left, CRectTime.top + TopOffset, CRectTime.right, CRectTime.top + TopOffset + TextHeight }; + TempRect.NormalizeRect(); + + dc.FillRect(TempRect, &RimcasBrush); + dc.SetTextColor(RGB(238, 238, 208)); + } - TopOffset += TextHeight; + dc.TextOutA(CRectTime.left + 5, CRectTime.top + TopOffset, tempS.c_str()); + } + else + { + tempS = std::to_string(Time) + ": "; + dc.TextOutA(CRectTime.left + 5, CRectTime.top + TopOffset, tempS.c_str()); + } + + TopOffset += LineSpacing; } AddScreenObject(RIMCAS_IAW, it->first.c_str(), CRectTime, true, ""); @@ -2585,6 +2760,14 @@ void CSMRRadar::OnRefresh(HDC hDC, int Phase) ShowLists["Visibility"] = false; } + if (ShowLists["RIMCAS Detail"]) { + GetPlugIn()->OpenPopupList(ListAreas["RIMCAS Detail"], "RIMCAS Detail", 1); + GetPlugIn()->AddPopupListElement("Detailed", "", RIMCAS_UPDATE_DETAILED, false, int(detailedRIMCAS)); + GetPlugIn()->AddPopupListElement("Simple", "", RIMCAS_UPDATE_DETAILED, false, int(!detailedRIMCAS)); + GetPlugIn()->AddPopupListElement("Close", "", RIMCAS_CLOSE, false, 2, false, true); + ShowLists["RIMCAS Detail"] = false; + } + if (ShowLists["Profiles"]) { GetPlugIn()->OpenPopupList(ListAreas["Profiles"], "Profiles", 1); vector allProfiles = CurrentConfig->getAllProfiles(); diff --git a/vSMR/SMRRadar.hpp b/vSMR/SMRRadar.hpp index 06b59e60b..19c3f732e 100644 --- a/vSMR/SMRRadar.hpp +++ b/vSMR/SMRRadar.hpp @@ -105,6 +105,7 @@ class CSMRRadar : bool ColorSettingsDay = true; bool isLVP = false; + bool detailedRIMCAS = true; map TimePopupAreas; @@ -133,6 +134,10 @@ class CSMRRadar : int Trail_App = 4; int PredictedLength = 0; + bool showAircraftType = true; + bool showSID = true; + bool showWakeTurb = true; + bool NeedCorrelateCursor = false; bool ReleaseInProgress = false; bool AcquireInProgress = false; @@ -162,7 +167,7 @@ class CSMRRadar : //---GenerateTagData-------------------------------------------- - static map GenerateTagData(CRadarTarget Rt, CFlightPlan fp, bool isAcCorrelated, bool isProMode, int TransitionAltitude, bool useSpeedForGates, string ActiveAirport); + static map GenerateTagData(CRadarTarget Rt, CFlightPlan fp, bool isAcCorrelated, bool isProMode, int TransitionAltitude, bool useSpeedForGates, string ActiveAirport, bool showAircraftType, bool showSID, bool showWakeTurb); //---IsCorrelatedFuncs--------------------------------------------- diff --git a/vSMR/vSMR_Profiles.json b/vSMR/vSMR_Profiles.json index 9e4d8d43d..72151d87b 100644 --- a/vSMR/vSMR_Profiles.json +++ b/vSMR/vSMR_Profiles.json @@ -1,327 +1,2290 @@ -[{ +[ + { "name": "Default", "font": { - "font_name": "EuroScope", - "weight": "Regular", - "sizes": { - "one": 11, - "two": 12, - "three": 13, - "four": 14, - "five": 16 - } + "font_name": "Arial", + "weight": "Regular", + "sizes": { + "one": 11, + "two": 12, + "three": 13, + "four": 14, + "five": 16 + } }, "filters": { - "hide_above_alt": 4000, - "hide_above_spd": 250, - "radar_range_nm": 30, - "night_alpha_setting": 110, - "pro_mode": { - "enable": false, - "accept_pilot_squawk": false, - "do_not_autocorrelate_squawks": [ - "1000", - "2000", - "2200", - "1200", - "7000" - ] + "hide_above_alt": 4000, + "hide_above_spd": 250, + "radar_range_nm": 300, + "night_alpha_setting": 110, + "pro_mode": { + "enable": true, + "accept_pilot_squawk": false, + "do_not_autocorrelate_squawks": [ + "2000", + "2200", + "1200", + "7000" + ] + } + }, + "labels": { + "auto_deconfliction": true, + "leader_line_length": 50, + "use_aspeed_for_gate": false, + "squawk_error_color": { + "r": 255, + "g": 255, + "b": 0 + }, + "departure": { + "definition": [ + [ + "callsign" + ], + [ + "actype", + "asid", + "wake" + ] + ], + "background_color": { + "r": 40, + "g": 50, + "b": 200, + "a": 255 + }, + "background_color_on_runway": { + "r": 40, + "g": 50, + "b": 200, + "a": 255 + }, + "text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "arrival": { + "definition": [ + [ + "callsign" + ], + [ + "uk_stand", + "actype" + ] + ], + "background_color": { + "r": 170, + "g": 50, + "b": 50, + "a": 255 + }, + "background_color_on_runway": { + "r": 170, + "g": 50, + "b": 50, + "a": 255 + }, + "text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "airborne": { + "use_departure_arrival_coloring": false, + "definition": [ + [ + "callsign" + ], + [ + "flightlevel" + ] + ], + "text_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "background_color": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + } + }, + "uncorrelated": { + "definition": [ + [ + "systemid" + ] + ], + "text_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "background_color": { + "r": 150, + "g": 22, + "b": 135, + "a": 255 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 } + } + }, + "rimcas": { + "rimcas_label_only": true, + "use_red_symbol_for_emergencies": true, + "timer": [ + 60, + 45, + 30, + 15, + 0 + ], + "timer_lvp": [ + 120, + 90, + 60, + 30, + 0 + ], + "rimcas_stage_two_speed_threshold": 25, + "background_color_stage_one": { + "r": 160, + "g": 90, + "b": 30, + "a": 255 + }, + "background_color_stage_two": { + "r": 150, + "g": 0, + "b": 0, + "a": 255 + }, + "alert_text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "targets": { + "show_primary_target": true, + "target_color": { + "r": 255, + "g": 242, + "b": 73, + "a": 255 + }, + "history_one_color": { + "r": 0, + "g": 255, + "b": 255, + "a": 255 + }, + "history_two_color": { + "r": 0, + "g": 219, + "b": 219, + "a": 255 + }, + "history_three_color": { + "r": 0, + "g": 183, + "b": 183, + "a": 255 + } + }, + "approach_insets": { + "extended_lines_length": 15, + "extended_lines_ticks_spacing": 1, + "extended_lines_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "runway_color": { + "r": 0, + "g": 0, + "b": 0 + }, + "background_color": { + "r": 127, + "g": 122, + "b": 122 + } + } + }, + { + "name": "Easy/Observer", + "font": { + "font_name": "Arial", + "weight": "Regular", + "sizes": { + "one": 11, + "two": 12, + "three": 13, + "four": 14, + "five": 16 + } + }, + "filters": { + "hide_above_alt": 4000, + "hide_above_spd": 250, + "radar_range_nm": 300, + "night_alpha_setting": 110, + "pro_mode": { + "enable": false, + "accept_pilot_squawk": false, + "do_not_autocorrelate_squawks": [ + "2000", + "2200", + "1200", + "7000" + ] + } }, "labels": { - "auto_deconfliction": true, - "leader_line_length": 50, - "use_aspeed_for_gate": false, - "squawk_error_color": { - "r": 255, - "g": 0, - "b": 0 - }, - "groundstatus_colors": { - "push": { - "r": 227, - "g": 121, - "b": 0 - }, - "taxi": { - "r": 255, - "g": 166, - "b": 0 - }, - "depa": { - "r": 255, - "g": 156, - "b": 64 - } + "auto_deconfliction": true, + "leader_line_length": 50, + "use_aspeed_for_gate": false, + "squawk_error_color": { + "r": 255, + "g": 255, + "b": 0 + }, + "departure": { + "definition": [ + [ + "callsign" + ], + [ + "actype", + "asid", + "wake" + ] + ], + "background_color": { + "r": 40, + "g": 50, + "b": 200, + "a": 255 }, - "departure": { - "definition": [ - ["callsign", "dest", "groundstatus"], - ["sctype", "asid", "deprwy"] - ], - "background_color": { - "r": 33, - "g": 115, - "b": 196, - "a": 255 - }, - "background_color_on_runway": { - "r": 40, - "g": 50, - "b": 200, - "a": 255 - }, - "nosid_color": { - "r": 104, - "g": 50, - "b": 168, - "a": 255 - }, - "text_color": { - "r": 255, - "g": 255, - "b": 255 - } + "background_color_on_runway": { + "r": 40, + "g": 50, + "b": 200, + "a": 255 }, - "arrival": { - "definition": [ - ["callsign", "srvrwy"], - ["gate", "actype"] - ], - "background_color": { - "r": 170, - "g": 50, - "b": 50, - "a": 255 - }, - "background_color_on_runway": { - "r": 170, - "g": 50, - "b": 50, - "a": 255 - }, - "text_color": { - "r": 255, - "g": 255, - "b": 255 - } + "text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "arrival": { + "definition": [ + [ + "callsign" + ], + [ + "uk_stand", + "actype" + ] + ], + "background_color": { + "r": 170, + "g": 50, + "b": 50, + "a": 255 }, - "airborne": { - "use_departure_arrival_coloring": true, - "definition": [ - ["callsign", "dep"], - ["gs", "tendency", "flightlevel"], - ["actype", "dest"] - ], - "background_color": { - "r": 0, - "g": 0, - "b": 0, - "a": 255 - }, - "background_color_on_runway": { - "r": 0, - "g": 0, - "b": 0, - "a": 0 - }, - "text_color": { - "r": 255, - "g": 255, - "b": 255 - } + "background_color_on_runway": { + "r": 170, + "g": 50, + "b": 50, + "a": 255 }, - "uncorrelated": { - "definition": [ - ["systemid"] - ], - "background_color": { - "r": 150, - "g": 22, - "b": 135, - "a": 255 - }, - "background_color_on_runway": { - "r": 150, - "g": 22, - "b": 135, - "a": 50 - }, - "text_color": { - "r": 255, - "g": 255, - "b": 255 - }, - "nofpl_color": { - "r": 170, - "g": 50, - "b": 50, - "a": 255 - } + "text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "airborne": { + "use_departure_arrival_coloring": false, + "definition": [ + [ + "callsign" + ], + [ + "flightlevel", + "gs" + ], + [ + "actype" + ] + ], + "text_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "background_color": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + } + }, + "uncorrelated": { + "definition": [ + [ + "systemid" + ] + ], + "text_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "background_color": { + "r": 150, + "g": 22, + "b": 135, + "a": 255 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 } + } }, "rimcas": { - "rimcas_label_only": true, - "use_red_symbol_for_emergencies": true, - "timer": [60, 45, 30, 15, 0], - "timer_lvp": [120, 90, 60, 30, 0], - "rimcas_stage_two_speed_threshold": 25, - "background_color_stage_one": { - "r": 160, - "g": 90, - "b": 30, - "a": 255 - }, - "background_color_stage_two": { - "r": 150, - "g": 0, - "b": 0, - "a": 255 - }, - "alert_text_color": { + "rimcas_label_only": true, + "use_red_symbol_for_emergencies": true, + "timer": [ + 60, + 45, + 30, + 15, + 0 + ], + "timer_lvp": [ + 120, + 90, + 60, + 30, + 0 + ], + "rimcas_stage_two_speed_threshold": 25, + "background_color_stage_one": { + "r": 160, + "g": 90, + "b": 30, + "a": 255 + }, + "background_color_stage_two": { + "r": 150, + "g": 0, + "b": 0, + "a": 255 + }, + "alert_text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "targets": { + "show_primary_target": true, + "target_color": { + "r": 255, + "g": 242, + "b": 73, + "a": 255 + }, + "history_one_color": { + "r": 0, + "g": 255, + "b": 255, + "a": 255 + }, + "history_two_color": { + "r": 0, + "g": 219, + "b": 219, + "a": 255 + }, + "history_three_color": { + "r": 0, + "g": 183, + "b": 183, + "a": 255 + } + }, + "approach_insets": { + "extended_lines_length": 15, + "extended_lines_ticks_spacing": 1, + "extended_lines_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "runway_color": { + "r": 0, + "g": 0, + "b": 0 + }, + "background_color": { + "r": 100, + "g": 100, + "b": 100 + } + } + }, + { + "name": "Heathrow (Realistic)", + "font": { + "font_name": "Arial", + "weight": "Regular", + "sizes": { + "one": 11, + "two": 12, + "three": 13, + "four": 14, + "five": 16 + } + }, + "filters": { + "hide_above_alt": 6000, + "hide_above_spd": 300, + "radar_range_nm": 15, + "night_alpha_setting": 100, + "pro_mode": { + "enable": true, + "accept_pilot_squawk": false, + "do_not_autocorrelate_squawks": [ + "2000", + "2200", + "1200", + "7000" + ] + } + }, + "labels": { + "auto_deconfliction": true, + "leader_line_length": 25, + "use_aspeed_for_gate": true, + "squawk_error_color": { + "r": 255, + "g": 255, + "b": 0 + }, + "departure": { + "definition": [ + [ + "callsign" + ], + [ + "actype", + "asid", + "wake" + ] + ], + "background_color": { + "r": 0, + "g": 0, + "b": 150, + "a": 255 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 150, + "a": 255 + }, + "text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "arrival": { + "definition": [ + [ + "callsign" + ], + [ + "uk_stand", + "actype" + ] + ], + "background_color": { + "r": 68, + "g": 34, + "b": 16, + "a": 255 + }, + "background_color_on_runway": { + "r": 68, + "g": 34, + "b": 16, + "a": 255 + }, + "text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "airborne": { + "use_departure_arrival_coloring": false, + "definition": [ + [ + "callsign" + ], + [ + "flightlevel" + ] + ], + "text_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "background_color": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + } + }, + "uncorrelated": { + "definition": [ + [ + "ssr" + ] + ], + "text_color": { "r": 255, "g": 255, "b": 255 + }, + "background_color": { + "r": 0, + "g": 150, + "b": 0, + "a": 255 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 } + } + }, + "rimcas": { + "rimcas_label_only": true, + "use_red_symbol_for_emergencies": true, + "timer": [ + 60, + 45, + 30, + 15, + 0 + ], + "timer_lvp": [ + 120, + 90, + 60, + 30, + 0 + ], + "rimcas_stage_two_speed_threshold": 40, + "background_color_stage_one": { + "r": 255, + "g": 135, + "b": 10, + "a": 255 + }, + "background_color_stage_two": { + "r": 255, + "g": 0, + "b": 0, + "a": 255 + }, + "alert_text_color": { + "r": 255, + "g": 255, + "b": 255 + } }, "targets": { - "show_primary_target": true, - "target_color": { - "r": 255, - "g": 242, - "b": 73, - "a": 255 - }, - "history_one_color": { - "r": 0, - "g": 255, - "b": 255, - "a": 255 - }, - "history_two_color": { - "r": 0, - "g": 219, - "b": 219, - "a": 255 - }, - "history_three_color": { - "r": 0, - "g": 183, - "b": 183, - "a": 255 + "show_primary_target": true, + "target_color": { + "r": 255, + "g": 242, + "b": 73, + "a": 255 + }, + "history_one_color": { + "r": 0, + "g": 235, + "b": 235, + "a": 200 + }, + "history_two_color": { + "r": 0, + "g": 219, + "b": 219, + "a": 150 + }, + "history_three_color": { + "r": 0, + "g": 183, + "b": 183, + "a": 100 + } + }, + "approach_insets": { + "extended_lines_length": 15, + "extended_lines_ticks_spacing": 1, + "extended_lines_color": { + "r": 150, + "g": 150, + "b": 150 + }, + "runway_color": { + "r": 50, + "g": 50, + "b": 50 + }, + "background_color": { + "r": 0, + "g": 0, + "b": 0 + } + }, + "maps": { + "EGLL": { + "runways": [ + { + "runway_name": "09L/27R", + "path": [ + [ + "N051.28.40.051", + "W000.29.26.292" + ], + [ + "N051.28.40.820", + "W000.25.56.013" + ], + [ + "N051.28.36.864", + "W000.25.56.013" + ], + [ + "N051.28.36.754", + "W000.29.26.657" + ] + ], + "path_lvp": [ + [ + "N051.28.40.051", + "W000.29.26.292" + ], + [ + "N051.28.40.820", + "W000.25.56.013" + ], + [ + "N051.28.36.864", + "W000.25.56.013" + ], + [ + "N051.28.36.754", + "W000.29.26.657" + ] + ] + }, + { + "runway_name": "09R/27L", + "path": [ + [ + "N051.27.56.534", + "W000.29.17.698" + ], + [ + "N051.27.50.490", + "W000.29.17.698" + ], + [ + "N051.27.50.820", + "W000.26.01.681" + ], + [ + "N051.27.56.534", + "W000.26.01.681" + ] + ], + "path_lvp": [ + [ + "N051.27.56.534", + "W000.29.17.698" + ], + [ + "N051.27.50.490", + "W000.29.17.698" + ], + [ + "N051.27.50.820", + "W000.26.01.681" + ], + [ + "N051.27.56.534", + "W000.26.01.681" + ] + ] + } + ], + "georeference_correlation_areas": [ + [ + [ + "N051.28.28.458", + "W000.29.23.191" + ], + [ + "N051.28.28.458", + "W000.29.07.023" + ], + [ + "N051.28.08.328", + "W000.29.07.023" + ], + [ + "N051.28.08.328", + "W000.29.23.191" + ] + ], + [ + [ + "N051.28.06.734", + "W000.29.20.736" + ], + [ + "N051.28.06.734", + "W000.29.16.550" + ], + [ + "N051.28.04.949", + "W000.29.16.550" + ], + [ + "N051.28.04.949", + "W000.29.20.736" + ] + ], + [ + [ + "N051.28.06.734", + "W000.29.13.454" + ], + [ + "N051.28.06.734", + "W000.29.07.023" + ], + [ + "N051.28.04.949", + "W000.29.07.023" + ], + [ + "N051.28.04.949", + "W000.29.13.454" + ] + ], + [ + [ + "N051.28.27.780", + "W000.28.58.775" + ], + [ + "N051.28.27.780", + "W000.28.46.050" + ], + [ + "N051.28.04.658", + "W000.28.46.050" + ], + [ + "N051.28.04.658", + "W000.28.58.775" + ] + ], + [ + [ + "N051.28.27.780", + "W000.28.40.695" + ], + [ + "N051.28.27.780", + "W000.28.27.136" + ], + [ + "N051.28.04.658", + "W000.28.27.136" + ], + [ + "N051.28.04.658", + "W000.28.40.695" + ] + ], + [ + [ + "N051.28.28.380", + "W000.28.22.042" + ], + [ + "N051.28.04.577", + "W000.28.22.042" + ], + [ + "N051.28.04.577", + "W000.28.09.854" + ], + [ + "N051.28.25.236", + "W000.28.09.854" + ], + [ + "N051.28.28.380", + "W000.28.11.303" + ] + ], + [ + [ + "N051.28.04.664", + "W000.27.31.900" + ], + [ + "N051.28.04.804", + "W000.26.46.556" + ], + [ + "N051.28.28.848", + "W000.26.46.327" + ], + [ + "N051.28.28.931", + "W000.27.39.302" + ], + [ + "N051.28.23.910", + "W000.27.34.158" + ], + [ + "N051.28.22.315", + "W000.27.37.954" + ], + [ + "N051.28.29.060", + "W000.27.45.067" + ], + [ + "N051.28.28.944", + "W000.28.00.576" + ], + [ + "N051.28.22.174", + "W000.27.59.311" + ], + [ + "N051.28.22.058", + "W000.27.50.580" + ] + ], + [ + [ + "N051.28.04.846", + "W000.27.38.329" + ], + [ + "N051.28.06.137", + "W000.27.38.329" + ], + [ + "N051.28.19.452", + "W000.27.52.414" + ], + [ + "N051.28.19.269", + "W000.27.59.701" + ], + [ + "N051.28.14.226", + "W000.27.59.727" + ], + [ + "N051.28.04.846", + "W000.27.49.363" + ] + ], + [ + [ + "N051.28.28.275", + "W000.26.41.425" + ], + [ + "N051.28.28.275", + "W000.26.28.548" + ], + [ + "N051.28.05.467", + "W000.26.28.548" + ], + [ + "N051.28.05.467", + "W000.26.41.425" + ] + ], + [ + [ + "N051.28.28.269", + "W000.26.23.457" + ], + [ + "N051.28.28.269", + "W000.26.18.050" + ], + [ + "N051.28.06.490", + "W000.26.18.050" + ], + [ + "N051.28.06.490", + "W000.26.23.457" + ] + ], + [ + [ + "N051.27.45.873", + "W000.28.23.748" + ], + [ + "N051.27.45.873", + "W000.28.27.768" + ], + [ + "N051.27.35.625", + "W000.28.27.768" + ], + [ + "N051.27.35.625", + "W000.28.23.748" + ] + ], + [ + [ + "N051.27.46.128", + "W000.27.22.536" + ], + [ + "N051.27.38.172", + "W000.27.14.181" + ], + [ + "N051.27.29.115", + "W000.27.14.368" + ], + [ + "N051.27.29.115", + "W000.28.18.746" + ], + [ + "N051.27.46.128", + "W000.28.18.746" + ] + ], + [ + [ + "N051.27.46.143", + "W000.26.34.534" + ], + [ + "N051.27.36.807", + "W000.26.40.632" + ], + [ + "N051.27.28.463", + "W000.26.52.555" + ], + [ + "N051.27.25.660", + "W000.27.01.636" + ], + [ + "N051.27.26.574", + "W000.27.07.679" + ], + [ + "N051.27.27.739", + "W000.27.09.732" + ], + [ + "N051.27.29.539", + "W000.27.09.623" + ], + [ + "N051.27.46.227", + "W000.26.45.515" + ] + ], + [ + [ + "N051.27.45.704", + "W000.26.24.475" + ], + [ + "N051.27.41.912", + "W000.26.26.980" + ], + [ + "N051.27.41.965", + "W000.26.14.450" + ], + [ + "N051.27.39.226", + "W000.26.14.527" + ], + [ + "N051.27.34.585", + "W000.26.32.700" + ], + [ + "N051.27.35.709", + "W000.26.36.944" + ], + [ + "N051.27.45.877", + "W000.26.29.901" + ] + ], + [ + [ + "N051.27.36.772", + "W000.27.05.666" + ], + [ + "N051.27.40.432", + "W000.27.00.460" + ], + [ + "N051.27.41.985", + "W000.27.04.255" + ], + [ + "N051.27.38.844", + "W000.27.09.051" + ] + ] + ] + } + } + }, + { + "name": "Heathrow (Old)", + "font": { + "font_name": "Arial", + "weight": "Regular", + "sizes": { + "one": 11, + "two": 12, + "three": 13, + "four": 14, + "five": 16 + } + }, + "filters": { + "hide_above_alt": 6000, + "hide_above_spd": 300, + "radar_range_nm": 15, + "night_alpha_setting": 100, + "pro_mode": { + "enable": true, + "accept_pilot_squawk": false, + "do_not_autocorrelate_squawks": [ + "2000", + "2200", + "1200", + "7000" + ] + } + }, + "labels": { + "auto_deconfliction": true, + "leader_line_length": 25, + "use_aspeed_for_gate": true, + "squawk_error_color": { + "r": 255, + "g": 255, + "b": 0 + }, + "departure": { + "definition": [ + [ + "callsign" + ], + [ + "actype", + "asid", + "wake" + ] + ], + "background_color": { + "r": 0, + "g": 0, + "b": 150, + "a": 255 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 150, + "a": 255 + }, + "text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "arrival": { + "definition": [ + [ + "callsign" + ], + [ + "uk_stand" + ] + ], + "background_color": { + "r": 68, + "g": 34, + "b": 16, + "a": 255 + }, + "background_color_on_runway": { + "r": 68, + "g": 34, + "b": 16, + "a": 255 + }, + "text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "airborne": { + "use_departure_arrival_coloring": false, + "definition": [ + [ + "callsign" + ], + [ + "flightlevel" + ] + ], + "text_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "background_color": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 } + }, + "uncorrelated": { + "definition": [ + [ + "ssr" + ] + ], + "text_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "background_color": { + "r": 0, + "g": 150, + "b": 0, + "a": 255 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + } + } + }, + "rimcas": { + "rimcas_label_only": true, + "use_red_symbol_for_emergencies": true, + "timer": [ + 60, + 45, + 30, + 15, + 0 + ], + "timer_lvp": [ + 120, + 90, + 60, + 30, + 0 + ], + "rimcas_stage_two_speed_threshold": 40, + "background_color_stage_one": { + "r": 255, + "g": 135, + "b": 10, + "a": 255 + }, + "background_color_stage_two": { + "r": 255, + "g": 0, + "b": 0, + "a": 255 + }, + "alert_text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "targets": { + "show_primary_target": true, + "target_color": { + "r": 255, + "g": 242, + "b": 73, + "a": 255 + }, + "history_one_color": { + "r": 0, + "g": 235, + "b": 235, + "a": 200 + }, + "history_two_color": { + "r": 0, + "g": 219, + "b": 219, + "a": 150 + }, + "history_three_color": { + "r": 0, + "g": 183, + "b": 183, + "a": 100 + } }, "approach_insets": { - "extended_lines_length": 15, - "extended_lines_ticks_spacing": 1, - "extended_lines_color": { - "r": 255, - "g": 255, - "b": 255 - }, - "runway_color": { - "r": 0, - "g": 0, - "b": 0 + "extended_lines_length": 15, + "extended_lines_ticks_spacing": 1, + "extended_lines_color": { + "r": 150, + "g": 150, + "b": 150 + }, + "runway_color": { + "r": 50, + "g": 50, + "b": 50 + }, + "background_color": { + "r": 0, + "g": 0, + "b": 0 + } + }, + "maps": { + "EGLL": { + "runways": [ + { + "runway_name": "09L/27R", + "path": [ + [ + "N051.28.40.051", + "W000.29.26.292" + ], + [ + "N051.28.40.820", + "W000.25.56.013" + ], + [ + "N051.28.36.864", + "W000.25.56.013" + ], + [ + "N051.28.36.754", + "W000.29.26.657" + ] + ], + "path_lvp": [ + [ + "N051.28.40.051", + "W000.29.26.292" + ], + [ + "N051.28.40.820", + "W000.25.56.013" + ], + [ + "N051.28.36.864", + "W000.25.56.013" + ], + [ + "N051.28.36.754", + "W000.29.26.657" + ] + ] + }, + { + "runway_name": "09R/27L", + "path": [ + [ + "N051.27.56.534", + "W000.29.17.698" + ], + [ + "N051.27.50.490", + "W000.29.17.698" + ], + [ + "N051.27.50.820", + "W000.26.01.681" + ], + [ + "N051.27.56.534", + "W000.26.01.681" + ] + ], + "path_lvp": [ + [ + "N051.27.56.534", + "W000.29.17.698" + ], + [ + "N051.27.50.490", + "W000.29.17.698" + ], + [ + "N051.27.50.820", + "W000.26.01.681" + ], + [ + "N051.27.56.534", + "W000.26.01.681" + ] + ] + } + ] + } + } + }, + { + "name": "Gatwick (Realistic)", + "font": { + "font_name": "Arial", + "weight": "Regular", + "sizes": { + "one": 11, + "two": 12, + "three": 13, + "four": 14, + "five": 16 + } + }, + "filters": { + "hide_above_alt": 6000, + "hide_above_spd": 300, + "radar_range_nm": 15, + "night_alpha_setting": 100, + "pro_mode": { + "enable": true, + "accept_pilot_squawk": false, + "do_not_autocorrelate_squawks": [ + "2000", + "2200", + "1200", + "7000" + ] + } + }, + "labels": { + "auto_deconfliction": true, + "leader_line_length": 25, + "use_aspeed_for_gate": true, + "squawk_error_color": { + "r": 255, + "g": 255, + "b": 0 + }, + "departure": { + "definition": [ + [ + "callsign" + ], + [ + "actype", + "asid", + "wake" + ] + ], + "background_color": { + "r": 0, + "g": 30, + "b": 200, + "a": 255 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 150, + "a": 255 + }, + "text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "arrival": { + "definition": [ + [ + "callsign" + ] + ], + "background_color": { + "r": 179, + "g": 137, + "b": 46, + "a": 255 + }, + "background_color_on_runway": { + "r": 220, + "g": 175, + "b": 80, + "a": 255 + }, + "text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "airborne": { + "use_departure_arrival_coloring": false, + "definition": [ + [ + "callsign" + ], + [ + "flightlevel" + ] + ], + "text_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "background_color": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + } + }, + "uncorrelated": { + "definition": [ + [ + "ssr" + ] + ], + "text_color": { + "r": 255, + "g": 255, + "b": 255 }, "background_color": { - "r": 100, - "g": 100, - "b": 100 + "r": 0, + "g": 150, + "b": 0, + "a": 255 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 } + } + }, + "rimcas": { + "rimcas_label_only": true, + "use_red_symbol_for_emergencies": true, + "timer": [ + 60, + 45, + 30, + 15, + 0 + ], + "timer_lvp": [ + 120, + 90, + 60, + 30, + 0 + ], + "rimcas_stage_two_speed_threshold": 40, + "background_color_stage_one": { + "r": 255, + "g": 135, + "b": 10, + "a": 255 + }, + "background_color_stage_two": { + "r": 255, + "g": 0, + "b": 0, + "a": 255 + }, + "alert_text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "targets": { + "show_primary_target": true, + "target_color": { + "r": 255, + "g": 242, + "b": 73, + "a": 255 + }, + "history_one_color": { + "r": 0, + "g": 235, + "b": 235, + "a": 200 + }, + "history_two_color": { + "r": 0, + "g": 219, + "b": 219, + "a": 150 + }, + "history_three_color": { + "r": 0, + "g": 183, + "b": 183, + "a": 100 + } + }, + "approach_insets": { + "extended_lines_length": 15, + "extended_lines_ticks_spacing": 1, + "extended_lines_color": { + "r": 150, + "g": 150, + "b": 150 + }, + "runway_color": { + "r": 50, + "g": 50, + "b": 50 + }, + "background_color": { + "r": 0, + "g": 0, + "b": 0 + } }, "maps": { - "EGKK": { - "sids": [{ - "names": ["CLN1M", "CLN9M", "CLN5P", "DVR9M", "DVR2P", "LAM5M", "LAM5P", "BIG8M", "BIG3P", "#SAM2M", "SAM3P", "SFD5M", "SFD9P", "BOGNA1M", "NOVMA1M", "DVR1M", "WIZAD4M", "LAM6M", "TIGER3M", "DAGGA1M"], - "comment": "Old Conventional Unused SIDS", - "color": { - "r": 255, - "g": 50, - "b": 50, - "a": 255 - } - }, - { - "names": ["BOGNA1X", "HARDY1X", "NOVMA1X"], - "comment": "26L A2 SIDs", - "color": { - "r": 220, - "g": 175, - "b": 80, - "a": 255 - } - }, - { - "names": ["FRANE1X", "LAM2X", "ADMAG2X"], - "comment": "26L A3 SIDs", - "color": { - "r": 80, - "g": 150, - "b": 255, - "a": 255 - } - }, - { - "names": ["FRANE1Z", "LAM1Z", "ODVIK2Z"], - "comment": "08R J4 SIDs", - "color": { - "r": 80, - "g": 150, - "b": 255, - "a": 255 - } - }, - { - "names": ["SFD4Z", "IMVUR1Z", "KENET3P"], - "comment": "08R J7 SIDs", - "color": { - "r": 220, - "g": 175, - "b": 80, - "a": 255 - } - }, - { - "names": ["BIG2X", "BIG2Z"], - "comment": "Biggin Hill SIDs", - "color": { - "r": 150, - "g": 255, - "b": 150, - "a": 255 - } - }, - { - "names": ["SFD1X", "DAGGA1X", "TIGER1X", "WIZAD1X"], - "comment": "Time Restricted and Relief SIDs", - "color": { - "r": 160, - "g": 90, - "b": 30, - "a": 255 - } - }], - "runways": [ - { - "runway_name": "08L/26R", - "path": [ - ["N051.08.49.700", "W000.12.45.500"], - ["N051.08.48.000", "W000.12.44.900"], - ["N051.09.05.900", "W000.10.36.200"], - ["N051.09.07.500", "W000.10.36.900"] - ] - }, - { - "runway_name": "08R/26L", - "path": [ - ["N051.08.43.500", "W000.12.44.700"], - ["N051.08.41.300", "W000.12.43.900"], - ["N051.09.04.000", "W000.09.55.600"], - ["N051.09.07.200", "W000.09.57.000"] - ] - } + "EGKK": { + "runways": [ + { + "runway_name": "08L/26R", + "path": [ + [ + "N051.08.49.700", + "W000.12.45.500" + ], + [ + "N051.08.48.000", + "W000.12.44.900" + ], + [ + "N051.09.05.900", + "W000.10.36.200" + ], + [ + "N051.09.07.500", + "W000.10.36.900" + ] + ] + }, + { + "runway_name": "08R/26L", + "path": [ + [ + "N051.09.06.780", + "W000.09.56.390" + ], + [ + "N051.09.04.410", + "W000.09.55.590" + ], + [ + "N051.08.41.200", + "W000.12.44.060" + ], + [ + "N051.08.43.560", + "W000.12.44.920" + ] ] + } + ], + "georeference_correlation_areas": [ + [ + [ + "N051.09.12.644", + "W000.09.44.398" + ], + [ + "N051.09.11.774", + "W000.09.51.322" + ], + [ + "N051.09.18.638", + "W000.09.53.778" + ], + [ + "N051.09.15.143", + "W000.10.19.074" + ], + [ + "N051.09.20.611", + "W000.10.21.095" + ], + [ + "N051.09.25.153", + "W000.09.48.343" + ] + ], + [ + [ + "N051.09.26.575", + "W000.09.58.329" + ], + [ + "N051.09.24.855", + "W000.10.11.231" + ], + [ + "N051.09.29.625", + "W000.10.12.918" + ], + [ + "N051.09.32.414", + "W000.10.11.336" + ], + [ + "N051.09.33.815", + "W000.10.07.508" + ], + [ + "N051.09.33.465", + "W000.10.03.142" + ], + [ + "N051.09.31.621", + "W000.09.59.965" + ] + ], + [ + [ + "N051.09.25.563", + "W000.10.32.294" + ], + [ + "N051.09.20.952", + "W000.10.30.620" + ], + [ + "N051.09.18.168", + "W000.10.49.739" + ], + [ + "N051.09.23.763", + "W000.10.45.818" + ] + ], + [ + [ + "N051.09.47.990", + "W000.10.54.729" + ], + [ + "N051.09.26.608", + "W000.10.47.224" + ], + [ + "N051.09.30.687", + "W000.10.17.510" + ], + [ + "N051.09.34.625", + "W000.10.14.098" + ], + [ + "N051.09.36.535", + "W000.10.08.389" + ], + [ + "N051.09.52.269", + "W000.10.22.055" + ] + ], + [ + [ + "N051.09.47.280", + "W000.10.59.133" + ], + [ + "N051.09.38.657", + "W000.10.56.124" + ], + [ + "N051.09.36.227", + "W000.10.59.922" + ], + [ + "N051.09.46.670", + "W000.11.03.879" + ] + ], + [ + [ + "N051.09.09.596", + "W000.10.49.184" + ], + [ + "N051.09.15.087", + "W000.10.51.063" + ], + [ + "N051.09.18.024", + "W000.10.29.656" + ], + [ + "N051.09.12.575", + "W000.10.27.814" + ] + ], + [ + [ + "N051.09.07.210", + "W000.11.10.890" + ], + [ + "N051.09.19.800", + "W000.11.15.339" + ], + [ + "N051.09.21.434", + "W000.11.03.279" + ], + [ + "N051.09.08.757", + "W000.10.58.863" + ] + ], + [ + [ + "N051.09.06.461", + "W000.11.15.543" + ], + [ + "N051.09.21.904", + "W000.11.21.006" + ], + [ + "N051.09.24.811", + "W000.11.00.359" + ], + [ + "N051.09.27.251", + "W000.11.01.236" + ], + [ + "N051.09.23.750", + "W000.11.27.105" + ], + [ + "N051.09.05.709", + "W000.11.20.536" + ] + ], + [ + [ + "N051.09.02.749", + "W000.11.41.919" + ], + [ + "N051.09.20.123", + "W000.11.48.021" + ], + [ + "N051.09.20.791", + "W000.11.43.383" + ], + [ + "N051.09.03.470", + "W000.11.37.328" + ] + ] + ] + } + } + }, + { + "name": "Gatwick (Unrealistic)", + "font": { + "font_name": "Arial", + "weight": "Regular", + "sizes": { + "one": 11, + "two": 12, + "three": 13, + "four": 14, + "five": 16 + } + }, + "filters": { + "hide_above_alt": 4000, + "hide_above_spd": 250, + "radar_range_nm": 300, + "night_alpha_setting": 110, + "pro_mode": { + "enable": true, + "accept_pilot_squawk": false, + "do_not_autocorrelate_squawks": [ + "2000", + "2200", + "1200", + "7000" + ] + } + }, + "labels": { + "auto_deconfliction": true, + "leader_line_length": 50, + "use_aspeed_for_gate": false, + "squawk_error_color": { + "r": 255, + "g": 255, + "b": 0 + }, + "departure": { + "definition": [ + [ + "callsign" + ], + [ + "actype", + "asid", + "wake" + ] + ], + "background_color": { + "r": 40, + "g": 50, + "b": 200, + "a": 255 + }, + "background_color_on_runway": { + "r": 40, + "g": 50, + "b": 200, + "a": 255 + }, + "text_color": { + "r": 255, + "g": 255, + "b": 255 } + }, + "arrival": { + "definition": [ + [ + "callsign" + ], + [ + "uk_stand", + "actype" + ] + ], + "background_color": { + "r": 200, + "g": 155, + "b": 60, + "a": 255 + }, + "background_color_on_runway": { + "r": 200, + "g": 155, + "b": 60, + "a": 255 + }, + "text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "airborne": { + "use_departure_arrival_coloring": false, + "definition": [ + [ + "callsign" + ], + [ + "flightlevel", + "gs" + ], + [ + "actype" + ] + ], + "text_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "background_color": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + } + }, + "uncorrelated": { + "definition": [ + [ + "systemid" + ] + ], + "text_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "background_color": { + "r": 150, + "g": 22, + "b": 135, + "a": 255 + }, + "background_color_on_runway": { + "r": 0, + "g": 0, + "b": 0, + "a": 0 + } + } + }, + "rimcas": { + "rimcas_label_only": true, + "use_red_symbol_for_emergencies": true, + "timer": [ + 60, + 45, + 30, + 15, + 0 + ], + "timer_lvp": [ + 120, + 90, + 60, + 30, + 0 + ], + "rimcas_stage_two_speed_threshold": 25, + "background_color_stage_one": { + "r": 160, + "g": 90, + "b": 30, + "a": 255 + }, + "background_color_stage_two": { + "r": 150, + "g": 0, + "b": 0, + "a": 255 + }, + "alert_text_color": { + "r": 255, + "g": 255, + "b": 255 + } + }, + "targets": { + "show_primary_target": true, + "target_color": { + "r": 255, + "g": 242, + "b": 73, + "a": 255 + }, + "history_one_color": { + "r": 0, + "g": 255, + "b": 255, + "a": 255 + }, + "history_two_color": { + "r": 0, + "g": 219, + "b": 219, + "a": 255 + }, + "history_three_color": { + "r": 0, + "g": 183, + "b": 183, + "a": 255 + } + }, + "approach_insets": { + "extended_lines_length": 15, + "extended_lines_ticks_spacing": 1, + "extended_lines_color": { + "r": 255, + "g": 255, + "b": 255 + }, + "runway_color": { + "r": 0, + "g": 0, + "b": 0 + }, + "background_color": { + "r": 100, + "g": 100, + "b": 100 + } + }, + "maps": { + "EGKK": { + "sids": [ + { + "names": [ + "FRANE1M", + "FRANE1V", + "MIMFO1M", + "MIMFO1V", + "LAM6M", + "LAM6V", + "#ADMAG2X", + "#BIG2X", + "#FRANE1X", + "#LAM2X" + ], + "comment": "Eastbound SIDs (Light Blue)", + "color": { + "r": 80, + "g": 150, + "b": 255, + "a": 255 + } + }, + { + "names": [ + "BOGNA1X", + "BOGNA1M", + "BOGNA1V", + "DAGGA1X", + "DAGGA1M", + "DAGGA1V", + "HARDY1X", + "HARDY5M", + "HARDY5V", + "NOVMA1X", + "NOVMA1M", + "NOVMA1V", + "SFD1X", + "SFD5M", + "SFD5V", + "TIGER1X", + "TIGER3M", + "TIGER3V", + "WIZAD1X", + "WIZAD4M", + "WIZAD4V" + ], + "comment": "Westbound SIDs (Blue)", + "color": { + "r": 40, + "g": 50, + "b": 200, + "a": 255 + } + }, + { + "names": [ + "FRANE1P", + "FRANE1W", + "FRANE1Z", + "DVR2P", + "DVR2W", + "LAM1Z", + "LAM5P", + "LAM5W", + "ODVIK2Z", + "#BIG2Z" + ], + "comment": "Eastbound SIDs (Light Blue)", + "color": { + "r": 80, + "g": 150, + "b": 255, + "a": 255 + } + }, + { + "names": [ + "IMVUR1Z", + "KENET3P", + "KENET3W", + "SAM3P", + "SAM3W", + "SFD4Z", + "SFD9P", + "SFD9W" + ], + "comment": "Westbound SIDs (Blue)", + "color": { + "r": 40, + "g": 50, + "b": 200, + "a": 255 + } + } + ], + "runways": [ + { + "runway_name": "08L/26R", + "path": [ + [ + "N051.08.49.700", + "W000.12.45.500" + ], + [ + "N051.08.48.000", + "W000.12.44.900" + ], + [ + "N051.09.05.900", + "W000.10.36.200" + ], + [ + "N051.09.07.500", + "W000.10.36.900" + ] + ] + }, + { + "runway_name": "08R/26L", + "path": [ + [ + "N051.08.43.500", + "W000.12.44.700" + ], + [ + "N051.08.41.300", + "W000.12.43.900" + ], + [ + "N051.09.04.000", + "W000.09.55.600" + ], + [ + "N051.09.07.200", + "W000.09.57.000" + ] + ] + } + ] + } } -}] \ No newline at end of file + } +] \ No newline at end of file