create simple android application with mapnik maps

git-svn-id: https://osmand.googlecode.com/svn/trunk@18 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-04-28 15:06:07 +00:00
parent 5f8af871f0
commit 63be777290
6 changed files with 378 additions and 9 deletions

View file

@ -44,7 +44,6 @@ import javax.xml.stream.XMLStreamException;
import org.apache.tools.bzip2.CBZip2InputStream; import org.apache.tools.bzip2.CBZip2InputStream;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import com.osmand.MapPanel.IMapLocationListener;
import com.osmand.data.City; import com.osmand.data.City;
import com.osmand.data.DataTileManager; import com.osmand.data.DataTileManager;
import com.osmand.data.Region; import com.osmand.data.Region;

View file

@ -0,0 +1,5 @@
package com.osmand;
public interface IMapLocationListener {
void locationChanged(double newLatitude, double newLongitude);
}

View file

@ -32,9 +32,6 @@ public class MapPanel extends JPanel {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public interface IMapLocationListener {
void locationChanged(double newLatitude, double newLongitude);
}
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");

View file

@ -4,9 +4,11 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
> >
<TextView <ZoomControls android:id="@+id/ZoomControls01" android:layout_width="wrap_content" android:layout_height="wrap_content"></ZoomControls><TextView
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hello" android:text="@string/hello"
/> />
<SurfaceView android:id="@+id/SurfaceView01" android:layout_width="fill_parent" android:layout_height="fill_parent"></SurfaceView>
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,357 @@
package com.osmand;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Paint.Style;
import android.view.MotionEvent;
import android.view.View;
import com.osmand.osm.MapUtils;
public class OsmandMapTileView extends View {
protected final int emptyTileDivisor = 4;
protected final int maxImgCacheSize = 512;
/**
* tile size of map
*/
private int tileSize = 256;
/**
* file or directory with tiles
*/
private File fileWithTiles;
/**
* zoom level
*/
private int zoom = 15;
// degree measurements (-180, 180)
// äîëãîòà
private double longitude = 27.56;
// øèðîòà
// degree measurements (90, -90)
private double latitude = 53.9;
/**
* listeners
*/
private List<IMapLocationListener> listeners = new ArrayList<IMapLocationListener>();
// cached data to draw images
private Bitmap[][] images;
// this value is always <= 0
private int xStartingImage = 0;
// this value is always <= 0
private int yStartingImage = 0;
Map<String, Bitmap> cacheOfImages = new WeakHashMap<String, Bitmap>();
Paint paintGrayFill;
Paint paintWhiteFill;
Paint paintBlack;
public OsmandMapTileView(Context context, File fileWithTiles) {
super(context);
this.fileWithTiles = fileWithTiles;
paintGrayFill = new Paint();
paintGrayFill.setColor(Color.GRAY);
paintGrayFill.setStyle(Style.FILL);
paintWhiteFill = new Paint();
paintWhiteFill.setColor(Color.WHITE);
paintWhiteFill.setStyle(Style.FILL);
paintBlack = new Paint();
paintBlack.setStyle(Style.STROKE);
paintBlack.setColor(Color.BLACK);
prepareImage();
setClickable(true);
// TODO !!!!
// MapMouseAdapter mouse = new MapMouseAdapter();
// addMouseListener(mouse);
// addMouseMotionListener(mouse);
}
private PointF startDragging = null;
public void dragTo(PointF p){
double dx = (startDragging.x - (double)p.x)/tileSize;
double dy = (startDragging.y - (double)p.y)/tileSize;
double lat = MapUtils.getLatitudeFromTile(zoom, getYTile() + dy);
double lon = MapUtils.getLongitudeFromTile(zoom, getXTile() + dx);
setLatLon(lat, lon);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
if(startDragging == null){
startDragging = new PointF(event.getX(), event.getY());
}
} else if(event.getAction() == MotionEvent.ACTION_UP) {
if(startDragging != null){
dragTo(new PointF(event.getX(), event.getY()));
fireMapLocationListeners();
startDragging = null;
}
} else if(event.getAction() == MotionEvent.ACTION_MOVE) {
if(startDragging != null){
PointF p = new PointF(event.getX(), event.getY());
dragTo(p);
startDragging = p;
}
}
return super.onTouchEvent(event);
}
public double getXTile(){
return MapUtils.getTileNumberX(zoom, longitude);
}
public double getYTile(){
return MapUtils.getTileNumberY(zoom, latitude);
}
protected void drawEmptyTile(Canvas cvs, int x, int y){
int tileDiv = tileSize / emptyTileDivisor;
for (int k1 = 0; k1 < emptyTileDivisor; k1++) {
for (int k2 = 0; k2 < emptyTileDivisor; k2++) {
if ((k1 + k2) % 2 == 0) {
cvs.drawRect(x, y, x + tileDiv, y + tileDiv, paintGrayFill);
} else {
cvs.drawRect(x, y, x + tileDiv, y + tileDiv, paintWhiteFill);
}
}
}
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawRect(0,0, getWidth(), getHeight(), paintWhiteFill);
if (images != null) {
for (int i = 0; i < images.length; i++) {
for (int j = 0; j < images[i].length; j++) {
if (images[i][j] == null) {
drawEmptyTile(canvas, i*tileSize+xStartingImage, j * tileSize + yStartingImage);
} else {
canvas.drawBitmap(images[i][j], i * tileSize + xStartingImage, j * tileSize + yStartingImage, null);
}
}
}
}
canvas.drawCircle(getWidth()/2, getHeight()/2, 3, paintBlack);
canvas.drawCircle(getWidth()/2, getHeight()/2, 6, paintBlack);
}
public Bitmap getImageFor(int x, int y) {
String file = "/" + zoom + "/" + (x) + "/" + y + ".png";
if (!cacheOfImages.containsKey(file)) {
File en = new File(fileWithTiles, file);
if (cacheOfImages.size() > maxImgCacheSize) {
ArrayList<String> list = new ArrayList<String>(cacheOfImages.keySet());
for (int i = 0; i < list.size(); i += 2) {
Bitmap bmp = cacheOfImages.remove(list.get(i));
bmp.recycle();
}
System.gc();
}
if (en.exists() && en.canRead()) {
cacheOfImages.put(file, BitmapFactory.decodeFile(en.getAbsolutePath()));
} else {
cacheOfImages.put(file, null);
}
}
return cacheOfImages.get(file);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
prepareImage();
}
// TODO async loading images (show busy cursor while it is loaded)
public void prepareImage() {
double xTileLeft = getXTile() - getWidth() / (2d * tileSize);
double xTileRight = getXTile() + getWidth() / (2d * tileSize);
double yTileUp = getYTile() - getHeight() / (2d * tileSize);
double yTileDown = getYTile() + getHeight() / (2d * tileSize);
xStartingImage = -(int) ((xTileLeft - Math.floor(xTileLeft)) * tileSize);
yStartingImage = -(int) ((yTileUp - Math.floor(yTileUp)) * tileSize);
int tileXCount = ((int) xTileRight - (int) xTileLeft + 1);
int tileYCount = ((int) yTileDown - (int) yTileUp + 1);
images = new Bitmap[tileXCount][tileYCount];
for (int i = 0; i < images.length; i++) {
for (int j = 0; j < images[i].length; j++) {
images[i][j] = getImageFor((int) xTileLeft + i, (int) yTileUp + j);
}
}
invalidate();
}
public void setZoom(int zoom){
this.zoom = zoom;
prepareImage();
}
public File getFileWithTiles() {
return fileWithTiles;
}
public void setFileWithTiles(File fileWithTiles) {
this.fileWithTiles = fileWithTiles;
}
public void setLatLon(double latitude, double longitude){
this.latitude = latitude;
this.longitude = longitude;
prepareImage();
fireMapLocationListeners();
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
public int getZoom() {
return zoom;
}
public void addMapLocationListener(IMapLocationListener l){
listeners.add(l);
}
public void removeMapLocationListener(IMapLocationListener l){
listeners.remove(l);
}
protected void fireMapLocationListeners(){
for(IMapLocationListener l : listeners){
l.locationChanged(latitude, longitude);
}
}
//
// @Override
// protected void processKeyEvent(KeyEvent e) {
// boolean processed = false;
// if (e.getID() == KeyEvent.KEY_RELEASED) {
// if (e.getKeyCode() == 37) {
// // LEFT button
// longitude = MapUtils.getLongitudeFromTile(zoom, getXTile()-0.5);
// processed = true;
// } else if (e.getKeyCode() == 39) {
// // RIGHT button
// longitude = MapUtils.getLongitudeFromTile(zoom, getXTile()+0.5);
// processed = true;
// } else if (e.getKeyCode() == 38) {
// // UP button
// latitude = MapUtils.getLatitudeFromTile(zoom, getYTile()-0.5);
// processed = true;
// } else if (e.getKeyCode() == 40) {
// // DOWN button
// latitude = MapUtils.getLatitudeFromTile(zoom, getYTile()+0.5);
// processed = true;
// }
// }
// if(e.getID() == KeyEvent.KEY_TYPED){
// if(e.getKeyChar() == '+'){
// zoom ++;
// processed = true;
// } else if(e.getKeyChar() == '-'){
// zoom --;
// processed = true;
// }
// }
//
// if(processed){
// e.consume();
// prepareImage();
// fireMapLocationListeners();
// }
// super.processKeyEvent(e);
// }
//
//
// public class MapMouseAdapter extends MouseAdapter {
// private Point startDragging = null;
//
// @Override
// public void mouseClicked(MouseEvent e) {
// if(e.getButton() == MouseEvent.BUTTON1){
// requestFocus();
// }
// }
//
// public void dragTo(Point p){
// double dx = (startDragging.x - (double)p.x)/tileSize;
// double dy = (startDragging.y - (double)p.y)/tileSize;
// double lat = MapUtils.getLatitudeFromTile(zoom, getYTile() + dy);
// double lon = MapUtils.getLongitudeFromTile(zoom, getXTile() + dx);
// setLatLon(lat, lon);
// }
//
// @Override
// public void mouseDragged(MouseEvent e) {
// if(startDragging != null){
// if(Math.abs(e.getPoint().x - startDragging.x) + Math.abs(e.getPoint().y - startDragging.y) >= 8){
// dragTo(e.getPoint());
// startDragging = e.getPoint();
// }
// }
// }
//
// @Override
// public void mousePressed(MouseEvent e) {
// if(e.getButton() == MouseEvent.BUTTON3){
// if(startDragging == null){
// startDragging = e.getPoint();
// }
// }
// }
// @Override
// public void mouseReleased(MouseEvent e) {
// if(e.getButton() == MouseEvent.BUTTON3){
// if(startDragging != null){
// dragTo(e.getPoint());
// fireMapLocationListeners();
// startDragging = null;
// }
// }
// super.mouseReleased(e);
// }
//
// }
}

View file

@ -1,13 +1,22 @@
package com.osmand; package com.osmand;
import java.io.File;
import android.app.Activity; import android.app.Activity;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment;
public class StartActivity extends Activity { public class StartActivity extends Activity {
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// SurfaceView surf = (SurfaceView) findViewById(R.id.SurfaceView01);
setContentView(new OsmandMapTileView(this, new File(Environment.getExternalStorageDirectory(), "osmand/tiles/Mapnik")));
// setContentView(R.layout.main);
} }
} }