لایههای feature سرویس-موسسه چشم انداز-آموزش کاربردی GIS و RS
اطلاعات هندسی عارضه را از ArcGIS Server میگیرد و به مرورگر انتقال میدهد و سپس عوارض با استفاده از این اطلاعات هندسی بر روی نقشه ترسیم میشوند. این اطلاعات هندسی ممکن است در یک جدول غیر مکانی و غیر هندسی باشند. کاربر اپلیکیشن، عوارض مورد نیازش را درخواست میکند و عملیات انتخاب و جستجو را بر روی آن عوارض انجام میدهد و نیازی ندارد که اطلاعات بیشتری را از سرور درخواست کند. شی FeatureLayer برای لایههایی مناسب است که به کلیکهای ماوس یا حرکت ماوس کاربر واکنش نشان میدهند. اگر شما با یک FeatureLayer که عارضههای زیادی دارد کار میکنید زمان زیادی طول میکشد تا عوارض از سرور به اپلیکیشن منتقل شوند. FeatureLayerدارای چند حالت نمایش است که مشکل طولانی بودن زمان بارگذاری لایه را حل میکند.
بیائید کد را گسترش دهیم و یک لایه feature سرویس به نقشه اضافه کنیم تا مقداری از نقشه را پوشش دهد. از عارضه پولیگونی Boston_Marathon استفاده میکنیم. با لایههای dynamic و Tiled اشاره گری به سرویس rest فراهم میکنید، اما در FeatureLayer باید به یک لایهی خاص در سرویس نقشه اشاره کنید. در کد زیر یک شی FeatureLayer از اولین لایهی موجود در سرویس نقشه ایجاد میکنید که با شمارهی 0 مشخص شده است.
نحوه کدنویسی جاوااسکریپتی یک لایه feature سرویس بهصورت زیر است.
Var marathon=newFeatureLayer
(“http://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Boston_Marathon/FeatureServer/0”, {
mode: FeatureLayer.MODE_ONDEMAND,
outFields:[“*”]
});
ابتدا باید یک شی FeatureLayer ایجاد کنیم. این شی آدرس URL لایه و mode و فیلدهای لایه را میگیرد. در این مثال تمام فیلدها را نمایش میدهیم. یک لایه feature در حالت on-demand سرعت بالایی دارد زیرا فقط عوارض مورد نیاز را از سرور بازیابی میکند. خصیصه mode مقدار snapshot را نیز دارد که تمام عوارض را بازیابی میکند. با متد addLayers شی map، شی FeatureLayer را به نقشه اضافه میکنیم.
map.addLayers([marathon]);
متد addLayers برای اضافه کردن چندین لایه استفاده میشود. اسامی لایهها درون [] و با علامت ,از هم جدا میشوند.
قدم بعدی اضافه کردن ماژول FeatureLayer به تابع require است.
<script src=”http://js.arcgis.com/3.11compact/”></script>
<script>
require([“esri/map”, “esri/layers/FeatureLayer”, “dojo/
domReady!”], function(Map, FeatureLayer) {
var map = new Map(“map”, {
center: [-118, 34.5],
zoom: 7,
basemap: “streets”
});
var marathon = new FeatureLayer(“http://services.arcgis.
com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Boston_Marathon/
FeatureServer/0”,
{
mode: FeatureLayer.MODE_ONDEMAND,
outFields:[“*”]
});
map.addLayers([marathon]);
});
</script>
حالا کد کامل شد. فایل firstMobileMap.html را با کدهای جدید ویرایش میکنیم. سپس نقشه با لایه پولیگونی marathon پوشش داده میشود. یک امکان جالبی که توسط Esri فراهم شده است، این است که کد را در یک کادر متنی بنویسید و سپس اجرا کنید. از لینک زیر میتوانید به این کادر متنی دسترسی داشته باشید. این کادر متنی در واقع مانند یک IDE عمل میکند.
http://developers.arcgis.com/en/javascript/sandbox/sandbox.html
رویدادهای نقشه
برنامه، اکنون یک نقشه را بارگذاری کرده و مقداری از نقشه را با یک پلیگون پوشش میدهد. اغلب کاربران میخواهند عارضهای را از یک لایه انتخاب کنند و فیلدهای عارضه انتخابی را ببینند. پس بیائید یک رویداد به لایه marathon اضافه کنیم.
marathon.on(“click”, myClickHandler);
میخواهیم هر زمان کاربر روی یکی از عوارض لایه کلیک کند یا با انگشت ضربه بزند، رویداد کلیک را به تابع myClickhandler() بفرستیم. در واقع وقتی کلیک انجام میشود، یک شی رویداد به رویداد فرستاده میشود و در نتیجه تابع myClickhandler() صدا زده میشود. در نهایت چیزی که دیده خواهد شد، خصوصیات شی عارضه است.
<script>
require([“esri/map”, “esri/layers/FeatureLayer”,”dojo/on”,
“dojo/domReady!”], function(Map, FeatureLayer, on) {
var map = new Map(“map”, {
center: [-118, 34.5],
zoom: 7,
basemap: “streets”
});
var marathon = new FeatureLayer(“http://services.arcgis.
com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Boston_Marathon/
FeatureServer/0”,
{
mode: FeatureLayer.MODE_ONDEMAND,
outFields:[“*”]
});
marathon.on(“click”, myClickHandler);
map.addLayers([marathon]);
//Marathon layer click handler
function myClickHandler(event)
{
alert(JSON.stringify(event.graphic.attributes));
};
});
</script>
وقتی کلیک(ضربه زدن با انگشت) صورت میگیرد یک شی رویداد کلیک ایجاد میشود. شی ایجاد شده به تابع myClickHandler فرستاده میشود. فایل firstMobileMap.html را در google chrome اجرا کنید و سپس Chrome’s DevTools یا همان developer tools را باز کنید. یک break point در خط function myClickHandler(event) قرار دهید و یک watch expression اضافه کنید.سپس میتوانید محتویات شی رویداد کلیک را ببینید.
event.graphic.attributes فیلدهای عارضه انتخاب شده را لیست میکند.
دقت کنید که شی حاوی فیلدها باید به رشته متنی تبدیل شود تا لیست فیلدها و مقدار فیلدها به صورت متن ظاهر شود. برای انجام این تبدیل از JSON. stringify() استفاده میکنیم. در تصویر زیر اپلیکیشن را با شبیه ساز DevTools روی یک Nexus 4 میبینید.
یکی از ابزارهای کارآمد Developer tools، ابزار object introspection است. اگر بخواهید محتویات شی رویداد که به تابع myClickHandler فرستاده شده را ببینید، یک breakpoint در کنار خط تعریف تابع بگذارید و در watch expression که قبلاً ایجاد کردید، محتویات شی رویداد قرار میگیرد. در تصویر زیر چگونگی انجام عملیات فوق را میبینید:
JavaScript Geolocation API
زمان آن رسیده که ابزار ویژه geolocation را به کد اضافه کنیم و روی موقعیت جاری کاربر متمرکز شویم. در بخش 2،Geolocation API را توضیح دادیم. در ابتدا باید رویداد load را تنظیم کنیم.
map.on(“load”, myLoadHandler);
درون تابع myLoadHandler ارجاعی به Geolocation API انجام دادیم. همهی مرورگرها geolocation-based navigation را پشتیبانی نمیکنند. موقعیت شی در متدهای coords.latitude، coords.longitude و coords.accuracy قرار میگیرد. البته ممکن است مقدار متدهای coords.altitude، coords.altitudeAccuracy, coords.heading، coords.speed و timestamp را نیز برگرداند. دقت کنید که برگرداندن مقدارهای مذکور به مرورگر بستگی دارد. اگر شی با تابع locationError() در دسترس نباشد و یا هر مشکل دیگری پیش بیاید، خطاها را باید مدیریت کرد. در کد زیر قابل دسترس بودن شی geolocation-based navigation بررسی میشود. آیا مرورگر از geolocation پشتیبانی میکند؟ میتواند موقعیت فعلی کاربر را برگرداند؟
Function myLoadHandler(event)
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(zoomToLocation,
locationError);
}
}
در تابع myLoadHandler ابتدا دسترسی شی navigator.geolocation را بررسی کردیم. سپس از مختصات موجود برای تولید یک شی نقطهای استفاده میکنیم. اگر دقت GPS موبایل اهمیت دارد، میتوان دقت را با استفاده از کد زیر تعیین کرد.
if (location.coords.accuracy <= 500){}
مقدار 500 در کد بالا مقدار ثابتی نیست و به نیازها و کاربرد مورد نظر بستگی دارد. اگر دقت یک اپلیکیشن مهم است، مشخصهی enableHighAccuracy را با مقدار true تنظیم کنید. برای اطلاعات بیشتر به لینک زیر مراجعه کنید:
http://dev.w3.org/geo/api/spec-source.html#high-accuracy
ArcGIS JavaScript API یک تابع تبدیل مختصات دارد. تابع geographicToWebMercator دادههای مختصات جغرافیایی را با استفاده از Geolocation API به سیستم تصویر Web Mercatorتبدیل میکند که سیستم تصویر پیش فرض نقشههای Arc Gis است. برای استفاده از این تابع باید ماژولهای esri/geometry/webMercatorUtils را به برنامه اضافه کنید. برای اطلاعات بیشتر در مورد سیستم تصویر نقشهها به لینک زیر مراجعه کنید:
http://support.esri.com/ja/knowledgebase/techarticles/detail/23025.
کد زیر را در نظر بگیرید. همانطور که در تابع zoomToLocation مشاهده میکنید، از یک شی نقطهای در تابع map.centerAndZoom() استفاده کردیم. در این تابع سطح زوم 16 تعیین شده است. موقعیت کاربر در سطح زوم 16 بر روی نقشه نمایش داده میشود و چهارگوشهی نقشه طوری تنظیم میشود که موقعیت کاربر در وسط نقشه نمایش داده شود.
function zoomToLocation(location) {
var pt = esri.geometry.geographicToWebMercator(new esri.geometry.
Point(location.coords.longitude, location.coords.latitude));
map.centerAndZoom(pt, 16);
}
در کد مدیریت خطای زیر اگر موقعیت جغرافیایی کاربر شناسایی نشد اطلاعات مناسبی برای کاربر نمایش داده میشود.
function locationError(error) {
switch (error.code) {
case error.PERMISSION_DENIED:
alert(“Location not provided”);
break;
case error.POSITION_UNAVAILABLE:
alert(“Current location not available”);
break;
case error.TIMEOUT:
alert(“Timeout”);
break;
default:
alert(“unknown error”);
break;
}
}
اگر میخواهید تغییر موقعیت کاربر را دنبال کنید از کد زیر استفاده کنید:
navigator.geolocation.watchPosition(showLocation, locationError);
کد کامل در فایل firstMobileMap.html قرار دارد.
کد کامل را به صورت زیر میبینید.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html;charset=utf-8″>
<meta name=”viewport” content=”initial-scale=1, maximumscale=1,user-scalable=no”/>
<title>Simple Map</title>
<link rel=”stylesheet” href=”http://js.arcgis.com/3.11/esri/css/esri.css”>
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
</style>
<script src=”http://js.arcgis.com/3.11compact/”></script>
<script>
require([“esri/map”, “esri/layers/FeatureLayer”,”dojo/on”,
“dojo/domReady!”], function(Map, FeatureLayer, on) {
var map = new Map(“map”, {
center: [-118, 34.5],
zoom: 7,
basemap: “streets”
});
var marathon = new FeatureLayer(“http://services.arcgis.
com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Boston_Marathon/
FeatureServer/0”,
{
mode: FeatureLayer.MODE_ONDEMAND,
outFields:[“*”]
});
marathon.on(“click”, myClickHandler);
map.addLayers([marathon]);
//Marathon layer click handler
function myClickHandler(event)
{
alert(JSON.stringify(event.graphic.attributes));
};
Function myLoadHandler(event)
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(zoomToLocation,
locationError);
}
}
function zoomToLocation(location) {
var pt = esri.geometry.geographicToWebMercator(new esri.geometry.
Point(location.coords.longitude, location.coords.latitude));
map.centerAndZoom(pt, 16);
}
function locationError(error) {
switch (error.code) {
case error.PERMISSION_DENIED:
alert(“Location not provided”);
break;
case error.POSITION_UNAVAILABLE:
alert(“Current location not available”);
break;
case error.TIMEOUT:
alert(“Timeout”);
break;
default:
alert(“unknown error”);
break;
}
}
)};
</script></head>
<body>
<div id=”map”></div>
</body>
</html>
برگرفته از کتاب تولید وب اپلیکیشن های موبایل با ArcGIS
نویسنده: دکتر محمد بافقی زاده
نشر: انتشارات اکادمیک
3 نظرات