micropeak: Make reported 'max height' value show filtered max height
[fw/altos] / altoslib / AltosMapStore.java
index c06384339eaf55f23580809d9528389597f86619..4eba3a044296987c5f1ebaa3b0a3cff548a8e3de 100644 (file)
@@ -3,7 +3,8 @@
  *
  * 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.
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -15,7 +16,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  */
 
-package org.altusmetrum.altoslib_9;
+package org.altusmetrum.altoslib_12;
 
 import java.io.*;
 import java.net.*;
@@ -28,6 +29,45 @@ public class AltosMapStore {
 
        int                                     status;
 
+       private static File map_file(AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+               double lat = center.lat;
+               double lon = center.lon;
+               char chlat = lat < 0 ? 'S' : 'N';
+               char chlon = lon < 0 ? 'W' : 'E';
+
+               if (lat < 0) lat = -lat;
+               if (lon < 0) lon = -lon;
+               String maptype_string = String.format("%s-", AltosMap.maptype_names[maptype]);
+               String format_string;
+               if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain)
+                       format_string = "jpg";
+               else
+                       format_string = "png";
+               return new File(AltosPreferences.mapdir(),
+                               String.format("map-%c%.6f,%c%.6f-%s%d%s.%s",
+                                             chlat, lat, chlon, lon, maptype_string, zoom, scale == 1 ? "" : String.format("-%d", scale), format_string));
+       }
+
+       private static String map_url(AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+               String format_string;
+               int z = zoom;
+
+               if (maptype == AltosMap.maptype_hybrid || maptype == AltosMap.maptype_satellite || maptype == AltosMap.maptype_terrain)
+                       format_string = "jpg";
+               else
+                       format_string = "png32";
+
+               for (int s = 1; s < scale; s <<= 1)
+                       z--;
+
+               if (AltosVersion.has_google_maps_api_key())
+                       return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s&key=%s",
+                                            center.lat, center.lon, z, px_size/scale, px_size/scale, scale, AltosMap.maptype_names[maptype], format_string, AltosVersion.google_maps_api_key);
+               else
+                       return String.format("http://maps.google.com/maps/api/staticmap?center=%.6f,%.6f&zoom=%d&size=%dx%d&scale=%d&sensor=false&maptype=%s&format=%s",
+                                            center.lat, center.lon, z, px_size/scale, px_size/scale, AltosMap.maptype_names[maptype], format_string);
+       }
+
        public int status() {
                return status;
        }
@@ -35,6 +75,7 @@ public class AltosMapStore {
        public synchronized void add_listener(AltosMapStoreListener listener) {
                if (!listeners.contains(listener))
                        listeners.add(listener);
+               listener.notify_store(this, status);
        }
 
        public synchronized void remove_listener(AltosMapStoreListener listener) {
@@ -50,6 +91,7 @@ public class AltosMapStore {
        static Object   forbidden_lock = new Object();
        static long     forbidden_time;
        static boolean  forbidden_set;
+       public static int forbidden_response;
 
        private int fetch_url() {
                URL u;
@@ -75,6 +117,7 @@ public class AltosMapStore {
                                        synchronized (forbidden_lock) {
                                                forbidden_time = System.nanoTime();
                                                forbidden_set = true;
+                                               forbidden_response = response;
                                                return AltosMapTile.forbidden;
                                        }
                                }
@@ -110,7 +153,7 @@ public class AltosMapStore {
                                file.delete();
                        return AltosMapTile.bad_request;
                }
-               return AltosMapTile.success;
+               return AltosMapTile.fetched;
        }
 
        static Object   fetch_lock = new Object();
@@ -118,42 +161,42 @@ public class AltosMapStore {
        static final long       forbidden_interval = 60l * 1000l * 1000l * 1000l;
        static final long       google_maps_ratelimit_ms = 1200;
 
-       static Object   loader_lock = new Object();
+       static Object   fetcher_lock = new Object();
 
        static LinkedList<AltosMapStore> waiting = new LinkedList<AltosMapStore>();
        static LinkedList<AltosMapStore> running = new LinkedList<AltosMapStore>();
 
-       static final int concurrent_loaders = 128;
+       static final int concurrent_fetchers = 128;
 
-       static void start_loaders() {
-               while (!waiting.isEmpty() && running.size() < concurrent_loaders) {
+       static void start_fetchers() {
+               while (!waiting.isEmpty() && running.size() < concurrent_fetchers) {
                        AltosMapStore   s = waiting.remove();
                        running.add(s);
-                       Thread lt = s.make_loader_thread();
+                       Thread lt = s.make_fetcher_thread();
                        lt.start();
                }
        }
 
-       void finish_loader() {
-               synchronized(loader_lock) {
+       void finish_fetcher() {
+               synchronized(fetcher_lock) {
                        running.remove(this);
-                       start_loaders();
+                       start_fetchers();
                }
        }
 
-       void add_loader() {
-               synchronized(loader_lock) {
+       void add_fetcher() {
+               synchronized(fetcher_lock) {
                        waiting.add(this);
-                       start_loaders();
+                       start_fetchers();
                }
        }
 
-       class loader implements Runnable {
+       class fetcher implements Runnable {
 
                public void run() {
                        try {
                                if (file.exists()) {
-                                       notify_listeners(AltosMapTile.success);
+                                       notify_listeners(AltosMapTile.fetched);
                                        return;
                                }
 
@@ -170,7 +213,7 @@ public class AltosMapStore {
                                        synchronized (fetch_lock) {
                                                long startTime = System.nanoTime();
                                                new_status = fetch_url();
-                                               if (new_status == AltosMapTile.success) {
+                                               if (new_status == AltosMapTile.fetched) {
                                                        long duration_ms = (System.nanoTime() - startTime) / 1000000;
                                                        if (duration_ms < google_maps_ratelimit_ms) {
                                                                try {
@@ -186,17 +229,17 @@ public class AltosMapStore {
                                }
                                notify_listeners(new_status);
                        } finally {
-                               finish_loader();
+                               finish_fetcher();
                        }
                }
        }
 
-       private Thread make_loader_thread() {
-               return new Thread(new loader());
+       private Thread make_fetcher_thread() {
+               return new Thread(new fetcher());
        }
 
-       private void load() {
-               add_loader();
+       private void fetch() {
+               add_fetcher();
        }
 
        private AltosMapStore (String url, File file) {
@@ -204,10 +247,10 @@ public class AltosMapStore {
                this.file = file;
 
                if (file.exists())
-                       status = AltosMapTile.success;
+                       status = AltosMapTile.fetched;
                else {
-                       status = AltosMapTile.loading;
-                       load();
+                       status = AltosMapTile.fetching;
+                       fetch();
                }
        }
 
@@ -228,16 +271,19 @@ public class AltosMapStore {
 
        static HashMap<String,AltosMapStore> stores = new HashMap<String,AltosMapStore>();
 
-       public static AltosMapStore get(String url, File file) {
+       public static AltosMapStore get(AltosLatLon center, int zoom, int maptype, int px_size, int scale) {
+               String url = map_url(center, zoom, maptype, px_size, scale);
+
                AltosMapStore   store;
                synchronized(stores) {
                        if (stores.containsKey(url)) {
                                store = stores.get(url);
                        } else {
-                               store = new AltosMapStore(url, file);
+                               store = new AltosMapStore(url, map_file(center, zoom, maptype, px_size, scale));
                                stores.put(url, store);
                        }
                }
                return store;
        }
+
 }