/
gibs_download.cpp
165 lines (146 loc) · 6.69 KB
/
gibs_download.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
This code downloads images from GIBS to generate LANCE-compatible images for the old cloudless, as a temporary fix between the LANCE-MODIS HDD crash and the upcoming recovery.
This program is not complete, as the input parameters and outputs still have to change to make it compatible with the old download.sh
BTW, the corrected reflectance from GIBS seems to be more reliable to me.
http://map1.vis.earthdata.nasa.gov/wmts-geo/MODIS_Terra_Data_No_Data/default/2014-01-01/EPSG4326_250m/0/0/0.png
How about 250m water mask? It could also be used.
*/
// Headers for GDAL
#include <gdal_priv.h>
#include "cpl_conv.h"
// Headers for OpenCV
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/opencv.hpp>
// Other general headers
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
// For calling wait()
#include <sys/types.h>
#include <sys/wait.h>
using namespace cv;
using namespace std;
char normal_bounds[] = "<UpperLeftX>-180.0</UpperLeftX><UpperLeftY>90</UpperLeftY><LowerRightX>396.0</LowerRightX><LowerRightY>-198</LowerRightY><TileLevel>8</TileLevel><TileCountX>2</TileCountX><TileCountY>1</TileCountY>";
char arctic_bounds[] = "<UpperLeftX>-4194304.0</UpperLeftX><UpperLeftY>4194304.0</UpperLeftY><LowerRightX>-4194304.0</LowerRightX><LowerRightY>4194304.0</LowerRightY><TileLevel>5</TileLevel><TileCountX>2</TileCountX><TileCountY>2</TileCountY>";
char antarctic_bounds[] = "<UpperLeftX>-4194304.0</UpperLeftX><UpperLeftY>4194304.0</UpperLeftY><LowerRightX>-4194304.0</LowerRightX><LowerRightY>4194304.0</LowerRightY><TileLevel>5</TileLevel><TileCountX>2</TileCountX><TileCountY>2</TileCountY>";
char wms_format[] = "<GDAL_WMS>"
"<Service name=\"TMS\">"
// arctic/geo/antarctic, Terra/Aqua, CorrectedReflectance_TrueColor/Data_No_Data, then yyyy-mm-dd, EPSG , jpg/png
"<ServerUrl>http://map1.vis.earthdata.nasa.gov/wmts-%s/MODIS_%s_%s/default/%04d-%02d-%02d/%s_250m/${z}/${y}/${x}.%s</ServerUrl>"
"</Service>"
"<DataWindow>%s<YOrigin>top</YOrigin></DataWindow>"
// North - EPSG:3413, Rectangular - EPSG:4326, South - EPSG:3031
"<Projection>%s</Projection>"
"<BlockSizeX>512</BlockSizeX>"
"<BlockSizeY>512</BlockSizeY>"
// JPG - 3, PNG - 4
"<BandsCount>%u</BandsCount>"
"</GDAL_WMS>";
// Data common to all threads
int year, month, day;
int row, col;
int daynum;
typedef enum {NORTH, NORMAL, SOUTH} region;
typedef enum {TERRA, AQUA} satellite;
typedef enum {REFLECTANCE, MASK} data_layer;
typedef enum {JPG, PNG} data_format;
int download(region regionFlag, satellite satFlag, data_layer dataFlag, data_format typeFlag){
GDALDataset *poDataset = NULL;
Mat imageBuffer, outputBuffer;
double pixel2geo[6];
double geo2pixel[6];
uint64_t xmin, ymin;
uint64_t xsize, ysize;
char GIBS_XML[1000];
char outFileName[100];
int numChannel;
// Get the data
sprintf(GIBS_XML, wms_format, /* Region name */ (regionFlag==NORTH)?"arctic":((regionFlag==NORMAL)?"geo":"antarctic"),
/*Satellite name */ (satFlag==TERRA)?"Terra":"Aqua",
/*Data layer name */ (dataFlag==REFLECTANCE)?"CorrectedReflectance_TrueColor":"Data_No_Data",
year, month, day,
/*Region EPSG code*/ (regionFlag==NORTH)?"EPSG3413":((regionFlag==NORMAL)?"EPSG4326":"EPSG3031"),
/*Data Format */ (typeFlag==JPG)?"jpg":"png",
/*Region EPSG code*/ (regionFlag==NORTH)?arctic_bounds:((regionFlag==NORMAL)?normal_bounds:antarctic_bounds),
/*Region EPSG code*/ (regionFlag==NORTH)?"EPSG:3413":((regionFlag==NORMAL)?"EPSG:4326":"EPSG:3031"),
(typeFlag==JPG)?3:4);
printf("%s\n\n", GIBS_XML);
// Open file
poDataset = (GDALDataset*) GDALOpen(GIBS_XML, GA_ReadOnly);
if(!poDataset){
fprintf(stderr,"File cannot be opened!\n");return 1;
}
// Print some metadata
xsize = poDataset->GetRasterXSize();
ysize = poDataset->GetRasterYSize();
numChannel = poDataset->GetRasterCount();
// Calculate coordinates
poDataset->GetGeoTransform(pixel2geo);
GDALInvGeoTransform(pixel2geo, geo2pixel);
double lat_offset, lon_offset;
switch(regionFlag){
case NORTH:
xmin = (col-1)*4096;
ymin = (6-row)*4096;
break;
case NORMAL:
GDALApplyGeoTransform(geo2pixel, (col-20)*9.0, (row-9)*9.0, &lon_offset, &lat_offset);
xmin = (int) lon_offset;
ymin = (int) lat_offset;
break;
case SOUTH:
xmin = (col-1)*4096;
ymin = (6-row)*4096;
break;
}
printf("Offset=(%lf,%lf)\n",lon_offset,lat_offset);
// Read Image data
ysize = 4096;
xsize = 4096;
imageBuffer.create(ysize, xsize, CV_8UC1);
outputBuffer.create(ysize, xsize, (typeFlag==JPG)?CV_8UC3:CV_8UC4);
outputBuffer.zeros(ysize, xsize, (typeFlag==JPG)?CV_8UC3:CV_8UC4);
int bandArray[1];
for(int i=0;i<((typeFlag==JPG)?3:4);i++){
bandArray[0] = i+1;
imageBuffer.zeros(ysize, xsize, CV_8U);
poDataset->RasterIO(GF_Read, xmin, ymin, xsize, ysize,
(void*) imageBuffer.ptr(0), xsize, ysize,
GDT_Byte, 1, bandArray, 0, 0, 0);
for(int x=0;x<xsize;x++){
for(int y=0;y<ysize;y++){
((uint8_t*)(outputBuffer.data))[(y*xsize+x)*numChannel+(numChannel-i-1)] = ((uint8_t*)(imageBuffer.data))[y*xsize+x];
}
}
}
if(typeFlag==PNG){
outputBuffer = (outputBuffer==0);
outputBuffer.convertTo(outputBuffer, CV_8UC1, 1, 0);
}
sprintf(outFileName, "%s_r%02dc%02d.%04d%03d.%s%s250m.%s", (regionFlag==NORTH)?"RRArctic":((regionFlag==NORMAL)?"RRGlobal":"RRAntarctic"), row, col, year, daynum,
(satFlag==TERRA)?"terra":"aqua", (dataFlag==REFLECTANCE)?".":".opaque.", (typeFlag==JPG)?"jpg":"png");
imwrite(outFileName, outputBuffer);
printf("File %s is written\n", outFileName);
return 0;
}
int main(int argc, char* argv[]){
// New main function
// Read arguments
year = 2014; month = 1; day = 1; daynum = 1;
row = 12; col = 32;
// Prepare the GDAL driver
GDALAllRegister();
//download(NORMAL, TERRA, REFLECTANCE, JPG);
//download(NORMAL, AQUA, REFLECTANCE, JPG);
for(day=1;day<=16;day++){
daynum=day;
if(fork()==0){download(NORMAL, TERRA, MASK, PNG);exit(0);}
if(fork()==0){download(NORMAL, AQUA, MASK, PNG);exit(0);}
if(fork()==0){download(NORMAL, TERRA, REFLECTANCE, JPG);exit(0);}
if(fork()==0){download(NORMAL, AQUA, REFLECTANCE, JPG);exit(0);}
for(int j=0;j<4;j++)wait(NULL);
}
return 0;
}