原文地址:
ArcGIS for Android地图控件的5大常见操作 - ArcGIS_Mobile的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/arcgis_mobile/article/details/7801467
GIS的开发中,什么时候都少不了地图操作。ArcGIS for Android中,地图组件就是MapView,MapView是基于Android中ViewGroup的一个类(参考),也是ArcGIS Runtime SDK for Android中的地图容器,与很多ArcGIS API中的Map、MapControl类的作用是一样的。
地图常见的操作有缩放、旋转、平移、获取范围、比例尺、分辨率等信息,以及常用的手势操作,其中,经常使用到的功能和常见问题有以下几个:
1)将地图缩放到指定的比例尺/分辨率/级别;
2)设置地图的最大最小缩放级别;
3)获取地图上某点的经纬度坐标;
4)地图的手势操作;
5)地图无法显示。
下面内容会为您详细解答以上问题。
1、获取/设置比例尺、分辨率、中心点、范围;
ArcGIS forAndroid中,MapView具有很多与地图操作有关的方法,其中,与地图的比例尺、分辨率、中心点、范围有关的方法如下:
获取/设置地图的中心点、范围、分辨率、比例尺 |
||
返回类型 |
方法 |
说明 |
Void |
centerAt(Point centerPt, Boolean animated) |
将地图居中到指定的点 |
Point |
getCenter() |
获取地图中心点 |
Polygon |
getExtent() |
获取地图最小外包矩形 |
Envelope |
getMapBoundaryExtent() |
获取地图的边界 |
Void |
setExtent(Geometry geometry) |
将地图放大到指定的范围,并将该geometry的bound作为地图当前的extent |
Void |
setExtent(Geometry geometry, int padding) |
将地图放大到指定的geometry以便geometry适应地图的bound |
Double |
getMaxResolution() |
获取地图最大分辨率 |
Void |
setMaxResolution(double maxResolution) |
设置地图最大分辨率 |
Double |
getMinResolution() |
获取地图最小分辨率 |
Void |
setMinResolution(double minResolution) |
设置地图最小分辨率 |
Double |
getResolution() |
获取当前地图分辨率 |
Void |
setResolution(double res) |
设置当前地图分辨率 |
Double |
getScale() |
获取当前地图比例尺 |
Void |
setScale(double scale) |
设置当前地图比例尺 |
要获取/设置地图的比例尺、初始分辨率、范围、中心点等信息,直接使用上述方法即可,非常简单,在此不赘述,示例代码如下:
map.setScale(18489297.737236);//设置地图初始化时的比例尺;
map.setAllowRotationByPinch(true);//设置是否允许地图通过pinch方式旋转;
map.setRotationAngle(15.0);//设置地图的旋转角度;
……
2、地图缩放、平移和旋转;
与缩放和旋转有关的地图事件如下:
地图缩放、旋转 |
||
返回类型 |
方法 |
说明 |
Void |
zoomin() |
|
Void |
zoomout() |
|
Void |
zoomTo(Point centerPt, float factor) |
将地图放荡到指定点 |
Void |
zoomToResolution(Point centerPt, double res) |
将地图放大到指定分辨率 |
Void |
zoomToScale(Point centerPt, double scale) |
将地图放大到指定比例尺 |
Double |
getRotationAngle() |
返回当前地图旋转角度(单位degree) |
Void |
setRotationAngle(double degree) |
将地图按照指定的角度(单位degree)旋转,度数为正数则按逆时针方向旋转 |
Void |
setRotationAngle(double degree, float pivotX, float pivotY) |
将地图按指定的点和角度旋转,角度为正数按逆时针 |
Void |
setAllowRotationByPinch(boolean allowRotationByPinch) |
允许/取消pinch旋转 |
Boolean |
isAllowRotationByPinch() |
是否允许pinch时旋转 |
2.1 平移
MapView的方法中,没有专门针对平移操作,主要原因在于,MapView中已经默认支持平移操作,即使用鼠标或手势拖动地图时就会平移地图,所以无需设置;
2.2 缩放至指定的分辨率/比例尺和连续放大n倍
一般的切片地图服务,在其REST服务的目录下都能查到切片的等级、等级对应的分辨率和比例尺,每个等级之间的分辨率和比例尺之间呈2倍的关系。
ArcGIS Android中没有像Web中的那种指针控件,没有直接的地图级别的控制,通常级别控制通过分辨率或比例尺来实现。可以用getResolution()和getscale()方法获取当前地图的比例尺和分辨率,然后利用2的倍数关系,使用zoomTo()/zoomToScale()/zoomToResolution()来达到“控制地图缩放级别”的目的:
放大/缩小1倍:
map.zoomin()、map.zoomout();
连续放大/缩小n倍:
map.zoomTo(point centerPt, float factor);如:map.zoomTo(centerPt,2n),其中,n为放大或缩小的倍数;
map.zoomToScale(Point centerPt, double scale) ;如:map.zoomToScale(centerPt, map.getScale()/2n)/map.zoomToScale(pt,map.getScale()*2n),其中,n为放大或缩小的倍数;
map.zoomToResolution(point centerPt, double res):map.zoomToResolution(centerPt,map.getResolution()/2n)/map.zoomToResolution(centerPt,map.getResolution() *2n),其中,n为放大或缩小的倍数;
在zoomTo(point centerPt, float factor)中,centerPt指在哪个点放大,factor参数用来计算新的分辨率,计算公式为:新的分辨率 = 当前分辨率/factor。这个意思也就是说,想在当前分辨率下放大3倍,则新分辨率 = 当前分辨率/(23),因为每一级之间分辨率呈2的倍数关系,放大三级,分辨率就是23倍,factor =23。 从上图中可以看出,地图级别每增加1级,分辨率/2,比例尺/2,故如果想将地图连续放大n级,factor =2n。如果想将地图连续缩小n级,则 factor =2-n。
在zooToScale(Point centerPt, double scale)和zoomToResolution(point centerPt, double res)中,scale和res都指实际的分辨率和比例尺,故按照2的倍数关系直接乘除即可。
2.3 设置地图最大最小缩放级别
有时候我们需要设置地图放大或缩小到某个级别之后,不允许用户再放大或缩小,用以下两个方法很容易做到:
map.setMaxResolution(MaxResolution);
map.setMinResolution(MinResolution);
这两个方法设置了地图的最大、最小分辨率,也就限制了地图的缩放级别,当地图达到最大、最小分辨率时,地图将不能再被缩小或者放大,以免用户无限制的缩放地图或看到更多的内容。
在初始化时将地图设定为某种级别(找到该级别对应的分辨率、比例尺):
map.setResolution(该级别对应的分辨率);
至于如何获取当前地图等级,没办法,先获取resolution,然后去rest服务目录中对照取其级别吧。
2.4 旋转地图
可以使用setRotationAngle(double degree)和setRotationAngle(doubledegree, float pivotX, float pivotY)来实现将地图旋转一定的角度,要实现通过手势进行旋转,需要通过setOnPinchListener(OnPinchListener onPinchListener)监听来实现。如:
public void onCreate(Bundle savedInstanceState, OnPinchListener onPinchListener) { super.onCreate(savedInstanceState); setContentView(R.layout.main); map = (MapView)findViewById(R.id.map); …… map.setAllowRotationByPinch(true); //是否允许使用Pinch方式旋转地图 map.setRotationAngle(15.0); //初始化时将地图旋转15度,参数为正时按逆时针方向旋转。 } |
3、获取地图上某点的坐标
获取地图上某点的坐标主要使用下列几个方法,其中,主要使用toMapPoint()方法实现获取地图上的点坐标信息:
返回类型 |
方法 |
说明 |
SpatialReference |
getSpatialReference() |
返回地图的坐标系统 |
Point |
toMapPoint(float screenx, float screeny) |
将屏幕坐标转换成地图坐标系下的ArcGIS geometry Point坐标 |
Point |
toMapPoint(Point src) |
将屏幕坐标转换成地图坐标系下的ArcGIS geometry Point坐标 |
Point |
toScreenPoint(Point src) |
将地图坐标系下的ArcGIS geometry Point坐标转换成屏幕坐标 |
如,在长按地图时获取鼠标点的坐标代码如下:
// 长按显示鼠标点坐标及比例尺 this.map.setOnLongPressListener(new OnLongPressListener() { private static final long serialVersionUID = 1L; @Override public void onLongPress(float x,float y) { com.esri.core.geometry.Point pt = map.toMapPoint(x, y); mapcenter.setText("X:"+ pt.getX() +"Y:"+ pt.getY()); labelxy.setText("当前地图分辨率为:" +map.getResolution()); mapscale.setText("当前地图比例尺为:" +map.getScale()); } }); |
运行结果如下:
4、手势操作
默认情况下,MapView响应以下手势:
1)单一手指双击和pinch-out放大地图;
2)两个或多个手指pinch-in缩小地图;
3)单个手指拖拽平移地图。
其它手势监听有:
手势事件 |
||
返回类型 |
方法/事件监听 |
说明 |
OnLongPressListener |
getOnLongPressListener() |
获取地图长按事件监听 |
OnPanListener |
getOnPanListener() |
获取地图平移事件监听 |
OnPinchListener |
getOnPinchListener() |
获取地图捏夹事件监听 |
OnSingleTapListener |
getOnSingleTapListener() |
获取地图单击事件监听 |
OnZoomListener |
getOnZoomListener() |
获取缩放监听 |
void |
setOnLongPressListener(OnLongPressListener onLongPressListener) |
设置地图长按事件监听 |
Void |
setOnPanListener(OnPanListener onPanListener) |
设置地图平移事件监听 |
Void |
setOnPinchListener(OnPinchListener onPinchListener) |
设置地图捏夹事件监听 |
Void |
setOnSingleTapListener(OnSingleTapListener onSingleTapListener) |
设置地图单击事件监听 |
Void |
setOnZoomListener(OnZoomListener onZoomListener) |
设置缩放监听 |
5、关于地图显示不出来的问题
许多新手在使用ArcGIS RuntimeSDk for Android开发时,最简单的HelloWorld程序都会遇到问题,按照教程的步骤,添加了MapView,添加了切片图层,一切就绪,地图却始终出不来,遇到这个问题可先从以下几个方面查找原因:
1)如果添加了多个图层,请确保多个图层的地理参考一致;
2)是服务类型是否对应;
3)图层声明在xml布局文件中;
4)如果只是添加了一个底图图层仍然出不来底图,那么十有八九是extent的问题。首先,MapView控件必须至少包含一个图层,其次,该图层最好为其指定initExtent,在xml中代码如下:
<com.esri.android.map.MapView android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" initExtent="-20037507.0672, -30240971.9584, 20037507.0672, 30240971.9584"> </com.esri.android.map.MapView> |
该initExtent来自哪里呢?还是地图服务目录中:
取两个中的任一个,或者自定义一个包含于上述两个范围中的extent均可,推荐使用full extent。
6、其它常用方法
除了上述提到的各种方法和监听之外,还有一些与地图相关的,也比较常用的方法和监听如下:
其它属性和事件 |
||
返回类型 |
方法/事件监听 |
说明 |
OnStatusChangedListener |
getOnStatusChangedListener() |
获取地图状态改变事件监听 |
Void |
setOnStatusChangedListener(OnStatusChangedListeneronStatusChangedListener) |
设置地图状态改变事件监听 |
Boolean |
isLoaded() |
MapView初始化之后返回true |
Void |
setEsriLogoVisible(Boolean visible) |
打开或关闭地图上的ESRI的logo标签 |
Void |
setMapBackground(int bkColor, int gridColor, float gridSize, float gridLineSize) |
设置地图背景颜色 |