2011-04-05 77 views
3

我有一个地图视图,其中有数千个我想加载的项目。 显然,我不能在视图创建时加载它们。android maps异步加载覆盖项目

我想我有异步根据什么是目​​前显示加载他们..

我怎么能只加载位于屏幕上显示的地图部分项目?

回答

8

使用AsyncTask在每个屏幕上加载单个图层。使用MapView API获取当前可见的地图的纬度/经度。在后端发送他们的经/纬边框来获得你想要的物品。因此,从内存大致会是这样的:

public class LoadMapItems extends AsyncTask<Integer,Integer,List<ItemizedOverlay>> { 
    private MapView view; 

    public LoadMapItems(MapView view) { 
     this.view = view; 
    } 

    public List<ItemizedOverlay> doInBackground(Integer... params) { 
     int left = params[0]; 
     int top = params[1]; 
     int right = params[2]; 
     int bottom = params[3]; 

     return convertToItemizedOverlay(someService.loadSomething(left, top, right, bottom)); 
    } 

    private List<ItemizedOverlay> convertToItemizedOverlay(List<SomeObject> objects) { 
     // ... fill this out to convert your back end object to overlay items 
    } 

    public void onPostExecute(List<ItemizedOverlay> items) { 
     List<Overlay> mapOverlays = mapView.getOverlays(); 
     for(ItemizedOverlay item : items) { 
     mapOverlays.add(item); 
     } 
    } 
} 

// somewhere else in your code you do this: 

GeoPoint center = someMap.getMapCenter(); 
new LoadMapItems(someMap).execute( 
     center.getLongitude() - someMap.getLongitudeSpan()/2, 
     center.getLatitude() - someMap.getLatitudeSpan()/2, 
     center.getLongitude() + someMap.getLongitudeSpan()/2, 
     center.getLatitude() + someMap.getLatitudeSpan()/2); 
+0

谢谢!这非常有帮助。 但是,如何处理当前可见地图上的更改? – Matteo 2011-04-05 11:18:59

+0

当有人移动它时,您的MapView会派发事件。在该事件处理程序期间,您将使用此AsyncTask从后端服务加载数据。我会得到那个工作,然后一旦它工作,我会考虑在数据结构中缓存这些加载可能映射<绑定框,列表>。它有一点小技巧,但它可以使它更快。然后,当用户拖动地图以查看您是否已经加载该地图块时,您会检查该数据结构... – chubbsondubs 2011-04-06 02:44:29

+0

...实际上,您可能会发现将覆盖图分配给固定网格单元格并加载它们网格单元格与您的MapView的当前纬度/经度跨度相交,如图所示。这使缓存固定网格段变得更容易。您可能会加载可见区域外部的功能,但它会很小。您加载的网格单元格的最大数量为4.另外,在后端进行优化更容易,因为您的数据库可以使用固定键进行索引。您只需要将lat/long转换为网格单元格编号并加载分配给该网格单元格编号的特征。 – chubbsondubs 2011-04-06 02:49:53