⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 maps.cpp

📁 给予QT的qps开源最新源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
      actMapList.remove(delmap);
   maps.remove(delmap);
}

MapImage::MapImage(QString & mapInfo, const QString &subdir) : MapBase(mapInfo, subdir)
{
	pixmap = NULL;
}

MapImage::MapImage():MapBase()
{
	pixmap = NULL;
}

MapImage::~MapImage()
{
	if(pixmap != NULL)
		unload();
}

void MapImage::setLimits()
{
	Position limit;
	calcPos(limit, 0, 0);
	limitNorthWest.lat = limit.lat;
	limitNorthWest.lon = limit.lon;
	calcPos(limit, mapSizeX, mapSizeY);
	limitSouthEast.lat = limit.lat;
	limitSouthEast.lon = limit.lon;
}

bool MapImage::load()
{
   if (pixmap != NULL && !pixmap->isNull())
      return true; // already loaded
   
   QString filename = mapSelector->mapPathStr();
	filename.append("/");
	filename.append(name());
	pixmap = new QPixmap(filename);
	if (pixmap->isNull())  // error reading map
	{
		unload();
		return false;
	}
	else
		return true;
}

void MapImage::unload()
{
	if (pixmap != NULL)
      delete pixmap;
	pixmap = NULL;
}

void MapImage::draw(QPixmap *viewer, const Position & pos)
{
	double xc, yc;
	
   // load the image
   if (!mapSelector->loadMapImage(this))
	   // load failed
	   return;

   calcxy(&xc, &yc, pos);

	int dx, dy, sx, sy, sw, sh;

   sw = viewer->width();
   if (sw/2 > (int) xc) {
      sx = 0;
      dx = sw/2 - (int)xc; 
      sw = sw - dx;
   }
   else {
      dx = 0;
      sx = (int)xc - sw/2;
   }
	if (sx+sw > pixmap->width())
		sw = pixmap->width() - sx;

   sh = viewer->height();
   if (sh/2 > (int) yc) {
      sy = 0;
      dy = sh/2 - (int)yc; 
      sh = sh - dy;
   }
   else {
      dy = 0;
      sy = (int)yc - sh/2;
   }
	if (sy+sh > pixmap->height())
		sh = pixmap->height() - sy;

   bitBlt(viewer, dx, dy, pixmap, sx, sy, sw, sh);
}

void MapImage::addTrack(Track *track, QColor &, int)
{
	// draw the track in the current map
	QPainter painter;

    if (pixmap && !pixmap->isNull())
	{
		painter.begin(pixmap);

		track->drawTrack(&painter,this,0,0,
			pixmap->width(), pixmap->height());

		painter.end();
	}

}

MapLin::MapLin(QString & mapInfo, const QString &subdir) : MapImage(mapInfo, subdir)
{
   // read additional map info
   QTextIStream mapIStream(&mapInfo);
   mapIStream >> mapName >> scale >> mapSizeX >> mapSizeY;
   mapIStream >> pos1.lon >> pos1.lat >> x1 >> y1
      >> pos2.lon >> pos2.lat >> x2 >> y2;
   projection = "LINEAR";
   // FIXME: why check only longitude?
   checkLg(deg2rad(pos1.lon));
   checkLg(deg2rad(pos2.lon));

   setLimits();
}

bool MapLin::calcxy(double * x, double * y, const Position & pos)
{
   *x =  x1 + (checkLg(deg2rad(pos.lon - pos1.lon)) * (x2 - x1)
         / checkLg(deg2rad(pos2.lon - pos1.lon)));
   *y = y1 + ((deg2rad(pos.lat - pos1.lat)) * (y2 - y1)
         / deg2rad(pos2.lat - pos1.lat));
   if ( (*x < 0) || (*x >= mapSizeX) || (*y < 0) || (*y >= mapSizeY) ) {
      return false;
   } else {
      return true;
   }
}

bool MapLin::calcPos(Position & pos, double x, double y)
{
   double latr = deg2rad(pos1.lat)
      + ((y - y1) * (deg2rad(pos2.lat - pos1.lat)) / (y2 - y1));
   double lonr =  checkLg(deg2rad(pos1.lon) + ((x - x1)
            * checkLg(deg2rad(pos2.lon - pos1.lon)) / (x2 - x1)));
   pos.lat = rad2deg(latr);
   pos.lon = rad2deg(lonr);
   // FIXME: all calcPos methods always return true?
   return true;
}

