ArcGIS for Android示例解析之标绘-----DrawGraphicElements

DrawGraphicElements

 

 

在ArcGIS中除了显示不同地图,还有一块非常重要,就是这个实例要介绍的绘图,如:绘制点、线、面等图形。

废话少说直入主题,首先我们还是先来了解一下布局文件main.xml,代码如下:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

      android:orientation="vertical"

      android:layout_width="fill_parent"

    android:layout_height="fill_parent">

   

      <!—地图控件 -->

    <com.esri.android.map.MapView

           android:id="@+id/map"

           android:layout_width="fill_parent"

           android:layout_height="fill_parent">

      </com.esri.android.map.MapView>   

 

      <LinearLayout

         android:orientation="horizontal"  

         android:gravity="left"  

         android:layout_width="wrap_content"

         android:layout_height="wrap_content"

         >

          <!—点击此按钮弹出点、线、面的选择列表 -->

        <Button android:id="@+id/geometrybutton"

                 android:text="Select Geometry"

                      android:layout_width="wrap_content"

                       android:layout_height="wrap_content" />

           <!—提示信息显示区域-->

           <TextView android:id="@+id/label"

                      android:layout_width="wrap_content"

                      android:layout_height="wrap_content"

                      android:maxLength="25"

                      android:singleLine="false"

                      android:editable="false"

                      android:gravity="center_horizontal"/>       

           <!—清理绘画的图形 -->

           <Button android:id="@+id/clearbutton"

                 android:text="Clear"

                      android:layout_width="wrap_content"

                      android:layout_height="wrap_content"/>

    </LinearLayout>

</RelativeLayout>

上面的布局显示的效果如下,两个按钮和一个文本框,文本框是隐藏的。

当点击第一按钮时,弹出一个列表,列表中有三个选项点、线、面。点击任意一个即可在地图上绘制多边形。

下面来看一下DrawGraphicElements.java中的代码,先来看看类中的属性:

      MapView mapView = null;//地图控件

    //切片服务

      ArcGISTiledMapServiceLayer tiledMapServiceLayer = null;

    //绘图时要用到的图层

      GraphicsLayer graphicsLayer = null;

    //扩展MapOnTouchListener类

      MyTouchListener myListener = null;

 

    //点击后弹出的列表按钮

      Button geometryButton = null;

    //点击清除graphicsLayer图层中的要素

      Button clearButton = null;

      TextView label = null;

 

      //切片服务的URL字符串

      String mapURL = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyBasemap/MapServer";

    //列表所需的数据源

      final String[] geometryTypes = new String[] { "Point", "Polyline",

                 "Polygon" };

    //设置当前选择的哪一项

      int selectedGeometryIndex = -1;

上面的代码设置了后面所需的属性,属性值在onCreate()中初始化

下面来看一下在onCreate中还做了上面事情:

@SuppressWarnings("serial")

      public void onCreate(Bundle savedInstanceState) {

           super.onCreate(savedInstanceState);

           setContentView(R.layout.main);

          

           mapView = (MapView)findViewById(R.id.map);

           myListener = new MyTouchListener(DrawGraphicElements.this, mapView);

        //给mapView添加了触摸事件监听

           mapView.setOnTouchListener(myListener);

           geometryButton = (Button) findViewById(R.id.geometrybutton);

           geometryButton.setEnabled(false);

         //给按钮添加了一个点击事件监听

           geometryButton.setOnClickListener(new View.OnClickListener() {

                 public void onClick(View v) {

                      showDialog(0);

                 }

           });

 

           label = (TextView) findViewById(R.id.label);

 

           clearButton = (Button) findViewById(R.id.clearbutton);

        //设置按钮不可用

           clearButton.setEnabled(false);

 

//给按钮添加了一个点击事件监听

           clearButton.setOnClickListener(new View.OnClickListener() {

                 public void onClick(View v) {

                      graphicsLayer.removeAll();

                     

 

                      clearButton.setEnabled(false);

                 }

           });

           tiledMapServiceLayer = new ArcGISTiledMapServiceLayer(mapURL);

           graphicsLayer = new GraphicsLayer();

//添加地图服务状态改变事件监听

tiledMapServiceLayer

                      .setOnStatusChangedListener(new OnStatusChangedListener() {

                     

public void onStatusChanged(Object arg0, STATUS status) {

                                 

if (status

                                             .equals(OnStatusChangedListener.STATUS.INITIALIZED)) {

                                       geometryButton.setEnabled(true);

                                  }

                            }

                      });

//将切片服务与graphicsLayer图层添加到mapView中去

           mapView.addLayer(tiledMapServiceLayer);

           mapView.addLayer(graphicsLayer);

}

从上面的代码和注释可以很清楚的看出,在这段代码中主要干了两件事:一个是初始化属性;另一个是为属性添加添加相应的事件监听。

基础工作做完后,进入重点,也就是我们实现的MyTouchListener类,它继承MapOnTouchListener类,在我们自己实现的类中主要完成了绘图的核心代码,是不是很激动,让我们来看一下吧:

class MyTouchListener extends MapOnTouchListener {

            //此变量是用来保存线或者面的轨迹数据的

           MultiPath poly;

           //判断是执行的哪种绘图方式,它可以为这三种值:point,polgyline,polgyon

           String type = "";

           //绘画点时用于储存点的变量

           Point startPoint = null;

           //构造方法

           public MyTouchListener(Context context, MapView view) {

                 super(context, view);

           }

           //

           public void setType(String geometryType) {

                 this.type = geometryType;

           }

 

           public String getType() {

                 return this.type;

           }

 

