Добавление наложения к OSMDROID

Я так долго боролся с этим. Я пытаюсь добавить Overlay на свою карту. Я использую OSMdroid с открытым исходным кодом. но все, что я получаю на примере, это прямая красная линия от одного угла к другому. Моя цель - добавить значок, где установлен мой геооп.

вот мой код:

 package osmdemo.demo;

import java.util.List;

import microsoft.mappoint.TileSystem;

import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.MapView.Projection;
import org.osmdroid.views.overlay.Overlay;
import org.osmdroid.views.overlay.ScaleBarOverlay;
import org.osmdroid.views.util.constants.MapViewConstants;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.location.LocationManager;
import android.os.Bundle;

public class map extends Activity implements MapViewConstants
{

    /** Called when the activity is first created. */

    protected static final String PROVIDER_NAME = LocationManager.GPS_PROVIDER;
    MapController mapController;
    MapView mapView;
    ScaleBarOverlay mScaleBarOverlay;
    private MapOverlay mmapOverlay = null;
    private LocationManager mLocMgr;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mapView = (MapView) findViewById(R.id.mapview);

        mapView.setTileSource(TileSourceFactory.MAPNIK);
        mapView.setBuiltInZoomControls(true);
        mapView.setMultiTouchControls(true);

        mapController = mapView.getController();
        mapController.setZoom(20);
        GeoPoint point2 = new GeoPoint(31.987968, 34.783069);
        mapController.setCenter(point2);

        this.mmapOverlay = new MapOverlay(this);

        List<Overlay> listOfOverlays = mapView.getOverlays();
        listOfOverlays.add(mmapOverlay);
        mapView.invalidate();
    }

    public class MapOverlay extends org.osmdroid.views.overlay.Overlay
    {

        public MapOverlay(Context ctx)
        {
            super(ctx);
            // TODO Auto-generated constructor stub
        }

        @Override
        protected void draw(Canvas pC, MapView pOsmv, boolean shadow)
        {
            if (shadow)
                return;

            Paint lp3;
            lp3 = new Paint();
            lp3.setColor(Color.RED);
            lp3.setAntiAlias(true);
            lp3.setStyle(Style.STROKE);
            lp3.setStrokeWidth(1);
            lp3.setTextAlign(Paint.Align.LEFT);
            lp3.setTextSize(12);
            // Calculate the half-world size
            final Rect viewportRect = new Rect();
            final Projection projection = pOsmv.getProjection();
            final int zoomLevel = projection.getZoomLevel();
            int mWorldSize_2 = TileSystem.MapSize(zoomLevel) / 2;

            // Save the Mercator coordinates of what is on the screen
            viewportRect.set(projection.getScreenRect());
            // DON'T set offset with either of below
            // viewportRect.offset(-mWorldSize_2, -mWorldSize_2);
            // viewportRect.offset(mWorldSize_2, mWorldSize_2);

            // Draw a line from one corner to the other
            pC.drawLine(viewportRect.left, viewportRect.top,
                    viewportRect.right, viewportRect.bottom, lp3);
        }

        public void onProviderDisabled(String arg0)
        {
        }

        public void onProviderEnabled(String provider)
        {
        }

    }

}

thats my Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.overlay" android:versionCode="1" android:versionName="1.0">
    <uses-sdk android:minSdkVersion="3" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


    <application >
        <activity android:name=".OverlayDemo" 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>
</manifest>

Спасибо заранее,

лучей.

Ответ 1

Варианты фреймов 3.0.3 и 3.0.4, похоже, немного изменились с момента написания кода примера.

Если вы основываете свое приложение на коде, как указано в предыдущем ответе, измените строку

mResourceProxy = new ResourceProxyImpl(getApplicationContext());

к

mResourceProxy = new DefaultResourceProxyImpl(getApplicationContext());

Это, по крайней мере, приведет вас к значку по умолчанию.

ИЗМЕНИТЬ

Это должно сосредоточить карту только NE в Ливерпуле и поместить значок в центр.

package osmdemo.demo;

import java.util.ArrayList;
import org.osmdroid.DefaultResourceProxyImpl;
import org.osmdroid.ResourceProxy;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ItemizedIconOverlay;
import org.osmdroid.views.overlay.ItemizedOverlay;
import org.osmdroid.views.overlay.OverlayItem;
import org.osmdroid.views.util.constants.MapViewConstants;

