add downloader for tile

git-svn-id: https://osmand.googlecode.com/svn/trunk@25 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-04-30 14:35:33 +00:00
parent fcaecf9d63
commit 76b36291bb
10 changed files with 605 additions and 173 deletions

View file

@ -0,0 +1,8 @@
.level = ERROR
handlers=java.util.logging.ConsoleHandler
# Set the default logging level for the logger named com.mycompany
com.osmand.level = ALL
java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

View file

@ -1,9 +1,19 @@
package com.osmand; package com.osmand;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/** /**
* Basic algorithms that are not in jdk * Basic algorithms that are not in jdk
*/ */
public class Algoritms { public class Algoritms {
private static final int BUFFER_SIZE = 1024;
private static final Log log = LogFactory.getLog(Algoritms.class);
public static boolean isEmpty(String s){ public static boolean isEmpty(String s){
return s == null || s.length() == 0; return s == null || s.length() == 0;
@ -18,4 +28,22 @@ public class Algoritms {
} }
} }
public static void streamCopy(InputStream in, OutputStream out) throws IOException{
byte[] b = new byte[BUFFER_SIZE];
int read;
while ((read = in.read(b)) != -1) {
out.write(b, 0, read);
}
}
public static void closeStream(Closeable stream){
try {
if(stream != null){
stream.close();
}
} catch(IOException e){
log.warn("Closing stream warn", e);
}
}
} }

View file

@ -3,6 +3,7 @@ package com.osmand;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Component; import java.awt.Component;
import java.awt.Container; import java.awt.Container;
import java.awt.MenuBar;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
@ -427,7 +428,9 @@ public class DataExtraction implements IMapLocationListener {
} }
}); });
MenuBar bar = new MenuBar();
bar.add(MapPanel.getMenuToChooseSource(mapPanel));
frame.setMenuBar(bar);
frame.setSize(1024, 768); frame.setSize(1024, 768);
frame.setVisible(true); frame.setVisible(true);
} }

View file

@ -1,16 +1,42 @@
package com.osmand; package com.osmand;
import com.osmand.map.ITileSource;
import com.osmand.map.TileSourceManager;
/** /**
* This is temp class where all path & machine specific properties are written * This is temp class where all path & machine specific properties are written
*/ */
public abstract class DefaultLauncherConstants { public abstract class DefaultLauncherConstants {
// External files
public static String pathToTestDataDir = "E:\\Information\\OSM maps\\"; public static String pathToTestDataDir = "E:\\Information\\OSM maps\\";
public static String pathToOsmFile = pathToTestDataDir + "minsk.osm"; public static String pathToOsmFile = pathToTestDataDir + "minsk.osm";
public static String pathToOsmBz2File = pathToTestDataDir + "belarus_2010_04_01.osm.bz2"; public static String pathToOsmBz2File = pathToTestDataDir + "belarus_2010_04_01.osm.bz2";
public static String pathToDirWithTiles = pathToTestDataDir +"MinskTiles"; public static String pathToDirWithTiles = pathToTestDataDir +"MinskTiles";
public static String writeTestOsmFile = "C:\\1_tmp.osm"; // could be null - wo writing public static String writeTestOsmFile = "C:\\1_tmp.osm"; // could be null - wo writing
// Initial map settings
public static double MAP_startMapLongitude = 27.56;
public static double MAP_startMapLatitude = 53.9;
public static int MAP_startMapZoom = 15;
public static int MAP_divNonLoadedImage = 8;
public static boolean loadMissingImages = true;
public static ITileSource MAP_defaultTileSource = TileSourceManager.getMapnikSource();
// Application constants
public static String APP_NAME = "OsmAnd";
public static String APP_VERSION = "0.1";
// Download manager tile settings
public static int TILE_DOWNLOAD_THREADS = 4;
public static int TILE_DOWNLOAD_SECONTS_TO_WORK = 25;
} }

View file

