//------------------------------------------------------------------------------ // pixelsToLatLon() - determine our lat lon position from a pixel X/Y //------------------------------------------------------------------------------ void MapPage::pixelsToLatLon(const int x, const int y, double &lat, double &lon) { double xpos = x; double ypos = y; // convert pixels position from top left to movement from center, so we // can base our cals from the center. if (getDisplay() != nullptr) { double myLat = 0, myLon = 0; double dLat = 0, dLon = 0; GLsizei vpW = 0, vpH = 0; getDisplay()->getViewportSize(&vpW, &vpH); GLdouble tl = 0, tr = 0, tb = 0, tt = 0, tn = 0, tf = 0; getDisplay()->getOrtho(tl, tr, tb, tt, tn, tf); // determine the middle of our viewing screen const double startX = (vpW / 2.0); const double startY = (vpH / 2.0); // find the position from our screen center (in pixels) xpos -= startX; ypos = startY - ypos; // we have to find our units per pixel const double unitsPerPixE = ((tr * 2) / vpW); const double unitsPerPixN = ((tt * 2) / vpH); // now from that we can determine our position in inches xpos *= unitsPerPixE; ypos *= unitsPerPixN; if (!isCentered) ypos -= displacement; // ok, now we can find our xpos and ypos in nautical miles xpos /= nm2Screen; ypos /= nm2Screen; if (!getNorthUp()) { LCreal acX = 0; LCreal acY = 0; earth2Aircraft( static_cast<LCreal>(xpos), static_cast<LCreal>(ypos), &acX, &acY); xpos = acX; ypos = acY; } // reference lat to figure off of (if centered()) myLat = referenceLat; myLon = referenceLon; // now convert to degree from our reference lat/lon dLat = ypos / 60.0; dLon = xpos / (60.0 * cosineLatReference); myLat += dLat; myLon += dLon; lat = myLat; lon = myLon; } }
//------------------------------------------------------------------------------ // draw() - draw the objects in their proper place //------------------------------------------------------------------------------ void SymbolLoader::draw() { if (isVisible()) { // Y Displacement (ie, decentered) LCreal displacement = 0; if (!getCentered()) displacement = getDisplacement(); // Radius (ie., range) LCreal radius = 0; if (!getCentered()) radius = getOuterRadiusDC(); else radius = getOuterRadius(); LCreal radius2 = radius * radius; // --- // Setup the drawing parameters for all of our symbols ... // --- for (int i = 0; i < MAX_SYMBOLS; i++) { if (symbols[i] != 0) { // When the symbol visibility flag is true ... if (symbols[i]->isVisible()) { // Get the pointer to the symbol's graphical component Basic::Pair* p = symbols[i]->getSymbolPair(); BasicGL::Graphic* g = (BasicGL::Graphic*)p->object(); // We need the symbol's position in screen coordinates (inches) ... LCreal xScn = (LCreal) symbols[i]->getScreenXPos(); LCreal yScn = (LCreal) symbols[i]->getScreenYPos(); if ( !(symbols[i]->isPositionScreen()) ) { // But when we were not give screen coordinates, // we'll need to compute them from A/C coordinates LCreal acX = 0.0; LCreal acY = 0.0; // 1) when given A/C coordinates ... if ( symbols[i]->isPositionAC() ) { acX = (LCreal) symbols[i]->getXPosition(); acY = (LCreal) symbols[i]->getYPosition(); } // 2) when given NED or L/L coordinates .. else { LCreal north = 0; LCreal east = 0; if (symbols[i]->isPositionLL()) { // 2a) we were give L/L so convert to NED coordinates double lat = symbols[i]->getXPosition(); double lon = symbols[i]->getYPosition(); latLon2Earth(lat, lon, &north, &east); } else { // 2b) we were give NED coordinates north = (LCreal) symbols[i]->getXPosition(); east = (LCreal) symbols[i]->getYPosition(); } // 2c) convert the NED coordinates to aircraft coordinates earth2Aircraft(north, east, &acX, &acY); } // 3) Convert the aircraft coordinates to screen coordinates aircraft2Screen(acX, acY, &xScn, &yScn); // 4) Save the screen coordinates (inches) symbols[i]->setXScreenPos(xScn); symbols[i]->setYScreenPos(yScn); } // In range? Do we care? bool inRange = !showInRangeOnly || (((xScn * xScn) + (yScn * yScn)) <= radius2); if (inRange) { // set symbol's visibility g->setVisibility(true); // and set the symbol's position g->lcSaveMatrix(); g->lcTranslate(xScn, yScn + displacement); // pass the argument value to the symbol (if needed) if (symbols[i]->getValue() != 0) { g->event(UPDATE_VALUE, symbols[i]->getValue()); } // rotate the symbol's heading subcomponent (if needed) // -- sending a 'Z' rotation event to a component named 'hdg' if (symbols[i]->isHeadingValid()) { BasicGL::Graphic* phdg = symbols[i]->getHdgGraphics(); if (phdg == 0) { Basic::Pair* hpair = (Basic::Pair*) g->findByName("hdg"); if (hpair != 0) { phdg = dynamic_cast<Graphic*>(hpair->object()); symbols[i]->setHdgGraphics(phdg); } } if (phdg != 0) { Basic::Degrees* angObj = symbols[i]->getHdgAngleObj(); if (angObj == 0) { angObj = new Basic::Degrees(); symbols[i]->setHdgAngleObj(angObj); } double relHeading = symbols[i]->getHeadingDeg() - getHeadingDeg(); angObj->set(-relHeading); phdg->event(UPDATE_VALUE6, angObj); } } } else { // out of range, so clear the graphical component's visibility flag g->setVisibility(false); } } // When the symbol visibility flag is false ... else { Basic::Pair* p = symbols[i]->getSymbolPair(); BasicGL::Graphic* g = (BasicGL::Graphic*)p->object(); g->setVisibility(false); } } } // --- // Let our base class handle the drawing // --- BaseClass::draw(); // --- // now restore the matrices on all of our graphical components // --- for (int i = 0; i < MAX_SYMBOLS; i++) { if (symbols[i] != 0) { Basic::Pair* p = symbols[i]->getSymbolPair(); BasicGL::Graphic* g = (BasicGL::Graphic*)p->object(); if (g->isVisible()) g->lcRestoreMatrix(); } } } }