Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/224.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android'中覆盖层定位不准确;s地图视图_Android_Android Mapview_Xamarin.android_Itemizedoverlay - Fatal编程技术网

Android'中覆盖层定位不准确;s地图视图

Android'中覆盖层定位不准确;s地图视图,android,android-mapview,xamarin.android,itemizedoverlay,Android,Android Mapview,Xamarin.android,Itemizedoverlay,我正在尝试创建一个包含MapView和ListView的活动。我使用C#和单机器人 布局看起来像这样 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"

我正在尝试创建一个包含MapView和ListView的活动。我使用C#和单机器人

布局看起来像这样

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <app.MD.UI.PlacesMapView
        android:id="@+id/mapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:enabled="true"
        android:clickable="true"
        android:layout_weight="1"
        android:apiKey="key" />
    <ListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:id="@+id/resultsTable" />
</LinearLayout>
var point = MapHelper.ConvertCoordinates(this.Context, this, e.GetX(), e.GetY());

GeoPoint longpressLocation = Projection.FromPixels(point.X, point.Y);
活动方法,该方法将标记添加到地图视图

protected void AddPinToMap(GeoPoint location, string title, bool scrollTo, int zoom)
        {
            var pin = Resources.GetDrawable(Resource.Drawable.maps_pin);
            PinOverlay pinOverlay = new PinOverlay(pin, this);
            OverlayItem item = new OverlayItem(location, title, "");
            pinOverlay.AddOverlay(item);
            mapView.Overlays.Clear();
            mapView.Overlays.Add(pinOverlay);

            if (scrollTo) {
                mapView.Controller.AnimateTo(location);
            }

            mapView.Controller.SetZoom(zoom);
        }
这是我的皮诺弗雷课

class PinOverlay : ItemizedOverlay
    {
        private List<OverlayItem> _items = new List<OverlayItem>();
        private Context _context;

        public PinOverlay(Drawable pin, Context context) : base(pin)
        {
            _context = context;
            BoundCenterBottom(pin);
            Populate();
        }

        protected override Java.Lang.Object CreateItem(int i)
        {
            return _items[i];
        }

        public override int Size()
        {
            return _items.Count();
        }

        public void AddOverlay(OverlayItem overlay) {
            _items.Add(overlay);
            Populate();
        }
    }
您是否尝试过:

public PinOverlay(Drawable pin, Context context) 
    : base(BoundCenterBottom(pin))
这将使放置在地图中心点上的
可绘制
,而不是在绘制时将地理坐标作为(x,y)(0,0)坐标

编辑: 我似乎无法在这里重现您的问题,当在构造函数的
:base()
中使用BoundCenterBottom(pin)时,它会将我的
可绘制的
居中

我还注意到,在您的
AddPinToMap
方法中,每次都会创建一个新的
PinOverlay
。这应该不是必需的,您只需将新的
OverlayItem
s添加到
PinOverlay
,您只需将其添加一次到地图。如果要在地图上添加大量的管脚,这将更高效,资源密集度也更低

所以它看起来应该更像:

protected void AddPinToMap(GeoPoint location, string title, bool scrollTo, int zoom)
{
    var pin = Resources.GetDrawable(Resource.Drawable.maps_pin);
    OverlayItem item = new OverlayItem(location, title, "");
    pinOverlay.AddOverlay(item); // this is instantiated in OnCreate

    if (scrollTo) {
        mapView.Controller.AnimateTo(location);
    }

    mapView.Controller.SetZoom(zoom);
}
如果希望能够同时删除覆盖项,请将
Remove
方法添加到
PinOverlay

另外,
MapView
已经有一个
LongClick
事件,您可以将其挂接到该事件中,而不是覆盖该类:

var mapView = FindViewById<MapView>(Resource.Id.myMapView);
mapView.LongClick += (sender, args) => { //do whatever in here };
var-mapView=findviewbyd(Resource.Id.myMapView);
mapView.LongClick+=(发送者,参数)=>{//在这里做任何事情};

var-mapView=findviewbyd(Resource.Id.myMapView);
mapView.LongClick+=OnLongClick;
private void OnLongClick(对象发送者,LongClickEventArgs LongClickEventArgs)
{
//在这里做什么都行
}

我终于找到了问题的原因

这一部分是错误的,因为投影是在经过的代理内部访问的。但到那时,投影已经改变了它的状态,这导致了错误的坐标

if (e.Action == MotionEventActions.Down) {
    // Finger has touched screen.
    longpressTimer = new Timer(LONGPRESS_THRESHOLD);
    longpressTimer.AutoReset = false;
    longpressTimer.Elapsed += delegate(object sender, ElapsedEventArgs e_elapsed) {
        GeoPoint longpressLocation = Projection.FromPixels((int)e.GetX(), (int)e.GetY());
        if (OnLongPress != null) {
             OnMapViewLongPressEventArgs args = new OnMapViewLongPressEventArgs();
             args.location = longpressLocation;
             OnLongPress(this, args);
        }
    };

    longpressTimer.Start();

    lastMapCenter = MapCenter;
}
因此,解决方案是在OnTouchEvent的最开始获得地质点

if (e.Action == MotionEventActions.Down) {
    capturedProjection = Projection.FromPixels((int)e.GetX(), (int)e.GetY());

    // Finger has touched screen.
    longpressTimer = new Timer(LONGPRESS_THRESHOLD);
    longpressTimer.AutoReset = false;
    longpressTimer.Elapsed += (object sender, ElapsedEventArgs e_timer) => {
        if (OnLongPress != null) {
            OnMapViewLongPressEventArgs args = new OnMapViewLongPressEventArgs();
            args.location = capturedProjection;
            OnLongPress(this, args);
        }
    };

    longpressTimer.Start();

    lastMapCenter = MapCenter;
}

是的,我试过这种方法,但没什么区别。即使我明确设置了边界,它也只会影响标记阴影的位置。感谢关于PinOverlay的建议。此外,我找不到如何从LongClickEventArgs获取XY,这就是我使用计时器和触摸事件的原因。
var mapView = FindViewById<MapView>(Resource.Id.myMapView);
mapView.LongClick += OnLongClick;

private void OnLongClick(object sender, LongClickEventArgs longClickEventArgs)
{
    // do whatever in here
}
if (e.Action == MotionEventActions.Down) {
    // Finger has touched screen.
    longpressTimer = new Timer(LONGPRESS_THRESHOLD);
    longpressTimer.AutoReset = false;
    longpressTimer.Elapsed += delegate(object sender, ElapsedEventArgs e_elapsed) {
        GeoPoint longpressLocation = Projection.FromPixels((int)e.GetX(), (int)e.GetY());
        if (OnLongPress != null) {
             OnMapViewLongPressEventArgs args = new OnMapViewLongPressEventArgs();
             args.location = longpressLocation;
             OnLongPress(this, args);
        }
    };

    longpressTimer.Start();

    lastMapCenter = MapCenter;
}
if (e.Action == MotionEventActions.Down) {
    capturedProjection = Projection.FromPixels((int)e.GetX(), (int)e.GetY());

    // Finger has touched screen.
    longpressTimer = new Timer(LONGPRESS_THRESHOLD);
    longpressTimer.AutoReset = false;
    longpressTimer.Elapsed += (object sender, ElapsedEventArgs e_timer) => {
        if (OnLongPress != null) {
            OnMapViewLongPressEventArgs args = new OnMapViewLongPressEventArgs();
            args.location = capturedProjection;
            OnLongPress(this, args);
        }
    };

    longpressTimer.Start();

    lastMapCenter = MapCenter;
}