相关参考站点:
Esri中国(Esri_mobile):ArcGis官方CSDN博客,其中 Esri_mobile已经停止更新,转到Esri中国,可以查看 文章分类--移动 部分。
Esri中国官网:可以在产品技术和下载中心了解到一些基础的相关知识。
Esri官网:我这里直接关联到Android的页面了。
ArcGis Runtime for Android :官方存放在GitHub上的代码示例。还有开源部分Esri/ Maps-app-Android
1、使用ArcGis for Android里的mapView作为容器,载入天地图的wmts数据生成底图
使用到的参考文档:ArcGIS for Android 2.0开发教程-基础版.pdf(这个文档有点古老,现在都已经10.2.7版本了)
还有安装配置的问题:ArcGIS for Android 在Eclipse上的安装配置(10.2.5之后不能直接当插件安装了)
相关博客:ArcGis读取天地图2.0 (里面提到的工具箱已经没有提供链接了,可以从评论区找。)
这里也提供一份从总的工具箱中提取出来的Android部分:ArcGIS for Android读取天地图2.0
但是我真正使用成功的是这一份Arcgis android 叠加天地图 (这个我直接测试成功,是原作者上传的)
只需要更改相应的天地图数据请求连接即可(底图和标注)
以浙江为例,数据源可以登录浙江天地图的官网,http://www.zjditu.cn/map.html,然后在不同层级抓包分析就可以了。
(需要注意,地方天地图的数据也是不同的,有需要可以增加。)
其他没有成功的也和上面这份差不多。有兴趣可以看一下:
arcgis for android 加载天地图服务arcgis使用天地图综合示例
2、详细功能(以下是在 上面使用成功的那份demo 上进行的操作)
一、地图初始化区域
map = (MapView)findViewById(R.id.map);
……//下面三个方法都可以改变地图的显示范围,在代码中是不会同时使用的
Envelope env = new Envelope(117.553370,26.698680,122.959910,31.608534);//范围
map. setExtent(env)//设置地图显示范围
map. setScale(295828763);//当前显示的比例尺
map. setResolution(9783.93962049996);//设置当前显示的分辨率该demo在继承TianDiTuTiledMapServiceLayer extends TiledServiceLayer 中初始化部分,控制了范围。
所以我们需要去除这段代码,并在Activity onCreate中使用初始化map时来控制范围。
mMapView.setOnStatusChangedListener(new OnStatusChangedListener() {
private static final long serialVersionUID = 1L;
@Override
public void onStatusChanged(Object o, STATUS status) {
if (status == STATUS.INITIALIZED) {
mMapView.setResolution(TDTConverse.res[15]);
mMapView.centerAt(28.112149, 120.957149, true);//浙江乐清
}
}
});
二、添加定位图标
LocationDisplayManager ldm=mMapView.getLocationDisplayManager();
ldm.setLocationListener(new LocationListener() {
boolean locationChanged = false;
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
//GPS开启时触发
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
if (!locationChanged) {
locationChanged = true;
}
}
});
ldm.start();这个是自带的定位(),所以不做什么操作,也可以显示出来。
因为我这个项目需要比较精确的定位,估计也就只能用百度地图的了。代码后面再贴,思路:通过百度地图获取经纬度--转化成屏幕点--添加一个自己的Marker。
三、添加Marker
可以参考最新的App Framework for ArcGIS Android
使用 mvHelper.addMarkerGraphic(28.112149, 120.957149, “Title”, "Snippet", null, icon, false, 0)添加
但是这个封装好的部分,弹出的Callout只包含一个标题和摘要,不能完成自定义。所以使用了一般的方法:
(这里有一个大坑,就是mapView.centAt 以及mvHelper.addMarkerGraphic都是使用的lat,lng的坐标点,而这里的Point顺序是lng,lat)
GraphicsLayer mGraphicsLayer=new GraphicsLayer();
PictureMarkerSymbol icon = new PictureMarkerSymbol(getResources().getDrawable(R.drawable.icon));
Graphic pointGraphic = new Graphic(new Point(120.957149,28.112149),icon);
mGraphicsLayer.addGraphic(pointGraphic);
//渲染设置,需要将图层中的graphics统一style或者分类渲染时使用
//mGraphicsLayer.setRenderer(new SimpleRenderer(new PictureMarkerSymbol(icon)));
mMapView.addLayer(mGraphicsLayer);
其中map添加Graphic图层需要在添加底图(其他)之后,可以在Graphic图层还未添加Graphics的时候添加,
然后在Graphic图层添加Graphics也是会更新图层信息的。
以上三部分的实现截图如下,(不管是定位点,还是graphicLayer上的icon,都不会随着地图放大缩小而变化,需要手动调整)
四、Marker的点击事件
ArcGis没有点击覆盖物事件,但是可以通过 点击地图--获取一定范围内的Graphic--进行需求操作 来模拟点击事件的产生。
(所以我很好奇,OnGraphicClickListener = =这个接口是干嘛的,官方说明后面这个方法根本没有嘛~
Defines signatures for methods that are called when tapping on a graphic added through the MapView.addXXXGraphic() methods.)
官方api中有方法,参数是点击的x,y 以及范围值,具体忘了。。
五、弹窗Callout的实现 这样就获得了点击位置(附近)的Graphic(即我们需求的覆盖物)接下来就通过callout来实现弹窗了(callout本身就是单例的)
private void initCallout() {
// TODO Auto-generated method stub
inflater = LayoutInflater.from(this);
calloutView = inflater.inflate(R.layout.callout, null);
callout=mMapView.getCallout();
callout.setStyle(R.xml.callout);//格式可以通过xml文件夹下的xml直接获取
callout.setOffset(0, 15);//也可以通过设置一步步实现
popView=(LinearLayout)calloutView.findViewById(R.id.popView);//绑定布局xml格式如下:(官网api对callout的使用有说明)
anchor="5"
backgroundAlpha="255"
backgroundColor="#ffffff"
cornerCurveDp="5"//边角的曲率(其实是圆弧半径吧)
frameColor="#111111"/>
但是我用的Arcgis for android sdk10.2.7,android:minSdkVersion="8" android:targetSdkVersion="19"
如果固定callout宽度为match屏宽,布局中(TextView tv)单行字符过长,则会显示不全。
设置tv singleLine=false,则初始化显示会换行,移动地图之后还是单行显示不全状态。
如果设置宽度固定值为屏宽大小,依旧显示不全;但是设置成较小值,会成功显示换行。
网上搜到过一篇文章说:作者callout在arcgis之前的一个版本可以,但是更新了之后也不行了。