diff options
author | Keith Packard <keithp@keithp.com> | 2014-05-25 20:55:11 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2014-05-25 20:56:48 -0700 |
commit | 0a6c76fc0525d6588a1d88127f0085f13a02f1af (patch) | |
tree | d7cf76748c86522708b0826237eb031f371e349d /altosuilib/AltosSiteMapCache.java | |
parent | 4ac7797d3efb9cc2d9fae88519f55e40b1050224 (diff) |
altosui/altosuilib/altoslib: Move more stuff out of autosui. Reduce site map memory
Prepare to share with TeleGPS application.
This also has the changes to the site map tile which cache only a few
images and regenerate the flight path on the fly, saving piles of memory
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'altosuilib/AltosSiteMapCache.java')
-rw-r--r-- | altosuilib/AltosSiteMapCache.java | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/altosuilib/AltosSiteMapCache.java b/altosuilib/AltosSiteMapCache.java new file mode 100644 index 00000000..cf93016a --- /dev/null +++ b/altosuilib/AltosSiteMapCache.java @@ -0,0 +1,194 @@ +/* + * Copyright © 2010 Anthony Towns <aj@erisian.com.au> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altosuilib_2; + +import javax.swing.*; +import javax.imageio.ImageIO; +import java.awt.image.*; +import java.awt.*; +import java.io.*; +import java.net.URL; +import java.net.URLConnection; + + +class AltosCacheImage { + Component component; + File file; + VolatileImage image; + int width; + int height; + long used; + + public void load_image() throws IOException { + BufferedImage bimg = ImageIO.read(file); + Graphics2D g = image.createGraphics(); + g.drawImage(bimg, 0, 0, null); + bimg.flush(); + } + + public Image validate() { + int returnCode; + + if (image != null) + returnCode = image.validate(component.getGraphicsConfiguration()); + else + returnCode = VolatileImage.IMAGE_INCOMPATIBLE; + if (returnCode == VolatileImage.IMAGE_RESTORED) { + try { + load_image(); + } catch (IOException e) { + return null; + } + } else if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) { + image = component.createVolatileImage(width, height); + try { + load_image(); + } catch (IOException e) { + return null; + } + } + return image; + } + + public void flush() { + image.flush(); + } + + public AltosCacheImage(Component component, File file, int w, int h) throws IOException { + this.component = component; + this.file = file; + width = w; + height = h; + image = component.createVolatileImage(w, h); + used = 0; + } +} + +public class AltosSiteMapCache extends JLabel { + static final long google_maps_ratelimit_ms = 1200; + // Google limits static map queries to 50 per minute per IP, so + // each query should take at least 1.2 seconds. + + public static boolean fetchMap(File file, String url) { + if (file.exists()) + return true; + + URL u; + long startTime = System.nanoTime(); + + try { + u = new URL(url); + } catch (java.net.MalformedURLException e) { + return false; + } + + byte[] data; + try { + URLConnection uc = u.openConnection(); + int contentLength = uc.getContentLength(); + InputStream in = new BufferedInputStream(uc.getInputStream()); + int bytesRead = 0; + int offset = 0; + data = new byte[contentLength]; + while (offset < contentLength) { + bytesRead = in.read(data, offset, data.length - offset); + if (bytesRead == -1) + break; + offset += bytesRead; + } + in.close(); + + if (offset != contentLength) { + return false; + } + } catch (IOException e) { + return false; + } + + try { + FileOutputStream out = new FileOutputStream(file); + out.write(data); + out.flush(); + out.close(); + } catch (FileNotFoundException e) { + return false; + } catch (IOException e) { + if (file.exists()) { + file.delete(); + } + return false; + } + + long duration_ms = (System.nanoTime() - startTime) / 1000000; + if (duration_ms < google_maps_ratelimit_ms) { + try { + Thread.sleep(google_maps_ratelimit_ms - duration_ms); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + return true; + } + + static int cache_size = 9; + + static AltosCacheImage[] images; + + static long used; + + public static void set_cache_size(int cache_size) { + AltosSiteMapCache.cache_size = cache_size; + images = null; + } + + public static Image get_image(Component component, File file, int width, int height) { + int oldest = -1; + long age = used; + AltosCacheImage image; + if (images == null) + images = new AltosCacheImage[cache_size]; + for (int i = 0; i < cache_size; i++) { + image = images[i]; + + if (image == null) { + oldest = i; + break; + } + if (image.component == component && file.equals(image.file)) { + image.used = used++; + return image.validate(); + } + if (image.used < age) { + oldest = i; + age = image.used; + } + } + + try { + image = new AltosCacheImage(component, file, width, height); + image.used = used++; + if (images[oldest] != null) + images[oldest].flush(); + images[oldest] = image; + return image.validate(); + } catch (IOException e) { + return null; + } + } +} |