_progress.setMaximum(inTileList.size());
_progress.setValue(0);
}
- String errorMessage = null;
- // Get urls for each tile
- URL[] urls = TileFinder.getUrls(inTileList);
- for (int t=0; t<inTileList.size() && !_progress.isCancelled() && urls != null; t++)
+ String errorMessage = "";
+ for (int t=0; t<inTileList.size() && !_progress.isCancelled(); t++)
{
- if (urls[t] != null)
+ SrtmTile tile = inTileList.get(t);
+ SrtmSource srtmSource = tile.findBestCachedSource();
+
+ if (srtmSource == null)
{
- SrtmTile tile = inTileList.get(t);
- try
- {
- // Set progress
- _progress.setValue(t);
- final int ARRLENGTH = 1201 * 1201;
- int[] heights = new int[ARRLENGTH];
- // Open zipinputstream on url and check size
- ZipInputStream inStream = getStreamToHgtFile(urls[t]);
- boolean entryOk = false;
- if (inStream != null)
- {
- ZipEntry entry = inStream.getNextEntry();
- entryOk = (entry != null && entry.getSize() == HGT_SIZE);
- if (entryOk)
- {
- // Read entire file contents into one byte array
- for (int i = 0; i < ARRLENGTH; i++)
- {
- heights[i] = inStream.read() * 256 + inStream.read();
- if (heights[i] >= 32768) {heights[i] -= 65536;}
- }
- }
- // else {
- // System.out.println("length not ok: " + entry.getSize());
- // }
- // Close stream from url
- inStream.close();
- }
+ errorMessage += "Tile "+tile.getTileName()+" not in cache!\n";
+ continue;
+ }
- if (entryOk)
- {
- numAltitudesFound += applySrtmTileToWholeTrack(tile, heights, inOverwriteZeros);
- }
- }
- catch (IOException ioe) {
- errorMessage = ioe.getClass().getName() + " - " + ioe.getMessage();
- }
+ // Set progress
+ _progress.setValue(t);
+
+ int[] heights;
+ try {
+ heights = srtmSource.getTileHeights(tile);
+ }
+ catch (SrtmSourceException e)
+ {
+ errorMessage += e.getMessage();
+ e.printStackTrace();
+ continue;
}
- // Loop over all points in track, try to apply altitude from array
- for (int p = 0; p < _track.getNumPoints(); p++)
- {
- DataPoint point = _track.getPoint(p);
- if (needsAltitude(point, inOverwriteZeros))
- {
- if (new SrtmTile(point).equals(tile))
- {
- double x = (point.getLongitude().getDouble() - tile.getLongitude()) * (rowSize - 1);
- double y = rowSize - (point.getLatitude().getDouble() - tile.getLatitude()) * (rowSize - 1);
- int idx1 = ((int)y)*rowSize + (int)x;
- try
- {
- int[] fouralts = {heights[idx1], heights[idx1+1], heights[idx1-rowSize], heights[idx1-rowSize+1]};
- int numVoids = (fouralts[0]==VOID_VAL?1:0) + (fouralts[1]==VOID_VAL?1:0)
- + (fouralts[2]==VOID_VAL?1:0) + (fouralts[3]==VOID_VAL?1:0);
- // if (numVoids > 0) System.out.println(numVoids + " voids found");
- double altitude = 0.0;
- switch (numVoids)
- {
- case 0: altitude = bilinearInterpolate(fouralts, x, y); break;
- case 1: altitude = bilinearInterpolate(fixVoid(fouralts), x, y); break;
- case 2:
- case 3: altitude = averageNonVoid(fouralts); break;
- default: altitude = VOID_VAL;
- }
- // Special case for terrain tracks, don't interpolate voids yet
- if (!_normalTrack && numVoids > 0) {
- altitude = VOID_VAL;
- }
- if (altitude != VOID_VAL)
- {
- point.setFieldValue(Field.ALTITUDE, ""+altitude, false);
- // depending on settings, this value may have been added as feet, we need to force metres
- point.getAltitude().reset(new Altitude((int)altitude, UnitSetLibrary.UNITS_METRES));
- numAltitudesFound++;
- }
- }
- catch (ArrayIndexOutOfBoundsException obe) {
- errorMessage += "Point not in tile? lat=" + point.getLatitude().getDouble() + ", x=" + x + ", y=" + y + ", idx=" + idx1+"\n";
- }
- }
- }
- }
+ int rowSize = srtmSource.getRowSize(tile);
+ if (rowSize <= 0)
+ {
+ errorMessage += "Tile "+tile.getTileName()+" is corrupted";
+ }
+
++ numAltitudesFound += applySrtmTimeToWholeTrack(tile, heights, rowSize, inOverwriteZeros);
}
_progress.dispose();
}
}
- /**
- * See whether the SRTM file is already available locally first, then try online
- * @param inUrl URL for online resource
- * @return ZipInputStream either on the local file or on the downloaded zip file
- */
- private ZipInputStream getStreamToHgtFile(URL inUrl)
- throws IOException
- {
- String diskCachePath = Config.getConfigString(Config.KEY_DISK_CACHE);
- if (diskCachePath != null)
- {
- File srtmDir = new File(diskCachePath, "srtm");
- if (srtmDir.exists() && srtmDir.isDirectory() && srtmDir.canRead())
- {
- File srtmFile = new File(srtmDir, new File(inUrl.getFile()).getName());
- if (srtmFile.exists() && srtmFile.isFile() && srtmFile.canRead()
- && srtmFile.length() > 400)
- {
- // System.out.println("Lookup: Using file " + srtmFile.getAbsolutePath());
- // File found, use this one
- return new ZipInputStream(new FileInputStream(srtmFile));
- }
- }
- }
- // System.out.println("Lookup: Trying online: " + inUrl.toString());
- _hadToDownload = true;
- // MAYBE: Only download if we're in online mode?
- return new ZipInputStream(inUrl.openStream());
- }
-
+ /**
+ * Given the height data read in from file, apply the given tile to all points
+ * in the track with missing altitude
+ * @param inTile tile being applied
+ * @param inHeights height data read in from file
+ * @param inOverwriteZeros true to overwrite zero altitude values
+ * @return number of altitudes found
+ */
- private int applySrtmTileToWholeTrack(SrtmTile inTile, int[] inHeights, boolean inOverwriteZeros)
++ private int applySrtmTimeToWholeTrack(SrtmTile inTile, int[] inHeights, int inRowSize, boolean inOverwriteZeros)
+ {
+ int numAltitudesFound = 0;
+ // Loop over all points in track, try to apply altitude from array
+ for (int p = 0; p < _track.getNumPoints(); p++)
+ {
+ DataPoint point = _track.getPoint(p);
- if (!point.hasAltitude()
- || (inOverwriteZeros && point.getAltitude().getValue() == 0))
++ if (needsAltitude(point, inOverwriteZeros))
+ {
+ if (new SrtmTile(point).equals(inTile))
+ {
- double x = (point.getLongitude().getDouble() - inTile.getLongitude()) * 1200;
- double y = 1201 - (point.getLatitude().getDouble() - inTile.getLatitude()) * 1200;
- int idx1 = ((int)y)*1201 + (int)x;
++ double x = (point.getLongitude().getDouble() - inTile.getLongitude()) * (inRowSize - 1);
++ double y = inRowSize - (point.getLatitude().getDouble() - inTile.getLatitude()) * (inRowSize - 1);
++ int idx1 = ((int)y)*inRowSize + (int)x;
+ try
+ {
- int[] fouralts = {inHeights[idx1], inHeights[idx1+1], inHeights[idx1-1201], inHeights[idx1-1200]};
++ int[] fouralts = {inHeights[idx1], inHeights[idx1+1], inHeights[idx1-inRowSize], inHeights[idx1-inRowSize+1]};
+ int numVoids = (fouralts[0]==VOID_VAL?1:0) + (fouralts[1]==VOID_VAL?1:0)
+ + (fouralts[2]==VOID_VAL?1:0) + (fouralts[3]==VOID_VAL?1:0);
+ // if (numVoids > 0) System.out.println(numVoids + " voids found");
+ double altitude = 0.0;
+ switch (numVoids)
+ {
- case 0: altitude = bilinearInterpolate(fouralts, x, y); break;
- case 1: altitude = bilinearInterpolate(fixVoid(fouralts), x, y); break;
- case 2:
- case 3: altitude = averageNonVoid(fouralts); break;
- default: altitude = VOID_VAL;
++ case 0: altitude = bilinearInterpolate(fouralts, x, y); break;
++ case 1: altitude = bilinearInterpolate(fixVoid(fouralts), x, y); break;
++ case 2:
++ case 3: altitude = averageNonVoid(fouralts); break;
++ default: altitude = VOID_VAL;
+ }
+ // Special case for terrain tracks, don't interpolate voids yet
+ if (!_normalTrack && numVoids > 0) {
+ altitude = VOID_VAL;
+ }
+ if (altitude != VOID_VAL)
+ {
+ point.setFieldValue(Field.ALTITUDE, ""+altitude, false);
+ // depending on settings, this value may have been added as feet, we need to force metres
+ point.getAltitude().reset(new Altitude((int)altitude, UnitSetLibrary.UNITS_METRES));
+ numAltitudesFound++;
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException obe) {
- // System.err.println("lat=" + point.getLatitude().getDouble() + ", x=" + x + ", y=" + y + ", idx=" + idx1);
++ System.err.println("Point not in tile? lat=" + point.getLatitude().getDouble() + ", x=" + x + ", y=" + y + ", idx=" + idx1+"\n");
+ }
+ }
+ }
+ }
+ return numAltitudesFound;
+ }
+
/**
* Perform a bilinear interpolation on the given altitude array
* @param inAltitudes array of four altitude values on corners of square (bl, br, tl, tr)
import tim.prune.function.browser.UrlGenerator;
import tim.prune.function.browser.WebMapFunction;
import tim.prune.function.search.SearchMapillaryFunction;
+import tim.prune.function.srtm.DownloadSrtmFunction;
+import tim.prune.function.srtm.SrtmGl1Source;
+import tim.prune.function.srtm.Srtm3Source;
+import tim.prune.function.srtm.SrtmViewfinderSource;
+ import tim.prune.function.settings.SaveConfig;
/**
* Class to manage the menu bar and tool bar,
private JMenu _browserMapMenu = null;
private JMenuItem _routingGraphHopperItem = null;
private JMenuItem _chartItem = null;
- private JMenuItem _getGpsiesItem = null;
- private JMenuItem _uploadGpsiesItem = null;
private JMenuItem _lookupSrtmItem = null;
- private JMenuItem _downloadSrtmItem = null;
+ private JMenu _downloadSrtmMenu = null;
private JMenuItem _nearbyWikipediaItem = null;
private JMenuItem _nearbyOsmPoiItem = null;
private JMenuItem _showPeakfinderItem = null;
// SRTM
_lookupSrtmItem = makeMenuItem(FunctionLibrary.FUNCTION_LOOKUP_SRTM, false);
onlineMenu.add(_lookupSrtmItem);
- _downloadSrtmItem = makeMenuItem(FunctionLibrary.FUNCTION_DOWNLOAD_SRTM, false);
- onlineMenu.add(_downloadSrtmItem);
+ // Download SRTM sub-menu
+ _downloadSrtmMenu = new JMenu(I18nManager.getText("function.downloadsrtm"));
+ _downloadSrtmMenu.setEnabled(false);
+ JMenuItem downloadStrmGl1Item = makeMenuItem(new DownloadSrtmFunction(_app, new SrtmGl1Source()));
+ _downloadSrtmMenu.add(downloadStrmGl1Item);
+ JMenuItem downloadStrmViewfinderItem = makeMenuItem(new DownloadSrtmFunction(_app, new SrtmViewfinderSource()));
+ _downloadSrtmMenu.add(downloadStrmViewfinderItem);
+ JMenuItem downloadStrm3Item = makeMenuItem(new DownloadSrtmFunction(_app, new Srtm3Source()));
+ _downloadSrtmMenu.add(downloadStrm3Item);
+ onlineMenu.add(_downloadSrtmMenu);
- // Get gpsies tracks
- _getGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_GET_GPSIES, false);
- onlineMenu.add(_getGpsiesItem);
- // Upload to gpsies
- _uploadGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_UPLOAD_GPSIES, false);
- onlineMenu.add(_uploadGpsiesItem);
-
onlineMenu.addSeparator();
// browser submenu
_browserMapMenu = new JMenu(I18nManager.getText("menu.view.browser"));
_reverseItem.setEnabled(hasRange);
_addTimeOffsetItem.setEnabled(hasRange);
_addAltitudeOffsetItem.setEnabled(hasRange);
+ _removeAltitudesItem.setEnabled(hasRange);
_convertNamesToTimesItem.setEnabled(hasRange && _track.hasWaypoints());
_deleteFieldValuesItem.setEnabled(hasRange);
- _fullRangeDetailsItem.setEnabled(hasRange);
+ _viewFullDetailsItem.setEnabled(hasRange || hasPoint);
_estimateTimeItem.setEnabled(hasRange);
_learnEstimationParams.setEnabled(hasData && _track.hasTrackPoints() && _track.hasData(Field.TIMESTAMP)
&& _track.hasAltitudeData());