//------------------------------------------------------------------------------ // 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; } }
//------------------------------------------------------------------------------ // converts screen to lat/lon coordinates //------------------------------------------------------------------------------ bool MapPage::screen2LatLon(const LCreal x, const LCreal y, double* const lat, double* const lon) const { bool ok = false; const double scale = getScale(); const double cosLat = getCosRefLat(); if (lat != nullptr && lon != nullptr && scale != 0 && cosLat != 0) { // buffer the inputs double screenX = x; double screenY = y; // Adjust for the decentered displayment if ( !getCentered() ) screenY -= getDisplacement(); // Scale from screen (inches) to A/C (NM) and // transpose the X and Y from screen to A/C const double acX = screenY/scale; const double acY = screenX/scale; // Rotate A/C to NED double earthX = 0.0; double earthY = 0.0; if (getNorthUp()) { earthX = acX; earthY = acY; } else { earthX = (acX * headingCos) - (acY * headingSin); earthY = (acX * headingSin) + (acY * headingCos); } // Convert nautical miles (NED) from ref point to lat/lon *lat = (earthX/60.0) + getReferenceLatDeg(); *lon = (earthY/(60.0*cosLat)) + getReferenceLonDeg(); ok = true; } return ok; }
//------------------------------------------------------------------------------ // converts lat/lon to screen coordinates //------------------------------------------------------------------------------ bool MapPage::latLon2Screen(const double lat, const double lon, LCreal* const x, LCreal* const y) const { bool ok = false; if (x != nullptr && y != nullptr) { // Convert to nautical miles (NED) centered on ownship const double earthX = ((lat - getReferenceLatDeg()) * 60.0); const double earthY = ((lon - getReferenceLonDeg()) * 60.0 * getCosRefLat()); // Rotate to aircraft coordinates double acX = 0; double acY = 0; if (getNorthUp()) { acX = earthX; acY = earthY; } else { acX = (earthX * headingCos) + (earthY * headingSin); acY = -(earthX * headingSin) + (earthY * headingCos); } // Scale from nautical miles to inches and // transpose the X and Y from A/C to screen double screenY = acX * getScale(); const double screenX = acY * getScale(); // Adjust for the decentered displayment if ( !getCentered() ) screenY += getDisplacement(); *x = static_cast<LCreal>(screenX); *y = static_cast<LCreal>(screenY); ok = true; } return ok; }
// ----------------------------------------------------------------------- // drawMap() - Called from draw fun, it tells our specific map to draw. // ----------------------------------------------------------------------- void MapDrawer::drawMap(const int zone, const int idx) { if (myMap != 0 && pagers[idx] != 0 && showMap && getDisplay() != 0){ // Update the tiles for the pager pagers[idx]->updateTextures(textureRow[idx], textureCol[idx]); // Set up for drawing lcColor3(mapIntensity, mapIntensity, mapIntensity); glPushMatrix(); // Not centered, move the whole map down the displacement value. if (!getCentered()) { LCreal dis = getOuterRadius(); //LCreal scale = getScale(); LCreal myScale = vpHL / dis; glTranslatef(0, GLfloat(getDisplacement() * myScale), 0); } glTranslatef(0, 0, -0.1f); sinAng = 0.0f; cosAng = 1.0f; // Set the scale, if not the CENTER_PAGER if (idx != CENTER_PAGER) determineScaling(idx); bool nu = getNorthUp(); if (!nu) { GLfloat hdg = (GLfloat) getHeadingDeg(); glRotatef(hdg, 0.0f, 0.0f, 1.0f); sinAng = (LCreal)lcSin(hdg * (LCreal)Basic::Angle::D2RCC); cosAng = (LCreal)lcCos(hdg * (LCreal)Basic::Angle::D2RCC); } // Translate down the pixels first float transPixelX = -pixelCol[idx] * scalingEast[idx]; float transPixelY = pixelRow[idx] * scalingNorth[idx]; // Translate to the next tile glTranslatef(transPixelX, transPixelY, 0.0f); TextureTable& tbl = pagers[idx]->getTable(); int si = tbl.getLowerBoundIndex(); int i1 = si; int i = 0; int lb = 0, ub = 0; // Enable texturing glEnable(GL_TEXTURE_2D); lb = tbl.getLowerBoundIndex(); ub = tbl.getUpperBoundIndex(); for (i = lb; i <= ub; i++) { int j1 = si; for (int j = lb; j <= ub; j++) { drawTexture(i1, j1, idx); j1++; } i1++; } glDisable(GL_TEXTURE_2D); // Done drawing tiles, now draw grid, if selected to draw. if (drawGrid) { i1 = si; for (i = lb; i <= ub; i++) { int j1 = si; for (int j = lb; j <= ub; j++) { goDrawGrid(i1, j1, idx); j1++; } i1++; } } glPopMatrix(); } }