X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=altoslib%2FAltosMapLoader.java;h=727dfbcb4cf559a0e6064e53c71fa6281aef6683;hp=9d4059e6e73aea3bc4daf560dbb5c61e3525f07d;hb=297eb795b24ec31f6599f48bc8c3769557a7ec6f;hpb=21d176f161b90f18f236ef887cef9676d712eee3 diff --git a/altoslib/AltosMapLoader.java b/altoslib/AltosMapLoader.java index 9d4059e6..727dfbcb 100644 --- a/altoslib/AltosMapLoader.java +++ b/altoslib/AltosMapLoader.java @@ -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,16 +16,17 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_10; +package org.altusmetrum.altoslib_13; import java.io.*; import java.util.*; +import java.util.concurrent.*; import java.text.*; import java.lang.Math; import java.net.URL; import java.net.URLConnection; -public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListener { +public class AltosMapLoader extends Thread implements AltosMapStoreListener { AltosMapLoaderListener listener; double latitude, longitude; @@ -34,6 +36,7 @@ public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListen int all_types; int cur_type; double radius; + int scale; int tiles_loaded_layer; int tiles_loaded_total; @@ -42,7 +45,11 @@ public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListen int layers_total; int layers_loaded; - AltosMap map; + private static final int MAX_LOADING = 200; + + private Semaphore loading = new Semaphore(MAX_LOADING); + + boolean abort; int tile_radius(int zoom) { double delta_lon = AltosMapTransform.lon_from_distance(latitude, radius); @@ -62,7 +69,7 @@ public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListen return (tile_radius * 2 + 1) * (tile_radius * 2 + 1); } - public void do_load() { + private boolean do_load() { tiles_this_layer = tiles_per_layer(cur_z); tiles_loaded_layer = 0; listener.debug("tiles_this_layer %d (zoom %d)\n", tiles_this_layer, cur_z); @@ -73,8 +80,6 @@ public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListen AltosLatLon load_centre = new AltosLatLon(latitude, longitude); AltosMapTransform transform = new AltosMapTransform(256, 256, zoom, load_centre); - map.centre(load_centre); - AltosPointInt upper_left; AltosPointInt lower_right; @@ -88,19 +93,25 @@ public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListen for (int y = (int) upper_left.y; y <= lower_right.y; y += AltosMap.px_size) { for (int x = (int) upper_left.x; x <= lower_right.x; x += AltosMap.px_size) { - listener.debug("Make tile at %d, %d\n", x, y); + try { + loading.acquire(); + } catch (InterruptedException ie) { + return false; + } AltosPointInt point = new AltosPointInt(x, y); AltosLatLon ul = transform.lat_lon(point); AltosLatLon center = transform.lat_lon(new AltosPointDouble(x + AltosMap.px_size/2, y + AltosMap.px_size/2)); - AltosMapTile tile = map.map_interface.new_tile(this, ul, center, zoom, maptype, AltosMap.px_size); - tile.add_store_listener(this); - if (tile.store_status() != AltosMapTile.loading) - notify_tile(tile, tile.store_status()); + AltosMapStore store = AltosMapStore.get(center, zoom, maptype, AltosMap.px_size, scale); + listener.debug("load state %s url %s\n", AltosMapTile.status_name(store.status()), store.url); + store.add_listener(this); + if (abort) + return false; } } + return true; } - public int next_type(int start) { + private int next_type(int start) { int next_type; for (next_type = start; next_type <= AltosMap.maptype_terrain && (all_types & (1 << next_type)) == 0; @@ -109,22 +120,22 @@ public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListen return next_type; } - public void next_load() { + private boolean next_load() { int next_type = next_type(cur_type + 1); if (next_type > AltosMap.maptype_terrain) { if (cur_z == max_z) { - return; + return false; } else { cur_z++; } next_type = next_type(0); } cur_type = next_type; - do_load(); + return true; } - private void start_load() { + public void run() { cur_z = min_z; int ntype = 0; @@ -139,67 +150,73 @@ public class AltosMapLoader implements AltosMapTileListener, AltosMapStoreListen cur_type = next_type(0); + tiles_total = 0; for (int z = min_z; z <= max_z; z++) - tiles_total += tiles_per_layer(z); + tiles_total += tiles_per_layer(z) * ntype; layers_total = (max_z - min_z + 1) * ntype; layers_loaded = 0; tiles_loaded_total = 0; - listener.debug("total tiles %d\n", tiles_total); + listener.debug("total tiles %d layers %d\n", tiles_total, layers_total); listener.loader_start(tiles_total); - do_load(); - } - - public void load(double latitude, double longitude, int min_z, int max_z, double radius, int all_types) { - listener.debug("lat %f lon %f min_z %d max_z %d radius %f all_types %d\n", - latitude, longitude, min_z, max_z, radius, all_types); - this.latitude = latitude; - this.longitude = longitude; - this.min_z = min_z; - this.max_z = max_z; - this.radius = radius; - this.all_types = all_types; - start_load(); + do { + if (!do_load()) + break; + } while (next_load()); + if (abort) + listener.loader_done(tiles_total); } public synchronized void notify_store(AltosMapStore store, int status) { boolean do_next = false; - if (status == AltosMapTile.loading) + if (status == AltosMapTile.fetching) return; + loading.release(); + + store.remove_listener(this); + if (layers_loaded >= layers_total) return; ++tiles_loaded_total; ++tiles_loaded_layer; - listener.debug("total %d layer %d\n", tiles_loaded_total, tiles_loaded_layer); + + listener.debug("AltosMapLoader.notify_store status %d total %d of %d layer %d of %d\n", + status, tiles_loaded_total, tiles_total, tiles_loaded_layer, tiles_this_layer); if (tiles_loaded_layer == tiles_this_layer) { ++layers_loaded; listener.debug("%d layers loaded\n", layers_loaded); - if (layers_loaded == layers_total) { - listener.loader_done(tiles_total); - return; - } else { - do_next = true; - } + do_next = true; } - listener.loader_notify(tiles_loaded_total, - tiles_total, store.file.toString()); - if (do_next) - next_load(); - } - public synchronized void notify_tile(AltosMapTile tile, int status) { - notify_store(tile.store, status); + if (tiles_loaded_total == tiles_total) + listener.loader_done(tiles_total); + else + listener.loader_notify(tiles_loaded_total, + tiles_total, store.file.toString()); } - public AltosMapCache cache() { return map.cache(); } + public void abort() { + this.abort = true; + } - public AltosMapLoader(AltosMap map, AltosMapLoaderListener listener) { - this.map = map; + public AltosMapLoader(AltosMapLoaderListener listener, + double latitude, double longitude, int min_z, int max_z, double radius, int all_types, int scale) { + listener.debug("lat %f lon %f min_z %d max_z %d radius %f all_types %d\n", + latitude, longitude, min_z, max_z, radius, all_types); this.listener = listener; + this.latitude = latitude; + this.longitude = longitude; + this.min_z = min_z; + this.max_z = max_z; + this.radius = radius; + this.all_types = all_types; + this.scale = scale; + this.abort = false; + start(); } }