[WebGIS với ArcGIS Server – API 4.x #10] – Hiển thị Popup sử dụng Identify Task

Bài này chúng ta sẽ tìm hiểu cách hiển thị Popup thông tin của đối tượng khi kick vào đối tượng . Ở đây chúng ta sẽ sử dụng Identify Task để lấy thông tin, sau đó đưa vào popup của View để hiển thị. Trong bài mình thêm chức năng hiển thị highlight đối tượng tìm được cho trực quan.

Tham khảo Identify Sample

Hiển thị Popup sử dụng IdentifyTask

Bài này chúng ta sẽ tạo ra một file html mới tên là popup.html. Các bạn có thể làm tiếp vào ví dụ của bài trước cũng được.

Các bước làm như sau:

Bước 1: tạo file popup.html, thêm thẻ <div> có id=”ui-map-view” (tùy chọn), gọi đến thư viện ArcGIS Javascript API như những bài trước.

Bước 2: Load thêm những module sau: IdentifyTask, IdentifyParameters, arrayUtils, SimpleFillSymbol, Graphic

require([
"esri/Map",
"esri/views/MapView",
"esri/layers/MapImageLayer",
"esri/request",
"esri/tasks/IdentifyTask",
"esri/tasks/support/IdentifyParameters",
"esri/symbols/SimpleFillSymbol",
"esri/Graphic",
"dojo/_base/array",
"dojo/dom",
"dojo/on",
"dojo/domReady!"
], function (Map, MapView, MapImageLayer, esriRequest, IdentifyTask, IdentifyParameters,SimpleFillSymbol,Graphic,
arrayUtils, dom, on) {
//code here
});

IdentifyTask, IdentifyParameters dùng để thực hiện chức năng Identify, thiết lập các thông số cho Identify. arrayUtils là một đối tượng mở rộng của ArcGIS Javascript API cho phép duyệt các đối tượng trong mảng một cách tường minh hơn sử dụng vòng lặp for. SimpleFillSymbol, Graphic để tạo một polygon add view graphic để highlight đối tượng tìm được.

Bước 3: Khai báo url, các biến Identify, params

var url = "http://localhost:6080/arcgis/rest/services/ThuaDat/ThuaDat/MapServer";
var identifyTask, params;

Bước 4: thêm các đối tượng layer,map, view

var layer = new MapImageLayer({
url: url
});
 
var map = new Map({
layers: [layer]
});
var view = new MapView({
container: "ui-map-view",
map: map
});

Bước 5: trong hàm then() của view thêm code sau:

view.then(function () {
 
on(view, "click", executeIdentifyTask);
 
// Create identify task for the specified map service
identifyTask = new IdentifyTask(url);
 
// Set the parameters for the Identify
params = new IdentifyParameters();
params.tolerance = 3;
params.layerIds = [0, 1];
params.layerOption = "top";
params.width = view.width;
params.height = view.height;
params.returnGeometry = true;
 
});

Đầu tiên chúng ta khởi tạo đối tượng Identify với câu lệnh

identifyTask = new IdentifyTask(url);

Tiếp theo chúng ta thiết lập các giá trị parameter cho Identify này, trong đó có <strong>layerIds </strong>là những sublayer sẽ thực hiện việc Identify. Ở đây trong layer của mình có 2 sublayer với id =0,1 nên sẽ để là [0,1]. Nếu muốn chỉ thực hiện Identify với một layer nào đó thôi thì chúng ta sẽ thiết lập ở đây.

Đăng ký sự kiện click vào view

Sau đó chúng ta đăng ký một sự kiện click vào view và tham số cho sự kiện này một hàm executeIdentifyTask. hàm này chúng ta sẽ định nghĩa như sau:

function executeIdentifyTask(event) {
// Set the geometry to the location of the view click
params.geometry = event.mapPoint;
params.mapExtent = view.extent;
dom.byId("ui-map-view").style.cursor = "wait";
 
// This function returns a promise that resolves to an array of features
// A custom popupTemplate is set for each feature based on the layer it
// originates from
identifyTask.execute(params).then(function (response) {
 
var results = response.results;
 
return arrayUtils.map(results, function (result) {
 
var feature = result.feature;
var layerName = result.layerName;
 
feature.attributes.layerName = layerName;
if (layerName === 'thuadat2.sde.Geo_ThuaDat') {
feature.popupTemplate = { // autocasts as new PopupTemplate()
title: "Thông tin thửa đất",
content: "<b>Số thửa:</b> {sothututhua} " +
"<br><b>Số tờ bản đồ:</b> {sohieubando}" +
"<br><b>Diện tích:</b> {dientich } " +
"<br><b>Địa chỉ:</b> {diachithua}"
};
}
else if (layerName === 'graphic') {
feature.popupTemplate = { // autocasts as new PopupTemplate()
title: "Graphic",
content: "<b>Tên:</b> {name}"
};
}
 
return feature;
});
}).then(showPopup); // Send the array of features to showPopup()
 
// Shows the results of the Identify in a popup once the promise is resolved
function showPopup(response) {
if (response.length > 0) {
view.popup.open({
features: response,
location: event.mapPoint
});
 
//show highlight
var graphics = arrayUtils.map(response, function (item) {
var symbol = new SimpleFillSymbol({
color: [0, 51, 204, 1],
style: "none",
outline: { // autocasts as esri/symbols/SimpleLineSymbol
color: [0, 51, 204, 1],
width: 2
}
});
var polygonGraphic = new Graphic({
geometry: item.geometry,
symbol: symbol
 
});
return polygonGraphic;
});
view.graphics.removeAll();
view.graphics.addMany(graphics);
}
dom.byId("ui-map-view").style.cursor = "auto";
}
}

Trong hàm này mình có check kiểm tra layer theo tên, với mỗi layer sẽ có cách hiển thị khác nhau. Hàm trên sẽ làm những việc sau: Lấy vị trí chuột khi bạn kick chuột vào view, từ vị trí đó đưa vào IdentifyTask xử lý sẽ ra được một giá trị trả về ứng với vị trí chúng trên view

identifyTask.execute(params).then(function (response) {
//có response rồi thì đọc nó và lấy dữ liệu thôi
});
return arrayUtils.map(results, function (result) {
});

Hàm trên dùng để duyệt toàn bộ các đối tượng trong mảng results, mỗi đối tượng trong mảng là result. Các bạn có thể sử dụng vòng lặp for nhưng cách này tường minh hơn và dễ dùng hơn.
Trong quá trình duyệt hết các thành phần trong mảng results, chúng ta sẽ lấy ra được các feature, sau đó chúng ta thêm popupTemplate cho từng feature này. Feature đã được hỗ trợ popup Template nên chúng ta không cần phải khai báo module require . Các bạn có thể tìm hiều thêm về Popup Template tại đây: Popup Template

Lưu lý: {sothututhua} là tên trường trong bảng dữ liệu của mìn, các bạn cần phải thay đổi phần này. Trong này chấp nhận cả Alias nên thay vì tên trường, chúng ta có thể truyền tên Alias vào được.

Cuối cùng sau khi duyệt xong thì hàm map() trả về cho chúng ta một mảng feature mới có popuptemplate, và để hiển thị popup chúng ta sẽ đến hàm then() tiếp theo của identifyTask.execute(params)

function showPopup(response) {
if (response.length > 0) {
view.popup.open({
features: response,
location: event.mapPoint
});
 
//show highlight
var graphics = arrayUtils.map(response, function (item) {
var symbol = new SimpleFillSymbol({
color: [0, 51, 204, 1],
style: "none",
outline: { // autocasts as esri/symbols/SimpleLineSymbol
color: [0, 51, 204, 1],
width: 2
}
});
var polygonGraphic = new Graphic({
geometry: item.geometry,
symbol: symbol
 
});
return polygonGraphic;
});
view.graphics.removeAll();
view.graphics.addMany(graphics);
}
dom.byId("ui-map-view").style.cursor = "auto";
}

Biến response trong hàm then này là những feature có popuptemplate đã lấy được ở hàm then() trước. (Bạn cần tìm hiểu thêm về Promise để hiểu cách sử dụng các hàm then() lồng nhau, nên nhớ tất cả các đối tượng trong ArcGIS Javascript API 4.0 trở lên đều là Promise).
Trong hàm này mình có tạo các đối tượng graphic với geometry chúng ta lấy được trong quá trình Identify ( chú ý bạn phải chọn parameter params.returnGeometry = true;) và symbol dạng SimpleFillSymbol ( vì các lớp đối tượng của mình dạng polygon, tùy vào kiểu dữ liệu mà chúng ta chọn symbol khác nhau – tham khảo SimpleFillSymbol). Cuối cùng là add các graphic đó vào View

Kết quả sẽ được như hình dưới:

popup-view

Chú ý: kết quả của quá trình Identify chúng ta có thể sử dụng để hiển thị popup nhưng cũng có thể hiển thị ra ngoài một thẻ <div> nào đó theo định dạng chúng ta muốn.

Code webgis có thêm popup hiện thị

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://js.arcgis.com/4.0/esri/css/main.css">
<script src="https://js.arcgis.com/4.0/"></script>
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
 
#ui-map-view {
width: 700px;
height: 700px;
}
</style>
 
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/MapImageLayer",
"esri/request",
"esri/tasks/IdentifyTask",
"esri/tasks/support/IdentifyParameters",
"esri/symbols/SimpleFillSymbol",
"esri/Graphic",
"dojo/_base/array",
"dojo/dom",
"dojo/on",
"dojo/domReady!"
], function (Map, MapView, MapImageLayer, esriRequest, IdentifyTask, IdentifyParameters,SimpleFillSymbol,Graphic,
arrayUtils, dom, on) {
//code ở đây
var url = "http://localhost:6080/arcgis/rest/services/ThuaDat/ThuaDat/MapServer";
var identifyTask, params;
 
var layer = new MapImageLayer({
url: url
});
 
var map = new Map({
layers: [layer]
});
var view = new MapView({
container: "ui-map-view",
map: map
});
view.then(function () {
 
on(view, "click", executeIdentifyTask);
 
// Create identify task for the specified map service
identifyTask = new IdentifyTask(url);
 
// Set the parameters for the Identify
params = new IdentifyParameters();
params.tolerance = 3;
params.layerIds = [0, 1];
params.layerOption = "top";
params.width = view.width;
params.height = view.height;
params.returnGeometry = true;
 
});
 
function executeIdentifyTask(event) {
// Set the geometry to the location of the view click
params.geometry = event.mapPoint;
params.mapExtent = view.extent;
dom.byId("ui-map-view").style.cursor = "wait";
 
// This function returns a promise that resolves to an array of features
// A custom popupTemplate is set for each feature based on the layer it
// originates from
identifyTask.execute(params).then(function (response) {
 
var results = response.results;
 
return arrayUtils.map(results, function (result) {
 
var feature = result.feature;
var layerName = result.layerName;
 
feature.attributes.layerName = layerName;
if (layerName === 'thuadat2.sde.Geo_ThuaDat') {
feature.popupTemplate = { // autocasts as new PopupTemplate()
title: "Thông tin thửa đất",
content: "<b>Số thửa:</b> {sothututhua} " +
"<br><b>Số tờ bản đồ:</b> {sohieubando}" +
"<br><b>Diện tích:</b> {dientich } " +
"<br><b>Địa chỉ:</b> {diachithua}"
};
}
else if (layerName === 'graphic') {
feature.popupTemplate = { // autocasts as new PopupTemplate()
title: "Graphic",
content: "<b>Tên:</b> {name}"
};
}
 
return feature;
});
}).then(showPopup); // Send the array of features to showPopup()
 
// Shows the results of the Identify in a popup once the promise is resolved
function showPopup(response) {
if (response.length > 0) {
view.popup.open({
features: response,
location: event.mapPoint
});
//show highlight
var graphics = arrayUtils.map(response, function (item) {
var symbol = new SimpleFillSymbol({
color: [0, 51, 204, 1],
style: "none",
outline: { // autocasts as esri/symbols/SimpleLineSymbol
color: [0, 51, 204, 1],
width: 2
}
});
var polygonGraphic = new Graphic({
geometry: item.geometry,
symbol: symbol
 
});
return polygonGraphic;
});
view.graphics.removeAll();
view.graphics.addMany(graphics);
}
dom.byId("ui-map-view").style.cursor = "auto";
}
}
 
});
</script>
</head>
<body>
<div id="ui-map-view"></div>
</body>
</html>

Hẹn các bạn ở những bài tiếp theo.

Tác giả: Đỗ Xuân Cường

Nguồn bài viết: cuongdx313.wordpress.com

Coi bài nguyên văn tại :
[WebGIS với ArcGIS Server – API 4.x #10] – Hiển thị Popup sử dụng Identify Task

Nhận xét

Bài đăng phổ biến từ blog này

DownLoad ảnh vệ tinh Landsat 8

CẮt ảnh theo ranh giới (Sử dụng File ranh giới dạng *shp)

Bản đồ du lịch Việt Nam