Changeset 35964 in osm for applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap
- Timestamp:
- 2022-04-27T21:18:31+02:00 (3 years ago)
- Location:
- applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation/ElevationHelper.java
r35165 r35964 6 6 import java.util.GregorianCalendar; 7 7 import java.util.List; 8 import java.util.Optional; 8 9 9 10 import org.openstreetmap.josm.data.Bounds; 10 11 import org.openstreetmap.josm.data.SystemOfMeasurement; 12 import org.openstreetmap.josm.data.coor.ILatLon; 11 13 import org.openstreetmap.josm.data.coor.LatLon; 12 14 import org.openstreetmap.josm.data.gpx.WayPoint; … … 34 36 35 37 private static GeoidCorrectionKind geoidKind = GeoidCorrectionKind.None; 36 37 /** The HGT reader instance. */38 private static final HgtReader hgt = new HgtReader();39 38 40 39 /** … … 166 165 * not height attribute. 167 166 */ 168 public static double getSrtmElevation( LatLon ll) {167 public static double getSrtmElevation(ILatLon ll) { 169 168 if (ll != null) { 170 169 // Try to read data from SRTM file 171 170 // TODO: Option to switch this off 172 double eleHgt = hgt.getElevationFromHgt(ll);171 double eleHgt = HgtReader.getElevationFromHgt(ll); 173 172 174 173 if (isValidElevation(eleHgt)) { … … 177 176 } 178 177 return NO_ELEVATION; 178 } 179 180 /** 181 * Get the bounds for the pixel elevation for the latitude 182 * @param location The location to get 183 * @return The bounds for the elevation area 184 */ 185 public static Optional<Bounds> getBounds(ILatLon location) { 186 if (location != null) { 187 return HgtReader.getBounds(location); 188 } 189 return Optional.empty(); 179 190 } 180 191 … … 252 263 253 264 Calendar calendar = GregorianCalendar.getInstance(); // creates a new calendar instance 254 calendar.setTime (wpt.getDate());// assigns calendar to given date265 calendar.setTimeInMillis(wpt.getTimeInMillis()); // assigns calendar to given date 255 266 return calendar.get(Calendar.HOUR_OF_DAY); 256 267 } … … 263 274 264 275 Calendar calendar = GregorianCalendar.getInstance(); // creates a new calendar instance 265 calendar.setTime (wpt.getDate());// assigns calendar to given date276 calendar.setTimeInMillis(wpt.getTimeInMillis()); // assigns calendar to given date 266 277 return calendar.get(Calendar.MINUTE); 267 278 } -
applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation/ElevationProfilePlugin.java
r33815 r35964 6 6 import java.awt.Color; 7 7 8 import org.openstreetmap.josm.actions.ExtensionFileFilter; 8 9 import org.openstreetmap.josm.gui.IconToggleButton; 9 10 import org.openstreetmap.josm.gui.MainApplication; … … 33 34 34 35 createColorMaps(); 36 ExtensionFileFilter.addImporter(new HgtFileImporter()); 35 37 36 38 // TODO: Disable this view as long as it is not stable -
applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation/HgtReader.java
r35165 r35964 3 3 4 4 import java.io.File; 5 import java.io.FileInputStream;6 5 import java.io.FileNotFoundException; 6 import java.io.IOException; 7 import java.io.InputStream; 7 8 import java.nio.ByteBuffer; 8 9 import java.nio.ByteOrder; 9 import java.nio. ShortBuffer;10 import java. nio.channels.FileChannel;10 import java.nio.file.Paths; 11 import java.util.Arrays; 11 12 import java.util.HashMap; 12 13 import java.util.List; 14 import java.util.Optional; 15 import java.util.regex.Matcher; 16 import java.util.regex.Pattern; 17 18 import org.apache.commons.compress.utils.IOUtils; 19 import org.openstreetmap.josm.data.Bounds; 13 20 import org.openstreetmap.josm.data.Preferences; 21 import org.openstreetmap.josm.data.coor.ILatLon; 14 22 import org.openstreetmap.josm.data.coor.LatLon; 23 import org.openstreetmap.josm.io.Compression; 15 24 import org.openstreetmap.josm.tools.CheckParameterUtil; 16 25 import org.openstreetmap.josm.tools.Logging; … … 23 32 */ 24 33 public class HgtReader { 25 private static final int SECONDS_PER_MINUTE = 60; 34 private static final int SRTM_EXTENT = 1; // degree 35 private static final List<String> COMPRESSION_EXT = Arrays.asList("xz", "gzip", "zip", "bz", "bz2"); 26 36 27 37 public static final String HGT_EXT = ".hgt"; 28 38 29 39 // alter these values for different SRTM resolutions 30 public static final int HGT_RES = 3; // resolution in arc seconds 31 public static final int HGT_ROW_LENGTH = 1201; // number of elevation values per line 32 public static final int HGT_VOID = -32768; // magic number which indicates 'void data' in HGT file 33 34 private final HashMap<String, ShortBuffer> cache = new HashMap<>(); 35 36 public double getElevationFromHgt(LatLon coor) { 40 public static final int HGT_VOID = Short.MIN_VALUE; // magic number which indicates 'void data' in HGT file 41 42 private static final HashMap<String, short[][]> cache = new HashMap<>(); 43 44 public static double getElevationFromHgt(ILatLon coor) { 37 45 try { 38 46 String file = getHgtFileName(coor); … … 48 56 String fullPath = new File(location + File.separator + "elevation", file).getPath(); 49 57 File f = new File(fullPath); 58 if (!f.exists()) { 59 for (String ext : COMPRESSION_EXT) { 60 f = new File(fullPath + "." + ext); 61 if (f.exists()) break; 62 } 63 } 50 64 if (f.exists()) { 51 // found something: read HGT file... 52 ShortBuffer data = readHgtFile(fullPath); 53 // ... and store result in cache 54 cache.put(file, data); 65 read(f); 55 66 break; 56 67 } … … 59 70 60 71 // read elevation value 61 return readElevation(coor );72 return readElevation(coor, file); 62 73 } catch (FileNotFoundException e) { 63 74 Logging.error("Get elevation from HGT " + coor + " failed: => " + e.getMessage()); … … 72 83 } 73 84 74 @SuppressWarnings("resource") 75 private ShortBuffer readHgtFile(String file) throws Exception { 85 public static Bounds read(File file) throws FileNotFoundException, IOException { 86 String location = file.getName(); 87 for (String ext : COMPRESSION_EXT) { 88 location = location.replaceAll("\\." + ext + "$", ""); 89 } 90 short[][] sb = readHgtFile(file.getPath()); 91 // Overwrite the cache file (assume that is desired) 92 cache.put(location, sb); 93 Pattern pattern = Pattern.compile("(N|S)([0-9]{2})(E|W)([0-9]{3})"); 94 Matcher matcher = pattern.matcher(location); 95 if (matcher.lookingAt()) { 96 int lat = (matcher.group(1) == "S" ? -1 : 1) * Integer.parseInt(matcher.group(2)); 97 int lon = (matcher.group(3) == "W" ? -1 : 1) * Integer.parseInt(matcher.group(4)); 98 return new Bounds(lat, lon, lat + 1, lon + 1); 99 } 100 return null; 101 } 102 103 private static short[][] readHgtFile(String file) throws FileNotFoundException, IOException { 76 104 CheckParameterUtil.ensureParameterNotNull(file); 77 105 78 FileChannel fc = null; 79 ShortBuffer sb = null; 80 try { 81 // Eclipse complains here about resource leak on 'fc' - even with 'finally' clause??? 82 fc = new FileInputStream(file).getChannel(); 106 short[][] data = null; 107 108 try (InputStream fis = Compression.getUncompressedFileInputStream(Paths.get(file))) { 83 109 // choose the right endianness 84 85 ByteBuffer bb = ByteBuffer.allocateDirect((int) fc.size()); 86 while (bb.remaining() > 0) fc.read(bb); 87 88 bb.flip(); 89 sb = bb.order(ByteOrder.BIG_ENDIAN).asShortBuffer(); 90 } finally { 91 if (fc != null) fc.close(); 92 } 93 94 return sb; 110 ByteBuffer bb = ByteBuffer.wrap(IOUtils.toByteArray(fis)); 111 //System.out.println(Arrays.toString(bb.array())); 112 bb.order(ByteOrder.BIG_ENDIAN); 113 int size = (int) Math.sqrt(bb.array().length / 2); 114 data = new short[size][size]; 115 int x = 0; 116 int y = 0; 117 while (x < size) { 118 while (y < size) { 119 data[x][y] = bb.getShort(2 * (x * size + y)); 120 y++; 121 } 122 x++; 123 y = 0; 124 } 125 } 126 127 return data; 95 128 } 96 129 … … 102 135 * @return the elevation value or <code>Double.NaN</code>, if no value is present 103 136 */ 104 public double readElevation(LatLon coor) {137 public static double readElevation(LatLon coor) { 105 138 String tag = getHgtFileName(coor); 106 107 ShortBuffer sb = cache.get(tag); 139 return readElevation(coor, tag); 140 } 141 142 /** 143 * Reads the elevation value for the given coordinate. 144 * 145 * See also <a href="http://gis.stackexchange.com/questions/43743/how-to-extract-elevation-from-hgt-file">stackexchange.com</a> 146 * @param coor the coordinate to get the elevation data for 147 * @param fileName The expected filename 148 * @return the elevation value or <code>Double.NaN</code>, if no value is present 149 */ 150 public static double readElevation(ILatLon coor, String fileName) { 151 152 short[][] sb = cache.get(fileName); 108 153 109 154 if (sb == null) { … … 111 156 } 112 157 113 // see http://gis.stackexchange.com/questions/43743/how-to-extract-elevation-from-hgt-file 114 double fLat = frac(coor.lat()) * SECONDS_PER_MINUTE; 115 double fLon = frac(coor.lon()) * SECONDS_PER_MINUTE; 116 117 // compute offset within HGT file 118 int row = (int) Math.round(fLat * SECONDS_PER_MINUTE / HGT_RES); 119 int col = (int) Math.round(fLon * SECONDS_PER_MINUTE / HGT_RES); 120 121 row = HGT_ROW_LENGTH - row; 122 int cell = (HGT_ROW_LENGTH * (row - 1)) + col; 123 124 // valid position in buffer? 125 if (cell < sb.limit()) { 126 short ele = sb.get(cell); 127 // check for data voids 128 if (ele == HGT_VOID) { 129 return ElevationHelper.NO_ELEVATION; 130 } else { 131 return ele; 132 } 133 } else { 134 return ElevationHelper.NO_ELEVATION; 135 } 158 int[] index = getIndex(coor, sb.length); 159 short ele = sb[index[0]][index[1]]; 160 161 if (ele == HGT_VOID) { 162 return ElevationHelper.NO_ELEVATION; 163 } 164 return ele; 165 } 166 167 public static Optional<Bounds> getBounds(ILatLon location) { 168 final String fileName = getHgtFileName(location); 169 final short[][] sb = cache.get(fileName); 170 171 if (sb == null) { 172 return Optional.empty(); 173 } 174 175 final double latDegrees = location.lat(); 176 final double lonDegrees = location.lon(); 177 178 final float fraction = ((float) SRTM_EXTENT) / sb.length; 179 final int latitude = (int) Math.floor(latDegrees) + (latDegrees < 0 ? 1 : 0); 180 final int longitude = (int) Math.floor(lonDegrees) + (lonDegrees < 0 ? 1 : 0); 181 182 final int[] index = getIndex(location, sb.length); 183 final int latSign = latitude > 0 ? 1 : -1; 184 final int lonSign = longitude > 0 ? 1 : -1; 185 final double minLat = latitude + latSign * fraction * index[0]; 186 final double maxLat = latitude + latSign * fraction * (index[0] + 1); 187 final double minLon = longitude + lonSign * fraction * index[1]; 188 final double maxLon = longitude + lonSign * fraction * (index[1] + 1); 189 return Optional.of(new Bounds(Math.min(minLat, maxLat), Math.min(minLon, maxLon), 190 Math.max(minLat, maxLat), Math.max(minLon, maxLon))); 191 } 192 193 /** 194 * Get the index to use for a short[latitude][longitude] = height in meters array 195 * 196 * @param latLon 197 * The location to get the index for 198 * @param mapSize 199 * The size of the map 200 * @return A [latitude, longitude] = int (index) array. 201 */ 202 private static int[] getIndex(ILatLon latLon, int mapSize) 203 { 204 double latDegrees = latLon.lat(); 205 double lonDegrees = latLon.lon(); 206 207 float fraction = ((float) SRTM_EXTENT) / mapSize; 208 int latitude = (int) Math.floor(Math.abs(latDegrees - (int) latDegrees) / fraction); 209 int longitude = (int) Math.floor(Math.abs(lonDegrees - (int) lonDegrees) / fraction); 210 if (latDegrees >= 0) 211 { 212 latitude = mapSize - 1 - latitude; 213 } 214 if (lonDegrees < 0) 215 { 216 longitude = mapSize - 1 - longitude; 217 } 218 return new int[] { latitude, longitude }; 136 219 } 137 220 … … 144 227 * @return the file name of the HGT file 145 228 */ 146 public String getHgtFileName(LatLon latLon) {147 int lat = (int) latLon.lat();148 int lon = (int) latLon.lon();229 public static String getHgtFileName(ILatLon latLon) { 230 int lat = (int) Math.floor(latLon.lat()); 231 int lon = (int) Math.floor(latLon.lon()); 149 232 150 233 String latPref = "N"; 151 if (lat < 0) latPref = "S"; 234 if (lat < 0) { 235 latPref = "S"; 236 lat = Math.abs(lat); 237 } 152 238 153 239 String lonPref = "E"; 154 240 if (lon < 0) { 155 241 lonPref = "W"; 156 } 157 158 return String.format("%s%02d%s%03d%s", latPref, lat, lonPref, lon, HGT_EXT); 242 lon = Math.abs(lon); 243 } 244 245 return latPref + lat + lonPref + lon + HGT_EXT; 159 246 } 160 247 … … 168 255 return fPart; 169 256 } 257 258 public static void clearCache() { 259 cache.clear(); 260 } 170 261 } -
applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation/IElevationProfile.java
r32775 r35964 2 2 package org.openstreetmap.josm.plugins.elevation; 3 3 4 import java. util.Date;4 import java.time.Instant; 5 5 import java.util.List; 6 6 … … 21 21 * Gets the time stamp of first recorded track point. 22 22 */ 23 DategetStart();23 Instant getStart(); 24 24 25 25 /** 26 26 * Gets the time stamp of last recorded track point. 27 27 */ 28 DategetEnd();28 Instant getEnd(); 29 29 30 30 /** -
applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation/actions/AddElevationLayerAction.java
r33815 r35964 28 28 currentLayer = new ElevationGridLayer(tr("Elevation Grid")); // TODO: Better name 29 29 MainApplication.getLayerManager().addLayer(currentLayer); 30 } else if (!MainApplication.getLayerManager().containsLayer(currentLayer)) { 31 currentLayer = null; 32 actionPerformed(arg0); 30 33 } 31 34 } -
applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation/gpx/ElevationProfile.java
r35465 r35964 2 2 package org.openstreetmap.josm.plugins.elevation.gpx; 3 3 4 import java.time.Instant; 4 5 import java.util.ArrayList; 5 import java.util.Date;6 6 import java.util.List; 7 7 … … 45 45 private int avrgHeight; 46 46 private double dist; 47 private Date start = new Date();48 private Date end = new Date();47 private Instant start; 48 private Instant end; 49 49 private final WayPoint[] importantWayPoints = new WayPoint[4]; 50 50 private IElevationProfile parent; … … 121 121 return; 122 122 123 start = new Date(0L);124 end = new Date();123 start = Instant.EPOCH; 124 end = Instant.now(); 125 125 this.minHeight = Integer.MAX_VALUE; 126 126 this.maxHeight = Integer.MIN_VALUE; … … 196 196 protected void setStart(WayPoint wp) { 197 197 importantWayPoints[WAYPOINT_START] = wp; 198 if(wp.get Date() != null)199 this.start = wp.get Date();198 if(wp.getInstant() != null) 199 this.start = wp.getInstant(); 200 200 } 201 201 … … 205 205 protected void setEnd(WayPoint wp) { 206 206 importantWayPoints[WAYPOINT_END] = wp; 207 if(wp.get Date() != null)208 this.end = wp.get Date();207 if(wp.getInstant() != null) 208 this.end = wp.getInstant(); 209 209 } 210 210 … … 257 257 258 258 @Override 259 public DategetEnd() {259 public Instant getEnd() { 260 260 return end; 261 261 } … … 308 308 309 309 if (wp1 != null && wp2 != null) { 310 Date wp1Date = wp1.getDate();311 Date wp2Date = wp2.getDate();310 Instant wp1Date = wp1.getInstant(); 311 Instant wp2Date = wp2.getInstant(); 312 312 if (wp1Date != null && wp2Date != null) { 313 return wp2Date. getTime() - wp1Date.getTime();313 return wp2Date.toEpochMilli() - wp1Date.toEpochMilli(); 314 314 } else { 315 315 Logging.warn("Waypoints without date: " + wp1 + " / " + wp2); … … 326 326 327 327 @Override 328 public DategetStart() {328 public Instant getStart() { 329 329 return start; 330 330 } … … 390 390 391 391 if (wp.hasDate()) { 392 if (wp.get Date().after(end)) {392 if (wp.getInstant().isAfter(this.end)) { 393 393 setEnd(wp); 394 394 } 395 395 396 if (wp.get Date().before(start)) {396 if (wp.getInstant().isBefore(start)) { 397 397 setStart(wp); 398 398 } -
applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation/grid/ElevationGridLayer.java
r35165 r35964 8 8 import java.awt.Graphics2D; 9 9 import java.awt.Point; 10 import java.awt.Rectangle; 11 import java.awt.event.MouseEvent; 12 import java.awt.event.MouseListener; 10 13 11 14 import javax.swing.Action; 12 15 import javax.swing.Icon; 13 16 17 import org.apache.commons.jcs3.JCS; 14 18 import org.openstreetmap.gui.jmapviewer.MemoryTileCache; 15 19 import org.openstreetmap.gui.jmapviewer.Tile; … … 19 23 import org.openstreetmap.gui.jmapviewer.interfaces.TileSource; 20 24 import org.openstreetmap.josm.data.Bounds; 25 import org.openstreetmap.josm.data.coor.ILatLon; 21 26 import org.openstreetmap.josm.data.coor.LatLon; 22 27 import org.openstreetmap.josm.data.imagery.CoordinateConversion; 28 import org.openstreetmap.josm.data.imagery.TileJobOptions; 29 import org.openstreetmap.josm.data.osm.BBox; 23 30 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor; 31 import org.openstreetmap.josm.gui.MainApplication; 24 32 import org.openstreetmap.josm.gui.MapView; 33 import org.openstreetmap.josm.gui.Notification; 25 34 import org.openstreetmap.josm.gui.layer.Layer; 35 import org.openstreetmap.josm.gui.util.GuiHelper; 36 import org.openstreetmap.josm.plugins.elevation.ElevationHelper; 37 import org.openstreetmap.josm.plugins.elevation.HgtReader; 26 38 import org.openstreetmap.josm.plugins.elevation.IVertexRenderer; 27 39 import org.openstreetmap.josm.tools.ImageProvider; … … 32 44 * 33 45 */ 34 public class ElevationGridLayer extends Layer implements TileLoaderListener {46 public class ElevationGridLayer extends Layer implements TileLoaderListener, MouseListener { 35 47 private static final int ELE_ZOOM_LEVEL = 13; 36 48 private final IVertexRenderer vertexRenderer; … … 40 52 protected TileController tileController; 41 53 54 private ILatLon clickLocation; 55 42 56 private Bounds lastBounds; 43 57 private TileSet tileSet; … … 45 59 public ElevationGridLayer(String name) { 46 60 super(name); 61 HgtReader.clearCache(); 62 MainApplication.getMap().mapView.addMouseListener(this); 47 63 48 64 setOpacity(0.8); … … 53 69 tileCache.setCacheSize(500); 54 70 tileSource = new ElevationGridTileSource(name); 55 tileLoader = new ElevationGridTileLoader(this );71 tileLoader = new ElevationGridTileLoader(this, JCS.getInstance("elevationgridlayer"), new TileJobOptions(20, 20, null, 3600)); 56 72 tileController = new ElevationGridTileController(tileSource, tileCache, this, tileLoader); 57 73 } … … 90 106 } 91 107 } 108 // Paint the current point area 109 ElevationHelper.getBounds(this.clickLocation).ifPresent(bounds -> { 110 final BBox bbox = bounds.toBBox(); 111 final Point upperLeft = mv.getPoint(bbox.getTopLeft()); 112 final Point bottomRight = mv.getPoint(bbox.getBottomRight()); 113 final Rectangle rectangle = new Rectangle(upperLeft.x, upperLeft.y, 114 bottomRight.x - upperLeft.x, bottomRight.y - upperLeft.y); 115 g.setColor(Color.RED); 116 g.draw(rectangle); 117 }); 92 118 } 93 119 … … 150 176 g.setColor(oldColor); 151 177 g.drawString(text, x, y); 178 } 179 180 @Override 181 public void mouseClicked(MouseEvent e) { 182 if (e.getButton() == MouseEvent.BUTTON1) { 183 this.clickLocation = MainApplication.getMap().mapView.getLatLon(e.getX(), e.getY()); 184 final double elevation = ElevationHelper.getSrtmElevation(clickLocation); 185 Notification notification = new Notification("Elevation is: " + elevation); 186 notification.setDuration(Notification.TIME_SHORT); 187 GuiHelper.runInEDT(notification::show); 188 GuiHelper.runInEDT(this::invalidate); 189 } 190 } 191 192 @Override 193 public void mousePressed(MouseEvent e) { 194 // Do nothing 195 } 196 197 @Override 198 public void mouseReleased(MouseEvent e) { 199 // Do nothing 200 } 201 202 @Override 203 public void mouseEntered(MouseEvent e) { 204 // Do nothing 205 } 206 207 @Override 208 public void mouseExited(MouseEvent e) { 209 // Do nothing 152 210 } 153 211 … … 224 282 } 225 283 } 284 285 @Override 286 public void destroy() { 287 super.destroy(); 288 HgtReader.clearCache(); 289 MainApplication.getMap().mapView.removeMouseListener(this); 290 } 226 291 } -
applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation/grid/ElevationGridTile.java
r35165 r35964 10 10 import java.io.IOException; 11 11 import java.io.InputStream; 12 import java.util.List;13 12 import java.util.concurrent.BlockingDeque; 14 13 import java.util.concurrent.LinkedBlockingDeque; … … 55 54 /** 56 55 * Paints the vertices of this tile. 57 *58 56 * @param g the graphics context 59 57 * @param mv the map view … … 67 65 Point p2 = mv.getPoint(eleVertex.get(2)); 68 66 Triangle shape = new Triangle(p0, p1, p2); 69 70 67 // obtain vertex color 71 68 g.setColor(vertexRenderer.getElevationColor(eleVertex)); … … 83 80 // We abuse the loadImage method to render the vertices... 84 81 // 85 while ( toDo.size() > 0) {82 while (!toDo.isEmpty()) { 86 83 EleVertex vertex = toDo.poll(); 87 84 … … 89 86 vertices.add(vertex); 90 87 } else { 91 List<EleVertex> newV = vertex.divide(); 92 for (EleVertex eleVertex : newV) { 93 toDo.add(eleVertex); 94 } 88 toDo.addAll(vertex.divide()); 95 89 } 96 90 } -
applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation/grid/ElevationGridTileLoader.java
r33214 r35964 2 2 package org.openstreetmap.josm.plugins.elevation.grid; 3 3 4 import java.io.IOException; 5 import java.net.URL; 6 import java.util.Optional; 7 import java.util.concurrent.ThreadPoolExecutor; 8 9 import org.apache.commons.jcs3.access.behavior.ICacheAccess; 4 10 import org.openstreetmap.gui.jmapviewer.Tile; 5 11 import org.openstreetmap.gui.jmapviewer.interfaces.TileJob; 6 import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;7 12 import org.openstreetmap.gui.jmapviewer.interfaces.TileLoaderListener; 13 import org.openstreetmap.gui.jmapviewer.interfaces.TileSource; 14 import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry; 15 import org.openstreetmap.josm.data.cache.JCSCachedTileLoaderJob; 16 import org.openstreetmap.josm.data.imagery.TMSCachedTileLoader; 17 import org.openstreetmap.josm.data.imagery.TileJobOptions; 8 18 import org.openstreetmap.josm.tools.CheckParameterUtil; 9 19 … … 12 22 * 13 23 */ 14 public class ElevationGridTileLoader implements TileLoader { 15 protected TileLoaderListener listener; 24 public class ElevationGridTileLoader extends TMSCachedTileLoader { 16 25 17 public ElevationGridTileLoader(TileLoaderListener listener) { 18 CheckParameterUtil.ensureParameterNotNull(listener); 19 this.listener = listener; 26 class ElevationGridTileJob extends JCSCachedTileLoaderJob<String, BufferedImageCacheEntry> implements TileJob { 27 28 private final Tile tile; 29 private final TileLoaderListener listener; 30 private final ICacheAccess<String, BufferedImageCacheEntry> cache; 31 32 protected ElevationGridTileJob(TileLoaderListener listener, Tile tile, ICacheAccess<String, BufferedImageCacheEntry> cache, TileJobOptions options, 33 ThreadPoolExecutor downloadJobExecutor) { 34 super(cache, options, downloadJobExecutor); 35 this.cache = cache; 36 this.tile = tile; 37 this.listener = listener; 38 } 39 40 @Override 41 public void run() { 42 synchronized (tile) { 43 if ((tile.isLoaded() && !tile.hasError()) || tile.isLoading()) 44 return; 45 tile.initLoading(); 46 } 47 try { 48 tile.loadImage(null); 49 tile.setLoaded(true); 50 listener.tileLoadingFinished(tile, true); 51 } catch (Exception e) { 52 tile.setError(e.getMessage()); 53 listener.tileLoadingFinished(tile, false); 54 } finally { 55 tile.finishLoading(); 56 } 57 } 58 59 @Override 60 public void submit() { 61 run(); 62 } 63 64 @Override 65 public void submit(boolean force) { 66 submit(); 67 } 68 69 @Override 70 public String getCacheKey() { 71 if (tile != null) { 72 TileSource tileSource = tile.getTileSource(); 73 return Optional.ofNullable(tileSource.getName()).orElse("").replace(':', '_') + ':' 74 + tileSource.getTileId(tile.getZoom(), tile.getXtile(), tile.getYtile()); 75 } 76 return null; 77 } 78 79 @Override 80 public URL getUrl() throws IOException { 81 return new URL(String.format("http://localhost/elevation/%d/%d", tile.getTileXY().getXIndex(), tile.getTileXY().getYIndex())); 82 } 83 84 @Override 85 protected BufferedImageCacheEntry createCacheEntry(byte[] content) { 86 return new BufferedImageCacheEntry(content); 87 } 88 } 89 90 /** 91 * Constructor 92 * @param listener called when tile loading has finished 93 * @param cache of the cache 94 * @param options tile job options 95 */ 96 public ElevationGridTileLoader(TileLoaderListener listener, ICacheAccess<String, BufferedImageCacheEntry> cache, 97 TileJobOptions options) { 98 super(listener, cache, options); 20 99 } 21 100 … … 24 103 CheckParameterUtil.ensureParameterNotNull(tile); 25 104 26 return new TileJob() { 27 28 @Override 29 public void run() { 30 synchronized (tile) { 31 if ((tile.isLoaded() && !tile.hasError()) || tile.isLoading()) 32 return; 33 tile.initLoading(); 34 } 35 try { 36 tile.loadImage(null); 37 tile.setLoaded(true); 38 listener.tileLoadingFinished(tile, true); 39 } catch (Exception e) { 40 tile.setError(e.getMessage()); 41 listener.tileLoadingFinished(tile, false); 42 } finally { 43 tile.finishLoading(); 44 } 45 } 46 47 @Override 48 public void submit() { 49 run(); 50 } 51 52 @Override 53 public void submit(boolean force) { 54 submit(); 55 } 56 }; 105 return new ElevationGridTileJob(listener, 106 tile, 107 cache, 108 options, 109 getDownloadExecutor()); 57 110 } 58 111 -
applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation/gui/ElevationProfilePanel.java
r32775 r35964 16 16 import java.text.Format; 17 17 import java.text.SimpleDateFormat; 18 import java.time.Instant; 18 19 import java.util.ArrayList; 19 import java.util.Date;20 20 import java.util.List; 21 21 … … 254 254 * Formats the date in a predefined manner: "21. Oct 2010, 12:10". 255 255 */ 256 private String formatDate( Datedate) {256 private String formatDate(Instant date) { 257 257 Format formatter = new SimpleDateFormat("d MMM yy, HH:mm"); 258 259 return formatter.format(date); 258 return formatter.format(date.toEpochMilli()); 260 259 } 261 260
Note:
See TracChangeset
for help on using the changeset viewer.