QString MapLin::getInfo()
{
   QString info;
   info = tr("Linear Projection, SCALE 1:%1,\nLat: %2 to %3, Lon: %4 to %5")
      .arg(scale)
      .arg(pos1.lat).arg(pos2.lat)
      .arg(pos1.lon).arg(pos2.lon);
   return info;
}

QString MapLin::getParameterStr()
{
   QString param;
   /*    param = tr("%1 %2 %3 %4 %5 %6 %7 %8 %9")
         .arg(projection).arg(name).arg(scale).arg(mapSizeX).arg(mapSizeY)
         .arg(longitude1*rad2deg).arg(latitude1*rad2deg).arg(x1).arg(y1);
         param.append(tr(" %1 %2 %3 %4")
         .arg(longitude2*rad2deg).arg(latitude2*rad2deg).arg(x2).arg(y2));
    */
   QTextOStream os(&param);
   os.precision(10);
   os << projection << " " << name() << " " << scale << " " << mapSizeX
      << " " << mapSizeY << " " << pos1.lon << " " << pos1.lat << " " << 
      x1 << " " << y1 << " " << pos2.lon << " " << pos2.lat << " " << 
      x2 << " " << y2;

   return param;
}

MapCEA::MapCEA(QString & mapInfo, const QString &subdir) : MapImage(mapInfo, subdir)
{
   // read additional map info
   QTextIStream mapIStream(&mapInfo);
   mapIStream >> mapName >> scale >> mapSizeX >> mapSizeY;
   Position pos1, pos2;
   mapIStream >> pos1.lon >> pos1.lat >> x1 >> y1
      >> pos2.lon >> pos2.lat >> x2 >> y2;

   projection = "CEA";

   // precalc
   xlon1 = checkLg(deg2rad(pos1.lon));
   ylat1 = sin(deg2rad(pos1.lat));
   xlon2 = checkLg(deg2rad(pos2.lon));
   ylat2 = sin(deg2rad(pos2.lat));

	setLimits();
}

bool MapCEA::calcxy(double * x, double * y, const Position & pos)
{
   double xt = deg2rad(pos.lon);
   double yt = sin(deg2rad(pos.lat));
   *x = x1 + (checkLg(xt - xlon1) * (x2 - x1) / checkLg(xlon2 - xlon1));
   *y = y1 + ((yt - ylat1) * (y2 - y1) / (ylat2 - ylat1));
   if ( (*x < 0) || (*x >= mapSizeX) || (*y < 0) || (*y >= mapSizeY) ) {
      return false;
   } else {
      return true;
   }
}

bool MapCEA::calcPos(Position & pos, double x, double y)
{
   double xt = xlon1 + ((x - x1) * checkLg(xlon2 - xlon1) / (x2 - x1));
   double yt = ylat1 + ((y - y1) * (ylat2 - ylat1) / (y2 - y1));
   pos.lat = rad2deg(asin(yt));
   pos.lon = rad2deg(checkLg(xt));
   return true;
}

QString MapCEA::getInfo()
{
   QString info;
   Position pos1, pos2;
   calcPos(pos1, x1, y1);
   calcPos(pos1, x1, y1);
   info = tr("Cylindrical Equal Area Projection, SCALE 1:%1,\n"
         "Lat: %2 to %3, Lon: %4 to %5")
      .arg(scale)
      .arg(pos1.lat).arg(pos2.lat)
      .arg(pos1.lon).arg(pos2.lon);
   return info;
}

QString MapCEA::getParameterStr()
{
   QString param;
   Position pos1, pos2;
   calcPos(pos1, x1, y1);
   calcPos(pos1, x1, y1);
   /*
      param = tr("%1 %2 %3 %4 %5 %6 %7 %8 %9")
      .arg(projection).arg(name).arg(scale).arg(mapSizeX).arg(mapSizeY)
      .arg(longitude1*rad2deg).arg(latitude1*rad2deg).arg(x1).arg(y1);
      param.append(tr(" %1 %2 %3 %4")
      .arg(longitude2*rad2deg).arg(latitude2*rad2deg).arg(x2).arg(y2));
    */
   QTextOStream os(&param);
   os.precision(10);
   os << projection << " " << name() << " " << scale << " " << mapSizeX
      << " " << mapSizeY << " " << pos1.lon << " " << pos1.lat << " " << 
      x1 << " " << y1 << " " << pos2.lon << " " << pos2.lat << " " << 
      x2 << " " << y2;

   return param;
}

