2012-04-05 7 views
2

Ich entwickle eine Android-App, die Osmdroid verwendet, um die Karten im Offline-Modus anzuzeigen. Ich habe ein Problem, wenn ich die Karte vergrößern oder verkleinern möchte, indem ich auf der Karte klicke oder die eingebauten Zoomsteuerelemente verwende. Wenn ich die Karte zoome, werden die Kacheln nicht immer korrekt gerendert und wenn ich die Karte ausziehe, sind manchmal graue Kacheln in der Karte, manchmal ist alles in Ordnung. Es bezieht sich nicht auf den Standort, der auf der Karte angezeigt wird. Meine Kartenkacheln werden in einer Osmdroid-Zip-Datei mit der Mapnik-Quelle im Ordner/mnt/sdcard/osmdroid gespeichert. Ich verwende osmdroid-3.0.7.Osmdroid Offline-Modus aktualisieren Kacheln nach Zoom

Also, jede Hilfe ist willkommen.

Sehen Sie meinen Code (meine beinhaltet sind hier nicht im Code enthalten):

public class MapActivity extends OSMapActivity { 

private ArrayList<String[]> mapPointData; 
private ArrayList<String[]> multiData; 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    super.setContentView(R.layout.map); 

    setABTitle(getIntent().getExtras().getStringArray("geoLoc")[0]); 
    actionButtonVisible(getIntent().getExtras().getBoolean("routeList")); 

    initLayout(); 
    setHomePoint(); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    Prefs.clearMapPrefs(this); 
} 

private void initLayout() { 

    c = this; 
    // Buttons @ top of the activity 
    doseeBN = (ImageView) findViewById(R.id.mapDoseeBN); 
    eatdrinkBN = (ImageView) findViewById(R.id.mapEatdrinkBN); 
    nightlifeBN = (ImageView) findViewById(R.id.mapNightlifeBN); 
    sleepBN = (ImageView) findViewById(R.id.mapSleepBN); 

    // The LinearLayout with the ScrollView for the Subcategories in "Do & See" 
    doseeLL = (LinearLayout) findViewById(R.id.doseeSubCatLL); 
    top10BN = (Button) findViewById(R.id.mapDoseeTop10BN); 
    monumentsBN = (Button) findViewById(R.id.mapDoseeMonumentsBN); 
    museumBN = (Button) findViewById(R.id.mapDoseeMuseumsBN); 
    cultureBN = (Button) findViewById(R.id.mapDoseeCultureBN); 
    attractionsBN = (Button) findViewById(R.id.mapDoseeAttractionBN); 
    shoppingBN = (Button) findViewById(R.id.mapDoseeShoppingBN); 
    marketBN = (Button) findViewById(R.id.mapDoseeMarketBN); 

    // Init of the map an mapcontroller 
    mapView = (MapView) findViewById(R.id.osmMV); 
    mapView.setTileSource(TileSourceFactory.MAPNIK); 
    mapController = mapView.getController(); 
    mapController.setZoom(16); 
    mapView.setUseDataConnection(false); 

    mapView.setBuiltInZoomControls(true); 
    mapView.setMultiTouchControls(true); 
    // mapView.setDrawingCacheEnabled(true); 


    mapData = new ArrayList<String[]>(); 
    mapPointData = new ArrayList<String[]>(); 
    multiData = new ArrayList<String[]>(); 
} 

private void setHomePoint() { 
    //GeoPoint centerPt = new GeoPoint(50.89489, 4.34140); // Point of Grand Place Brussels 

    homeLat = Double.parseDouble(getIntent().getExtras().getStringArray("geoLoc")[1]); 
    homeLong = Double.parseDouble(getIntent().getExtras().getStringArray("geoLoc")[2]); 

    GeoPoint centerPt = new GeoPoint(homeLat, homeLong); 

    if (checkMapRange(Double.parseDouble(getIntent().getExtras().getStringArray("geoLoc")[1]), 
      Double.parseDouble(getIntent().getExtras().getStringArray("geoLoc")[2]))) { 
     mapController.setCenter(centerPt); 

     Drawable marker = getResources().getDrawable(R.drawable.ic_pin_marker); 

     ArrayList<OverlayItem> items = new ArrayList<OverlayItem>(); 
     items.add(new OverlayItem("Here I am!", "Hello", centerPt)); 
     ItemizedOverlay<OverlayItem> itemOverlay = 
           new ItemizedIconOverlay<OverlayItem>(items, marker, null, new DefaultResourceProxyImpl(this)); 
     mapView.getOverlays().add(itemOverlay); 
     mapView.invalidate(); 
    } else { 
     mapController.setCenter(new GeoPoint(50.89489, 4.34140)); 
     mapController.setZoom(11); 
     Action.alert(this, getResources().getString(R.string.alert_title_notinregion), 
       getResources().getString(R.string.alert_message_notinregion), false); 
     mapView.setClickable(false); 
    } 
} 

