`

ArcGIS Server 开发系列(七)--物流配送

阅读更多
    ArcGIS Server开发系列的文章至今已经一年多了,虽然文章只有短短六篇,也比较基础,但值得高兴的是帮助了不少第一次接触ArcGIS Server的开发者,现在不少都已经完成一两个项目了,相信收获不小,有时间可以和大家一起分享经验。今天开始,我们将继续这个系列教程,争取覆盖ADF开发常用功能,以帮助更多的人轻松入门ADF开发。

    目标:
    实现简易的物流配送(VRP)

    准备工作:
    1.重新复习《ArcGIS Server 开发系列(六)--自定义 Tasks》
    2.准备数据"%ArcGISInstallDir%\DeveloperKit\SamplesNET\Server\data\SanFranciscoNetwork"
    3.发布NATasks.mxd地图服务,添加Network Analyst功能服务
    4.MapResourceManager中添加一个ArcGIS Server Local类型服务

    在这个应用中,多车配送的功能封装为一个自定义的Task,然后生成一个dll添加到ASP.Net工具箱中,由Web Mapping Application的Task Manager调用,更改自定义Task的Task Results Container为模板应用中的TaskResults1控件。

    Web Mapping Application大家已经非常熟悉,现在的重点就在如何利用ArcGIS Server实现VRP功能。VRP全称vehicle routing problem,属于NP难问题,基本没有统一的方法来解决所有的VRP问题,只能根据具体的情况采用最合适的算法,咱们下面就利用ArcGIS Server模拟一个简单的应用场景,实现多车物流的配送计算。

    自定义Task,需要构建Task的UI和业务逻辑,UI构建通过重写方法CreateChildControls完成,咱们最终实现的效果:



    相应的代码比较容易看懂,结合上面实现的UI效果图和代码注释就能明白每部分代码所完成的功能,实现代码:

protected override void CreateChildControls()
{
Controls.Clear();

base.CreateChildControls();

Create top level table#region Create top level table
System.Web.UI.WebControls.Table table = new System.Web.UI.WebControls.Table();
table.Width = System.Web.UI.WebControls.Unit.Pixel(240);

Controls.Add(table);
TableRow tr;
TableCell td;
#endregion

Orders Label#region Orders Label
tr = new TableRow();
td = new TableCell();
td.Text = "Select orders to service";
tr.Cells.Add(td);
table.Rows.Add(tr);
#endregion

Create and populate orders Listbox#region Create and populate orders Listbox
_oids = new List<int>();
_ordersCheckBoxList = new CheckBoxList();
_ordersCheckBoxList.ID = "OrdersCheckBoxList";
_ordersCheckBoxList.Width = System.Web.UI.WebControls.Unit.Point(200);

IServerContext serverContext = MapResourceLocal.ServerContextInfo.ServerContext;
IMap vrpMap = Utility.GetCartoIMap(MapInstance, "NA_MapResourceItem");
IFeatureLayer ordersInputFLayer = Utility.GetFeatureLayer("Stores", vrpMap);
IFeatureClass ordersInputFClass = ordersInputFLayer.FeatureClass;
int nameIndex = ordersInputFClass.FindField("Name");
IFeatureCursor ordersInputFCursor = ordersInputFClass.Search(null, false);
IFeature orderFeature = ordersInputFCursor.NextFeature();
while (orderFeature != null)
{
ListItem li = new ListItem(orderFeature.get_Value(nameIndex).ToString());
li.Selected = true;
_ordersCheckBoxList.Items.Add(li);
_oids.Add(orderFeature.OID);

orderFeature = ordersInputFCursor.NextFeature();
}
#endregion

OrdersPanel#region OrdersPanel
tr = new TableRow();
td = new TableCell();
Panel ordersPanel = new Panel();
ordersPanel.Height = 200;
ordersPanel.Width = 240;
ordersPanel.BorderColor = System.Drawing.Color.Black;
ordersPanel.BorderStyle = BorderStyle.Inset;
ordersPanel.BorderWidth = 1;
ordersPanel.ScrollBars = ScrollBars.Vertical;
ordersPanel.Controls.Add(_ordersCheckBoxList);
td.Controls.Add(ordersPanel);
tr.Cells.Add(td);
table.Rows.Add(tr);
#endregion

Get Directions Button#region Get Directions Button
tr = new TableRow();
tr.Attributes.Add("align", "right");
td = new TableCell();
td.ColumnSpan = 2;

HtmlInputButton button = new HtmlInputButton();
button.Value = "Get Directions";
button.ID = "execute";

td.Controls.Add(button);
tr.Cells.Add(td);
table.Rows.Add(tr);
#endregion

OnClick Event for executing task#region OnClick Event for executing task
string argument = string.Format("'selectedIndexes=' + getCheckedItemIndexes('{0}', '{1}')", _ordersCheckBoxList.ClientID, _ordersCheckBoxList.Items.Count);
string onClick = string.Format("executeTask({0},\"{1}\");", argument, CallbackFunctionString);
button.Attributes.Add("onclick", onClick);
#endregion

// Access the graphics layer so it is created and shown in the TOC
ElementGraphicsLayer pointsGraphicsLayer = PointsGraphicsLayer;
}

    CreateChildControls用于构建VRPTask UI,除了界面要素之外,还需要从源数据中读取商店信息,如读取商店名称显示在界面上,当VRPTask中的商店被勾选上时,车辆将为该商店送货。商店供货信息存储在数据源中单独的一个图层中stores.shp,包含商店所需的货物数量和预计提供服务的时间。


    VRPTask UI完成之后,接下来要设计VRP的业务逻辑,ArcGIS 9.3 Network Extension提供了一个基本的VRP解决方案,因此我们在发布NATasks服务的时候需要勾选Network Analyst功能,通过ServerContext去远程调用AO方法。

    第一步,获取VRP分析图层。

IServerContext serverContext = MapResourceLocal.ServerContextInfo.ServerContext;
IMap vrpMap = Utility.GetCartoIMap(MapInstance, "NA_MapResourceItem");
IGPMessages gpMessages = serverContext.CreateObject("esriGeodatabase.GPMessages") as IGPMessages;

INALayer2 vrpNALayer = Utility.GetNALayer("Vehicle Routing Problem", vrpMap);
INAContext vrpNAContext = vrpNALayer.CopyContext();
INAContextEdit vrpNAContextEdit = vrpNAContext as INAContextEdit;
vrpNAContextEdit.Bind(vrpNALayer.Context.NetworkDataset, gpMessages);

    第二步,获取配送中心信息、商店信息、车辆信息和司机午餐时间。

IFeatureLayer depotsInputFLayer = Utility.GetFeatureLayer("DistributionCenters", vrpMap);
IFeatureClass depotsInputFClass = depotsInputFLayer.FeatureClass;
IFeatureCursor depotsInputFCursor = depotsInputFClass.Search(null, false);
LoadAnalysisClass(serverContext, vrpNAContext, "Depots", depotsInputFCursor as ICursor);

// Load Orders
IFeatureLayer ordersInputFLayer = Utility.GetFeatureLayer("Stores", vrpMap);
IFeatureClass ordersInputFClass = ordersInputFLayer.FeatureClass;
IFeatureCursor ordersInputFCursor = ordersInputFClass.GetFeatures(oids, true);
LoadAnalysisClass(serverContext, vrpNAContext, "Orders", ordersInputFCursor as ICursor);

// Load the Routes
ITable routesInputTable = Utility.GetStandaloneTable("Vehicles", vrpMap).Table;
ICursor routesInputCursor = routesInputTable.Search(null, true);
LoadAnalysisClass(serverContext, vrpNAContext, "Routes", routesInputCursor as ICursor);

// Load the Breaks
ITable breaksInputTable = Utility.GetStandaloneTable("LunchBreaks", vrpMap).Table;
ICursor breaksInputCursor = breaksInputTable.Search(null, true);
LoadAnalysisClass(serverContext, vrpNAContext, "Breaks", breaksInputCursor as ICursor);

// Message all of the network analysis agents that the analysis context has changed
vrpNAContextEdit.ContextChanged();

    配送中心、商店信息均存储在物理图层中,分别对应DistributionCenters.shp、Stores.shp,车辆信息和司机午餐时间存储于Table表中。车辆Table包含物流配送过程中和车辆相关的一切信息,如起止配送中心、承载量、最多订单数、发车时间、最长驾驶时间、最长行驶距离等,司机午餐Table包含允许的午餐持续时间、允许的午餐时间范围等,这些都将用于ArcGIS VRP模型的计算中。

    第三步,路径计算,做过ArcEngine Network Analyst开发的工程师对INASolver、INAVRPSolver一定非常熟悉了,调用过程比较简单,路径计算的同时处理系统反馈的消息信息。

gpMessages.Clear();
INASolver naSolver = vrpNAContext.Solver;
INAVRPSolver vrpSolver = naSolver as INAVRPSolver;
vrpSolver.GenerateInternalRouteContext = true; // Required for true-shape and directions
vrpSolver.DefaultDate = DateTime.Today;        // Set the default date to be today

bool partialResults = naSolver.Solve(vrpNAContext, gpMessages, null);

// report errors
if (partialResults || gpMessages.Count > 0)
{
StringBuilder sErrors = new StringBuilder();
for (int i = 0; i < gpMessages.Count; i++)
sErrors.AppendLine(gpMessages.GetMessage(i).Description);

Results = sErrors.ToString();
return;
}

    第四步,处理结果,VRP计算后最重要的结果就是生成的车辆分配情况、配送顺序和车辆配送路径,将车辆行驶的详细信息以图文并茂的方式展示出来。

// Get Map's Spatial Reference (to project output geometries
ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality mf = (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)MapInstance.GetFunctionality("NA_MapResourceItem");
SpatialReference mapSpatialReference = mf.MapDescription.SpatialReference;

// Output result Routes and Stops
Utility.OutputRoutesAsGraphics(serverContext, vrpNAContext, RoutesGraphicsLayer, mapSpatialReference);
Utility.OutputOrdersAsGraphics(serverContext, vrpNAContext, PointsGraphicsLayer, mapSpatialReference);

// Create results node
TaskResultNode parentTaskResultNode = Utility.CreateTaskResultNode("VRP Results");
parentTaskResultNode.Expanded = true;

// Get the Route Context from the results to use for directions
INAVRPResult vrpResult = vrpNAContext.Result as INAVRPResult;
INAContext routeNAContext = vrpResult.InternalRouteContext;

// Loop through the resulting routes and add items for each route (vehicle)
ISet routeSet = serverContext.CreateObject("esriSystem.Set") as ISet;
IFeatureClass routeRoutesFClass = routeNAContext.NAClasses.get_ItemByName("Routes") as IFeatureClass;
int routeNameIndex = routeRoutesFClass.FindField("Name");
IFeatureCursor routesRouteFCursor = routeRoutesFClass.Search(null, false);
int routeNumber = 0;
IFeature routeFeature = routesRouteFCursor.NextFeature();
while (routeFeature != null)
{
string routeName = routeFeature.get_Value(routeNameIndex).ToString();

Choose color for each route#region Choose color for each route

TaskResultNode routeTaskResultNode = Utility.CreateTaskResultNode(routeName);
routeTaskResultNode.TextCellStyleAttributes.Add("font-weight", "bold");
routeTaskResultNode.TextCellStyleAttributes.Add("font-size", "12");
if (routeNumber == 0)
routeTaskResultNode.TextCellStyleAttributes.Add("color", System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.Blue));
else if (routeNumber == 1)
routeTaskResultNode.TextCellStyleAttributes.Add("color", System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.Purple));
else if (routeNumber == 2)
routeTaskResultNode.TextCellStyleAttributes.Add("color", System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.Green));
else if (routeNumber == 3)
routeTaskResultNode.TextCellStyleAttributes.Add("color", System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.Brown));
#endregion

routeTaskResultNode.Expanded = true;
parentTaskResultNode.Nodes.Add(routeTaskResultNode);

// Add Statistics
TaskResultNode vrpRouteStatisticsNode = Utility.GetVRPRouteStatisticsNode(serverContext, vrpNAContext, routeName);
vrpRouteStatisticsNode.TextCellStyleAttributes.Add("font-weight", "bold");
routeTaskResultNode.Nodes.Add(vrpRouteStatisticsNode);

// Add Directions

// Get the directions for the specified route
routeSet.RemoveAll();
routeSet.Add(routeFeature);// Get Directions

// Generate the directions
TaskResultNode directionsTaskResultNode = Utility.GetDirectionsNode(false, routeNAContext, routeSet);
directionsTaskResultNode.TextCellStyleAttributes.Add("font-weight", "bold");

// Add the directions to the results node
routeTaskResultNode.Nodes.Add(directionsTaskResultNode);

routeNumber++;
routeFeature = routesRouteFCursor.NextFeature();
}

    通过上述过程,完成了VRPTask的UI设计和业务逻辑程序,之后需要将应用重新生成为dll,添加到ASP.Net工具箱中,方便WebGIS应用调用该Task控件,我们在Web Mapping Application模板应用程序基础上添加VRPTask,运行后效果:
    数据源vehicles table中包含三辆汽车的记录,在应用中勾选需要进行配送的商店,

    例如选择15家商店,点击"Get Directions"执行VRP计算,生成结果如下所示:
   

    我们可以发现,很多路径配送需要考虑的问题ArcGIS VRP模型都提供了一套非常简便的解决方案,能够解决一般情况下的VRP问题,但是就如文章前面所说,VRP没有统一的解决方法,但是至少我们可以选择基于ArcGIS Server进行扩展,请思考:
    1.地图数据结构。
    2.配送分区怎么考虑。
    3.配送效率测试。
    4.结对订单。




  • 大小: 6.8 KB
  • 大小: 96.5 KB
  • 大小: 102.4 KB
分享到:
评论

相关推荐

    ArcGIS Server 开发系列(七)--物流配送.doc

    ### ArcGIS Server 开发系列(七) -- 物流配送 #### 一、概述 本文档作为 ArcGIS Server 开发系列教程的一部分,旨在探讨如何利用 ArcGIS Server 技术实现物流配送系统的开发。物流配送是现代商业活动中不可或缺的...

    arcgis-runtime-sdk-java-guide-100.4.0

    - 适用于物流配送、紧急救援等应用场景。 - **路线到最近的位置:** - 找出到达一系列位置中最近的一个的最佳路径。 - 适用于快递配送、紧急响应等场景。 #### 十、数据分析 - **地理处理:** - 执行地理处理...

    基于ArcGIS Server的最短路径关键技术

    在WebGIS中,最短路径分析是一项极为重要的功能,尤其在交通规划、物流配送、城市规划等领域有广泛应用。本文以基于ArcGIS Server的最短路径关键技术为核心,探讨其实现机制,并结合ASP.NET平台进行具体应用。 ####...

    利用ArcGIS Server实现BS架构的车辆监控系统

    本文介绍了如何利用ArcGIS Server构建一个基于B/S架构的车辆监控系统。该系统结合了全球卫星定位系统(GPS)技术和地理信息系统(GIS)技术,实现了对...这种系统在交通管理、物流配送、公共安全等领域有广泛应用价值。

    Arcgis SERVER网络分析代码包括测试数据

    这对于开发地理定位应用,如导航系统或物流配送规划,非常有用。 在实际操作中,网络分析还涉及到许多其他方面,例如定义限制条件(如单行道、限速区)、考虑交通流量、设定权重(如行驶时间、距离、费用),以及...

    Arcgis_server_查询地图

    为了更具体地理解ArcGIS Server查询地图功能的实际应用,我们可以考虑一个假设场景:一家物流公司希望优化其配送路线,减少运输成本和时间。他们可以利用ArcGIS Server查询地图的功能,输入各个配送点的位置信息,...

    ArcGIS Server 网络分析功能实现源码(java)

    总的来说,通过学习和理解这个示例,开发者可以掌握在Java环境中如何利用ArcGIS Server的网络分析功能,这对于构建基于GIS的物流配送、紧急响应、公共交通规划等应用具有重要价值。记住,实际应用中,还需要根据具体...

    arcgis server 网络分析

    在ArcGIS Server中,最短路径分析是网络分析的重要组成部分,它可以帮助用户找到两点之间最具效率的路线,这在物流配送、交通规划、紧急响应等领域有着广泛的应用。 在进行最短路径分析之前,你需要确保ArcGIS ...

    ArcGIS_最优路径

    这项技术广泛应用于交通规划、物流配送、紧急响应等领域,它能帮助决策者制定高效、节省时间和资源的路线。 在ArcGIS Server中,路由服务是核心组件之一,通过集成“ArcGIS Routing”标签所示的功能,可以实现复杂...

    ArcGIS Engine10.0的开发

    这在交通规划、物流配送等领域有着广泛的应用。 在开发过程中,ArcGIS Engine支持多种编程语言,如.NET Framework(C#、VB.NET)、Java等,这为不同背景的开发者提供了便利。对于.NET开发者,可以通过COM Interop...

    ArcGIS.Server.9.2.DotNet3.rar_arcgis lyx_路径分析

    网络分析是GIS中的一个重要领域,它涉及到在图论模型中的路线选择问题,如交通规划、物流配送、应急响应等实际场景。 最短路径分析是网络分析的核心内容,其目标是在网络中找到从起点到终点的最短路径。在地理空间...

    ArcGIS 10 产品白皮书

    - **网络分析:** ArcGIS还支持网络分析扩展模块(ArcGIS Network Analyst),用于交通规划、物流配送等场景下的路径分析和选址优化。 以上是基于《ArcGIS 10 产品白皮书》提供的关键知识点梳理。ArcGIS 10 作为一款...

    c# arcgis.rar

    这在物流配送、交通规划等领域有着广泛的应用。 三、MapServerBrowser组件 MapServerBrowser是ArcGIS的一个重要组件,用于浏览和管理地图服务。通过C#,我们可以控制MapServerBrowser,实现动态加载地图服务、查询...

    Server Java NetWork Analysis

    - **使用场景:** 如物流配送、交通规划等领域。 #### 五、扩展知识点 ##### 1. 自定义工具按钮 - 为了实现用户可以在地图上直接选择起点、终点以及路障点的目标,需要在地图界面上添加自定义工具按钮。 - 这些...

    ArcGIS地理信息系统

    - 网络分析:解决基于网络的路径选择问题,如公交线路规划、物流配送路线优化等。 - 地形分析:利用数字高程模型进行坡度、坡向、流域划分等分析,为环境评价和工程设计提供依据。 **4. 制图与发布** ArcGIS不仅...

    测绘资料-ArcGIS地理信息系统空间分析_光盘数据.rar

    在物流配送、交通规划等领域有广泛应用。 4. 地形分析:ArcGIS提供了强大的地形处理工具,如坡度、坡向、高程剖面等,用于理解和模拟地形特征,这对于环境评估、水利规划等项目至关重要。 光盘数据中可能包含了一...

    arcgis js api最优路径分析

    这在物流配送、交通规划、紧急救援等诸多领域有着广泛的应用。 首先,我们要理解ArcGIS JS API 的基本概念。它是由Esri公司提供的,基于JavaScript的库,用于在网页上创建地图和进行地理空间分析。API 提供了丰富的...

Global site tag (gtag.js) - Google Analytics