在 Android OverlayItem 中使用自定义 Drawable 绘制位置时出现问题

发布于 2024-10-17 11:27:51 字数 4401 浏览 5 评论 0原文

这段代码正在使用 Google API(级别 8)。

当我更新 OverlayItem 以使用自定义可绘制画布时 对象似乎在错误的位置绘制像素。在这个 例如我正在尝试在路易斯安那州画一个圆圈。当查看 整个地图上的圆圈是从地图上画出来的。当您放大“新建”时 在奥尔良,您会看到圆圈接近适当的纬度,并且 经度。热点似乎位于正确的位置,没有 不管圆画在哪里。

如果,在draw方法中,调用了canvas的恢复方法circle 绘制在正确的位置。

另外,如果不使用自定义可绘制对象,则图标将绘制在 正确的位置(不使用画布“恢复”)。

下面是显示此行为的代码。我尝试添加“setBounds” 和“boundCenterBottom”,因为其他人似乎表明 解决了“位置错误”的问题。尽管 老实说,我不确定为什么需要这些电话。

=======================================================================
public class MapsActivity extends MapActivity
{
    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        MapView mapView = (MapView) findViewById(R.id.mapView);
        mapView.setBuiltInZoomControls(true);

        // Itemized Overlay
        List<Overlay> mapOverlays = mapView.getOverlays();
        Drawable defaultIcon =
this.getResources().getDrawable(R.drawable.icon);
        MyItemizedOverlay itemizedoverlay = new
MyItemizedOverlay(defaultIcon, this);

        // Overlay Item
        GeoPoint pt = new GeoPoint(30000000, -90000000);
        OverlayItem item = new OverlayItem(pt,"New Orleans",
"Louisiana");

        // Custom Drawable
        CustomDrawable customDrawable = new CustomDrawable(pt,
mapView);

        boolean showProblem = true;
        if (showProblem)
        {
            item.setMarker(customDrawable);
        }
        else
        {
            item.setMarker(defaultIcon);
        }

        // Add item we want to overlay
        itemizedoverlay.addOverlay(item);

        // Add overlay
        mapOverlays.add(itemizedoverlay);
    }

    protected boolean isRouteDisplayed()
    {
        return false;
    }
}
=======================================================================
public class MyItemizedOverlay extends ItemizedOverlay<OverlayItem>
{
    private ArrayList<OverlayItem> mOverlays = new
ArrayList<OverlayItem>();

    private Context mContext;

    public MyItemizedOverlay(Drawable defaultMarker, Context context)
    {
        super(boundCenterBottom(defaultMarker));
        mContext = context;
    }

    public void addOverlay(OverlayItem item)
    {
        mOverlays.add(item);
        populate();
    }

    public void removeOverlay(OverlayItem item)
    {
        mOverlays.remove(item);
    }

    public void removeOverlay(int item)
    {
        mOverlays.remove(item);
    }

    protected OverlayItem createItem(int i)
    {
        OverlayItem item = mOverlays.get(i);
        Drawable drawable = item.getMarker(0);

        if (drawable != null)
        {
            int w = drawable.getIntrinsicWidth();
            int h = drawable.getIntrinsicHeight();

            drawable.setBounds(0, 0, w, h);

            item.setMarker(boundCenterBottom(drawable));
        }

        return item;
    }

    public void draw(android.graphics.Canvas canvas, MapView mapView,
            boolean shadow)
    {
        if (shadow)
            return;

        super.draw(canvas, mapView, shadow);
    }

    public int size()
    {
        return mOverlays.size();
    }

    protected boolean onTap(int index)
    {
        OverlayItem item = mOverlays.get(index);
        AlertDialog.Builder dialog = new
AlertDialog.Builder(mContext);
        dialog.setTitle(item.getTitle());
        dialog.setMessage(item.getSnippet());
        dialog.show();

        return true;
    }
}

=======================================================================
public class CustomDrawable extends ShapeDrawable
{
    private int radius = 10;
    private GeoPoint point = null;
    private MapView mapView = null;

    public CustomDrawable(GeoPoint point, MapView mapView)
    {
        this.point  = point;
        this.mapView  = mapView;
    }

    public void draw(Canvas canvas)
    {
        // TODO This (somewhat) fixes projection problem?
        //canvas.restore();

        Projection projection = mapView.getProjection();

        Point pt = projection.toPixels(point, null);

        canvas.drawCircle(pt.x, pt.y, radius,
getPaint());
    }

    public int getIntrinsicHeight()
    {
        return 2 * radius;
    }

    public int getIntrinsicWidth()
    {
        return 2 * radius;
    }
}
=======================================================================

This code is using
the Google APIs (level 8).

