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 ***************************************************************************/
21 * @file tcSrtmCache.cpp
22 * @brief Manages cache of SRTM data.
25 #include "tcSrtmCache.h"
26 #include "tcSrtmData.h"
27 #include "tcElevationData.h"
30 #include <QStringList>
39 QDir
tcSrtmCache::s_dataDirectory("/home/james/cs/pro/data/srtm");
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
)
59 for (int i
= 0; i
< 360; ++i
)
61 for (int j
= 0; j
< 180; ++j
)
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
])
87 /// Load raw SRTM height file.
88 tcSrtmData
* tcSrtmCache::loadData(int lon
, int lat
)
90 tcSrtmData
*& cacheItem
= cache(lon
, lat
);
93 QString filename
= QString("%1/%2/%3%4%5%6.hgt")
94 .arg(s_dataDirectory
.path())
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
&)));
107 // 0x1 represents a previous failed attempt
108 cacheItem
= (tcSrtmData
*)0x1;
111 if ((tcSrtmData
*)0x1 != cacheItem
)
121 /// Load raw SRTM height file.
122 tcSrtmData
* tcSrtmCache::loadData(const tcGeo
& coord
)
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
)
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
);
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
)
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
);
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
);
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
];