add zoom in/out

git-svn-id: https://osmand.googlecode.com/svn/trunk@19 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-04-28 23:32:03 +00:00
parent 63be777290
commit cccf85c74a
9 changed files with 279 additions and 147 deletions

View file

@ -419,7 +419,7 @@ public class DataExtraction implements IMapLocationListener {
} }
@Override @Override
public void locationChanged(final double newLatitude, final double newLongitude){ public void locationChanged(final double newLatitude, final double newLongitude, Object source){
Region reg = (Region) amenitiesTree.getUserObject(); Region reg = (Region) amenitiesTree.getUserObject();
List<Node> closestAmenities = reg.getClosestAmenities(newLatitude, newLongitude); List<Node> closestAmenities = reg.getClosestAmenities(newLatitude, newLongitude);
Collections.sort(closestAmenities, new Comparator<Node>(){ Collections.sort(closestAmenities, new Comparator<Node>(){

View file

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

View file

@ -70,9 +70,9 @@ public class MapPanel extends JPanel {
private int zoom = 15; private int zoom = 15;
// degree measurements (-180, 180) // degree measurements (-180, 180)
// äîëãîòà // долгота
private double longitude = 27.56; private double longitude = 27.56;
// øèðîòà // широта
// degree measurements (90, -90) // degree measurements (90, -90)
private double latitude = 53.9; private double latitude = 53.9;
@ -288,7 +288,7 @@ public class MapPanel extends JPanel {
protected void fireMapLocationListeners(){ protected void fireMapLocationListeners(){
for(IMapLocationListener l : listeners){ for(IMapLocationListener l : listeners){
l.locationChanged(latitude, longitude); l.locationChanged(latitude, longitude, null);
} }
} }

View file

@ -3,8 +3,8 @@
package="com.osmand" package="com.osmand"
android:versionCode="1" android:versionCode="1"
android:versionName="1.0"> android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name"> <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
<activity android:name=".StartActivity" <activity android:name=".MapActivity"
android:label="@string/app_name"> android:label="@string/app_name">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@ -15,4 +15,8 @@
</application> </application>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
</manifest> </manifest>

View file

@ -1,14 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
> >
<ZoomControls android:id="@+id/ZoomControls01" android:layout_width="wrap_content" android:layout_height="wrap_content"></ZoomControls><TextView <com.osmand.OsmandMapTileView android:id="@+id/View01" android:layout_width="wrap_content" android:layout_height="wrap_content"></com.osmand.OsmandMapTileView>
android:layout_width="fill_parent" <com.osmand.PointOfView android:id="@+id/PointOfView" android:layout_width="wrap_content" android:layout_height="wrap_content"></com.osmand.PointOfView>
android:layout_height="wrap_content" <ZoomControls android:id="@+id/ZoomControls01"
android:text="@string/hello" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|right"></ZoomControls>
/>
<SurfaceView android:id="@+id/SurfaceView01" android:layout_width="fill_parent" android:layout_height="fill_parent"></SurfaceView>
</LinearLayout>
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top|right" android:id="@+id/BackToLocation" android:background="@drawable/icon"></ImageButton>
</FrameLayout>

View file

@ -0,0 +1,146 @@
package com.osmand;
import java.io.File;
import android.app.Activity;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ZoomControls;
import com.osmand.osm.MapUtils;
public class MapActivity extends Activity implements LocationListener, IMapLocationListener {
/** Called when the activity is first created. */
private OsmandMapTileView mapView;
private boolean linkLocationWithMap = true;
private Location lastKnownLocation = null;
private ImageButton backToLocation;
private PointOfView pointOfView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (OsmandMapTileView) findViewById(R.id.View01);
mapView.setFileWithTiles(new File(Environment.getExternalStorageDirectory(), "osmand/tiles/Mapnik"));
mapView.addMapLocationListener(this);
ZoomControls zoomControls = (ZoomControls) findViewById(R.id.ZoomControls01);
zoomControls.setOnZoomInClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mapView.setZoom(mapView.getZoom() + 1);
}
});
zoomControls.setOnZoomOutClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mapView.setZoom(mapView.getZoom() - 1);
}
});
pointOfView = (PointOfView)findViewById(R.id.PointOfView);
backToLocation = (ImageButton)findViewById(R.id.BackToLocation);
backToLocation.setVisibility(linkLocationWithMap ? View.INVISIBLE : View.VISIBLE);
backToLocation.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
if(!linkLocationWithMap){
linkLocationWithMap = true;
backToLocation.setVisibility(View.INVISIBLE);
if(lastKnownLocation != null){
mapView.setLatLon(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude());
}
}
}
});
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
service.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
service.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this);
}
@Override
public void onLocationChanged(Location location) {
lastKnownLocation = location;
if(linkLocationWithMap){
mapView.setLatLon(location.getLatitude(), location.getLongitude());
}
validatePointOfView();
}
@Override
public void onProviderDisabled(String provider) {
// TODO when provider disabled reset lastKnownLocation!
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void validatePointOfView(){
if(lastKnownLocation == null){
if(pointOfView.isVisible()){
pointOfView.setLocationX(-1);
pointOfView.setLocationY(-1);
pointOfView.setAreaRadius(0);
pointOfView.invalidate();
}
} else {
int newX = MapUtils.getPixelShiftX(mapView.getZoom(),
lastKnownLocation.getLongitude(), mapView.getLongitude(), mapView.getTileSize()) +
mapView.getWidth()/2;
int newY = MapUtils.getPixelShiftY(mapView.getZoom(),
lastKnownLocation.getLatitude(), mapView.getLatitude() , mapView.getTileSize()) +
mapView.getHeight()/2;
// TODO clear radius & specify bearing!
double tileNumberX = MapUtils.getTileNumberX(mapView.getZoom(), mapView.getLongitude());
double tileNumberLeft = tileNumberX - ((double)mapView.getWidth()) / (2d * mapView.getTileSize());
double dist = MapUtils.getDistance(mapView.getLatitude(),
MapUtils.getLongitudeFromTile(mapView.getZoom(),tileNumberLeft), mapView.getLatitude(),
MapUtils.getLongitudeFromTile(mapView.getZoom(),tileNumberX));
int radius = (int) ((mapView.getWidth()/ (2d*dist))* lastKnownLocation.getAccuracy());
pointOfView.setLocationX(newX);
pointOfView.setLocationY(newY);
pointOfView.setAreaRadius(radius);
pointOfView.invalidate();
}
}
@Override
public void locationChanged(double newLatitude, double newLongitude, Object source) {
// when user
if(source == mapView && lastKnownLocation != null){
linkLocationWithMap = false;
backToLocation.setVisibility(View.VISIBLE);
}
validatePointOfView();
}
}

