By using FrameLayout, we can create a custom View overlap with a MapView, such that we can draw on the canvas of the customer View. Also we can call MapView.getProjection().fromPixels(x, y) to get the coresponding coordinates on the map.
Further work on the last exercise "
Get the the coordinates (Latitude and Longitude) currently displayed on MapView".
Create the custom view, MyView.java
package com.exercise.AndroidMap;
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 MyView extends View {
Paint myPaint;
float x1, y1; //Top Left point
float x2, y2; //Bottom Right point
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init();
}
private void init(){
myPaint = new Paint();
myPaint.setColor(Color.WHITE);
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setStrokeWidth(3);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
int w = getWidth();
int h = getHeight();
x1 = (float)w/4;
x2 = (float)w * 3/4;
y1 = (float)h/4;
y2 = (float)h *3/4;
canvas.drawRect(x1, y1, x2, y2, myPaint);
}
public float getx1(){
return x1;
}
public float getx2(){
return x2;
}
public float gety1(){
return y1;
}
public float gety2(){
return y2;
}
}
main.xml, include own custom View overlap with MapView, using FrameLayout.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/getinfo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Get Info"
/>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="0PE9qMoMP-Wy2MijPaIfdbg7dUHlub6gWJe-xQw" />
<com.exercise.AndroidMap.MyView
android:id="@+id/myview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</FrameLayout>
</LinearLayout>
main code, AndroidMapActivity.java
package com.exercise.AndroidMap;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class AndroidMapActivity extends MapActivity {
MapView myMap;
MyView myView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myMap = (MapView) findViewById(R.id.map);
myMap.setBuiltInZoomControls(true);
Button buttonGetInfo = (Button)findViewById(R.id.getinfo);
buttonGetInfo.setOnClickListener(buttonGetInfoOnClickListener);
myView = (MyView)findViewById(R.id.myview);
}
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
Button.OnClickListener buttonGetInfoOnClickListener
= new Button.OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
GeoPoint mapCenter = myMap.getMapCenter();
float centerLatitude = (float)(mapCenter.getLatitudeE6())/1000000;
float centerLongitude = (float)(mapCenter.getLongitudeE6())/1000000;
float latitudeSpan = (float)(myMap.getLatitudeSpan())/1000000;
float longitudeSpan = (float)(myMap.getLongitudeSpan()/1000000);
GeoPoint mapTopLeft
= myMap.getProjection().fromPixels((int)myView.getx1(), (int)myView.gety1());
float topLatitude = (float)(mapTopLeft.getLatitudeE6())/1000000;
float leftLongitude = (float)(mapTopLeft.getLongitudeE6())/1000000;
GeoPoint mapBottomRight
= myMap.getProjection().fromPixels((int)myView.getx2(), (int)myView.gety2());
float bottomLatitude = (float)(mapBottomRight.getLatitudeE6())/1000000;
float rightLongitude = (float)(mapBottomRight.getLongitudeE6())/1000000;
int zoomLevel = myMap.getZoomLevel();
String info =
"Center: " + centerLatitude + "/" + centerLongitude + "\n"
+ "Top Left: " + topLatitude + "/" + leftLongitude + "\n"
+ "Bottom Right: " + bottomLatitude + "/" + rightLongitude + "\n"
+ "latitudeSpan: " + latitudeSpan + "\n"
+ "longitudeSpan: " + longitudeSpan + "\n"
+ "zoomLevel: " + zoomLevel;
Toast.makeText(AndroidMapActivity.this,
info,
Toast.LENGTH_LONG).show();
}};
}
AndroidManifest.xml, xml. Grand permission of "android.permission.INTERNET" and include uses-library of "com.google.android.maps".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exercise.AndroidMap"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<uses-library android:name="com.google.android.maps" />
<activity android:name=".AndroidMapActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
Download the files.