OverlayItem not showing on correct point on Android - android

I've used below code for show GeoPoint on Android map:
drawable = getResources().getDrawable(R.drawable.annot_start);
point = new GeoPoint((int)(startLatitude*1E6), (int)(startLongitude*1E6));
overlayItem = new OverlayItem(point, startAddress, "");
itemizedOverlay[n]= new RouteItemizedOverlay(getDrawable(drawable), mapView);
itemizedOverlay[n].addOverlay(overlayItem);
mapOverlays.add(itemizedOverlay[n]);
But the pin point is not showing on the current place, it is shown below the point.
How to pin the point on correct position?

In ItemizedOverlay<OverlayItem> constructor use super(boundCenterBottom(marker));. May be it helps.

Related

Set multiple marker in osmdroid

Hi everyone I'm using osmdroid in my application. I have a list of Latitude and Longitude sets and want to show them on the map and each one should be clickable means when I click on one of them it opens new specific activity. so how i suppose to do that ?
I want to do something just like this :
Sadly i couldn't find much information about working with osmdroid so any help would be appreciated.
This is how i used osmdroid map
mapView.setTileSource(TileSourceFactory.MAPNIK);
IMapController mapController = mapView.getController();
mapController.setZoom(9.5);
GeoPoint startPoint = new GeoPoint(34.796830, 48.514820);
mapController.setCenter(startPoint);
mapView.setBuiltInZoomControls(true);
mapView.setMultiTouchControls(true);
And this is overlays with geopoints :
List<OverlayItem> mItem = new ArrayList<OverlayItem>();
Drawable mMarker = this.getResources().getDrawable(R.drawable.marker_default);
GeoPoint point;
if (nearestDiscountsList.size()>0) {
for (int i = 0; i < nearestDiscountsList.size(); i++) {
point = new
GeoPoint(Double.parseDouble(nearestDiscountsList.get(i).getLatitude()),
Double.parseDouble(nearestDiscountsList.get(i).getLongitude()));
OverlayItem overlayItem = new OverlayItem("Here",
"sampleDescription", point);
overlayItem.setMarker(mMarker);
mItem.add(overlayItem);
}
}
But I do not know where to add these ):
Even any sample code about this will do the job.

2 markers in my map (openstreetmap)

Well.
i have an irritating problem and i dont know how to fix it !!
When i get the lat and lng form gps. The map shows 2 markers ( one icon by default and another icon customized by me).
i need the costumized icon appears on the map!!
pd: i already change the path on the method DRAW()
here is my code.
myOpenMapView = (MapView)findViewById(R.id.openmapview);
myOpenMapView.setBuiltInZoomControls(true);
myMapController = myOpenMapView.getController();
myMapController.setZoom(12);
myOpenMapView.setMultiTouchControls(true);
ArrayList<OverlayItem> anotherOverlayItemArray;
anotherOverlayItemArray = new ArrayList<OverlayItem>();
GeoPoint geoPoint = new GeoPoint(Double.valueOf(lat),
(Double.valueOf(lng)));
anotherOverlayItemArray.add(new OverlayItem("US", "US", geoPoint));
myMapController.setCenter(geoPoint);
myMapController.animateTo(geoPoint);
DefaultResourceProxyImpl defaultResourceProxyImpl = new DefaultResourceProxyImpl(this);
MyItemizedIconOverlay myItemizedIconOverlay = new MyItemizedIconOverlay(anotherOverlayItemArray, null, defaultResourceProxyImpl);
myOpenMapView.getOverlays().add(myItemizedIconOverlay);
I had the same problem and I fixed it deleting the super.draw(...) call on draw overrided function of my own ItemizedIconOverlay class.
Hope it helps!
IMPORTANT EDIT: The solution explained above seems to cause problems on marker tap action (we have to call super.draw method).
To fix this I have left behind my CustomItemizedOverlay class and changed the icon using setMarker(Drawable d) method of OverlayItem on each element instead, rude but does the job.
Drawable newMarker = this.getResources().getDrawable(R.drawable.ic_launcher);
mMyLocationOverlay = new ItemizedIconOverlay<OverlayItem>(anotherOverlayItemArray,
newMarker, "listener", new DefaultResourceProxyImpl(getActivity()));
mapView.getOverlays().add(mMyLocationOverlay);
or maybe the myLocationOverlay.enableMyLocation(); is enabled this means it will show the default marker for location on the map

How do I post multiple markers from a JSON array on google maps

