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::WriteOnly
);
92 // if it doesn't exist, initialize with void
93 if (srtm
[index
].atEnd())
95 QDataStream
stream(&srtm
[index
]);
96 stream
.setByteOrder(QDataStream::BigEndian
);
97 uint16_t sample
= 0x8000;
98 for (int i
= 0; i
< 1201*1201; ++i
)
106 // overwrite directly with new values
109 // go through the rows
110 for (int row
= 0; row
< nrows
; ++row
)
112 int y
= (int)floor(0.5 + yllcorner
/cellsize
- latMin
/cellsize
+ nrows
-1-row
);
115 for (int col
= 0; col
< ncols
; ++col
)
117 int x
= (int)floor(0.5 + xllcorner
/cellsize
- lonMin
/cellsize
+ col
);
123 uint16_t sample
= value
;
125 bool inX
= (lonDiv
>= 0 && lonDiv
< tilesX
);
126 bool inY
= (latDiv
>= 0 && latDiv
< tilesY
);
127 bool inXm1
= (lonDiv
> 0 && lonDiv
<= tilesX
);
128 bool inYm1
= (latDiv
> 0 && latDiv
<= tilesY
);
129 #define FILEPOS(X,Y) (((1201-(Y))*1201 + (X))*2)
132 int index
= latDiv
*tilesX
+ lonDiv
;
133 QDataStream
stream(&srtm
[index
]);
134 stream
.setByteOrder(QDataStream::BigEndian
);
135 srtm
[index
].seek(FILEPOS(lonMod
, latMod
));
138 bool edgeX
= (lonMod
== 0);
139 bool edgeY
= (latMod
== 0);
140 if (edgeX
&& inXm1
&& inY
)
142 int index
= latDiv
*tilesX
+ lonDiv
-1;
143 QDataStream
stream(&srtm
[index
]);
144 stream
.setByteOrder(QDataStream::BigEndian
);
145 srtm
[index
].seek(FILEPOS(1200, latMod
));
148 if (edgeY
&& inX
&& inYm1
)
150 int index
= (latDiv
-1)*tilesX
+ lonDiv
;
151 QDataStream
stream(&srtm
[index
]);
152 stream
.setByteOrder(QDataStream::BigEndian
);
153 srtm
[index
].seek(FILEPOS(lonMod
, 1200));
156 if (edgeX
&& edgeY
&& inXm1
&& inYm1
)
158 int index
= (latDiv
-1)*tilesX
+ lonDiv
-1;
159 QDataStream
stream(&srtm
[index
]);
160 stream
.setByteOrder(QDataStream::BigEndian
);
161 srtm
[index
].seek(FILEPOS(1200, 1200));
170 int main(int argc
, char** argv
)
172 qDebug() << "Welcome to arcToHgt";
174 // Convert the file in each argument to HGT, overwriting any existing data
175 for (int i
= 1; i
< argc
; ++i
)
177 error
|= arcToHgt(argv
[i
]);