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类,绘图功能竟在掌控中。

        注:由于后面的代码越来越长,下面的示例只挑选一下复杂的代码来解释,像上面的变量初始化代码将不再列出,学习时请根据示例来对应相应代码。
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AppWizard has created this drawGraphics application for you. This application not only demonstrates the basics of using the Microsoft Foundation classes but is also a starting point for writing your application. This file contains a summary of what you will find in each of the files that make up your drawGraphics application. drawGraphics.dsp This file (the project file) contains information at the project level and is used to build a single project or subproject. Other users can share the project (.dsp) file, but they should export the makefiles locally. drawGraphics.h This is the main header file for the application. It includes other project specific headers (including Resource.h) and declares the CDrawGraphicsApp application class. drawGraphics.cpp This is the main application source file that contains the application class CDrawGraphicsApp. drawGraphics.rc This is a listing of all of the Microsoft Windows resources that the program uses. It includes the icons, bitmaps, and cursors that are stored in the RES subdirectory. This file can be directly edited in Microsoft Visual C++. drawGraphics.clw This file contains information used by ClassWizard to edit existing classes or add new classes. ClassWizard also uses this file to store information needed to create and edit message maps and dialog data maps and to create prototype member functions. resdrawGraphics.ico This is an icon file, which is used as the application s icon. This icon is included by the main resource file drawGraphics.rc. resdrawGraphics.rc2 This file contains resources that are not edited by Microsoft Visual C++. You should place all resources not editable by the resource editor in this file.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值