2010-05-17 67 views
21

我想做以下和幾天我就這幾樣卡:高效的地圖疊加層在Android的谷歌地圖

  1. 我試圖繪製折線(我已編碼折線,但設法解碼那些)我移動地圖時移動的
    我發現的唯一解決方案是將Geopoints轉換爲屏幕座標......如果我移動地圖,它將不會移動。

  2. I used HelloItemizedOverlay添加約150個標記,它變得非常非常慢
    不知道該怎麼辦?我正在考慮線程(處理程序)。

  3. 我正在尋找一些定時器功能,定期執行給定的功能,比如說,每隔1分鐘左右。

  4. 我也從所有標記/線尋找各種方法來清楚谷歌地圖等。下面給出

+1

Q1爲解決......我找到了答案,同時通過stackoverflow.com ......瀏覽:)這裏http://stackoverflow.com/questions/2176397發佈的解決/想要在Google地圖中繪製線或路徑在hellomapview – Ahsan 2010-05-17 11:56:13

+1

q4 ...解決了,我在stackoverflow.com找到了答案...解決方法是:.. use此代碼 if(!mapOverlays.isEmpty()) { mapOverlays.clear(); mapView.invalidate(); } – Ahsan 2010-05-18 11:11:40

+3

q2解決,發現於ostackoverflow.com ... ////////////////////////// createMarkers(){ for( elem:bigList)GeoPoint geoPoint = new GeoPoint((int)(elem.getLat()* 1000000),(int)(elem.getLat()getLon()* 1000000)); OverlayItem overlayItem = new OverlayItem(geoPoint,elem.getName(),elem.getData()); itemizedOverlay.addOverlay(overlayItem); itemizedOverlay.addOverlay(overlayItem); } itemizedOverlay.populateNow(); mapOverlays.add(itemizedOverlay); // for循環 } 和在MyOverlay以外: 公共無效addOverlay(OverlayItem覆蓋){ m_overlays.add(覆蓋); } public void populateNow(){ populate(); } – Ahsan 2010-05-19 14:46:36

回答

11

答案:

1)下面是我使用的解決方案:

/** Called when the activity is first created. */ 
private List<Overlay> mapOverlays; 

private Projection projection; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    linearLayout = (LinearLayout) findViewById(R.id.zoomview); 
    mapView = (MapView) findViewById(R.id.mapview); 
    mapView.setBuiltInZoomControls(true); 

    mapOverlays = mapView.getOverlays();   
    projection = mapView.getProjection(); 
    mapOverlays.add(new MyOverlay());   

} 

@Override 
protected boolean isRouteDisplayed() { 
    return false; 
} 

class MyOverlay extends Overlay{ 

    public MyOverlay(){ 

    } 

    public void draw(Canvas canvas, MapView mapv, boolean shadow){ 
     super.draw(canvas, mapv, shadow); 

    Paint mPaint = new Paint(); 
     mPaint.setDither(true); 
     mPaint.setColor(Color.RED); 
     mPaint.setStyle(Paint.Style.FILL_AND_STROKE); 
     mPaint.setStrokeJoin(Paint.Join.ROUND); 
     mPaint.setStrokeCap(Paint.Cap.ROUND); 
     mPaint.setStrokeWidth(2); 

     GeoPoint gP1 = new GeoPoint(19240000,-99120000); 
     GeoPoint gP2 = new GeoPoint(37423157, -122085008); 

     Point p1 = new Point(); 
     Point p2 = new Point(); 

    Path path = new Path(); 

    Projection projection.toPixels(gP1, p1); 
     projection.toPixels(gP2, p2); 

     path.moveTo(p2.x, p2.y); 
     path.lineTo(p1.x,p1.y); 

     canvas.drawPath(path, mPaint); 
    } 

禮貌:Drawing a line/path on Google Maps

2)這裏是爲我工作:

createMarkers() 
{ 
    for(elem:bigList) 
    { 
     GeoPoint geoPoint = new GeoPoint((int)(elem.getLat()*1000000), (int) (elem.getLon()*1000000)); 
     OverlayItem overlayItem = new OverlayItem(geoPoint, elem.getName(), elem.getData()); 
     itemizedOverlay.addOverlay(overlayItem); 
    } 

    itemizedOverlay.populateNow(); 
    mapOverlays.add(itemizedOverlay); //outside of for loop 
} 

和MyOverlay:

public void addOverlay(OverlayItem overlay) 
{ 
    m_overlays.add(overlay); 
} 

public void populateNow() 
{ 
    populate(); 
} 

禮貌:stackoverflow.com不明鏈接

3)最好的方法是使用Timer類。定時器類的非常詳細的介紹,以及如何使用它,在這個環節中給出:

http://life.csu.edu.au/java-tut/essential/threads/timer.html

4)我用這個代碼:

if(!mapOverlays.isEmpty()) 
{ 
    mapOverlays.clear(); 
    mapView.invalidate(); 
} 

希望這些答案可以幫助ATLEAST另外一個人。謝謝。

+1

您應該在單獨的答案中提供解決方案,而不是在評論中。對每個人都好,它可以讓你使用代碼的格式。 – 2010-07-14 10:53:24

+1

你是男人。我在地圖上繪製200/300針的任務,而且我沒有平滑度的麻煩。所以在我的研發過程中,我遇到了這篇文章,你是那個人。非常感謝。 **在MapView **上繪製多個針腳的解決方案是步驟2 – 2012-07-18 09:19:53

