شناسایی و پیدا کردن عوارض-موسسه چشم انداز-آموزش کاربردی GIS و RS
در این بخش به توضیح دو تا از کارهای ArcGIS Server که مربوط به برگرداندن فیلدهای عارضه است میپردازیم: IdentifyTask و FindTask.
از دیگر کاربردهای رایج در اپلیکیشنهای GIS، شناسایی عوارض است که اطلاعات فیلدهای عارضهی کلیک شده بر روی نقشه را برمیگرداند. نمایش اطلاعات فیلدها در یک پنجرهی پاپآپ و با کلاس IdentifyTask امکان پذیر است. شی IdentifyTask از شی IdentifyParameters که حاوی پارامترهای ورودی است، استفاده میکند. شی IdentifyParameters شامل پارامترهایی است که نتایج عملیات شناسایی را کنترل میکنند. این پارامترها قابلیت شناسایی لایههای تکی، بالاترین لایه در سرویس نقشه و لایههای قابل مشاهده در سرویس نقشه را دارند. شی IdentifyResult برای نگه داری نتایج عملیات شناسایی است. عملیاتی که با ArcGIS API for JavaScript قابل انجام است با تعدادی از توابع مورد استفاده و رایج در ArcGIS Desktop یکسان است… FindTask یکی از این توابع پراستفاده و مشترک است. در نسخه ArcGIS Desktop با FindTask میتوانید عوارض یک لایه را با یک مقدار رشتهای پیدا کنید. قبل از اینکه با شی FindTask عوارض را پیدا کنیم، باید پارامترهای مختلف عملیات جستجو را در یک نمونه از شی FindParameters. FindParameters قرار دهیم. با این شی گزینههای مختلفی مانند متن جستجو، فیلدهای مورد جستجو و موارد دیگر قابل تنظیم هستند. بعد از اینکه شی FindParameters را تنظیم کردید، شی FindTask جستجو را بر روی یک یا چند لایه و فیلدها انجام میدهد و یک شی FindResult برمیگرداند. شی FindResult شامل ID لایه، نام لایه و عارضهای است که با رشتهی جستجو تطبیق دارد.
استفاده از IdentifyTask برای برگرداندن فیلدهای عارضه
مقادیر فیلدهای لایه با استفاده از IdentifyTask به اپلیکیشن شما برگردانده میشوند. در این قسمت کارکردن با اشیائی را یاد میگیریم که با IdentifyTask ادغام میشوند و مقادیر فیلدها را برمیگردانند.
معرفی IdentifyTask
IdentifyTask به سه کلاس IdentifyParameters، IdentifyTask و IdentifyResult تفکیک میشود.
شی IdentifyParameters
شی ورودی عملیات شناسایی، شی IdentifyTask است. ویژگیهای عملیات شناسایی با استفاده از کلاس IdentifyParameters تنظیم میشود. این پارامترها شامل:
1- هندسهی عارضهی مورد نظر و با IdentifyParameters.geometry تنظیم میشود.
2- ID لایهای که میخواهیم شناسایی را بر روی آن انجام دهیم و با IdentifyParameters.layerIds تعیین میشود.
3- سطح آستانه که با IdentifyParameters.tolerance تعیین میشود.
ابتدا باید id منابع را مطابق کد زیر در تابع require وارد کنید تا بتوانید از توابع شناسایی عوارض درون کد استفاده کنید.
require([“esri/tasks/IdentifyTask”, … ], function(IdentifyTask, … ){ … });
قبل از تنظیم ویژگیهای شی IdentifyParameters باید یک نمونه از این شی را مطابق کد زیر بدون هیچ گونه پارامتر ورودی ایجاد کنید.
var identifyParams = new IdentifyParameters();
بعد از ایجاد شی، ویژگیها را مطابق زیر تنظیم کنید:
identifyParams.geometry = evt.MapPoint;
identifyParams.layerIds[0,1,2];
identifyParams.returnGeometry = true;
identifyParams.tolerance = 3;
در بسیاری از مواقع شناسایی با کلیک نقطهای از نقشه انجام میشود. میتوانید این نقطه ی کلیک شده را از رویداد map-click که در کد قبلی استفاده کردید، به دست آورید. لایههایی که باید جستجو شوند، با آرایهای از ID لایهها تعیین میشوند. این آرایهی عددی به ویژگی IdentifyParameters.layerIds فرستاده میشود. ID لایهها در ArcGIS Server manager و در قسمت سرویس نقشه ای وجود دارند. ویژگی tolerance فاصلهی بین نقطهی کلیک شده با پیکسلهای اطراف نقطه را تنظیم میکند؛ بنابراین اینگونه فکر کنید که شعاع دایرهای که اطراف یک نقطه قرار گرفته است با توجه به مقداری است که برای tolerance تعیین کردهاید. این مقدار در واحد پیکسل است. زمانی که ویژگی IdentifyTask اجرا میشود، همهی عوارضی که در دایره هستند یا با دایره تداخل دارند، شناسایی شده و برگردانده میشوند. احتمالاً باید مقدار tolerance را به دفعات آزمایش و بررسی کنید تا مقدار مناسب اپلیکیشن را به دست آورید. اگر این مقدار خیلی زیاد انتخاب شود، ممکن است عوارض بسیار زیادی برگردانده شوند. پیدا کردن عدد متعادل آسان نیست و ممکن است مقدار tolerance که در اپلیکیشن x خوب کار میکند در اپلیکیشن y، مناسب نباشد.
ویژگی IdentifyTask
این ویژگی عملیات شناسایی را بر روی یک یا چند لایه با استفاده از پارامترهای مشخص شده در IdentifyParameters انجام میدهد. IdentifyTask نیاز به URL ای دارد که به سرویس نقشهای که لایهها در آنجا قرار دارند، اشاره میکند. کد زیر یک نمونه از شی IdentifyTask را ایجاد میکند که یک URL میگیرد. این URL برای اشاره به سرویس نقشهای است که لایههای موردنظر برای جستجو در آن سرویس نقشه قرار دارند.
var identify =
new IdentifyTask
(“http://sampleserver1.arcgisonline.com
/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/
MapServer”);
بعد از ایجاد یک نمونه از شی IdentifyTask، میتوانید عملیات جستجو را با متد IdentifyTask.execute() اجرا کنید. این متد شامل پارامترهای ورودی شی IdentifyParameters و توابع بازخوردی شکست و موفقیت است. در قطعه کد زیر متد IdentifyTask.execute() صدا زده میشود. پارامترهای این متد؛ یک نمونه از شی IdentifyParameters و یک ارجاع به متد addToMap() میباشند. نتایج برگشتی که در idResults قرار دارند، به متد addToMap() فرستاده میشوند و این متد نتایج را پردازش میکند.
identifyParams = new IdentifyParameters();
identifyParams.tolerance = 3;
identifyParams.returnGeometry = true;
identifyParams.layerIds = [0,2];
identifyParams.geometry = evt.mapPoint;
identifyTask.execute(identifyParams, function(idResults) {
addToMap(idResults, evt); });
function addToMap(idResults, evt) {
//add the results to the map
}
پس از انجام جستجو، IdentifyTask نتایج جستجو را در یک نمونه از شی IdentifyResult قرار میدهد. این شی نتیجه را در بخش بعدی توضیح میدهیم.
شی IdentifyResult
نتایج جستجو به یک آرایه از اشیاء IdentifyResult فرستاده میشود. هر شی IdentifyResult شامل یک عارضهی برگشتی از نتایج جستجو، نام لایه و ID لایهای است که عارضهی برگشتی در آن لایه قرار دارد.
در قطعه کد زیر تابع بازخوردی یک آرایه از اشیاء IdentifyResult را پردازش میکند.
function addToMap(idResults, evt) {
bldgResults = {displayFieldName:null,features:[]};
parcelResults = {displayFieldName:null,features:[]};
for (vari=0, i<idResults.length; i++) {
var idResult = idResults[i];
if (idResult.layerId === 0) {
if (!bldgResults.displayFieldName)
{bldgResults.displayFieldName = idResult.displayFieldName};
bldgResults.features.push(idResult.feature);
}
else if (idResult.layerId === 2) {
if (!parcelResults.displayFieldName)
{parcelResults.displayFieldName = idResult.displayFieldName};
parcelResults.features.push(idResult.feature);
}
}
dijit.byId(“bldgTab”).setContent(layerTabContent(bldgResults,”bldgRes
ults”));
dijit.byId(“parcelTab”).setContent(layerTabContent(parcelResults,”par
celResults”));
map.infoWindow.show(evt.screenPoint,
map.getInfoWindowAnchor(evt.screenPoint));
}
پیاده سازی عملیات جستجو و شناسایی
در اپلیکیشن زیر وقتی کاربر بر روی نقطهای از نقشه کلیک کرد، اطلاعات پارسلی که نقطهی کلیک شده درون آن است را نشان میدهد.
مراحل زیر را برای ایجاد این اپلیکیشن دنبال کنید:
1- Sandbox را در لینک زیر باز کنید:
http://developers.arcgis.com/en/javascript/sandbox/sandbox.html.
2- همهی محتویات تگ <script> را پاک کنید.
3- متغیرهای زیر را برای استفاده در اپلیکیشن تعریف کنید:
<script>
var map;
var identifyTask, identifyParams;
</script>
4- تابع require() را برای تعیین منابع مورد استفاده در اپلیکیشن ایجاد کنید:
<script>
var map;
var identifyTask, identifyParams;
require([
“esri/map”, “esri/dijit/Popup”,
“esri/layers/ArcGISDynamicMapServiceLayer”,
“esri/tasks/IdentifyTask”,
“esri/tasks/IdentifyResult”,
“esri/tasks/IdentifyParameters”,
“esri/dijit/InfoWindow”,
“esri/symbols/SimpleFillSymbol”,
“esri/symbols/SimpleLineSymbol”,
“esri/InfoTemplate”, “dojo/_base/Color” ,
“dojo/on”,
“dojo/domReady!”
], function(Map, Popup, ArcGISDynamicMapServiceLayer,
IdentifyTask, IdentifyResult, IdentifyParameters,
InfoWindow,
SimpleFillSymbol, SimpleLineSymbol, InfoTemplate,
Color, on) {
});
</script>
5- یک نمونه از شی map ایجاد کنید:
<script>
var map;
var identifyTask, identifyParams;
require([
“esri/map”, “esri/dijit/Popup”,
“esri/layers/ArcGISDynamicMapServiceLayer”,
“esri/tasks/IdentifyTask”,
“esri/tasks/IdentifyResult”,
“esri/tasks/IdentifyParameters”,
“esri/dijit/InfoWindow”,
“esri/symbols/SimpleFillSymbol”,
“esri/symbols/SimpleLineSymbol”, “esri/InfoTemplate”
, “dojo/_base/Color” ,”dojo/on”,
“dojo/domReady!”
], function(Map, Popup, ArcGISDynamicMapServiceLayer,
IdentifyTask, IdentifyResult, IdentifyParameters,
InfoWindow,
SimpleFillSymbol, SimpleLineSymbol, InfoTemplate, Color,
on) {
//setup the popup window
var popup = new Popup({
fillSymbol: new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,
new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
new Color([255,0,0]), 2), new Color([255,255,0,0.25]))
}, dojo.create(“div”));
map = new Map(“map”, {
basemap: “streets”,
center: [-83.275, 42.573],
zoom: 18,
infoWindow: popup
});
});
</script>
6- یک لایه از نوع سرویس نقشهی dynamic ایجاد کنید و به نقشه اضافه کنید:
map = new Map(“map”, {
basemap: “streets”,
center: [-83.275, 42.573],
zoom: 18,
infoWindow: popup
});
var landBaseLayer = new ArcGISDynamicMapServiceLayer
(“http://sampleserver3.arcgisonline.com/ ArcGIS/rest/services/BloomfieldHillsMichigan/ Parcels/MapServer”
,{opacity:.55});
map.addLayer(landBaseLayer);
7- حال یک رویداد کلیک اضافه کنید تا هنگامی که کاربر بر روی نقشه کلیک کند، این رویداد اجرا میشود.
map = new Map(“map”, {
basemap: “streets”,
center: [-83.275, 42.573],
zoom: 18,
infoWindow: popup
});
varlandBaseLayer = new ArcGISDynamicMapServiceLayer
(“http://sampleserver3.arcgisonline.com/ArcGIS/
rest/services/BloomfieldHillsMichigan/Parcels/
MapServer”,{opacity:.55});
map.addLayer(landBaseLayer);
map.on(“click”, executeIdentifyTask);
8- یک شی IdentifyTask ایجاد کنید:
identifyTask = new
IdentifyTask(“http://sampleserver3.arcgisonline.com/
ArcGIS/rest/services/BloomfieldHillsMichigan/
Parcels/MapServer”);
9- یک شی IdentifyParameters ایجاد و با ویژگیهای زیر تنظیم کنید:
identifyTask = new
IdentifyTask(“http://sampleserver3.arcgisonline.com/
ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/
MapServer”);
identifyParams = new IdentifyParameters();
identifyParams.tolerance = 3;
identifyParams.returnGeometry = true;
identifyParams.layerIds = [0,2];
identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_ALL;
identifyParams.width = map.width;
identifyParams.height = map.height;
10- executeIdentifyTask() تابعی است که به رویداد کلیک کاربر، پاسخ میدهد و پس از کلیک کاربر بر روی نقشه، اجرا میشود. در بخش قبلی رویداد کلیک نقشه Map.click)) را اضافه کردیم. تابع executeIdentifyTask() یک تابع جاوااسکریپتی با یک پارامتر ورودی است. این پارامتر ورودی یک نمونه از شی Event است که هر رویداد، یک شی Event ایجاد میکند. این شی ویژگیهای مختلفی دارد. پس رویداد Map.click نیز یک شی Event دارد که حاوی نقطهی کلیک شده است. این نقطهی کلیک شده را میتوانید با ویژگی Event.mapPoint بازیابی کنید و از این نقطه برای تنظیم ویژگی IdentifyParameters.geometry استفاده کنید. متد IdentifyTask.execute() یک شی Deferred برمیگرداند که برای تجزیه و تحلیل نتایج استفاده میشود. میتوانید یک تابع بازخوردی برای این شی ایجاد کنید. کد زیر را برای ایجاد تابع executeIdentifyTask() اضافه کنید. این تابع باید مستقل و خارج از تابع require() ایجاد شود.
function executeIdentifyTask(evt) {
identifyParams.geometry = evt.mapPoint;
identifyParams.mapExtent = map.extent;
var deferred = identifyTask.execute(identifyParams);
deferred.addCallback(function(response) {
// response is an array of identify result objects
// Let’s return an array of features.
return dojo.map(response, function(result) {
var feature = result.feature;
feature.attributes.layerName = result.layerName;
if(result.layerName === ‘Tax Parcels’){
console.log(feature.attributes.PARCELID);
var template = new esri.InfoTemplate(“”, “${Postal
Address} <br/> Owner of record: ${First Owner
Name}”);
feature.setInfoTemplate(template);
}
else if (result.layerName === ‘Building Footprints’){
var template = new esri.InfoTemplate(“”, “Parcel ID:
${PARCELID}”);
feature.setInfoTemplate(template);
}
return feature;
});
});
// InfoWindow expects an array of features from each deferred
// object that you pass. If the response from the task execution
// above is not an array of features, then you need to add a
callback
// like the one above to post-process the response and return an
// array of features.
map.infoWindow.setFeatures([ deferred ]);
map.infoWindow.show(evt.mapPoint);
}
11- در فایل identify.html موجود در پوشهی موجود در DVD ضمیمه ی کتاب کد کامل این اپلیکیشن قرار دارد.
12- دکمهی Run را برای اجرای کد کلیک کنید. خروجی را به صورت زیر خواهید دید.
استفاده از FindTask برای اخذ اطلاعات عارضه
FindTask بر اساس یک مقدار رشتهای، سرویس نقشهای که ArcGIS ServerREST API فراهم کرده را جستجو و پیدا میکند. این جستجو بر اساس یک فیلد از یک لایه، چندین فیلد از یک لایه و یا چندین فیلد از چندین لایه انجام میشود.
همانند دیگر عملیاتی که انجام دادیم، عملیات جستجو و شناسایی نیز از ترکیب سه شی FindParameters، FindTask و FindResul ایجاد میشود.
شی FindParameters
شی FindParameters مانند یک پارامتر ورودی معیارهای جستجو را تعیین میکند. این شی یک ویژگی متنی searchText دارد که شامل مشخصات فیلدها و لایههای مورد جستجو است. علاوه براین با تنظیم ویژگی returnGeometry به true هندسهی عوارضی که در نتیجهی جستجو به دست آمده اند، برگردانده میشود.
کد زیر یک نمونه شی FindParameters با ویژگیهای مختلف ایجاد میکند. قبل از کار با اشیاء، باید منبع این اشیاء را با تابع require به برنامه اضافه کنید. منبع esri/tasks/find resource را برای استفاده از اشیاء عملیات جستجو، به کد اضافه کنید.
ویژگی searchText یک مقدار رشتهای است که در میان مقادیر فیلدها میگردد و فیلدی که مقدارش با این مقدار برابر باشد را پیدا کرده و کل رکورد آن فیلد را برمیگرداند. هر رکورد نشان دهندهی یک عارضه است. لازم به ذکر است که این ویژگی تنها آن فیلدهایی را برمیگرداند که در ویژگی searchFields تعیین شده اند. لایههایی که باید جستجو شوند به صورت آرایهای از اعداد مشخص میشوند و در ویژگی layerIds قرار میگیرند. این اعداد همان ID لایهها است. در مواقعی نیازی به برگرداندن هندسهی عوارض ندارید. مثلاً وقتی که میخواهید اطلاعات فیلدها را در یک جدول قرار دهید. در این مواقع ویژگی geometry را با false تنظیم کنید.
var findParams = new FindParameters();
findParams.searchText = dom.byId(“ownerName”).value;
findParams.searchFields = [“LEGALDESC”,”ADDRESS”];
// fields to search
findParams.returnGeometry = true;
findParams.layerIds = [0]; //layers to use in the find
findParams.outSpatialReference = map.spatialReference;
شی FindTask
FindTask در لایهها و فیلدهایی که با FindParameters مشخص شدهاند، عملیات جستجو را انجام میدهد و یک شی FindResult شامل رکوردهای برگشتی را برمیگرداند.
findTask = new FindTask(“http://sampleserver1.arcgisonline.com/ArcGIS/
rest/services/TaxParcel/TaxParcelQuery/MapServer/”);
findTask.execute(findParams,showResults);
function showResults(results) {
//This function processes the results
}
FindTask شامل URL ای است که به سرویس نقشه اشاره میکند. در این URL فقط آدرس سرویس نقشه قرار میگیرد و نیازی به آوردن ID لایهها در این URL نیست؛ زیرا لایهها و فیلدهایی که باید مورد جستجو قرار گیرند با شی FindParameters تعیین میشوند. حال باید متد FindTask.execute() را صدا بزنید تا جستجو انجام شود. شی FindParameters به عنوان اولین پارامتر به این متد فرستاده میشود. سپس میتوانید توابع بازخوردی موفقیت و شکست را تعیین کنید. تابع بازخوردی موفقیت یک شی FindResults شامل نتایج جستجو را میفرستد.
شی FindResult
FindResult شامل نتایج عملیات FindTask است. در این شی عوارض حاصل از جستجو به صورت گرافیک قرار گرفته اند. هم چنین ID و نام لایهای که عارضه در آن قرار دارد، در این شی قرار دارند.
function showResults(results) {
//This function works with an array of FindResult that the task
returns
map.graphics.clear();
var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,
new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
new Color([98,194,204]), 2), new Color([98,194,204,0.5]));
//create array of attributes
var items = array.map(results,function(result){
var graphic = result.feature;
graphic.setSymbol(symbol);
map.graphics.add(graphic);
return result.feature.attributes;
});
//Create data object to be used in store
var data = {
identifier: “PARCELID”, //This field needs to have unique values
label: “PARCELID”, //Name field for display. Not pertinent to
agrid but may be used elsewhere.
items: items
};
//Create data store and bind to grid.
store = new ItemFileReadStore({ data:data });
var grid = dijit.byId(‘grid’);
grid.setStore(store);
//Zoom back to the initial map extent
map.centerAndZoom(center, zoom);
}
برگرفته از کتاب تولید و طراحی اپلیکیشن های Web GIS و Mobile GIS با استفاده از ArcGIS API for JavaScript
نویسنده: دکتر محمد بافقی زاده
نشر: انتشارات اکادمیک
3 نظرات