ArcGIS for Android 查找最短路径

本文介绍如何在ArcGIS for Android (10.1.1)中实现在线网络分析,通过RoutingTask类的solve方法进行路径分析,并展示了具体的实现代码。应用中包括增加停靠点、执行最短路径查找等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ArcGIS for Android(10.1.1)只支持在线的网络分析,执行路径分析可以通过RoutingTask类的solve方法来进行,通过给slove方法传递RoutingParameters类型的参数,可以最短路径的查找。而要成功执行路径分析,就必须发布网络分析服务,比较麻烦,下面的代码中使用的服务是arcgisonline.上已经发布的服务。以下代码程序的界面如下:


界面包含两控件:TextView和MapView,在执行路径分析前单击MapView会增加路径分析的停靠点,长按MapView会根据停靠点(至少要两个停靠点)执行查找最短路径的操作,执行成功之后会在TextView中显示相关的路径信息,这时候单击查询的路径,会选中路径片段,相关的信息也会在TextView上显示。单击TextView就会清空所有结果,恢复到原始状态。(代码绝大部分来自API中的Routing这个例子)

public class NATestActivity extends Activity {
	
	MapView mMapView ;
	private TextView tv_label;
	private SpatialReference mapSR=SpatialReference.create(102100);;
	private SpatialReference NASR=SpatialReference.create(4326);
	private GraphicsLayer routeLayer;//查询到的整条路径
	private GraphicsLayer semLayer;//查询到的路径片段
	private List<Point> stopPoints;//保存所有的停靠点
	private Symbol stopSymbol;//停靠点的符号
	 private SimpleLineSymbol hiderSym;//查询到的路径的片段,设置透明将其“隐藏”
	 private SimpleLineSymbol showSym;//当路径片段被选中的时候,显示的符号
	 private int selectID=-1;//被选中的路径片段的ID(-1表示没有变选中)
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
		mMapView = (MapView) findViewById(R.id.map);
		
