Fix arc to hgt converter overwriting and make more verbose
[tecorrec.git] / arctohgt / arcToHgt.cpp
blob6ce5052bd779df64b08e330219035801e4d3d493
1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
20 #include <QString>
21 #include <QByteArray>
22 #include <QFile>
23 #include <QRegExp>
24 #include <QtDebug>
26 #include <cmath>
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();
36 else
38 return -1;
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();
50 else
52 return -1;
56 int arcToHgt(const QString filename)
58 qDebug() << "Reading" << filename;
60 // first open arcinfo file
61 QFile af(filename);
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)
101 stream << sample;
104 else
106 qDebug() << " Writing to" << filename;
111 // overwrite directly with new values
113 QTextStream in(&af);
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);
118 int latDiv = y/1200;
119 int latMod = y%1200;
120 for (int col = 0; col < ncols; ++col)
122 int x = (int)floor(0.5 + xllcorner/cellsize - lonMin/cellsize + col);
123 int lonDiv = x/1200;
124 int lonMod = x%1200;
126 int value;
127 in >> value;
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)
135 if (inX && inY)
137 int index = latDiv*tilesX + lonDiv;
138 QDataStream stream(&srtm[index]);
139 stream.setByteOrder(QDataStream::BigEndian);
140 srtm[index].seek(FILEPOS(lonMod, latMod));
141 stream << sample;
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));
151 stream << sample;
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));
159 stream << sample;
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));
167 stream << sample;
172 delete [] srtm;
175 int main(int argc, char** argv)
177 qDebug() << "Welcome to arcToHgt";
178 int error = 0;
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]);
184 return error;