注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

姑射道人的博客

博客新地址:nixuchen.com

 
 
 

日志

 
 

osmdroid 的使用  

2013-04-08 16:12:00|  分类: android |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

For my EnschedeLocator app, I wanted the users to be able to store an offline map on the device and see it while navigating to their destinations. In our BeerFinder project at NTNU last year, we were able to do this using Nutiteq’s android library, but poor documentation lead me to looking for other solutions. I discoveredOSMDroid which is a library that aims to be an opensource alternative to Google MapView in Android.

Below, I will outline how I did it and how I solved some small obstacles i encountered. Note that there may be other and better ways of doing this, but this is what worked for me.

Tools needed

  • Eclipse with Android SDK (assuming you know the basics here).
  • Mobile Atlas Creator, for preparing map tiles.
  • OSMDroid library, available here. I used osmdroid-android-3.0.7.jar.
  • SLF4J Android library, available here. I used slf4j-android-1.5.8.jar. Without this library I got a NoClassDefFoundError when trying to run the app. Adding this library somehow fixed it [source].

Preparing the map

To download the map tiles I used Mobile Atlas Creator.

My steps were as follows, most settings are done in the options pane to the left of the map:

  1. Set atlas format to Osmdroid ZIP [Atlas - Convert Atlas Format].
  2. Set your map area coordinates, either by clicking and dragging on the map, or by setting min and max coordinates in the coordinate selection pane to the left.
  3. Set map source to OpenStreetMap Mapnik. Note: I originally set my source to something else, and the map wouldn’t appear on my phone. I’m sure there’s a simple fix for this, but haven’t looked into it yet.
  4. Select the zoom levels you want to include. This will impact the storage space required. As you select more levels, the number of tiles needed are displayed. Each pane takes about 20kilobytes. I included all levels because my area of interest is so small that I’m not to concerned about that yet, I might make small versions available when I publish the app. For my area, 178 tiles + 20kB = 3.48MB.
  5. In the Atlas Content pane, set the name of your map first, then click “add selection” (the name really isn’t important, though).
  6. Then select “Create atlas” and your map is stored in the atlas folder under Mobile Atlas Creator.
  7. Move the resulting zip-file to /mnt/sdcard/osmdroid/ on your device. (For a slight improvement in performance, you can unzip the file and move the resulting Mapnik-folder to /mnt/sdcard/osmdroid/tiles/ instead. The difference in size isn’t that big, but the zip-file might be a good way to organize different maps if you have several areas, but I digress).

That’s it for preparing the map! Again, these are steps and settings that worked for me, others might work better, but I haven’t researched them yet.

Importing the libraries to Android project

When I attach external libraries to my projects I put the .jar-files in the project folder so that I know where they are.

  • Move the osmdroid-android-3.0.7.jar and slf4j-android-1.5.8.jar (and osmdroid-android-3.0.7-javadoc.jar for documentation) into your project folder.
  • In eclipse, right click the project and click refresh, the files should show up.
  • Right-click the files and select [Build Path -> Add to Build Path].
  • Then, go into [Build Path -> Configure Build Path] and under the Libraries tab select the osmdroid.jar and edit javadoc location to the osmdroid-android-3.0.7-javadoc.jar file.

The code

This example code shows the map parts of the Activity class and should be enough to view the map. Note that this Activity doesn’t need to specify an .xml layout as we’re doing it in the code.

package com.yourpackage.name;

import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;

import android.app.Activity;
import android.os.Bundle;

public class OSMDroidMapActivity extends Activity {
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        MapView mapView = new MapView(this, 256); //constructor
        mapView.setClickable(true);
        mapView.setBuiltInZoomControls(true);
        setContentView(mapView); //displaying the MapView
        mapView.getController().setZoom(15); //set initial zoom-level, depends on your need
        mapView.getController().setCenter(new GeoPoint(52.221, 6.893)); //This point is in Enschede, Netherlands. You should select a point in your map or get it from user's location.
        mapView.setUseDataConnection(false); //keeps the mapView from loading online tiles using network connection.
    }
}

This displays the MapView only. If you would like to add some other Views, you can remove the setContentView(mapView); and add the following to your class and remember to do the right imports.

TextView myTextView = new TextView(this);
        myTextView.setTextAppearance(this, android.R.style.TextAppearance_Large_Inverse);
        myTextView.setText("Enschede, Netherlands");
        Button myUselessButton = new Button(this);
        myUselessButton.setText("Click");

        final RelativeLayout relativeLayout = new RelativeLayout(this);
        final RelativeLayout.LayoutParams mapViewLayoutParams = new RelativeLayout.LayoutParams(
                        RelativeLayout.LayoutParams.FILL_PARENT,RelativeLayout.LayoutParams.FILL_PARENT);
        final RelativeLayout.LayoutParams textViewLayoutParams = new RelativeLayout.LayoutParams(
                        RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        final RelativeLayout.LayoutParams buttonLayoutParams = new RelativeLayout.LayoutParams(
                        RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        buttonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);

        relativeLayout.addView(mapView, mapViewLayoutParams);
        relativeLayout.addView(myTextView, textViewLayoutParams);
        relativeLayout.addView(myUselessButton,buttonLayoutParams);
        setContentView(relativeLayout);

Basically, we did three things here:

  • Create the TextView and Button.
  • Create the RelativeLayout and the rules for the different Views.
  • Add the Views to the Layout and finally set the Activity to show the layout.

Now we should get something like this:

  评论这张
 
阅读(1404)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017