+0

@PareshMayani:很高興它幫助:) – Ahsan 2012-07-18 17:59:45

0

對於#2,我認爲你沒有解決任何問題。您難以閱讀的代碼展示瞭如何將標記放置在覆蓋圖上,然後如何將該覆蓋圖添加到地圖。我正是這麼做的。我有大約300家酒店的地圖,我的Nexus One上的Android需要大約5秒才能創建標記。整個事情在線程內運行,我想我將不得不做一些進度條讓用戶知道發生了什麼。

我正在研究iPhone上已經存在的應用程序,看起來iPhone沒有任何問題,幾乎可以即時繪製這300多個標記。我將很難向我的老闆解釋進度條的存在。

如果有人有想法如何優化這個過程......我將不勝感激。

這裏是我的代碼:

... 
     for (int m = 0; m < ArrList.size(); m++) { 
      tName = ArrList.get(m).get("name").toString(); 
      tId = ArrList.get(m).get("id").toString(); 
      tLat = ArrList.get(m).get("lat").toString();; 
      tLng = ArrList.get(m).get("lng").toString();; 
      try { 
       lat = Double.parseDouble(tLat); 
       lng = Double.parseDouble(tLng); 
       p1 = new GeoPoint(
         (int) (lat * 1E6), 
         (int) (lng * 1E6)); 
       OverlayItem overlayitem = new OverlayItem(p1, tName, tId); 
       itemizedoverlay.addOverlay(overlayitem); 
      } catch (NumberFormatException e) { 
       Log.d(TAG, "NumberFormatException" + e);  
      } 
     } 

我知道我可以通過避免此String>雙轉換節省一些時間,但我不覺得會給我節省顯著..或者它會嗎?

2

我有同樣的問題。我們正在同時開發一個iphone應用程序和一個android應用程序。我有2500多個地圖疊加層。 iPhone上沒問題;在添加所有疊加層後調用populate()時,會對android產生巨大的性能影響。 (當然,我的第一次嘗試是在添加覆蓋之後每次調用populate();由於google的教程,這是一個典型的錯誤。現在,我只需調用一次populate(),所有2500+覆蓋已添加到ItemizedOverlay。 )

所以單個populate()調用需要40秒才能在htc英雄設備上完成。我不得不提出一個繁忙的指標;沒有進度條是可能的,因爲我們無法獲得關於populate()的進度的任何信息。

我嘗試了另一種解決方案:不使用ItemizedOverlay,而是手動添加疊加層,覆蓋子類。結果:確實將所有覆蓋圖添加到地圖上要快得多;然而,由於在每個疊加層上不斷調用draw()方法,地圖變得不可用。在我的繪畫方法中,我試圖儘可能優化;我不會每次創建一個位圖。我的draw()方法是這樣的:

public void draw(android.graphics.Canvas canvas, MapView mapView, boolean shadow) { 
// our marker bitmap already includes shadow. 
// centerPoint is the geopoint where we need to put the marker. 
if (!shadow) { 
    Point point = new Point(); 
    mapView.getProjection().toPixels(centerPoint, point); 
    canvas.drawBitmap(markerBitmap, point.x, point.y, null); 
} 

} 

這裏markerBitmap預計算。我不知道還有什麼可以優化的。如果我們不使用ItemizedOverlay,是否需要某種populate()調用?我找不到任何好的答案。

現在我使用後臺線程創建的ItemizedOverlay緩存。這樣至少用戶不必每次都等待。

+0

+1的詳細解釋。 – 2012-12-05 19:03:40

+0

在Android上添加2500個標記實際上是不可能的。該項目的解決方案首先是找出當前地圖上可見的標記。 (每次在平移/縮放後都必須重新計算)。然後我們檢查是否有<100個標記,否則不需要顯示所有標記。幾百秒內就可以將100個標記添加到地圖中。所有這些當然都在後臺線程中,因此用戶在等待populate()完成時查看旋轉的圓。在iPhone上,類似的代碼是即時的(2500個標記也有點慢)。 – winitzki 2012-12-11 09:19:11

-3

可以將多個可繪製對象添加到單個疊加層,然後將其添加到地圖中。因此,除非對象類型不同,否則不需要爲x個對象繪製x個覆蓋圖。代碼片段.. .. 這裏,CustomPinPoint是我的課堂延伸ItemizedOverlay<OverlayItem>

CustomPinPoint customPinPoint = new CustomPinPoint(drawable, Main.this); 

OverlayItem tempOverLayItem = new OverlayItem(
    touchedPoint, "PinPoint", "PintPoint 2"); //Point One 
customPinPoint.insertPinPoint(tempOverLayItem); 
tempOverLayItem = new OverlayItem(new GeoPoint(
     (int)(-27.34498 * 1E6), (int)(153.00724 * 1E6)), "PinPoint", 
    "PintPoint 2"); //Point Two 
customPinPoint.insertPinPoint(tempOverLayItem); 
overlayList.add(customPinPoint); //Overlay added only once 
-2

爲了您的第4個問題....簡單地使用mapOverlays.clear();方法和所有以前的標記將會消失。

代碼:

if(!mapOverlays.isEmpty()) { 
    mapOverlays.clear(); 
    mapView.invalidate(); 
}