《慢性病地理信息系统——“路径查询”模块》项目研发阶段性总结-------------拓扑交通路线图与最佳路径分析

《慢性病地理信息系统——“路径查询”模块》项目研发阶段性总结

··························································

开发工具:Visual Studio 2015

关键技术:SuperMap iDesktop 9D、C#MVC

作者:邵亮华

完成模块功能:路经查询

撰写时间:2019-01-17

··························································

拓扑交通路线图与最佳路径分析

我在做GIS项目时,其中有个最佳路径分析的功能。当我调试项目里最佳路径分析的功能时,它老报一个错误,如图:

这个原因是我发布的交通服务的url不正确,所以在使用交通服务的url查询时报错。

这个最佳路径分析需要在拓扑构网构建一个二维网络(二维的交通路线)

一、打开SuperMap iDesktop 9D

 

1、先需要构建二维交通路线图

2、接下来会弹出一个构建二维网络数据集的窗体,点击文件夹的图标,添加想要拓扑的对象

 

3、由于构建二维的交通路线会有相交、重复等等错误数据的产生,会影响后续的数据处理和工作分析、影响数据的质量和可用性,SuperMap iDesktop 9D的打断容限,就能完美解决这个问题。

  • 打断容限值:单位与数据集的单位相同。用于控制线数据集打断时的节点选择。若两条线段的交点与点数据集中邻近点的距离在此容限范围内,则予以打断;否则不进行打断处理。
  • 节点容限:单位与数据集的单位相同。Fuzzy 容限即是图层的精度(分辨率),代表顶点(Vertex)或结点(Node)之间的最小距离。也就是说,在此距离之内的两个点可以视为重合。Fuzzy 容限一般为图层范围的1/10000 -- 1/1000000之间。为确保地图精度,本系统默认为1/1000000。

 

 

 

 

(往里面多添加几个零,将打断容限值最小化)

4、确认之后会它会自动生成一个数据集

5、打开刚刚新构建的数据集CasePath,点击交通分析下方的最佳路径分析调试一下是否执行成功,没有问题就将数据集CasePath拉到地图里即可。

 

二、打开SuperMap iserver发布地图(或者直接在SuperMap iDesktop 9D发布)

 

1、在SuperMap iserver发布地图

 

 

2、记住重要字段

3、分布地图后,打开SuperMap iserver的工作空间

 

4、找到该地图的交通网络分析服务

 

5、跳转到该服务地址,点击到下一级

 

 

6、再下一级

 

 

7、再再下一级

 

8、最后跳转到网络数据名的界面才是正确的网络交通路线url

 

 

 

 

 

三、项目执行

 

最佳路径查询的功能是我从数据库查询出数据再引用SuperMap iserver的最佳路径分析案例完成的功能,如图:

首先输入条件查询出该病人信息,点击病人弹出病人信息框,再点击《活动路径》按钮,在地图图层显示出路径坐标,再点击《查询》进行最佳路径分析

经典代码:

1、需要获取地图的url与网络交通分析的url

2、声明地图map、图层layer的变量和两种不同的图层控件,再为图层layer使用on()接口监听事件,方便添加图层控件

3、添加图层控件