public void onClickMapPointsBN(View v) { 

    switch(v.getId()) { 
    case R.id.mapDoseeBN: 
     setPrefsCategory("DOSEE", doseeBN, "btn_map_dosee", "btn_map_dosee_pressed"); 
     break; 
    case R.id.mapEatdrinkBN: 
     setPrefsCategory("EATDRINK", eatdrinkBN, "btn_map_eatdrink", "btn_map_eatdrink_pressed"); 
     break; 
    case R.id.mapNightlifeBN: 
     setPrefsCategory("NIGHTLIFE", nightlifeBN, "btn_map_nightlife", "btn_map_nightlife_pressed"); 
     break; 
    case R.id.mapSleepBN: 
     setPrefsCategory("SLEEP", sleepBN, "btn_map_sleep", "btn_map_sleep_pressed"); 
     break; 
    } 

    setPOIs(); 
} 

public void onClickDoseeListBN(View v) { 
    switch (v.getId()) { 
    case R.id.mapDoseeTop10BN: 
     setDosseSubCat(Definitions.doseeList[0], top10BN); 
     break; 
    case R.id.mapDoseeMuseumsBN: 
     setDosseSubCat(Definitions.doseeList[2], museumBN); 
     break; 
    case R.id.mapDoseeCultureBN: 
     setDosseSubCat(Definitions.doseeList[3], cultureBN); 
     break; 
    case R.id.mapDoseeAttractionBN: 
     setDosseSubCat(Definitions.doseeList[4], attractionsBN); 
     break; 
    case R.id.mapDoseeShoppingBN: 
     setDosseSubCat(Definitions.doseeList[5], shoppingBN); 
     break; 
    case R.id.mapDoseeMarketBN: 
     setDosseSubCat(Definitions.doseeList[6], marketBN); 
     break; 
    default: 
     setDosseSubCat(Definitions.doseeList[1], monumentsBN); 
     break; 
    } 

    setPOIs(); 
} 

private void setPrefsCategory(String cat, ImageView btn, String image, String imageSelected) { 
    boolean sel = Prefs.getBoolean(this, "map" + cat, false); 

    Prefs.setBoolean(this, "map" + cat, !sel); 
    setCategoryImage(btn, image, imageSelected, sel); 

    if (cat.equalsIgnoreCase("DOSEE")) { 
     if (sel) { 
      doseeLL.setVisibility(View.GONE); 
     } else { 
      doseeLL.setVisibility(View.VISIBLE); 

      for (String s : Definitions.doseeList) { 
       if (s.equals(Definitions.doseeList[1])) { 
        Prefs.setBoolean(this, "mapDS_" + s, true); 
       } else { 
        Prefs.setBoolean(this, "mapDS_" + s, false); 
       } 
      } 
     } 

     setSubcategoryColor(sel); 
    } 
} 

private void setCategoryImage(ImageView btn, String image, String imageSelected, boolean selected) { 
    String devLang = Prefs.getString(this, "devLanguage", "en"); 

    if (!devLang.equalsIgnoreCase("en")) { 
     image += "_" + devLang; 
     imageSelected += "_" + devLang; 
    } 

    if (selected) { 
     btn.setImageResource(this.getResources().getIdentifier(image, "drawable", getPackageName())); 
    } else { 
     btn.setImageResource(this.getResources().getIdentifier(imageSelected, "drawable", getPackageName())); 
    } 
} 

private void setSubcategoryColor(boolean doseeSelected) { 
    setDoseeSubCatTextColor(true, top10BN); 
    setDoseeSubCatTextColor(doseeSelected, monumentsBN); 
    setDoseeSubCatTextColor(true, museumBN); 
    setDoseeSubCatTextColor(true, cultureBN); 
    setDoseeSubCatTextColor(true, attractionsBN); 
    setDoseeSubCatTextColor(true, shoppingBN); 
    setDoseeSubCatTextColor(true, marketBN); 
} 

