source: osm/applications/editors/josm/plugins/imagery_offset_db/src/iodb/GetImageryOffsetAction.java@ 27986

Last change on this file since 27986 was 27986, checked in by zverik, 12 years ago

imagery_offset_db initial commit

File size: 6.8 KB
Line 
1package iodb;
2
3import java.awt.event.ActionEvent;
4import java.awt.event.KeyEvent;
5import java.io.IOException;
6import java.io.InputStream;
7import java.io.UnsupportedEncodingException;
8import java.net.*;
9import java.util.ArrayList;
10import java.util.Collections;
11import java.util.HashMap;
12import java.util.List;
13import java.util.concurrent.Future;
14import java.util.logging.Level;
15import java.util.logging.Logger;
16import org.openstreetmap.gui.jmapviewer.tilesources.AbstractTMSTileSource;
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.actions.JosmAction;
19import org.openstreetmap.josm.data.coor.LatLon;
20import org.openstreetmap.josm.data.projection.Projection;
21import org.openstreetmap.josm.gui.MapView;
22import org.openstreetmap.josm.gui.PleaseWaitRunnable;
23import org.openstreetmap.josm.gui.layer.ImageryLayer;
24import org.openstreetmap.josm.gui.progress.ProgressMonitor;
25import org.openstreetmap.josm.io.OsmTransferException;
26import static org.openstreetmap.josm.tools.I18n.tr;
27import org.openstreetmap.josm.tools.Shortcut;
28import org.xml.sax.SAXException;
29
30/**
31 * Download a list of imagery offsets for the current position, let user choose which one to use.
32 *
33 * @author zverik
34 */
35public class GetImageryOffsetAction extends JosmAction {
36
37 private List<ImageryOffsetBase> offsets;
38
39 private HashMap<String, String> imageryAliases;
40
41 public GetImageryOffsetAction() {
42 super(tr("Get Imagery Offset..."), "getoffset", tr("Download offsets for current imagery from a server"),
43 Shortcut.registerShortcut("imageryoffset:get", tr("Imagery: {0}", tr("Get Imagery Offset...")), KeyEvent.VK_I, Shortcut.ALT+Shortcut.CTRL), true);
44 offsets = Collections.emptyList();
45 }
46
47 public void actionPerformed(ActionEvent e) {
48 Projection proj = Main.map.mapView.getProjection();
49 LatLon center = proj.eastNorth2latlon(Main.map.mapView.getCenter());
50 // todo: download a list of offsets for current bbox * N
51 List<ImageryOffsetBase> offsets = download(center); // todo: async
52 DownloadOffsets download = new DownloadOffsets();
53 Future<?> future = Main.worker.submit(download);
54 try {
55 future.get();
56 } catch( Exception ex ) {
57 ex.printStackTrace();
58 return;
59 }
60
61 // todo: show a dialog for selecting one of the offsets (without "update" flag)
62 ImageryOffsetBase offset = new OffsetDialog(offsets).showDialog();
63 if( offset != null ) {
64 // todo: use the chosen offset
65 }
66 }
67
68 private List<ImageryOffsetBase> download( LatLon center ) {
69 String base = Main.pref.get("iodb.server.url", "http://textual.ru/iodb.php");
70 String query = "?action=get&lat=" + center.getX() + "&lon=" + center.getY();
71 List<ImageryOffsetBase> result = null;
72 try {
73 query = query + "&imagery=" + URLEncoder.encode(getImageryID(), "utf-8");
74 URL url = new URL(base + query);
75 HttpURLConnection connection = (HttpURLConnection)url.openConnection();
76 connection.connect();
77 int retCode = connection.getResponseCode();
78 InputStream inp = connection.getInputStream();
79 if( inp != null ) {
80 result = new IODBReader(inp).parse();
81 }
82 connection.disconnect();
83 } catch( MalformedURLException ex ) {
84 // ?
85 } catch( UnsupportedEncodingException e ) {
86 // do nothing. WTF is that?
87 } catch( IOException e ) {
88 e.printStackTrace();
89 // ?
90 } catch( SAXException e ) {
91 e.printStackTrace();
92 // ?
93 }
94 if( result == null )
95 result = new ArrayList<ImageryOffsetBase>();
96 return result;
97 }
98
99 private String getImageryID() {
100 List<ImageryLayer> layers = Main.map.mapView.getLayersOfType(ImageryLayer.class);
101 String url = null;
102 for( ImageryLayer layer : layers ) {
103 if( layer.isVisible() ) {
104 url = layer.getInfo().getUrl();
105 break;
106 }
107 }
108 if( url == null )
109 return null;
110
111 if( imageryAliases == null )
112 loadImageryAliases();
113 for( String substr : imageryAliases.keySet() )
114 if( url.contains(substr) )
115 return imageryAliases.get(substr);
116
117 return url; // todo: strip parametric parts, etc
118 }
119
120 private void loadImageryAliases() {
121 if( imageryAliases == null )
122 imageryAliases = new HashMap<String, String>();
123 else
124 imageryAliases.clear();
125
126 // { substring, alias }
127 imageryAliases.put("bing", "bing");
128 // todo: load from a resource?
129 }
130
131 // Following three methods were snatched from TMSLayer
132 private double latToTileY(double lat, int zoom) {
133 double l = lat / 180 * Math.PI;
134 double pf = Math.log(Math.tan(l) + (1 / Math.cos(l)));
135 return Math.pow(2.0, zoom - 1) * (Math.PI - pf) / Math.PI;
136 }
137
138 private double lonToTileX(double lon, int zoom) {
139 return Math.pow(2.0, zoom - 3) * (lon + 180.0) / 45.0;
140 }
141
142 private int getCurrentZoom() {
143 if (Main.map == null || Main.map.mapView == null) {
144 return 1;
145 }
146 MapView mv = Main.map.mapView;
147 LatLon topLeft = mv.getLatLon(0, 0);
148 LatLon botRight = mv.getLatLon(mv.getWidth(), mv.getHeight());
149 double x1 = lonToTileX(topLeft.lon(), 1);
150 double y1 = latToTileY(topLeft.lat(), 1);
151 double x2 = lonToTileX(botRight.lon(), 1);
152 double y2 = latToTileY(botRight.lat(), 1);
153
154 int screenPixels = mv.getWidth() * mv.getHeight();
155 double tilePixels = Math.abs((y2 - y1) * (x2 - x1) * 256 * 256);
156 if (screenPixels == 0 || tilePixels == 0) {
157 return 1;
158 }
159 double factor = screenPixels / tilePixels;
160 double result = Math.log(factor) / Math.log(2) / 2 + 1;
161 int intResult = (int) Math.floor(result);
162 return intResult;
163 }
164
165 class DownloadOffsets extends PleaseWaitRunnable {
166
167 private boolean cancelled;
168
169 public DownloadOffsets() {
170 super(tr("Downloading calibration data"));
171 cancelled = false;
172 }
173
174 @Override
175 protected void realRun() throws SAXException, IOException, OsmTransferException {
176 // todo: open httpconnection to server and read xml
177 if( cancelled )
178 return;
179
180 }
181
182 @Override
183 protected void finish() {
184 if( cancelled )
185 return;
186 // todo: parse xml and return an array of ImageryOffsetBase
187 }
188
189 @Override
190 protected void cancel() {
191 cancelled = true;
192 }
193 }
194}
Note: See TracBrowser for help on using the repository browser.