MapUTM::MapUTM(QString & mapInfo, bool utmCoord, const QString &subdir) : MapImage(mapInfo, subdir)
{
   // read additional map info
   Position pos1, pos2;
   QTextIStream mapIStream(&mapInfo);
   mapIStream >> mapName >> scale >> mapSizeX >> mapSizeY;
   if ( utmCoord ) {
      universal = true;
      mapIStream >> utmZone >> utmNorthing1 >> utmEasting1 >> x1 >> y1
         >> utmNorthing2 >> utmEasting2 >> x2 >> y2;
      UTMtoLL(utmNorthing1, utmEasting1, utmZone, pos1, stdLon );
      UTMtoLL(utmNorthing2, utmEasting2, utmZone, pos2, stdLon );
      projection = "UTM";
   } else {
      universal = false;
      mapIStream >> pos1.lon >> pos1.lat >> x1 >> y1
         >> pos2.lon >> pos2.lat >> x2 >> y2 >> stdLon;
      projection = "TM";
   }

   stdLon = deg2rad(stdLon);

   // precalc
   xlon1 = 0.5 * atanh(cos(deg2rad(pos1.lat))
         * sin(checkLg(deg2rad(pos1.lon) - stdLon)));
   ylat1 = atan(tan(deg2rad(pos1.lat))
         / cos(checkLg(deg2rad(pos1.lon) - stdLon)));
   xlon2 = 0.5 * atanh(cos(deg2rad(pos2.lat))
         * sin(checkLg(deg2rad(pos2.lon) - stdLon)));
   ylat2 = atan(tan(deg2rad(pos2.lat))
         / cos(checkLg(deg2rad(pos2.lon) - stdLon)));

	setLimits();
}

MapUTM::MapUTM(bool utmCoord) : MapImage()
{
   if ( utmCoord ) {
      universal = true;
      projection = "UTM";
   } else {
      universal = false;
      projection = "TM";
   }

	setLimits();
}

bool MapUTM::calcxy(double * x, double * y, const Position & pos)
{
   double xt = 0.5 * atanh(cos(deg2rad(pos.lat))
         * sin(checkLg(deg2rad(pos.lon) - stdLon)));
   double yt = atan(tan(deg2rad(pos.lat))
         / cos(checkLg(deg2rad(pos.lon) - stdLon)));
   *x = x1 + (checkLg(xt - xlon1) * (x2 - x1) / checkLg(xlon2 - xlon1));
   *y = y1 + ((yt - ylat1) * (y2 - y1) / (ylat2 - ylat1));
   if ( (*x < 0) || (*x >= mapSizeX) || (*y < 0) || (*y >= mapSizeY) ) {
      return false;
   } else {
      return true;
   }
}

bool MapUTM::calcPos(Position & pos, double x, double y)
{
   double xt = xlon1 + ((x - x1) * checkLg(xlon2 - xlon1) / (x2 - x1));
   double yt = ylat1 + ((y - y1) * (ylat2 - ylat1) / (y2 - y1));
   pos.lat = rad2deg(asin(sin(yt) / cosh(xt)));
   pos.lon = rad2deg(checkLg(stdLon + atan(sinh(xt) / cos(yt))));
   return true;
}

