1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * Tecorrec is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * Tecorrec is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with Tecorrec. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
28 double readDouble(QFile
& file
)
30 QByteArray line
= file
.readLine();
31 static QRegExp
intLine("^\\s*\\w+\\s+([-+]?\\d+(\\.\\d+)?)\\s*$");
32 if (intLine
.exactMatch(line
))
34 return intLine
.cap(1).toDouble();
42 int readInt(QFile
& file
)
44 QByteArray line
= file
.readLine();
45 static QRegExp
intLine("^\\s*\\w+\\s+([-+]?\\d+)\\s*$");
46 if (intLine
.exactMatch(line
))
48 return intLine
.cap(1).toInt();
56 int arcToHgt(const QString filename
)
58 qDebug() << "Reading" << filename
;
60 // first open arcinfo file
62 af
.open(QIODevice::ReadOnly
);
64 // and read the header info
65 int ncols
= readInt(af
);
66 int nrows
= readInt(af
);
67 double xllcorner
= readDouble(af
);
68 double yllcorner
= readDouble(af
);
69 double cellsize
= readDouble(af
);
70 int nodata_value
= readInt(af
);
72 // find corresponding HGT tiles
73 int lonMin
= (int)floor(xllcorner
);
74 int lonMax
= (int)floor(xllcorner
+ cellsize
*(ncols
-1));
75 int latMin
= (int)floor(yllcorner
);
76 int latMax
= (int)floor(yllcorner
+ cellsize
*(nrows
-1));
77 int tilesX
= 1+lonMax
-lonMin
;
78 int tilesY
= 1+latMax
-latMin
;
79 QFile
* srtm
= new QFile
[tilesX
*tilesY
];
80 for (int lon
= lonMin
; lon
<= lonMax
; ++lon
)
82 for (int lat
= latMin
; lat
<= latMax
; ++lat
)
84 QString filename
= QString("%3%4%5%6.hgt")
85 .arg(lat
>= 0 ? 'N' : 'S')
86 .arg(abs(lat
), 2, 10, QLatin1Char('0'))
87 .arg(lon
>= 0 ? 'E' : 'W')
88 .arg(abs(lon
), 3, 10, QLatin1Char('0'));
89 int index
= tilesX
*(lat
-latMin
) + lon
-lonMin
;
90 srtm
[index
].setFileName(filename
);
91 srtm
[index
].open(QIODevice::ReadWrite
);
92 // if it doesn't exist, initialize with void
93 if (srtm
[index
].atEnd())
95 qDebug() << " Creating" << filename
;
96 QDataStream
stream(&srtm
[index
]);
97 stream
.setByteOrder(QDataStream::BigEndian
);
98 uint16_t sample
= 0x8000;
99 for (int i
= 0; i
< 1201*1201; ++i
)
106 qDebug() << " Writing to" << filename
;
111 // overwrite directly with new values
114 // go through the rows
115 for (int row
= nrows
-1; row
>= 0; --row
)
117 int y
= (int)floor(0.5 + yllcorner
/cellsize
- latMin
/cellsize
+ nrows
-1-row
);
120 for (int col
= 0; col
< ncols
; ++col
)
122 int x
= (int)floor(0.5 + xllcorner
/cellsize
- lonMin
/cellsize
+ col
);
128 uint16_t sample
= value
;
130 bool inX
= (lonDiv
>= 0 && lonDiv
< tilesX
);
131 bool inY
= (latDiv
>= 0 && latDiv
< tilesY
);
132 bool inXm1
= (lonDiv
> 0 && lonDiv
<= tilesX
);
133 bool inYm1
= (latDiv
> 0 && latDiv
<= tilesY
);
134 #define FILEPOS(X,Y) (((1201-(Y))*1201 + (X))*2)
137 int index
= latDiv
*tilesX
+ lonDiv
;
138 QDataStream
stream(&srtm
[index
]);
139 stream
.setByteOrder(QDataStream::BigEndian
);
140 srtm
[index
].seek(FILEPOS(lonMod
, latMod
));
143 bool edgeX
= (lonMod
== 0);
144 bool edgeY
= (latMod
== 0);
145 if (edgeX
&& inXm1
&& inY
)
147 int index
= latDiv
*tilesX
+ lonDiv
-1;
148 QDataStream
stream(&srtm
[index
]);
149 stream
.setByteOrder(QDataStream::BigEndian
);
150 srtm
[index
].seek(FILEPOS(1200, latMod
));
153 if (edgeY
&& inX
&& inYm1
)
155 int index
= (latDiv
-1)*tilesX
+ lonDiv
;
156 QDataStream
stream(&srtm
[index
]);
157 stream
.setByteOrder(QDataStream::BigEndian
);
158 srtm
[index
].seek(FILEPOS(lonMod
, 1200));
161 if (edgeX
&& edgeY
&& inXm1
&& inYm1
)
163 int index
= (latDiv
-1)*tilesX
+ lonDiv
-1;
164 QDataStream
stream(&srtm
[index
]);
165 stream
.setByteOrder(QDataStream::BigEndian
);
166 srtm
[index
].seek(FILEPOS(1200, 1200));
175 int main(int argc
, char** argv
)
177 qDebug() << "Welcome to arcToHgt";
179 // Convert the file in each argument to HGT, overwriting any existing data
180 for (int i
= 1; i
< argc
; ++i
)
182 error
|= arcToHgt(argv
[i
]);