您的位置:首页 > 移动开发 > Android开发

ArcGIS for Android 之定位功能开发

2013-04-28 16:05 627 查看
关于定位的功能,开发,很早之前就有做过百度的定位功能。起初是有想法把百度的Loc V3.2的定位SDK整合进来用。但是终归是想法,但是知道昨天,我问技术群,里面的一位朋友就说起了百度地位SDK整合进来的实现方法。顿时,我就思考了一会,随后就是很激动地操作起来。根据朋友给的一个demo。做了两天,终于算是真正将功能实现了。至于界面的美观或者样式的显示这个就偷懒掉了。
http://developer.baidu.com/map/sdk-android.htm
这个是百度的SDK。帮助文档。

第一次看这个定位的实现的时候,觉得按步骤来就可以实现,把该设置的参数设置好就行了。其实,的确就行了。很简单!

我根据demo,也用了V2.2.1的版本的百度定位。我会把工程发在我的资源里面。有需要自行下载。这里讲些重点错误的地方。

1.构建路径(Build Path),如何把LocV2.2.1.jar导入Android Dependencies内呢?

在ADT17之前,如果要在Android项目中引入外部JAR包,只需在项目属性的Java Build Path中选择Add External JARs,然后选择相应JAR包即可。但是,在升级到ADT17之后,Android项目下多出了一个Android Dependencies目录,之前通过Add
External JARs加入的jar包依然出现在Referenced Libraries目录之下,但是似乎已经被弃用,虽然没有提示任何错误,但是在运行时会抛出ClassNotFoundException。解决方法是将JAR包加入到Android Dependencies下,其中一个默认引入目录是libs,因此只要将JAR包复制该目录下。

所以,记得新建一个ArcGIS工程后,要记得导入LocV2.2.1.jar包。

2.配置清单里面一定需要添加百度定位的services:

<service
android:name="com.baidu.location.f"
android:enabled="true"
android:permission="android.permission.BAIDU_LOCATION_SERVICE"
android:process=":remote" >
<intent-filter>
<action android:name="com.baidu.location.service_v2.2" >
</action>
</intent-filter>
</service>


3.有了服务没有权限,我想您也觉得不行。所以我就来了一个大手笔:

<permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >
</permission>

<uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >
</uses-permission>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >
</uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
</uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
</uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >
</uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE" >
</uses-permission>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >
</uses-permission>
<uses-permission android:name="android.permission.READ_LOGS" >
</uses-permission>


4.于是清单文件是没有问题滴啦,那么还有什么不是重点的周边问题要解决呢?right!布局文件嘛!很简单,加个button:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:context=".QueryTaskkkkkkActivity" >

<com.esri.android.map.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
initExtent="1.2757645697558502E7 2576233.422813467 1.3480434236922514E7 3307582.9093442294" >
</com.esri.android.map.MapView>

<Button
android:id="@+id/location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="定位" />

</RelativeLayout>


5.接下来就直接把这个代码拷贝进来好了,里面的内容一会分行讲:

package com.esri.arcgis.query;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.esri.android.map.GraphicsLayer;
import com.esri.android.map.MapView;
import com.esri.android.map.ags.ArcGISTiledMapServiceLayer;
import com.esri.android.map.event.OnLongPressListener;
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.map.Graphic;
import com.esri.core.symbol.PictureMarkerSymbol;
import com.esri.core.symbol.SimpleFillSymbol;
import com.esri.core.symbol.SimpleLineSymbol;

public class QueryTaskkkkkkActivity extends Activity {

MapView mMapView;
GraphicsLayer glLayer = null;
Graphic gp = null;
Button location;
LocationClient locationClient = null;
String TAG = null;
MyLocationListenner myListener = new MyLocationListenner();
PictureMarkerSymbol locationPH;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

mMapView = (MapView) findViewById(R.id.map);
String url = "http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer";
ArcGISTiledMapServiceLayer tl = new ArcGISTiledMapServiceLayer(url);
mMapView.addLayer(tl);
glLayer = new GraphicsLayer();
mMapView.addLayer(glLayer);
mMapView.setEsriLogoVisible(true);

// 启动百度定位
locationClient = new LocationClient(this);
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);
option.setCoorType("gpj02");// 返回国测局经纬度坐标系 coor=gcj02
option.setProdName("定位Test");
option.setScanSpan(10000);
option.setPriority(LocationClientOption.GpsFirst);// GPS定位优先
locationClient.setLocOption(option);
locationClient.registerLocationListener(myListener);// 发起定位,异步获取当前位置。