void MapUTM::UTMtoLL(double UTMNorthing, double UTMEasting, QString UTMZone,
      Position & pos, double & stdLon )
{
   //converts UTM coords to lat/long.  Equations from USGS Bulletin 1532
   //East Longitudes are positive, West longitudes are negative.
   //North latitudes are positive, South latitudes are negative
   //pos is in decimal degrees.
   //Written by Chuck Gantz- chuck.gantz@globalstar.com

   static const double k0 = 0.9996;
   static const double a = 6378137;
   static const double eccSquared = 0.00669438;

   double e1 = (1 - sqrt(1 - eccSquared)) / (1 + sqrt(1 - eccSquared));
   int NorthernHemisphere; //1 for northern hemispher, 0 for southern

   double x = UTMEasting - 500000.0; //remove 500,000 meter offset for longitude
   double y = UTMNorthing;

   char * ZoneLetter;
   int ZoneNumber = strtoul(UTMZone.latin1(), &ZoneLetter, 10);
   if ( (*ZoneLetter - 'N') >= 0 ) {
      NorthernHemisphere = 1;//point is in northern hemisphere
   } else {
      NorthernHemisphere = 0;//point is in southern hemisphere
      y -= 10000000.0;//remove 10,000,000 meter offset used for southern hemisphere
   }

   double eccPrimeSquared = eccSquared / (1 - eccSquared);

   double M = y / k0;
   double mu = M / (a * (1 - eccSquared/4 - 3 * square(eccSquared) / 64
            - 5 * std::pow(eccSquared, 3) / 256));

   // FIXME: double check the following two lines
   double phi1Rad = mu + (3 * e1 / 2 - 27 * std::pow(e1, 3) / 32) * sin(2 * mu)
      + (21 * square(e1) / 16 - 55 * std::pow(e1, 4) / 32) * sin(4 * mu)
      + (151 * std::pow(e1, 3) / 96) * sin(6 * mu);
//   double phi1 = deg2rad(phi1Rad);

   double N1 = a / sqrt(1 - eccSquared * square(sin(phi1Rad)));
   double T1 = square(tan(phi1Rad));
   double C1 = eccPrimeSquared * square(cos(phi1Rad));
   double R1 = a * (1 - eccSquared)
      / std::pow(1 - eccSquared * square(sin(phi1Rad)), 1.5);
   double D = x / (N1 * k0);

   pos.lat = rad2deg(phi1Rad - (N1 * tan(phi1Rad) / R1) * (square(D) / 2
            - (5 + 3 * T1 + 10 * C1 - 4 * square(C1) - 9 * eccPrimeSquared)
            * std::pow(D, 4) / 24 + (61 + 90 * T1 + 298 * C1 + 45 * square(T1)
               - 252  * eccPrimeSquared - 3 * square(C1)) * std::pow(D, 6)
            / 720));

   // default value
   double LonOrigin = (ZoneNumber - 1) * 6 - 180 + 3;  //+3 puts origin in middle of zone
   // check for need of special value
   switch ( ZoneNumber ) {
      case 31:
         if ( pos.lat >= 72.0 && pos.lat < 84.0 ) {
            LonOrigin = 4.5; // special case Svalbard
         } else if ( pos.lat >= 56.0 && pos.lat < 64.0 ) {
            LonOrigin = 1.5; // special case southwest Norway
         }
         break;
      case 32:
         if ( pos.lat >= 56.0 && pos.lat < 64.0 ) {
            LonOrigin = 7.5; // special case southwest Norway
         }
         break;
      case 33:
         if ( pos.lat >= 72.0 && pos.lat < 84.0 ) {
            LonOrigin = 15; // special case Svalbard
         }
         break;
      case 35:
         if ( pos.lat >= 72.0 && pos.lat < 84.0 ) {
            LonOrigin = 27; // special case Svalbard
         }
         break;
      case 37:
         if ( pos.lat >= 72.0 && pos.lat < 84.0 ) {
            LonOrigin = 37.5; // special case Svalbard
         }
         break;
   }
   stdLon = LonOrigin;

   pos.lon = LonOrigin + rad2deg((D -(1 + 2 * T1 + C1) * std::pow(D, 3) / 6
            + (5 - 2 * C1 + 28 * T1 - 3 * square(C1) + 8 * eccPrimeSquared
               + 24 * square(T1)) * std::pow(D, 5) / 120) / cos(phi1Rad));
}

