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
Nội dung chính
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:
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