0

I'm using Mapsforge to show a offline map and i want to display in realtime the user GPS location. I have a Overlay class that represents the user location on the map showing a drawable.

When the device has received a new GPS location, a method from the Overlay class is being called. The method is locationChanged. The method changes the location of the Overlay and calls mapView.invalidate();

It works fine with GoogleMaps, but didn't works with Mapsforge. With Mapsforge the drawable is shown correctly the first time showing the GPS location of the user, but when the device receives a new GPS location, the drawable does not move. Only moves when the users moves the map with the finger. I think that the invalidate() method of Mapsforge library is not working properly.

The method locationChanged is being called becuase i checked it with a breakpoint. The location is being received correctly and the instance of mapView is correct.

This is my Overlay class:

public class CapoMyLocationOverlay extends Overlay implements CapoLocationListener{
    Bitmap pointer;
    GeoPoint location;
    int radius;
    boolean valid_location;
    public MapView mapView;

    public CapoMyLocationOverlay(MapView mapView){       
        Drawable d = ApplicationContextProvider.getContext().getResources().getDrawable(R.drawable.target_location);
        pointer = ((BitmapDrawable) d).getBitmap();
        radius = pointer.getWidth() / 2;       
        valid_location = false;
        this.mapView=mapView;
    }

    @Override
    protected void drawOverlayBitmap(Canvas canvas, Point drawPosition, Projection projection, byte drawZoomLevel) {
        if( valid_location ){           
            Point screenPts = new Point();
            //GeoPoint location = SectionManager.instance.lastLocationGeoPoint;
            mapView.getProjection().toPixels( location , screenPts);
            canvas.drawBitmap(pointer, screenPts.x-radius, screenPts.y-radius , null);   
        }       
    }   

    @Override
    public void locationChanged(Location newLocation) {
        location = new GeoPoint( (int)(newLocation.getLatitude() * 1000000) , (int)(newLocation.getLongitude()*1000000) );       
        valid_location = true;
        mapView.invalidate();
    }
}
NullPointerException
  • 36,107
  • 79
  • 222
  • 382

2 Answers2

0

Have you tried using, or extending MyLocationOverlay? This would probably be simpler. At least, you could get inspiration from its code:

    @Override
    public void onLocationChanged(Location newLocation) {
            synchronized (this) {
                    location = new GeoPoint((int)(newLocation.getLatitude() * 1000000) , (int)(newLocation.getLongitude()*1000000));
                    // [...]
            }
            mapView.getOverlayController().redrawOverlays();
    }
etienne
  • 3,146
  • 1
  • 24
  • 45
0

I had the exact same problem, after some searching, I did the simplest thing:

    new Timer().scheduleAtFixedRate(tasknew, 500, 1000);
        TimerTask tasknew = new TimerTask() {
                    @Override
                    public void run() {
                        Refresh();
                    }
                };

Well, we needed to refresh the MapView, but since "mfMapView.invalidate();" was going to call another thread to edit UI,we couldn't use that kinda refresh, so the easiest way to refresh with least overload was the lines below

      public void Refresh() {

            mfMapView.getModel().mapViewPosition.setZoomLevelMin((byte) 00);
        }
Ariasohrab
  • 23
  • 6