QString MapUTM::getInfo()
{
   QString info;
   Position pos1, pos2;
   calcPos(pos1, x1, y1);
   calcPos(pos1, x1, y1);
   if ( universal ) {
      info = tr("Universal Transverse Mercator Projection, "
            "SCALE 1:%1,\nLat: %2 to %3, Lon: %4 to %5\n"
            "std.Longitude: %6")
         .arg(scale)
         .arg(pos1.lat).arg(pos2.lat)
         .arg(pos1.lon).arg(pos2.lon)
         .arg(rad2deg(stdLon));
   } else {
      info = tr("Transverse Mercator Projection, "
            "SCALE 1:%1,\nLat: %2 to %3, Lon: %4 to %5\n"
            "std.Longitude: %6")
         .arg(scale)
         .arg(pos1.lat).arg(pos2.lat)
         .arg(pos1.lon).arg(pos2.lon)
         .arg(rad2deg(stdLon));
   }
   return info;
}

QString MapUTM::getParameterStr()
{
   QString param;
   if ( universal ) {
      /*        param = tr("%1 %2 %3 %4 %5 %6 %7 %8 %9")
                .arg(projection).arg(name).arg(scale).arg(mapSizeX).arg(mapSizeY)
                .arg(utmZone).arg(utmNorthing1).arg(utmEasting1).arg(x1);
                param.append(tr(" %1 %2 %3 %4 %5")
                .arg(y1).arg(utmNorthing2).arg(utmEasting2).arg(x2).arg(y2));
       */
      QTextOStream os(&param);
      os.precision(10);
      os << projection << " " << name() << " " << scale << " "
         <<  mapSizeX  << " " << mapSizeY << " " << utmZone << " "
         << utmNorthing1 << " " << utmEasting1 << " " << x1 << " " << y1 << " "
         << utmNorthing2 << " " << utmEasting2 << " " << x2 << " " << y2;
      return param;
   } else {
      /*        param = tr("%1 %2 %3 %4 %5 %6 %7 %8 %9")
                .arg(projection).arg(name).arg(scale).arg(mapSizeX).arg(mapSizeY)
                .arg(longitude1*rad2deg).arg(latitude1*rad2deg).arg(x1).arg(y1);
                param.append(tr(" %1 %2 %3 %4 %5")
                .arg(longitude2*rad2deg).arg(latitude2*rad2deg).arg(x2).arg(y2).arg(stdLon*rad2deg));
       */
      Position pos1, pos2;
      calcPos(pos1, x1, y1);
      calcPos(pos1, x1, y1);
      QTextOStream os(&param);
      os.precision(10);
      os << projection << " " << name() << " " << scale << " " << 
         mapSizeX << " " << mapSizeY << " " << pos1.lon << " " << pos1.lat
         << " " << x1 << " " << y1 << " " << pos2.lon << " " << pos2.lat 
         << " " << x2 << " " << y2 << " " << rad2deg(stdLon);
      return param;
   }
}

MapMercator::MapMercator(QString & mapInfo, const QString &subdir) : MapImage(mapInfo, subdir)
{
   // read additional map info
   QTextIStream mapIStream(&mapInfo);
   mapIStream >> mapName >> scale >> mapSizeX >> mapSizeY;
   Position pos1, pos2;
   mapIStream >> pos1.lon >> pos1.lat >> x1 >> y1
      >> pos2.lon >> pos2.lat >> x2 >> y2;

   projection = "MERCATOR";

   // precalc
   xlon1 = checkLg(deg2rad(pos1.lon));
   //ylat1 = log(tan(latitude1)+1.0/cos(latitude1));
   ylat1 = atanh(sin(deg2rad(pos1.lat)));
   xlon2 = checkLg(deg2rad(pos2.lon));
   //ylat2 = log(tan(latitude2)+1.0/cos(latitude2));
   ylat2 = atanh(sin(deg2rad(pos2.lat)));

	setLimits();
}

bool MapMercator::calcxy(double * x, double * y, const Position & pos)
{
   double xt = deg2rad(pos.lon);
   //yt = log(tan(lat)+1.0/cos(lat));
   double yt = atanh(sin(deg2rad(pos.lat)));
   *x = x1 + (checkLg(xt - xlon1) * (x2 - x1) / checkLg(xlon2 - xlon1));
   *y = y1 + ((yt - ylat1) * (y2 - y1) / (ylat2 - ylat1) );
   if ( (*x < 0) || (*x >= mapSizeX) || (*y < 0) || (*y >= mapSizeY) ) {
      return false;
   } else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -