Exemplo n.º 1
0
//------------------------------------------------------------------------------
// 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;
}
Exemplo n.º 2
0
//------------------------------------------------------------------------------
// 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;
}
Exemplo n.º 3
0
//------------------------------------------------------------------------------
// drawFunc() - Draw the map.
//------------------------------------------------------------------------------
void MapDrawer::drawFunc()
{
    GLdouble ocolor[4];
    // Get our old color 
    glGetDoublev(GL_CURRENT_COLOR, &ocolor[0]);
    
    GLdouble dLeft = 0, dRight = 0, dBottom = 0, dTop = 0, dNear = 0, dFar = 0;
    //double lat = 0, lon = 0;

    // Determine our rotation, if needed.
    if (getDisplay() != 0) getDisplay()->getOrtho(dLeft, dRight, dBottom, dTop, dNear, dFar);

    if (myMap != 0) {
        double rLat = myMap->getReferenceLatDeg();
        double rLon = myMap->getReferenceLonDeg();
        int refZone = myMap->findBestZone(rLat, rLon); 
        if (refZone != -1) {
            // Determine our CENTER tile and pixel position
            myMap->latLonToTileRowColumn(rLat, rLon, originRow[CENTER_PAGER], originCol[CENTER_PAGER], textureRow[CENTER_PAGER], textureCol[CENTER_PAGER], pixelRow[CENTER_PAGER], \
                pixelCol[CENTER_PAGER], pagers[CENTER_PAGER]);
            // Take the distance in nautical miles, and then convert to degrees
            LCreal quickRange = getRange();
            LCreal disDegN = quickRange / 60.0f;
            LCreal disDegE = (LCreal)(quickRange / (60.0 * getCosRefLat()));
            // Get the space (in latitude degrees) between each pixel
            CadrgTocEntry* te = pagers[CENTER_PAGER]->getToc();
            LCreal n = 1, e = 1;
            if (te != 0) {
                n = (LCreal)te->getVertInterval();
                e = (LCreal)te->getHorizInterval();
            }
               
            // OK, so we know how far we want to look out (disDeg, and how far it is per pixel, so we can find 
            // the total amount of pixels by dividing disDeg / x.
            vpHL = disDegN / n;
            vpWL = disDegE / e;

            // Scale our viewport by the ratio of our map page to our actual ortho, to make our background map fit into our range circle
            LCreal rad = getOuterRadius();
            LCreal radRatio = (LCreal)(dTop / rad);
            vpHL *= radRatio;
            vpWL *= radRatio;
            
            // Now stretch and shrink our ortho based on if we are track up
            double newVPHL = vpHL;
            double newVPWL = vpWL;

            // Force our ortho before drawing
            getDisplay()->forceOrtho(-newVPWL, newVPWL,  -newVPHL, newVPHL, -2, 2);

            // Update our current reference zone            
            updateZone(refZone, zones[CENTER_PAGER], CENTER_PAGER);
            
            // Tell our center pager to draw the map
            drawMap(zones[CENTER_PAGER], CENTER_PAGER);

            // Check to see if we need to have zones around us (depending on the range)
            LCreal rngDeg = (quickRange * 2) / 60.0f;
            int tZone = myMap->findBestZone(rLat + rngDeg, rLon); 

            // Now determine if there are other zones to draw
            if (tZone != zones[CENTER_PAGER]) {
                updateZone(tZone, zones[TOP_PAGER], TOP_PAGER);
                myMap->latLonToTileRowColumn(rLat, rLon, originRow[TOP_PAGER], originCol[TOP_PAGER], textureRow[TOP_PAGER], textureCol[TOP_PAGER], pixelRow[TOP_PAGER], \
                pixelCol[TOP_PAGER], pagers[TOP_PAGER]);
                // Draw the map 
                drawMap(zones[TOP_PAGER], TOP_PAGER);
            }
            else pagers[TOP_PAGER]->flushTextures();

            // Set our reference zone.
            myMap->setZone(zones[CENTER_PAGER], pagers[CENTER_PAGER]);
		}
    }   

    // Set our ortho and our color back to it's original state after we draw.
    getDisplay()->forceOrtho(dLeft, dRight, dBottom, dTop, dNear, dFar);
    glColor4dv(ocolor);
}