When I update the OverlayItem to use a custom drawable the Canvas
object seems to draw the pixels in the wrong location. In this
example I'm trying to draw a circle in Louisiana. When viewing the
entire map the circle is drawn off the map. As you zoom into New
Orleans you'll see the circle approach the appropriate latitude and
longitude. The hot spot seems to be in the correct location, no
matter where the circle is being drawn.

If, in the draw method, the canvas restore method is called the circle
draws in the correct location.

Also If the custom drawable is not used, the icon is drawn in the
correct location (without using Canvas "restore").

Below is the code showing this behavior. I tried adding "setBounds"
and "boundCenterBottom", since other people seemed to indicate that
resolved their "wrong location" problems. Though
to be honest I'm not sure why those calls are needed.

=======================================================================
public class MapsActivity extends MapActivity
{
    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        MapView mapView = (MapView) findViewById(R.id.mapView);
        mapView.setBuiltInZoomControls(true);

        // Itemized Overlay
        List<Overlay> mapOverlays = mapView.getOverlays();
        Drawable defaultIcon =
this.getResources().getDrawable(R.drawable.icon);
        MyItemizedOverlay itemizedoverlay = new
MyItemizedOverlay(defaultIcon, this);

        // Overlay Item
        GeoPoint pt = new GeoPoint(30000000, -90000000);
        OverlayItem item = new OverlayItem(pt,"New Orleans",
"Louisiana");

        // Custom Drawable
        CustomDrawable customDrawable = new CustomDrawable(pt,
mapView);

        boolean showProblem = true;
        if (showProblem)
        {
            item.setMarker(customDrawable);
        }
        else
        {
            item.setMarker(defaultIcon);
        }

        // Add item we want to overlay
        itemizedoverlay.addOverlay(item);

        // Add overlay
        mapOverlays.add(itemizedoverlay);
    }

    protected boolean isRouteDisplayed()
    {
        return false;
    }
}
=======================================================================
public class MyItemizedOverlay extends ItemizedOverlay<OverlayItem>
{
    private ArrayList<OverlayItem> mOverlays = new
ArrayList<OverlayItem>();

    private Context mContext;

    public MyItemizedOverlay(Drawable defaultMarker, Context context)
    {
        super(boundCenterBottom(defaultMarker));
        mContext = context;
    }

    public void addOverlay(OverlayItem item)
    {
        mOverlays.add(item);
        populate();
    }

    public void removeOverlay(OverlayItem item)
    {
        mOverlays.remove(item);
    }

    public void removeOverlay(int item)
    {
        mOverlays.remove(item);
    }

    protected OverlayItem createItem(int i)
    {
        OverlayItem item = mOverlays.get(i);
        Drawable drawable = item.getMarker(0);

        if (drawable != null)
        {
            int w = drawable.getIntrinsicWidth();
            int h = drawable.getIntrinsicHeight();

            drawable.setBounds(0, 0, w, h);

            item.setMarker(boundCenterBottom(drawable));
        }

        return item;
    }

    public void draw(android.graphics.Canvas canvas, MapView mapView,
            boolean shadow)
    {
        if (shadow)
            return;

        super.draw(canvas, mapView, shadow);
    }

    public int size()
    {
        return mOverlays.size();
    }

    protected boolean onTap(int index)
    {
        OverlayItem item = mOverlays.get(index);
        AlertDialog.Builder dialog = new
AlertDialog.Builder(mContext);
        dialog.setTitle(item.getTitle());
        dialog.setMessage(item.getSnippet());
        dialog.show();

        return true;
    }
}

=======================================================================
public class CustomDrawable extends ShapeDrawable
{
    private int radius = 10;
    private GeoPoint point = null;
    private MapView mapView = null;

    public CustomDrawable(GeoPoint point, MapView mapView)
    {
        this.point  = point;
        this.mapView  = mapView;
    }

    public void draw(Canvas canvas)
    {
        // TODO This (somewhat) fixes projection problem?
        //canvas.restore();

        Projection projection = mapView.getProjection();

        Point pt = projection.toPixels(point, null);

        canvas.drawCircle(pt.x, pt.y, radius,
getPaint());
    }

    public int getIntrinsicHeight()
    {
        return 2 * radius;
    }

    public int getIntrinsicWidth()
    {
        return 2 * radius;
    }
}
=======================================================================

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萌辣 2024-10-24 11:27:51

您的 CustomDrawable 不应相对于地图定位自身。它应该只在其边界内绘制自身,而不引用 MapView 或其 ProjectionItemizedOverlay 负责为您的 OverlayItem 定位 Drawable

Your CustomDrawable shouldn't be positioning itself with respect to the map. It should just draw itself within its bounds, and not reference the MapView or its Projection. ItemizedOverlay takes care of positioning the Drawable for your OverlayItem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文