我正在开发一款使用Osmdroid在离线模式下显示地图的Android应用。当我想通过捏在地图上或使用内置zoomcontrol来放大或缩小时,我遇到了问题。当我放大地图时,地图拼贴并不总是正确渲染,当我缩小时,地图中有时会出现一些灰色拼贴,有时一切都会渲染好。它与地图上显示的位置无关。我的地图图块存储在osmdroid zip文件中,Mapnik源文件夹位于文件夹/ mnt / sdcard / osmdroid中。我使用的是osmdroid-3.0.7。
所以,欢迎任何帮助。
请参阅下面的代码(我的代码中未包含此代码):
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;
}
}
这里是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);
}
}
}
感谢您的帮助。
氪
答案 0 :(得分:3)
我在3.0.6版本上提出了issue。在评论中,作者说这是在2月1日修复的。由于3.0.7 jar是在1月29日,我认为修复不在其中。我现在坚持使用3.0.5版本,虽然循环图在它中不起作用,并且图块加载可能有点闪烁。如果您的地图离线,它们应该加载非常快,闪烁可能不是问题。
答案 1 :(得分:1)
我不能100%确定这是否与此处报告的问题相同:
如果是这样,那么解决方案(现在)似乎是下载当前的OSMDroid源并构建您自己的.jar库。 不需要更改源,但瓷砖加载问题是固定的。