           //当我们绘制点时执行的处理函数

           public boolean onSingleTap(MotionEvent e) {

                 if (type.length() > 1 && type.equalsIgnoreCase("POINT")) {

                      graphicsLayer.removeAll();//绘制点时首先清除图层要素

                       //生成点图形,并设置相应的样式

                      Graphic graphic = new Graphic(mapView.toMapPoint(new Point(e.getX(), e

                                  .getY())),new SimpleMarkerSymbol(Color.RED,25,STYLE.CIRCLE));

                      //将点要素添加到图层上

                      graphicsLayer.addGraphic(graphic);

                      //设置按钮可用

                      clearButton.setEnabled(true);

                      return true;

                 }

                 return false;

 

           }

            //当绘制线或者面时调用的函数

           public boolean onDragPointerMove(MotionEvent from, MotionEvent to) {

                 if (type.length() > 1

                            && (type.equalsIgnoreCase("POLYLINE") || type

                                       .equalsIgnoreCase("POLYGON"))) {

                      //得到移动后的点

                      Point mapPt = mapView.toMapPoint(to.getX(), to.getY());

 

                      //判断startPoint是否为空,如果为空,给startPoint赋值

                      if (startPoint == null) {

                            graphicsLayer.removeAll();

                            poly = type.equalsIgnoreCase("POLYLINE") ?new Polyline()

                                       : new Polygon();

                            startPoint = mapView.toMapPoint(from.getX(), from.getY());

                            //将第一个点存入poly中

                            poly.startPath((float) startPoint.getX(),

                                       (float) startPoint.getY());

 

                           

                            Graphic graphic = new Graphic(startPoint,new SimpleLineSymbol(Color.RED,5));

 

                           

 

                            graphicsLayer.addGraphic(graphic);

                      }

                      //将移动的点放入poly中

                      poly.lineTo((float) mapPt.getX(), (float) mapPt.getY());

                     

                      return true;

                 }

                 return super.onDragPointerMove(from, to);

 

           }

           //当绘制完线或面,离开屏幕时调用的函数

           @Override

           public boolean onDragPointerUp(MotionEvent from, MotionEvent to) {

                 if (type.length() > 1

                            && (type.equalsIgnoreCase("POLYLINE") || type

                                       .equalsIgnoreCase("POLYGON"))) {

                      //判断当绘制的是面时,将起始点填入到poly中形成闭合

                      if (type.equalsIgnoreCase("POLYGON")) {

                            poly.lineTo((float) startPoint.getX(),

                                       (float) startPoint.getY());

                            graphicsLayer.removeAll();

                            graphicsLayer.addGraphic(new Graphic(poly,new SimpleFillSymbol(Color.RED)));

                           

                      }

                      //最后将poly图形添加到图层中去

                      graphicsLayer.addGraphic(new Graphic(poly,new SimpleLineSymbol(Color.BLUE,5)));

                      startPoint = null;

                      clearButton.setEnabled(true);

                      return true;

                 }

                 return super.onDragPointerUp(from, to);

           }

      }

通过上面的代码和注释我们可以知道,在这个类中主要完成了一下几项工作:
  1、当点击地图时,将点添加到图层上并且将其渲染;

          2、当在屏幕上滑动时,将滑动生成的点逐步添加到poly变量中;

          3、当滑动完离开屏幕时,判断是绘制的线还是面,当是面时,将第一个点追加到poly变量中,并将poly变量添加到图层中去。

            所有绘图的操作基本都在上面的代码中实现,还剩下一小部分代码为点击geometryButton按钮而弹出的列表,下面的形式如果对于Android开发经验的一定不会陌生,对了,就是弹出列表的一种方式,而当我们选择不同的选项时调用myListener.setType()来指定绘图方式。

protected Dialog onCreateDialog(int id) {

           return new AlertDialog.Builder(DrawGraphicElements.this)

                      .setTitle("Select Geometry")

                       // geometryTypes为这个弹出框的数据源

                      .setItems(geometryTypes, new DialogInterface.OnClickListener() {

                            public void onClick(DialogInterface dialog,int which) {

                                  graphicsLayer.removeAll();

 

                                  // ignore first element

                                  Toast toast = Toast.makeText(getApplicationContext(),

                                             "", Toast.LENGTH_LONG);

                                  toast.setGravity(Gravity.BOTTOM, 0, 0);//提示信息

 

                                  // Get item selected by user.

                                  String geomType = geometryTypes[which];

                                  label.setText(geomType + " selected.");

                                  selectedGeometryIndex = which;

 

                                  // process user selection

                                  if (geomType.equalsIgnoreCase("Polygon")) {

                                       myListener.setType("POLYGON");

                                       toast.setText("Drag finger across screen to draw a Polygon. \nRelease finger to stop drawing.");

                                  } else if (geomType.equalsIgnoreCase("Polyline")) {

                                       myListener.setType("POLYLINE");

                                       toast.setText("Drag finger across screen to draw a Polyline. \nRelease finger to stop drawing.");

                                  } else if (geomType.equalsIgnoreCase("Point")) {

                                       myListener.setType("POINT");

                                       toast.setText("Tap on screen once to draw a Point.");

                                  }

 

                                  toast.show();

                            }

                      }).create();

      }

到此,绘图的实例的解析已经完成,是不是也那么难,只要熟练掌握MapOnTouchListener类和MultiPath类,绘图功能竟在掌控中。

        注:由于后面的代码越来越长,下面的示例只挑选一下复杂的代码来解释,像上面的变量初始化代码将不再列出,学习时请根据示例来对应相应代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值