mMapView.setOnLongPressListener(new OnLongPressListener() {

private static final long serialVersionUID = 1L;

@Override
public void onLongPress(float x, float y) {
// TODO Auto-generated method stub
Point pt = mMapView.toMapPoint(x, y);
Log.i(TAG, "" + pt.getX());
Log.i(TAG, "" + pt.getY());
}
});
// 定位
location = (Button) findViewById(R.id.location);
location.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (locationClient == null)
return;
if (locationClient.isStarted()) {
locationClient.stop();
location.setText("开启定位");
} else {
locationClient.start();
location.setText("停止定位");
}
}
});
}

public class MyLocationListenner implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
// TODO Auto-generated method stub
if (location != null) {
// 显示定位的结果
ShowLocation(location);
}
return;
}
}

public void ShowLocation(BDLocation bdLocation) {
// double locx = bdLocation.getLatitude();// 获得纬度
// double locy = bdLocation.getLongitude();// 获得经度
// Point wgsPoint = new Point(locx, locy);
// Point rs4326 = (Point) GeometryEngine.project(wgsPoint,
// SpatialReference.create(4326), mMapView.getSpatialReference());

// glLayer.removeAll();//这句话放在这个位置才是正确的啊!笨蛋
// gp = new Graphic(rs4326, locationPH);
// glLayer = new GraphicsLayer();// init
// glLayer.addGraphic(gp);
// mMapView.addLayer(glLayer);
// mMapView.centerAt(rs4326, true);
// if (bdLocation.getLocType() == 61) {
// Log.i(TAG, "GPS实现定位!");
// }
PictureMarkerSymbol locationPH = new PictureMarkerSymbol(
QueryTaskkkkkkActivity.this.getResources().getDrawable(
R.drawable.location32));
double locy = bdLocation.getLatitude();
double locx = bdLocation.getLongitude();
Point wgspoint = new Point(locx, locy);
Point mapPoint = (Point) GeometryEngine.project(wgspoint,
SpatialReference.create(4326), mMapView.getSpatialReference());

// Polygon pg = GeometryEngine.buffer(wgspoint,
// mMapView.getSpatialReference(), 0.11, null);
// SimpleFillSymbol sfs = new SimpleFillSymbol(Color.BLACK);
// sfs.setOutline(new SimpleLineSymbol(Color.RED, 1));
// sfs.setAlpha(0);

glLayer.removeAll();
glLayer.addGraphic(new Graphic(mapPoint, locationPH));
// glLayer.addGraphic(new Graphic(pg, sfs));
mMapView.centerAt(mapPoint, true);// 漫游到当前位置
mMapView.addLayer(glLayer);
if (bdLocation.getLocType() == BDLocation.TypeGpsLocation) {
Log.v("locationType", "Gps");
}
}

@Override
protected void onDestroy() {
if (locationClient != null && locationClient.isStarted()) {
locationClient.stop();
locationClient = null;
}
super.onDestroy();
}

@Override
protected void onPause() {
super.onPause();
mMapView.pause();
}

@Override
protected void onResume() {
super.onResume();
mMapView.unpause();
}

}


这样子,我的这个应该就算都做完了,可以用真机来测试一下,它的快速定位!

接下来讲解一下其中的一些细节:

a.启动百度定位。