import android.app.Activity;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.Toast;

public class DemoMap extends Activity implements LocationListener,
        MapViewConstants {

    private MapView mMapView;
    private MapController mapController;
    private LocationManager mLocMgr;
    private ItemizedOverlay<OverlayItem> mMyLocationOverlay;
    private ResourceProxy mResourceProxy;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mResourceProxy = new DefaultResourceProxyImpl(getApplicationContext());
        setContentView(R.layout.copymain);

        mMapView = (MapView) this.findViewById(R.id.mapview);
        mMapView.setTileSource(TileSourceFactory.MAPNIK);
        mMapView.setBuiltInZoomControls(true);
        mMapView.setMultiTouchControls(true);
        mapController = this.mMapView.getController();
        mapController.setZoom(15);
        GeoPoint point2 = new GeoPoint(53554070, -2959520); // centre map here
        GeoPoint point3 = new GeoPoint(53554070 + 1000, -2959520 + 1000); // icon goes here
        mapController.setCenter(point2);
        mLocMgr = (LocationManager) getSystemService(LOCATION_SERVICE);
        mLocMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 100,
                this);

        ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();
        // Put overlay icon a little way from map centre
        items.add(new OverlayItem("Here", "SampleDescription", point3));

        /* OnTapListener for the Markers, shows a simple Toast. */
        this.mMyLocationOverlay = new ItemizedIconOverlay<OverlayItem>(items,
                new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
                    @Override
                    public boolean onItemSingleTapUp(final int index,
                            final OverlayItem item) {
                        Toast.makeText(
                                DemoMap.this,
                                "Item '" + item.mTitle, Toast.LENGTH_LONG).show();
                        return true; // We 'handled' this event.
                    }
                    @Override
                    public boolean onItemLongPress(final int index,
                            final OverlayItem item) {
                        Toast.makeText(
                                DemoMap.this, 
                                "Item '" + item.mTitle ,Toast.LENGTH_LONG).show();
                        return false;
                    }
                }, mResourceProxy);
        this.mMapView.getOverlays().add(this.mMyLocationOverlay);
        mMapView.invalidate();
    }

    public void onLocationChanged(Location location) {
        int lat = (int) (location.getLatitude() * 1E6);
        int lng = (int) (location.getLongitude() * 1E6);
        GeoPoint gpt = new GeoPoint(lat, lng);
        mapController.setCenter(gpt);
        mMapView.invalidate();
    }

    @Override
    public void onProviderDisabled(String arg0) {}
    @Override
    public void onProviderEnabled(String provider) {}
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {}

}

Это немного грубо и готово, но, по крайней мере, он работает нормально только с флагом 3.0.4 и slf4j. Надеюсь, что это поможет.

РЕДАКТИРОВАТЬ 2

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="osmdemo.demo"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name="DemoMap"
                  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-sdk android:minSdkVersion="3" />

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

</manifest> 

.

Ответ 2

Если вы пытаетесь добавить значок, то вы хотите посмотреть классы ItemizedOverlay. Вы можете использовать osmdroid ItemizedIconOverlay, который представляет собой конкретную реализацию ItemizedOverlay, или вы можете подклассифицировать ItemizedOverlay самостоятельно. Взгляните на образцы, например:

http://code.google.com/p/osmdroid/source/browse/trunk/OpenStreetMapViewer/src/org/osmdroid/samples/SampleWithMinimapItemizedoverlay.java

Ответ 3

@rayman

Пожалуйста, еще одна вещь. При изменении местоположения карта меняется, но Икона ушла. как я могу проверить значок в новые изменения? - rayman Jul 1 '11 в 7:12

здесь изменяется ваше местоположение.

public void onLocationChanged(Location location) {
    int lat = (int) (location.getLatitude() * 1E6);
    int lng = (int) (location.getLongitude() * 1E6);
    GeoPoint gpt = new GeoPoint(lat, lng);
    mapController.setCenter(gpt);
    mMapView.invalidate();
}

Но, как вы видите, он не добавляет новый значок в оверлей.

Вы должны удалить предыдущие элементы

items.clear()

(если вы хотите, чтобы "старый" значок был удален при создании нового), а затем добавьте новую точку (gpt) в элементы.

items.add(new OverlayItem("Title", "Description", gpt));

и т.д.