0

我正在使用 Mapsforge 显示离线地图,我想实时显示用户 GPS 位置。我有一个 Overlay 类,它表示地图上显示可绘制对象的用户位置。

当设备接收到新的 GPS 位置时,将调用 Overlay 类的方法。方法是locationChanged。该方法改变Overlay的位置并调用mapView.invalidate();

它适用于 GoogleMaps,但不适用于 Mapsforge。使用 Mapsforge,drawable 第一次正确显示用户的 GPS 位置,但是当设备接收到新的 GPS 位置时,drawable 不会移动。只有当用户用手指移动地图时才会移动。我认为 Mapsforge 库的 invalidate() 方法无法正常工作。

方法 locationChanged 被调用,因为我用断点检查了它。位置被正确接收并且 mapView 的实例是正确的。

这是我的覆盖类:

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();
    }
}
4

2 回答 2

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);
        }
于 2014-09-06T05:32:39.480 回答
0

您是否尝试过使用或扩展MyLocationOverlay?这可能会更简单。至少,你可以从它的代码中得到灵感:

    @Override
    public void onLocationChanged(Location newLocation) {
            synchronized (this) {
                    location = new GeoPoint((int)(newLocation.getLatitude() * 1000000) , (int)(newLocation.getLongitude()*1000000));
                    // [...]
            }
            mapView.getOverlayController().redrawOverlays();
    }
于 2013-04-22T10:42:26.717 回答