Android 在地图视图上使用多个可绘制图形

Android 在地图视图上使用多个可绘制图形,android,overlay,android-mapview,itemizedoverlay,Android,Overlay,Android Mapview,Itemizedoverlay,我在Mapview、Overlay和ItemizedOverlay方面的经验非常有限。我见过一些简单的代码示例,它们使用一个可绘制的覆盖图和项目化覆盖图,但我不确定如何满足这些要求:我希望在我的地图视图上有多个可绘制的(例如:地图中心的星形图标和其他覆盖图项目的其他图标),但我希望其中一个不可绘制(星形)。我应该同时使用Overlay和ItemizeOverlay来实现这一点吗 另外,我的下一个问题是演示问题:如果我有500个项目要显示在地图上,那么显示这些信息的实用方法是什么?同样,我几乎没有

我在Mapview、Overlay和ItemizedOverlay方面的经验非常有限。我见过一些简单的代码示例,它们使用一个可绘制的覆盖图和项目化覆盖图,但我不确定如何满足这些要求:我希望在我的地图视图上有多个可绘制的(例如:地图中心的星形图标和其他覆盖图项目的其他图标),但我希望其中一个不可绘制(星形)。我应该同时使用Overlay和ItemizeOverlay来实现这一点吗


另外,我的下一个问题是演示问题:如果我有500个项目要显示在地图上,那么显示这些信息的实用方法是什么?同样,我几乎没有开发和使用地图应用程序的经验。

几周前,我遇到了同样的情况

您应该为每个不同的绘图表使用一个ItemizedOverlay,然后向ItemizedOverlay添加覆盖项

最方便的方法是扩展ItemizeOverlay,这样您就可以为需要的每个样式定义一个标记和单击行为

对于第二部分,出于性能考虑,您不应该一次用所有500个项目填充地图。我使用了一个系统,它可以动态地添加到属于地图显示范围的地图标记中

以下是我的ItemizeOverlay片段,它可能对您的两个问题都有用:

    private class MarkerItemized_Overlay extends ItemizedOverlay<OverlayItem> {



        private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
    Context mContext;

    public MarkerItemizedOverlay(Drawable marker, Context context) {
        super(boundCenterBottom(marker));
        mContext = context;
    }

    public void addOverlay(OverlayItem overlay) {
        if (!mOverlays.contains(overlay)) {
            mOverlays.add(overlay);
            populate();
        }
    }

    @Override
    protected OverlayItem createItem(int i) {
        return mOverlays.get(i);
    }

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

    @Override
    protected boolean onTap(final int index) {
        OverlayItem item = mOverlays.get(index);

        AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
        dialog.setTitle(item.getTitle());
        dialog.setMessage(item.getSnippet());
        dialog.setNegativeButton("Annuler",
                new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton){}
        });
        dialog.setPositiveButton("Naviguer",
                new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton){ showDirections(mOverlays.get(index).getPoint()); }
        });
        dialog.setInverseBackgroundForced(true);
        dialog.show();
        return true;
    }
    public boolean contains(Store store) {
        return mOverlays.contains(store);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e, MapView mapView) {

        if (e.getAction() == MotionEvent.ACTION_UP) {
            GeoPoint newCenter = mapView.getMapCenter();
            int minLat, maxLat, minLng, maxLng;
            minLat = mapCenter.getLatitudeE6() - mapView.getLatitudeSpan()/2;
            maxLat = mapCenter.getLatitudeE6() + mapView.getLatitudeSpan()/2;
            minLng = mapCenter.getLongitudeE6() - mapView.getLongitudeSpan()/2;
            maxLng = mapCenter.getLongitudeE6() + mapView.getLongitudeSpan()/2;
            if (newCenter.getLatitudeE6() > maxLat ||
                    newCenter.getLatitudeE6() < minLat ||
                    newCenter.getLongitudeE6() > maxLng ||
                    newCenter.getLongitudeE6() < minLng)
            {
                mapCenter = mapView.getMapCenter();
                Location mapCenterLoc = new Location(providerName);
                mapCenterLoc.setLatitude(newCenter.getLatitudeE6()/1E6);
                mapCenterLoc.setLongitude(newCenter.getLongitudeE6()/1E6);
                Store[] newClosestStores = storeDB.getClosestStores(mapCenterLoc);

                for (int i = 0; i < newClosestStores.length; i++) 
                    if (! itemizedOverlay.contains(newClosestStores[i])) 
                        setMarker(newClosestStores[i]);
            }
        }
        return super.onTouchEvent(e, mapView);
    }
}
private class MarkerItemized\u覆盖扩展了ItemizedOverlay{
private ArrayList mOverlays=new ArrayList();
语境;
公共标记emizedoverlay(可绘制标记,上下文){
super(boundCenterBottom(marker));
mContext=上下文;
}
公共void addOverlay(OverlayItem overlay){
如果(!mOverlays.contains(覆盖)){
添加(覆盖);
填充();
}
}
@凌驾
受保护的OverlayItem createItem(int i){
返回mOverlays.get(i);
}
@凌驾
公共整数大小(){
返回mOverlays.size();
}
@凌驾
受保护的布尔onTap(最终整数索引){
OverlayItem item=mOverlays.get(索引);
AlertDialog.Builder dialog=新建AlertDialog.Builder(mContext);
setTitle(item.getTitle());
setMessage(item.getSnippet());
对话框。setNegativeButton(“环空器”,
新建DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int whichButton){}
});
对话框.setPositiveButton(“Naviguer”,
新建DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int whichButton){showDirections(mOverlays.get(index.getPoint());}
});
对话框。setInverseBackgroundForced(真);
dialog.show();
返回true;
}
公共布尔包含(存储){
返回mOverlays.contains(存储);
}
@凌驾
公共布尔onTouchEvent(MotionEvent e,MapView MapView){
如果(e.getAction()==MotionEvent.ACTION\u UP){
GeoPoint newCenter=mapView.getMapCenter();
int minLat、maxLat、minLng、maxLng;
minLat=mapCenter.getLatitudeE6()-mapView.getLatitudeSpan()/2;
maxLat=mapCenter.getLatitudeE6()+mapView.getLatitudeSpan()/2;
minLng=mapCenter.getLongitudeE6()-mapView.getLongitudeSpan()/2;
maxLng=mapCenter.getLongitudeE6()+mapView.getLongitudeSpan()/2;
如果(newCenter.getlatudee6()>maxLat||
newCenter.getLatitudeE6()maxLng||
newCenter.getLongitudeE6()
一次在地图上显示500个项目是个坏主意,因为性能会非常差。试着过滤掉并只显示其中的一些。这是一个好问题。尤其是当您开始考虑在某些缩放级别对点进行聚类时。如果发现自己需要在更高的缩放级别上显示多个点,则可以考虑将覆盖区聚类为一个,并在放大时相应地展开群集。