I am a bit new to JavaScript. I want to buffer the location of a person's position when they click the Locate Button Widget.
I modified the Locate Widget in the JavaScript API 4.0 a little bit. I am trying to get the coordinates of the position when you click the button, so that I can create a point geometry to use in a buffer. I have looked around and can't find a firm answer. I saw that you need to use the getCurrentPosition function, but some reason I can't properly implement it in my code. This is what I have so far:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Final Project</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.1/esri/css/main.css">
<script src="https://js.arcgis.com/4.1/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#legendDiv {
max-width: 300px;
background-color: black;
padding: 8px;
color: white;
opacity: 0.85;
}
p {
max-width: 400px;
background-color: black;
padding: 15px;
border: 1px solid white;
color: white;
opacity: 0.95;
}
#toggle {
bottom: 20px;
left: 20px;
position: absolute;
z-index: 99;
max-width: 105px;
background-color: black;
border-radius: 8px;
padding: 10px;
color: white;
opacity: 0.85;
}
.esri-locate {
font-size: 18px;
background-color: white;
color: red;
width: 120px;
height: 40px;
padding: 0;
margin: 0;
border-radius: 8px;
overflow: hidden;
cursor: pointer;
}
.esri-locate span {
display: none;
}
.esri-locate:after {
content: 'GeoProcess';
}
</style>
<script>
require([
"esri/Map",
"esri/layers/FeatureLayer",
"esri/views/MapView",
"esri/widgets/Legend",
"esri/config",
"esri/core/urlUtils",
"esri/widgets/Locate",
"esri/layers/GraphicsLayer",
"esri/Graphic",
"esri/symbols/SimpleFillSymbol",
"esri/geometry/geometryEngine",
"dojo/dom-construct",
"dojo/dom",
"dojo/on",
"dojo/domReady!"
], function(
Map,
FeatureLayer,
MapView,
Legend,
esriConfig,
urlUtils,
Locate,
GraphicsLayer,
Graphic,
SimpleFillSymbol,
geometryEngine,
domConstruct,
dom,
on) {
var floodLayer = new FeatureLayer({
url: "https://igems.doi.gov/arcgis/rest/services/igems_haz/MapServer/0",
visible: true
});
var volcanoeLayer = new FeatureLayer({
url: "https://igems.doi.gov/arcgis/rest/services/igems_haz/MapServer/1",
visible: true
});
var earthquakeLayer = new FeatureLayer({
url: "https://igems.doi.gov/arcgis/rest/services/igems_haz/MapServer/3",
visible: true
});
var hurricaneLayer = new FeatureLayer({
url: "https://igems.doi.gov/arcgis/rest/services/igems_haz/MapServer/5",
visible: true
});
var wildfireLayer = new FeatureLayer({
url: "https://igems.doi.gov/arcgis/rest/services/igems_haz/MapServer/10",
visible: true
});
var shelterLayer = new FeatureLayer({
url: "http://gis.fema.gov/REST/services/NSS/FEMA_NSS/MapServer/5",
visible: false
});
var gLayer = new GraphicsLayer({});
var map = new Map({
basemap: "dark-gray",
layers: [gLayer, shelterLayer, floodLayer, volcanoeLayer, earthquakeLayer, hurricaneLayer, wildfireLayer]
});
var view = new MapView({
container: "viewDiv",
center: [-96.050173, 39.216911],
zoom: 5,
map: map
});
var legend = new Legend({
view: view,
layerInfos: [{
layer: floodLayer,
title: "Floods"
},
{
layer: volcanoeLayer,
title: "Volcanoes"
},
{
layer: earthquakeLayer,
title: "Earthquakes"
},
{
layer: hurricaneLayer,
title: "Hurricanes"
},
{
layer: wildfireLayer,
title: "Wildfires"
}]
}, "legendDiv");
view.ui.add(legend, "bottom-right");
var info = domConstruct.create("infoDiv", {
innerHTML: "<p>This map presents the geospatial locations for current natural hazards events (such as earthquakes, hurricanes, floods, and wildfires) as well as the locations of FEMA shelters. <br> <br> By clicking the button, this application will geocode your location, create a 5-10 mile buffer around that location, and provide directions to the closest shelter.</p>",
});
view.ui.add(info, "top-right");
var shelterTog = dom.byId("shelterToggle");
var wildfireTog = dom.byId("wildfireToggle");
var hurricaneTog = dom.byId("hurricaneToggle");
var earthquakeTog = dom.byId("earthquakeToggle");
var volcanoeTog = dom.byId("volcanoeToggle");
var floodTog = dom.byId("floodToggle");
on(shelterTog, "change", function(){
shelterLayer.visible = shelterTog.checked;
});
on(wildfireTog, "change", function(){
wildfireLayer.visible = wildfireTog.checked;
});
on(hurricaneTog, "change", function(){
hurricaneLayer.visible = hurricaneTog.checked;
});
on(earthquakeTog, "change", function(){
earthquakeLayer.visible = earthquakeTog.checked;
});
on(volcanoeTog, "change", function(){
volcanoeLayer.visible = volcanoeTog.checked;
});
on(floodTog, "change", function(){
floodLayer.visible = floodTog.checked;
});
//Locate Position
var locateBtn = new Locate({
view: view,
});
locateBtn.startup();
view.ui.add(locateBtn, {
position: "top-left",
index: 0
});
//Creat a symbol for buffer
var fillSymbol = new SimpleFillSymbol({
color: [227, 139, 79, 0.8],
outline: {color: [255, 255, 255],
width: 1
}
});
//Begin geoprocessing
locateBtn.on("locate", function(geoProcess){
view.zoom = 15;
navigator.geolocation.getCurrentPosition(function(position) {
var pt = new Point ({
longitude: position.coords.longitude,
latitude: position.coords.latitude
});
var buffer = geometryEngine.buffer(pt, 100, "miles");
var bufferGraphic = new Graphic({
geometry: buffer,
symbol: fillSymbol
});
gLayer.add(bufferGraphic);
});
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="legendDiv"></div>
<span id="toggle">
<input type="checkbox" id="shelterToggle"> Shelters<br>
<input type="checkbox" id="wildfireToggle" checked> Wildfires<br>
<input type="checkbox" id="hurricaneToggle" checked> Hurricanes<br>
<input type="checkbox" id="earthquakeToggle" checked> Earthquakes<br>
<input type="checkbox" id="volcanoeToggle" checked> Volcanoes<br>
<input type="checkbox" id="floodToggle" checked> Floods
</span>
</body>
</html>
Solved! Go to Solution.
Taylor,
In your locateBtn locate event handler just use:
Var locPnt = locateBtn.graphic.geometry;
If I am understanding you correctly, you could use this widget in WAB instead of writing your own code.
I appreciate your answer, but I need to write this in JavaScript without Web AppBuilder.
Taylor,
In your locateBtn locate event handler just use:
Var locPnt = locateBtn.graphic.geometry;
I added that text, and nothing happens with my buffer. It appears the point won't buffer at all. Is there maybe something wrong with my code for the buffer?
Taylor,
Did you use the new locPnt bar in the buffer?
Yes, I did. See below:
Just checked the console and I am getting an error when I try to buffer:
"The input unit and the spatial reference unit are not of the same unit type.ie Linear vs.Angular"
Any ideas?
Ok so the likely issue is that the locate graphic is geographic and the map is web Mercator so you need to use webmercatorutils to project the point to web Mercator before you bugger it.
Stupid autocorrect that was buffer.