2012-12-18 27 views
1

繪製我有從JSON對象創建一個path()。我將JSON對象傳遞給構造函數中的覆蓋對象。Android地圖,在疊加構造

延伸Overlay的對象在任何時候地圖移動,渲染,觸及任何事物時總是調用draw()。即使您的疊加層不可見或附近或任何東西。

我想在for循環中生成我的路徑對象,實際上是一個嵌套循環,因爲json對象包含嵌套的json數組。這具有很高的理論計算時間,所以我不想在draw()方法中做到這一點。相反,我試圖做的邏輯在我的構造,使path()文件,然後調用路徑文件只有一次在draw()方法,其中在這裏需要canvas.drawPath(path, mPaint);

不幸的是,當我在構造函數創建我的道路,它不與地圖平移。但是,當我創建它,完全相同的代碼,在draw()方法,它確實有期望的功能:即圍欄的地圖的一部分的路徑。

問題是draw()方法會一遍又一遍地調用我的double for循環,並且性能下降是顯而易見的並且使人虛弱。即使將draw()中的循環放入new Thread()也無助於性能。在構造函數中運行它將是理想的,但路徑不會隨地圖平移。

類似地在draw()方法內使用一個私有布爾轉換,以使所需的代碼只運行,也不起作用。該路徑將不會出現在地圖上,除非它不斷重繪,這是一項任務過於繁重。

本網站有關此問題的其他解答的問題是,人們正在製作正方形,圓形和圖像,它們只需要在draw()之內調用一次,而不是生成路徑的循環。

意見建議?一些關於draw()方法有助於覆蓋堅持地圖,我怎麼能運行我的for循環只有一次

回答

2

一些注意事項你:

  1. 你不應該重寫draw()方法。 Overlay類已經爲您完成整個平移操作。閱讀您將找到它的文檔。

  2. 新的API使用起來更容易幾千倍。用一個簡單的代碼,如:

    PolylineOptions p = new new PolylineOptions().width(3).color(0xFFEE8888); 
    for(//... first for ....){ 
        for(// .... how many you'll need to nest...){ 
         // compute your JSON and get lat/long pair 
         p.add(new LatLng(lat, lon)); 
        } 
    } 
    getMap().addPolyline(p); 
    

,讓地圖類處理的平移和縮放。

+0

我沒有意識到新的api,它是否與薑餅向後兼容? – CQM

+0

你有沒有針對當前api的解決方案?我沒有使用片段,也不想疏遠開放的gl 1.1用戶,並且不希望切換我管理API密鑰的方式,因爲我的編譯腳本也必須更改 – CQM

+0

要繼續使用舊的API,請閱讀1 – Budius

0

雖然您已經接受了答案,但我在這裏採用了這種方法。在下面的示例代碼中,我使用舊的MapView,但該概念應該可以在任何版本中使用。我也使用它與mapforges(與最小的調整)。

概念,你path在第一draw()號召,點的記錄位置(0)旁邊draw()如果點(0)的位置改變

  • ,地圖移動

    • 生成。在繪製之前用相同的值偏移「路徑」。
    • 如果縮放更改,請重新創建path對象。

    性能

    隨着在介質範圍裝置的10.000個路徑大約需要每2 ms緩存draw()呼叫。當路徑需要重建時(當縮放變化時)大約需要80 ms

    在cource中,您還可以緩存不同的路徑縮放級別,通過更多內存交易更多的性能。

    示例代碼

    拉伸()方法僅當有一個變焦改變(如果這樣要求的路徑是重建),並且如果地圖已經移動(如果這樣的偏移路徑)和最後得出的檢查路徑。

    @Override 
    public void draw(Canvas canvas, MapView mapview, boolean shadow) { 
        super.draw(canvas, mapview, shadow); 
        if(shadow) return; 
        if(mp.getPoints() == null || mp.getPoints().size() < 2) return; 
    
        Projection projection = mapview.getProjection(); 
        int lonSpanNew = projection.fromPixels(0,mapview.getHeight()/2).getLongitudeE6() - 
          projection.fromPixels(mapview.getWidth(),mapview.getHeight()/2).getLongitudeE6(); 
        if(lonSpanNew != pathInitialLonSpan) 
         pathBuild(); 
        else{ //check if path need to be offset 
         projection.toPixels(mp.getPoints().get(0), p1); 
         if(p1.x != pathInitialPoint.x || p1.y != pathInitialPoint.y){ 
          path.offset(p1.x - pathInitialPoint.x, p1.y - pathInitialPoint.y); 
          pathInitialPoint.x = p1.x; 
          pathInitialPoint.y = p1.y; 
         } 
    
        } 
        canvas.drawPath(path, paint); 
    } 
    

    每次縮放更改時都必須構建路徑。縮放更改檢測使用pathInitialLonSpan完成,因爲getZoomLevel()與地圖縮放動畫不同步。

    private void pathBuild(){ 
        path.rewind(); 
        if(mp.getPoints() == null || mp.getPoints().size() < 2) return; 
    
        Projection projection = mapView.getProjection(); 
        pathInitialLonSpan = projection.fromPixels(0,mapView.getHeight()/2).getLongitudeE6() - 
          projection.fromPixels(mapView.getWidth(),mapView.getHeight()/2).getLongitudeE6(); 
    
        projection.toPixels(mp.getPoints().get(0), pathInitialPoint); 
        path.moveTo(pathInitialPoint.x,pathInitialPoint.y); 
    
        for(int i=1; i<mp.getPoints().size(); i++){ 
         projection.toPixels(mp.getPoints().get(i), p1); 
         int distance2 = (pPrev.x - p1.x) * (pPrev.x - p1.x) + (pPrev.y - p1.y) * (pPrev.y - p1.y); 
         if(distance2 > 9){ 
          path.lineTo(p1.x,p1.y); 
          pPrev.set(p1.x, p1.y); 
         } 
        } 
    

    問候。