【问题标题】:How to create map tiles from OpenStreetMap offline, display it on Android?如何从 OpenStreetMap 离线创建地图图块,在 Android 上显示?
【发布时间】:2011-11-29 08:24:30
【问题描述】:

我想要的是使用 OpenStreetMap 显示一个简单的离线地图。我在网络上找不到合适的工具来创建地图图块并使用它在 Android 中显示地图。我已经下载了不同的资源,但似乎我不知道从哪里开始。我想使用 JOSM 集成来自 OpenStreetMap 的图像,但我不知道是否可以在 Android 上使用它。

我可以使用 Mapnik 吗?非常感谢您的帮助。

【问题讨论】:

  • 是的,您可以使用 Mapnik。但是这个问题在这里是题外话。你应该问help.openstreetmap.org
  • 我不认为这是题外话,但你在 help.openstreetmap.org 可能是更多的 OSM 专家
  • 感谢您的评论。您还有什么其他想法可以添加到该主题中吗?
  • 我能够显示地图但使用互联网“”。

标签: java android map openstreetmap


【解决方案1】:

我目前正在使用 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 中创建了一个新项目,将我的代码转储到那里,修复了一些东西并让它运行起来。我所做的所有更改都反映在上面的代码中!我忘记了几个基本的导入语句,也忘记了向 manifest.xml 文件添加权限。

manifest.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"
/>

&lt;uses-sdk ... /&gt; 部分之后添加。

另外,一定要导入以下两个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,我的代码会一直崩溃,直到我记得包含它。

确保修改默认坐标,使其指向您实际拥有地图图块的位置,否则您将看不到任何东西,除了白色画布。

对不起,我没有先运行代码!

【讨论】:

  • 您好,蒂姆爵士。你真的很棒。感谢您分享您的代码和想法。我很高兴能尝试一下。您的程序非常清晰且内容丰富。请更新您的状态先生..谢谢。
  • 我有这个错误:[2011-10-05 22:22:58 - OsmNavigator] Dx 1 错误;中止 [2011-10-05 22:22:58 - OsmNavigator] 转换为 Dalvik 格式失败,错误 1 ​​[2011-10-05 22:26:07 - YourMap] Dx UNEXPECTED TOP-LEVEL EXCEPTION: java.lang.IllegalArgumentException:已添加:Lorg/osmdroid/tileprovider/tilesource/bing/BingMapTileSource; [2011-10-05 22:26:07 - YourMap] Dx 在 com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:123) [2011-10-05 22:26:07 - YourMap] Dx at com.android.dx.dex.file.DexFile.add(DexFile.java:143)
  • 嗨,rahstam,从您发布的输出来看,您可能试图包含两个共享某些相同包和类的 JAR;换句话说,您包含的一些 JAR 文件之间存在冲突。看看这个link中的建议。
  • 当我右键单击项目 > 属性 > java 构建路径 > 库时。然后我发现我使用了 osmdroid-android-3.0.1.jar 和 osmdroid-android-3.0.5.jar 的 diff 库。我删除了 3.0.5.jar。然后我能够编译,但是当我进入模拟器屏幕时,它显示“对不起,应用程序意外运行”
【解决方案2】:

这里是一步一步的解决方案:

简而言之:

1- 您必须使用Mobile Atlas Creator 下载地图图块。我已经解释了步骤HERE

2- 将生成的 zip 文件移动到您设备上的 /mnt/sdcard/osmdroid/

3- 将osmdroid-android-XXX.jarslf4j-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" />

这是一个很好的Sample Project。 希望对您有所帮助;)

重要

正如@Scai 所说:最近Open Street Map 宣布this tool is not good 并有一些问题:

此工具会导致 OSM 磁贴服务器的流量过大,并且可能会被阻止。 请不要使用它。

【讨论】:

【解决方案3】:

除了地图图块,您还可以将矢量数据用于离线地图,例如 mapsforge 或 Mapbox Android SDK。有关offline OSMAndroid libraries 的更多信息,请参阅 OSM wiki。

【讨论】:

    猜你喜欢
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多