View file

@ -15,6 +15,7 @@ import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.PointF; import android.graphics.PointF;
import android.graphics.Paint.Style; import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
@ -42,9 +43,9 @@ public class OsmandMapTileView extends View {
private int zoom = 15; private int zoom = 15;
// degree measurements (-180, 180) // degree measurements (-180, 180)
// äîëãîòà // долгота
private double longitude = 27.56; private double longitude = 27.56;
// øèðîòà // широта
// degree measurements (90, -90) // degree measurements (90, -90)
private double latitude = 53.9; private double latitude = 53.9;
@ -67,9 +68,18 @@ public class OsmandMapTileView extends View {
Paint paintWhiteFill; Paint paintWhiteFill;
Paint paintBlack; Paint paintBlack;
public OsmandMapTileView(Context context, File fileWithTiles) {
public OsmandMapTileView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public OsmandMapTileView(Context context) {
super(context); super(context);
this.fileWithTiles = fileWithTiles; initView();
}
public void initView(){
paintGrayFill = new Paint(); paintGrayFill = new Paint();
paintGrayFill.setColor(Color.GRAY); paintGrayFill.setColor(Color.GRAY);
paintGrayFill.setStyle(Style.FILL); paintGrayFill.setStyle(Style.FILL);
@ -84,10 +94,6 @@ public class OsmandMapTileView extends View {
prepareImage(); prepareImage();
setClickable(true); setClickable(true);
// TODO !!!!
// MapMouseAdapter mouse = new MapMouseAdapter();
// addMouseListener(mouse);
// addMouseMotionListener(mouse);
} }
@ -96,9 +102,10 @@ public class OsmandMapTileView extends View {
public void dragTo(PointF p){ public void dragTo(PointF p){
double dx = (startDragging.x - (double)p.x)/tileSize; double dx = (startDragging.x - (double)p.x)/tileSize;
double dy = (startDragging.y - (double)p.y)/tileSize; double dy = (startDragging.y - (double)p.y)/tileSize;
double lat = MapUtils.getLatitudeFromTile(zoom, getYTile() + dy); this.latitude = MapUtils.getLatitudeFromTile(zoom, getYTile() + dy);
double lon = MapUtils.getLongitudeFromTile(zoom, getXTile() + dx); this.longitude = MapUtils.getLongitudeFromTile(zoom, getXTile() + dx);
setLatLon(lat, lon); prepareImage();
fireMapLocationListeners(this);
} }
@Override @Override
@ -110,7 +117,6 @@ public class OsmandMapTileView extends View {
} else if(event.getAction() == MotionEvent.ACTION_UP) { } else if(event.getAction() == MotionEvent.ACTION_UP) {
if(startDragging != null){ if(startDragging != null){
dragTo(new PointF(event.getX(), event.getY())); dragTo(new PointF(event.getX(), event.getY()));
fireMapLocationListeners();
startDragging = null; startDragging = null;
} }
} else if(event.getAction() == MotionEvent.ACTION_MOVE) { } else if(event.getAction() == MotionEvent.ACTION_MOVE) {
@ -134,11 +140,14 @@ public class OsmandMapTileView extends View {
protected void drawEmptyTile(Canvas cvs, int x, int y){ protected void drawEmptyTile(Canvas cvs, int x, int y){
int tileDiv = tileSize / emptyTileDivisor; int tileDiv = tileSize / emptyTileDivisor;
for (int k1 = 0; k1 < emptyTileDivisor; k1++) { for (int k1 = 0; k1 < emptyTileDivisor; k1++) {
for (int k2 = 0; k2 < emptyTileDivisor; k2++) { for (int k2 = 0; k2 < emptyTileDivisor; k2++) {
int xk = x + tileDiv* k1;
int yk = y + tileDiv* k2;
if ((k1 + k2) % 2 == 0) { if ((k1 + k2) % 2 == 0) {
cvs.drawRect(x, y, x + tileDiv, y + tileDiv, paintGrayFill); cvs.drawRect(xk, yk, xk + tileDiv, yk + tileDiv, paintGrayFill);
} else { } else {
cvs.drawRect(x, y, x + tileDiv, y + tileDiv, paintWhiteFill); cvs.drawRect(xk, yk, xk + tileDiv, yk + tileDiv, paintWhiteFill);
} }
} }
} }
@ -165,7 +174,7 @@ public class OsmandMapTileView extends View {
public Bitmap getImageFor(int x, int y) { public Bitmap getImageFor(int x, int y) {
String file = "/" + zoom + "/" + (x) + "/" + y + ".png"; String file = "/" + zoom + "/" + (x) + "/" + y + ".png";
if (!cacheOfImages.containsKey(file)) { if (!cacheOfImages.containsKey(file) && fileWithTiles != null) {
File en = new File(fileWithTiles, file); File en = new File(fileWithTiles, file);
if (cacheOfImages.size() > maxImgCacheSize) { if (cacheOfImages.size() > maxImgCacheSize) {
ArrayList<String> list = new ArrayList<String>(cacheOfImages.keySet()); ArrayList<String> list = new ArrayList<String>(cacheOfImages.keySet());
@ -189,6 +198,7 @@ public class OsmandMapTileView extends View {
@Override @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) { protected void onSizeChanged(int w, int h, int oldw, int oldh) {
prepareImage(); prepareImage();
super.onSizeChanged(w, h, oldw, oldh);
} }
// TODO async loading images (show busy cursor while it is loaded) // TODO async loading images (show busy cursor while it is loaded)
@ -225,13 +235,14 @@ public class OsmandMapTileView extends View {
public void setFileWithTiles(File fileWithTiles) { public void setFileWithTiles(File fileWithTiles) {
this.fileWithTiles = fileWithTiles; this.fileWithTiles = fileWithTiles;
prepareImage();
} }
public void setLatLon(double latitude, double longitude){ public void setLatLon(double latitude, double longitude){
this.latitude = latitude; this.latitude = latitude;
this.longitude = longitude; this.longitude = longitude;
prepareImage(); prepareImage();
fireMapLocationListeners(); fireMapLocationListeners(null);
} }
public double getLatitude() { public double getLatitude() {
@ -246,6 +257,10 @@ public class OsmandMapTileView extends View {
return zoom; return zoom;
} }
public int getTileSize() {
return tileSize;
}
public void addMapLocationListener(IMapLocationListener l){ public void addMapLocationListener(IMapLocationListener l){
listeners.add(l); listeners.add(l);
@ -255,103 +270,13 @@ public class OsmandMapTileView extends View {
listeners.remove(l); listeners.remove(l);
} }
protected void fireMapLocationListeners(){ protected void fireMapLocationListeners(Object source){
for(IMapLocationListener l : listeners){ for(IMapLocationListener l : listeners){
l.locationChanged(latitude, longitude); l.locationChanged(latitude, longitude, source);
} }
} }
//
// @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

@ -0,0 +1,78 @@
package com.osmand;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class PointOfView extends View {
private Paint location;
private Paint area;
private int areaRadius = 0;
private int locationX = -1;
private int locationY = -1;
public PointOfView(Context context, AttributeSet attrs) {
super(context, attrs);
initUI();
}
public PointOfView(Context context) {
super(context);
initUI();
}
private void initUI() {
location = new Paint();
location.setColor(Color.BLUE);
location.setAlpha(150);
location.setAntiAlias(true);
area = new Paint();
area.setColor(Color.BLUE);
area.setAlpha(40);
}
@Override
protected void onDraw(Canvas canvas) {
if(locationX >= 0 && locationY >=0){
canvas.drawCircle(locationX, locationY, 4, location);
}
if(areaRadius > 4){
canvas.drawCircle(locationX, locationY, areaRadius, area);
}
}
public void setLocationX(int locationX) {
this.locationX = locationX;
}
public void setLocationY(int locationY) {
this.locationY = locationY;
}
public int getLocationX() {
return locationX;
}
public int getLocationY() {
return locationY;
}
public int getAreaRadius() {
return areaRadius;
}
public boolean isVisible() {
return locationX >= 0 && locationY >= 0;
}
public void setAreaRadius(int areaRadius) {
this.areaRadius = areaRadius;
}
}

View file

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