简体   繁体   English

如何从 OpenStreetMap 离线创建地图图块,并在 Android 上显示?

[英]How to create map tiles from OpenStreetMap offline, display it on Android?

What I want is to display a simple offline map using OpenStreetMap.我想要的是使用 OpenStreetMap 显示一个简单的离线地图。 I cannot find in the web the right tools to create map tiles and use it to display a map in Android.我在网络上找不到创建地图图块并使用它在 Android 中显示地图的正确工具。 I have downloaded different resources but it seems that I don't have any idea where to start.我下载了不同的资源,但似乎我不知道从哪里开始。 I want to integrate images from OpenStreetMap using JOSM but i don't know if I can use it on Android.我想使用 JOSM 集成来自 OpenStreetMap 的图像,但我不知道我是否可以在 Android 上使用它。

Can I use Mapnik?我可以使用 Mapnik 吗? Your help will a great thank you.您的帮助将不胜感激。

I'm currently developing (my first) Android application using the OpenStreetMap (OSM) API, so while I can't help you with the JSOM, I can try to help with the OSM part:我目前正在使用 OpenStreetMap (OSM) API 开发(我的第一个)Android 应用程序,所以虽然我无法帮助您处理 JSOM,但我可以尝试帮助处理 OSM 部分:

Assuming that you want to create a new activity in your android application that simply displays a OSM map, you might start with something like this:假设您想在您的 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

Where your osm_map.xml layout may look something like this:您的 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>

As for the actual map tiles, there is a really cool program called Mobile Atlas Creator , which allows you to generate the necessary map tiles for the offline Android map implemented above.至于实际的地图图块,有一个非常酷的程序叫做Mobile Atlas Creator ,它允许您为上面实现的离线 Android 地图生成必要的地图图块。

Once you have the application installed, and you want to create a new atlas, you'll be asked to select your "desired altas format."安装应用程序后,如果您想创建新的地图集,系统会要求您选择“所需的 Altas 格式”。 When this pops up, select "Osmdroid zip."当它弹出时,选择“Osmdroid zip”。

Once everything loads, select a region on the map that you would like to create tiles for, select the zoom levels you want tiles for, and hit the "Add Selection" button in the column on the left, followed by "Create Atlas."加载完所有内容后,在地图上选择要为其创建图块的区域,选择要为其创建图块的缩放级别,然后点击左侧列中的“添加选择”按钮,然后点击“创建图集”。

Oh, and depending on the source, you may need to check the "Create/Adjust Map tiles" checkbox to force the tiles to be exported as PNGs -- does anyone know if it's possible to use JPG with OSM?哦,根据来源,您可能需要选中“创建/调整地图图块”复选框以强制将图块导出为 PNG - 有谁知道是否可以将 JPG 与 OSM 一起使用?

Once the ZIP has been generated, I renamed it to "Mapnik.zip" and moved it to a newly created folder called "tiles" in my Eclipse Android project workspace.生成 ZIP 后,我将其重命名为“Mapnik.zip”并将其移动到我的 Eclipse Android 项目工作区中新创建的名为“tiles”的文件夹中。 In order to get it working, I also had to open the zip file, and rename the top level folder from something like "Google Earth" (depending on the map source you used), to "Mapnik," in order for the tile to display in my Android application.为了让它正常工作,我还必须打开 zip 文件,并将顶级文件夹从“Google Earth”(取决于您使用的地图源)之类的名称重命名为“Mapnik”,以便磁贴显示在我的 Android 应用程序中。

In order to actually load the tiles onto your phone, however, you'll need to use the ADB tool from the terminal.但是,为了将磁贴实际加载到您的手机上,您需要从终端使用 ADB 工具。 In your ADB tool directory, you'll want to run something like this (each line is a new command):在您的 ADB 工具目录中,您需要运行如下内容(每一行都是一个新命令):

./adb shell rm -r /sdcard/osmdroid/
./adb shell mkdir /sdcard/osmdroi/
./adb push ~/path/to/your/mapnik.zip /sdcard/osmdroid

Depending on the size of the map and the speed of the phone's memory bus, this last step may take a several minutes to an hour to complete.根据地图的大小和手机内存总线的速度,这最后一步可能需要几分钟到一个小时才能完成。 Once done, your map should work -- I hope!完成后,您的地图应该可以工作了——我希望!