private void setPOIs() { 
    mapView.getOverlays().clear(); 
    mapView.invalidate(); 
    mapData.clear(); 

    setHomePoint(); 

    boolean selected; 

    for (String category : Definitions.categoryList) { 
     selected = Prefs.getBoolean(this, "map" + category, false); 

     Log.d("VB.Map", "Category: " + category + " selected: " + selected); 
     if (selected) { 
      if (category.equalsIgnoreCase("DOSEE")) { 
       boolean subSelected; 

       for (String subcategory : Definitions.doseeList) { 
        subSelected = Prefs.getBoolean(this, "mapDS_" + subcategory, false); 

        if (subSelected) { 
         getSqlData(category, subcategory); 
        } 
       } 
      } else { 
       getSqlData(category, null); 
      } 
     } 
    } 

    removeMapDataItems(); 
    //mapPointData = mapData; 
    //multiDataLocationSelector(); 
    setMapDataPoints(); 
    //setMultiMapPoints(); 
} 

private void getSqlData(String category, String subCategory) { 
    ArrayList<String[]> sqlData = SqlDB.db.getCategoryItems(Adjust.rewriteCategoryName(category), subCategory); 

    for (String[] data : sqlData) { 
     mapData.add(data); 
    } 
} 

private void removeMapDataItems() { 
    for (int i = 0; i < mapData.size(); i++) { 
     if ((mapData.get(i)[13].equalsIgnoreCase("")) || (mapData.get(i)[14].equalsIgnoreCase(""))) { 
      mapData.remove(i); 
      i--; 
     } 
    } 
} 

private void setDosseSubCat(String subCat, Button btn) { 
    boolean selected = Prefs.getBoolean(this, "mapDS_" + subCat, false); 

    Prefs.setBoolean(this, "mapDS_" + subCat, !selected); 

    setDoseeSubCatTextColor(selected, btn); 
} 

private void setDoseeSubCatTextColor(boolean selected, Button btn) { 
    if (selected) { 
     btn.setTextColor(Definitions.colorDoseeSubcat); 
    } else { 
     btn.setTextColor(Definitions.colorDoseeSubcatSelected); 
    } 
} 

private void setMapDataPoints() { 
    if (mapData != null) { 
     ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>(); 
     OverlayItem overlayItem; 

     for (String[] item : mapData) { 
      multiData.add(item); 
      if (existsInOverlayItems(item, mapOverlays)) { 
       overlayItem = new OverlayItem("-1", "", new GeoPoint(Float.parseFloat(item[13]), Float.parseFloat(item[14]))); 
       overlayItem.setMarker(getResources().getDrawable(R.drawable.ic_pin_multiple)); 
      } else { 
       overlayItem = new OverlayItem(item[0], "", new GeoPoint(Float.parseFloat(item[13]), Float.parseFloat(item[14]))); 
       overlayItem.setMarker(getResources().getDrawable(getResources().getIdentifier(item[15], "drawable", getPackageName()))); 
      } 

      mapOverlays.add(overlayItem); 
     } 

     setMapOverlays(mapOverlays); 
    } 
} 

private boolean existsInOverlayItems(String[] item, ArrayList<OverlayItem> overlayItemList) { 
    for (int i = 0; i < overlayItemList.size(); i++) { 
     if ((new GeoPoint(Double.parseDouble(item[13]), Double.parseDouble(item[14]))).equals(overlayItemList.get(i).mGeoPoint)) { 
      overlayItemList.remove(i); 
      return true; 
     } 
    } 

    return false; 
} 

private void setMapOverlays(ArrayList<OverlayItem> overlays) { 
    ItemizedOverlay<OverlayItem> itemOverlays = new ItemizedIconOverlay<OverlayItem>(
      overlays, getResources().getDrawable(R.drawable.ic_pin_marker), new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() { 

     public boolean onItemLongPress(int arg0, OverlayItem item) { 
      mapOverlayItemPressed(Integer.parseInt(item.mTitle), item); 
      return false; 
     } 

     public boolean onItemSingleTapUp(int arg0, OverlayItem item) { 
      mapOverlayItemPressed(Integer.parseInt(item.mTitle), item); 
      return false; 
     } 
    }, new DefaultResourceProxyImpl(this)); 


    mapView.getOverlays().add(itemOverlays); 

    mapView.invalidate(); 
} 

