我只是小能

---致力于.NET和WEBGIS
posts - 34, comments - 129, trackbacks - 2, articles - 0
  博客园 ::  :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

ArcGIS Server的最短路径开发系列(3)

Posted on 2008-06-03 08:52 长沙小能 阅读(722) 评论(20)  编辑 收藏 所属分类: ARCGIS SERVER

本文版权归小能所有,转载麻烦标明出处,谢谢! 同时写作过程中也参阅了大量其他网络文档,如果您觉得侵犯版权,请和我联系:chinazhousheng@gmail.com

   

网络分析之最短路径查询系列:

ArcGIS Server的最短路径开发系列(1)

ArcGIS Server的最短路径开发系列(2)

ArcGIS Server的最短路径开发系列(2)补充

ArcGIS Server的最短路径开发系列(3)

    前几天在群里面有朋友问我最短路径的事,他想实现一个可能分别在地图上取点设置起点与终点的功能,再计算最短路径的功能。由于最近很多事情,所以一直没有做,昨天花了一点时间,做了一下,其实还是一个状态保存的问题,其思路如下:

step1 :点击地图上的起点,获取起点的坐标,将其转换并保存至session  中

step2:获取终点坐标,判断session中是否有值,如果有,则获取起点

step3:计算最短路径(这在前面已经说过,稍微改变一下),显示在地图上

step4:清除session

大体思路就是这样,当然还有其他的思路,希望大家实现后共享,这次的代码很简单,我简单的发一点!


//获取屏幕点,并转换成Map点
      ESRI.ArcGIS.ADF.Web.Geometry.Point pnt = new ESRI.ArcGIS.ADF.Web.Geometry.Point();
      ESRI.ArcGIS.ADF.Web.UI.WebControls.PointEventArgs ptargs 
= null;
      ptargs 
= (PointEventArgs)args;
      pnt 
= ESRI.ArcGIS.ADF.Web.Geometry.Point.ToMapPoint(ptargs.ScreenPoint.X, ptargs.ScreenPoint.Y, mapctrl.Extent, (int)mapctrl.Width.Value, (int)mapctrl.Height.Value);

 

if (System.Web.HttpContext.Current.Session["beg_point"]==null)
       