As I mentioned, this is the first time I've used the OSM API, so I'm by no means an expert on it, and I can only comment on what worked for me.正如我所提到的,这是我第一次使用 OSM API,所以我绝不是这方面的专家,我只能评论对我有用的东西。

Hope this will help you get started!希望这能帮助您入门!

EDIT:编辑:

I didn't have a chance to actually run the code that I wrote up yesterday, so I didn't catch a few of the errors.我没有机会实际运行我昨天编写的代码,所以我没有发现一些错误。 I just created a new project in Eclipse, dumped my code in there, fixed a few things and got it up and running.我刚刚在 Eclipse 中创建了一个新项目,将我的代码转储到其中,修复了一些问题并使其启动并运行。 All changes that I made are reflected in the code above!我所做的所有更改都反映在上面的代码中! I forgot several of the basic import statements, and I forgot to add permissions to the manifest.xml file.我忘记了几个基本的导入语句,也忘记向 manifest.xml 文件添加权限。

The last few lines of my manifest.xml now look like this:我的 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>

And you also might want to add this to the manifest, although certainly not critical:而且您可能还想将其添加到清单中,尽管肯定不是关键:

<supports-screens 
    android:anyDensity="true"
    android:resizeable="false"
    android:largeScreens="true"
    android:normalScreens="true"
/>

Add this right after the <uses-sdk ... /> part.<uses-sdk ... />部分之后添加它。

Furthermore, be sure to import the following two JAR libraries:此外,请务必导入以下两个 JAR 库:

osmdroid-android-3.0.3.jar // Or whatever version you're using...

and

slf4j-android-1.5.8.jar // Or whatever the latest version is...

Without this last JAR, my code kept crashing until I remembered to include it.没有这个最后一个 JAR,我的代码一直崩溃,直到我记得要包含它。

Make sure to modify the default coordinates so that they point to a location that you actually have map tiles for, otherwise you're not going to see much of anything, aside from a white canvas.确保修改默认坐标,使它们指向您实际拥有地图图块的位置,否则除了白色画布之外,您将看不到任何东西。

Sorry for not running the code on my end first!抱歉没有先在我这边运行代码!

Here is a step by step solution:这是一个分步解决方案:

In brief:简单来说:

1- You must download map tiles using Mobile Atlas Creator . 1- 您必须使用Mobile Atlas Creator下载地图图块。 I have explained the steps HERE我已经解释了这里的步骤

2- Move the resulting zip-file to /mnt/sdcard/osmdroid/ on your device. 2- 将生成的 zip 文件移动到设备上的/mnt/sdcard/osmdroid/

3- Adding osmdroid-android-XXX.jar and slf4j-android-1.5.8.jar into build path your project 3- 将osmdroid-android-XXX.jarslf4j-android-1.5.8.jar 添加到您的项目的构建路径中

4- Adding MapView: You can add a MapView to your xml layout 4- 添加 MapView:您可以将 MapView 添加到您的 xml 布局

<org.osmdroid.views.MapView
    android:id="@+id/mapview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tilesource="Mapnik"
    />

Or create a MapView programmatically:或者以编程方式创建一个 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;
}

Don't forget to add these permissions to your Manifest:不要忘记将这些权限添加到您的清单中:

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

This is a good Sample Project .这是一个很好的示例项目 Hope it Helps ;)希望能帮助到你 ;)

Important重要的

As @Scai mentioned: recently Open Street Map announced that this tool is not good and had some problems:正如@Scai 提到的:最近 Open Street Map 宣布这个工具不好并且有一些问题:

This tool results in heavy traffic for the OSM tile servers and is likely to be blocked.此工具会导致 OSM 磁贴服务器的大量流量,并且可能会被阻止。 Please don't use it.请不要使用它。

Alternatively to map tiles you can also use vector data for your offline map, for example mapsforge or the Mapbox Android SDK.除了地图图块,您还可以为离线地图使用矢量数据,例如 mapsforge 或 Mapbox Android SDK。 For more information consult the OSM wiki about offline OSM and Android libraries .有关更多信息,请参阅 OSM wiki 关于离线 OSMAndroid 库

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM