I am overlaying custom radar weather tiles on top of Google Maps. I'd also like to add a location pin marker in accordance with city the user is viewing weather from. I can't figure out how to have the tiles AND a marker. I can do one or the other, but not both....any help?
I have a MapsItemizedOverlay class:
<pre><code>public class MapsItemizedOverlay extends ItemizedOverlay<OverlayItem> {
private static final String DEBUG_TAG = "TurboWeather/MapsItemizedOverlay";
private ArrayList<OverlayItem> myOverlays = new ArrayList<OverlayItem>();
//private ArrayList<Drawable> mDrawables = new ArrayList<Drawable>();
//private ArrayList<GeoPoints> mGeoPoints = new ArrayList<GeoPoints>();
public MapsItemizedOverlay(Drawable defaultMarkers, Context context) {
super(boundCenterBottom(defaultMarkers));
//Log.i(DEBUG_TAG, "MapsItemizedOverlay constructor");
populate();
}
public void addOverlay(OverlayItem overlay){
//Log.i(DEBUG_TAG, "addOverlay");
myOverlays.add(overlay);
populate();
}
#Override
protected OverlayItem createItem(int i) {
//Log.i(DEBUG_TAG, "createItem");
return myOverlays.get(i);
}
// Returns present number of items in list
#Override
public int size() {
return myOverlays.size();
}
#Override
public void draw(Canvas canvas, MapView mapview, boolean shadow) {
super.draw(canvas, mapview, false);
}
}
And here is where I utilize the MapsItemizedOverlay class and am able to draw the custom radar image tiles to Google Maps:
private void addOverlay(Drawable drawable, int xTile, int yTile) {
OverlayItem overlayitem, locationOverlayitem;
GeoPoint geopoint, locGeopoint;
int x1 = 0, y1 = 0;
double lat[] = {0.0};
double lon[] = {0.0};
int x[] = {0};
int y[] = {0};
mCurrentProjection.fromPixels(x1, y1);
mMapOverlays = mMapView.getOverlays();
x = new int[] {xTile};
y = new int[] {yTile};
TileSystem.TileXYToPixelXY(xTile, yTile, x, y);
TileSystem.PixelXYToLatLong(x, y, mZoomLevel, lat, lon);
Log.i(DEBUG_TAG, "X: " + x[0] + " Y: " + y[0]);
//Log.i(DEBUG_TAG, "GeoPointX is " + lat[0] + ", GeoPointY is " + lon[0]);
geopoint = new GeoPoint((int)(lat[0] * 1E6), (int)(lon[0] * 1E6));
if (mMapOverlays.size() == 0) {
mItemizedOverlay = new MapsItemizedOverlay(drawable, mContext) {
public boolean onTouchEvent(MotionEvent event, com.google.android.maps.MapView mv) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
post(new Runnable() {
#Override
public void run() {
mMapView.getOverlays().clear();
getAccuWxTiles(mMapVars);
}
});
break;
}
return false;
}
};
} else {
mItemizedOverlay = new MapsItemizedOverlay(drawable, mContext);
}
overlayitem = new OverlayItem(geopoint, "", "");
mItemizedOverlay.addOverlay(overlayitem);
mMapOverlays.add(mItemizedOverlay);
mMapView.invalidate();
}
Related
I am using OSM maps in my App. I am using 3.0.8 jar file for osmdroid. i have an issue with when i draw custom marker on Map it draw after 2-3 seconds. I goggled it find a solution that use library 3.0.5 osmdroid. when i tried it gives error that android dependencies failed. so please give me way that can i solve this problem.
here is my code for draw a custom marker.
public class Map extends Activity {
GoogleMap gMap;
static int loginCheck = 0;
ConnectionDetector conDec;
ArrayList<HashMap<String, String>> aList = new ArrayList<HashMap<String, String>>();
SharedPreferences prefs;
LatLng latLng;
MarkerOptions markerOptions;
LinearLayout botlay;
EditText desc;
MyItemizedOverlay myItemizedOverlay = null;
MyLocationOverlay myLocationOverlay = null;
ArrayList<OverlayItem> anotherOverlayItemArray, overlayItemArray;
GeoPoint p, loc, currentLocationPixels, t;
GeoPoint myPoint1;
Projection proj;
GPSTracker gps;
double my_Latitude, my_Longitude;
private MapView mapView;
private MapController myMapController;
public int count = 0;
EditText ed1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map1);
ed1 = (EditText) findViewById(R.id.descr);
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
mapView = (MapView) findViewById(R.id.mapViewosm);
mapView.setBuiltInZoomControls(true);
mapView.setMultiTouchControls(true);
myMapController = mapView.getController();
myMapController.setZoom(15);
ScaleBarOverlay myScaleBarOverlay = new ScaleBarOverlay(this);
mapView.getOverlays().add(myScaleBarOverlay);
Drawable marker = getResources().getDrawable(
android.R.drawable.star_big_on);
int markerWidth = marker.getIntrinsicWidth();
int markerHeight = marker.getIntrinsicHeight();
marker.setBounds(0, markerHeight, markerWidth, 0);
ResourceProxy resourceProxy = new DefaultResourceProxyImpl(
getApplicationContext());
myItemizedOverlay = new MyItemizedOverlay(marker, resourceProxy);
// add overlay for current location..RAJ
MyCurrentItemizedOverlay myCurrentLocationOverlay = new MyCurrentItemizedOverlay(
marker, resourceProxy);
mapView.getOverlays().add(myCurrentLocationOverlay);
mapView.getOverlays().add(myItemizedOverlay);
// mapView.postInvalidate();
gps = new GPSTracker(Map.this);
// check if GPS enabled
if (gps.canGetLocation()) {
while (gps.getLatitude() == 0.0 || gps.getLongitude() == 0.0) {
gps.canGetLocation();
}
my_Latitude = gps.getLatitude();
my_Longitude = gps.getLongitude();
// \n is for new line
// Toast.makeText(getApplicationContext(),
// "Your Location is - \nLat: " + my_Latitude + "\nLong: " +
// my_Longitude, Toast.LENGTH_LONG).show();
} else {
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
}
// set the current loaction for clicked location..
p = new GeoPoint((int) (my_Latitude * 1E6), (int) (my_Longitude * 1E6));
// add overlay for current location..RAJ
currentLocationPixels = new GeoPoint((int) (my_Latitude * 1E6),
(int) (my_Longitude * 1E6));
// its mine..
Toast.makeText(
getApplicationContext(),
"Your Location is - \nLat: " + my_Latitude + "\nLong: "
+ my_Longitude, Toast.LENGTH_LONG).show();
// ConvertPointToLocation(currentLocationPixels);
myLocationOverlay = new MyLocationOverlay(this, mapView);
// mapView.getOverlays().add(myLocationOverlay);
// myLocationOverlay.enableMyLocation();
// myLocationOverlay.getMyLocation();
mapView.invalidate();
// String coordinates[] = {
// myLocationOverlay.getMyLocation().getLatitudeE6()+"",
// myLocationOverlay.getMyLocation().getLatitudeE6()+"" };
// double lat = (double)
// myLocationOverlay.getMyLocation().getLatitudeE6();
// double lng = (double)
// myLocationOverlay.getMyLocation().getLongitudeE6();
// //
// //
// p = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
// mapView.postInvalidate();
// double lat = (double) loc.getLatitudeE6();
// double lng = (double) loc.getLongitudeE6();
// addLocation(my_Latitude, my_Longitude);
// myLocationOverlay.runOnFirstFix(new Runnable() {
// public void run() {
// mapView.getController().animateTo(
// myLocationOverlay.getMyLocation());
// }
// });
// mapView.getOverlays().add(touchOverlay);
}
// private void addLocation(double lat, double lng) {
// // ---Add a location marker---
//
// p = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
//
// Drawable marker = getResources().getDrawable(
// android.R.drawable.star_big_on);
// int markerWidth = marker.getIntrinsicWidth();
// int markerHeight = marker.getIntrinsicHeight();
// marker.setBounds(0, markerHeight, markerWidth, 0);
//
// ResourceProxy resourceProxy = new DefaultResourceProxyImpl(
// getApplicationContext());
//
// myItemizedOverlay = new MyItemizedOverlay(marker, resourceProxy);
// mapView.getOverlays().add(myItemizedOverlay);
//
// List<Overlay> listOfOverlays = mapView.getOverlays();
// listOfOverlays.clear();
// listOfOverlays.add(myItemizedOverlay);
// mapView.invalidate();
// }
#Override
protected void onResume() {
super.onResume();
myLocationOverlay.enableMyLocation();
myLocationOverlay.enableFollowLocation();
}
#Override
protected void onPause() {
super.onPause();
myLocationOverlay.disableMyLocation();
myLocationOverlay.disableFollowLocation();
}
public class MyItemizedOverlay extends ItemizedOverlay<OverlayItem> {
private ArrayList<OverlayItem> overlayItemList = new ArrayList<OverlayItem>();
public MyItemizedOverlay(Drawable pDefaultMarker,
ResourceProxy pResourceProxy) {
super(pDefaultMarker, pResourceProxy);
}
#Override
public void draw(Canvas canvas, MapView mapView, boolean arg2) {
super.draw(canvas, mapView, arg2);
// ---translate the GeoPoint to screen pixels---
Point screenPts = new Point();
mapView.getProjection().toPixels(p, screenPts);
// ---add the marker---
if (count == 1) {
int caller = getIntent().getIntExtra("button", 0);
switch (caller) {
case R.id.btMap:
Bitmap bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_darkblue);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
break;
case R.id.imageButton1:
Bitmap bmp1 = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_green);
canvas.drawBitmap(bmp1, screenPts.x, screenPts.y - 50, null);
break;
case R.id.imageButton2:
Bitmap bmp2 = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_bue);
canvas.drawBitmap(bmp2, screenPts.x, screenPts.y - 50, null);
break;
case R.id.imageButton3:
Bitmap bmp3 = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_light);
canvas.drawBitmap(bmp3, screenPts.x, screenPts.y - 50, null);
break;
case R.id.imageButton4:
Bitmap bmp4 = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_purple);
canvas.drawBitmap(bmp4, screenPts.x, screenPts.y - 50, null);
break;
case R.id.imageButton5:
Bitmap bmp5 = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_red);
canvas.drawBitmap(bmp5, screenPts.x, screenPts.y - 50, null);
break;
case R.id.imageButton6:
Bitmap bmp6 = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_yellow);
canvas.drawBitmap(bmp6, screenPts.x, screenPts.y - 50, null);
break;
}
}
// Bitmap bmp = BitmapFactory.decodeResource(getResources(),
// R.drawable.pin_annotation_green);
// if (count == 1) {
// canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
// }
}
public void addItem(GeoPoint p, String title, String snippet) {
OverlayItem newItem = new OverlayItem(title, snippet, p);
overlayItemList.add(newItem);
populate();
}
#Override
public boolean onSnapToItem(int arg0, int arg1, Point arg2,
IMapView arg3) {
return false;
}
#Override
protected OverlayItem createItem(int arg0) {
return overlayItemList.get(arg0);
}
#Override
public int size() {
return overlayItemList.size();
}
#Override
public boolean onLongPress(MotionEvent e, MapView mapView) {
proj = mapView.getProjection();
loc = (GeoPoint) proj.fromPixels((int) e.getX(), (int) e.getY());
ConvertPointToLocation(loc);
return true;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent e, MapView mapView) {
count = 1;
Projection proj = mapView.getProjection();
p = (GeoPoint) proj.fromPixels((int) e.getX(), (int) e.getY());
// ConvertPointToLocation(p);
return true;
}
}
public class MyCurrentItemizedOverlay extends ItemizedOverlay<OverlayItem> {
private ArrayList<OverlayItem> overlayItemList = new ArrayList<OverlayItem>();
public MyCurrentItemizedOverlay(Drawable pDefaultMarker,
ResourceProxy pResourceProxy) {
super(pDefaultMarker, pResourceProxy);
}
#Override
public void draw(Canvas canvas, MapView mapView, boolean arg2) {
super.draw(canvas, mapView, arg2);
// ---translate the GeoPoint to screen pixels---
Point screenPts = new Point();
mapView.getProjection().toPixels(currentLocationPixels, screenPts);
// ---add the marker---
Bitmap bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pin_annotation_current_location);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 50, null);
}
public void addItem(GeoPoint p, String title, String snippet) {
OverlayItem newItem = new OverlayItem(title, snippet, p);
overlayItemList.add(newItem);
populate();
}
#Override
public boolean onSnapToItem(int arg0, int arg1, Point arg2,
IMapView arg3) {
return false;
}
#Override
protected OverlayItem createItem(int arg0) {
return overlayItemList.get(arg0);
}
#Override
public int size() {
return overlayItemList.size();
}
}
// Method for convert the lat & long into Address
public String ConvertPointToLocation(GeoPoint point) {
String address = "";
Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocation(
point.getLatitudeE6() / 1E6, point.getLongitudeE6() / 1E6,
1);
if (addresses.size() > 0) {
for (int index = 0; index < addresses.get(0)
.getMaxAddressLineIndex(); index++)
address += addresses.get(0).getAddressLine(index) + " ";
}
Toast.makeText(getBaseContext(), address, Toast.LENGTH_SHORT)
.show();
} catch (IOException e) {
e.printStackTrace();
}
return address;
}
public void btHome(View v) {
startActivity(new Intent(Map.this, JamInfo.class));
}
public void btMap(View v) {
}
public void btReport(View v) {
startActivity(new Intent(Map.this, Report.class));
}
public void btSetting(View v) {
startActivity(new Intent(Map.this, Setting.class));
}
}
The first thing I would try to is to stop allocating Bitmaps every draw cycle. Your draw() methods should be as fast as possible and allocating objects in that method will surely slow things down - especially if the garbage collector has to run. You should create all those Bitmaps in the constructor and store them in variables. Also it is recommended that you don't call toPixels() every draw cycle if you can avoid it - call it only when the location changes and store it (and update it if the zoom level changes).
Take a look at the sample application OpenStreetMapViewer for some well-crafted examples of how to use osmdroid.
So I've spent a good amount of time attempting to figure out how to speed this up, but I'm out of ideas now. I have a class, mapPopup in which a MapView is displayed over the entire screen. There is an array of an array of GeoPoint in mapPopup, and I want to draw lines between each GeoPoint in the 2nd dimensions of the array. I've accomplished this task already using a custom class, mapOverlay, that extends Overlay, but the problem I am having is that once all the map overlays are drawn, the map is extremely slow to zoom or pan. Once all the overlays are added to the map there are often over 2000, but they are all very small.
Thinking that the map would work more quickly if there were less overlays, I drew all the lines to three seperate overlays instead of a seperate overlay for each line. This actually resulted in SLOWER panning and zooming of the map, so I reverted back to the many small overlays.
I would appreciate some informative and easy to understand descriptions of a method that I could employ to make the map faster. Pseudocode or real code for the potential method would also help me to understand it better. My code is posted below. Once more, please note that my overlays and map display properly; I would just like a method that will allow faster panning and zooming.
mapOverlay class
public class mapOverlay extends Overlay {
private Projection projection;
private GeoPoint gp1;
private GeoPoint gp2;
private int color;
public mapOverlay(int color, MapView map, GeoPoint geo1, GeoPoint geo2) {
// super();
this.projection = map.getProjection();
this.gp1 = geo1;
this.gp2 = geo2;
this.color = color;
}
public void draw(Canvas canvas, MapView mapv, boolean shadow) {
super.draw(canvas, mapv, false);
Paint mPaint = new Paint();
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(4);
mPaint.setColor(this.color);
Point p1 = new Point();
Point p2 = new Point();
Path path1 = new Path();
projection.toPixels(gp1, p1);
projection.toPixels(gp2, p2);
path1.moveTo(p1.x, p1.y);
path1.lineTo(p2.x, p2.y);
canvas.drawPath(path1, mPaint);
}
}
mapPopup class
public class mapPopup extends MapActivity {
public String[] trailNames;
public String tableName = "";
public int numTrails = 0;
public static GeoPoint[][] geoPoints;
public int[] colors = new int[] { Color.WHITE, Color.BLUE, Color.CYAN,
Color.RED, Color.YELLOW, Color.MAGENTA, Color.GRAY, Color.LTGRAY };
public int[] newColors;
// public Bitmap b;
public GeoPoint firstP;
public void loadMapData(Bitmap b, MapView map, int[] colors,
GeoPoint[][] GPAA, int ZoomLevel) {
// GPAA holds an array of an array of GeoPoint
Log.i("DEBUG", "starting loadMapDataTask");
map.setSatellite(true);
MapController mc = map.getController();
mapOverlay[][] mapOverlay = new mapOverlay[GPAA.length][];
Log.i("DEBUG", "length of GPAA is: " + GPAA.length);
// i cycles through the first dimension of GPAA
for (int i = 0; i < GPAA.length; i++) {
GeoPoint[] geoPoints = GPAA[i];
int length = geoPoints.length - 1;
mapOverlay[i] = new mapOverlay[length]; //
int pointCount = 0;
// z cycles through the second dimension of GPAA
for (int z = 0; z < length; z++) {
mapOverlay[i][z] = new mapOverlay(colors[i], map,
geoPoints[pointCount], geoPoints[pointCount + 1]);
pointCount++;
}
}
// Actually adds overlays to map
List<Overlay> mapOverlays = map.getOverlays();
for (int i = 0; i < mapOverlay.length; i++) {
int length = mapOverlay[i].length;
Log.i("DEBUG", "Adding map overlays for trail: " + i);
Log.i("DEBUG", "Length of mapOverlay[i] is: " + length);
for (int z = 0; z < length; z++) {
mapOverlays.add(mapOverlay[i][z]);
}
}
mc.animateTo(GPAA[0][0]);
mc.setZoom(ZoomLevel);
Rect r = new Rect();
map.getDrawingRect(r);
map.invalidate(r);
}
public static class runBGLoad extends
AsyncTask<bgLoadParam, Integer, GeoPoint[][]> {
public GeoPoint[][] geoPoints;
protected GeoPoint[] getGPa(Context context, String name, int ID) {
File file = context.getFileStreamPath(name);
if (file.exists() == false) {
Log.i("DEBUG", "Creating file");
InputStream is;
FileOutputStream fos;
try {
Log.i("DEBUG", "id is " + ID);
is = context.getResources().openRawResource(ID);
byte[] buffer = new byte[is.available()];
is.read(buffer);
fos = context.openFileOutput(name, Context.MODE_PRIVATE);
fos.write(buffer);
fos.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.i("DEBUG", "File already exists");
}
// Log.i("DEBUG", "starting to get geopoints");
List<Location> gpsPoints = XMLParser.getPoints(file);
int i = 0;
int index = 0;
GeoPoint[] geoPoints = new GeoPoint[gpsPoints.size()];
// makes list of gpsPoints into GeoPoint[]
ListIterator<Location> it = gpsPoints.listIterator();
while (it.hasNext()) {
index = it.nextIndex();
Location loc = gpsPoints.get(index);
geoPoints[i] = new GeoPoint((int) (loc.getLatitude() * 1E6),
(int) (loc.getLongitude() * 1E6));
it.next();
i++;
}
return geoPoints;
}
#Override
protected GeoPoint[][] doInBackground(bgLoadParam... params) {
Context context = params[0].getContext();
int tNLength = params[0].getTNames().length;
geoPoints = new GeoPoint[tNLength][];
for (int i = 0; i < params[0].getTNames().length; i++) {
String modName = params[0].getTNames()[i].toLowerCase()
.replace(' ', '_');
int identifier = context.getResources().getIdentifier(modName,
"raw", context.getPackageName());
geoPoints[i] = getGPa(params[0].getContext(), modName
+ "_mapfile", identifier);
}
Log.i("DEBUG", "TEST");
mapPopup.geoPoints = geoPoints;
Log.i("DEBUG", "TEST2");
return geoPoints;
}
#Override
protected void onPostExecute(GeoPoint[][] result) {
Log.i("DEBUG", "The points are loaded.");
mapPopup.geoPoints = result;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
String[] extras = intent.getStringArrayExtra("strings");
tableName = extras[1];
numTrails = Integer.parseInt(extras[2]);
trailNames = intent.getStringArrayExtra("trailNamesA");
super.onCreate(savedInstanceState);
setContentView(R.layout.map_popup_layout);
newColors = new int[numTrails];
for (int i = 0; i < numTrails; i++) {
newColors[i] = colors[i];
}
ViewGroup layout = (ViewGroup) findViewById(R.id.map_popup);
TextView[] tVs = new TextView[numTrails];
for (int i = 0; i < numTrails; i++) {
LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tVs[i] = new TextView(getApplicationContext());
tVs[i].setText(trailNames[i]);
tVs[i].setId(i + 700);
tVs[i].setTextColor(colors[i]);
tVs[i].setBackgroundColor(Color.BLACK);
if (i > 0) {
params.addRule(RelativeLayout.BELOW, (699 + i));
}
layout.addView(tVs[i], params);
}
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
MapView map = (MapView) findViewById(R.id.popupMV);
Bitmap b = Bitmap.createBitmap(map.getWidth(), map.getHeight(),
Bitmap.Config.RGB_565);
try {
trailsActivity.mapPreLoad.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
loadMapData(b, map, newColors, geoPoints, 17);
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
I'm currently facing the same problematic, and I just found a workaround : prevent the overlays from drawing when zooming or panning. That's not perfect and I'm still looking for a better solution, but at least the map is usable without waiting 5 seconds for each pan or zoom.
Here is the code I used in my Overlay extension. It's not Java but C# (using Monodroid) - but it should be easily understandable.
public override bool OnTouchEvent (MotionEvent e, Android.GoogleMaps.MapView mapView)
{
if (e.Action == MotionEventActions.Down)
_mustDraw = false;
else if (e.Action == MotionEventActions.Up)
_mustDraw = true;
return base.OnTouchEvent (e, mapView);
}
public override void Draw (Android.Graphics.Canvas canvas, Android.GoogleMaps.MapView mapView, bool shadow)
{
if (shadow || !_mustDraw)
return;
// ...
}
That solution works for every map-touch based action, and now performs with a good speed, I just lack implementation of the same behaviour when zooming in or out using built-in zoom controls, but I first need to fight some of my bugs before doing this part, I'll come back on this part later.
I am able to draw path between two sets of geo-coordinates from reference of
j2memaprouteprovider.
I am able to get current location latitude and longitude.
How do i implement these coordinates in the following class to get path drawn from current position to target position.
MapRouteActivity.java
public class MapRouteActivity extends MapActivity {
LinearLayout linearLayout;
MapView mapView;
private Road mRoad;
static Context context = null;
String GPSPROVIDER = LocationManager.GPS_PROVIDER;
private static final long MIN_GEOGRAPHIC_POOLING_TIME_PERIOD = 10000;
private static final float MIN_GEOGRAPHIC_POOLING_DISTANCE = (float) 5.0;
public LocationManager gpsLocationManager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
context = this;
/* Get a listener for GPS */
LocationListener gpsLocationListener = null;
gpsLocationListener = new GpsLocationListener(this);
/* Start Location Service for GPS */
gpsLocationManager = (LocationManager) this
.getSystemService(Context.LOCATION_SERVICE);
/* Register GPS listener with Location Manager */
gpsLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
MIN_GEOGRAPHIC_POOLING_TIME_PERIOD,
MIN_GEOGRAPHIC_POOLING_DISTANCE, gpsLocationListener);
if (gpsLocationManager == null) {
gpsLocationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_GEOGRAPHIC_POOLING_TIME_PERIOD,
MIN_GEOGRAPHIC_POOLING_DISTANCE, gpsLocationListener);
}
boolean isAvailableGps = gpsLocationManager
.isProviderEnabled(GPSPROVIDER);
if (isAvailableGps) {
Location loc = gpsLocationManager.getLastKnownLocation("gps");
if (loc != null) {
double lattitude = loc.getLatitude();
double longitude = loc.getLongitude();
Toast.makeText(
MapRouteActivity.this,
"Longitude iss " + lattitude + " Latitude iss "
+ longitude, Toast.LENGTH_LONG).show();
}
}
new Thread() {
#Override
public void run() {
double fromLat = 49.85, fromLon = 24.016667, toLat = 50.45, toLon = 30.523333;
String url = RoadProvider
.getUrl(fromLat, fromLon, toLat, toLon);
InputStream is = getConnection(url);
mRoad = RoadProvider.getRoute(is);
mHandler.sendEmptyMessage(0);
}
}.start();
}
Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
TextView textView = (TextView) findViewById(R.id.description);
textView.setText(mRoad.mName + " " + mRoad.mDescription);
MapOverlay mapOverlay = new MapOverlay(mRoad, mapView);
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
mapView.invalidate();
};
};
private InputStream getConnection(String url) {
InputStream is = null;
try {
URLConnection conn = new URL(url).openConnection();
is = conn.getInputStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
public static class GpsLocationListener implements LocationListener {
private ImageView mCurrentPointer;
public GpsLocationListener(Context context) {
}
public void onLocationChanged(Location loc) {
if (loc != null) {
double latitude = loc.getLatitude();
double longitude = loc.getLongitude();
GeoPoint point = new GeoPoint((int) (latitude * 1E6),
(int) (longitude * 1E6));
Toast.makeText(
context,
"Longitude is " + longitude + " Latitude is "
+ latitude, Toast.LENGTH_LONG).show();
}
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
}
class MapOverlay extends com.google.android.maps.Overlay {
Road mRoad;
ArrayList<GeoPoint> mPoints;
public MapOverlay(Road road, MapView mv) {
mRoad = road;
if (road.mRoute.length > 0) {
mPoints = new ArrayList<GeoPoint>();
for (int i = 0; i < road.mRoute.length; i++) {
mPoints.add(new GeoPoint((int) (road.mRoute[i][1] * 1000000),
(int) (road.mRoute[i][0] * 1000000)));
}
int moveToLat = (mPoints.get(0).getLatitudeE6() + (mPoints.get(
mPoints.size() - 1).getLatitudeE6() - mPoints.get(0)
.getLatitudeE6()) / 2);
int moveToLong = (mPoints.get(0).getLongitudeE6() + (mPoints.get(
mPoints.size() - 1).getLongitudeE6() - mPoints.get(0)
.getLongitudeE6()) / 2);
GeoPoint moveTo = new GeoPoint(moveToLat, moveToLong);
MapController mapController = mv.getController();
mapController.animateTo(moveTo);
mapController.setZoom(7);
}
}
#Override
public boolean draw(Canvas canvas, MapView mv, boolean shadow, long when) {
super.draw(canvas, mv, shadow);
drawPath(mv, canvas);
return true;
}
public void drawPath(MapView mv, Canvas canvas) {
int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
Paint paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
for (int i = 0; i < mPoints.size(); i++) {
Point point = new Point();
mv.getProjection().toPixels(mPoints.get(i), point);
x2 = point.x;
y2 = point.y;
if (i > 0) {
canvas.drawLine(x1, y1, x2, y2, paint);
}
x1 = x2;
y1 = y2;
}
}
}
I want to assign current position lattiude and longitude value to fromLat and fronLon variable in above code here:
new Thread() {
#Override
public void run() {
double fromLat = 49.85, fromLon = 24.016667, toLat = 50.45, toLon = 30.523333;
String url = RoadProvider
.getUrl(fromLat, fromLon, toLat, toLon);
InputStream is = getConnection(url);
mRoad = RoadProvider.getRoute(is);
mHandler.sendEmptyMessage(0);
}
}.start();
Help !!
Its very Simple---
Make your Activity like this:--
public class GoogleMapLocationActivity extends MapActivity {
private LocationManager myLocationManager;
private LocationListener myLocationListener;
private TextView myLongitude, myLatitude;
private MapView myMapView;
private MapController myMapController;
LinearLayout zoomLayout;
GeoPoint myLastPosition;
AddItemizedOverlay mapOvlay;
private void CenterLocatio(GeoPoint centerGeoPoint)
{
myMapController.animateTo(centerGeoPoint);
List<Overlay> mapOverlays = myMapView.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.map_point);
if(myLastPosition != null){
mapOvlay = new AddItemizedOverlay(myLastPosition ,centerGeoPoint,drawable );
OverlayItem overlayitem = new OverlayItem(centerGeoPoint,"","" );
mapOvlay.addOverlay(overlayitem);
mapOverlays.add(mapOvlay);
}
myLastPosition = centerGeoPoint;
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myMapView = (MapView)findViewById(R.id.mapview);
myLastPosition = null;
myMapController = myMapView.getController();
myMapController.setZoom(18); //Fixed Zoom Level
myLocationManager = (LocationManager)getSystemService(
Context.LOCATION_SERVICE);
myLocationListener = new MyLocationListener();
myLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0,
0,
myLocationListener);
private class MyLocationListener implements LocationListener{
public void onLocationChanged(Location argLocation) {
GeoPoint myGeoPoint = new GeoPoint(
(int)(argLocation.getLatitude()*1000000),
(int)(argLocation.getLongitude()*1000000));
GeoPoint newGeoPoint = new GeoPoint(myGeoPoint.getLatitudeE6() ,myGeoPoint.getLongitudeE6());
CenterLocatio(newGeoPoint);
}
public void onProviderDisabled(String provider) {
Toast.makeText(getBaseContext(),"GPS Disabled" ,Toast.LENGTH_SHORT).show();
}
public void onProviderEnabled(String provider) {
Toast.makeText(getBaseContext(),"GPS Enabled" ,Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider,
int status, Bundle extras) {
Toast.makeText(getBaseContext(),"GPS Unavailable" ,Toast.LENGTH_SHORT).show();
}
}
#Override
protected boolean isRouteDisplayed() {
return false;
};
}
AddItemizedOverlay.class-----
public class AddItemizedOverlay extends ItemizedOverlay<OverlayItem> {
private ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
private Context context;
private GeoPoint mGpt1;
private GeoPoint mGpt2;
public AddItemizedOverlay(GeoPoint gp1,GeoPoint gp2, Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
mGpt1 = gp1;
mGpt2 = gp2;
}
public AddItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}
public AddItemizedOverlay(Drawable defaultMarker, Context context) {
this(defaultMarker);
this.context = context;
}
#Override
protected OverlayItem createItem(int i) {
return mapOverlays.get(i);
}
#Override
public int size() {
return mapOverlays.size();
}
#Override
protected boolean onTap(int index) {
Log.e("Tap", "Tap Performed");
return true;
}
public void addOverlay(OverlayItem overlay) {
mapOverlays.add(overlay);
this.populate();
}
public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
long when) {
super.draw(canvas, mapView, shadow);
Paint paint;
paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(2);
Point pt1 = new Point();
Point pt2 = new Point();
Projection projection = mapView.getProjection();
projection.toPixels(mGpt1, pt1);
projection.toPixels(mGpt2, pt2);
canvas.drawLine(pt1.x, pt1.y, pt2.x, pt2.y, paint);
return true;
}
}
Hope it will help you...
Use following, It will display direction on native map application,
final Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(
"http://maps.google.com/maps?" +
"saddr="+YOUR_START_LONGITUDE+","+YOUR_START_LATITUDE+"&daddr="YOUR_END_LONGITUDE+","+YOUR_END_LATITUDE));
intent.setClassName(
"com.google.android.apps.maps",
"com.google.android.maps.MapsActivity");
startActivity(intent);
Hi iam displaying mulitple markers in google map in android.while iam displaying, the markers are displaying in the google map one by one.Here i want to display more than 50 markers.But according to my code the markers are displaying one by one and to display 50 markers it is taking so much time.Below is my code which is in the same class.Any idea is appreciated.
public void displayMarkersOnMap(){
Runnable r=new Runnable(){
public void run(){
for (int i = 0; i < vector.size(); i++) {
try {
pinHM = (HashMap<String, Object>)vector.get(i);
mapView = (MapView)findViewById(R.id.mapView);
mapView.getController().setZoom(9);
Drawable marker;
else{
String status = pinHM.get("status").toString();
if (status.equals("ST_COMPLETE")) {
marker = getResources().getDrawable(R.drawable.pin_green);
}else if (status.equals("ST_IN_PROGRESS")) {
marker = getResources().getDrawable(R.drawable.pin_orange);
}else {
marker = getResources().getDrawable(R.drawable.pin_gray);
}
}
marker.setBounds((int) (-marker.getIntrinsicWidth() / 2),-marker.getIntrinsicHeight(),(int) (marker.getIntrinsicWidth() / 2), 0);
double latitude=Double.parseDouble(pinHM.get("latitude").toString());
double longitude=Double.parseDouble(pinHM.get("longitude").toString());
Geocoder geoCoder = new Geocoder(BaseMapActivity.this, Locale.getDefault());
List<Address> addresses = geoCoder.getFromLocationName(address,5);
if (addresses.size() > 0) {
GeoPoint point = new GeoPoint((int)(latitude*1E6),(int)(longitude*1E6));
funPlaces = new MyItemizedOverlay(point,marker,hmtostring,nameaddress,mapView);
mapView.getOverlays().add(funPlaces);
GeoPoint pt = funPlaces.getCenterPt();
int latSpan = funPlaces.getLatSpanE6();
int lonSpan = funPlaces.getLonSpanE6();
Log.v("Overlays", "Lat span is " + latSpan);
Log.v("Overlays", "Lon span is " + lonSpan);
MapController mc = mapView.getController();
mc.setCenter(pt);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}//end of run
};//end of Runnable
Thread thread = new Thread(r, "BaseMapActiviy");
thread.start();
}
public class MyItemizedOverlay extends BalloonItemizedOverlay {
private ArrayList<OverlayItem> m_overlays = new ArrayList<OverlayItem>();
#SuppressWarnings("unused")
private Context c;
private GeoPoint center = null;
public MyItemizedOverlay(GeoPoint point, Drawable marker,String hmtostring,String nameaddress,MapView mapView) {
super(boundCenter(marker), mapView);
c = mapView.getContext();
m_overlays.add(new OverlayItem(point,hmtostring,nameaddress));
populate();
}
public GeoPoint getCenterPt() {
if (center == null) {
int northEdge = -90000000;
int southEdge = 90000000;
int eastEdge = -180000000;
int westEdge = 180000000;
Iterator<OverlayItem> iter = m_overlays.iterator();
while (iter.hasNext()) {
GeoPoint pt = iter.next().getPoint();
if (pt.getLatitudeE6() > northEdge)
northEdge = pt.getLatitudeE6();
if (pt.getLatitudeE6() < southEdge)
southEdge = pt.getLatitudeE6();
if (pt.getLongitudeE6() > eastEdge)
eastEdge = pt.getLongitudeE6();
if (pt.getLongitudeE6() < westEdge)
westEdge = pt.getLongitudeE6();
}
center = new GeoPoint((int) ((northEdge + southEdge) / 2),
(int) ((westEdge + eastEdge) / 2));
}
return center;
}
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
if (!shadow) {
super.draw(canvas, mapView, shadow);
}
return false;
}
public void addOverlay(OverlayItem overlay) {
m_overlays.add(overlay);
populate();
}
#Override
protected OverlayItem createItem(int i) {
return m_overlays.get(i);
}
#Override
public int size() {
return m_overlays.size();
}
#Override
protected boolean onBalloonTap(int index) {
return true;
}
}
I just went through this myself. For your specific case define a new OverlayItem (not MyItemizedOverlay) with whatever then just add it to MyItemizedOverlay.
For your case it would be something like this.
OverlayItem anotherFunPlace = new OverlayItem(theGeoPointYouWantItAt,"Some string","Another String");
//Then you would use the following to add it
FunPlaces.add(anotherFunPlace);
Make sure to place those above lines before
mapView.getOverlays().add(funPlaces);
Hope that helps. Let me know if I missed something or if you have other problems.
I have a class :
class MapItemizedOverlay extends com.google.android.maps.ItemizedOverlay<OverlayItem> {
private Context context;
private ArrayList items = new ArrayList();
public MapItemizedOverlay(Context aContext, Drawable marker) {
super(boundCenterBottom(marker));
context = aContext;
}
public void addOverlayItem(OverlayItem item) {
items.add(item);
populate();
}
#Override
protected OverlayItem createItem(int i) {
return (OverlayItem) items.get(i);
}
#Override
public int size() {
return items.size();
}
#Override
protected boolean onTap(int index) {
OverlayItem item = (OverlayItem) items.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
#Override
public boolean onTap (final GeoPoint p, final MapView mapView) {
Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocation(p.getLatitudeE6() / 1E6,
p.getLongitudeE6() / 1E6, 1);
String address = "";
if (addresses.size() > 0) {
for (int i=0; i<addresses.get(0).getMaxAddressLineIndex(); i++)
address += addresses.get(0).getAddressLine(i) + "\n";
}
address.cancel();
address.setText(address);
address.show();
}
catch (IOException e) {
e.printStackTrace();
}
return true;
}
}
I add some overlays on the map with the function:
private void initialiseOverlays() {
// Create an ItemizedOverlay to display a list of markers
Drawable defaultMarker = getResources().getDrawable(R.drawable.marker);
MapItemizedOverlay mapItemizedOverlay = new MapItemizedOverlay(this, defaultMarker);
mapItemizedOverlay.addOverlayItem(new OverlayItem(new GeoPoint((int) (12.345678 * 1E6), (int) (23.456789 * 1E6)), "Point 1", "some-random-text"));
mapItemizedOverlay.addOverlayItem(new OverlayItem(new GeoPoint((int) (89.012345 * 1E6), (int) (67.890123 * 1E6)), "Point number 2", "more-random-text"));
// Add the overlays to the map
mapView.getOverlays().add(mapItemizedOverlay);
}
If only one of the onTap functions is defined everything works fine - I can either get the address if I click somewhere over the map or I can get a dialog with the place's title and content if I click on the icon over the place.
But I want to have both of the functions working together, the application to detect if the click was over an empty place on the map or over a marker(the drawable set) and show it's information. How can I achieve this?
Found the answer - had to include the:
if(super.onTap(p, mapView)) {
return true;
}
in the beginning of the public boolean onTap (final GeoPoint p, final MapView mapView) function.
you can use onTouch method
#Override
public boolean onTouchEvent(MotionEvent event, final MapView mapView) {
final int action=event.getAction();
final int x=(int)event.getX();
final int y=(int)event.getY();
result = false;
if (action==MotionEvent.ACTION_DOWN) {
downPressed = true;
drag = false;
/* here check for the items is null or not and then after get all the items
so if you click on map and on that place if the item on placed then it will
check for the item hit other it refer the user click on map not on marker
*/
if(items!=null){
for(int i=0;i<items.size();i++){
OverlayItem item = items.get(i);
Point mp=new Point(0,0);
mapView.getProjection().toPixels(item.getPoint(), mp);
xDragTouchOffset=x-mp.x;
yDragTouchOffset=y-mp.y;
if (hitTest(item, marker, x-(mp.x-(xDragImageOffset+xDragTouchOffset*2)), y-(mp.y-((yDragImageOffset/2)+yDragTouchOffset)))) {
result = true;
markerIndex = i;
task_id = Long.parseLong(item.getTitle());
downPressed = false;
markerPressed = true;
break;
}
}
}
}
else if (action==MotionEvent.ACTION_MOVE) {
// here user pressed and drag the downPressed set to false so it will indicate that user want to move the map and drag set to true;
downPressed = false;
drag=true;
}
else if (action==MotionEvent.ACTION_UP) {
// if user not drag then this downPressed is true and it will return the screen and map coordinate
if(downPressed){
tempPoint = mapView.getProjection().fromPixels(x, y);
markerLat = tempPoint.getLatitudeE6()/1e6;
markerLng = tempPoint.getLongitudeE6()/1e6;
mapView.invalidate();
}
drag = false;
downPressed = false;
}
return(result | super.onTouchEvent(event, mapView));
}
here i can do this way hope you get some idea