如何离线从OpenStreetMap创建地图图块,并在Android上显示?
我想要的是使用OpenStreetMap显示一个简单的离线地图。我无法在网络中找到合适的工具来创建地图图块并使用它来在Android中显示地图。我已经下载了不同的资源,但似乎我不知道从哪里开始。我想使用JOSM集成OpenStreetMap中的图像,但我不知道我是否可以在Android上使用它。
我可以使用Mapnik吗?您的帮助将非常感谢您。
我想要的是使用OpenStreetMap显示一个简单的离线地图。我无法在网络中找到合适的工具来创建地图图块并使用它来在Android中显示地图。我已经下载了不同的资源,但似乎我不知道从哪里开始。我想使用JOSM集成OpenStreetMap中的图像,但我不知道我是否可以在Android上使用它。
我可以使用Mapnik吗?您的帮助将非常感谢您。
我目前正在使用OpenStreetMap(OSM)API开发(我的第一个)Android应用程序,所以虽然我无法在JSOM方面为您提供帮助,但我可以尝试在OSM部分提供帮助:
假设您要在 Android 应用程序中创建一个仅显示 OSM 映射的新活动,则可以从如下所示的内容开始:
package example.stackoverflow.osmdroid;
import android.app.Activity;
import android.os.Bundle;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
public class YourMap extends Activity {
// The MapView variable:
private MapView m_mapView;
// Default map zoom level:
private int MAP_DEFAULT_ZOOM = 15;
// Default map Latitude:
private double MAP_DEFAULT_LATITUDE = 38.535350;
// Default map Longitude:
private double MAP_DEFAULT_LONGITUDE = -121.753807;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Specify the XML layout to use:
setContentView(R.layout.osm_map);
// Find the MapView controller in that layout:
m_mapView = (MapView) findViewById(R.id.mapview);
// Setup the mapView controller:
m_mapView.setBuiltInZoomControls(true);
m_mapView.setMultiTouchControls(true);
m_mapView.setClickable(true);
m_mapView.setUseDataConnection(false);
m_mapView.getController().setZoom(MAP_DEFAULT_ZOOM);
m_mapView.getController().setCenter(
new GeoPoint(MAP_DEFAULT_LATITUDE, MAP_DEFAULT_LONGITUDE));
m_mapView.setTileSource(TileSourceFactory.MAPNIK);
} // end onCreate()
} // end class YourMap
您的osm_map.xml布局可能如下所示:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.osmdroid.views.MapView
android:id="@+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:enabled="true"
android:clickable="true"
/>
</RelativeLayout>
至于实际的地图图块,有一个非常酷的程序叫做Mobile Atlas Creator,它允许你为上面实现的离线Android地图生成必要的地图图块。
安装应用程序并希望创建新的地图集后,系统将要求您选择“所需的altas格式”。弹出此窗口时,选择“Osmdroid zip”。
加载所有内容后,在地图上选择要为其创建切片的区域,选择要为其创建切片的缩放级别,然后点击左侧列中的“添加选择”按钮,然后单击“创建图集”。
哦,根据来源的不同,您可能需要选中“创建/调整地图图块”复选框以强制将图块导出为PNG - 有谁知道是否可以将JPG与OSM一起使用?
生成 ZIP 后,我将其重命名为“Mapnik.zip”,并将其移动到 Eclipse Android 项目工作区中新创建的名为“tiles”的文件夹中。为了让它正常工作,我还必须打开zip文件,并将顶级文件夹从“Google Earth”(取决于您使用的地图源)重命名为“Mapnik”,以便瓷砖在我的Android应用程序中显示。
但是,为了将磁贴实际加载到手机上,您需要从终端使用ADB工具。在 ADB 工具目录中,您需要运行如下操作(每行都是一个新命令):
./adb shell rm -r /sdcard/osmdroid/
./adb shell mkdir /sdcard/osmdroi/
./adb push ~/path/to/your/mapnik.zip /sdcard/osmdroid
根据地图的大小和手机内存总线的速度,最后一步可能需要几分钟到一个小时才能完成。一旦完成,你的地图应该可以工作了 - 我希望!
正如我所提到的,这是我第一次使用OSM API,所以我绝不是这方面的专家,我只能评论什么对我有用。
希望这将有助于您入门!
编辑:
我没有机会实际运行我昨天编写的代码,所以我没有发现一些错误。我刚刚在Eclipse中创建了一个新项目,将我的代码转储到那里,修复了一些问题,然后启动并运行了它。我所做的所有更改都反映在上面的代码中!我忘记了几个基本的导入语句,并且忘记了向清单.xml文件添加权限。
我的清单的最后几行.xml现在看起来像这样:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
您可能还希望将其添加到清单中,尽管肯定不重要:
<supports-screens
android:anyDensity="true"
android:resizeable="false"
android:largeScreens="true"
android:normalScreens="true"
/>
在部件之后添加此内容。<uses-sdk ... />
此外,请务必导入以下两个 JAR 库:
osmdroid-android-3.0.3.jar // Or whatever version you're using...
和
slf4j-android-1.5.8.jar // Or whatever the latest version is...
没有最后一个JAR,我的代码一直在崩溃,直到我记得包含它。
确保修改默认坐标,使其指向您实际具有地图切片的位置,否则除了白色画布之外,您不会看到太多内容。
很抱歉没有先在我这边运行代码!
以下是分步解决方案:
简言之:
1-您必须使用移动地图集创建器下载地图切片。我已经在这里解释了步骤
2-将生成的zip文件移动到设备上。/mnt/sdcard/osmdroid/
3-将osmdroid-android-XXX.jar和slf4j-android-1.5.8.jar添加到项目的构建路径中
4-添加MapView:您可以将MapView添加到xml布局中
<org.osmdroid.views.MapView
android:id="@+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
tilesource="Mapnik"
/>
或者以编程方式创建 MapView:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
mResourceProxy = new ResourceProxyImpl(inflater.getContext().getApplicationContext());
mMapView = new MapView(inflater.getContext(), 256, mResourceProxy);
return mMapView;
}
不要忘记将这些权限添加到清单:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
这是一个很好的示例项目。希望它能;)
重要
正如@Scai提到的:最近Open Street Map宣布这个工具不好,并且有一些问题:
此工具会导致 OSM 切片服务器的流量过大,并且可能会被阻止。请不要使用它。