private void mapOverlayItemPressed(int itemId, OverlayItem overlayItem) { 
    if (itemId == -1) { 
     Collect.multiPOIList.clear(); 

     for (String[] item : multiData) { 
      if ((new GeoPoint(Double.parseDouble(item[13]), Double.parseDouble(item[14]))).equals(overlayItem.mGeoPoint)) { 
       Collect.multiPOIList.add(item); 
      } 
     } 

     Action.alertWithListView(this, getResources().getString(R.string.alert_title_multiplepoi), false); 

    } else { 
     SqlDB.db.getItemsById(itemId); 

     Bundle b = new Bundle(); 
     b.putInt("listSelection", 0); 

     Action.newIntent(c, DetailActivity.class, b); 
    } 
} 

private boolean checkMapRange(double lat, double lng) { 
    double mapLatMax = 50.922085; 
    double mapLatMin = 50.781631; 
    double mapLongMin = 4.240723; 
    double mapLongMax = 4.490662; 

    if ((lat > mapLatMin) && (lat < mapLatMax)) { 
     if ((lng > mapLongMin) && (lng < mapLongMax)) { 
      return true; 
     } 
    } 
    return false; 
} 

}

Und hier der Code des OSMapActivity:

public class OSMapActivity extends ActionbarActivity { 

protected Context c; 

protected MapView mapView; 
protected MapController mapController; 
protected ArrayList<String[]> mapData; 

protected ImageView doseeBN; 
protected ImageView eatdrinkBN; 
protected ImageView nightlifeBN; 
protected ImageView sleepBN; 
protected LinearLayout doseeLL; 

protected Button top10BN; 
protected Button monumentsBN; 
protected Button museumBN; 
protected Button cultureBN; 
protected Button attractionsBN; 
protected Button shoppingBN; 
protected Button marketBN; 

protected double homeLat; 
protected double homeLong; 

public void onClickABActionButton(View v) { 
    boolean actionButton = Prefs.getBoolean(this, "abActionButtonRoute", false); 

    if (actionButton) { 
     // TODO Add with current location => location manager in separate class 
     /*GPS.init(this); 
     GPS.enableGPSProvider(); 
     GPS.enableNetworkProvider(); 
     //Action.loadApp(this, Intent.ACTION_VIEW, Uri.parse("geo:50.89489,4.34140?daddr=Heiveld+21+Opwijk")); 
     Action.loadApp(this, Intent.ACTION_VIEW, Uri.parse("http://maps.google.com/maps?saddr=" + GPS.latitude + "," + GPS.longitude 
                  + "&daddr=Heiveld+21+1745+Opwijk")); 
     GPS.stop();*/ 
     Action.loadMapsWithMyLocation(this, homeLat, homeLong); 
    } else { 
     Collect.dbList.clear(); 

     for (String[] data : mapData) { 
      Collect.dbList.add(data); 
     } 

     // TODO Load new intent with list 
     Action.newIntent(this, MapListActivity.class, null); 

    } 
} 

}

Danke für Ihre Hilfe.

Kr

Antwort

3

Ich hob eine issue auf Version 3.0.6 darüber. In den Kommentaren sagen die Autoren, dass es am 1. Februar festgelegt wurde. Da das 3.0.7-Glas vom 29. Januar datiert wird, nehme ich an, dass der Fix nicht darin enthalten ist. Ich bleibe mit Version 3.0.5 für jetzt, obwohl die Zykluskarten nicht darin arbeiten und das Laden der Fliese ein wenig flickerig sein kann. Wenn Ihre Karten jedoch offline sind, sollten sie ziemlich schnell geladen werden und Flimmern ist möglicherweise kein Problem.

+1

Vielen Dank für Ihre sehr hilfreiche Antwort. Ich habe die Osmdroid-API mit Version 3.0.5 ersetzt und jetzt funktioniert es gut. Vielleicht ein bisschen Flickern, aber es stört nicht in meiner App. Ich habe dem Osmdroid-Team erneut einen Fehler in der Version 3.0.7 gemeldet. Also, vielen Dank! –

1

Ich bin nicht 100% sicher, ob dies das gleiche Problem wie hier berichtet:

OSMDroid Google Group

Wenn ja, dann die Lösung (vorerst) die aktuelle OSMDroid Quelle zu sein scheint zum Herunterladen und bauen Ihre eigene .jar-Bibliothek. Es sind keine Änderungen an der Quelle erforderlich, aber das Problem beim Laden der Kacheln ist behoben.

+1

Danke für den Link, aber der Aufbau der neuesten osmdroid 4.2 hilft nicht. Ich denke, es ist das von @NickT erwähnte Problem, und es ist immer noch ungelöst (( – Mixaz

Verwandte Themen