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 ***************************************************************************/
29 double readDouble(QFile
& file
)
31 QByteArray line
= file
.readLine();
32 static QRegExp
intLine("^\\s*\\w+\\s+([-+]?\\d+(\\.\\d+)?)\\s*$");
33 if (intLine
.exactMatch(line
))
35 return intLine
.cap(1).toDouble();
43 int readInt(QFile
& file
)
45 QByteArray line
= file
.readLine();
46 static QRegExp
intLine("^\\s*\\w+\\s+([-+]?\\d+)\\s*$");
47 if (intLine
.exactMatch(line
))
49 return intLine
.cap(1).toInt();
57 int arcToHgt(const QString filename
, char* voids
)
59 qDebug() << "Reading" << filename
;
61 // first open arcinfo file
63 if (!af
.open(QIODevice::ReadOnly
))
68 // and read the header info
69 int ncols
= readInt(af
);
70 int nrows
= readInt(af
);
71 double xllcorner
= readDouble(af
);
72 double yllcorner
= readDouble(af
);
73 double cellsize
= readDouble(af
);
74 int nodata_value
= readInt(af
);
76 // find corresponding HGT tiles
77 int lonMin
= (int)floor(xllcorner
);
78 int lonMax
= (int)floor(xllcorner
+ cellsize
*(ncols
-1));
79 int latMin
= (int)floor(yllcorner
);
80 int latMax
= (int)floor(yllcorner
+ cellsize
*(nrows
-1));
81 int tilesX
= 1+lonMax
-lonMin
;
82 int tilesY
= 1+latMax
-latMin
;
83 QFile
* srtm
= new QFile
[tilesX
*tilesY
];
87 voidfs
= new QFile
[tilesX
*tilesY
];
89 for (int lon
= lonMin
; lon
<= lonMax
; ++lon
)
91 for (int lat
= latMin
; lat
<= latMax
; ++lat
)
93 QString filename
= QString("%3%4%5%6.hgt")
94 .arg(lat
>= 0 ? 'N' : 'S')
95 .arg(abs(lat
), 2, 10, QLatin1Char('0'))
96 .arg(lon
>= 0 ? 'E' : 'W')
97 .arg(abs(lon
), 3, 10, QLatin1Char('0'));
98 int index
= tilesX
*(lat
-latMin
) + lon
-lonMin
;
99 srtm
[index
].setFileName(filename
);
100 srtm
[index
].open(QIODevice::ReadWrite
);
103 voidfs
[index
].setFileName(QString("%1/%2").arg(voids
).arg(filename
));
104 voidfs
[index
].open(QIODevice::ReadOnly
);
106 // if it doesn't exist, initialize with void
107 if (srtm
[index
].atEnd())
109 qDebug() << " Creating" << filename
;
110 QDataStream
stream(&srtm
[index
]);
111 stream
.setByteOrder(QDataStream::BigEndian
);
112 uint16_t sample
= 0x8000;
113 for (int i
= 0; i
< 1201*1201; ++i
)
120 qDebug() << " Writing to" << filename
;
125 // overwrite directly with new values
128 // go through the rows
129 for (int row
= nrows
-1; row
>= 0; --row
)
131 int y
= (int)floor(0.5 + yllcorner
/cellsize
- latMin
/cellsize
+ row
);
134 for (int col
= 0; col
< ncols
; ++col
)
136 int x
= (int)floor(0.5 + xllcorner
/cellsize
- lonMin
/cellsize
+ col
);
142 uint16_t sample
= value
;
144 bool inX
= (lonDiv
>= 0 && lonDiv
< tilesX
);
145 bool inY
= (latDiv
>= 0 && latDiv
< tilesY
);
146 bool inXm1
= (lonDiv
> 0 && lonDiv
<= tilesX
);
147 bool inYm1
= (latDiv
> 0 && latDiv
<= tilesY
);
148 #define FILEPOS(X,Y) (((1200-(Y))*1201 + (X))*2)
151 int index
= latDiv
*tilesX
+ lonDiv
;
152 // if void flag is set, adjust sample
153 if (0 != voidfs
&& voidfs
[index
].isOpen())
155 QDataStream
stream(&voidfs
[index
]);
156 stream
.setByteOrder(QDataStream::BigEndian
);
157 voidfs
[index
].seek(FILEPOS(lonMod
, latMod
));
165 QDataStream
stream(&srtm
[index
]);
166 stream
.setByteOrder(QDataStream::BigEndian
);
167 srtm
[index
].seek(FILEPOS(lonMod
, latMod
));
170 bool edgeX
= (lonMod
== 0);
171 bool edgeY
= (latMod
== 0);
172 if (edgeX
&& inXm1
&& inY
)
174 int index
= latDiv
*tilesX
+ lonDiv
-1;
175 QDataStream
stream(&srtm
[index
]);
176 stream
.setByteOrder(QDataStream::BigEndian
);
177 srtm
[index
].seek(FILEPOS(1200, latMod
));
180 if (edgeY
&& inX
&& inYm1
)
182 int index
= (latDiv
-1)*tilesX
+ lonDiv
;
183 QDataStream
stream(&srtm
[index
]);
184 stream
.setByteOrder(QDataStream::BigEndian
);
185 srtm
[index
].seek(FILEPOS(lonMod
, 1200));
188 if (edgeX
&& edgeY
&& inXm1
&& inYm1
)
190 int index
= (latDiv
-1)*tilesX
+ lonDiv
-1;
191 QDataStream
stream(&srtm
[index
]);
192 stream
.setByteOrder(QDataStream::BigEndian
);
193 srtm
[index
].seek(FILEPOS(1200, 1200));
208 int main(int argc
, char** argv
)
210 qDebug() << "Welcome to arcToHgt";
212 // Convert the file in each argument to HGT, overwriting any existing data
214 for (int i
= 1; i
< argc
; ++i
)
216 if (0 == strcmp(argv
[i
], "--voids"))
218 // next argument is voids directory
222 qDebug() << "Using voids from " << voids
;
227 error
|= arcToHgt(argv
[i
], voids
);