JS部分

  function SelectPath() {

            var SeRecordNum = $("#SeRecordNum").val();

            var PathDate1 = $("#PathDate1").val();

            var PathDate2 = $("#PathDate2").val();

            if (SeRecordNum != null ) {

                if (PathDate1 != null && PathDate2 != null) {

                    var form = $("#SelectPath").serializeArray();

                    $.post("/Main/SelectCase", form, function (data) {   //数组查询、提交只能用post提交

                        if (data.length > 0) {

                            var marker = null;

                            var bool = true;

                            //初始化弹窗参数---------------------------------------------------

                            var size = new SuperMap.Size(25, 20);//标记的大小

                            var offset = new SuperMap.Pixel(-(size.w / 2), -size.h);//此类用x,y坐标描绘屏幕坐标(像素点)。

                            var icon = new SuperMap.Icon('/Content/layui-v2.3.0/layui-v2.3.0/layui/images/face/1.gif', size, offset);//图标类,表示显示在屏幕上的图标

                            //---------------------------------------------------

                            for (var i = 0; i < data.length; i++) {

                                //初始化标记覆盖物类

                                marker = new SuperMap.Marker(new SuperMap.LonLat(data[i].SiteCoordinateX, data[i].SiteCoordinateY), icon);//LonLat坐标

                                marker.CaseRecordID = data[i].CaseRecordID;

                                marker.CasePeopleID = data[i].CasePeopleID;

                                marker.SiteCoordinateX = data[i].SiteCoordinateX;

                                marker.SiteCoordinateY = data[i].SiteCoordinateY;

                                marker.CaseMC = data[i].CaseMC;

                                marker.RecordNum = data[i].RecordNum;

                                marker.RecordDate = data[i].RecordDate;

                                marker.CaseType = data[i].CaseType;

                                marker.CasePeopleMC = data[i].CasePeopleMC;

                                marker.Site = data[i].Site;

                                marker.Age = data[i].Age;

                                marker.Native = data[i].Native;

                                marker.Sex = data[i].Sex;

                               

                                //注册 click 事件,触发 mouseClickHandler()方法

                                marker.events.on({

                                    'click': Openfr,//单击触发

                                    'touchstart': Openfr,//当在触摸屏上对marker开始进行触摸时触发此事件。//假如要在移动端的浏览器也实现点击弹框,则在注册touch类事件

                                    "scope": marker,//大概是传参数把

                                });

                                markerLayer.addMarker(marker);//添加到图层

                            }

                        } else {

                            alert("没有查询出数据");

                        }

 

                    })

                }

                else {

                    alert("请输入日期");

                }

            }

            else {

                alert("请输入登记号");

            }

 

        }

         //病例的活动路径查询坐标事件

        function SelectCasePath(CasePeopleID) {

            var PathDate1 = $("#PathDate1").val();

            var PathDate2 = $("#PathDate2").val();

            var temp = "";

            if (PathDate1 > PathDate2) {

                temp = PathDate2;     

                PathDate2 = PathDate1;

                PathDate1 = temp;

            }

            $.post("/Main/SelectCasePath", { CasePeopleID: CasePeopleID, PathDate1: PathDate1, PathDate2: PathDate2 }, function (data) {

                if (data.length > 0) {

                    var marker = null;

                    var bool = true;

                    //初始化弹窗参数---------------------------------------------------

                    var size = new SuperMap.Size(25, 20);//标记的大小

                    var offset = new SuperMap.Pixel(-(size.w / 2), -size.h);//此类用x,y坐标描绘屏幕坐标(像素点)。

                   //图标类,表示显示在屏幕上的图标

                    var icon = new SuperMap.Icon('/Content/layui-v2.3.0/layui-v2.3.0/layui/images/face/4.gif', size, offset);

                    //---------------------------------------------------

                    for (var i = 0; i < data.length; i++) {

                        var X = data[i].PathX;

                        var Y = data[i].PathY;

                        //初始化标记覆盖物类

                        marker = new SuperMap.Marker(new SuperMap.LonLat(X,Y), icon);//LonLat坐标

                        markerLayer.addMarker(marker);//添加到图层

                        var point = new SuperMap.Geometry.Point(X, Y);

                          //获取点的坐标与 ID 的数组

                        nodeArray.push(point);

                    }

                } else {

                    alert("没有查询出数据");

                }

            })

         

        }

        var nodeArray = [], pathTime, pathListIndex = 0, routeCompsIndex = 0;

        // 病例的活动最佳分析路径查询

        function findPath() {

            var findPathService, parameter, analystParameter, resultSetting;

            resultSetting = new SuperMap.REST.TransportationAnalystResultSetting({

                returnEdgeFeatures: true,

                returnEdgeGeometry: true,

                returnEdgeIDs: true,

                returnNodeFeatures: true,

                returnNodeGeometry: true,

                returnNodeIDs: true,

                returnPathGuides: true,

                returnRoutes: true

            });

            analystParameter = new SuperMap.REST.TransportationAnalystParameter({

                resultSetting: resultSetting,

                weightFieldName: "SmLength"

//weightFieldName:阻力字段的名称,标识了进行网络分析时所使用的阻力字段,例如表示时间、长度等的字段都可以用作阻力字段。 该字段默值为服务器发布的所有耗费字段的第一个字段。

            });

            parameter = new SuperMap.REST.FindPathParameters({

                isAnalyzeById: false,       

//isAnalyzeById:事件点和设施点是否通过节点 ID 号来指定,默认为 false,即通过坐标点指定事件点和设施点。

                nodes: nodeArray,           //nodes:应为点的坐标与 ID 的数组

                hasLeastEdgeCount: false,    //hasLeastEdgeCount:是否按照弧段数最少的进行最佳路径分析

                parameter: analystParameter

            });

            if (nodeArray.length <= 1) {

                alert("站点数目有误");

            }

            findPathService = new SuperMap.REST.FindPathService(url2, {

                eventListeners: { "processCompleted": processPathCompleted }

            });

            findPathService.processAsync(parameter);

        }

        // 病例的活动最佳分析路径查询结果

        function processPathCompleted(findPathEventArgs) {

            var result = findPathEventArgs.result;

            if (pathListIndex < result.pathList.length) {

                addPath(result);

            } else {

                pathListIndex = 0;

                //线绘制完成后会绘制关于路径指引点的信息

                addPathGuideItems(result);

            }

        }

      

        //以动画效果显示分析结果

        function addPath(result) {

            if (routeCompsIndex < result.pathList[pathListIndex].route.components.length) {

                var pathFeature = new SuperMap.Feature.Vector();

                var points = [];

                for (var k = 0; k < 2; k++) {

                    if (result.pathList[pathListIndex].route.components[routeCompsIndex + k]) {

                        points.push(new SuperMap.Geometry.Point(result.pathList[pathListIndex].route.components[routeCompsIndex + k].x, result.pathList[pathListIndex].route.components[routeCompsIndex + k].y));

                    }

                }

                var curLine = new SuperMap.Geometry.LinearRing(points);

                pathFeature.geometry = curLine;

                pathFeature.style = style;

                lineLayer.addFeatures(pathFeature);

                //每隔0.001毫秒加载一条弧段

                pathTime = setTimeout(function () { addPath(result); }, 0.001);

                routeCompsIndex++;

            } else {

                clearTimeout(pathTime);

                routeCompsIndex = 0;

                pathListIndex++;

                allScheme(result);

            }

        }

