implement bundle tile download
git-svn-id: https://osmand.googlecode.com/svn/trunk@66 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
2b9afd0abb
commit
31a56b670a
4 changed files with 260 additions and 2 deletions
|
@ -40,6 +40,10 @@ public class ToDoConstants {
|
|||
// 14. Show zoom level directly on map
|
||||
// -------------------
|
||||
|
||||
// BUGS Androd :
|
||||
// 1. When firstly run osmand navigation (from notification bar) show map & go to menu shows desktop.
|
||||
// No chance to close application
|
||||
|
||||
|
||||
/// SWING version :
|
||||
// TODO :
|
||||
|
@ -52,5 +56,6 @@ public class ToDoConstants {
|
|||
// 9. Normalizing streets
|
||||
// 10. Reinvent index mechanism (save in zip file with tile indexes, save city/town addresses separately, read partially !)
|
||||
// 11. Street setName() change in city index!
|
||||
// 12. Invent different file extensions for poi.index, address.index,...
|
||||
|
||||
}
|
||||
|
|
|
@ -107,6 +107,14 @@ public class MapTileDownloader {
|
|||
return currentlyDownloaded.contains(f);
|
||||
}
|
||||
|
||||
public boolean isSomethingBeingDownloaded(){
|
||||
return !currentlyDownloaded.isEmpty();
|
||||
}
|
||||
|
||||
public int getRemainingWorkers(){
|
||||
return (int) (threadPoolExecutor.getTaskCount());
|
||||
}
|
||||
|
||||
|
||||
public void refuseAllPreviousRequests(){
|
||||
while(!threadPoolExecutor.getQueue().isEmpty()){
|
||||
|
@ -130,7 +138,7 @@ public class MapTileDownloader {
|
|||
|
||||
|
||||
private class DownloadMapWorker implements Runnable, Comparable<DownloadMapWorker> {
|
||||
private long time = System.currentTimeMillis();
|
||||
|
||||
private DownloadRequest request;
|
||||
|
||||
private DownloadMapWorker(DownloadRequest request){
|
||||
|
@ -143,6 +151,7 @@ public class MapTileDownloader {
|
|||
log.debug("Start downloading tile : " + request.url);
|
||||
}
|
||||
if (request != null && request.fileToSave != null && request.url != null) {
|
||||
long time = System.currentTimeMillis();
|
||||
currentlyDownloaded.add(request.fileToSave);
|
||||
try {
|
||||
request.fileToSave.getParentFile().mkdirs();
|
||||
|
|
|
@ -398,6 +398,7 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
|||
return;
|
||||
}
|
||||
this.zoom = zoom;
|
||||
updateLocationLabel();
|
||||
prepareImage();
|
||||
}
|
||||
|
||||
|
@ -529,7 +530,7 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback {
|
|||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
new TileBundleDownloadDialog(MapPanel.this, MapPanel.this).showDialog();
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
package com.osmand.swing;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import com.osmand.ExceptionHandler;
|
||||
import com.osmand.data.preparation.MapTileDownloader;
|
||||
import com.osmand.data.preparation.MapTileDownloader.DownloadRequest;
|
||||
import com.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback;
|
||||
import com.osmand.map.ITileSource;
|
||||
import com.osmand.osm.MapUtils;
|
||||
import com.osmand.swing.MapPanel.MapSelectionArea;
|
||||
|
||||
public class TileBundleDownloadDialog extends JDialog {
|
||||
|
||||
private static final long serialVersionUID = -4862884032977071296L;
|
||||
|
||||
private JLabel label;
|
||||
private ITileSource map;
|
||||
private MapSelectionArea selectionArea;
|
||||
private int zoom;
|
||||
private JSpinner startSpinner;
|
||||
private JSpinner endSpinner;
|
||||
private JButton downloadButton;
|
||||
private JButton cancelButton;
|
||||
private File tilesLocation;
|
||||
|
||||
public TileBundleDownloadDialog(Component parent, MapPanel panel){
|
||||
super(JOptionPane.getFrameForComponent(parent), true);
|
||||
map = panel.getMap();
|
||||
panel.getLatitude();
|
||||
selectionArea = panel.getSelectionArea();
|
||||
zoom = panel.getZoom();
|
||||
tilesLocation = panel.getTilesLocation();
|
||||
setTitle("Download bundle tiles");
|
||||
initDialog();
|
||||
|
||||
}
|
||||
|
||||
public void showDialog(){
|
||||
setSize(550, 150);
|
||||
double x = getParent().getBounds().getCenterX();
|
||||
double y = getParent().getBounds().getCenterY();
|
||||
setLocation((int) x - getWidth() / 2, (int) y - getHeight() / 2);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
protected SpinnerNumberModel getSpinnerModel(int minimum, int maximum){
|
||||
SpinnerNumberModel model = new SpinnerNumberModel();
|
||||
model.setStepSize(1);
|
||||
model.setValue(zoom);
|
||||
model.setMaximum(maximum);
|
||||
model.setMinimum(minimum);
|
||||
return model;
|
||||
}
|
||||
|
||||
private void initDialog() {
|
||||
JPanel pane = new JPanel(new BorderLayout());
|
||||
pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
add(pane);
|
||||
|
||||
label = new JLabel();
|
||||
pane.add(label, BorderLayout.CENTER);
|
||||
|
||||
JPanel zoomControls = new JPanel();
|
||||
zoomControls.setLayout(new BoxLayout(zoomControls, BoxLayout.X_AXIS));
|
||||
|
||||
JLabel lab = new JLabel("Start zoom level : ");
|
||||
zoomControls.add(lab);
|
||||
startSpinner = new JSpinner(getSpinnerModel(map.getMinimumZoomSupported(), zoom));
|
||||
zoomControls.add(startSpinner);
|
||||
startSpinner.setMaximumSize(new Dimension(15, startSpinner.getMaximumSize().height));
|
||||
|
||||
zoomControls.add(Box.createHorizontalStrut(15));
|
||||
lab = new JLabel("End zoom level : ");
|
||||
zoomControls.add(lab);
|
||||
endSpinner = new JSpinner(getSpinnerModel(zoom, map.getMaximumZoomSupported()));
|
||||
zoomControls.add(endSpinner);
|
||||
endSpinner.setMaximumSize(new Dimension(15, endSpinner.getMaximumSize().height));
|
||||
zoomControls.add(Box.createHorizontalGlue());
|
||||
pane.add(zoomControls, BorderLayout.NORTH);
|
||||
|
||||
|
||||
JPanel buttonControls = new JPanel();
|
||||
buttonControls.setLayout(new BoxLayout(buttonControls, BoxLayout.X_AXIS));
|
||||
buttonControls.add(Box.createHorizontalGlue());
|
||||
downloadButton = new JButton("Download tiles");
|
||||
buttonControls.add(downloadButton);
|
||||
buttonControls.add(Box.createHorizontalStrut(3));
|
||||
cancelButton = new JButton("Cancel");
|
||||
buttonControls.add(cancelButton);
|
||||
pane.add(buttonControls, BorderLayout.SOUTH);
|
||||
|
||||
updateLabel();
|
||||
addListeners();
|
||||
}
|
||||
|
||||
private void addListeners(){
|
||||
cancelButton.addActionListener(new ActionListener(){
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
startSpinner.addChangeListener(new ChangeListener(){
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
((SpinnerNumberModel)endSpinner.getModel()).setMinimum((Integer) startSpinner.getValue());
|
||||
updateLabel();
|
||||
}
|
||||
});
|
||||
endSpinner.addChangeListener(new ChangeListener(){
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
((SpinnerNumberModel)startSpinner.getModel()).setMaximum((Integer) endSpinner.getValue());
|
||||
updateLabel();
|
||||
}
|
||||
});
|
||||
downloadButton.addActionListener(new ActionListener(){
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
downloadTiles();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void downloadTiles(){
|
||||
setVisible(false);
|
||||
final ProgressDialog progressDialog = new ProgressDialog(this, "Downloading tiles");
|
||||
int numberTiles = 0;
|
||||
final int startZoom = (Integer) startSpinner.getValue();
|
||||
final int endZoom = (Integer) endSpinner.getValue();
|
||||
for (int zoom = startZoom; zoom <= endZoom; zoom++) {
|
||||
int x1 = (int) MapUtils.getTileNumberX(zoom, selectionArea.getLon1());
|
||||
int x2 = (int) MapUtils.getTileNumberX(zoom, selectionArea.getLon2());
|
||||
int y1 = (int) MapUtils.getTileNumberY(zoom, selectionArea.getLat1());
|
||||
int y2 = (int) MapUtils.getTileNumberY(zoom, selectionArea.getLat2());
|
||||
numberTiles += (x2 - x1 + 1) * (y2 - y1 + 1);
|
||||
}
|
||||
final int number = numberTiles;
|
||||
final MapTileDownloader instance = MapTileDownloader.getInstance();
|
||||
progressDialog.setRunnable(new Runnable(){
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
progressDialog.startTask("Loading...", number);
|
||||
for (int zoom = startZoom; zoom <= endZoom; zoom++) {
|
||||
int x1 = (int) MapUtils.getTileNumberX(zoom, selectionArea.getLon1());
|
||||
int x2 = (int) MapUtils.getTileNumberX(zoom, selectionArea.getLon2());
|
||||
int y1 = (int) MapUtils.getTileNumberY(zoom, selectionArea.getLat1());
|
||||
int y2 = (int) MapUtils.getTileNumberY(zoom, selectionArea.getLat2());
|
||||
for(int x = x1; x <= x2; x++){
|
||||
for(int y=y1; y<= y2; y++){
|
||||
String file = getFileForImage(x, y, zoom, map.getTileFormat());
|
||||
if(new File(tilesLocation, file).exists()){
|
||||
progressDialog.progress(1);
|
||||
} else {
|
||||
DownloadRequest req = new DownloadRequest(map.getUrlToLoad(x, y, zoom),
|
||||
new File(tilesLocation, file), x, y, zoom);
|
||||
instance.requestToDownload(req);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
while(instance.isSomethingBeingDownloaded()){
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
IMapDownloaderCallback previousCallback = instance.getDownloaderCallback();
|
||||
instance.setDownloaderCallback(new IMapDownloaderCallback(){
|
||||
|
||||
@Override
|
||||
public void tileDownloaded(DownloadRequest request) {
|
||||
// TODO request could be null if bundle loading?
|
||||
progressDialog.progress(1);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
try {
|
||||
progressDialog.run();
|
||||
instance.refuseAllPreviousRequests();
|
||||
} catch (InvocationTargetException e) {
|
||||
ExceptionHandler.handle((Exception) e.getCause());
|
||||
} catch (InterruptedException e) {
|
||||
ExceptionHandler.handle(e);
|
||||
} finally {
|
||||
instance.setDownloaderCallback(previousCallback);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getFileForImage (int x, int y, int zoom, String ext){
|
||||
return map.getName() +"/"+zoom+"/"+(x) +"/"+y+ext+".tile";
|
||||
}
|
||||
|
||||
|
||||
protected void updateLabel(){
|
||||
int numberTiles = 0;
|
||||
for (int zoom = (Integer) startSpinner.getValue(); zoom <= (Integer) endSpinner.getValue(); zoom++) {
|
||||
int x1 = (int) MapUtils.getTileNumberX(zoom, selectionArea.getLon1());
|
||||
int x2 = (int) MapUtils.getTileNumberX(zoom, selectionArea.getLon2());
|
||||
int y1 = (int) MapUtils.getTileNumberY(zoom, selectionArea.getLat1());
|
||||
int y2 = (int) MapUtils.getTileNumberY(zoom, selectionArea.getLat2());
|
||||
numberTiles += (x2 - x1 + 1) * (y2 - y1 + 1);
|
||||
}
|
||||
|
||||
String text = MessageFormat.format("Request to download {0} tiles from ''{1}'' (approximately {2} Mb)",
|
||||
numberTiles, map.getName(), (double)numberTiles*12/1000);
|
||||
label.setText(text);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue