7 height = oldheight = 0;
22 HP[0].setX( 0);
HP[0].setY(-3);
23 HP[1].setX(-2);
HP[1].setY(-2);
24 HP[2].setX(-1);
HP[2].setY(-2);
25 HP[3].setX(0);
HP[3].setY(-2);
26 HP[4].setX(1);
HP[4].setY(-2);
27 HP[5].setX(2);
HP[5].setY(-2);
28 HP[6].setX(-2);
HP[6].setY(-1);
29 HP[7].setX(-1);
HP[7].setY(-1);
30 HP[8].setX(0);
HP[8].setY(-1);
31 HP[9].setX(1);
HP[9].setY(-1);
32 HP[10].setX(2);
HP[10].setY(-1);
33 HP[11].setX(-3);
HP[11].setY(0);
34 HP[12].setX(-2);
HP[12].setY(0);
35 HP[13].setX(-1);
HP[13].setY(0);
36 HP[14].setX(1);
HP[14].setY(0);
37 HP[15].setX(2);
HP[15].setY(0);
38 HP[16].setX(3);
HP[16].setY(0);
39 HP[17].setX(-2);
HP[17].setY(1);
40 HP[18].setX(-1);
HP[18].setY(1);
41 HP[19].setX(0);
HP[19].setY(1);
42 HP[20].setX(1);
HP[20].setY(1);
43 HP[21].setX(2);
HP[21].setY(1);
44 HP[22].setX(-2);
HP[22].setY(2);
45 HP[23].setX(-1);
HP[23].setY(2);
46 HP[24].setX(0);
HP[24].setY(2);
47 HP[25].setX(1);
HP[25].setY(2);
48 HP[26].setX(2);
HP[26].setY(2);
49 HP[27].setX(0);
HP[27].setY(3);
66 MS0.summitcolor = QColor(100,15,0).rgba();
80 MS0.drawstreetcontour = 1;
81 MS0.woodcolor = QColor(0,200,0,50).rgba();
83 MS0.watercolor = QColor(0,0,200,100).rgba();
85 MS0.drawstreetlabel = 1;
97 MS0.
sun.azimut = -135;
98 MS0.
sun.elevation = 45;
100 MS0.
sun.
sphi = sin(-MS0.
sun.azimut/180.*M_PI);
107 for(
int wx = 0; wx <
width+2; wx++){
127 oldwidth = this->
width;
129 oldheight = this->height;
130 this->height = height;
133 double lonmin0,
double lonmax0){
160 mminlat = lattomercator(
minlat0);
162 if( q > 1.0 * height/
width){
172 mminlat = middle - ((middle-mminlat)/
width/q*height);
174 minlat = mercatortolat(mminlat);
187 int zoomint = int(
zoom);
188 switch(zoomint > 50 ? 4 : zoomint > 30 ? 3:
189 zoomint > 15 ? 2:zoomint <= 15 ? 1:zoomint){
198 if((
width != oldwidth || height != oldheight)
199 &&
width != 0 && height != 0){
202 for(
int wx = 0; wx < oldwidth+2; wx++){
217 for(
int wx = 0; wx <
width+2; wx++){
218 hc[wx] =
new double[height+2];
219 dhdx[wx] =
new double[height+2];
220 dhdy[wx] =
new double[height+2];
221 t[wx] =
new char[height+2];
227 cd =
new unsigned char[(3*width+
lineos)*height];
232 double minlatex = mercatortolat(mminlat - (
mmaxlat-mminlat)/height);
233 double maxlatex = mercatortolat(
mmaxlat + (
mmaxlat-mminlat)/height);
237 hd->
set_rect(minlatex,maxlatex,minlonex,maxlonex);
250 QImage img(
cd,
width,height,QImage::Format_RGB888);
252 cmap =
new QPixmap(
width,height);
253 cmap->convertFromImage(img);
257 for(
int k = 0; k <
width; k++)
258 for(
int l = 0; l < height; l++){
268 double dI[4], f0l, f0h, fnl, fnh;
269 int dx[4]={+1,+1,+1,0};
270 int dy[4]={-1,0,+1,+1};
271 double I[4]={-0.2,-0.4,-0.2,-0.4};
272 int dd[4]={-1,0,1,2};
274 for(
int x = 0; x <
width; x++)
275 for(
int y = 0; y < height; y++){
279 for(
int i = 0; i < 4; i++){
288 /qAbs(
hc[x+1+dx[i]][y+1+dy[i]] -
hc[x+1][y+1]);
292 for(
int j = 0; j < 4; j++){
293 if(dI[j] < 0.5) dI[j] = 1.;
294 else dI[j] = qMax(0.,1.5-dI[j]);
303 /qAbs(
hc[x+1+dx[i]][y+1+dy[i]] -
hc[x+1][y+1]));
305 *qAbs(
hc[x+1 ][y+1 ] - fnl*lowcontour)
306 /qAbs(
hc[x+1+dx[i]][y+1+dy[i]] -
hc[x+1][y+1]));
315 while(h > MS->
heights[i+1] && i < 3)
324 /sqrt(1+dxf*dxf+dyf*dyf)-MS->
sun.
ctheta);
326 cd[0] = qMin(uchar(255),
329 cd[1] = qMin(uchar(255),
332 cd[2] = qMin(uchar(255),
343 if( x >= 0 && x < width && y >= 0 && y < height){
346 c[0] = c[0]/(1+dI)+255*dI/1+dI;
347 c[1] = c[1]/(1+dI)+255*dI/1+dI;
348 c[2] = c[2]/(1+dI)+255*dI/1+dI;
360 double MAP::getminlon(){
363 double MAP::getmaxlat(){
366 double MAP::getmaxlon(){
372 int MAP::getheight(){
379 double MAP::x_to_lon(
int x){
382 double MAP::lat_to_y(
double lat){
386 double MAP::lon_to_x(
double lon){
389 double MAP::xy_to_height(
int x,
int y){
390 if(x>=0 && x < width && y >= 0 && y < height)
395 inline float MAP::lattoy(
double lat){
399 inline float MAP::lontox(
double lon){
402 float MAP::get_mperlon(){
405 float MAP::get_mperlat(){
408 void MAP::OSMtoMAP(
short getcmap,
short drawroads,
short drawnature ,
short drawpoints){
413 if(drawnature && (MS->drawwood||MS->drawater))
414 TemplatetoColorData();
417 cmap =
new QPixmap(
width,height);
422 QImage img(
cd,
width,height,QImage::Format_RGB888);
423 p.drawImage(0,0,img);
425 p.setRenderHint(QPainter::Antialiasing);
426 p.setRenderHint(QPainter::TextAntialiasing);
428 if(drawnature && MS->drawater){
443 if(drawpoints && MS->drawpoints){
447 if(drawpoints && MS->drawsummit)
448 peaktomap(o,&p,o->
peak,0,1e10, QColor(MS->summitcolor),
zoomsize(MS->summitsize));
450 rivernametomap(o,&p,o->
river, QColor(0,0,60,255),
zoomsize(8 ));
451 if(drawpoints && MS->drawpoints)
454 waternametomap(o,&p,o->
water, QColor(0,0,60,255),
zoomsize(8 ));
457 if(MS->drawstreetlabel){
466 float linewidth,
float minlinewidth){
467 if(linewidth >= minlinewidth){
470 if(MS->drawstreetcontour)
471 p->setPen(QPen(color,linewidth,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
473 p->setPen(QPen(color,linewidth));
477 for(
int i = 0; i < l->
way->
nodec;i++){
478 pts[i].setX(lontox(l->
way->
node[i]->lon));
497 void MAP::pointtomap(
OSM* o, QPainter *p,
points** pp,QColor color,
float size){
500 QColor blight(color.red()*0.1+220,
501 color.green()*0.1+220,
502 color.blue()*0.1+200,
504 p->setFont(QFont(
"Arial",size, QFont::Bold,
false));
505 QFontMetricsF fm(p->font());
507 R.setHeight(fm.height());
508 float yoffset = fm.ascent()-fm.strikeOutPos();
509 float yso = fm.strikeOutPos();
514 x = lontox(pts->
k->lon);
515 y = lattoy(pts->
k->
lat);
516 QString w = QString().fromUtf8(pts->
name);
517 R.setWidth(fm.width(w));
518 R.moveTo(x-R.width()/2,y-yoffset);
520 Draw_lighted_text(p,&w,QPointF(R.left(),y+yso),&blight,&btext);
528 void MAP::peaktomap(
OSM* o, QPainter *p,
points** pp,
float min,
float max,
529 QColor color,
float size){
531 QBrush blight(QColor(color.red()*0.2+204,
532 color.green()*0.2+204,
533 color.blue()*0.2+204,
540 while(pts != NULL && pts->
index >= min){
541 if(pts->
index < max &&
545 size = size0 * sqrt(pts->
index/1500);
547 p->setFont(QFont(
"Arial",size, QFont::Bold,
false));
548 x = lontox(pts->
k->lon);
549 y = lattoy(pts->
k->
lat);
550 float size05 = size * 0.5;
552 QString w = QString().fromUtf8(pts->
name);
553 QPointF p1(x ,y-size05*1.2);
554 QPointF p2(x+size05*0.866,y+size05*0.5);
555 QPointF p3(x-size05*0.866,y+size05*0.5);
556 QPointF d1(frc*size05,0);
557 QPointF d2(-frc*size05*0.5,frc*size05*0.866);
558 QPointF d3(-frc*size05*0.5,-frc*size05*0.866);
561 Triang.cubicTo(p1+d1,p2-d2,p2);
562 Triang.cubicTo(p2+d2,p3-d3,p3);
563 Triang.cubicTo(p3+d3,p1-d1,p1);
564 alignto[0].setX(x-5*size); alignto[0].setY(y+1*size);
565 alignto[1].setX(x); alignto[1].setY(y-1.5*size);
566 alignto[2].setX(x+5*size); alignto[2].setY(y+1*size);
567 R = Triang.boundingRect();
569 if(Draw_aligned_text(p,&(alignto[0]),3,&w,p1,&blight,&btext)){
570 p->setPen(Qt::NoPen);
571 Draw_lighted_Path(p,&Triang,&blight,&btext);
579 void MAP::waternametomap(
OSM* o, QPainter *p,
lines** pp,QColor color,
float size){
582 QColor btext(color.darker(200));
583 QColor blight(color.red()*0.1+220,
584 color.green()*0.1+220,
585 color.blue()*0.1+220,
587 p->setFont(QFont(
"Arial",size, QFont::Bold,
false));
588 QFontMetricsF fm(p->font());
590 R.setHeight(fm.height());
591 float yoffset = fm.ascent()-fm.strikeOutPos();
592 float yso = fm.strikeOutPos();
597 if( pts->
name != NULL
603 y = lattoy((pts->
way->maxlat+pts->
way->minlat)/2);
604 QString w = QString().fromUtf8(pts->
name);
605 R.setWidth(fm.width(w));
606 R.moveTo(x-R.width()/2,y-yoffset);
608 Draw_lighted_text(p,&w,QPointF(R.left(),y+yso),&blight,&btext);
616 void MAP::streetnametomap(
OSM* o, QPainter *p,
lines** pp,QColor color,
float size){
618 p->setBrush(QBrush(QColor(50,50,50,150)));
619 p->setFont(QFont(
"Arial",size, QFont::Bold,
false));
620 QFontMetricsF fm(p->font());
622 float yoffset = fm.ascent()-fm.strikeOutPos();
623 float yso = fm.strikeOutPos();
628 if(pts->
name != NULL){
631 QString w = QString().fromUtf8(pts->
name);
632 R.setHeight(fm.height());
633 fwidth = fm.width(w);
634 R.setWidth(fwidth*1.2);
635 R.moveTo(x-R.width()/2,y-yoffset);
637 p->setPen(QColor(0,0,0));
638 p->drawRoundRect(R,25,25);
640 p->drawText(x-fwidth/2,y+yso,w);
644 R.adjust(-2*R.width(),-2*R.height(),2*R.width(),2*R.height());
651 void MAP::rivernametomap(
OSM* o, QPainter *p,
lines** pp,QColor color,
float size){
655 QBrush btext(color.darker(200));
656 QBrush blight(QColor(color.red()*0.2+204,
657 color.green()*0.2+204,
658 color.blue()*0.2+204,
660 p->setFont(QFont(
"Arial",size,QFont::Bold));
661 QFontMetricsF fm(p->font());
668 if( pts->
name != NULL
671 QString w = QString().fromUtf8(pts->
name);
672 brect = fm.boundingRect(w);
676 +(pts->
way->maxlat - pts->
way->minlat)*
678 > brect.width()*2*
zoom){
680 path[0].setX(lontox(pts->
way->
node[0]->lon));
685 do{ path[i].setX(lontox(pts->
way->
node[i]->lon));
687 d = d+ sqrt((path[i-1].x()-path[i].x())*(path[i-1].x()-path[i].x())
688 +(path[i-1].y()-path[i].y())*(path[i-1].y()-path[i].y()));
689 if(d < brect.width()*1.5) j = i;
691 }
while(d < brect.width()*3 && i < pts->
way->
nodec);
695 Draw_aligned_text(p,&(path[0]),i,&w,P,&blight,&btext);
703 void MAP::add_scale(QPainter *p){
705 QColor w(255,255,255,120);
706 QColor wt(255,255,255,20);
707 p->setFont(QFont(
"Arial",10, QFont::Bold,
false));
708 QFontMetricsF fm(p->font());
710 float dsd = float(upperscale(sd/8));
711 int x0 =
width/3*2-20;
712 int y0 = height - 20;
713 int width0 = int(floor(dsd*1000/
zoom));
716 p->setPen(Qt::NoPen);
717 for(
int i = 0; i < sd/dsd-1; i++)
720 p->drawRect(x0+i*width0,y0,width0,10);
724 p->drawRect(x0+i*width0,y0,width0,10);
728 for(
int i = 0; i < sd/dsd; i++){
730 QString label = QString(
"%1 km").arg(i*dsd,0,
'f',1);
731 R = fm.boundingRect(label);
732 R.translate(x0+i*width0-R.width()/2,y0-5-fm.descent());
733 Draw_lighted_text(p,&label,R.bottomLeft(),&wt,&b);
736 void MAP::Draw_lighted_text(QPainter *p, QString* w, QPointF P,
737 QColor* lightcolor, QColor* textcolor){
738 p->setPen(*lightcolor);
739 for(
int i = 0; i < 28; i++)
740 p->drawText(P+
HP[i],*w);
741 p->setPen(*textcolor);
744 int MAP::Draw_lighted_text(QPainter* p,
KOO *k, QString* w,
745 QColor* lightcolor, QColor* textcolor){
746 float x = lontox(k->lon);
747 float y = lattoy(k->
lat);
748 QFontMetricsF fm(p->font());
750 R.setHeight(fm.height());
751 float yoffset = fm.ascent()-fm.strikeOutPos();
752 float yso = fm.strikeOutPos();
753 R.setWidth(fm.width(*w));
754 R.moveTo(x-R.width()/2,y-yoffset);
757 Draw_lighted_text(p,w,QPointF(R.left(),y+yso),lightcolor,textcolor);
765 return size * sqrt(40/
zoom);
771 int i,j,ymin,ymax,xmin;
777 p[i].x = lontox(f->
way->
node[i]->lon);
782 for(i = 0; i < f->
way->
nodec-1; i++){
783 if(p[i+1].y != p[i].y){
785 if(p[i+1].y > p[i].y){
788 dxdy = float(1.*(p[i+1].x - p[i].x)/(ymax - ymin));
795 dxdy = float(1.*(p[i].x - p[i+1].x)/(ymax - ymin));
797 for(j = ymin; j < ymax; j++)
798 set(xmin+
int((j-ymin)*dxdy),j,val);
804 void MAP::TemplatetoColorData(){
806 int wor = qRed(MS->woodcolor);
807 int wog = qGreen(MS->woodcolor);
808 int wob = qBlue(MS->woodcolor);
809 float woa = 1.*qAlpha(MS->woodcolor)/255.;
810 int war = qRed(MS->watercolor);
811 int wag = qGreen(MS->watercolor);
812 int wab = qBlue(MS->watercolor);
813 float waa = 1.*qAlpha(MS->watercolor)/255.;
816 for(y = 0; y < height; y++){
818 for(x = 0; x <
width; x++){
819 if(
t[x][y] %10 == 1){
828 cd[y *(3*width+
lineos)+x*3+0] = uchar(
cd[y *(3*width+
lineos)+x*3+0]*(1-waa)+waa*war);
829 cd[y *(3*width+
lineos)+x*3+1] = uchar(
cd[y *(3*width+
lineos)+x*3+1]*(1-waa)+waa*wag);
830 cd[y *(3*width+
lineos)+x*3+2] = uchar(
cd[y *(3*width+
lineos)+x*3+2]*(1-waa)+waa*wab);
834 cd[y *(3*width+
lineos)+x*3+0] = uchar(
cd[y *(3*width+
lineos)+x*3+0]*(1-woa)+woa*wor);
835 cd[y *(3*width+
lineos)+x*3+1] = uchar(
cd[y *(3*width+
lineos)+x*3+1]*(1-woa)+woa*wog);
836 cd[y *(3*width+
lineos)+x*3+2] = uchar(
cd[y *(3*width+
lineos)+x*3+2]*(1-woa)+woa*wob);
842 if(y >= 0 && x < width && y < height){
854 if(
t[x][y] % 10 == 1)
864 for(i = 0; i <
width; i++)
865 for(j = 0; j < height; j++)
869 if(R.height() == 0 || R.width() == 0)
872 int x,y,xmin,xmax,ymin,ymax;
873 if(R.bottom() >= height)ymax = height;
874 else ymax = int(R.bottom()+1);
875 if(R.top() < 0) ymin = 0;
876 else ymin = int(R.top());
877 if(R.right() >=
width) xmax = width;
878 else xmax = int(R.right()+1);
879 if(R.left() < 0) xmin = 0;
880 else xmin = int(R.left());
881 for(y = ymin ; y < ymax; y++)
882 for(x = xmin ; x < xmax; x++)
891 if(R.height() == 0 || R.width() == 0)
893 int x,y,xmin,xmax,ymin,ymax;
894 if(R.bottom() >= height) ymax = height;
895 else ymax = int(R.bottom()+1);
896 if(R.top() < 0) ymin = 0;
897 else ymin = int(R.top());
898 if(R.right() >=
width) xmax = width;
899 else xmax = int(R.right()+1);
900 if(R.left() < 0) xmin = 0;
901 else xmin = int(R.left());
902 for(y = ymin ; y < ymax; y++)
903 for(x = xmin ; x < xmax; x++)
907 if(R.height() == 0 || R.width() == 0)
910 int x,y,xmin,xmax,ymin,ymax;
911 if(R.bottom() >= height) ymax = height;
912 else ymax = int(R.bottom()+1);
913 if(R.top() < 0) ymin = 0;
914 else ymin = int(R.top());
915 if(R.right() >=
width) xmax = width;
916 else xmax = int(R.right()+1);
917 if(R.left() < 0) xmin = 0;
918 else xmin = int(R.left());
919 for(y = ymin ; y < ymax; y++)
920 for(x = xmin ; x < xmax; x++)
929 if(R.height() == 0 || R.width() == 0)
931 int x,y,xmin,xmax,ymin,ymax;
932 if(R.bottom() >= height) ymax = height;
933 else ymax = int(R.bottom()+1);
934 if(R.top() < 0) ymin = 0;
935 else ymin = int(R.top());
936 if(R.right() >=
width) xmax = width;
937 else xmax = int(R.right()+1);
938 if(R.left() < 0) xmin = 0;
939 else xmin = int(R.left());
940 for(y = ymin ; y < ymax; y++)
941 for(x = xmin ; x < xmax; x++)
945 if(R.height() == 0 || R.width() == 0)
948 int x,y,xmin,xmax,ymin,ymax;
949 if(R.bottom() >= height) ymax = height;
950 else ymax = int(R.bottom()+1);
951 if(R.top() < 0) ymin = 0;
952 else ymin = int(R.top());
953 if(R.right() >=
width) xmax = width;
954 else xmax = int(R.right()+1);
955 if(R.left() < 0) xmin = 0;
956 else xmin = int(R.left());
957 for(y = ymin ; y < ymax; y++)
958 for(x = xmin ; x < xmax; x++)
963 int MAP::Draw_aligned_text(QPainter* g,QPointF* path,
int pointcount, QString*w,
964 QPointF P,QBrush* lightbrush, QBrush* textbrush){
967 QMatrix matrix, KOOfwd,KOObwd;
968 QFontMetricsF fm(g->font());
974 int strhigh = w->length();
979 brect = fm.boundingRect(*w);
980 if(sqrt((path[0].y()-path[pointcount-1].y())*(path[0].y()-path[pointcount-1].y())
981 +(path[0].x()-path[pointcount-1].x())*(path[0].x()-path[pointcount-1].x()))
985 x = FitPolynom(path,pointcount,1);
986 if(x != NULL) PHI = -atan(x[0])/M_PI*180;
992 PHI = -atan((path[0].y()-path[pointcount-1].y())/(path[0].x()-path[pointcount-1].x()))/M_PI*180;
995 KOOfwd.rotate(qreal(PHI));
996 KOOfwd.translate(-path[pointcount/2].x(),-path[pointcount/2].y());
997 for(
int i = 0; i < pointcount; i++)
998 path[i] = KOOfwd.map(path[i]);
1000 KOObwd = KOOfwd.inverted();
1003 int grad = min(5,pointcount);
1005 while(x == NULL && grad >= 0){
1007 x = FitPolynom(path,pointcount,grad);
1023 QPainterPath* c =
new QPainterPath[strhigh];
1024 float* clen =
new float[strhigh];
1026 float* cangle =
new float[strhigh];
1028 float strlenpx = 0, lent = 0;
1029 double em = fm.width(
'M');
1030 double yoffset = fm.strikeOutPos();
1031 for(i = 0; i < strhigh; i++){
1032 brect = fm.boundingRect(w->mid(i,1));
1033 c[i].addText(0,0,g->font(),w->mid(i,1));
1034 crect = c[i].boundingRect();
1035 clen[i] = qMax(crect.width()*1.4,0.3*em);
1036 strlenpx = strlenpx + clen[i];
1037 c[i].translate(-crect.left(),yoffset);
1042 while(lent < strlenpx/2 && i < strhigh-1){
1043 lent = lent + clen[i];
1046 lent = lent-strlenpx/2;
1049 QPointF* sp =
new QPointF[strhigh];
1050 float dx = 0, dy = 0;
1053 P.setY(fpln(P.x(),x,grad));
1054 while(sqrt(dx*dx+dy*dy) <= lent){
1055 dx = dx + float(0.01);
1056 dy = float(P.y()-fpln(
double(P.x() + dx),x,grad));
1058 sp[i].setX(P.x() + dx);
1059 sp[i].setY(fpln(sp[i].x(),x,grad));
1062 for(j = i-1; j >= 0; j--){
1065 while(sqrt(dx*dx+dy*dy) <= clen[j]){
1066 dx = dx + float(0.01);
1067 dy = sp[j+1].y()-float(fpln(sp[j+1].x()-dx,x,grad));
1069 sp[j].setX(sp[j+1].x() - dx);
1070 sp[j].setY(sp[j+1].y() - dy);
1071 cangle[j] = float(atan(dy/dx)/M_PI*180);
1074 for(j = i+1; j < strhigh; j++){
1077 while(sqrt(dx*dx+dy*dy) <= clen[j-1]){
1078 dx = dx + float(0.01);
1079 dy = sp[j-1].y()-float(fpln(sp[j-1].x()+dx,x,grad));
1081 sp[j].setX(sp[j-1].x() + dx);
1082 sp[j].setY(sp[j-1].y() - dy);
1083 cangle[j-1] = float(atan(-dy/dx)/M_PI*180);
1088 while(sqrt(dx*dx+dy*dy) <= clen[strhigh-1]){
1089 dx = dx + float(0.01);
1090 dy = sp[strhigh-1].y()-float(fpln(sp[strhigh-1].x()+dx,x,grad));
1092 cangle[strhigh-1] = float(atan(-dy/dx)/M_PI*180);
1098 cg.setFillRule(Qt::WindingFill);
1100 QList<QRectF> spacelist;
1101 for(i = 0; i < strhigh; i++){
1103 matrix.translate(sp[i].x(),sp[i].y());
1104 matrix.rotate(cangle[i]);
1105 c[i] = matrix.map(c[i]);
1106 c[i] = KOObwd.map(c[i]);
1107 brect = c[i].boundingRect();
1114 spacelist.append(brect);
1118 Draw_lighted_Path(g,&cg,lightbrush,textbrush);
1119 for(i = 0; i < strhigh; i++)
1138 void MAP::Draw_lighted_Path(QPainter* g, QPainterPath* p,
1139 QBrush* lightbrush,QBrush* textbrush){
1140 g->setPen(QPen(*lightbrush,4.5));
1141 g->setBrush(Qt::NoBrush);
1143 g->setPen(Qt::NoPen);
1144 g->setBrush(*textbrush);
1153 QPointF* pts =
new QPointF[kc];
1155 pts[0].setX(lontox(k[0].k->lon));
1156 pts[0].setY(lattoy(k[0].k->lat));
1157 for(
int i = 1; i < kc; i++){
1158 pts[ci].setX(lontox(k[i].k->lon));
1159 pts[ci].setY(lattoy(k[i].k->lat));
1160 if((pts[ci]-pts[ci-1]).manhattanLength()>5
1164 p->drawPolyline(pts,ci);
1169 QPointF* pts =
new QPointF[count];
1170 for(
int cp = 0; cp < count; cp++){
1171 pts[cp].setX(lontox(k[cp]->lon));
1172 pts[cp].setY(lattoy(k[cp]->lat));
1174 p->drawPolyline(pts,count);
1178 QPointF* pts =
new QPointF[count];
1179 for(
int cp = 0; cp < count; cp++){
1180 pts[cp].setX(lontox(k[1][cp]));
1181 pts[cp].setY(lattoy(k[0][cp]));
1183 p->drawPolyline(pts,count);
1189 ct->get_data_ref(NULL,NULL,&kl,&kc);
1191 for(
int i = 0; i < kc; i++)
1193 p->drawEllipse(lon_to_x(kl[i].k->lon)-5,
1194 lat_to_y(kl[i].k->lat)-5,
1198 cmap->save(filename,
"PNG");
1202 p.setRenderHint(QPainter::Antialiasing);
1203 QColor blight(140,140,140,60);
1205 for(
long i = 0; i < cl->climbcount; i++){
1208 p.setPen(QPen(Qt::black,linewidth*
zoomsize(0.6)+2));
1209 draw_line(&p,cl->climb[i].KOOarray,cl->climb[i].KOOcount);
1210 p.setPen(QPen(c,linewidth*
zoomsize(0.6)));
1211 draw_line(&p,cl->climb[i].KOOarray,cl->climb[i].KOOcount);
1216 for(
long i = cl->climbcount - 1; i >= 0 ; i--){
1217 int mindex = cl->climb[i].KOOcount/2;
1219 k.lon = cl->climb[i].KOOarray[1][mindex];
1220 k.
lat = cl->climb[i].KOOarray[0][mindex];
1229 w = QString(
"%1 m").arg(cl->climb[i].
P,0,
'f',1);
1230 p.setFont(QFont(
"Arial",8 + 10 * cl->climb[i].
LocRank,QFont::Bold));
1231 if(!Draw_lighted_text(&p,&k,&w,&blight,&c)){
1232 int s = 0;
short repeat;
1236 if((mindex+s)>= 0 && (mindex+s)< cl->climb[i].KOOcount){
1237 k.lon = cl->climb[i].KOOarray[1][mindex];
1238 k.
lat = cl->climb[i].KOOarray[0][mindex];
1239 if(Draw_lighted_text(&p,&k,&w,&blight,&c))
1251 if(SL->data != NULL){
1256 g =
new QPainter(cmap);
1257 g->setRenderHint(QPainter::Antialiasing);
1262 for(
int drawblack = 1; drawblack >= 0; drawblack --){
1263 for(
long int i = 0; i < SL->ncount; i++){
1264 if(SL->data[i].n != NULL){
1265 k = &(SL->data[i].n->
node[0]);
1266 x = sqrt(qMax(
float(0.),SL->data[i].
index));
1268 QPointF* p =
new QPointF[SL->data[i].n->
nodec];
1269 for(
int j = 0; j < SL->data[i].n->
nodec; j++){
1270 p[j].setX(lontox(k[j]->lon));
1271 p[j].setY(lattoy(k[j]->lat));
1274 g->setPen(QPen(Qt::black,linewidth,Qt::SolidLine,Qt::RoundCap));
1275 g->drawPolyline(p,SL->data[i].n->
nodec);
1279 linewidth = linewidth - 2;
1280 g->setPen(QPen(Qt::green,linewidth,Qt::SolidLine,Qt::RoundCap));
1281 g->drawPolyline(p,SL->data[i].n->
nodec);
1295 int vsteps = height / 15;
1296 int hsteps = width / 20;
1297 float *hP =
new float[hsteps];
1298 float *hbend =
new float[hsteps];
1299 float *hslope =
new float[hsteps];
1300 float *vP =
new float[vsteps];
1301 float *vbend =
new float[vsteps];
1302 float *vslope =
new float[vsteps];
1303 for(
int i = 0; i < hsteps; i++)
1304 hP[i] = hbend[i] = hslope[i] = 0;
1305 for(
int i = 0; i < vsteps; i++)
1306 vP[i] = vbend[i] = vslope[i] = 0;
1309 for(
int i = 0; i < cl->climbcount; i++){
1310 ix = hsteps * lontox(cl->climb[i].midlon)/
width;
1311 iy = vsteps * lattoy(cl->climb[i].midlat)/height;
1312 if(ix >= 0 && ix < hsteps && iy >= 0 && iy < vsteps){
1313 bendv = cl->climb[i].
bend*cl->climb[i].
bend*cl->climb[i].
d/48.;
1314 if(cl->climb[i].
P > hP[ix])
1315 hP[ix] = cl->climb[i].
P;
1316 if(cl->climb[i].
slope > hslope[ix])
1317 hslope[ix] = cl->climb[i].
slope;
1318 if(bendv > hbend[ix])
1320 if(cl->climb[i].
P > vP[iy])
1321 vP[iy] = cl->climb[i].
P;
1322 if(cl->climb[i].
slope > vslope[iy])
1323 vslope[iy] = cl->climb[i].
slope;
1324 if(bendv > vbend[iy])
1334 g =
new QPainter(cmap);
1335 g->setRenderHint(QPainter::Antialiasing);
1336 g->setFont(QFont(
"Arial",10,QFont::Bold));
1339 for(
int i = 0; i < hsteps; i++){
1341 w = QString(
"%1").arg(hP[i],0,
'f',0);
1343 l = 1.*width * i/hsteps;
1344 rt = qMin(width-1.,1.*width * (i+1)/hsteps);
1345 QRectF r; r.setRect(l,height-13.5,rt-l,13);
1346 g->setBrush(QBrush(c));
1347 g->setPen(Qt::NoPen);
1349 g->setPen(QPen(Qt::black,2));
1350 g->drawText(r,Qt::AlignCenter,w);
1351 g->setPen(QPen(Qt::white,2));
1352 g->drawLine(r.left(),r.top()+1,
1353 r.left()+ r.width()*qMin(1.,
double(sqrt(hbend[i]))),r.top()+1);
1354 g->drawLine(r.left(),r.bottom()-1,
1355 r.left()+ r.width()*qMin(1.,
double(sqrt(hbend[i]))),r.bottom()-1);
1357 g->setPen(Qt::NoPen);
1359 g->setPen(QPen(Qt::black,2));
1360 g->drawText(r,Qt::AlignCenter,w);
1361 g->setPen(QPen(Qt::white,2));
1362 g->drawLine(r.left(),r.top()+1,
1363 r.left()+ r.width()*qMin(1.,
double(sqrt(hbend[i]))),r.top()+1);
1364 g->drawLine(r.left(),r.bottom()-1,
1365 r.left()+ r.width()*qMin(1.,
double(sqrt(hbend[i]))),r.bottom()-1);
1368 for(
int i = 0; i < vsteps; i++){
1370 w = QString(
"%1").arg(vP[i],0,
'f',0);
1372 t = floor(1.*height * i/vsteps)+0.5;
1373 QRectF r; r.setRect(0,t,20,14);
1374 g->setBrush(QBrush(c));
1375 g->setPen(Qt::NoPen);
1377 g->setPen(QPen(Qt::black,2));
1378 g->drawText(r,Qt::AlignCenter,w);
1379 g->setPen(QPen(Qt::white,2));
1380 g->drawLine(r.left(),r.top()+1,
1381 r.left()+ r.width()*qMin(1.,
double(sqrt(hbend[i]))),r.top()+1);
1382 g->drawLine(r.left(),r.bottom()-1,
1383 r.left()+ r.width()*qMin(1.,
double(sqrt(hbend[i]))),r.bottom()-1);
1384 r.moveRight(width-0.5);
1385 g->setPen(Qt::NoPen);
1387 g->setPen(QPen(Qt::black,2));
1388 g->drawText(r,Qt::AlignCenter,w);
1389 g->setPen(QPen(Qt::white,2));
1390 g->drawLine(r.left(),r.top()+1,
1391 r.left()+ r.width()*qMin(1.,
double(sqrt(hbend[i]))),r.top()+1);
1392 g->drawLine(r.left(),r.bottom()-1,
1393 r.left()+ r.width()*qMin(1.,
double(sqrt(hbend[i]))),r.bottom()-1);
1416 if(MS->drawater || MS->drawwood)
1417 TemplatetoColorData();
1418 QImage img(
cd,width,height,QImage::Format_RGB888);
1422 p.setRenderHint(QPainter::Antialiasing);
1430 if(MS->drawstreetcontour){
1447 p.setPen(QPen(Qt::green,5));
1456 peaktomap(o,&p,o->
peak,1500,1e10,QColor::fromRgba(MS->summitcolor),
zoomsize(MS->summitsize));
1460 rivernametomap(o,&p,o->
river, QColor::fromRgba(MS->watercolor),
zoomsize(8 ));
1464 peaktomap(o,&p,o->
peak,0,1500, QColor::fromRgba(MS->summitcolor),
zoomsize(MS->summitsize));
1466 waternametomap(o,&p,o->
water, QColor::fromRgba(MS->watercolor),
zoomsize(8 ));
1472 if(MS->drawstreetlabel){
1488 cmap =
new QPixmap(width,height);
1490 cmap->convertFromImage(img);
1496 double minlatex = mercatortolat(mminlat - (
mmaxlat-mminlat)/height);
1497 double maxlatex = mercatortolat(
mmaxlat + (
mmaxlat-mminlat)/height);
1501 hd->
set_rect(minlatex,maxlatex,minlonex,maxlonex);
1516 double d, lat, lon, dx ,dy,gmax = 0;
1519 int gx = width / spergx;
1520 int gy = height / spergy;
1521 spergx = 1.*width / (gx-1);
1522 spergy = 1.*height / (gy-1);
1524 double **grid = (
double**)malloc(gx*
sizeof(
double*));
1525 for(
int x = 0; x < gx; x++)
1526 grid[x] = (
double*)malloc(gy*
sizeof(
double));
1527 for(
int x = 0; x < gx; x++)
1528 for(
int y = 0; y < gy; y++){
1532 for(
int i = 0; i < cl->climbcount; i++){
1533 d = distance(lat,lon,cl->climb[i].midlat,cl->climb[i].midlon);
1534 grid[x][y] += cl->climb[i].
P/(1.+(d*d*d*d*d*d/512./512.));
1536 grid[x][y] = sqrt(grid[x][y]);
1537 if(grid[x][y] > gmax)
1541 for(
int x = 0; x < gx-1; x++)
1542 for(
int y = 0; y < gy-1; y++)
1543 for(
int xx = ceil(x * spergx); xx < qMin(
double(width-1.),(x+1)*spergx); xx++)
1544 for(
int yy = ceil(y * spergy); yy < qMin(
double(height-1.),(y+1)*spergy); yy++){
1545 dx = 1.*xx/spergx - x;
1546 dy = 1.*yy/spergy - y;
1547 d = grid[x+0][y+0]*(1-dx) * (1-dy) +
1548 grid[x+1][y+0]*( dx) * (1-dy) +
1549 grid[x+0][y+1]*(1-dx) * ( dy) +
1550 grid[x+1][y+1]*( dx) * ( dy);
1552 QRgb c = colorgradientSchading(d).rgb();
1553 uchar* cdt = &(
cd[yy*(3*width+
lineos)+xx*3]);
1554 cdt[0] = uchar((1.-MS->climblayershading) * cdt[0] +
1555 MS->climblayershading * cdt[0]* qRed(c)/255.);
1556 cdt[1] = uchar((1.-MS->climblayershading) * cdt[1] +
1557 MS->climblayershading * cdt[1]* qGreen(c)/255.);
1558 cdt[2] = uchar((1.-MS->climblayershading) * cdt[2] +
1559 MS->climblayershading * cdt[2]* qBlue(c)/255.);
1561 for(
int x = 0; x < gx; x++)
1568 for(
long i = 0; i < cl->climbcount; i++){
1572 p->setPen(QPen(Qt::black,linewidth+2));
1573 draw_line(p,cl->climb[i].KOOarray,cl->climb[i].KOOcount);
1574 p->setPen(QPen(c,linewidth));
1575 draw_line(p,cl->climb[i].KOOarray,cl->climb[i].KOOcount);
1579 QColor blight(140,140,140,60);
1581 for(
long i = cl->climbcount - 1; i >= 0 ; i--){
1583 k.
lat = cl->climb[i].midlat;
1584 k.lon = cl->climb[i].midlon;
1585 QPointF P(
float(lontox(cl->climb[i].midlon)),
1586 float(lattoy(cl->climb[i].midlat)));
1590 w = QString(
"%1").arg(cl->climb[i].
P,0,
'f',1);
1591 w = QString().fromUtf8(cl->climb[i].name);
1593 p->setFont(QFont(
"Arial",8 + 10 * cl->climb[i].
LocRank,QFont::Bold));
1595 QFontMetricsF fm(p->font());
1597 int drawn = 1, minIntSec = R.height() * R.width()+100;
1599 Track t(cl->climb[i].KOOarray,cl->climb[i].KOOcount);
1600 double d = cl->climb[i].
d / 2.;
1604 for(
double dt = 0.0; dt < d; dt += d/3.){
1605 for(
int dtm = -1; dtm <= 1; dtm = dtm + 2){
1607 P = QPointF(
float(lontox(kt.lon)),
1608 float(lattoy(kt.
lat)));
1609 R = fm.boundingRect(w);
1611 R.translate(-R.width()/2,-R.height()/2);
1613 if(IntSect < minIntSec){
1615 minIntSec = IntSect;
1632 ref[0][0] = &j; ref[0][1] = ≺
1633 ref[1][0] = &j; ref[1][1] = &mr;
1634 ref[2][0] = ≺ ref[2][1] = &j;
1635 ref[3][0] = &mr; ref[3][1] = &j;
1636 R = fm.boundingRect(w);
1637 int radius = floor(min(R.width(),R.height()));
1638 for(pr = 0; pr <= radius; pr++){
1640 for(
double dt = 0.0; dt < d; dt += 0.1){
1641 for(
int dtm = -1; dtm <= 1; dtm = dtm + 2){
1643 P = QPointF(
float(lontox(kt.lon)),
float(lattoy(kt.
lat)));
1644 R = fm.boundingRect(w);
1646 R.translate(-R.width()/2,-R.height()/2);
1647 for(
int k = 0; k < 4; k++){
1648 for(j = -pr; j <= pr; j++){
1650 Rt.translate(*ref[k][0],*ref[k][1]);
1652 if(IntSect < minIntSec){
1654 minIntSec = IntSect;
1655 Pmin = P + QPointF(
float(*(ref[k][0])),
1656 float(*(ref[k][1])));
1673 R = fm.boundingRect(w);
1675 R.translate(-R.width()/2,-R.height()/2);
1676 P = QPointF(R.left(),R.top()+fm.ascent());
1678 Draw_lighted_text(p,&w,P,&blight,&c);
1685 float alpha = 255*cl->climb[i].
LocRank*(1-1.*minIntSec/(R.width()*R.height()));
1695 float d = - R.left() + R.right();
1696 p->setPen(QPen(c,2));
1697 p->drawLine(R.left(),R.top()+1.,R.right(),R.top()+1.);
1698 p->drawLine(R.left(),R.bottom()-1.,R.right(),R.bottom()-1.);
1699 p->setPen(QPen(Qt::white,2));
1700 p->drawLine(R.left(),R.top()+1.,
1701 R.left() + d *qMin(1.,sqrt(
1702 cl->climb[i].
bend*cl->climb[i].
bend*cl->climb[i].
d/48.)),R.top()+1.);
1703 p->drawLine(R.left(),R.bottom()-1.,
1704 R.left() + d*qMin(1.,(cl->climb[i].
slope-5)/10.),R.bottom()-1.);
1710 if(x<0 )
return QColor( 0, 0, 0);
1711 if(x<0.25)
return QColor( 255*x/0.25,255, 0);
1712 if(x<0.50)
return QColor( 255,255*(0.50-x)/0.25, 0);
1713 if(x<0.75)
return QColor(255,0, (x-0.5)/0.25*255);
1714 if(x<=1)
return QColor((1-x)/0.25*255,0,255);
1715 if(x>1)
return QColor(0,0,255);
1718 QColor MAP::colorgradientSchading(
float x){
1721 if(x<0 )
return QColor( 255, 255, 255);
1722 if(x<0.2)
return QColor( min+d*(0.2-x)/0.2,255,min+d*(0.2-x)/0.2);
1723 if(x<0.4)
return QColor( min+d*(x-0.2)/0.2,255, min);
1724 if(x<0.6)
return QColor( 255,min+d*(0.60-x)/0.2, min);
1725 if(x<0.8)
return QColor(255,min, min+d*(x-0.6)/0.2);
1726 if(x<=1)
return QColor(min+d*(1-x)/0.2,min,255);
1727 if(x>1)
return QColor(min,min,255);
1730 inline void MAP::mult_color(
unsigned char* cd, QColor* c){
1731 cd[0] = cd[0] * c->red() / 255.;
1732 cd[1] = cd[1] * c->green() / 255.;
1733 cd[2] = cd[2] * c->blue() / 255.;
points ** locality
< 20 : tag hamlet, locality, isolated_dwelling
void SRTM3ClimbtoMAP(climblayer *cl)
climb layer method: SRTM3 DEM plus shading of climbs
void settings(MapSettings *MS)
assigns new settings
float mperlat
meter per SRTM3 cell vertical
void add_contour()
adds contours to relief
void OSMtoMAP(short getcmap, short drawroads, short drawnature, short drawpoints)
draws Open Street Map data
int lowcontour
small contour step
void reset_Template()
clears tamplate
double heights[5]
heights of 5 step color scale
void draw_line(QPainter *p, KOOlist *k, int kc)
drawing commends from outside
void set(int x, int y, char val)
edge flag algorithm marking the px(x,y), used by linestoTemplate
QPointF HP[28]
help data to render picture
float pxperlon
px per SRTM3 cell horizontal
MAP(HeightData *h, OSM *o)
create with SRTM3 class and OSM-data manager
float index
connection to be drawn
float stheta
precalculated sin
float sphi
precalculated sin
void STRONGlayer_to_Map(QPainter *p, STRONGlayer *SL)
draws STRONG calculation network
short isin(lines *l, double minlat, double maxlat, double minlon, double maxlon)
void add_DEM()
transform heighdata with sun settings into colors
double getminlat()
return real borders
float maxlon
bounding rect, for rendering
float index
for summit ranking
list elements to handle multiple STRONGlayers
container struct to hold data of a coordinate
QRgb roadcolor[6]
color for all different road types
KOO ** node
reference to KOO (of way)
QRgb heightcolor[5]
5 step color scale
void SRTM3toMAP(short getcmap)
draws the relief
short extract_KOO(KOO *k, double d)
creates KOO refering distance point d
float zoomsize(float size)
int highcontour
big contour step
void facetoTemplate(lines **ff, char val)
fills areas marked by edge flag algorithm
void climblayer_schading(climblayer *cl)
climb layer method: shading called from SRTM3ClimbtoMAP()
int nodec
count of used KOO in way
QColor colorgradient(float x)
color functions
short check_TemplateSpace(QRectF R)
check R on the picture if free
float pxperlat
px per SRTM3 cell vertical
void linetomap(OSM *o, QPainter *p, lines **ll, QColor QColor, float linewidth, float minlinewidth)
OSM drawing.
char * name
OSM name of point
holds digital elevation model extracted from SRTM3 data
void ClimbTracks(QPainter *p, climblayer *cl)
climb layer method: draw tracks
official representation of Track in BTP3
void set_rect(double minlat, double maxlat, double minlon, double maxlon)
specifies area of the precalculated data grid
points ** col
mountain pass
double mmaxlat
marcator projection scaled lattitude
void save_to_png(QString filename)
save map as picture to hard disk
void resize(int width, int height)
adapts size, recalculate borders from desired borders
double y_to_lat(int y)
map coordinate information
void interpolate_bicubic_conv3_mercator(int width, int height, double alpha, double **h, double **dhdx, double **dhdy)
returns heigth data grid h with size (width,height)
SunSetting sun
lighting of relief
int width
specified picture format
QRgb pointcolor[6]
fontcolor of town, village, ...
float mperlon
meter per SRTM3 cell horizontal
void set_borders(double latmin0, double latmax0, double lonmin0, double lonmax0)
sets desired borders, recalculate bordes due to window size
KOO ** node
array KOO pointers
double minlat0
desired area with ordinary coordinates
QPixmap * get_Map()
return pixmap of the last generated map
void calc_borders()
desired borders to real borders
void set_TemplateSpace(QRectF R)
marks R on the picture as occupied
char * name
OSM name of line
void draw_map(STRONGlayer *SL, climblayer *cl, Track *ct, int fastmode)
universal high quality drawing
BTP3 database, created from OpenStreetMap data.
void ClimbLabels(QPainter *p, climblayer *cl, int fastmode)
climb layer method: draw labels
int IntSec(QRectF R, char l)
quantifies l-content in r-region
points ** metropolis
100000 : tag city
double minlat
smaller area inside desired conform width picture scales
float pointsize[6]
fontsize of town, village, ...
void linestoTemplate(lines *f, char val)
edge flag algorithm to draw polyedges
void interpolate_linear_mercator(int width, int height, double alpha, double **h, double **dhdx, double **dhdy)
returns heigth data grid h with size (width,height)
void change_intensity(int x, int y, double dI)
void add_BestClimb_Bar(QPainter *p, climblayer *cl)
projects best climbs to the borders of the picture
void htocolorfast(unsigned char *cd, float h, float dxf, float dyf)
function to height to color operation
main container for Track, WayHeight and ClimbAnalyse
osm data container list for line like data (roads, rivers)
float roadwidth[6]
width for all different road types
float ctheta
precalculated cos
osm data container list for point like data (summits, towns, ...)
void climblayer_to_map(climblayer *cl)
draws climbs
float cphi
precalculated cos
int get_status()
returns current class state
points ** village
20 : tag village, suburban
points ** town
3000 : tag town
Way * way
reference element of this list