56 #define DEGREE_STRING "Decimal Degree (DD)"
57 #define METER_STRING "METERS"
68 static PGSt_integer DEM_layers[
LAYERS]={PGSd_DEM_ELEV};
69 static PGSt_double fillValue[
LAYERS]={-9999.0};
71 static PGSt_double scaling[
LAYERS]={1.0};
80 static double tile_ver_size=8;
93 static short int *DEM_record;
96 static short int *height_min;
97 static short int *height_max;
100 static short int *DEM_tile_data=
NULL;
101 static int current_tile=-1;
102 static double corner_lat;
103 static double corner_lon;
104 static double lat_inc=
DEG2RAD/120.0;
105 static double lon_inc=
DEG2RAD/120.0;
124 static int firstRun = 1;
127 DEM_record = (
short int*) calloc(
MAX_DEM_TILES,
sizeof(
short int));
128 height_min = (
short int*) calloc(
MAX_DEM_TILES,
sizeof(
short int));
129 height_max = (
short int*) calloc(
MAX_DEM_TILES,
sizeof(
short int));
210 #define TILES_BASE 90.0
211 #define COSLAT_OFFSET 0.1059
221 PGSt_double pixLatInfo[2]={1.0/120.0, 1.0/240.0};
222 PGSt_double pixLonInfo[2]={1.0/120.0, 1.0/240.0};
226 char positionUnits[30]=
"", dataUnits[30]=
"";
227 char msgbuf[
sizeof(positionUnits)+
sizeof(dataUnits)+64];
229 char filefunc[] = __FILE__
", GEO_initialize_DEM";
243 pixLonInfo, positionUnits, &scaling[0], &
offset[0], &fillValue[0],
244 dataUnits,
NULL,
NULL) !=PGS_S_SUCCESS)
246 sprintf(msgbuf,
"PGS_DEM_GetMetadata(%ld,%ld)",
253 for(
p1=positionUnits;
p1 < positionUnits+
sizeof(positionUnits) &&
255 for(p2=dataUnits; p2 < dataUnits+
sizeof(dataUnits) &&
259 sizeof(positionUnits)-(size_t)(
p1-positionUnits)) ||
260 strncmp(p2,
METER_STRING,
sizeof(dataUnits)-(size_t)(p2-dataUnits)) ||
263 sprintf(msgbuf,
"\"%.*s\", \"%.*s\" scale:%g offset:%g",
264 (
int)
sizeof(positionUnits), positionUnits,
265 (
int)
sizeof(dataUnits), dataUnits, scaling[0],
offset[0]);
273 lon_inc = pixLonInfo[0]*
DEG2RAD;
274 lat_inc = -pixLatInfo[0]*
DEG2RAD;
275 min_lat = pixLatInfo[0]*0.5 - 90.0;
276 max_lon = 180.0 - 0.5 * pixLonInfo[0];
280 row_start_tile[0] = 0;
281 for(row=0; row<num_rows; row++)
287 top_lat += tile_ver_size;
289 coslat = cos(top_lat);
300 if(row_num_tiles[row] < 1 || row==0 || row==num_rows-1)
301 row_num_tiles[row] = 1;
304 num_tiles = row_start_tile[row]+row_num_tiles[row];
306 row_start_tile[row+1] = (short)(row_start_tile[row]+row_num_tiles[row]);
309 for(tile=0; tile<num_tiles; tile++)
311 height_min[tile] = SHRT_MAX;
312 height_max[tile] = SHRT_MIN;
520 #define BORDER 0.004084
531 double tile_hor_size=1.0;
534 PGSt_double firstElement[2]={0.0};
538 PGSt_integer sizeDataType=0;
539 PGSt_integer numPixVertical=0, numPixHorizontal[PARTS];
544 int16 *inrow, *outrow;
546 unsigned short int ci;
548 char filefunc[] = __FILE__
", GEO_read_DEM";
551 if( hgtmin ==
NULL || hgtmax ==
NULL ||
554 sprintf(msgbuf,
"lat:%g hgtmin:%p hgtmax:%p",
lat, (
void *)hgtmin,
579 tile = row_start_tile[row] + col;
615 hor_size = ver_size = 0;
618 DEM_tile_data = (
short int *)
NULL;
633 else if( row == num_rows-1 )
645 if( corner_lat < 0.0 )
646 border =
BORDER/cos(corner_lat);
648 border =
BORDER/cos(corner_lat+tile_ver_size);
661 if( row_num_tiles[row] == 1 )
670 (tile_hor_size+2.0*border)*
RAD2DEG;
687 if( PGS_DEM_GetSize(
DEM_resolutions[0], PGSd_DEM_ELEV, PGSd_DEM_DEGREE,
690 != PGS_S_SUCCESS || numPixVertical<=0 || numPixHorizontal[
WEST]<=0)
692 sprintf(msgbuf,
"PGS_DEM_GetSize({%g,%g}, {%g,%g})",
latitude[0],
694 modsmf(
MODIS_E_GEO, msgbuf,
"GEO_DEM.c, GEO_read_DEM");
699 if( (
size_t)sizeDataType !=
sizeof(tempdata[0][0]) )
701 sprintf(msgbuf,
"%ld", (
long)sizeDataType);
706 ver_size = numPixVertical;
707 hor_size = numPixHorizontal[
WEST];
710 (
size_t)(numPixVertical*numPixHorizontal[
WEST]*sizeDataType) );
715 PGSd_DEM_ELEV, PGSd_DEM_DEGREE, PGSd_DEM_NEAREST_NEIGHBOR,
719 corner_lat = firstElement[0]*
DEG2RAD;
720 corner_lon = firstElement[1]*
DEG2RAD;
721 hor_start = ver_start = 0;
723 if( row_num_tiles[row]==1 )
745 inrow = tempdata[
WEST] + (numPixVertical-2)*numPixHorizontal[
WEST];
746 for(
i = 0;
i < numPixHorizontal[
WEST];
i++ )
747 pole += (
long)inrow[
i];
748 pole /= (long)numPixHorizontal[
WEST];
750 else if( row == num_rows-1 )
760 inrow = tempdata[
WEST];
761 for(
i = 0;
i < numPixHorizontal[
WEST];
i++ )
762 pole += (
long)inrow[
i];
763 pole /= (long)numPixHorizontal[
WEST];
767 (ver_size*hor_size*sizeDataType));
769 if( DEM_tile_data !=
NULL )
771 for(
i = 0;
i < numPixVertical;
i++ )
773 inrow = tempdata[
WEST]+
i*numPixHorizontal[
WEST];
776 outrow = DEM_tile_data + (
i+ver_start)*hor_size;
779 outrow[0] = inrow[numPixHorizontal[
WEST]-1];
780 outrow[hor_size-1] = inrow[0];
782 for(
j = 0;
j < numPixHorizontal[
WEST];
j++ )
783 outrow[
j+1] = inrow[
j];
787 outrow = DEM_tile_data + (ver_size-1)*hor_size;
788 else if(row == num_rows-1)
789 outrow = DEM_tile_data;
794 for(
j = 0;
j < hor_size;
j++ )
798 else if( col == 0 || col == row_num_tiles[row]-1 )
807 == PGS_S_SUCCESS && numPixVertical>0 && numPixHorizontal[
EAST]>0)
810 (numPixVertical*numPixHorizontal[
EAST]*sizeDataType));
821 hor_size += numPixHorizontal[
EAST];
823 (ver_size*hor_size*sizeDataType));
827 if( DEM_tile_data !=
NULL )
829 for(
i = 0;
i < ver_size;
i++ )
834 outrow = DEM_tile_data +
i*hor_size;
835 inrow = tempdata[
WEST] +
i*numPixHorizontal[
WEST];
836 for(
j = 0;
j < numPixHorizontal[
WEST];
j++ )
837 outrow[
j] = inrow[
j];
842 outrow += numPixHorizontal[
WEST];
843 inrow = tempdata[
EAST] +
i*numPixHorizontal[
EAST];
844 for(
j = 0;
j < numPixHorizontal[
EAST];
j++ )
845 outrow[
j] = inrow[
j];
851 DEM_tile_data = tempdata[
WEST];
855 if( DEM_tile_data !=
NULL )
859 for(
i = ver = 0; ver < ver_size; ver++)
860 for(hor = 0; hor < hor_size; hor++,
i++)
874 double lat = (ver - ver_start)*lat_inc + corner_lat;
875 double lon = (hor - hor_start)*lon_inc + corner_lon;
880 sprintf(msgbuf,
"GEO_get_geoid(%g,%g) = %d",
886 DEM_tile_data[
i] += geoid_height;
887 if( DEM_tile_data[
i] < height_min[tile] )
888 height_min[tile] = DEM_tile_data[
i];
890 if( DEM_tile_data[
i] > height_max[tile] )
891 height_max[tile] = DEM_tile_data[
i];
897 DEM_record[tile] = (short)tile;
899 temp_cache.
tile = tile;
916 free(tempdata[
WEST]);
917 free(tempdata[
EAST]);
922 if( DEM_tile_data ==
NULL )
924 modsmf(
MODIS_E_GEO,
"GEO_DEMalloc()",
"GEO_DEM.c, GEO_read_DEM");
936 *hgtmin = (
int)height_min[tile];
937 *hgtmax = (
int)height_max[tile];
1024 int near_DEM[2][2] = {0};
1031 dlon =
lon - corner_lon;
1032 dlat =
lat - corner_lat;
1037 dlon = dlon - 2.0*
PGS_PI;
1040 dlon = dlon + 2.0*
PGS_PI;
1044 hor = dlon / lon_inc + (
double)hor_start;
1045 ver = dlat / lat_inc + (
double)ver_start;
1049 if( (hor < 0.0) || (hor >= (
double)hor_size) ||
1050 (ver < 0.0) || (ver >= (
double)ver_size)) {
1053 "GEO_DEM.c, GEO_latlon2height");
1068 dhor = modf(hor, &dihor);
1069 dver = modf(ver, &diver);
1075 near_DEM[0][0] = (
int)DEM_tile_data[iver * hor_size + ihor];
1076 near_DEM[0][1] = (
int)DEM_tile_data[iver * hor_size + ihor + 1];
1077 near_DEM[1][0] = (
int)DEM_tile_data[(iver + 1) * hor_size + ihor];
1078 near_DEM[1][1] = (
int)DEM_tile_data[(iver + 1) * hor_size + ihor + 1];
1082 *
h = (
double)near_DEM[0][0] * (1.0 - dhor) * (1.0 - dver)
1083 + (
double)near_DEM[0][1] * dhor * (1.0 - dver)
1084 + (
double)near_DEM[1][0] * (1.0 - dhor) * dver
1085 + (
double)near_DEM[1][1] * dhor * dver;
1142 char filefunc[] = __FILE__
", GEO_close_DEM";
1158 sprintf(msgbuf,
"PGS_DEM_Close(%d, 1)",
RESOLUTIONS);
1164 return PGS_S_SUCCESS;