问题
Actually I am using ArcGIS API for JavaScript 4.7. I want to get name of hospital or street in particular area when draw polyline . How to achieve that ?
Suppose I draw a area through polyline. In this area there are some hospital or street ..etc . Now I need the name of hospitals or street within that area.
the result look like :- [street1,street2, ...] , [hospital1,hospital2, ...]
Update error :-esri.layers.graphics.QueryEngine", message: "Unsupported query" details: undefined} this error appear when try to collect hospital name in selected area the user can draw multi polygon,polyline
require([
"esri/views/MapView",
"esri/Map",
"esri/Basemap",
"esri/layers/TileLayer",
"esri/layers/MapImageLayer",
"esri/widgets/Sketch/SketchViewModel",
"esri/geometry/geometryEngine",
"esri/widgets/CoordinateConversion",
"esri/geometry/support/webMercatorUtils",
"esri/Graphic",
"esri/layers/GraphicsLayer",
"esri/config",
"esri/core/urlUtils",
"esri/widgets/Search",
"esri/tasks/Locator",
"esri/layers/FeatureLayer",
"esri/widgets/Expand",
"dojo/domReady!"
], function (
MapView, Map, Basemap, TileLayer, MapImageLayer,
SketchViewModel,
geometryEngine,
CoordinateConversion,
webMercatorUtils,
Graphic, GraphicsLayer, esriConfig,
urlUtils,Search,Locator,FeatureLayer,Expand
) {
const hospitals =new FeatureLayer({
url: 'https://services.arcgis.com/fLeGjb7u4uXqeF9q/ArcGIS/rest/services/Hospitals/Feat
ureServer/0',
renderer: {
type: 'simple',
symbol: {
type: 'text',
color: 'green',
text: '\ue687',
font: {
size: 16,
family: 'CalciteWebCoreIcons'
},
haloColor: 'white',
haloSize: 2
}
},
outFields: ['*']
});
var tempGraphicsLayer = new GraphicsLayer();
var saveGraphicsLayer = new GraphicsLayer();
var updateGraphic;
let hospitalsLayerView = null;
let highlight = null;
var myMap;
myMap = new Map({
basemap: "streets", //satellite
layers: [hospitals,tempGraphicsLayer, saveGraphicsLayer]
});
view = new MapView({
center: [-75.1683665, 39.951817],// [54.49, 24.41] long, lat
container: "viewDiv",
map: myMap,
zoom: 14
});
var ccWidget = new CoordinateConversion({
view: view
});
const searchWidget = new Search({
sources: [{
locator: new Locator({ url:
"https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer"}),
countryCode:"AE",
singleLineFieldName: "SingleLine",
name: "Custom Geocoding Service",
localSearchOptions: {
minScale: 300000,
distance: 50000
},
placeholder: "Find a place",
maxResults: 3,
maxSuggestions: 6,
suggestionsEnabled: true,
minSuggestCharacters: 0
}],
view: view,
includeDefaultSources: false
});
view.ui.add(searchWidget, {
position: "top-right",
index: 1
});
view.ui.add(ccWidget, "bottom-left");
view.ui.add("topbar", "top-right");
var pointSymbol = { // symbol used for points
type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
style: "square",
color: "#8A2BE2",
size: "16px",
outline: { // autocasts as new SimpleLineSymbol()
color: [255, 255, 255],
width: 3 // points
}
}
var polylineSymbol = { // symbol used for polylines
type: "simple-line", // autocasts as new SimpleLineSymbol()
color: "#8A2BE2",
width: "4",
style: "dash"
}
var polygonSymbol = { // symbol used for polygons
type: "simple-fill", // autocasts as new SimpleFillSymbol()
color: "rgba(138,43,226, 0.8)",
style: "solid",
outline: {
color: "white",
width: 1
}
}
var polygonBoundrySymbol = { // symbol used for polygons
type: "simple-line", // autocasts as new SimpleFillSymbol()
color: "red"
}
let drawBoundry = function(){
let boundryJson = $v('P0_USER_LIMITS');
if(boundryJson){
let boundry = Graphic.fromJSON(JSON.parse(boundryJson));
boundry.symbol = polygonBoundrySymbol;
tempGraphicsLayer.add(boundry);
return boundry;
}
}
view.when(function () {
$('.esri-view-root').on('click', '.esri-print__export-button',
function(e){
e.preventDefault();
saveExportedImg();
});
// create a new sketch view model
var sketchViewModel = new SketchViewModel({
view: view,
layer: tempGraphicsLayer,
pointSymbol: pointSymbol,
polylineSymbol: polylineSymbol,
polygonSymbol: polygonSymbol
});
hospitals.when(function () {
view.whenLayerView(hospitals).then(function (layerView){
hospitalsLayerView = layerView;
})
})
.catch(errorCallback);
sketchViewModel.on("draw-complete", addGraphic);
sketchViewModel.on("update-complete", addGraphic);
sketchViewModel.on("update-cancel", addGraphic);
sketchViewModel.on("vertex-add", addGraphic);
function addGraphic(evt) {
// console.log ('graphic.geometry',evt.geometry)
//let currentGraphic = popActiveGraphic(tempGraphicsLayer);
let currentGraphic = saveGraphicsLayer.graphics.items.pop();
selectFeatures(evt.geometry);
var geometry = evt.geometry;
var vertices = evt.vertices;
var symbol;
var attr = {
Name: "Selected Area",
X: $v('P24_X'),
Y: $v('P24_Y')
};
// Choose a valid symbol based on return geometry
switch (geometry.type) {
case "point":
symbol = pointSymbol;
break;
case "polyline":
symbol = polylineSymbol;
break;
default:
symbol = polygonSymbol;
break;
}
geometry = webMercatorUtils.webMercatorToGeographic(geometry)
var within = true;
//}
if(within){
let graphic = new Graphic({
geometry: geometry,
symbol: symbol,
//attributes: attr,
popupTemplate: {
title: "{Name}",
content: [{
type: "fields",
fieldInfos: [{
fieldName: "X"
}, {
fieldName: "Y"
}]
}]
}
});
tempGraphicsLayer.add(graphic);
if(currentGraphic){
geometry.rings.forEach( ring =>
currentGraphic.geometry.addRing(ring));
graphic = currentGraphic;
}
var saveObj = graphic.toJSON();
$x('P24_JSON').value = JSON.stringify(saveObj);
saveGraphicsLayer.add(graphic);
} else {
apex.message.alert('&G_MAP_BOUNDRY_MSG.');
}
updateGraphic = null;
}
window.loadGraphic = function(polygon){
if(polygon===undefined || polygon === ''){
console.error('no polygon');
} else {
var graphic = Graphic.fromJSON(JSON.parse(polygon));
if (graphic.geometry){
addMultiGraph(graphic);
view.center.longitude = graphic.geometry.centroid.longitude;
view.center.latitude = graphic.geometry.centroid.latitude;
view.center = [graphic.geometry.centroid.longitude,
graphic.geometry.centroid.latitude];
view.zoom = 12;
}
}
}
loadGraphic($v('P24_JSON'));
// *************************************
// activate the sketch to create a point
// *************************************
var drawPointButton = document.getElementById("pointButton");
drawPointButton.onclick = function () {
// set the sketch to create a point geometry
sketchViewModel.create("point");
setActiveButton(this);
};
// ****************************************
// activate the sketch to create a polyline
// ****************************************
var drawLineButton = document.getElementById("polylineButton");
drawLineButton.onclick = function () {
// set the sketch to create a polyline geometry
sketchViewModel.create("polyline");
setActiveButton(this);
};
// ***************************************
// activate the sketch to create a polygon
// ***************************************
var drawPolygonButton = document.getElementById("polygonButton");
drawPolygonButton.onclick = function () {
// set the sketch to create a polygon geometry
sketchViewModel.create("polygon");
setActiveButton(this);
};
// ***************************************
// activate the sketch to create a rectangle
// ***************************************
var drawRectangleButton = document.getElementById(
"rectangleButton");
drawRectangleButton.onclick = function () {
// set the sketch to create a polygon geometry
sketchViewModel.create("rectangle");
setActiveButton(this);
};
document.getElementById("resetBtn").onclick = function () {
sketchViewModel.reset();
tempGraphicsLayer.removeAll();
saveGraphicsLayer.removeAll();
setActiveButton();
drawBoundry();
};
function setActiveButton(selectedButton) {
// focus the view to activate keyboard shortcuts for sketching
view.focus();
var elements = document.getElementsByClassName("active");
for (var i = 0; i < elements.length; i++) {
elements[i].classList.remove("active");
}
if (selectedButton) {
selectedButton.classList.add("active");
}
}
// ************************************************************************************
// set up logic to handle geometry update and reflect the update on "tempGraphicsLayer"
// ************************************************************************************
function setUpClickHandler() {
view.on("click", function (evt) {
view.hitTest(evt).then(function (response) {
var results = response.results;
// Found a valid graphic
if (results.length && results[results.length - 1]
.graphic) {
// Check if we're already editing a graphic
if (!updateGraphic) {
// Save a reference to the graphic we intend to update
updateGraphic = results[results.length - 1].graphic;
// Remove the graphic from the GraphicsLayer
// Sketch will handle displaying the graphic while being updated
tempGraphicsLayer.remove(updateGraphic);
sketchViewModel.update(updateGraphic.geometry);
}
}
});
});
}
function selectFeatures(geometry) {
if (hospitalsLayerView) {
let query = hospitals.createQuery();
query.returnGeometry = true;
query.outFields = ["*"];
hospitalsLayerView.queryFeatures(query)
.then(function (results) {
console.log ('results.features',results.features);
const graphics = results.features;
if (highlight) {
highlight.remove();
}
highlight = hospitalsLayerView.highlight(graphics);
console.log ('hospitL',graphics.map(g =>
g.attributes.HOSPITAL_NAME).join(','));
// namesDiv.innerHTML = graphics.map(g =>
g.attributes.HOSPITAL_NAME).join(',');
}).catch(errorCallback);
}
}
function errorCallback(error) {
console.log('error:', error);
}
// ************************************************************************************
// returns graphic object if drawn on the map to contcat new graphics to it
// ************************************************************************************
function popActiveGraphic(graphicsLayer){
let length = graphicsLayer.graphics.length;
let count = 0;
if($v('P0_USER_LIMITS').length > 0){
count++;
}
if(length > count){ //active drawing detected
let result = graphicsLayer.graphics.items[length-1];
graphicsLayer.remove(result);
return result;
}
}
});
});
Thanks,
回答1:
Well, here I made an example for you merging some ArcGIS examples.
Just select the hospitals using a polygon. The selected hospitals are highlighted and the names display in the text section.
In your case do the same thing with any other layer you want to query to get features data.
<html>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='initial-scale=1, maximum-scale=1, user-scalable=no'>
<title>Select Feature With Polygon</title>
<style>
html,
body {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#viewDiv {
padding: 0;
margin: 0;
height: 400px;
width: 100%;
}
#namesDiv {
margin: 10px;
height: 200px;
width: 100%;
font-style: italic;
font-weight: bold;
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
color: green;
overflow: auto;
}
</style>
<link rel='stylesheet' href='https://js.arcgis.com/4.15/esri/css/main.css'>
<script src='https://js.arcgis.com/4.15/'></script>
<script>
require([
'esri/Map',
'esri/views/MapView',
'esri/layers/FeatureLayer',
'esri/layers/GraphicsLayer',
'esri/widgets/Sketch/SketchViewModel',
'esri/Graphic',
'esri/widgets/Expand'
], function (
Map,
MapView,
FeatureLayer,
GraphicsLayer,
SketchViewModel,
Graphic,
Expand
) {
let hospitalsLayerView = null;
let highlight = null;
const hospitals = new FeatureLayer({
url: 'https://services.arcgis.com/fLeGjb7u4uXqeF9q/ArcGIS/rest/services/Hospitals/FeatureServer/0',
renderer: {
type: 'simple',
symbol: {
type: 'text',
color: 'green',
text: '\ue687',
font: {
size: 16,
family: 'CalciteWebCoreIcons'
},
haloColor: 'white',
haloSize: 2
}
},
outFields: ['*']
});
const polygonGraphicsLayer = new GraphicsLayer();
const map = new Map({
basemap: 'streets',
layers: [hospitals, polygonGraphicsLayer]
});
const view = new MapView({
container: 'viewDiv',
map: map,
center: [-75.1683665, 39.951817],
zoom: 14
});
const sketchViewModel = new SketchViewModel({
view: view,
layer: polygonGraphicsLayer,
pointSymbol: {
type: 'simple-marker',
color: [255, 255, 255, 0],
size: '1px',
outline: {
color: 'gray',
width: 0
}
}
});
sketchViewModel.on('create', function (event) {
if (event.state === 'complete') {
polygonGraphicsLayer.remove(event.graphic);
selectFeatures(event.graphic.geometry);
}
});
hospitals.when(function () {
view.whenLayerView(hospitals).then(function (layerView){
hospitalsLayerView = layerView;
})
})
.catch(errorCallback);
const namesDiv = document.getElementById('namesDiv');
view.ui.add('select-by-polygon', 'top-left');
const selectButton = document.getElementById('select-by-polygon');
selectButton.addEventListener('click', function () {
clearUpSelection();
sketchViewModel.create('polygon');
});
function selectFeatures(geometry) {
view.graphics.removeAll();
if (hospitalsLayerView) {
const query = {
geometry: geometry,
outFields: ['*']
};
hospitalsLayerView
.queryFeatures(query)
.then(function (results) {
const graphics = results.features;
if (highlight) {
highlight.remove();
}
highlight = hospitalsLayerView.highlight(graphics);
namesDiv.innerHTML = graphics.map(g => g.attributes.HOSPITAL_NAME).join(',');
})
.catch(errorCallback);
}
}
function clearUpSelection() {
view.graphics.removeAll();
namesDiv.innerHTML = null;
}
function errorCallback(error) {
console.log('error:', error);
}
});
</script>
</head>
<body>
<div id='viewDiv'>
<div
id="select-by-polygon"
class="esri-widget esri-widget--button esri-widget esri-interactive"
title="Select hospitals by polygon"
>
<span class="esri-icon-checkbox-unchecked"></span>
</div>
</div>
<div id="namesDiv"></div>
</body>
</html>
来源:https://stackoverflow.com/questions/65166095/how-to-get-get-name-of-hospital-or-street-in-particular-area-when-draw-polyline