I have an android app that takes an array from a website
{"d":[{"latitude":-1.0,"longitude":-1.0,"time":"07:14 PM 01/18/2038","most_recent":"1","user_id":"4e3f2c6659f25a0f8400000b"},{"latitude":-1.0,"longitude":-1.0,"time":"07:14 PM 01/18/2038","most_recent":"0","user_id":"4e3f2c6659f25a0f8400000b"},{"latitude":-1.0,"longitude":-1.0,"time":"07:14 PM 01/18/2038","most_recent":"0","user_id":"4e3f2c6659f25a0f8400000b"},{"latitude":34.0608,"longitude":-118.454,"time":"07:14 PM 01/18/2038","most_recent":"1","user_id":"4e3da65e59f25a3956000005"},{"latitude":34.0608,"longitude":-118.454,"time":"07:14 PM 01/18/2038","most_recent":"0","user_id":"4e3da65e59f25a3956000005"},{"latitude":34.0608,"longitude":-118.454,"time":"07:14 PM 01/18/2038","most_recent":"0","user_id":"4e3da65e59f25a3956000005"}]}
as you can see each item has a latitude and longitude component as well as an id.
How do I modify this program to show either a green pin R.drawable.greenpin or a blue pin R.drawable.bluepin for "user_id":"4e3f2c6659f25a0f8400000b" or "user_id":"4e3da65e59f25a3956000005" for each of the items in the array ( should be three blue pins and three green pins at these locations)
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when)
{
super.draw(canvas,mapView,shadow);
Point screenPts=new Point();
mapView.getProjection().toPixels(p,screenPts);
Bitmap bmp=BitmapFactory.decodeResource(getResources(),R.drawable.greenpin);
canvas.drawBitmap(bmp,screenPts.x,screenPts.y-50,null);
return true;
}
}
//to add the location marker
MapOverlay mapOverlay=new MapOverlay();
List<Overlay> listOfOVerlays=mapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
The method that I have confuses me a bit because it draws the point based on the screen point. I would rather add these points by inserting the pins by the longitude and latitude of the arrays.
I don't understanding what u want but in my case this code work for me, for put marker in appropriate lat,long address.
myPoint = new GeoPoint(((int) LATITUDE_Add) * 1E6),(int)LONGITUDE_Add) * 1E6));
drawable = getResources().getDrawable(R.drawable.marker_blue);
itemizedoverlay = new MapOverLay(drawable, MapPage.this, mapview);
OverlayItem overlayitem = new OverlayItem(myPoint, address, "");
itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);
mapview.getController().animateTo(myPoint);
Thnx.

Efficient Map Overlays in Android Google Map

