tcElevationOptimization: fix typo s/write/read/
[tecorrec.git] / geo / tcSrtmCache.cpp
blob3b22e54a52aea131977c31ab5123fff5e92e64a3
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 /**
21 * @file tcSrtmCache.cpp
22 * @brief Manages cache of SRTM data.
25 #include "tcSrtmCache.h"
26 #include "tcSrtmData.h"
27 #include "tcElevationData.h"
29 #include <QString>
30 #include <QStringList>
31 #include <QFile>
33 #include <cstdlib>
36 * Static variables
39 QDir tcSrtmCache::s_dataDirectory("/home/james/cs/pro/data/srtm");
42 * Static functions
45 /// Get a list of datasets.
46 QStringList tcSrtmCache::dataSets()
48 return s_dataDirectory.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name);
52 * Constructors + destructor
55 /// Primary constructor.
56 tcSrtmCache::tcSrtmCache(const QString& dataSet)
57 : m_dataSet(dataSet)
59 for (int i = 0; i < 360; ++i)
61 for (int j = 0; j < 180; ++j)
63 m_cache[i][j] = 0;
68 /// Destructor.
69 tcSrtmCache::~tcSrtmCache()
71 for (int i = 0; i < 360; ++i)
73 for (int j = 0; j < 180; ++j)
75 if ((tcSrtmData*)0x1 != m_cache[i][j])
77 delete m_cache[i][j];
84 * Main interface
87 /// Load raw SRTM height file.
88 tcSrtmData* tcSrtmCache::loadData(int lon, int lat)
90 tcSrtmData*& cacheItem = cache(lon, lat);
91 if (0 == cacheItem)
93 QString filename = QString("%1/%2/%3%4%5%6.hgt")
94 .arg(s_dataDirectory.path())
95 .arg(m_dataSet)
96 .arg(lat >= 0 ? 'N' : 'S')
97 .arg(abs(lat), 2, 10, QLatin1Char('0'))
98 .arg(lon >= 0 ? 'E' : 'W')
99 .arg(abs(lon), 3, 10, QLatin1Char('0'));
100 QFile file(filename);
101 if (file.open(QIODevice::ReadOnly))
103 cacheItem = new tcSrtmData(lon, lat, file, this, SIGNAL(progressing(const QString&)));
105 else
107 // 0x1 represents a previous failed attempt
108 cacheItem = (tcSrtmData*)0x1;
111 if ((tcSrtmData*)0x1 != cacheItem)
113 return cacheItem;
115 else
117 return 0;
121 /// Load raw SRTM height file.
122 tcSrtmData* tcSrtmCache::loadData(const tcGeo& coord)
124 int lon,lat;
125 toIntLonLat(coord, &lon, &lat);
126 return loadData(lon, lat);
129 /** Find some SRTM height data overlapping an area.
130 * @param swCorner Geographical coordinate of south-west corner.
131 * @param neCorner Geographical coordinate of north-east corner.
132 * @returns An arbitrary SRTM data for a chunk in the lon lat range.
134 tcSrtmData* tcSrtmCache::findData(const tcGeo& swCorner, const tcGeo& neCorner)
136 int swLon,swLat;
137 int neLon,neLat;
138 toIntLonLat(swCorner, &swLon, &swLat);
139 toIntLonLat(neCorner, &neLon, &neLat);
140 for (int lon = swLon; lon <= neLon; ++lon)
142 for (int lat = swLat; lat <= neLat; ++lat)
144 tcSrtmData* result = loadData(lon,lat);
145 if (0 != result)
147 return result;
151 return 0;
154 /// Update any samples affected by the elevation field.
155 void tcSrtmCache::updateFromElevationData(const tcElevationData* elevation)
157 tcGeo swCorner = elevation->swCorner();
158 tcGeo neCorner = elevation->neCorner();
159 int mini = (int)floor(swCorner.lon()*180.0/M_PI) + 180;
160 int maxi = (int) ceil(neCorner.lon()*180.0/M_PI) + 180;
161 int minj = (int)floor(swCorner.lat()*180.0/M_PI) + 90;
162 int maxj = (int) ceil(neCorner.lat()*180.0/M_PI) + 90;
163 for (int ii = mini; ii < maxi; ++ii)
165 int i = ii % 360;
166 for (int j = minj; j < maxj; ++j)
168 if (0 != m_cache[i][j] && (tcSrtmData*)0x1 != m_cache[i][j])
170 m_cache[i][j]->updateFromElevationData(elevation);
177 * Private functions
180 /// Convert a geographical coordinate into lon lat ints.
181 void tcSrtmCache::toIntLonLat(const tcGeo& coord, int* const outLon, int* const outLat)
183 int lat = (int)floor(coord.lat() * 180.0/M_PI);
184 int lon = (int)floor(coord.lon() * 180.0/M_PI);
185 lat = lat % 360;
186 if (lat < -90)
188 lat += 360;
190 if (lat >= 90)
192 lat -= 180;
193 lon += 180;
195 lon = lon % 360;
196 if (lon < -180)
198 lon += 360;
200 else if (lon >= 180)
202 lon -= 360;
204 *outLon = lon;
205 *outLat = lat;
208 /// Cache index.
209 tcSrtmData*& tcSrtmCache::cache(int lon, int lat)
211 Q_ASSERT(lon >= -180 && lon < 180);
212 Q_ASSERT(lat >= -90 && lat < 90);
213 return m_cache[180 + lon][90 + lat];