// 启动百度定位
locationClient = new LocationClient(this);
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);
option.setCoorType("gpj02");// 返回国测局经纬度坐标系 coor=gcj02
option.setProdName("定位Test");
option.setScanSpan(10000);
option.setPriority(LocationClientOption.GpsFirst);// GPS定位优先
locationClient.setLocOption(option);
locationClient.registerLocationListener(myListener);// 发起定位,异步获取当前位置。


上面代码,一看,很明显,直接按照百度定位的帮助文档里面的步骤来的,连顺序都是一样的!那肯定的,因为我就是看一条加一条的。嘻嘻!各个参数的说明,我就不再讲了,不然说错一点,百度人家不愿意了,我就完蛋了。

就是,最后两句代码,要记得注意下,设置了那么多的参数,开心得半死,忘记了引用到软件上的话,那就只能郁闷了。选择异步操作,自然是有好处的啦,但是如果GPS和网络那会信号不好,软件会出现类似假死状态哦,为啥,异步在后面操作运算,自然前端就没有任何反应,建议大家做个进度条,增加和谐感!

b.接下来说个让我痛恨自己的地方,显示定位结果:

// double locx = bdLocation.getLatitude();// 获得纬度
// double locy = bdLocation.getLongitude();// 获得经度
// Point wgsPoint = new Point(locx, locy);
// Point rs4326 = (Point) GeometryEngine.project(wgsPoint,
// SpatialReference.create(4326), mMapView.getSpatialReference());

// glLayer.removeAll();//这句话放在这个位置才是正确的啊!笨蛋
// gp = new Graphic(rs4326, locationPH);
// glLayer = new GraphicsLayer();// init
// glLayer.addGraphic(gp);
// mMapView.addLayer(glLayer);
// mMapView.centerAt(rs4326, true);
// if (bdLocation.getLocType() == 61) {
// Log.i(TAG, "GPS实现定位!");
// }
PictureMarkerSymbol locationPH = new PictureMarkerSymbol(
QueryTaskkkkkkActivity.this.getResources().getDrawable(
R.drawable.location32));
double locy = bdLocation.getLatitude();
double locx = bdLocation.getLongitude();
Point wgspoint = new Point(locx, locy);
Point mapPoint = (Point) GeometryEngine.project(wgspoint,
SpatialReference.create(4326), mMapView.getSpatialReference());

// Polygon pg = GeometryEngine.buffer(wgspoint,
// mMapView.getSpatialReference(), 0.11, null);
// SimpleFillSymbol sfs = new SimpleFillSymbol(Color.BLACK);
// sfs.setOutline(new SimpleLineSymbol(Color.RED, 1));
// sfs.setAlpha(0);

glLayer.removeAll();
glLayer.addGraphic(new Graphic(mapPoint, locationPH));
// glLayer.addGraphic(new Graphic(pg, sfs));
mMapView.centerAt(mapPoint, true);// 漫游到当前位置
mMapView.addLayer(glLayer);
if (bdLocation.getLocType() == BDLocation.TypeGpsLocation) {
Log.v("locationType", "Gps");
}


应该有看见很多注释掉的代码,其实注释掉的就是我之前自己写,语法句子上都是没问题的。问题就在有“笨蛋”的那个语句,呵呵,你或许会疑惑,这个语句这么简单。我也是这么认为的,于是就自以为滴放在了gp = new Graphic(rs4326, locationPH);后面。就也没有注意。于是苦逼的日子就开始了,没有错误却一点就异常。辛辛苦苦定位到的结果被清除了,这样子的逻辑错误。严重得很!

6.实现了定位,也成功定位了。突然有个想法,想实现以定位点为圆心向四周动画滴发散的动画效果的实现。首先我会想到去自定义一个动画,然后实现。这个理论上是肯定可行的。可是我是小白,哪里有那么高超技术呢?于是领导给了个到现在还觉得很棒的思路,可以去找一下有没有这样子动画的gif图片,然后用图片符号集把它添加进去,不是就OK了,而且还简单得要死。领导就是领导,想法都这么牛X!

综上所述:实现ArcGIS的定位功能其实是很简单的事情。不信你就研究下我说的,还有我的工程文件。“定位功能的实现.rar”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