No Description

map.cpp 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "map.h"
  2. #include <QDebug>
  3. #include <QDesktopWidget>
  4. #include <QPainter>
  5. #include <QPen>
  6. Map::Map(QWidget *parent) :
  7. QWidget(parent)
  8. {
  9. srand(time(NULL));
  10. // Create country object and read data from the json file
  11. qDebug() << "Reading the Json...";
  12. myCountry = new Country;
  13. myCountry->readInfoFromJSON(":/data/pr-all-all.geo.json");
  14. qDebug() << "...done, read " << myCountry->Cities.size();
  15. cityColorMap = NULL;
  16. gisLocations = NULL;
  17. drawRoutes = false;
  18. // Compute the limits of the coordinates
  19. qDebug() << "Computing limits...";
  20. myCountry->limits();
  21. // Create the main widget and resize according to the map aspect ratio
  22. QDesktopWidget widget;
  23. QRect mainScreenSize = widget.availableGeometry(widget.primaryScreen());
  24. double diffX = myCountry->maxX - myCountry->minX > 0 ? myCountry->maxX - myCountry->minX : myCountry->minX - myCountry->maxX;
  25. double diffY = myCountry->maxY - myCountry->minY > 0 ? myCountry->maxY - myCountry->minY : myCountry->minY - myCountry->maxY;
  26. if (diffX > diffY) resize(mainScreenSize.width() * 0.5 , 0.5 * mainScreenSize.width()*(diffY/diffX));
  27. else resize(mainScreenSize.width() * 0.5, 0.5 * mainScreenSize.width()*(diffX/diffY));
  28. }
  29. Map::~Map() {
  30. if (myCountry != NULL) delete myCountry;
  31. if (cityColorMap != NULL) delete cityColorMap;
  32. if (gisLocations != NULL) delete [] gisLocations;
  33. }
  34. // These are used during the map drawing.
  35. QPoint **qpA = new QPoint*[100];
  36. unsigned int qpASize = 0;
  37. void Map::paintEvent(QPaintEvent *) {
  38. this->setWindowTitle("PR Visualization");
  39. QDesktopWidget widget;
  40. QRect mainScreenSize = widget.availableGeometry(widget.primaryScreen());
  41. // Creating the arrays that will hold the points for the cities
  42. if (qpASize == 0) {
  43. for (int i = 0; i < 100; i++) {
  44. qpA[i] = new QPoint[20000];
  45. }
  46. }
  47. // the QPainter is the 'canvas' to which we will draw
  48. // the QPen is the pen that will be used to draw to the 'canvas
  49. QPainter *p = new QPainter(this);
  50. QPen myPen;
  51. myPen.setWidth(1);
  52. myPen.setColor(QColor(0x100000));
  53. myPen.setBrush(QBrush(Qt::black));
  54. p->setPen(myPen);
  55. double factorX, factorY;
  56. // Computing the factors by which we'll scale the x and y coordinates.
  57. double diffX = myCountry->maxX - myCountry->minX > 0 ?
  58. myCountry->maxX - myCountry->minX : myCountry->minX - myCountry->maxX;
  59. double diffY = myCountry->maxY - myCountry->minY > 0 ?
  60. myCountry->maxY - myCountry->minY : myCountry->minY - myCountry->maxY;
  61. if (diffX > diffY) resize(mainScreenSize.width() * 0.5 , 0.5 * mainScreenSize.width()*(diffY/diffX));
  62. else resize(mainScreenSize.width() * 0.5, 0.5 * mainScreenSize.width()*(diffX/diffY));
  63. factorX = this->width() / diffX;
  64. factorY = this->height() / diffY;
  65. int colorCtr = 0;
  66. QMap<QString,QPolygonF*>::iterator it;
  67. unsigned int randColor;
  68. int cityCounter = 0;
  69. for (it = myCountry->Cities.begin() ; it != myCountry->Cities.end(); ++it) {
  70. QPolygonF *c = it.value();
  71. int x1 ,y1, x2, y2;
  72. x1 = factorX * (c->at(0).x() - myCountry->minX);
  73. y1 = height() - factorY*(c->at(0).y() - myCountry->minY) ;
  74. QPointF p1 = c->at(0);
  75. QPointF p2;
  76. int ctr = 0;
  77. QPoint *qp = qpA[cityCounter];
  78. QPoint *qpBegin = qp;
  79. // if no color map provided, we'll just color every city white.
  80. randColor = 0xffffff;
  81. if (cityColorMap)
  82. randColor = (cityColorMap->find(it.key()) == cityColorMap->end()) ?
  83. 0xffffff : (*cityColorMap)[it.key()];
  84. for(int i = 0; i < c->size() + 1; i++) {
  85. p2 = c->at((i+1)%c->size());
  86. x2 = factorX * (p2.x() - myCountry->minX);
  87. y2 = height() - factorY*(p2.y() - myCountry->minY) ;
  88. if (p2.x() != 0 && p1.x() != 0) {
  89. qp->setX(x2);
  90. qp->setY(y2);
  91. ctr++;
  92. qp++;
  93. }
  94. else if (p2.x() == 0) {
  95. QPolygon yourPoly;
  96. for (int i = 0; i < ctr; i++) yourPoly.push_back(qpBegin[i]);
  97. QPainterPath tmpPath;
  98. tmpPath.addPolygon(yourPoly);
  99. p->fillPath(tmpPath,QBrush(randColor));
  100. p->drawPolygon(qpBegin,ctr);
  101. ctr = 0;
  102. qpBegin = qp;
  103. }
  104. x1 = x2;
  105. y1 = y2;
  106. p1 = p2;
  107. }
  108. QPolygon yourPoly;
  109. for (int i = 0; i < ctr; i++) yourPoly.push_back(qpBegin[i]);
  110. QPainterPath *tmpPath = new QPainterPath;
  111. tmpPath->addPolygon(yourPoly);
  112. p->fillPath(*tmpPath,QBrush(randColor));
  113. p->drawPolygon(qpBegin,ctr,Qt::WindingFill);
  114. delete tmpPath;
  115. colorCtr++;
  116. cityCounter++;
  117. }
  118. qpASize = cityCounter;
  119. // Draw the city centers
  120. int circleRadius = (this->height() > this->width()) ? this->width()/20 : this->height()/20 ;
  121. int cX, cY, pX, pY;
  122. cX = cY = pX = pY = -1;
  123. if(gisLocations) {
  124. myPen.setWidth(2);
  125. myPen.setColor(QColor(0x100000));
  126. myPen.setBrush(QBrush(Qt::black));
  127. p->setPen(myPen);
  128. for (unsigned int i = 0; i < numLocations; i++) {
  129. qDebug() << "name from locations:" << gisLocations[i].getName();
  130. cX = factorX * (gisLocations[i].getLon() - myCountry->minX);
  131. cY = height() - factorY*(gisLocations[i].getLat() - myCountry->minY);
  132. p->setBrush(Qt::SolidPattern);
  133. p->setBrush(QBrush(0xff0000));
  134. p->drawEllipse(cX, cY, circleRadius, circleRadius);
  135. p->setBrush(Qt::NoBrush);
  136. if (drawRoutes && pX > 0) {
  137. p->drawLine(pX+circleRadius/2,pY+circleRadius/2,cX+circleRadius/2,cY+circleRadius/2);
  138. }
  139. pX = cX; pY = cY;
  140. }
  141. }
  142. // Draws any lines between the cities which have been added using
  143. // the drawLine method.
  144. QVector < QPair<const GISPOI *,const GISPOI *> > ::iterator vit = this->cityLines.begin();
  145. for (; vit != this->cityLines.end(); vit++) {
  146. cX = factorX * (vit->first->getLon() - myCountry->minX);
  147. cY = height() - factorY*(vit->first->getLat() - myCountry->minY);
  148. pX = factorX * (vit->second->getLon() - myCountry->minX);
  149. pY = height() - factorY*(vit->second->getLat() - myCountry->minY);
  150. p->drawLine(pX+circleRadius/2,pY+circleRadius/2,cX+circleRadius/2,cY+circleRadius/2);
  151. }
  152. //c++11 way
  153. /*
  154. for (QPair<const GISPOI *, const GISPOI *> linePair: this->cityLines) {
  155. // qDebug() << "A line from " << linePair.first->getName() << " to " << linePair.second->getName() << endl;
  156. cX = factorX * (linePair.first->getLon() - myCountry->minX);
  157. cY = height() - factorY*(linePair.first->getLat() - myCountry->minY);
  158. pX = factorX * (linePair.second->getLon() - myCountry->minX);
  159. pY = height() - factorY*(linePair.second->getLat() - myCountry->minY);
  160. p->drawLine(pX+circleRadius/2,pY+circleRadius/2,cX+circleRadius/2,cY+circleRadius/2);
  161. }
  162. */
  163. delete p;
  164. }