5db20cf8cbe54fecd7eb0f01e1d323e0dd075328
[fw/altos] / altoslib / AltosMapLoader.java
1 /*
2  * Copyright © 2015 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 package org.altusmetrum.altoslib_7;
19
20 import java.io.*;
21 import java.util.*;
22 import java.text.*;
23 import java.lang.Math;
24 import java.net.URL;
25 import java.net.URLConnection;
26
27 public class AltosMapLoader implements AltosMapTileListener {
28         AltosMapLoaderListener  listener;
29
30         double  latitude, longitude;
31         int     min_z;
32         int     max_z;
33         int     cur_z;
34         int     all_types;
35         int     cur_type;
36         int     radius;
37
38         int     tiles_per_layer;
39         int     tiles_loaded;
40         int     layers_total;
41         int     layers_loaded;
42
43         AltosMap        map;
44         AltosMapCache   cache;
45
46         public void do_load() {
47                 map.set_zoom(cur_z + AltosMap.default_zoom);
48                 map.set_maptype(cur_type);
49                 map.set_load_params(latitude, longitude, radius, this);
50         }
51
52         public int next_type(int start) {
53                 int next_type;
54                 for (next_type = start;
55                      next_type <= AltosMap.maptype_terrain && (all_types & (1 << next_type)) == 0;
56                      next_type++)
57                         ;
58                 return next_type;
59         }
60
61         public void next_load() {
62                 int next_type = next_type(cur_type + 1);
63
64                 if (next_type > AltosMap.maptype_terrain) {
65                         if (cur_z == max_z) {
66                                 return;
67                         } else {
68                                 cur_z++;
69                         }
70                         next_type = next_type(0);
71                 }
72                 cur_type = next_type;
73                 do_load();
74         }
75
76         private void start_load() {
77
78                 cur_z = min_z;
79                 int ntype = 0;
80
81                 for (int t = AltosMap.maptype_hybrid; t <= AltosMap.maptype_terrain; t++)
82                         if ((all_types & (1 << t)) != 0)
83                                 ntype++;
84                 if (ntype == 0) {
85                         all_types = (1 << AltosMap.maptype_hybrid);
86                         ntype = 1;
87                 }
88
89                 cur_type = next_type(0);
90                 tiles_per_layer = (radius * 2 + 1) * (radius * 2 + 1);
91                 layers_total = (max_z - min_z + 1) * ntype;
92                 layers_loaded = 0;
93                 tiles_loaded = 0;
94
95                 listener.loader_start(layers_total * tiles_per_layer);
96                 do_load();
97         }
98
99         public void load(double latitude, double longitude, int min_z, int max_z, int radius, int all_types) {
100                 this.latitude = latitude;
101                 this.longitude = longitude;
102                 this.min_z = min_z;
103                 this.max_z = max_z;
104                 this.radius = radius;
105                 this.all_types = all_types;
106                 start_load();
107         }
108
109         public synchronized void notify_tile(AltosMapTile tile, int status) {
110                 boolean do_next = false;
111                 if (status == AltosMapTile.loading)
112                         return;
113
114                 if (layers_loaded >= layers_total)
115                         return;
116
117                 ++tiles_loaded;
118
119                 if (tiles_loaded == tiles_per_layer) {
120                         tiles_loaded = 0;
121                         ++layers_loaded;
122                         if (layers_loaded == layers_total) {
123                                 listener.loader_done(layers_total * tiles_per_layer);
124                                 return;
125                         } else {
126                                 do_next = true;
127                         }
128                 }
129                 listener.loader_notify(layers_loaded * tiles_per_layer + tiles_loaded,
130                                        layers_total * tiles_per_layer, tile.store.file.toString());
131                 if (do_next)
132                         next_load();
133         }
134
135         public AltosMapCache cache() { return cache; }
136
137         public AltosMapLoader(AltosMap map, AltosMapCache cache,
138                               AltosMapLoaderListener listener) {
139                 this.map = map;
140                 this.cache = cache;
141                 this.listener = listener;
142         }
143 }