//在路线上添加人型的图片

        function addPathGuideItems(result) {

            lineLayer.removeAllFeatures();

            //显示每个pathGuideItem和对应的描述信息

            for (var k = 0; k < result.pathList.length; k++) {

                var pathGuideItems = result.pathList[pathListIndex].pathGuideItems, len = pathGuideItems.length;

                for (var m = 0; m < len; m++) {

                    var guideFeature = new SuperMap.Feature.Vector();

                    guideFeature.geometry = pathGuideItems[m].geometry;

                    guideFeature.attributes = { description: pathGuideItems[m].description };

                    if (guideFeature.geometry.CLASS_NAME === "SuperMap.Geometry.Point") {

                        guideFeature.style = styleGuidePoint;

                    }

                    else {

                        guideFeature.style = style;

                    }

                    lineLayer.addFeatures(guideFeature);

                }

            }

          

        }

 

4、相关业务表和关系

四、开发总结

 

 我刚刚上手对于SuperMap iDesktop 9D的运用不是熟。一路摸索,从开始绘制二维地图然后到发布,这个复杂的过程让人有点烦躁,特别是里面的图层显示还有颜色的一系列的规划,密密麻麻的让人有点晕头,不过做出来倒是蛮有成就感的(虽然比百度地图、谷歌地图差了点)。

我在做在做这个GIS的项目最佳路径分析得到几个心得

一、在做这个交通路线的拓扑图时,一定要注意构建二维网络数据集的窗体里的打断容限(往里面多添加几个零,将打断容限值最小化)

由于构建二维的交通路线会有相交、重复等等错误数据的产生,会影响后续的数据处理和工作分析、影响数据的质量和可用性,SuperMap iDesktop 9D的打断容限,就能完美解决这个问题。

二、GIS的项目最佳路径分析:

1、要理清地图与图层的关系,想要在地图上显示想要的样式必须要在地图上加图层,我项目用了两种类型的图层控件一种是SuperMap.Layer.Markers用来创建有标签的图层,另一种是SuperMap.Layer.Vector用来矢量图层。

2、要理清地图url与与交通网络图的url,获取地图的url可以得到地图的数据,然后借助拓扑的交通网络图的url分析交通路线。

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/weixin_42193004/article/details/86531426