gsvc = new esri.tasks.GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"); gsvc.on("buffer-complete", function(result){ var symbol = new esri.symbol.SimpleFillSymbol( esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol( esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0,0,0,0.85]), 2 ), new dojo.Color([0,0,0,0.35]) ); var bufferGeometry = result.geometries[0]; var graphic = new Graphic(bufferGeometry, symbol); app.map.graphics.add(graphic); app.map.setExtent(graphic.geometry.getExtent().expand(1.4)); var query = new Query(); query.geometry = bufferGeometry; featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW) }); .... .... function BufferPrj(evt){ BufferDistance = document.getElementById('BufferDistanceKM').value; if (BufferDistance.length < 1){ alert("Please enter a buffer distance") }else{ app.map.graphics.clear(); var bufparams = new esri.tasks.BufferParameters(); bufparams.geometries = [ evt.mapPoint ]; //buffer in linear units such as meters, km, miles etc. bufparams.distances = [ BufferDistance ]; bufparams.geodesic = true; bufparams.bufferSpatialReference = app.map.spatialReference; bufparams.unit = esri.tasks.GeometryService.UNIT_KILOMETER; bufparams.outSpatialReference = app.map.spatialReference; gsvc.buffer(bufparams); } }
Jake,
I am new to JavaScript API and I came across your reply. I am trying to do something similar, using buffer to select from a feature layer and I want the results of the selection sent to a table, but when I put your code to buffer it does not work, do I need something else?
Here is the link to my code so far on JSFiddle:http://jsfiddle.net/JSSR/Lrby1wve/1/
It will be great if you can take a look at this and help me figure out what I am missing here
Thanks
Are you aware of the new capabilities added in the 3.9 version of the API that allows you to query against a Feature Layer hosted on ArcGIS.com where you can specify a buffer distance (and units)? This means you wouldn't have to use a GeometryService to return a buffer.
Ken,
I saw those and the only sample I found was doing this was using a Circle, for which I can give a radius to draw buffer and select features, but I was looking for something where the users can put in any distance value to buffer and select the features falling within that distance,
something like this:
BufferDistance = document.getElementById('BufferDistanceMiles').value;
Is there any way I can do this using Circle class?
Here is the sample I am referring to and I have added my hosted service to this example:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--The viewport meta tag is used to improve the presentation and behavior of the samples
on iOS devices-->
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Select with feature layer</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/tundra/tundra.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
<style>
html, body, #mapDiv {
padding: 0;
margin: 0;
height: 100%;
}
#messages{
background-color: #fff;
box-shadow: 0 0 5px #888;
font-size: 1.1em;
max-width: 15em;
padding: 0.5em;
position: absolute;
right: 20px;
top: 20px;
z-index: 40;
}
</style>
<script src="http://js.arcgis.com/3.10/"></script>
<script>
var map;
require([
"esri/map", "esri/layers/FeatureLayer",
"esri/tasks/query", "esri/geometry/Circle",
"esri/graphic", "esri/InfoTemplate", "esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/renderers/SimpleRenderer",
"esri/config", "esri/Color", "dojo/dom", "dojo/domReady!"
], function(
Map, FeatureLayer,
Query, Circle,
Graphic, InfoTemplate, SimpleMarkerSymbol,
SimpleLineSymbol, SimpleFillSymbol, SimpleRenderer,
esriConfig, Color, dom
) {
// use a proxy page if a URL generated by this page is greater than 2000 characters
//
// this should not be needed as nearly all query & select functions are performed on the client
esriConfig.defaults.io.proxyUrl = "/proxy";
map = new Map("mapDiv", {
basemap: "streets",
center: [-99.249, 31.954],
zoom: 7,
slider: true
});
// Note that an info template has been defined so when
//selected features are clicked a popup window will appear displaying the content defined in the info template.
var featureLayer = new FeatureLayer("https://services1.arcgis.com/hVMNhMnY75fwfIFy/ArcGIS/rest/services/NursingFacilities/FeatureServer/0",{
infoTemplate: new InfoTemplate("NursingFacility: ${FacilityID}", "${*}"),
outFields: ["ObjectID", "FacilityID", "FacilityName", "Full_Address", "Phone1"],
mode: FeatureLayer.MODE_ONDEMAND
});
// selection symbol used to draw the selected census block points within the buffer polygon
var symbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_CIRCLE,
12,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_NULL,
new Color([247, 34, 101, 0.9]),
1
),
new Color([207, 34, 171, 0.5])
);
featureLayer.setSelectionSymbol(symbol);
//make unselected features invisible
//var nullSymbol = new SimpleMarkerSymbol().setSize(0);
//featureLayer.setRenderer(new SimpleRenderer(nullSymbol));
map.addLayer(featureLayer);
var circleSymb = new SimpleFillSymbol(
SimpleFillSymbol.STYLE_NULL,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SHORTDASHDOTDOT,
new Color([105, 105, 105]),
2
), new Color([255, 255, 0, 0.25])
);
var circle;
//when the map is clicked create a buffer around the click point of the specified distance.
map.on("click", function(evt){
circle = new Circle({
center: evt.mapPoint,
geodesic: true,
radius: 10,
radiusUnit: "esriMiles"
});
map.graphics.clear();
map.infoWindow.show();
var graphic = new Graphic(circle, circleSymb);
map.graphics.add(graphic);
var query = new Query();
query.geometry = circle.getExtent();
//use a fast bounding box query. will only go to the server if bounding box is outside of the visible map
featureLayer.queryFeatures(query, selectInBuffer);
});
function selectInBuffer(response){
var feature;
var features = response.features;
var inBuffer = [];
//filter out features that are not actually in buffer, since we got all points in the buffer's bounding box
for (var i = 0; i < features.length; i++) {
feature = features;
if(circle.contains(feature.geometry)){
inBuffer.push(feature.attributes[featureLayer.objectIdField]);
}
}
var query = new Query();
query.objectIds = inBuffer;
//use a fast objectIds selection query (should not need to go to the server)
featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){
var totalFeatures = sumCount(results);
var r = "";
r = "<b>The total Number of Nursing Homes within the Buffer <i>" + totalFeatures+ "</i>.</b>";
dom.byId("messages").innerHTML = r;
});
}
function sumCount(features) {
var TotalCountl = 0;
for (var x = 0; x < features.length; x++) {
TotalCount = TotalCount + features
}
return TotalCount;
}
});
</script>
</head>
<body>
<span id="messages">Click on the map to select Nursing Homes within a 10 mile buffer.</span>
<div id="mapDiv"></div>
</body>
It is selecting the features like I want but I still need to figure out a way to have a choice to put in any distance to buffer and to send the selection to the datagrid.
Thanks
Hi Saloni,
You can create an input text box and then use the value from this using the dojo/dom module, ex:
var radius = parseInt(dom.byId("bufferDistance").value);
You will then want to specify this for the 'radius' option for the Circle:
map.on("click", function(evt){
circle = new Circle({
center: evt.mapPoint,
geodesic: true,
radius: radius,
radiusUnit: "esriMiles"
});
Here is an example:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Select with feature layer</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/tundra/tundra.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
<style>
html, body, #mapDiv {
padding: 0;
margin: 0;
height: 100%;
}
#messages{
background-color: #fff;
box-shadow: 0 0 5px #888;
font-size: 1.1em;
max-width: 15em;
padding: 0.5em;
position: absolute;
right: 20px;
top: 20px;
z-index: 40;
}
#bufferDiv{
background-color: #fff;
box-shadow: 0 0 5px #888;
font-size: 1.1em;
max-width: 15em;
padding: 0.5em;
position: absolute;
left: 70px;
top: 20px;
z-index: 40;
}
</style>
<script src="http://js.arcgis.com/3.10/"></script>
<script>
var map;
require([
"esri/map", "esri/layers/FeatureLayer",
"esri/tasks/query", "esri/geometry/Circle",
"esri/graphic", "esri/InfoTemplate", "esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/renderers/SimpleRenderer",
"esri/config", "esri/Color", "dojo/dom", "dojo/domReady!"
], function(
Map, FeatureLayer,
Query, Circle,
Graphic, InfoTemplate, SimpleMarkerSymbol,
SimpleLineSymbol, SimpleFillSymbol, SimpleRenderer,
esriConfig, Color, dom
) {
// use a proxy page if a URL generated by this page is greater than 2000 characters
// this should not be needed as nearly all query & select functions are performed on the client
esriConfig.defaults.io.proxyUrl = "/proxy";
map = new Map("mapDiv", {
basemap: "streets",
center: [-99.249, 31.954],
zoom: 7,
slider: true
});
// Note that an info template has been defined so when
//selected features are clicked a popup window will appear displaying the content defined in the info template.
var featureLayer = new FeatureLayer("https://services1.arcgis.com/hVMNhMnY75fwfIFy/ArcGIS/rest/services/NursingFacilities/FeatureServer/0",{
infoTemplate: new InfoTemplate("NursingFacility: ${FacilityID}", "${*}"),
outFields: ["ObjectID", "FacilityID", "FacilityName", "Full_Address", "Phone1"],
mode: FeatureLayer.MODE_ONDEMAND
});
// selection symbol used to draw the selected census block points within the buffer polygon
var symbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_CIRCLE,
12,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_NULL,
new Color([247, 34, 101, 0.9]),
1
),
new Color([207, 34, 171, 0.5])
);
featureLayer.setSelectionSymbol(symbol);
map.addLayer(featureLayer);
var circleSymb = new SimpleFillSymbol(
SimpleFillSymbol.STYLE_NULL,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SHORTDASHDOTDOT,
new Color([105, 105, 105]),
2
), new Color([255, 255, 0, 0.25])
);
var circle;
var radius = parseInt(dom.byId("bufferDistance").value);
//when the map is clicked create a buffer around the click point of the specified distance.
map.on("click", function(evt){
circle = new Circle({
center: evt.mapPoint,
geodesic: true,
radius: radius,
radiusUnit: "esriMiles"
});
map.graphics.clear();
map.infoWindow.show();
var graphic = new Graphic(circle, circleSymb);
map.graphics.add(graphic);
var query = new Query();
query.geometry = circle.getExtent();
//use a fast bounding box query. will only go to the server if bounding box is outside of the visible map
featureLayer.queryFeatures(query, selectInBuffer);
});
function selectInBuffer(response){
var feature;
var features = response.features;
var inBuffer = [];
//filter out features that are not actually in buffer, since we got all points in the buffer's bounding box
for (var i = 0; i < features.length; i++) {
feature = features;
if(circle.contains(feature.geometry)){
inBuffer.push(feature.attributes[featureLayer.objectIdField]);
}
}
var query = new Query();
query.objectIds = inBuffer;
//use a fast objectIds selection query (should not need to go to the server)
featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){
var totalFeatures = results.length;
var r = "";
r = "<b>The total Number of Nursing Homes within the Buffer <i>" + totalFeatures+ "</i>.</b>";
dom.byId("messages").innerHTML = r;
});
}
function sumCount(features) {
var TotalCount = 0;
for (var x = 0; x < features.length; x++) {
TotalCount = TotalCount + features
.attributes["POP2000"]; }
return TotalCount;
}
});
</script>
</head>
<body>
<span id="messages">Click on the map to select Nursing Homes within specified buffer distance.</span>
<div id="mapDiv">
<div id="bufferDiv">
<label for="bufferDistance">Enter distance: </label><input type="text" value="30" id="bufferDistance"/>
</div>
</div>
</body>
</html>
Hi Jake,
Thanks for the help, it looks like it should be doing exactly what we are looking for, but for some reason, when we change the value or put in a different number, the size of the buffer, it is actually drawing does not change when we move or click on another point. I tried it in ArcGIS API for JavaScript Sandbox.
Let me know if it looks right when you try.
Thanks again!
To fix this, you will just need to place the radius variable within the 'map.on' click event. Ex:
map.on("click", function(evt){
var radius = parseInt(dom.byId("bufferDistance").value);
circle = new Circle({
center: evt.mapPoint,
geodesic: true,
radius: radius,
radiusUnit: "esriMiles"
});
Jake,
I tried it and it works fine now.
I will look at the reference link you sent for dojo/dom documentation and try out other examples given there.
Appreciate your help, Thanks.