2 #include "HeightData.h"
6 HeightData::HeightData(){
12 if(minlat > maxlat) maxlat = minlat = 0;
13 if(minlon > maxlon) maxlon = minlon = 0;
19 HeightData::~HeightData(
void){
24 int xminlon = floor(
DEMRect.minlon*1200);
25 int xmaxlon = floor(
DEMRect.maxlon*1200);
26 int yminlat = floor(
DEMRect.minlat*1200);
27 int ymaxlat = floor(
DEMRect.maxlat*1200);
30 GridRect.maxlon = xmaxlon+nReserve+1;
31 GridRect.maxlat = ymaxlat+nReserve+1;
35 grid =
new short*[sy];
36 for(
int i = 0; i < sy; i++){
37 grid[i] =
new short[sx];
38 for(
int j = 0; j < sx; j++)
43 for(
int lon = floor(
GridRect.minlon/1200.); lon <= floor(
GridRect.maxlon/1200.);lon++)
44 for(
int lat = floor(
GridRect.minlat/1200.); lat <= floor(
GridRect.maxlat/1200.);lat++){
47 if(lat < 0 && lon < 0) sprintf(&(filename[0]),
"S%02iW%03i.hgt",-lat,-lon);
48 if(lat < 0 && lon >= 0) sprintf(&(filename[0]),
"S%02iE%03i.hgt",-lat, lon);
49 if(lat >= 0 && lon < 0) sprintf(&(filename[0]),
"N%02iW%03i.hgt", lat,-lon);
50 if(lat >= 0 && lon >= 0) sprintf(&(filename[0]),
"N%02iE%03i.hgt", lat, lon);
54 strcat(path,filename);
56 int ystart = (lat + 1) * 1200 - max(
GridRect.minlat, lat * 1200);
57 int yend = (lat + 1) * 1200 - min(
GridRect.maxlat,(lat+1) * 1200);
58 int yos = (lat + 1) * 1200 -
GridRect.minlat;
59 int xstart = max(lon * 1200,
GridRect.minlon) - lon * 1200;
60 int xend = min((lon+1) * 1200,
GridRect.maxlon) - lon * 1200;
61 int xread = xend - xstart + 1;
64 FILE* f = fopen(path,
"rb");
67 for(
int y = ystart; y >= yend; y--){
68 fseek(f,2*(1201*y+xstart),SEEK_SET);
69 fread(&(
grid[yos-y][xos]),2,xread,f);
75 for(
int y = ystart; y >= yend; y--)
76 for(
int x = xos; x < xos + xread; x++)
81 for(
int y = 0; y < sy; y++)
82 for(
int x = 0; x < sx; x++)
83 grid[y][x] = (((
grid[y][x])>>8)&0xff)+(((
grid[y][x]) << 8)&0xff00);
87 for(
int i = 0; i < sy; i++)
95 return floor(1200*lat) -
GridRect.minlat;
98 return floor(1200*lon) -
GridRect.minlon;
101 return (1200*lat - floor(1200*lat));
104 return (1200*lon - floor(1200*lon));
107 double** h,
double** dhdx,
double** dhdy){
116 for(
int x = 0; x < width; x++){
117 kxx[x].index[2] = kx[x].index[2] =
ltx(1.*x/(width-1)*dlon +
DEMRect.minlon);
118 kxx[x].index[0] = kx[x].index[0] = kx[x].index[2] - 2;
119 kxx[x].index[1] = kx[x].index[1] = kx[x].index[2] - 1;
120 kxx[x].index[3] = kx[x].index[3] = kx[x].index[2] + 1;
121 kxx[x].index[4] = kx[x].index[4] = kx[x].index[2] + 2;
122 kxx[x].index[5] = kx[x].index[5] = kx[x].index[2] + 3;
123 double dx =
ltdx(1.*x/(width-1)*dlon +
DEMRect.minlon);
140 for(
int y = 0; y <
height; y++){
141 kyy[y].index[2] = ky[y].index[2] =
lty(1.*y/(height-1)*dlat +
DEMRect.minlat);
142 kyy[y].index[0] = ky[y].index[0] = ky[y].index[2] - 2;
143 kyy[y].index[1] = ky[y].index[1] = ky[y].index[2] - 1;
144 kyy[y].index[3] = ky[y].index[3] = ky[y].index[2] + 1;
145 kyy[y].index[4] = ky[y].index[4] = ky[y].index[2] + 2;
146 kyy[y].index[5] = ky[y].index[5] = ky[y].index[2] + 3;
147 double dy =
ltdy(1.*y/(height-1)*dlat +
DEMRect.minlat);
162 for(
int x = 0; x < width; x++)
163 for(
int y = 0; y <
height; y++){
179 for(
int x = 1; x < width-1; x++)
180 for(
int y = 1; y < height-1; y++)
181 dhdx[x][y] = (h[x+1][y]-h[x-1][y])/2.*pxperx;
182 for(
int i = 0 ; i < width; i++)
183 dhdx[i][0] = dhdx[i][height-1] = 0;
187 for(
int x = 1; x < width-1; x++)
188 for(
int y = 1; y < height-1; y++)
189 dhdy[x][y] = (h[x][y+1]-h[x][y-1])/2.*pxpery;
190 for(
int i = 0 ; i <
height; i++)
191 dhdy[0][i] = dhdy[width-1][i] = 0;
195 double alpha,
double** h,
196 double** dhdx,
double** dhdy){
204 for(
int x = 0; x < width; x++){
205 kxx[x].index[2] = kx[x].index[2] =
ltx((0.5+x)/width*dlon +
DEMRect.minlon);
206 kxx[x].index[0] = kx[x].index[0] = kx[x].index[2] - 2;
207 kxx[x].index[1] = kx[x].index[1] = kx[x].index[2] - 1;
208 kxx[x].index[3] = kx[x].index[3] = kx[x].index[2] + 1;
209 kxx[x].index[4] = kx[x].index[4] = kx[x].index[2] + 2;
210 kxx[x].index[5] = kx[x].index[5] = kx[x].index[2] + 3;
211 double dx =
ltdx((0.5+x)/width * dlon +
DEMRect.minlon);
226 double* ylat =
new double[
height];
229 double mmax = lattomercator(
DEMRect.maxlat);
230 double mmin = lattomercator(
DEMRect.minlat);
231 double dlat = mmax - mmin;
232 for(
int y = 0; y <
height; y++){
233 ylat[y] = mercatortolat((0.5+y)/height*dlat + mmin);
234 kyy[y].index[2] = ky[y].index[2] =
lty(ylat[y]);
235 kyy[y].index[0] = ky[y].index[0] = ky[y].index[2] - 2;
236 kyy[y].index[1] = ky[y].index[1] = ky[y].index[2] - 1;
237 kyy[y].index[3] = ky[y].index[3] = ky[y].index[2] + 1;
238 kyy[y].index[4] = ky[y].index[4] = ky[y].index[2] + 2;
239 kyy[y].index[5] = ky[y].index[5] = ky[y].index[2] + 3;
240 double dy =
ltdy(ylat[y]);
255 for(
int x = 0; x < width; x++)
256 for(
int y = 0; y <
height; y++){
272 for(
int x = 1; x < width-1; x++)
273 for(
int y = 1; y < height-1; y++)
274 dhdx[x][y] = (h[x+1][y]-h[x-1][y])/2.*pxperx;
275 for(
int i = 0 ; i < width; i++)
276 dhdx[i][0] = dhdx[i][height-1] = 0;
281 for(
int y = 1; y < height-1; y++){
282 pxpery = 2./((ylat[y+1]-ylat[y-1])*1200.);
283 for(
int x = 1; x < width-1; x++)
284 dhdy[x][y] = (h[x][y+1]-h[x][y-1])/2.*pxpery;
286 for(
int i = 0 ; i <
height; i++)
287 dhdy[0][i] = dhdy[width-1][i] = 0;
294 if(x > 2)
return x*x*x/12.-2.*x*x/3.+21.*x/12.-3./2.;
295 if(x > 1)
return -7.*x*x*x/12.+3*x*x-59.*x/12+15./6.;
296 if(x >=0)
return 4.*x*x*x/3.-7.*x*x/3.+1.;
300 int IsGreaterZero = 1;
306 if(x > 3) result = 0;
307 if(x < 3 && x >= 2) result = x*x/4.-4.*x/3.+7./4.;
308 if(x < 2 && x >= 1) result = -7.*x*x/4.+6*x-59./12.;
309 if(x < 1 && x >= 0) result = 4.*x*x-14.*x/3.;
318 for(
int x = 0; x < 6; x++)
319 for(
int y = 0; y < 6; y++)
320 result = result +
grid[ky.index[y]][kx.index[x]]
321 * kx.weights[x] * ky.weights[y];
329 set_rect(minlat,maxlat,minlon,maxlon);
335 result = int(
grid[0][0]);
336 for(
int y = 0; y < sy; y++)
337 for(
int x = 0; x < sx; x++)
338 if(
grid[y][x] > result)
345 kx.index[2] =
ltx(lon);
346 kx.index[0] = kx.index[2] - 2;
347 kx.index[1] = kx.index[2] - 1;
348 kx.index[3] = kx.index[2] + 1;
349 kx.index[4] = kx.index[2] + 2;
350 kx.index[5] = kx.index[2] + 3;
352 ky.index[2] =
lty(lat);
353 ky.index[0] = ky.index[2] - 2;
354 ky.index[1] = ky.index[2] - 1;
355 ky.index[3] = ky.index[2] + 1;
356 ky.index[4] = ky.index[2] + 2;
357 ky.index[5] = ky.index[2] + 3;
359 double dx =
ltdx(lon);
360 double dy =
ltdy(lat);
363 if(ky.index[0] < 0 || ky.index[5] >= sy ||
364 kx.index[0] < 0 || kx.index[5] >= sx)
367 double h = 0,dhdx=0,dhdy=0;
368 if(mode == 0 || hc != NULL){
370 for(
int i = 0; i < 6; i++){
376 if(mode == 1 || mode == 3 || mode == 4){
378 for(
int i = 0; i < 6; i++){
384 if(mode == 2 || mode == 3 || mode == 4){
386 for(
int i = 0; i < 6; i++){
402 return atan2(
double(dhdx),
double(dhdy*cos(lat/180*PI)));
406 double dlat = 0.00007, dlon = dlat/cos(lat/180.*PI);
407 hn[0] =
height_t(lon-2*dlon*((
double*)hc)[1],lat+2*dlat*((
double*)hc)[2],NULL,0);
408 hn[1] =
height_t(lon-1*dlon*((
double*)hc)[1],lat+1*dlat*((
double*)hc)[2],NULL,0);
409 hn[2] =
height_t(lon+1*dlon*((
double*)hc)[1],lat-1*dlat*((
double*)hc)[2],NULL,0);
410 hn[3] =
height_t(lon+2*dlon*((
double*)hc)[1],lat-2*dlat*((
double*)hc)[2],NULL,0);
411 ((
double*)hc)[0]= (2*hn[0]-hn[1]-2*h-hn[2]+2*hn[3])/14.*
412 qAbs(((
double*)hc)[2]*dhdy-((
double*)hc)[1]*dhdx/cos(lat/180*PI));
422 double result =
height_t(lon,lat,hc,mode);
427 int cc,
int ac,
float d,
float mperlon,
float mperlat){
428 int j,i,x,y,ymin,ymax,xmin,xmax, Ac = 0, AcF = 0;
429 float x0 = lon*1200 -
GridRect.minlon;
430 float y0 = lat*1200 -
GridRect.minlat;
431 float sx = mperlon/1000;
432 float sy = mperlat/1000;
433 float h0 =
height_t(lon,lat,NULL,0);
436 int **wc =
new int*[ac];
437 for(i = 0; i < ac; i++)
441 for(i = 0; i < ac; i++)
442 for(j = 0; j < cc; j++){
447 xmin = qMax(0 ,
int(floor(x0-(d*cc)/sx)));
448 xmax = qMin(this->sx-1,
int (ceil(x0+(d*cc)/sx)));
449 for(x = xmin; x <= xmax; x++){
450 ymin = qMax(0 ,
int(floor(y0-sqrt((d*cc*d*cc)-((x-x0)*sx*(x-x0)*sx)+1)/sx)));
451 ymax = qMin(this->sy-1,
int(ceil (y0+sqrt((d*cc*d*cc)-((x-x0)*sx*(x-x0)*sx)+1)/sx)));
452 for(y = ymin; y <= ymax; y++){
453 i = int(floor((atan2(y-y0,x-x0)/PI+1)/2*ac));
454 j = int(floor(sqrt(((y-y0)*sy*(y-y0)*sy)+((x-x0)*sx*(x-x0)*sx))/d));
455 if(i < cc &&
grid[y][x] < 9000
456 && i < ac && j < cc){
457 c[i][j] = c[i][j] + long(
grid[y][x]);
459 if(
grid[y][x] > h0) Ac++;
465 for(i = 0; i < ac; i++)
466 for(j = 0; j < cc; j++)
468 c[i][j] = c[i][j] / wc[i][j];
473 for(i = 0; i < ac; i++)
477 *Ahigher = float(1.*Ac/AcF);
481 double** h,
double** dhdx,
double** dhdy){
486 for(
int x = 0; x < width; x++)
487 for(
int y = 0; y <
height; y++){
490 h[x][height-1-y] = 1.*( +
grid[iy ][ix] +
grid[iy ][ix+1]
491 +
grid[iy+1][ix] +
grid[iy+1][ix+1])/4.;
492 dhdx[x][height-1-y] = 1.*( -
grid[iy ][ix] +
grid[iy ][ix+1]
493 -
grid[iy+1][ix] +
grid[iy+1][ix+1])/2.;
494 dhdy[x][height-1-y] =-1.*( -
grid[iy ][ix] -
grid[iy ][ix+1]
495 +
grid[iy+1][ix] +
grid[iy+1][ix+1])/2.;
499 double** h,
double** dhdx,
double** dhdy){
502 double mmax = lattomercator(
DEMRect.maxlat);
503 double mmin = lattomercator(
DEMRect.minlat);
505 for(
int y = 0; y <
height; y++){
506 iy =
lty(mercatortolat(mmin + (mmax-mmin)*((0.5+y)/height)));
507 for(
int x = 0; x < width; x++){
509 h[x][height-1-y] = 1.*( +
grid[iy ][ix] +
grid[iy ][ix+1]
510 +
grid[iy+1][ix] +
grid[iy+1][ix+1])/4.;
511 dhdx[x][height-1-y] = 1.*( -
grid[iy ][ix] +
grid[iy ][ix+1]
512 -
grid[iy+1][ix] +
grid[iy+1][ix+1])/2.;
513 dhdy[x][height-1-y] =-1.*( -
grid[iy ][ix] -
grid[iy ][ix+1]
514 +
grid[iy+1][ix] +
grid[iy+1][ix+1])/2.;
524 qsh = *heights =
new short[*count];
525 qslon = *lons =
new double[*count];
526 qslat= *lats =
new double[*count];
528 for(
int ii = 0; ii < sy; ii++)
529 for(
int jj = 0; jj < sx; jj++){
530 (*heights)[ii*sx+jj] =
grid[ii][jj];
531 (*lons)[ii*sx+jj] = 1.*(
GridRect.minlon+jj)/1200.;
532 (*lats)[ii*sx+jj] = 1.*(
GridRect.minlat+ii)/1200.;
540 double p = qsh[(s+e)/2], db;
542 while(qsh[l] < p) l++;
543 while(qsh[r] > p) r--;
545 sb = qsh[l]; qsh[l] = qsh[r]; qsh[r] = sb;
546 db = qslon[l]; qslon[l] = qslon[r]; qslon[r] = db;
547 db = qslat[l]; qslat[l] = qslat[r]; qslat[r] = db;
555 recti HeightData::get_GridRect(){
558 int HeightData::correct_hgt(
char* filename){
560 short badheight = -1000;
561 int lnl = strlen(filename);
562 strcpy(&(fn[0]),&(filename[strlen(filename)-11]));
563 int lon = -190,lat = -190;
565 if(fn[3]==
'E') lon = atoi(&(fn[4]));
566 if(fn[3]==
'W') lon = - atoi(&(fn[4]));
568 if(fn[0]==
'N') lat = atoi(&(fn[1]));
569 if(fn[0]==
'S') lat = - atoi(&(fn[1]));
570 bool corrected =
false;
571 if(lon >= -180 && lon < 180 && lat >= -90 && lat < 90){
575 for(
int x = 99; x < 1300; x++)
576 for(
int y = 99; y < 1300; y++)
577 if(
grid[y][x] < badheight){
579 int ym = y, yp = y, xm = x, xp = x;
580 double hy = badheight-100., hx = badheight-100.;
581 while(
grid[ym][x] < badheight && ym > 0) ym--;
582 while(
grid[yp][x] < badheight && yp < sy-1) yp++;
583 while(
grid[y][xm] < badheight && xm > 0) xm--;
584 while(
grid[y][xp] < badheight && xp < sx-1) xp++;
585 short y0 =
grid[y][x];
586 short y1 =
grid[yp][x];
587 short y2 =
grid[ym][x];
588 short y3 =
grid[y][xp];
589 short y4 =
grid[y][xm];
590 if(
grid[ym][x] > badheight &&
grid[yp][x] > badheight)
591 hy = ((yp-y)*
grid[ym][x]+(y-ym)*
grid[yp][x])/(yp-ym);
592 if(
grid[ym][x] > badheight &&
grid[yp][x] > badheight)
593 hx = ((xp-x)*
grid[y][xm]+(x-xm)*
grid[y][xp])/(xp-xm);
594 if(hy > badheight && hx > badheight)
595 grid[y][x] = (hx+hy)/2;
605 FILE* f = fopen(filename,
"wb");
606 for(
int y = 1300; y >= 99; y--){
607 for(
int x = 99; x < 1300; x++)
608 grid[y][x] = (((
grid[y][x])>>8)&0xff)+(((
grid[y][x]) << 8)&0xff00);
609 fwrite(&(
grid[y][100]),2,1201,f);
void get_sorted_grid_data(short **heights, double **lons, double **lats, long *count)
returns sorted raw data heights within the specified area
double height_t(double lon, double lat, void *hc, short mode)
returns height data operating at the precalculated data grid
void interpolate_linear(int width, int height, double alpha, double **h, double **dhdx, double **dhdy)
returns heigth data grid h with size (width,height)
double height(double lon, double lat, void *hc, short mode)
returns height data
void interpolate_bicubic_conv3(int width, int height, double alpha, double **h, double **dhdx, double **dhdy)
returns heigth data grid h with size (width,height)
double Cubic_conv_kernel3(double x)
calculates weights of the bicubic convolution for the absolute height
holds weights for cubic interpolation
holds data grid information with angles multiplied by 1200
void paek_pro(double lon, double lat, qint64 **c, float *Ahigher, int cc, int ac, float d, float mperlon, float mperlat)
evaluates prominence of summits
double Bicubic_conv3(CubicKernel3 kx, CubicKernel3 ky)
executes the bicubic convolution with the kernels kx and ky
void set_rect(double minlat, double maxlat, double minlon, double maxlon)
specifies area of the precalculated data grid
void reset_t(double minlat, double maxlat, double minlon, double maxlon)
generates the data grid being
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)
void set_SRTM3_folder(char *folder)
specifies the folder where hgt-files of SRTM3 data are searched
double Cubic_conv_kernel3_d(double x)
calculates weights of the bicubic convolution for the gradient
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)
int max_t()
maximum height of the precalculated data grid
void sort_GridList(long s, long e)
quick sort used by get_sorted_grid_data()