{
           System.Web.HttpContext.Current.Session[
"beg_point"= pnt;

}


 

else
       
{

try
          
{
              
// Get the NAServer

              
using (NAServerProxy naServer = NAServerProxy.Create(SERVER_NAME, ROUTE_SERVICE_NAME, null))
              
{

                  
if (naServer == null)
                      
throw (new System.Exception("Could not find the web service."));

                  
// Get the NAServerSolverParams
                  string[] naLayers = naServer.GetNALayerNames(esriNAServerLayerType.esriNAServerRouteLayer);

                  NAServerSolverParams solverParams 
= naServer.GetSolverParameters(naLayers[0]) as NAServerSolverParams;

                  
// Set the NAServerRouteParams
                  NAServerRouteParams routeParams = solverParams as NAServerRouteParams;
                  DateTime time;

                  routeParams.ReturnMap 
= false;
                  routeParams.ReturnRouteGeometries 
= true;
                  routeParams.ReturnStops 
= true;
                  routeParams.ReturnDirections 
= false;

                  
// Geocode two addresses and create the stop network locations
                  NetAnalysis location = new NetAnalysis(mapctrl);
                  
////
                  PropertySet[] propSets = new PropertySet[2];
                  propSets[
0= GeocodeAddress(beg_point.X, beg_point.Y);//
                  propSets[1= GeocodeAddress(pnt.X, pnt.Y);//

                  NAServerPropertySets StopsPropSets 
= new NAServerPropertySets();
                  StopsPropSets.PropertySets 
= propSets;

                  NAServerRouteParams routeParams1 
= solverParams as NAServerRouteParams;
                  routeParams1.Stops 
= StopsPropSets;
                  
/////
                  // Solve the Route
                  NAServerSolverResults solverResults;
                  solverResults 
= naServer.Solve(solverParams);

                  
// Display results
                  location.OutputResults(solverResults);

              }


          }

          
catch (Exception exception)
          
{
              
//pnlDirectionSummary.Visible = false;
              
//lblDirections.Visible = false;
              
//lblTotalDistance.Visible = false;
              
//dataGridDirections.Visible = false;
              lblError.Text = "An error has occurred Mesage = " + exception.Message;
          }

private PropertySetProperty CreatePropertySetProperty(string key, object value)
    
{
        PropertySetProperty propSetProperty 
= new PropertySetProperty();
        propSetProperty.Key 
= key;
        propSetProperty.Value 
= value;
        
return propSetProperty;
    }




    
private PropertySet GeocodeAddress(double streetAddress_x, double streetAddress_y)
    
{

        
//寻找地理位置
        PointN addr_point = new PointN() ;
        addr_point.X 
= streetAddress_x;
        addr_point.Y 
= streetAddress_y;
        
//新建propertyset及PropertySetProperty数组
        PropertySet propSet = new PropertySet();
        PropertySetProperty[] propSetProperty_new 
= new PropertySetProperty[2];
        propSet.PropertyArray 
= propSetProperty_new;
        
//设置propSet结构
        propSet.PropertyArray[0= CreatePropertySetProperty("Shape", addr_point) as PropertySetProperty;
        propSet.PropertyArray[
1= CreatePropertySetProperty("Name""44"as PropertySetProperty;
        
return propSet;
    }

当然,可以添加效果,比如点击起点后,在地图上画一个标志!下面是结果图

image64

所有版权归小能所有哦!!!

Feedback

#1楼    回复  引用  查看    

2008-06-10 11:59 by SueJ      
很不错!学习!

#2楼 [楼主]   回复  引用  查看    

2008-06-11 09:35 by 长沙小能      
欢迎多多指教

#3楼    回复  引用  查看    

2008-06-11 10:38 by Josephgis      
很感谢楼主的demo,可我是个新手,看的有些乱,不知道怎么修改一下可以运行起来呢??

#4楼    回复  引用  查看    

2008-06-12 08:24 by Josephgis      
楼主,你发的demo是第一种方式还是第二种方式的啊??我想要第二种方式的,谢谢!!

#5楼 [楼主]   回复  引用  查看    

2008-06-12 08:45 by 长沙小能      
@Josephgis
已经发了,如果不懂,我建议先把flyingis上面的几个例子先学习一下,很不错的说

#6楼    回复  引用  查看    

2008-06-18 14:32 by Josephgis      
using (NAServerProxy naServer = NAServerProxy.Create(SERVER_NAME, ROUTE_SERVICE_NAME, null))
这行代码中的SERVER_NAME, ROUTE_SERVICE_NAME,分别对应什么呀,SERVER_NAME是data source名称吗??ROUTE_SERVICE_NAME是resource名称吗??
如果是的话怎么每次执行完string[] naLayers = naServer.GetNALayerNames(esriNAServerLayerType.esriNAServerRouteLayer);
就跳到catch (Exception exception)
{
//pnlDirectionSummary.Visible = false;
//lblDirections.Visible = false;
//lblTotalDistance.Visible = false;
//dataGridDirections.Visible = false;
lblError.Text = "An error has occurred Mesage = " + exception.Message;
}
而不是继续执行NAServerSolverParams solverParams = naServer.GetSolverParameters(naLayers[0]) as NAServerSolverParams;
以及后面的代码呢

#7楼 [楼主]   回复  引用  查看    

2008-06-21 11:30 by 长沙小能      
代码中的SERVER_NAME,分别表示你的机器名,也就是你的服务器名称,如果是你本机的话就是你的机器的名称, ROUTE_SERVICE_NAME表示你建立的网络服务的名称,这是最开始建立的,因此,你应该先设定好这两个

#8楼    回复  引用  查看    

2008-06-23 14:35 by Josephgis      
已经实现了功能,谢谢啊!!!
不过现在想再改进一点,就是通过鼠标点击选择点的时候,选完是否可以显示一个小十字表示选中的点啊?不然点了以后没有任何表示,感觉有些像没被选中一样。

#9楼    回复  引用  查看    

2008-06-23 17:19 by Josephgis      
对了,还有个问题,就是用Server自带的SanFrancisco.mxd文件可以实现最短路径,但是用我自己的一个mxd文件就显示不出来最短路径,不知道是不是对地图还有什么特殊的要求啊??谢谢!!!

#10楼 [楼主]   回复  引用  查看    

2008-06-25 09:43 by 长沙小能      
@Josephgis
这个非常简单,你新建一个Graphics Layers,把坐标显示出来就可以了,你自己的不行,是不是没有建网络分析图层呢?

#11楼    回复  引用  查看    

2008-06-25 10:09 by Josephgis      
一开始是没有建网络分析图层,后来创建了Network Dataset,但是还是不行,说是选取的点unlocated,不知道什么原因,是本身shape文件缺少什么属性呢还是创建Network Dataset时需要配置一些东西啊??

#12楼 [楼主]   回复  引用  查看    

2008-06-26 10:27 by 长沙小能      
建完以后先到arcmap里面试验一下,如果那里可以的话,相信server也是没有问题的

#13楼    回复  引用  查看    

2008-06-26 22:39 by Josephgis      
我现在新建了一个Graphics Layers,可是执行到函数OutputResults里的
ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality mapFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)CsMap.GetFunctionality(0);时,提示错误
无法将类型为
ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality
的对象强制转换为类型
ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality
单独一个地图服务没这错误,加了一个Graphics Layers就出现这个错误,是什么原因呢??

#14楼 [楼主]   回复  引用  查看    

2008-07-02 09:59 by 长沙小能      
@Josephgis
肯定啦,因为你多了一个图层,所以CsMap.GetFunctionality(0);要改成CsMap.GetFunctionality(1);

#15楼    回复  引用  查看    

2008-07-10 14:56 by Josephgis      
现在最短路径实现了,但是希望能用一个Gridview显示出最短路径的一些信息,不知道楼主有没做过啊??或者给些提示参考,谢谢!

#16楼 [楼主]   回复  引用  查看    

2008-07-10 15:30 by 长沙小能      
@Josephgis
当然是可以的,AGS自带例子里面就有,你可以研究一下,呵呵

#17楼    回复  引用  查看    

2008-07-10 15:50 by Josephgis      
不过AGS自带的例子是有locator文件的,带有direction的好像,一般的地图好像不行吧!

#18楼 [楼主]   回复  引用  查看    

2008-07-11 10:25 by 长沙小能      
@Josephgis
呵, 个人感觉没有技术问题,但实在现在时间比较紧,要不你钻研一下,咱们共享一下?

#19楼    回复  引用  查看    

2008-07-11 10:31 by Josephgis      
呵呵 技术上我估计是没太大问题,就是我不是地信专业的,对地图这块不太熟悉,网上查了下,说是一般道路地图是不带有方向性,好像要比较专业的网络数据地图才有,所以地图制作这块似乎我还没那水平呢,实在是棘手!

#20楼 [楼主]   回复  引用  查看    

2008-07-11 16:18 by 长沙小能      
@Josephgis
呵,我本科也不是地信,对这些也不是特别清楚,我推荐你加入一个QQ群,里面热心人还是有很多,56280495,也许能帮你解决问题