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

📄 maps.cpp

📁 给予QT的qps开源最新源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
      return true;
   }
}

bool MapMercator::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(atan(sinh(yt)));
   pos.lon = rad2deg(checkLg(xt));
   return true;
}

QString MapMercator::getInfo()
{
   Position pos1, pos2;
   calcPos(pos1, x1, y1);
   calcPos(pos1, x1, y1);
   QString info = tr("Mercator 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 MapMercator::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;
}

MapLambert::MapLambert(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
      >> std1Lat >> std2Lat  >> refLon;

   std1Lat = deg2rad(std1Lat);
   std2Lat = deg2rad(std2Lat);
   refLon = deg2rad(refLon);
   projection = "LAMBERT";

   // precalc
   n = log(cos(std1Lat) * (1 / cos(std2Lat)))
      / log(tan(PI_1_4 + std2Lat / 2) * -tan(PI_3_4 + std1Lat / 2));
   F = (cos(n) * pow(tan(PI_1_4 + std1Lat / 2), n)) / n;
   p0 = F * pow((-tan(PI_3_4)), n);
   double p = F * pow(-tan(PI_3_4 + deg2rad(pos1.lat) / 2), n);
   xlon1 = p * sin(n * (deg2rad(pos1.lon) - refLon));
   ylat1 = p0 - p * cos(n * (deg2rad(pos1.lon) - refLon));
   p = F * pow(-tan(PI_3_4 + deg2rad(pos2.lat) / 2), n);
   xlon2 = p * sin(n * (deg2rad(pos2.lon) - refLon));
   ylat2 = p0 - p * cos(n * (deg2rad(pos2.lon) - refLon));
   if ( n > 0 ) {
      n_sign = 1.0;
   } else if ( n == 0 ) {
      n_sign = 0.0;
   } else {
      n_sign = -1.0;
   }

	setLimits();
}

bool MapLambert::calcxy(double * x, double * y, const Position & pos)
{
   double p = F * pow(-tan(PI_3_4 + deg2rad(pos.lat) / 2), n);
   double xt = p * sin(n * (deg2rad(pos.lon) - refLon));
   double yt = p0 - p * cos(n * (deg2rad(pos.lon) - refLon));
   *x = x1 + ((xt - xlon1) * (x2 - x1) / (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 MapLambert::calcPos(Position & pos, double x, double y)
{
   double xt = xlon1 + ((x - x1) * (xlon2 - xlon1) / (x2 - x1));
   double yt = ylat1 + ((y - y1) * (ylat2 - ylat1) / (y2 - y1));
   double p = n_sign * sqrt(xt * xt + (p0 - yt) * (p0 - yt));
   double s = atan(xt / (p0 - yt));
   pos.lat = rad2deg(2.0 * atan(pow(F / p, 1.0 / n)) - PI_1_2);
   pos.lon = rad2deg(refLon + (s / n));
   return true;
}

QString MapLambert::getInfo()
{
   QString info;
   Position pos1, pos2;
   calcPos(pos1, x1, y1);
   calcPos(pos1, x1, y1);
   info = tr("Lambert Projection, SCALE 1:%1,\nLat: %2 to %3, Lon: %4 to %5\n"
         "std.Latitudes: %6 %7, ref longitude %8")
      .arg(scale)
      .arg(pos1.lat).arg(pos2.lat)
      .arg(pos1.lon).arg(pos2.lon)
      .arg(rad2deg(std1Lat)).arg(rad2deg(std2Lat)).arg(rad2deg(refLon));
   return info;
}

QString MapLambert::getParameterStr()
{
   QString param;
   Position pos1, pos2;
   calcPos(pos1, x1, y1);
   calcPos(pos1, x1, y1);
   /*    param = tr("%1 %2 %3 %4 %5 %6 %7 %8")
         .arg(projection).arg(name).arg(scale).arg(mapSizeX).arg(mapSizeY)
         .arg(longitude1*rad2deg).arg(latitude1*rad2deg).arg(x1);
         param.append(tr(" %1 %2 %3 %4 %5 %6 %7 %8")
         .arg(y1).arg(longitude2*rad2deg).arg(latitude2*rad2deg).arg(x2).arg(y2)
         .arg(std1Lat*rad2deg).arg(std2Lat*rad2deg).arg(refLon*rad2deg));
    */
   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(std1Lat) << " " << rad2deg(std2Lat)
      << " " << rad2deg(refLon);
   return param;
}

// create static Ra
double MapFritz::Ra[201] = {0};

MapFritz::MapFritz(QString & mapInfo, const QString &subdir) : MapImage(mapInfo, subdir)
{
   pixelfact = 10000 / 2817.947378;
   projection = "FRITZ";
   /*
    * Build array for earth radii
    */
   if ( !Ra[0] ) {
      for (int i = -100; i <= 100; ++i) {
         Ra[i + 100] = calcR(i);
      }
   }

   // read additional map info
   QTextIStream mapIStream(&mapInfo);
   mapIStream >> mapName >> scale >> mapSizeX >> mapSizeY;
   mapIStream >> center.lat >> center.lon;

   mapSizeX2 = mapSizeX / 2;
   mapSizeY2 = mapSizeY / 2;

	setLimits();
}

bool MapFritz::calcxy(double * x, double * y, const Position & pos)
{
   zero.lat = center.lat;
   zero.lon = center.lon;
   pixelfact = scale / PIXELFACT;
   if ( pixelfact == 0 ) {
      return false;
   }
   double argr = deg2rad(Ra[(int)(100 + deg2rad(pos.lat))]);
   *x = argr * cos(deg2rad(pos.lat))
      * deg2rad(pos.lon - zero.lon);
   *y = argr * deg2rad(pos.lat - zero.lat);
   double dif = argr * (1 - cos(deg2rad(pos.lon - zero.lon)));
   *y += dif / 1.85;
   *x /= pixelfact;
   *y /= pixelfact;
   *x += mapSizeX2;
   *y = mapSizeY2 - *y;
   if ( (*x < 0) || (*x >= mapSizeX) || (*y < 0) || (*y >= mapSizeY) ) {
      return false;
   } else {
      return true;
   }
}

bool MapFritz::calcPos(Position & pos, double x, double y)
{
   // FIXME: double check the deg2rad, rad2deg conversions
   // FIXME: optimize equations/iteration
   zero = center;
   pixelfact = scale / PIXELFACT;
   x = (mapSizeX2 - x) * pixelfact;
   y = (y - mapSizeY2) * pixelfact;
   double latr = deg2rad(center.lat);
   int i = 0;
   double idxr;
   do {
      idxr = latr;
      latr = deg2rad(zero.lat) - y / deg2rad(Ra[(int)(100 + idxr)]);
      ++i;
   } while((fabs(latr - idxr) >= 1.0) && (i < 4));
   latr = deg2rad(zero.lat) - y / deg2rad(Ra[(int)(100 + idxr)]);
   // double lonr = deg2rad(zero.lon) - x
   //   / (deg2rad(Ra[(int)(100 + latr)]) * cos(deg2rad(latr)));
   double lonr = deg2rad(zero.lon) - x
      / (deg2rad(Ra[(int)(100 + latr)]) * cos(latr));
   // double dif = latr * (1 - (cos((deg2rad(fabs(lonr - zero.lon))))));
   double diff = latr * (1 - cos(fabs(lonr - deg2rad(zero.lon))));
   latr -= diff / 1.5;
   // lonr = zero.lon - x / (deg2rad(Ra[(int)(100 + latr)]) * cos(deg2rad(latr)));
   lonr = deg2rad(zero.lon) - x / (deg2rad(Ra[(int)(100 + latr)]) * cos(latr));
   pos.lat = rad2deg(latr);
   pos.lon = rad2deg(lonr);
   return true;
}

QString MapFritz::getInfo()
{
   QString info = tr("Fritz Projection, "
         "SCALE 1:%1,\nCenter Lat: %2, Center Lon: %3")
      .arg(scale).arg(center.lat).arg(center.lon);
   return info;
}

QString MapFritz::getParameterStr()
{
   QString param;
   /*   param = tr("%1 %2 %3 %4 %5 %6 %7")
        .arg(projection).arg(name).arg(scale).arg(mapSizeX).arg(mapSizeY)
        .arg(center_latitude).arg(center_longitude);*/
   QTextOStream os(&param);
   os.precision(10);
   os << projection << " " << name() << " " << scale
      << " " <<  mapSizeX << " " << mapSizeY
      << " " << center.lat << " " << center.lon;

   return param;
}

double MapFritz::calcR(double lat)
{
   static const double a = 6378.137;
   static const double e2 = square(0.081082);
   /*
    * the radius of curvature of an ellipsoidal Earth in the plane of the
    * meridian is given by
    *
    * R' = a * (1 - e^2) / (1 - e^2 * (sin(lat))^2)^(3/2)
    *
    * where a is the equatorial radius, b is the polar radius, and e is
    * the eccentricity of the ellipsoid = sqrt(1 - b^2/a^2)
    *
    * a = 6378 km (3963 mi) Equatorial radius (surface to center distance)
    * b = 6356.752 km (3950 mi) Polar radius (surface to center distance) e
    * = 0.081082 Eccentricity
    */

   double sc = sin(deg2rad(lat));
   double x = a * (1.0 - e2);
   double z = 1.0 - e2 * square(sc);
   double y = std::pow(z, 1.5);
   return (x / y) * 1000.0; // R
}

int QMapVector::compareItems( Item s1, Item s2 )
{
   MapBase *m1 = (MapBase *)s1;
   MapBase *m2 = (MapBase *)s2;

   if (m1->limitNorthWest.lat > m2->limitNorthWest.lat)
      return -1;
   else if (m1->limitNorthWest.lat < m2->limitNorthWest.lat)
      return 1;
   else {
      if (m1->limitSouthEast.lon < m2->limitSouthEast.lon)
         return -1;
      else if (m1->limitSouthEast.lon > m2->limitSouthEast.lon)
         return 1;
      else
         return 0;
   }
   return 0;
}

MapTiled::MapTiled( QString & mapInfo, const QString &subdir ) : MapBase(mapInfo, subdir)
{
QTime medidor;
int contador = 0;
medidor.start();
   projection = "TILED";

   QTextIStream mapIStream(&mapInfo);
   mapIStream >> mapName >> scale >> mapSizeX >> mapSizeY;

   tileSizeX = mapSizeX;
   tileSizeY = mapSizeY;

   limitNorthWest.lat = -90;
   limitSouthEast.lat = 90;
   limitNorthWest.lon = 90;
   limitSouthEast.lon = -90;

   // read maps
   QString filename(mapSelector->mapPathStr());
   filename.append("/");
   filename.append(name());
	QFile mapFile(filename);
   int iMap = 0;
   MapBase *map;
   maps.resize(tileSizeX*tileSizeY);
	if ( mapFile.open(IO_ReadOnly) ) {
      QTextStream t( &mapFile );
	   QString pro;
	   QString mapInfo;
      const QStringList& list = QStringList::split('\n', t.read());
      mapFile.close();
      QStringList::ConstIterator it;
      for(it=list.begin(); it!=list.end(); ++it) {
         const QString& s = *it;
         int sp = s.find(' ');
         pro = s.left(sp);
         mapInfo = s.right(s.length()-sp-1);
         map = MapBase::newMap(pro, mapInfo, subdir);
contador++;
		   // add the map
         if (map) {
            maps.insert(iMap++, map);

            if (map->limitNorthWest.lat > limitNorthWest.lat)
               limitNorthWest.lat = map->limitNorthWest.lat;
            if (map->limitSouthEast.lat < limitSouthEast.lat)
               limitSouthEast.lat = map->limitSouthEast.lat;
            if (map->limitNorthWest.lon < limitNorthWest.lon)
               limitNorthWest.lon = map->limitNorthWest.lon;
            if (map->limitSouthEast.lon > limitSouthEast.lon)
               limitSouthEast.lon = map->limitSouthEast.lon;
         }
      }
      ASSERT(tileSizeX*tileSizeY==iMap);
		
      // order the maps
      maps.sort();

      // calculate virtual image size and tiles limits (X / Lon)
      mapLimitsX.resize(tileSizeX);
      iMap = (tileSizeY/2)*tileSizeX; // middle row
      map = maps[iMap];
      mapSizeX = 0;
      Position lastLimit;
      lastLimit.lon = map->limitNorthWest.lon; // east
      lastLimit.lat = map->limitNorthWest.lat; // south
      double lx, ly;
      for (int i = 0; i < tileSizeX ; i++) {
         map = maps[iMap];
         iMap += 1;
         map->calcxy(&lx, &ly, lastLimit);
         mapLimitsX[i] = mapSizeX  - (int) rint(lx);
         mapSizeX = mapLimitsX[i] + map->mapSizeX;
         lastLimit = map->limitSouthEast;
      }

      // calculate virtual image size and tiles limits (Y / Lat)
      mapLimitsY.resize(tileSizeY);
      iMap = tileSizeX/2;
      map = maps[iMap];
      mapSizeY = 0;
      lastLimit = map->limitNorthWest; 
      for (int i = 0; i < tileSizeY ; i++) {
         map = maps[iMap];
         iMap += tileSizeX;
         map->calcxy(&lx, &ly, lastLimit);
         mapLimitsY[i] = mapSizeY  - (int) rint(ly);
         mapSizeY = mapLimitsY[i] + map->mapSizeY;
         lastLimit = map->limitSouthEast;
      }
   }
}

QString MapTiled::getInfo()
{
   QString info = tr("Tiled Map, "
         "SCALE 1:%1, %2x%3 tiles")
      .arg(scale).arg(tileSizeX).arg(tileSizeY);
   return info;
}

QString MapTiled::getParameterStr()
{
   QString param;
   /*   param = tr("%1 %2 %3 %4 %5 %6 %7")
        .arg(projection).arg(name).arg(scale).arg(mapSizeX).arg(mapSizeY)
        .arg(center_latitude).arg(center_longitude);*/
   QTextOStream os(&param);
   os.precision(10);
   os << projection << " " << name() << " " << scale
      << " " <<  tileSizeX << " " << tileSizeY;

   return param;
}

MapTiled::~MapTiled()
{
	maps.setAutoDelete(TRUE);
	maps.clear();
}

bool MapTiled::calcxy( double * x, double * y, const Position & pos )
{
   int tileX;
   int tileY;

   tileX = (int) (((pos.lon - limitNorthWest.lon) * tileSizeX)/ (limitSouthEast.lon - limitNorthWest.lon));
   tileY = (int) (((pos.lat - limitSouthEast.lat) * tileSizeX)/ (limitNorthWest.lat - limitSouthEast.lat));
   if ( tileX < 0 )
      tileX = 0;
   else if (tileX >= tileSizeX)
      tileX = tileSizeX - 1;
   if ( tileY < 0 )
      tileY = 0;
   else if (tileY >= tileSizeY)
      tileY = tileSizeY - 1;

   maps[tileX+tileY*tileSizeX]->calcxy(x, y, pos);

   *x += mapLimitsX[tileX];
   *y += mapLimitsY[tileY];

   if ( (*x < 0) || (*x >= mapSizeX) || (*y < 0) || (*y >= mapSizeY) ) {
      return false;
   } else {
      return true;
   }
}

bool MapTiled::calcPos( Position & pos, double x, double y )
{
   int tileX;
   int tileY;

   tileX = (int) (((x) * tileSizeX) / mapSizeX);
   tileY = (int) (((y) * tileSizeX) / mapSizeY);
   if ( tileX < 0 )
      tileX = 0;
   else if (tileX >= tileSizeX)
      tileX = tileSizeX - 1;
   if ( tileY < 0 )
      tileY = 0;
   else if (tileY >= tileSizeY)
      tileY = tileSizeY - 1;

   x -= mapLimitsX[tileX];
   y -= mapLimitsY[tileY];

   return maps[tileX+tileY*tileSizeX]->calcPos(pos, x, y);
}

void MapTiled::draw(QPixmap *viewer, const Position &pos)
{
	double xc, yc;
	
	calcxy(&xc, &yc, pos);
   xc = rint(xc);
   yc = rint(yc);
   
	int xinic, yinic, xend, yend;

   xend = viewer->width();
   if (xend/2 > (int) xc) {
      xinic = 0;
      xend = xend/2 + (int)xc;
   }
   else {
      xinic = (int)xc - xend/2;
   	xend += xinic;
   }
   if (xend > mapSizeX)
		xend = mapSizeX;

   yend = viewer->height();
   if (yend/2 > (int) yc) {
      yinic = 0;
      yend = yend/2 + (int)yc;
   }
   else {
      yinic = (int)yc - yend/2;
   	yend += yinic;
   }
   if (yend > mapSizeY)
		yend = mapSizeY;

   int startX = 0;
   while (startX+1 < tileSizeX && mapLimitsX[startX+1] < xinic)
      startX ++;
   int startY = 0;
   while (startY+1 < tileSizeY && mapLimitsY[startY+1] < yinic)
      startY ++;

   MapBase *map;
   for (int tileY = startY; 
         tileY < tileSizeY && mapLimitsY[tileY] < yend; tileY++) {
      for (int tileX = startX; 
            tileX < tileSizeX && mapLimitsX[tileX] < xend; tileX++) {
         map = maps[tileX+tileY*tileSizeX];
         map->draw(viewer, pos);
      }
   }
}

⌨️ 快捷键说明

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