سلام دوستان
یک چالش و مشکل دارم که باید نتیجه و پیشرفت چشم گیر ان رو تا دو روز دیگه به رئیس اداره بدهم ولی متاسفانه من بک اند کار هستم و جاوا اسکریپتم تخصصی نیست.لطفا یکی کمکم کنه.
نمیدونم تا به حال اسم arcgis رو شنیده اید یا نه.یک سامانه و تخصص پیشرفته نمایش و کار با نقشه هست که سطح لایه بندی و نمایش لایه های متنوع و نا محدودی رو به کاربر میدهد کاربرد نظامی هم داره و البته به طور کامل برای ایران تحریم هست، برای عضویت باید با پرا کسی اقدام کرد.سایت معرفی arcgis , اموزش وب سرویس
یک وب سرویس دیگه هم داریم که برای وزارت راه کشور فنلاند هست که به طور آنلاین مختصات مکان و سرعت و .... کشتی ها،ترن و اتومبیل های در جاده ای کشور فنلان رو نشان میدهد و خروجی ان رو با استفاده از وب سرویس arcgis به کاربران نشان داد.سیستم نمایش ترافیک وزارت راه کشور فنلاند
قراره با استفاده از خروجی وب سرویس ترافیک راه(مثلا دریافت مکان ترن ها اموزش و توضیحات داده شده سایت که متاسفانه این هم تحریم هستیم) در وب سرویس arcgis ، مکان ترن ها رو بینیم که البته تابع فراخوانی رو هر از 10 ثانیه مجدد اجرا کنیم تا به روز بشن.
یک نفر که نمیدانم کیست امده یک نمونه کوچک و ناقص این رو ساخته که باید یا درون ان تغییرات لازم رو بدم و پردازش ها و خروجی های لازم واکشی بشه یا از اول بنویسمش که ان هم داستانی هست برای خودش
![تصویر خروجی کد نوشته شده]
و این هم کد نوشته شده:
<html>
<head>
<meta charset="utf-8"/>
<meta
name="viewport"
content="initial-scale=1, maximum-scale=1,user-scalable=no"
/>
<title>FeatureLayerView - query statistics by geometry - 4.14</title>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.14/esri/themes/light/main.css"
/>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.14/dijit/themes/claro/claro.css"
/>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
#chartPanel {
background: #fff;
font: "Avenir Next W00";
line-height: 1.5em;
overflow: auto;
padding: 10px;
width: 580px;
height: 300px;
}
.chart {
height: 280px;
}
</style>
<!-- Load the Chart.js library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
<script src="https://js.arcgis.com/4.14/"></script>
<script>
require([
"esri/widgets/Sketch/SketchViewModel",
"esri/geometry/Polyline",
"esri/geometry/Point",
"esri/Graphic",
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/layers/GraphicsLayer",
"esri/geometry/geometryEngine",
"esri/widgets/Expand",
"esri/widgets/Legend",
"esri/widgets/Search",
"esri/layers/GeoJSONLayer",
"esri/core/watchUtils"
], function (
SketchViewModel,
Polyline,
Point,
Graphic,
Map,
MapView,
FeatureLayer,
GraphicsLayer,
geometryEngine,
Expand,
Legend,
Search,
GeoJSONLayer,
watchUtils
) {
// App 'globals'
let sketchViewModel, featureLayerView, pausableWatchHandle, chartExpand;
let centerGraphic,
edgeGraphic,
polylineGraphic,
bufferGraphic,
centerGeometryAtStart,
labelGraphic;
const unit = "kilometers";
const url1 = "https://rata.digitraffic.fi/api/v1/train-locations.geojson/latest";
const url2 = "https://meri.digitraffic.fi/api/v1/locations/latest";
const template = {
title: "Train Info",
content: "Train number {trainNumber} on {timestamp} speed {speed}",
};
const renderer = {
type: "simple",
field: "speed",
symbol: {
type: "simple-marker",
color: "orange",
outline: {
color: "white"
}
},
visualVariables: [
{
type: "size",
field: "speed",
stops: [
{
value: 2,
size: "8px"
},
{
value: 8,
size: "25px"
}
]
}
]
};
let geojsonLayer1 = new GeoJSONLayer({
url: url1,
copyright: "Centria university of applied sciences",
popupTemplate: template,
renderer: renderer, //optional
});
let geojsonLayer2 = new GeoJSONLayer({
url: url2,
copyright: "Centria university of applied sciences",
popupTemplate: template,
//renderer: renderer, //optional
});
console.log(geojsonLayer2);
// Create layers
const graphicsLayer = new GraphicsLayer();
const graphicsLayer2 = new GraphicsLayer();
const featureLayer = new FeatureLayer({
portalItem: {
id: "83c37666a059480bb8a7cb73f449ff52"//buffergraphics has dependecies on portal item
},
outFields: ["*"]
});
// Create map
const map = new Map({
basemap: "dark-gray",
layers: [featureLayer, graphicsLayer2, graphicsLayer, geojsonLayer1, geojsonLayer2]
});
updateLayer();
function updateLayer() {
let geojsonLayer1 = new GeoJSONLayer({
url: url1,
copyright: "Centria",
popupTemplate: template,
renderer: renderer,
});
let geojsonLayer2 = new GeoJSONLayer({
url: url2,
copyright: "Centria",
popupTemplate: template,
//renderer: renderer,
});
map.layers.removeAll();
map.layers.addMany([featureLayer, graphicsLayer2, graphicsLayer, geojsonLayer1, geojsonLayer2]);
}
setInterval(function () {
updateLayer();
}, 12000);
// Create view
const view = new MapView({
container: "viewDiv",
map: map,
zoom: 7,
center: [23.13066, 63.83847]
});
// Update UI
setUpAppUI();
setUpSketch();
function setUpAppUI() {
// When layer is loaded, create a watcher to trigger drawing of the buffer polygon
view.whenLayerView(featureLayer).then(function (layerView) {
featureLayerView = layerView;
pausableWatchHandle = watchUtils.pausable(
layerView,
"updating",
function (val) {
if (!val) {
drawBufferPolygon();
}
}
);
// Display directions when the layerView is loading
watchUtils.whenFalseOnce(layerView, "updating", function () {
view.popup.open({
title: "Center point",
content:
"Drag this point to move the buffer.<br/> " +
"Or drag the <b>Edge</b> point to resize the buffer.",
location: centerGraphic.geometry
});
view.popup.alignment = "top-left";
});
});
view.when(function () {
const search = new Search({
view: view,
resultGraphicEnabled: false,
popupEnabled: false
});
// Resume drawBufferPolygon() function; user searched for a new location
// Must update the buffer polygon and re-run the stats query
search.on("search-complete", function () {
pausableWatchHandle.resume();
});
// Legend widget
const legend = new Legend({
view: view
});
// Display the Legend in an Expand widget
const legendExpand = new Expand({
expandTooltip: "Show Legend",
expanded: false,
view: view,
content: legend
});
// Add our components to the UI
view.ui.add(chartExpand, "bottom-left");
view.ui.add(search, "top-right");
//view.ui.add(legendExpand, "bottom-right");
});
// Close the 'help' popup when view is focused
view.watch("focused", function (newValue) {
if (newValue) {
view.popup.close();
}
});
}
/*****************************************************************
* Create SketchViewModel and wire up event listeners
*****************************************************************/
function setUpSketch() {
sketchViewModel = new SketchViewModel({
view: view,
layer: graphicsLayer
});
// Listen to SketchViewModel's update event so that population pyramid chart
// is updated as the graphics are updated
sketchViewModel.on("update", onMove);
}
/*********************************************************************
* Edge or center graphics are being moved. Recalculate the buffer with
* updated geometry information and run the query stats again.
*********************************************************************/
function onMove(event) {
// If the edge graphic is moving, keep the center graphic
// at its initial location. Only move edge graphic
if (
event.toolEventInfo &&
event.toolEventInfo.mover.attributes.edge
) {
const toolType = event.toolEventInfo.type;
if (toolType === "move-start") {
centerGeometryAtStart = centerGraphic.geometry;
}
// keep the center graphic at its initial location when edge point is moving
else if (toolType === "move" || toolType === "move-stop") {
centerGraphic.geometry = centerGeometryAtStart;
}
}
// the center or edge graphic is being moved, recalculate the buffer
const vertices = [
[centerGraphic.geometry.x, centerGraphic.geometry.y],
[edgeGraphic.geometry.x, edgeGraphic.geometry.y]
];
// client-side stats query of features that intersect the buffer
calculateBuffer(vertices);
// user is clicking on the view... call update method with the center and edge graphics
if (event.state === "cancel" || event.state === "complete") {
sketchViewModel.update([edgeGraphic, centerGraphic], {
tool: "move"
});
}
}
/*********************************************************************
* Edge or center point is being updated. Recalculate the buffer with
* updated geometry information.
*********************************************************************/
function calculateBuffer(vertices) {
// Update the geometry of the polyline based on location of edge and center points
polylineGraphic.geometry = new Polyline({
paths: vertices,
spatialReference: view.spatialReference
});
// Recalculate the polyline length and buffer polygon
const length = geometryEngine.geodesicLength(
polylineGraphic.geometry,
unit
);
const buffer = geometryEngine.geodesicBuffer(
centerGraphic.geometry,
length,
unit
);
// Update the buffer polygon
bufferGraphic.geometry = buffer;
// Query female and male age groups of the census tracts that intersect
// the buffer polygon on the client
queryGeoJsonLayer(buffer).then(function (newData) {
// Create a population pyramid chart from the returned result
updateList(newData);
});
// Update label graphic to show the length of the polyline
labelGraphic.geometry = edgeGraphic.geometry;
labelGraphic.symbol = {
type: "text",
color: "#FFEB00",
text: length.toFixed(2) + " kilometers",
xoffset: 50,
yoffset: 10,
font: {
// autocast as Font
size: 14,
family: "sans-serif"
}
};
}
/*********************************************************************
* Spatial query the census tracts feature layer view for statistics
* using the updated buffer polygon.
*********************************************************************/
function queryGeoJsonLayer(buffer) {
// Data storage for the chart
let trainData = [],
shipData = [];
// Client-side spatial query:
// Get a sum of age groups for census tracts that intersect the polygon buffer
const query = featureLayerView.layer.createQuery();
//query.outStatistics = statDefinitions;
query.geometry = buffer;
// Query the features on the client using FeatureLayerView.queryFeatures
return featureLayerView
.queryFeatures(query)
.then(function (results) {
// Statistics query returns a feature with 'stats' as attributes
const attributes = results.features[0].attributes;
// Loop through attributes and save the values for use in the population pyramid.
for (var key in attributes) {
if (key.includes("properties")) {
trainData.push(attributes[key]);
} else {
// Make 'all male age group population' total negative so that
// data will be displayed to the left of female age group
shipData.push(attributes[key]);
}
}
// Return information, seperated by gender
return [trainData, shipData];
})
.catch(function (error) {
console.log(error);
});
}
/***************************************************
* Draw the buffer polygon when application loads or
* when user searches for a new location
**************************************************/
function drawBufferPolygon() {
// When pause() is called on the watch handle, the callback represented by the
// watch is no longer invoked, but is still available for later use
// this watch handle will be resumed when user searches for a new location
pausableWatchHandle.pause();
// Initial location for the center, edge and polylines on the view
const viewCenter = view.center.clone();
const centerScreenPoint = view.toScreen(viewCenter);
const centerPoint = view.toMap({
x: centerScreenPoint.x + 120,
y: centerScreenPoint.y - 120
});
const edgePoint = view.toMap({
x: centerScreenPoint.x + 240,
y: centerScreenPoint.y - 120
});
// Store updated vertices
const vertices = [
[centerPoint.x, centerPoint.y],
[edgePoint.x, edgePoint.y]
];
// Create center, edge, polyline and buffer graphics for the first time
if (!centerGraphic) {
const polyline = new Polyline({
paths: vertices,
spatialReference: view.spatialReference
});
// get the length of the initial polyline and create buffer
const length = geometryEngine.geodesicLength(polyline, unit);
const buffer = geometryEngine.geodesicBuffer(
centerPoint,
length,
unit
);
// Create the graphics representing the line and buffer
const pointSymbol = {
type: "simple-marker",
style: "circle",
size: 10,
color: [0, 255, 255, 0.5]
};
centerGraphic = new Graphic({
geometry: centerPoint,
symbol: pointSymbol,
attributes: {
center: "center"
}
});
edgeGraphic = new Graphic({
geometry: edgePoint,
symbol: pointSymbol,
attributes: {
edge: "edge"
}
});
polylineGraphic = new Graphic({
geometry: polyline,
symbol: {
type: "simple-line",
color: [254, 254, 254, 1],
width: 2.5
}
});
bufferGraphic = new Graphic({
geometry: buffer,
symbol: {
type: "simple-fill",
color: [150, 150, 150, 0.2],
outline: {
color: "#FFEB00",
width: 2
}
}
});
labelGraphic = labelLength(edgePoint, length);
// Add graphics to layer
graphicsLayer.addMany([centerGraphic, edgeGraphic]);
// once center and edge point graphics are added to the layer,
// call sketch's update method pass in the graphics so that users
// can just drag these graphics to adjust the buffer
setTimeout(function () {
sketchViewModel.update([edgeGraphic, centerGraphic], {
tool: "move"
});
}, 1000);
graphicsLayer2.addMany([
bufferGraphic,
polylineGraphic,
labelGraphic
]);
}
// Move the center and edge graphics to the new location returned from search
else {
centerGraphic.geometry = centerPoint;
edgeGraphic.geometry = edgePoint;
}
// Query features that intersect the buffer
calculateBuffer(vertices);
}
// Create an population pyramid chart for the census tracts that intersect the buffer polygon
// Chart is created using the Chart.js library
let list;
function updateList(newData) {
chartExpand.expanded = true;
const trainData = newData[0];
const shipData = newData[0];
if (!list) {
// Get the canvas element and render the chart in it
const canvasElement = document.getElementById("list");
list = new Chart(canvasElement.getContext("2d"), {
type: "horizontalBar",
data: {
// age groups
labels: [
"85+",
"80-84",
"75-79",
"70-74",
"65-69",
"60-64",
"55-59",
"50-54",
"45-49",
"40-44",
"35-39",
"30-34",
"25-29",
"20-24",
"15-19",
"10-14",
"5-9",
"0-4"
],
datasets: [
{
label: "trains",
backgroundColor: "#B266FF",
borderColor: "#7F00FF",
borderWidth: 0.25,
data: trainData
},
{
label: "ships",
backgroundColor: "#0080FF",
borderColor: "#004C99",
borderWidth: 0.25,
data: shipData
}
]
},
options: {
responsive: false,
legend: {
position: "bottom"
},
title: {
display: true,
text: "Population pyramid"
},
scales: {
yAxes: [
{
categorySpacing: 0,
barThickness: 10,
stacked: true,
scaleLabel: {
display: true,
labelString: "vehicles"
}
}
],
xAxes: [
{
ticks: {
callback: function (value) {
const val = Math.abs(parseInt(value));
return numberWithCommas(val);
}
},
scaleLabel: {
display: true,
labelString: "Population"
}
}
]
},
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
return (
data.datasets[tooltipItem.datasetIndex].label +
": " +
numberWithCommas(Math.abs(tooltipItem.xLabel))
);
}
}
}
}
});
} else {
chart.data.datasets[0].data = trainData;
chart.data.datasets[1].data = shipData;
chart.update();
}
}
/* // Helper function for formatting number labels with commas
function numberWithCommas(value) {
value = value || 0;
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} */
// Label polyline with its length
function labelLength(geom, length) {
return new Graphic({
geometry: geom,
symbol: {
type: "text",
color: "#FFEB00",
text: length.toFixed(2) + " kilometers",
xoffset: 50,
yoffset: 10,
font: {
// autocast as Font
size: 14,
family: "sans-serif"
}
}
});
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="chartPanel">
<canvas id="list" class="list"></canvas>
</div>
</body>
</html>
که برای دیدن نقشه هم متاسفانه پرا کسی لازمه
حالا دوستان کمک کنید یک مقداری در باره بخش جاوا استکریپت نوشته شده بهم سر نخ بدین تا چیزی که از من خواستند و بعدا از من میخواهند رو انجام بدهم.
برای شروع کار خواستند که اگر کاربر، مکان دایره pointer رو تغییر داد یا مساحت ان رو بیشتر کرد و که باعث میشود ترن های در نقشه درون مساحت دایره قرار گیرند یا از ان محدوده مساحت دایره ما خارج بشوند.باید کاری کنم که با این اتفاق ، ترن های وارد شده به محدوده رو شناسایی و مثلا در یک لیست یا آلرت ، اسم ترن رو نشان و تشخیص بدم.
</body></html>
لینک صفحه توضیح وب سرویس ها رو گذاشتم.میتواند ببینید.من که بلد نبودم و سردرنیاوردم کدام بخش به درد من میخورد
مثلا اینجا رو ببینید چیزی متوجه میشوید
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