I want to do the following and am kind of stuck on these for a few days:
I was trying to draw polylines (I have encoded polylines, but have managed to decode those) that move when I move the map.
The only solution that I found was for Geopoints to be transformed into screen coordinates... which won't move if I move the map.
I used HelloItemizedOverlay to add about 150 markers and it gets very very slow.
Any idea what to do? I was thinking about threads (handler).
I was looking for some sort of a timer function that executes a given function periodically, say, every 1 minute or so.
I was also looking for ways to clear the Google map from all the markers/lines, etc.
Answers given below :
1) Here's a solution that I used :
/** Called when the activity is first created. */
private List<Overlay> mapOverlays;
private Projection projection;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
linearLayout = (LinearLayout) findViewById(R.id.zoomview);
mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
mapOverlays = mapView.getOverlays();
projection = mapView.getProjection();
mapOverlays.add(new MyOverlay());
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
class MyOverlay extends Overlay{
public MyOverlay(){
}
public void draw(Canvas canvas, MapView mapv, boolean shadow){
super.draw(canvas, mapv, shadow);
Paint mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(2);
GeoPoint gP1 = new GeoPoint(19240000,-99120000);
GeoPoint gP2 = new GeoPoint(37423157, -122085008);
Point p1 = new Point();
Point p2 = new Point();
Path path = new Path();
Projection projection.toPixels(gP1, p1);
projection.toPixels(gP2, p2);
path.moveTo(p2.x, p2.y);
path.lineTo(p1.x,p1.y);
canvas.drawPath(path, mPaint);
}
courtesy: Drawing a line/path on Google Maps
2) Here's what worked for me :
createMarkers()
{
for(elem:bigList)
{
GeoPoint geoPoint = new GeoPoint((int)(elem.getLat()*1000000), (int) (elem.getLon()*1000000));
OverlayItem overlayItem = new OverlayItem(geoPoint, elem.getName(), elem.getData());
itemizedOverlay.addOverlay(overlayItem);
}
itemizedOverlay.populateNow();
mapOverlays.add(itemizedOverlay); //outside of for loop
}
and in MyOverlay:
public void addOverlay(OverlayItem overlay)
{
m_overlays.add(overlay);
}
public void populateNow()
{
populate();
}
courtesy: stackoverflow.com unknown link
3) The best way is to use a timer class. A very detailed description of the timer class and how to use it is given at this link :
http://life.csu.edu.au/java-tut/essential/threads/timer.html
4) I used this code :
if(!mapOverlays.isEmpty())
{
mapOverlays.clear();
mapView.invalidate();
}
Hope these answers help atleast one other person. Thanks.
I have the same problem. We are developing an iphone app and an android app at the same time. I have 2500 + map overlays. No problem on iphone; a huge performance hit on android when calling populate() after adding all overlays. (Of course, my first try was to call populate() every time after adding an overlay; a typical mistake due to google's tutorial. Now I am calling populate() just once, after all 2500+ overlays have been added to the ItemizedOverlay.)
So the single populate() call takes over 40 seconds to complete on an htc hero device. I had to put in a busy indicator; no progress bar is possible because we cannot get any information about the progress of populate().
I tried another solution: not use ItemizedOverlay but add overlays by hand, subclassing Overlay. Result: indeed it is much faster to add all those overlays to the map; however, the map becomes unusable due to constant calling of the draw() method on each overlay. In my draw method, I tried to optimize as much as possible; I do not create a bitmap every time. My draw() method looks like this:
public void draw(android.graphics.Canvas canvas, MapView mapView, boolean shadow) {
// our marker bitmap already includes shadow.
// centerPoint is the geopoint where we need to put the marker.
if (!shadow) {
Point point = new Point();
mapView.getProjection().toPixels(centerPoint, point);
canvas.drawBitmap(markerBitmap, point.x, point.y, null);
}
}
Here markerBitmap is precomputed. I don't know what else I could optimize. Is there some kind of populate() call required if we are not using ItemizedOverlay??? I could not find any good answers for that.
Right now I resort to caching the ItemizedOverlay once it has been created in a background thread. This way at least the user does not have to wait every time.
For #2, I don't think you solved anything there. Your hard-to-read code is showing how to put markers on overlay and then, how to add that overlay to the map. That's exactly how I do it. I have map with around 300 hotels and it takes around 5 seconds for Android on my Nexus One to create markers. The whole thing is running inside thread and I guess I will have to do some sort of progress bar to let user know what's going on.
I am working on app that already exists on iPhone and it seems iPhone doesn't have any issues to almost instantaneously draw these 300+ markers. I'll have hard time to explain existence of progress bar to my bosses.
If anybody have idea how to optimize this process... I will be grateful.
Here is my code:
...
for (int m = 0; m < ArrList.size(); m++) {
tName = ArrList.get(m).get("name").toString();
tId = ArrList.get(m).get("id").toString();
tLat = ArrList.get(m).get("lat").toString();;
tLng = ArrList.get(m).get("lng").toString();;
try {
lat = Double.parseDouble(tLat);
lng = Double.parseDouble(tLng);
p1 = new GeoPoint(
(int) (lat * 1E6),
(int) (lng * 1E6));
OverlayItem overlayitem = new OverlayItem(p1, tName, tId);
itemizedoverlay.addOverlay(overlayitem);
} catch (NumberFormatException e) {
Log.d(TAG, "NumberFormatException" + e);
}
}
I know I could save some time by avoiding this String > Double conversion, but I don't feel that would give me significant saving.. or it would?
For your 4th question.... simply use the mapOverlays.clear(); method and all the previous markers will be vanished.
code:
if(!mapOverlays.isEmpty()) {
mapOverlays.clear();
mapView.invalidate();
}
Multiple number of drawable objects can be added to a single Overlay which can then be added to the map. Hence, drawing x number of overlay's for x number of objects wouldnt be necessary unless the objects are of different types. Code snippet..
..
Here, CustomPinPoint is my class which extends ItemizedOverlay<OverlayItem>
CustomPinPoint customPinPoint = new CustomPinPoint(drawable, Main.this);
OverlayItem tempOverLayItem = new OverlayItem(
touchedPoint, "PinPoint", "PintPoint 2"); //Point One
customPinPoint.insertPinPoint(tempOverLayItem);
tempOverLayItem = new OverlayItem(new GeoPoint(
(int)(-27.34498 * 1E6), (int)(153.00724 * 1E6)), "PinPoint",
"PintPoint 2"); //Point Two
customPinPoint.insertPinPoint(tempOverLayItem);
overlayList.add(customPinPoint); //Overlay added only once

How to to make 2 MapView on one Activity?

Is it possible to make 2 MapView on one Activity ?
If so, How to make it ?
I've tried but no luck.
Thanks in advance.
The short answer is no.
Currently Android supports only one MapView per MapActivity.
yes possible, I used this code for two different kinds of maps------ 1. for getting gps location------2. for getting some location when it is searched by its area/city/country name. The code is,
public void mapDisplay(double lat, double lng, int arg){
if(arg == 1){
mapView = (MapView)findViewById(R.id.map_view);
}
else if (arg ==2 ){
mapView = (MapView)findViewById(R.id.map_view2);
}
mapView.setBuiltInZoomControls(true);
//mapView.setStreetView(true);
//mapView.setTraffic(true);
//mapView.setSatellite(true);
// to display the pin point
List<Overlay> mapOverlays = mapView.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.icon);
CustomItemizedOverlay itemizedOverlay = new CustomItemizedOverlay(drawable, this);
GeoPoint point = new GeoPoint((int) (lat * 1E6), (int)(lng * 1E6));
OverlayItem overlayitem = new OverlayItem(point, "", "");
itemizedOverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedOverlay);
mapView.getController().setZoom(18);
mapView.getController().setCenter(point);
mapView.getController().animateTo(point);
mapView.invalidate();
}
Note: Make sure that you have set the ContentViews before calling this method and
int arg
is used here to indicate that which mapView is going to be called.....I used

Categories

Resources