`
chenhaodejia
  • 浏览: 111070 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android地图开发中的地理编码与地理反编码

阅读更多

地理编码(Geocoding)与地理反编码(Reverse Geocoding)是地图操作中的常见操作,前者表示通过街道地址请求空间坐标,后者表示通过空间坐标请求街道地址。通俗的说,二者就是街道地址与经纬度的转换。举例来说,前者就是输入查询"上海市杨浦区四平路1239号"得到(31.285207060526762, 121.50546412914991),而后者则表示这个反过程。

在实际的移动开发过程中,地图相关的操作对于地理编码与地理反编码的使用都是十分普遍。幸运的是,Android的MapView控件中对于这两者都进行了封装,因此可以方便的利用Google Map Service进行二者查询。下面将对开发过程做一个简单介绍。

首先必须进行MapKey的申请,任何地图的显示都需要申请一个MapKey。具体的申请步骤可见

http://code.google.com/intl/zh-CN/android/maps-api-signup.html

然后可以建立一个基于Google APIs的程序,并且在AndroidManifest.xml中加入地图API的支持。

view plaincopy to clipboardprint?
01.<?xml version="1.0" encoding="utf-8"?> 
02.<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
03.      package="net.learn2develop.GoogleMaps" 
04.      android:versionCode="1" 
05.      android:versionName="1.0.0"> 
06.    <application android:icon="@drawable/icon" android:label="@string/app_name"> 
07.    <uses-library android:name="com.google.android.maps" />    
08.        <activity android:name=".MapsActivity" 
09.                  android:label="@string/app_name"> 
10.            <intent-filter> 
11.                <action android:name="android.intent.action.MAIN" /> 
12.                <category android:name="android.intent.category.LAUNCHER" /> 
13.            </intent-filter> 
14.        </activity> 
15.    </application> 
16.   
17.    <uses-permission android:name="android.permission.INTERNET" /> 
18.</manifest> 
19.</xml> 
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="net.learn2develop.GoogleMaps"
      android:versionCode="1"
      android:versionName="1.0.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
    <uses-library android:name="com.google.android.maps" /> 
        <activity android:name=".MapsActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

    <uses-permission android:name="android.permission.INTERNET" />
</manifest>
</xml>

接着可以在主Layout文件中加入对于地图的显示,这里需要加入刚才申请的MapKey,否则地图将无法正常显示。

view plaincopy to clipboardprint?01.<?xml version="1.0" encoding="utf-8"?>  02.<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    03.    android:layout_width="fill_parent"    04.    android:layout_height="fill_parent">  05.    06.    <com.google.android.maps.MapView    07.        android:id="@+id/mapView"  08.        android:layout_width="fill_parent"  09.        android:layout_height="fill_parent"  10.        android:enabled="true"  11.        android:clickable="true"  12.        android:apiKey="MapKey"  13.        />  14.    15.</RelativeLayout>  <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.google.android.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:enabled="true"
        android:clickable="true"
        android:apiKey="MapKey"
        />

</RelativeLayout>

接着在主Activity的JAVA文件进行修改,支持地图显示。

view plaincopy to clipboardprint?
01.import com.google.android.maps.MapActivity;  
02.import com.google.android.maps.MapView;  
03.import android.os.Bundle;  
04.   
05.public class MapsActivity extends MapActivity   
06.{      
07.    /** Called when the activity is first created. */ 
08.    @Override 
09.    public void onCreate(Bundle savedInstanceState)  
10.    {  
11.        super.onCreate(savedInstanceState);  
12.        setContentView(R.layout.main);  
13.    MapView mapView = (MapView) findViewById(R.id.mapView);  
14.    mapView.setBuiltInZoomControls(true);  
15.    }  
16.} 
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import android.os.Bundle;

public class MapsActivity extends MapActivity
{   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
MapView mapView = (MapView) findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
    }
}

此时运行程序,地图应该就可以正常显示了,见下图。







此时我们再向程序中加入地理编码与地理反编码的功能,其参考代码如下。

地理编码:

view plaincopy to clipboardprint?
01.Geocoder geoCoder = new Geocoder(this, Locale.getDefault());      
02.try {  
03.    List<Address> addresses = geoCoder.getFromLocationName(  
04.        "上海市杨浦区四平路1239号", 5);  
05.    String add = "";  
06.    if (addresses.size() > 0) {  
07.        p = new GeoPoint(  
08.                (int) (addresses.get(0).getLatitude() * 1E6),   
09.                (int) (addresses.get(0).getLongitude() * 1E6));  
10.        mc.animateTo(p);      
11.        mapView.invalidate();  
12.    }      
13.} catch (IOException e) {  
14.    e.printStackTrace();  
15.} 
        Geocoder geoCoder = new Geocoder(this, Locale.getDefault());   
        try {
            List<Address> addresses = geoCoder.getFromLocationName(
                "上海市杨浦区四平路1239号", 5);
            String add = "";
            if (addresses.size() > 0) {
                p = new GeoPoint(
                        (int) (addresses.get(0).getLatitude() * 1E6),
                        (int) (addresses.get(0).getLongitude() * 1E6));
                mc.animateTo(p);   
                mapView.invalidate();
            }   
        } catch (IOException e) {
            e.printStackTrace();
        }

地理反编码,其中MapOverlay为地图图层上的叠加图层,用于标识的显示以及点击事件的捕捉。


view plaincopy to clipboardprint?
01.class MapOverlay extends com.google.android.maps.Overlay  
02.    {  
03.        @Override 
04.        public boolean draw(Canvas canvas, MapView mapView,   
05.        boolean shadow, long when)   
06.        {  
07.          //...  
08.        }  
09.   
10.        @Override 
11.        public boolean onTouchEvent(MotionEvent event, MapView mapView)   
12.        {     
13.            //---when user lifts his finger---  
14.            if (event.getAction() == 1) {                  
15.                GeoPoint p = mapView.getProjection().fromPixels(  
16.                    (int) event.getX(),  
17.                    (int) event.getY());  
18.   
19.                Geocoder geoCoder = new Geocoder(  
20.                    getBaseContext(), Locale.getDefault());  
21.                try {  
22.                    List<Address> addresses = geoCoder.getFromLocation(  
23.                        p.getLatitudeE6()  / 1E6,   
24.                        p.getLongitudeE6() / 1E6, 1);  
25.   
26.                    String add = "";  
27.                    if (addresses.size() > 0)   
28.                    {  
29.                        for (int i=0; i<addresses.get(0).getMaxAddressLineIndex();   
30.                             i++)  
31.                           add += addresses.get(0).getAddressLine(i) + "\n";  
32.                    }  
33.   
34.                    Toast.makeText(getBaseContext(), add, Toast.LENGTH_SHORT).show();  
35.                }  
36.                catch (IOException e) {                  
37.                    e.printStackTrace();  
38.                }     
39.                return true;  
40.            }  
41.            else                  
42.                return false;  
43.        }          
44.    } 
class MapOverlay extends com.google.android.maps.Overlay
    {
        @Override
        public boolean draw(Canvas canvas, MapView mapView,
        boolean shadow, long when)
        {
          //...
        }

        @Override
        public boolean onTouchEvent(MotionEvent event, MapView mapView)
        {  
            //---when user lifts his finger---
            if (event.getAction() == 1) {               
                GeoPoint p = mapView.getProjection().fromPixels(
                    (int) event.getX(),
                    (int) event.getY());

                Geocoder geoCoder = new Geocoder(
                    getBaseContext(), Locale.getDefault());
                try {
                    List<Address> addresses = geoCoder.getFromLocation(
                        p.getLatitudeE6()  / 1E6,
                        p.getLongitudeE6() / 1E6, 1);

                    String add = "";
                    if (addresses.size() > 0)
                    {
                        for (int i=0; i<addresses.get(0).getMaxAddressLineIndex();
                             i++)
                           add += addresses.get(0).getAddressLine(i) + "\n";
                    }

                    Toast.makeText(getBaseContext(), add, Toast.LENGTH_SHORT).show();
                }
                catch (IOException e) {               
                    e.printStackTrace();
                }  
                return true;
            }
            else               
                return false;
        }       
    }
最终实现结果如下图所示,地理编码,查询“上海市杨浦区四平路1239号”,结果其实略有偏差。中国的地址与邮编比较混乱,所以结果有些地方无法做到完全准确。




地理反编码


  • 大小: 217.4 KB
  • 大小: 166.6 KB
  • 大小: 246.6 KB
分享到:
评论
1 楼 床头捉刀人 2011-11-28  
你好,我使用geocoder.getFromLocation(latitude, longitude, 1)方法,报异常java.io.IOException: Service not Available。
请问这是为什么呢?

相关推荐

    Android studio 百度地图开发:触摸选点、地理编码、定位和导航

    Android studio 百度地图开发:触摸选点、地理编码、定位和导航 [注:本内容来自网络,在此分享仅为帮助有需要的网友,如果侵犯了您的权利,麻烦联系我,我会第一时间删除,谢谢您。]

    Android-Android百度地图POI检索行政区边界公交线路规划查询地理编码介绍

    Android百度地图POI检索,行政区边界、公交、线路规划查询,地理编码介绍

    Android 百度地图个人开发demo 源码程序.zip

    2015年 Android百度地图个人开发demo 源码程序,包括地图图层展示,覆盖物添加,地理编码+反地理编码,地图控制+定位,poi检索,公交路线查询+路线规划。可以做为你的学习设计参考。

    Android-用百度地图实现了关键字搜索定位反地理编码搜索移动地图获取地图中间的经纬度

    用百度地图实现了 关键字搜索 定位 反地理编码搜索 移动地图获取地图中间的经纬度 仿qq发送位置 简单版

    Xamrin Android开发实战 基础下篇 源代码

    9.8 反地理编码 60 9.9 打开内置的地图应用 63 9.10 自定义地图 67 第10章 访问网络 73 10.1 网页视图 73 10.1.1 加载内容 73 10.1.2 加载内容的事件 82 10.1.3 导航 85 10.2 网络服务 87 第11章 本地化 98 11.1 ...

    android开发秘籍

    android开发秘籍完整版清晰版 第1 章 android 概述 1 1.1 android 演化史 1 1.2 android 的两面性 2 1.3 运行android 的设备 2 1.3.1 htc 系列机型 4 1.3.2 摩托罗拉系列机型 4 1.3.3 三星系列机型 4 1.3.4 ...

    Android高级编程--源代码

    1.5.2 自带的Google地图、地理编码和基于位置的服务 6 1.5.3 后台服务 6 1.5.4 SQLite 数据存储和检索数据库 6 1.5.5 共享数据和应用程序间通信 7 1.5.6 使用Google Talk的P2P服务 7 1.5.7 扩展的数据支持和2D...

    Android定位功能开发-使用百度地图API的例子

    使用百度地图API显示地图,使用地理编码服务的例子。

    ArcGIS for Android 2.0开发教程

    4. 使用Android模拟器开发 8 5. 使用Android设备开发 10 第三章. 创建第一个HelloWorld Map 12 1. 创建项目 12 2. 项目结构 14 3. 编码实现 16 第四章. 地图、图层及空间参考 . 18 1. MapView地图组件 18 2....

    百度地图API地图描点示例

    包括JavaScript API、Web服务API、Android SDK、iOS SDK、定位SDK、车联网API、LBS云等多种开发工具与服务,提供基本地图展现、搜索、定位、逆/地理编码、路线规划、LBS云存储与检索等功能,适用于PC端、移动端、...

    android百度api2.1

    Android SDKv2.1.0是适用于Android系统移动设备的矢量地图开发包,也是v2.0.0的升级版本。 v2.1.0,功能介绍: 地图展示:包括2D图、卫星图、3D图地图展示。 地图操作:提供平移、缩放、双指手势操作、底图旋转等...

    android高级编程

     1.5.2 自带的google地图、地理编码和基于位置的服务  1.5.3 后台服务  1.5.4 sqlite 数据存储和检索数据库  1.5.5 共享数据和应用程序间通信  1.5.6 使用小组件、live folder和live wallpaper增强主屏幕 ...

    百度地图开发指南

    • 地理编码:提供地址信息与坐标之间的相互转换。 • 位置标注:提供一个或多个POI位置标注,且支持用户自定义图标。 • 实时路况:提供城市实时交通路况信息图。 • 离线地图:提供离线地图功能,可节省用户流量。...

    《Android高级编程》

    6.6 小结 第7章 地图、地理编码和基于位置的服务 7.1 使用基于位置的服务 7.2 使用Test Proyider构建模拟器 7.2.1 更新模拟位置提供器中的位置 7.2.2 创建一个应用程序来管理Test Location Provider 7.3 选择——个...

    Android 4高级编程(第3版)源代码

    内容推荐  《Android 4高级编程(第3版)》由Android权威专家编写,涵盖了所有最新的内容,是学习使用Android 4SDK...第13章 地图、地理编码和基于位置的服务 第14章 个性化主屏幕 第15章 音频、视频以及摄像头的使用

    Android高级编程.pdf

    1.5.2 自带的Google地图、地理编码和基于位置的服务 1.5.3 后台服务 1.5.4 SQLite数据存储和检索数据库 1.5.5 共享数据和应用程序间通信 1.5.6 使用Google Talk的P2P服务 1.5.7 扩展的数据支持和2D/3D图形 1.5.8 ...

    Android高级编程_高清pdf_中文版.part2

     1.5.2 自带的google地图、地理编码和基于位置的服务  1.5.3 后台服务  1.5.4 sqlite 数据存储和检索数据库  1.5.5 共享数据和应用程序间通信  1.5.6 使用小组件、live folder和live wallpaper增强主屏幕 ...

Global site tag (gtag.js) - Google Analytics