		tv_label=(TextView) findViewById(R.id.directionsLabel);
		ArcGISTiledMapServiceLayer atl=new ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
		mMapView.addLayer(atl);
		//mapSR=mMapView.getSpatialReference();
		routeLayer=new GraphicsLayer();
		semLayer=new GraphicsLayer();
		stopPoints=new ArrayList<Point>();
		mMapView.addLayer(routeLayer);
		mMapView.addLayer(semLayer);
		stopSymbol=new SimpleMarkerSymbol(Color.RED, 3, SimpleMarkerSymbol.STYLE.CIRCLE);
		hiderSym=new SimpleLineSymbol(Color.WHITE, 1);
		//设置成透明,使其处于“隐藏”状态
		hiderSym.setAlpha(100);
		showSym=new SimpleLineSymbol(Color.RED, 4);
		mMapView.setOnStatusChangedListener(new OnStatusChangedListener() {
			
			public void onStatusChanged(Object arg0, STATUS arg1) {
				if(arg0==mMapView&&arg1==STATUS.INITIALIZED){
					Point p= new Point( -122.084095,37.422006);
					mMapView.zoomToResolution((Point) GeometryEngine.project(p, NASR, mapSR), 20.0);
					Log.i("OK", "KKK");
					//单击地图添加要经过的位置
					mMapView.setOnSingleTapListener(new MyOnSintTapLis());
					//长按开始执行路径分析
					mMapView.setOnLongPressListener(new MyOnPressLis());
					//设置tv_label的单击事件为,清楚所以选中的和查询的结果
					tv_label.setOnClickListener(new OnClickListener() {
						public void onClick(View v) {
							semLayer.removeAll();
							routeLayer.removeAll();
							selectID=-1;
							tv_label.setText("");
						}
					});
				}
			}
		});

    }
    
    /**
     * 单击地图事件,先判断是semLayer里面是否为空,
     * 如果为空就增加停靠点,如果不为空则进行选择semLayer中的内容操作
     */
    class MyOnSintTapLis implements OnSingleTapListener{
		public void onSingleTap(float arg0, float arg1) {
			
			if(semLayer.getNumberOfGraphics()==0){//增加停靠点
				Point mapPoint=mMapView.toMapPoint(arg0, arg1);
				routeLayer.addGraphic(new Graphic(mapPoint, stopSymbol));
				stopPoints.add((Point)GeometryEngine.project(mapPoint, mapSR, NASR));
			}else{//选中路径片段
				int[] ids= semLayer.getGraphicIDs(arg0, arg1, 20);
				if(ids.length>0){//有路径片段被选中
					//回复已经被选中的路径片段为透明
					semLayer.updateGraphic(selectID,hiderSym);
					//设置新的被选中的路径片段为被选中状态
					selectID=ids[0];
					semLayer.updateGraphic(selectID,showSym);
					//取得被选中的路径片段和其属性
					Graphic selectGraphic=semLayer.getGraphic(selectID);
					String text=(String) selectGraphic.getAttributeValue("text");
					double time=(Double) selectGraphic.getAttributeValue("time");
					double length=(Double) selectGraphic.getAttributeValue("length");
					tv_label.setText("长度:"+length+"米,  时间:"+time+"分钟,描述:"+text);
					//缩放到被选中的片段
					mMapView.setExtent(selectGraphic.getGeometry(),100);
				}
			}
		}
    	
    }
    //长按地图事件
    class MyOnPressLis implements OnLongPressListener{
		public void onLongPress(float arg0, float arg1) {
		if(stopPoints.size()<2){
			Toast.makeText(getApplicationContext(), "必须至少选择两个停靠点", 0).show();
			return;
		}
		Toast.makeText(getApplicationContext(), "开始查找最短路径", 1).show();
			new Thread(){//网络分析不能再主线程中进行
				public void run() {
					//准备参数
					RoutingParameters rp=new RoutingParameters();
					NAFeaturesAsFeature naferture=new NAFeaturesAsFeature();
					//设置查询停靠点,至少要两个
					for(Point p :stopPoints){
						StopGraphic sg=new StopGraphic(p);
						naferture.addFeature(sg);
					}
					rp.setStops(naferture);
					//设置查询输入的坐标系跟底图一样
					rp.setOutSpatialReference(mapSR);
					  RoutingTask rt = new RoutingTask( 
			                  "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Network/USA/NAServer/Route",
			                  null);
					  try {
						  //执行操作
						RoutingResult rr=rt.solve(rp);
						runOnUiThread(new MyRun(rr));
					} catch (Exception e) {
						e.printStackTrace();
						Looper.prepare();
						Toast.makeText(getApplicationContext(), e.getMessage(), 1).show();
						Looper.loop();
					}
				
				}
			}.start();
		}
    	
    }
    
    class MyRun implements Runnable{
    	private RoutingResult rr;
		public MyRun(RoutingResult rr) {
			this.rr=rr;
		}
		public void run() {
				stopPoints.clear();
				//得到查询到的路径
				Route r=rr.getRoutes().get(0);
				//往tv_label中赋值
				tv_label.setText("中长度:"+r.getTotalLength()+"米,  总时间:"+r.getTotalTime()+"分钟,描述:"+r.getRouteName());
				//将这条查询到路径放入routeLayer中
				Graphic routeGraphic=new Graphic(r.getRoute().getGeometry(),new SimpleLineSymbol(Color.BLUE, 3));
				routeLayer.addGraphic(routeGraphic);
				mMapView.setExtent(routeGraphic.getGeometry(),100);
				List<RoutingDirection>  routeDirs=rr.getRoutes().get(0).getRoutingDirections();
				
				//取得查询到的路径片段,和其属性,放入到semLayer中,供点击查询每个片断信息
				Map<String ,Object> atts=new HashMap<String,Object>();
				for(RoutingDirection routeDir: routeDirs){
				atts.put("text", routeDir.getText());
				atts.put("length", routeDir.getLength());
				atts.put("time", routeDir.getTime());
				Graphic dirGraphic=new Graphic(routeDir.getGeometry(), hiderSym, atts, null);
				semLayer.addGraphic(dirGraphic);	
			}
		}
    	
    }

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

}


结果:



下载全部代码


评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值