Merge branch 'scan-telemetry' into preload-maps
[fw/altos] / altosui / AltosSiteMapPreload.java
1 /*
2  * Copyright © 2011 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 altosui;
19
20 import java.awt.*;
21 import java.awt.image.*;
22 import java.awt.event.*;
23 import javax.swing.*;
24 import javax.swing.event.MouseInputAdapter;
25 import javax.imageio.ImageIO;
26 import javax.swing.table.*;
27 import java.io.*;
28 import java.util.*;
29 import java.text.*;
30 import java.util.prefs.*;
31 import java.lang.Math;
32 import java.awt.geom.Point2D;
33 import java.awt.geom.Line2D;
34
35 class AltosMapPos extends Box {
36         JLabel          label;
37         JComboBox       hemi;
38         JTextField      deg;
39         JLabel          deg_label;
40         JTextField      min;
41         JLabel          min_label;
42
43         public void set_value(double new_value) {
44                 double  d, m;
45                 int     h;
46
47                 h = 0;
48                 if (new_value < 0) {
49                         h = 1;
50                         new_value = -new_value;
51                 }
52                 d = Math.floor(new_value);
53                 deg.setText(String.format("%3.0f", d));
54                 m = (new_value - d) * 60.0;
55                 min.setText(String.format("%7.4f", m));
56                 hemi.setSelectedIndex(h);
57         }
58
59         public double get_value() throws NumberFormatException {
60                 int     h = hemi.getSelectedIndex();
61                 double d = Double.parseDouble(deg.getText());
62                 double m = Double.parseDouble(min.getText());
63                 double v = d + m/60.0;
64                 if (h == 1)
65                         v = -v;
66                 return v;
67         }
68
69         public AltosMapPos(String label_value,
70                            String[] hemi_names,
71                            double default_value) {
72                 super(BoxLayout.X_AXIS);
73                 label = new JLabel(label_value);
74                 hemi = new JComboBox(hemi_names);
75                 hemi.setEditable(false);
76                 deg = new JTextField("000");
77                 deg_label = new JLabel("degrees");
78                 min = new JTextField("00.0000");
79                 min_label = new JLabel("minutes");
80                 set_value(default_value);
81                 add(label);
82                 add(Box.createRigidArea(new Dimension(5, 0)));
83                 add(hemi);
84                 add(Box.createRigidArea(new Dimension(5, 0)));
85                 add(deg);
86                 add(Box.createRigidArea(new Dimension(5, 0)));
87                 add(deg_label);
88                 add(Box.createRigidArea(new Dimension(5, 0)));
89                 add(min);
90                 add(Box.createRigidArea(new Dimension(5, 0)));
91                 add(min_label);
92         }
93 }
94
95 public class AltosSiteMapPreload extends JDialog implements ActionListener {
96         AltosUI         owner;
97         AltosSiteMap    map;
98
99         AltosMapPos     lat;
100         AltosMapPos     lon;
101
102         JProgressBar    pbar;
103
104         final static int        width = 9;
105         final static int        height = 9;
106         final static int        tiles = width * height;
107
108         JToggleButton   load_button;
109         boolean         loading;
110         JButton         close_button;
111
112         static final String[]   lat_hemi_names = { "N", "S" };
113         static final String[]   lon_hemi_names = { "E", "W" };
114
115         class updatePbar implements Runnable {
116                 int             n;
117                 String          s;
118
119                 public updatePbar(int in_n, String in_s) {
120                         n = in_n;
121                         s = in_s;
122                 }
123
124                 public void run() {
125                         pbar.setValue(n);
126                         pbar.setString(s);
127                         if (n == width * height) {
128                                 load_button.setSelected(false);
129                                 loading = false;
130                         }
131                 }
132         }
133
134         class bgLoad extends Thread {
135
136                 AltosSiteMap    map;
137
138                 public bgLoad(AltosSiteMap in_map) {
139                         map = in_map;
140                 }
141
142                 public void run() {
143                         for (int y = 0; y < height; y++) {
144                                 for (int x = 0; x < width; x++) {
145                                         map.prefetchMap(y - height/2, x - width/2);
146                                         SwingUtilities.invokeLater(new updatePbar(y * height + x + 1,
147                                                                                   map.pngfile.toString()));
148                                 }
149                         }
150                 }
151         }
152
153         public void actionPerformed(ActionEvent e) {
154                 String  cmd = e.getActionCommand();
155
156                 if (cmd.equals("close"))
157                         setVisible(false);
158
159                 if (cmd.equals("load")) {
160                         if (!loading) {
161                                 loading = true;
162                                 final double    latitude = lat.get_value();
163                                 final double    longitude = lon.get_value();
164                                 map.show(latitude,longitude);
165                                 bgLoad thread = new bgLoad(map);
166                                 thread.start();
167                         }
168                 }
169         }
170
171         public AltosSiteMapPreload(AltosUI in_owner) {
172                 owner = in_owner;
173
174                 Container               pane = getContentPane();
175                 GridBagConstraints      c = new GridBagConstraints();
176                 Insets                  i = new Insets(4,4,4,4);
177
178                 pane.setLayout(new GridBagLayout());
179
180                 map = new AltosSiteMap();
181
182                 c.fill = GridBagConstraints.BOTH;
183                 c.anchor = GridBagConstraints.CENTER;
184                 c.insets = i;
185                 c.weightx = 1;
186                 c.weighty = 1;
187
188                 c.gridx = 0;
189                 c.gridy = 0;
190                 c.gridwidth = 2;
191                 c.anchor = GridBagConstraints.CENTER;
192
193                 pane.add(map, c);
194
195                 pbar = new JProgressBar();
196                 pbar.setMinimum(0);
197                 pbar.setMaximum(width * height);
198                 pbar.setValue(0);
199                 pbar.setString("");
200                 pbar.setStringPainted(true);
201                 
202                 c.fill = GridBagConstraints.HORIZONTAL;
203                 c.anchor = GridBagConstraints.CENTER;
204                 c.insets = i;
205                 c.weightx = 1;
206                 c.weighty = 0;
207
208                 c.gridx = 0;
209                 c.gridy = 1;
210                 c.gridwidth = 2;
211
212                 pane.add(pbar, c);
213
214                 lat = new AltosMapPos("Latitude:",
215                                       lat_hemi_names,
216                                       37.167833333);
217                 c.fill = GridBagConstraints.NONE;
218                 c.anchor = GridBagConstraints.CENTER;
219                 c.insets = i;
220                 c.weightx = 0;
221                 c.weighty = 0;
222
223                 c.gridx = 0;
224                 c.gridy = 2;
225                 c.gridwidth = 1;
226                 c.anchor = GridBagConstraints.CENTER;
227
228                 pane.add(lat, c);
229                 
230                 lon = new AltosMapPos("Longitude:",
231                                       lon_hemi_names,
232                                       -97.73975);
233
234                 c.fill = GridBagConstraints.NONE;
235                 c.anchor = GridBagConstraints.CENTER;
236                 c.insets = i;
237                 c.weightx = 0;
238                 c.weighty = 0;
239
240                 c.gridx = 1;
241                 c.gridy = 2;
242                 c.gridwidth = 1;
243                 c.anchor = GridBagConstraints.CENTER;
244
245                 pane.add(lon, c);
246
247                 load_button = new JToggleButton("Load Map");
248                 load_button.addActionListener(this);
249                 load_button.setActionCommand("load");
250                 
251                 c.fill = GridBagConstraints.NONE;
252                 c.anchor = GridBagConstraints.CENTER;
253                 c.insets = i;
254                 c.weightx = 1;
255                 c.weighty = 0;
256
257                 c.gridx = 0;
258                 c.gridy = 3;
259                 c.gridwidth = 1;
260                 c.anchor = GridBagConstraints.CENTER;
261
262                 pane.add(load_button, c);
263
264                 close_button = new JButton("Close");
265                 close_button.addActionListener(this);
266                 close_button.setActionCommand("close");
267                 
268                 c.fill = GridBagConstraints.NONE;
269                 c.anchor = GridBagConstraints.CENTER;
270                 c.insets = i;
271                 c.weightx = 1;
272                 c.weighty = 0;
273
274                 c.gridx = 1;
275                 c.gridy = 3;
276                 c.gridwidth = 1;
277                 c.anchor = GridBagConstraints.CENTER;
278
279                 pane.add(close_button, c);
280
281                 pack();
282                 setLocationRelativeTo(owner);
283                 setVisible(true);
284         }
285 }