ArcGIS API For JS之网络分析(临近设施分析)
ArcGIS 提供两种网络分析,即基于Geometric Network的有向网络或者设施网络和基于Network Dataset的无向网络,在这里网络的分析指后者,ArcGIS api支持网络分析中的最短路径分析、服务区分析、临近设施分析。本文主要讲的是临近设施分析,关于发布网络服务在这里就不在叙述了,三种分析发布相同,只是在后台ArcMap中处理方式有点区别。
一、概述
1、概念
临近设施服务计算事件和设施之间的行驶成本,并决定那一个距离最近,最后给出最佳的路径,在这里认为,这算是最短距离的升级版本
2、相关的类
- ClosestFacilityTask(执行命令,声明需要一个Rest资源,即NAServer服务)
- ClosestFacilityParameters(参数)
- ClosestFacilitySolveResult(处理结果)(这里没用到,该类用处非常大)
二、参数声明与设置
closestFacilityTask = new ClosestFacilityTask("http://localhost:6080/arcgis/rest/services/Test/CloseFacilityTest/NAServer/CloseFacility");
//临近设施分析参数
var params = new ClosestFacilityParameters();
//单位
params.impedenceAttribute = "Miles";
params.defaultCutoff = 7.0;
//是否返回事件信息
params.returnIncidents = false;
//是否返回路径
params.returnRoutes = true;
//路径是否有参数
params.returnDirections = true;
//服务点
params.facilities = new FeatureSet();
//事件点
params.incidents = new FeatureSet();
//点障碍
params.pointBarriers = new FeatureSet();
//空间参考
params.outSpatialReference = map.SpatialReference;
在这里有很多参数可以设置,服务点、事件点、路径、空间参考,是必须要设置的,其他参数可以根据自己需要设置,这里FeatureSet是要素类的轻量级的表示,相当于地理数据中的一个要素类,Feature的集合,FeatureSet中的每个Feature可能包含Geometry、属性、符号、InfoTemplate。FeatureSet是api和arcgis server通讯的非常重要的对象。当使用查询、地理出咯i和路径分析的时候,FeatureSet常常作为这些分析功能的输入或输出参数。
三、符号样式
//服务点符号样式
var facilityPointSymbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_SQUARE,
20,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SOLID,
new Color([89, 95, 35]), 2
),
new Color([130, 159, 83, 0.40])
);
//事件点符号样式
var incidentPointSymbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_CIRCLE,
16,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SOLID,
new Color([89, 95, 35]), 2
),
new Color([130, 159, 83, 0.40])
);
//障碍点的符号样式
var barrierSymbol = new SimpleMarkerSymbol();
barrierSymbol.style = SimpleMarkerSymbol.STYLE_X;
barrierSymbol.setSize(12);
barrierSymbol.setColor(new Color("#f1a340"));
incidentsGraphicsLayer = new GraphicsLayer();
//结果路径线符号样式
var routePolylineSymbol = new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SOLID,
new Color("#0078df"),
4.0
);
四、分析结果处理
function showRoute(solveResult) {
//路径分析的结果
var routeResults = solveResult.routes;
//路径分析的长度
var res = routeResults.length;
if (res > 0) {
for (var i = 0; i < res; i++) {
var graphicroute = routeResults[i];
var graphic = graphicroute;
graphic.setSymbol(routePolylineSymbol);
map.graphics.add(graphic);
}
}
else {
alert("没有返回结果");
}
}
五、全部源码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Closest Facilities</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.25/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.25/esri/css/esri.css">
<style type="text/css">
#map
{
width: 100%;
height: 600px;
border: 1px solid #000;
}
</style>
<script src="https://js.arcgis.com/3.25/"></script>
<script src="../Scripts/jquery-1.7.1.js"></script>
</head>
<body>
<div id="map"></div>
<input id="server" type="button" value="服务点" />
<input id="eventPoint" type="button" value="事件点" />
<input id="barriers" type="button" value="障碍点" />
<input id="analyse" type="button" value="分析" />
<input id="clear" type="button" value="清除" />
<script>
require([
"dojo/on",
"dojo/dom",
"dojo/_base/array",
"esri/Color",
"dojo/parser",
"dijit/registry",
"esri/urlUtils",
"esri/map",
"esri/lang",
"esri/graphic",
"esri/InfoTemplate",
"esri/layers/GraphicsLayer",
"esri/renderers/SimpleRenderer",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/geometry/Point",
"esri/tasks/FeatureSet",
"esri/tasks/ClosestFacilityTask",
"esri/tasks/ClosestFacilityParameters",
"esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/TextSymbol",
"dijit/form/ComboBox",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane"
], function (
on, dom, array, Color, parser, registry,
urlUtils, Map, esriLang, Graphic, InfoTemplate, GraphicsLayer, SimpleRenderer, ArcGISDynamicMapServiceLayer,
Point, FeatureSet,
ClosestFacilityTask, ClosestFacilityParameters,
SimpleMarkerSymbol, SimpleLineSymbol, TextSymbol
) {
var incidentsGraphicsLayer, routeGraphicLayer, closestFacilityTask;
var map = new Map("map");
var layer = new esri.layers.ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/Test/CloseFacilityTest/MapServer");
map.addLayer(layer)
closestFacilityTask = new ClosestFacilityTask("http://localhost:6080/arcgis/rest/services/Test/CloseFacilityTest/NAServer/CloseFacility");
//临近设施分析参数
var params = new ClosestFacilityParameters();
//单位
params.impedenceAttribute = "Miles";
params.defaultCutoff = 7.0;
//是否返回事件信息
params.returnIncidents = false;
//是否返回路径
params.returnRoutes = true;
//路径是否有参数
params.returnDirections = true;
//服务点
params.facilities = new FeatureSet();
//事件点
params.incidents = new FeatureSet();
//点障碍
params.pointBarriers = new FeatureSet();
//空间参考
params.outSpatialReference = map.SpatialReference;
//服务点符号样式
var facilityPointSymbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_SQUARE,
20,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SOLID,
new Color([89, 95, 35]), 2
),
new Color([130, 159, 83, 0.40])
);
//事件点符号样式
var incidentPointSymbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_CIRCLE,
16,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SOLID,
new Color([89, 95, 35]), 2
),
new Color([130, 159, 83, 0.40])
);
//障碍点的符号样式
var barrierSymbol = new SimpleMarkerSymbol();
barrierSymbol.style = SimpleMarkerSymbol.STYLE_X;
barrierSymbol.setSize(12);
barrierSymbol.setColor(new Color("#f1a340"));
incidentsGraphicsLayer = new GraphicsLayer();
//结果路径线符号样式
var routePolylineSymbol = new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SOLID,
new Color("#0078df"),
4.0
);
//定义一个标志
//selectPointID=0什么都不做
//selectPointID=1是添加服务点
//selectPointID=2是添加事件点
//selectPointID=3是添加障碍点
var selectPointID;
//添加服务点
$("#server").click(function () {
selectPointID = 1;
});
//添加事件点
$("#eventPoint").click(function () {
selectPointID = 2;
});
//添加障碍点
$("#barriers").click(function () {
selectPointID = 3;
});
//清除所有障碍、事件、服务点和路径线
on(map, "mouse-down", function (evt) {
//通过selectPointID判断是添加是停靠点还是障碍点
switch (selectPointID) {
case 0:
break;
case 1:
//获得服务点的坐标
var pointServer = evt.mapPoint;
var gr = new Graphic(pointServer, facilityPointSymbol);
//构建服务点的参数
params.facilities.features.push(gr);
break;
case 2:
//获得事件点的坐标
var pointEvent = evt.mapPoint;
var gr = new Graphic(pointEvent, incidentPointSymbol);
//构建事件点的参数
params.incidents.features.push(gr);
break;
case 3:
//获得障碍点的坐标
var pointBarrier = evt.mapPoint;
var gr = new Graphic(pointBarrier, barrierSymbol);
//构建障碍点的参数
params.pointBarriers.features.push(gr);
break;
}
//如果selectPointID不等于0,将点的坐标在地图上显示出来
if (selectPointID != 0) {
addTextPoint("服务点", pointServer, facilityPointSymbol);
addTextPoint("事件点", pointEvent, incidentPointSymbol);
addTextPoint("障碍点", pointBarrier, barrierSymbol);
}
});
//文本符号:文本信息,点坐标,符号
function addTextPoint(text, point, symbol) {
var textSymbol = new TextSymbol(text);
textSymbol.setColor(new Color([128, 0, 0]));
var graphicText = Graphic(point, textSymbol);
var graphicpoint = new Graphic(point, symbol);
//用默认的图层添加
map.graphics.add(graphicpoint);
map.graphics.add(graphicText);
}
//分析执行事件
$("#analyse").click(function () {
selectPointID = 0;
//如果服务点或者事件点的个数有一个为0,提示用户参数输入不对
if (params.facilities.features.length == 0 || params.incidents.features.length == 0) {
alert("输入参数不全,无法分析");
return;
}
//执行路径分析函数
closestFacilityTask.solve(params, showRoute)
});
//处理路径分析返回的结果。
function showRoute(solveResult) {
//路径分析的结果
var routeResults = solveResult.routes;
//路径分析的长度
var res = routeResults.length;
if (res > 0) {
for (var i = 0; i < res; i++) {
var graphicroute = routeResults[i];
var graphic = graphicroute;
graphic.setSymbol(routePolylineSymbol);
map.graphics.add(graphic);
}
}
else {
alert("没有返回结果");
}
}
});
</script>
</body>
</html>
六、成果图
七、总结
在这里我为了省事参数设置的不多,三种分析其实差别不是很大,使用的方式也比较相似,如果说恶心应该是在发布数据之前的构造网络,错误出一堆,奈何我对着不是个很了解,浪费了很多的时间,技术不行还需要很多努力。