@ -5,25 +5,25 @@ import java.awt.Color;
import java.awt.Container; import java.awt.Container;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Image; import java.awt.Image;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Point; import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter; import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Stack;
import javax.imageio.IIOException; import javax.imageio.IIOException;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
@ -35,16 +35,39 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import com.osmand.DataExtraction.ExitListener; import com.osmand.DataExtraction.ExitListener;
import com.osmand.MapTileDownloader.DownloadRequest;
import com.osmand.MapTileDownloader.IMapDownloaderCallback;
import com.osmand.data.DataTileManager; import com.osmand.data.DataTileManager;
import com.osmand.map.ITileSource;
import com.osmand.map.TileSourceManager;
import com.osmand.map.TileSourceManager.TileSourceTemplate;
import com.osmand.osm.LatLon; import com.osmand.osm.LatLon;
import com.osmand.osm.MapUtils; import com.osmand.osm.MapUtils;
public class MapPanel extends JPanel { public class MapPanel extends JPanel implements IMapDownloaderCallback {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Log log = LogFactory.getLog(MapPanel.class); protected static final Log log = LogFactory.getLog(MapPanel.class);
public static Menu getMenuToChooseSource(final MapPanel panel){
Menu tiles = new Menu("Source tile");
List<TileSourceTemplate> list = TileSourceManager.getKnownSourceTemplates();
for(final TileSourceTemplate l : list){
MenuItem menuItem = new MenuItem(l.getName());
menuItem.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
panel.setMapName(l);
}
});
tiles.add(menuItem);
}
return tiles;
}
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("Tree of choose"); JFrame frame = new JFrame("Tree of choose");
@ -61,33 +84,33 @@ public class MapPanel extends JPanel {
MapPanel panel = new MapPanel(new File(DefaultLauncherConstants.pathToDirWithTiles)); MapPanel panel = new MapPanel(new File(DefaultLauncherConstants.pathToDirWithTiles));
content.add(panel, BorderLayout.CENTER); content.add(panel, BorderLayout.CENTER);
MenuBar bar = new MenuBar();
bar.add(getMenuToChooseSource(panel));
frame.setMenuBar(bar);
frame.setSize(512, 512); frame.setSize(512, 512);
frame.setVisible(true); frame.setVisible(true);
} }
// name of source map private File tilesLocation = null;
private String map = "Mapnik";
// name of source map
private ITileSource map = DefaultLauncherConstants.MAP_defaultTileSource;
// tile size of map
private final int tileSize = 256;
// file name with tiles
private final File fileWithTiles;
// special points to draw // special points to draw
private DataTileManager<LatLon> points; private DataTileManager<LatLon> points;
// zoom levle // zoom level
private int zoom = 15; private int zoom = DefaultLauncherConstants.MAP_startMapZoom;
// degree measurements (-180, 180) // degree measurements (-180, 180)
// долгота // долгота
private double longitude = 27.56; private double longitude = DefaultLauncherConstants.MAP_startMapLongitude;
// широта // широта
// degree measurements (90, -90) // degree measurements (90, -90)
private double latitude = 53.9; private double latitude = DefaultLauncherConstants.MAP_startMapLatitude;
private List<IMapLocationListener> listeners = new ArrayList<IMapLocationListener>(); private List<IMapLocationListener> listeners = new ArrayList<IMapLocationListener>();
@ -97,15 +120,23 @@ public class MapPanel extends JPanel {
private int yStartingImage = 0; private int yStartingImage = 0;
private List<Point> pointsToDraw = new ArrayList<Point>(); private List<Point> pointsToDraw = new ArrayList<Point>();
private AsyncLoadTileThread autoThread = new AsyncLoadTileThread(); private MapTileDownloader downloader = MapTileDownloader.getInstance();
Map<String, Image> cache = new HashMap<String, Image>(); Map<String, Image> cache = new HashMap<String, Image>();
public MapPanel(File fileWithTiles) { public MapPanel(File fileWithTiles) {
this.fileWithTiles = fileWithTiles; tilesLocation = fileWithTiles;
autoThread.start(); downloader.setDownloaderCallback(this);
initUI(); setFocusable(true);
addComponentListener(new ComponentAdapter(){
public void componentResized(ComponentEvent e) {
prepareImage();
}
});
MapMouseAdapter mouse = new MapMouseAdapter();
addMouseListener(mouse);
addMouseMotionListener(mouse);
} }
@ -117,176 +148,99 @@ public class MapPanel extends JPanel {
return MapUtils.getTileNumberY(zoom, latitude); return MapUtils.getTileNumberY(zoom, latitude);
} }
public int getTileSize(){
return map == null ? 256 : map.getTileSize();
}
@Override @Override
protected void paintComponent(Graphics g) { protected void paintComponent(Graphics g) {
if (images != null) { if (images != null) {
for (int i = 0; i < images.length; i++) { for (int i = 0; i < images.length; i++) {
for (int j = 0; j < images[i].length; j++) { for (int j = 0; j < images[i].length; j++) {
if(images[i][j] == null){ if (images[i][j] == null) {
int div = 4; int div = DefaultLauncherConstants.MAP_divNonLoadedImage;
int tileDiv = tileSize / div; int tileDiv = getTileSize() / div;
for(int k1 = 0; k1 < div; k1++){ for (int k1 = 0; k1 < div; k1++) {
for(int k2 = 0; k2 < div; k2++){ for (int k2 = 0; k2 < div; k2++) {
if ((k1 + k2) % 2 == 0) { if ((k1 + k2) % 2 == 0) {
g.setColor(Color.gray); g.setColor(Color.gray);
} else { } else {
g.setColor(Color.white); g.setColor(Color.white);
} }
g.fillRect(i * tileSize+xStartingImage + k1*tileDiv, g.fillRect(i * getTileSize() + xStartingImage + k1 * tileDiv, j * getTileSize() + yStartingImage + k2
j * tileSize + yStartingImage + k2*tileDiv, tileDiv, tileDiv); * tileDiv, tileDiv, tileDiv);
} }
} }
} else { } else {
g.drawImage(images[i][j], i * tileSize+xStartingImage, j * tileSize + yStartingImage, this); g.drawImage(images[i][j], i * getTileSize() + xStartingImage, j * getTileSize() + yStartingImage, this);
} }
} }
} }
} }
g.setColor(Color.black); g.setColor(Color.black);
// draw user points // draw user points
for(Point p : pointsToDraw){ for (Point p : pointsToDraw) {
g.drawOval(p.x, p.y, 3, 3); g.drawOval(p.x, p.y, 3, 3);
g.fillOval(p.x, p.y, 3, 3); g.fillOval(p.x, p.y, 3, 3);
} }
String s = MessageFormat.format("Lat : {0}, lon : {1}, zoom : {2}",latitude, longitude, zoom); String s = MessageFormat.format("Lat : {0}, lon : {1}, zoom : {2}", latitude, longitude, zoom);
g.drawString(s, 5, 20); g.drawString(s, 5, 20);
g.fillOval(getWidth() / 2 - 2, getHeight() / 2 - 2, 4, 4);
g.fillOval(getWidth()/2 - 2, getHeight()/2 -2, 4, 4); g.drawOval(getWidth() / 2 - 2, getHeight() / 2 - 2, 4, 4);
g.drawOval(getWidth()/2 - 2, getHeight()/2 -2, 4, 4); g.drawOval(getWidth() / 2 - 5, getHeight() / 2 - 5, 10, 10);
g.drawOval(getWidth()/2 - 5, getHeight()/2 -5, 10, 10);
} }
public String getFile(int zoom, int x, int y){
return map +"/"+zoom+"/"+(x) +"/"+y+".png";
}
public Image getImageFor(int x, int y) throws IOException{ public String getFileForImage (int x, int y, int zoom){
String file = getFile(zoom, x, y); return map.getName() +"/"+zoom+"/"+(x) +"/"+y+".png";
}
public Image getImageFor(int x, int y, int zoom) throws IOException{
if(map == null){
return null;
}
String file = getFileForImage(x, y, zoom);
if(!cache.containsKey(file)){ if(!cache.containsKey(file)){
// ZipEntry en = fileWithTiles.getEntry(file); File en = new File(tilesLocation, file);
File en = new File(fileWithTiles, file);
if(cache.size() > 1000){ if(cache.size() > 1000){
ArrayList<String> list = new ArrayList<String>(cache.keySet()); ArrayList<String> list = new ArrayList<String>(cache.keySet());
for(int i=0; i<list.size(); i+=2){ for(int i=0; i<list.size(); i+=2){
cache.remove(list.get(i)); cache.remove(list.get(i));
} }
} }
// if(en != null){
if(en.exists()){ if(en.exists()){
// cache.put(file, ImageIO.read(fileWithTiles.getInputStream(en)));
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
cache.put(file, ImageIO.read(en)); try {
System.out.println("Loaded " + (System.currentTimeMillis() - time)); cache.put(file, ImageIO.read(en));
} else { if(log.isDebugEnabled()){
autoThread.requestTileToLoad(zoom, x, y); log.debug("Loaded file : " + file + " " + -(time -System.currentTimeMillis())+" ms");
} }
} catch (IIOException e) {
log.error("Eror reading png " + x +" " + y + " zoom : " + zoom, e);
}
}
} }
return cache.get(file); return cache.get(file);
} }
public void loadImage(int zoom, int x, int y){ @Override
try { public void tileDownloaded(String dowloadedUrl, DownloadRequest fileSaved) {
Image img = null; prepareImage(false);
File en = new File(fileWithTiles, getFile(zoom, x, y));
URL url = new URL("http://tile.openstreetmap.org/" + zoom + "/" + x + "/" + y + ".png");
en.getParentFile().mkdirs();
try {
ImageIO.setUseCache(true);
javax.imageio.ImageIO.setCacheDirectory(en.getParentFile());
} catch (Exception e) {
log.warn("cannot set ImageIO cache-directory to " + en.getParent(), e);
}
try {
URLConnection connection = url.openConnection();
connection.setRequestProperty("User-Agent", "osmand TilePainter/0.1");
img = javax.imageio.ImageIO.read(connection.getInputStream());
} catch (UnknownHostException e) {
log.info("UnknownHostException, cannot download tile " + url.toExternalForm());
} catch (IIOException e) {
if (e.getCause() != null && e.getCause() instanceof UnknownHostException) {
log.info("UnknownHostException, cannot download tile " + url.toExternalForm(), e);
} else {
log.warn("cannot download tile " + url.toExternalForm(), e);
}
}
cache.put(getFile(zoom, x, y), img);
if (img != null) {
try {
ImageIO.write((RenderedImage) img, "png", en);
} catch (IOException e) {
log.warn("cannot save img to " + en.getAbsolutePath(), e);
}
}
} catch (IOException e) {
log.warn("cannot download pre-rendered tile [" + e.getClass().getSimpleName() + "]", e);
}
} }
public class AsyncLoadTileThread extends Thread {
Stack<TileIndex> tilesToLoad = new Stack<TileIndex>();
private class TileIndex {
int zoom;
int x;
int y;
}
public AsyncLoadTileThread() {
super("AsyncLoadingTiles");
}
@Override
public void run() {
try {
while (true) {
synchronized (this) {
wait();
}
while (!tilesToLoad.isEmpty()) {
TileIndex p = tilesToLoad.pop();
if (cache.get(getFile(p.zoom, p.x, p.y)) == null) {
loadImage(p.zoom, p.x, p.y);
// TODO dead cycle (causes cancelAllPreviousTile)
prepareImage();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void cancelAllPreviousTile(){
tilesToLoad.clear();
}
public void requestTileToLoad(int zoom, int x, int y){
synchronized (this) {
TileIndex ind = new TileIndex();
ind.zoom = zoom;
ind.x = x;
ind.y = y;
tilesToLoad.add(ind);
notify();
}
}
}
// TODO async loading images (show busy cursor while it is loaded)
public void prepareImage(){ public void prepareImage(){
prepareImage(DefaultLauncherConstants.loadMissingImages);
}
public void prepareImage(boolean loadNecessaryImages){
try { try {
int tileSize = getTileSize();
if (images != null) { if (images != null) {
for (int i = 0; i < images.length; i++) { for (int i = 0; i < images.length; i++) {
for (int j = 0; j < images[i].length; j++) { for (int j = 0; j < images[i].length; j++) {
@ -303,13 +257,24 @@ public class MapPanel extends JPanel {
xStartingImage = -(int) ((xTileLeft - Math.floor(xTileLeft)) * tileSize); xStartingImage = -(int) ((xTileLeft - Math.floor(xTileLeft)) * tileSize);
yStartingImage = -(int) ((yTileUp - Math.floor(yTileUp)) * tileSize); yStartingImage = -(int) ((yTileUp - Math.floor(yTileUp)) * tileSize);
autoThread.cancelAllPreviousTile(); if(loadNecessaryImages){
downloader.refuseAllPreviousRequests();
}
int tileXCount = ((int) xTileRight - (int) xTileLeft + 1); int tileXCount = ((int) xTileRight - (int) xTileLeft + 1);
int tileYCount = ((int) yTileDown - (int) yTileUp + 1); int tileYCount = ((int) yTileDown - (int) yTileUp + 1);
images = new BufferedImage[tileXCount][tileYCount]; images = new BufferedImage[tileXCount][tileYCount];
for (int i = 0; i < images.length; i++) { for (int i = 0; i < images.length; i++) {
for (int j = 0; j < images[i].length; j++) { for (int j = 0; j < images[i].length; j++) {
images[i][j] = getImageFor((int) xTileLeft + i, (int) yTileUp + j); int x= (int) xTileLeft + i;
int y = (int) yTileUp + j;
images[i][j] = getImageFor(x, y, zoom);
if(loadNecessaryImages && images[i][j] == null && map != null){
String urlToLoad = map.getUrlToLoad(x, y, zoom);
if(urlToLoad != null){
downloader.requestToDownload(urlToLoad,
new DownloadRequest(new File(tilesLocation, getFileForImage(x, y, zoom))));
}
}
} }
} }
@ -337,19 +302,6 @@ public class MapPanel extends JPanel {
private void initUI() {
setFocusable(true);
addComponentListener(new ComponentAdapter(){
public void componentResized(ComponentEvent e) {
prepareImage();
}
});
MapMouseAdapter mouse = new MapMouseAdapter();
addMouseListener(mouse);
addMouseMotionListener(mouse);
}
public void setZoom(int zoom){ public void setZoom(int zoom){
this.zoom = zoom; this.zoom = zoom;
prepareImage(); prepareImage();
@ -374,11 +326,11 @@ public class MapPanel extends JPanel {
return zoom; return zoom;
} }
public String getMap(){ public ITileSource getMap(){
return map; return map;
} }
public void setMapName(String map){ public void setMapName(ITileSource map){
this.map = map; this.map = map;
prepareImage(); prepareImage();
} }
@ -422,12 +374,12 @@ public class MapPanel extends JPanel {
} }
if(e.getID() == KeyEvent.KEY_TYPED){ if(e.getID() == KeyEvent.KEY_TYPED){
if(e.getKeyChar() == '+'){ if(e.getKeyChar() == '+'){
if(zoom < 18){ if(zoom < map.getMaximumZoomSupported()){
zoom ++; zoom ++;
processed = true; processed = true;
} }
} else if(e.getKeyChar() == '-'){ } else if(e.getKeyChar() == '-'){
if(zoom > 1){ if(zoom > map.getMinimumZoomSupported()){
zoom --; zoom --;
processed = true; processed = true;
} }
@ -461,8 +413,8 @@ public class MapPanel extends JPanel {
} }
public void dragTo(Point p){ public void dragTo(Point p){
double dx = (startDragging.x - (double)p.x)/tileSize; double dx = (startDragging.x - (double)p.x)/getTileSize();
double dy = (startDragging.y - (double)p.y)/tileSize; double dy = (startDragging.y - (double)p.y)/getTileSize();
double lat = MapUtils.getLatitudeFromTile(zoom, getYTile() + dy); double lat = MapUtils.getLatitudeFromTile(zoom, getYTile() + dy);
double lon = MapUtils.getLongitudeFromTile(zoom, getXTile() + dx); double lon = MapUtils.getLongitudeFromTile(zoom, getXTile() + dx);
setLatLon(lat, lon); setLatLon(lat, lon);

View file

@ -0,0 +1,158 @@
package com.osmand;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MapTileDownloader {
private static MapTileDownloader downloader = null;
private static Log log = LogFactory.getLog(MapTileDownloader.class);
private ThreadPoolExecutor threadPoolExecutor;
private IMapDownloaderCallback callback;
private Map<String, DownloadRequest> requestsToLoad;
public static MapTileDownloader getInstance(){
if(downloader == null){
downloader = new MapTileDownloader(DefaultLauncherConstants.TILE_DOWNLOAD_THREADS);
}
return downloader;
}
/**
* Callback for map downloader
*/
public interface IMapDownloaderCallback {
public void tileDownloaded(String dowloadedUrl, DownloadRequest fileSaved);
}
/**
* Download request could subclassed to create own detailed request
*/
public static class DownloadRequest {
public final File fileToSave;
public final int zoom;
public final int xTile;
public final int yTile;
public DownloadRequest(File fileToSave, int xTile, int yTile, int zoom) {
this.fileToSave = fileToSave;
this.xTile = xTile;
this.yTile = yTile;
this.zoom = zoom;
}
public DownloadRequest(File fileToSave) {
this.fileToSave = fileToSave;
xTile = -1;
yTile = -1;
zoom = -1;
}
}
public MapTileDownloader(int numberOfThreads){
threadPoolExecutor = new ThreadPoolExecutor(1, numberOfThreads, DefaultLauncherConstants.TILE_DOWNLOAD_SECONTS_TO_WORK,
TimeUnit.SECONDS, new PriorityBlockingQueue<Runnable>());
requestsToLoad = Collections.synchronizedMap(new LinkedHashMap<String, DownloadRequest>());
}
public void setDownloaderCallback(IMapDownloaderCallback callback){
this.callback = callback;
}
public IMapDownloaderCallback getDownloaderCallback() {
return callback;
}
public void refuseAllPreviousRequests(){
requestsToLoad.clear();
}
public void requestToDownload(String url, DownloadRequest request){
requestsToLoad.put(url, request);
threadPoolExecutor.execute(new DownloadMapWorker(url, request));
}
private class DownloadMapWorker implements Runnable, Comparable<DownloadMapWorker> {
private long time = System.currentTimeMillis();
private final String downloadUrl;
private DownloadRequest request;
private DownloadMapWorker(String downloadUrl, DownloadRequest request){
this.downloadUrl = downloadUrl;
this.request = request;
}
@Override
public void run() {
synchronized (requestsToLoad) {
if(!requestsToLoad.containsKey(downloadUrl)){
return;
}
request = requestsToLoad.remove(downloadUrl);
}
try {
URL url = new URL(downloadUrl);
// if(log.isDebugEnabled()){
log.debug("Downloading tile : " + downloadUrl);
// }
URLConnection connection = url.openConnection();
connection.setRequestProperty("User-Agent", DefaultLauncherConstants.APP_NAME+"/"+DefaultLauncherConstants.APP_VERSION);
BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream(), 8 * 1024);
try {
if(request != null && request.fileToSave != null){
request.fileToSave.getParentFile().mkdirs();
FileOutputStream stream = new FileOutputStream(request.fileToSave);
try {
Algoritms.streamCopy(inputStream, stream);
} finally {
Algoritms.closeStream(stream);
}
}
} finally {
Algoritms.closeStream(inputStream);
}
if(log.isDebugEnabled()){
log.debug("Downloading tile : " + downloadUrl + " successfull");
}
if(callback != null){
callback.tileDownloaded(downloadUrl, request);
}
} catch (UnknownHostException e) {
log.error("UnknownHostException, cannot download tile " + downloadUrl, e);
} catch (IOException e) {
log.warn("Cannot download tile : " + downloadUrl, e);
}
}
@Override
public int compareTo(DownloadMapWorker o) {
return (int) (time - o.time);
}
}
}

View file

@ -0,0 +1,18 @@
package com.osmand.map;
public interface ITileSource {
public int getMaximumZoomSupported();
public String getName();
public int getTileSize();
public String getUrlToLoad(int x, int y, int zoom);
public int getMinimumZoomSupported();
public String getTileFormat();
}

View file

@ -0,0 +1,121 @@
package com.osmand.map;
import java.text.MessageFormat;
import java.util.ArrayList;
public class TileSourceManager {
public static class TileSourceTemplate implements ITileSource {
private int maxZoom;
private int minZoom;
private String name;
private int tileSize;
private String urlToLoad;
private String ext;
private int avgSize;
public TileSourceTemplate(String name, String urlToLoad, String ext, int maxZoom, int minZoom, int tileSize, int avgSize) {
this.maxZoom = maxZoom;
this.minZoom = minZoom;
this.name = name;
this.tileSize = tileSize;
this.urlToLoad = urlToLoad;
this.ext = ext;
this.avgSize = avgSize;
}
public int getAverageSize(){
return avgSize;
}
@Override
public int getMaximumZoomSupported() {
return maxZoom;
}
@Override
public int getMinimumZoomSupported() {
return minZoom;
}
@Override
public String getName() {
return name;
}
@Override
public int getTileSize() {
return tileSize;
}
public String getTileFormat(){
return ext;
}
@Override
public String getUrlToLoad(int x, int y, int zoom) {
return MessageFormat.format(urlToLoad, zoom+"", x+"", y+"");
}
}
static java.util.List<TileSourceTemplate> list;
public static java.util.List<TileSourceTemplate> getKnownSourceTemplates(){
if(list == null){
list = new ArrayList<TileSourceTemplate>();
list.add(getMapnikSource());
list.add(getOsmaRenderSource());
list.add(getCycleMapSource());
// list.add(getAerialMapSource());
list.add(getCloudMadeSource());
list.add(getOpenPisteMapSource());
list.add(getGoogleMapsSource());
list.add(getGoogleMapsSatelliteSource());
list.add(getGoogleMapsTerrainSource());
}
return list;
}
public static TileSourceTemplate getMapnikSource(){
return new TileSourceTemplate("Mapnik", "http://tile.openstreetmap.org/{0}/{1}/{2}.png", ".png", 18, 1, 256, 18000);
}
public static TileSourceTemplate getOsmaRenderSource(){
return new TileSourceTemplate("OsmaRender", "http://tah.openstreetmap.org/Tiles/tile/{0}/{1}/{2}.png", ".png", 17, 1, 256, 18000);
}
public static TileSourceTemplate getCycleMapSource(){
return new TileSourceTemplate("CycleMap", "http://b.andy.sandbox.cloudmade.com/tiles/cycle/{0}/{1}/{2}.png", ".png", 17, 0, 256, 18000);
}
public static TileSourceTemplate getAerialMapSource(){
return new TileSourceTemplate("OpenAerialMap", "http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/{0}/{1}/{2}.jpg", ".jpg", 13, 0, 256, 18000);
}
public static TileSourceTemplate getCloudMadeSource(){
return new TileSourceTemplate("Cloudmade", "http://tile.cloudmade.com/7ded028e030c5929b28bf823486ce84f/1/256/{0}/{1}/{2}.png", ".png", 18, 0, 256, 18000);
}
public static TileSourceTemplate getOpenPisteMapSource(){
return new TileSourceTemplate("OpenPisteMap", "http://openpistemap.org/tiles/contours/{0}/{1}/{2}.png", ".png", 17, 0, 256, 18000);
}
public static TileSourceTemplate getGoogleMapsSource(){
return new TileSourceTemplate("GoogleMaps", "http://mt3.google.com/vt/v=w2.97&x={1}&y={2}&z={0}", ".png", 19, 0, 256, 18000);
}
public static TileSourceTemplate getGoogleMapsSatelliteSource(){
return new TileSourceTemplate("GoogleMaps Satellite", "http://khm1.google.com/kh/v=37&x={1}&y={2}&z={0}", ".png", 19, 0, 256, 18000);
}
public static TileSourceTemplate getGoogleMapsTerrainSource(){
return new TileSourceTemplate("GoogleMaps Terrain", "http://mt3.google.com/mt/v=w2p.87&x={1}&y={2}&z={0}", ".png", 15, 0, 256, 18000);
}
}

View file

@ -76,6 +76,7 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
}); });
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
// service.get
service.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this); service.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
} }
@ -129,6 +130,18 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
pointOfView.invalidate(); pointOfView.invalidate();
} }
} }
@Override
protected void onPause() {
// TODO switch off gps
super.onPause();
}
@Override
protected void onResume() {
// TODO switch on gps
super.onResume();
}
@Override @Override

View file

@ -0,0 +1,105 @@
package org.apache.commons.logging;
public class LogFactory {
public static String TAG = "com.osmand";
public static Log getLog(Class<?> cl){
final String name = cl.getName();
return new Log() {
@Override
public void debug(Object message) {
android.util.Log.d(TAG, name + " " + message);
}
@Override
public void debug(Object message, Throwable t) {
android.util.Log.d(TAG, name + " " + message, t);
}
@Override
public void error(Object message) {
android.util.Log.e(TAG, name + " " + message);
}
@Override
public void error(Object message, Throwable t) {
android.util.Log.e(TAG, name + " " + message, t);
}
@Override
public void fatal(Object message) {
android.util.Log.e(TAG, name + " " + message);
}
@Override
public void fatal(Object message, Throwable t) {
android.util.Log.e(TAG, name + " " + message, t);
}
@Override
public void info(Object message) {
android.util.Log.i(TAG, name + " " + message);
}
@Override
public void info(Object message, Throwable t) {
android.util.Log.i(TAG, name + " " + message, t);
}
@Override
public boolean isDebugEnabled() {
return android.util.Log.isLoggable(TAG, android.util.Log.DEBUG);
}
@Override
public boolean isErrorEnabled() {
return android.util.Log.isLoggable(TAG, android.util.Log.ERROR);
}
@Override
public boolean isFatalEnabled() {
return android.util.Log.isLoggable(TAG, android.util.Log.ERROR);
}
@Override
public boolean isInfoEnabled() {
return android.util.Log.isLoggable(TAG, android.util.Log.INFO);
}
@Override
public boolean isTraceEnabled() {
return android.util.Log.isLoggable(TAG, android.util.Log.DEBUG);
}
@Override
public boolean isWarnEnabled() {
return android.util.Log.isLoggable(TAG, android.util.Log.WARN);
}
@Override
public void trace(Object message) {
android.util.Log.d(TAG, name + " " + message);
}
@Override
public void trace(Object message, Throwable t) {
android.util.Log.d(TAG, name + " " + message, t);
}
@Override
public void warn(Object message) {
android.util.Log.w(TAG, name + " " + message);
}
@Override
public void warn(Object message, Throwable t) {
android.util.Log.w(TAG, name + " " + message, t);
}
};
}
}