ArcGIS API For JS之網路分析(臨近設施分析)
阿新 • • 發佈:2019-01-24
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>
六、成果圖
七、總結
在這裡我為了省事引數設定的不多,三種分析其實差別不是很大,使用的方式也比較相似,如果說噁心應該是在釋出資料之前的構造網路,錯誤出一堆,奈何我對著不是個很瞭解,浪費了很多的時間,技術不行還需要很多努力。