Combine Locate Button and Geolocation

4703
4
Jump to solution
06-08-2015 03:39 AM
StevePiercy1
New Contributor

Thanks to a helpful person, I have a working example of a map with a QueryTask.

Now I want to add both Geolocation and a Locate Button. My attempts have been close but buggy. The following is my best effort.

I would greatly appreciate any assistance to add both features to the previous map.

<!DOCTYPE html>
<html>
<head>
<title>Create a Web Map</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" type="text/css" href="http://js.arcgis.com/3.13/esri/css/esri.css">
<style>
html,body,#mapDiv,#mapDiv.container{
    padding:20;
    margin:;
    height:650px;
    width:650px;
}
#LocateButton {
    position: absolute;
    top: 200px;
    left: 20px;
    z-index: 50;
}
</style>
<script src="http://js.arcgis.com/3.13compact/"></script>
<script type="text/javascript">
// TODO


// zoom to 50 miles
// center map on geolocation, else ZIP code, else CalPoly


// Add Locate Button
// https://developers.arcgis.com/javascript/jssamples/widget_locate.html
// 
// Add search location widget
// https://developers.arcgis.com/javascript/jshelp/intro_search_widget.html
// 
// OR Add geocoder widget
// https://developers.arcgis.com/javascript/jshelp/tutorial_geocoder.html
// http://developers.arcgis.com/javascript/sandbox/sandbox.html?sample=widget_geocoder_tutorial


// remove duplicates nurseries


var map;


window.onload=function(){
    require([
        "esri/map",
        "esri/arcgis/utils",
        "esri/dijit/LocateButton", // locate button
        "esri/geometry/webMercatorUtils", // geolocation
        "esri/geometry/Point", // geolocation
        "esri/layers/DynamicMapServiceLayer",
        "esri/layers/ArcGISDynamicMapServiceLayer",
        "esri/tasks/query",
        "esri/tasks/QueryTask",
        "esri/symbols/SimpleMarkerSymbol",
        "esri/InfoTemplate",
        "dojo/_base/Color",
        "dojo/ready",
        "dojo/domReady!"
        ], function(Map, arcgisUtils, LocateButton, webMercatorUtils, Point, DynamicMapServiceLayer, ArcGISDynamicMapServiceLayer, Query, QueryTask, SimpleMarkerSymbol, InfoTemplate, Color, ready){
        var createMapOptions = {
            mapOptions: {
                basemap: "streets",
                center: [-120.696,37.372],
                zoom: 10
            }
        };
        //create map and add layer
        arcgisUtils.createMap("bf27abedb4dd4197b0fd2237a56d1555", "mapDiv", createMapOptions).then(function (response) {
            map = response.map;
            executeQueryTask(dojo.byId('wholesaler_id').value);
        });


        //initialize query task
        queryTask = new esri.tasks.QueryTask("https://services1.arcgis.com/0j6vZbECadDEXdAS/arcgis/rest/services/Retail_Nurseries/FeatureServer/0");


        //initialize query
        query = new Query();
        query.returnGeometry = true;
        query.outFields = ["name","street_address","city","state","zip_code","telephone","website"];


        //initialize InfoTemplate
        infoTemplate = new InfoTemplate();
        infoTemplate.setTitle(getTextTitle);
        infoTemplate.setContent(getTextContent);


        function getTextTitle(graphic) {
            return graphic.attributes.name;
        }


        function getTextContent(graphic) {
            return (graphic.attributes.street_address + "<br/>"
            + graphic.attributes.city + ", "
            + graphic.attributes.state + " "
            + graphic.attributes.zip_code + "<br/>"
            + graphic.attributes.telephone
            + (String(graphic.attributes.website).length > 0
                & graphic.attributes.website !== null
                ? "<br/><a href=\"" + graphic.attributes.website + "\" target=\"_blank\">website</a>"
                : " "));
        }


        //create symbol for selected features
        symbol = new SimpleMarkerSymbol();
        symbol.setStyle(SimpleMarkerSymbol.STYLE_SQUARE);
        symbol.setSize(10);
        symbol.setColor(new Color([255,255,0,0.5]));


        // geolocation
        function zoomToLocation(location) {
            var pt = webMercatorUtils.geographicToWebMercator(new Point(location.coords.longitude, location.coords.latitude));
            map.centerAndZoom(pt, 10);
        }
        function showLocation(location) {
            if (location.coords.accuracy <= 500) {
                // the reading is accurate, do something
            } else {
                // reading is not accurate enough, do something else
            }
        }
        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;
            }
        }
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(zoomToLocation, locationError);
            navigator.geolocation.watchPosition(showLocation, locationError);
        }


        // geolocate
        var geoLocate = new LocateButton({
            map: mapDiv
        }, "LocateButton");
        geoLocate.startup();


    });
}


function executeQueryTask(wholesaler_id) {
    //set query based on what user typed in for id;
    query.where = "wholesaler_id IN(" + wholesaler_id + ")";
//    query.where = "wholesaler_id = " + wholesaler_id;
//     query.where = "wholesaler_id IN (1,2,3)";


    //execute query
    queryTask.execute(query,showResults);
}


function showResults(featureSet) {
    //remove all graphics on the maps graphics layer
    map.graphics.clear();


    //Performance enhancer - assign featureSet array to a single variable.
    var resultFeatures = featureSet.features;


    //Loop through each feature returned
    for (var i = 0, il = resultFeatures.length; i < il; i++) {
        //Get the current feature from the featureSet.
        //Feature is a graphic
        var graphic = resultFeatures;
        graphic.setSymbol(symbol);


        //Set the infoTemplate.
        graphic.setInfoTemplate(infoTemplate);


        //Add graphic to the map graphics layer.
        map.graphics.add(graphic);
    }
}
</script>


</head>
<body>
<h1>SelecTree Web Map</h1>
Enter wholesaler_id (0, 1, 2, or 3):
  <input type="text" id="wholesaler_id" value="1,2,3">
  <input type="button" value="Get Nurseries" onclick="executeQueryTask(dojo.byId('wholesaler_id').value);">
  <div id="mapDiv" class="map"><div id="LocateButton"></div></div>
</body>
</html>
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Steve,

  You had several issues.

  1. Get away from using window.onload.
  2. Add html element listeners in the js code by using on.
  3. You were defining the map twice.

<!DOCTYPE html>
<html>

<head>
  <title>Create a Web Map</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <link rel="stylesheet" type="text/css" href="http://js.arcgis.com/3.13/esri/css/esri.css">
  <style>
    html,
    body,
    #mapDiv,
    .map.container {
      padding: 20;
      margin: ;
      height: 650px;
      width: 650px;
    }

    #LocateButton {
      position: absolute;
      top: 200px;
      left: 20px;
      z-index: 50;
    }
  </style>
  <script src="http://js.arcgis.com/3.13compact/"></script>
  <script type="text/javascript">
    // TODO

    // zoom to 50 miles
    // center map on geolocation, else ZIP code, else CalPoly

    // Add Locate Button
    // https://developers.arcgis.com/javascript/jssamples/widget_locate.html
    //
    // Add search location widget
    // https://developers.arcgis.com/javascript/jshelp/intro_search_widget.html
    //
    // OR Add geocoder widget
    // https://developers.arcgis.com/javascript/jshelp/tutorial_geocoder.html
    // http://developers.arcgis.com/javascript/sandbox/sandbox.html?sample=widget_geocoder_tutorial

    var map;
    require([
      "esri/map",
      "esri/arcgis/utils",
      "esri/dijit/LocateButton", // locate button
      "esri/layers/DynamicMapServiceLayer",
      "esri/layers/ArcGISDynamicMapServiceLayer",
      "esri/tasks/query",
      "esri/tasks/QueryTask",
      "esri/symbols/SimpleMarkerSymbol",
      "esri/InfoTemplate",
      "dojo/_base/Color",
      "dojo/ready",
      "dojo/on",
      "dojo/_base/lang",
      "dojo/domReady!"
    ], function (
      Map, arcgisUtils, LocateButton, DynamicMapServiceLayer, ArcGISDynamicMapServiceLayer, Query, QueryTask,
      SimpleMarkerSymbol, InfoTemplate, Color, ready, on, lang) {

      //create symbol for selected features
      var symbol = new SimpleMarkerSymbol();
      symbol.setStyle(SimpleMarkerSymbol.STYLE_SQUARE);
      symbol.setSize(10);
      symbol.setColor(new Color([255, 255, 0, 0.5]));

      //create map and add layer
      arcgisUtils.createMap("bf27abedb4dd4197b0fd2237a56d1555", "mapDiv").then(function (response) {
        map = response.map;
        var geoLocate = new LocateButton({
          map: map
        }, "LocateButton");
        geoLocate.startup();
        executeQueryTask();
      });

      //initialize query task
      queryTask = new esri.tasks.QueryTask("https://services1.arcgis.com/0j6vZbECadDEXdAS/arcgis/rest/services/Retail_Nurseries/FeatureServer/0");

      //initialize query
      query = new Query();
      query.returnGeometry = true;
      query.outFields = ["name", "street_address", "city", "state", "zip_code", "telephone", "website"];

      on(dojo.byId('queryBtn'), 'click', lang.hitch(this, function(){
        executeQueryTask();
      }));

      //initialize InfoTemplate
      infoTemplate = new InfoTemplate();
      infoTemplate.setTitle(getTextTitle);
      infoTemplate.setContent(getTextContent);

      function getTextTitle(graphic) {
        return graphic.attributes.name;
      }

      function getTextContent(graphic) {
        return (graphic.attributes.street_address + "<br/>" + graphic.attributes.city + ", " + graphic.attributes.state + " " + graphic.attributes.zip_code + "<br/>" + graphic.attributes.telephone + (String(graphic.attributes.website).length > 0 & graphic.attributes.website !== null ? "<br/><a href=\"" + graphic.attributes.website + "\" target=\"_blank\">website</a>" : " "));
      }

      function executeQueryTask() {
        //set query based on what user typed in for id;
        query.where = "wholesaler_id IN(" + dojo.byId('wholesaler_id').value + ")";
        //execute query
        queryTask.execute(query, showResults);
      }

      function showResults(featureSet) {
        //remove all graphics on the maps graphics layer
        map.graphics.clear();

        //Performance enhancer - assign featureSet array to a single variable.
        var resultFeatures = featureSet.features;

        //Loop through each feature returned
        for (var i = 0, il = resultFeatures.length; i < il; i++) {
          //Get the current feature from the featureSet.
          //Feature is a graphic
          var graphic = resultFeatures;
          graphic.setSymbol(symbol);

          //Set the infoTemplate.
          graphic.setInfoTemplate(infoTemplate);

          //Add graphic to the map graphics layer.
          map.graphics.add(graphic);
        }
      }
    });
  </script>

</head>

<body>
  <h1>SelecTree Web Map</h1> Enter wholesaler_id (0, 1, 2, or 3):
  <input type="text" id="wholesaler_id" value="1,2,3">
  <input type="button" value="Get Nurseries" id="queryBtn">
  <div id="mapDiv" class="map">
    <div id="LocateButton"></div>
  </div>
</body>

</html>

View solution in original post

4 Replies
RobertScheitlin__GISP
MVP Emeritus

Steve,

   The locate button Dijit use HTML5 Geolocation abilities internally so there is no need to combine the two.

You can see this listed in the description of the locate button sample:

HTML5 Geolocation Position options for finding a location such as maximumAge and timeout.

StevePiercy1
New Contributor

Thanks, Robert. That solves half the problem. However, there is still an issue with combining dijit/LocateButton and QueryTask.

Here is the revised code.

<!DOCTYPE html>
<html>
<head>
<title>Create a Web Map</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" type="text/css" href="http://js.arcgis.com/3.13/esri/css/esri.css">
<style>
html,body,#mapDiv,.map.container{
    padding:20;
    margin:;
    height:650px;
    width:650px;
}
#LocateButton {
    position: absolute;
    top: 200px;
    left: 20px;
    z-index: 50;
}
</style>
<script src="http://js.arcgis.com/3.13compact/"></script>
<script type="text/javascript">
// TODO


// zoom to 50 miles
// center map on geolocation, else ZIP code, else CalPoly


// Add Locate Button
// https://developers.arcgis.com/javascript/jssamples/widget_locate.html
// 
// Add search location widget
// https://developers.arcgis.com/javascript/jshelp/intro_search_widget.html
// 
// OR Add geocoder widget
// https://developers.arcgis.com/javascript/jshelp/tutorial_geocoder.html
// http://developers.arcgis.com/javascript/sandbox/sandbox.html?sample=widget_geocoder_tutorial


// remove duplicates nurseries


var map;


window.onload=function(){
    require([
        "esri/map",
        "esri/arcgis/utils",
        "esri/dijit/LocateButton", // locate button
        "esri/layers/DynamicMapServiceLayer",
        "esri/layers/ArcGISDynamicMapServiceLayer",
        "esri/tasks/query",
        "esri/tasks/QueryTask",
        "esri/symbols/SimpleMarkerSymbol",
        "esri/InfoTemplate",
        "dojo/_base/Color",
        "dojo/ready",
        "dojo/domReady!"
        ], function(Map, arcgisUtils, LocateButton, DynamicMapServiceLayer, ArcGISDynamicMapServiceLayer, Query, QueryTask, SimpleMarkerSymbol, InfoTemplate, Color, ready){
        //create map and add layer
        arcgisUtils.createMap("bf27abedb4dd4197b0fd2237a56d1555", "mapDiv").then(function (response) {
            map = response.map;
            executeQueryTask(dojo.byId('wholesaler_id').value);
        });


        //initialize query task
        queryTask = new esri.tasks.QueryTask("https://services1.arcgis.com/0j6vZbECadDEXdAS/arcgis/rest/services/Retail_Nurseries/FeatureServer/0");


        //initialize query
        query = new Query();
        query.returnGeometry = true;
        query.outFields = ["name","street_address","city","state","zip_code","telephone","website"];


        //initialize InfoTemplate
        infoTemplate = new InfoTemplate();
        infoTemplate.setTitle(getTextTitle);
        infoTemplate.setContent(getTextContent);


        function getTextTitle(graphic) {
            return graphic.attributes.name;
        }


        function getTextContent(graphic) {
            return (graphic.attributes.street_address + "<br/>"
            + graphic.attributes.city + ", "
            + graphic.attributes.state + " "
            + graphic.attributes.zip_code + "<br/>"
            + graphic.attributes.telephone
            + (String(graphic.attributes.website).length > 0
                & graphic.attributes.website !== null
                ? "<br/><a href=\"" + graphic.attributes.website + "\" target=\"_blank\">website</a>"
                : " "));
        }


        //create symbol for selected features
        symbol = new SimpleMarkerSymbol();
        symbol.setStyle(SimpleMarkerSymbol.STYLE_SQUARE);
        symbol.setSize(10);
        symbol.setColor(new Color([255,255,0,0.5]));


        // locate button
        map = new Map("mapDiv", {
            basemap: "streets",
            center: [-120.696,37.372],
            zoom: 10
        });
        var geoLocate = new LocateButton({
            map: map
        }, "LocateButton");
        geoLocate.startup();
    });
}


function executeQueryTask(wholesaler_id) {
    //set query based on what user typed in for id;
    query.where = "wholesaler_id IN(" + wholesaler_id + ")";
//    query.where = "wholesaler_id = " + wholesaler_id;
//     query.where = "wholesaler_id IN (1,2,3)";


    //execute query
    queryTask.execute(query,showResults);
}


function showResults(featureSet) {
    //remove all graphics on the maps graphics layer
    map.graphics.clear();


    //Performance enhancer - assign featureSet array to a single variable.
    var resultFeatures = featureSet.features;


    //Loop through each feature returned
    for (var i = 0, il = resultFeatures.length; i < il; i++) {
        //Get the current feature from the featureSet.
        //Feature is a graphic
        var graphic = resultFeatures;
        graphic.setSymbol(symbol);


        //Set the infoTemplate.
        graphic.setInfoTemplate(infoTemplate);


        //Add graphic to the map graphics layer.
        map.graphics.add(graphic);
    }
}
</script>


</head>
<body>
<h1>SelecTree Web Map</h1>
Enter wholesaler_id (0, 1, 2, or 3):
  <input type="text" id="wholesaler_id" value="1,2,3">
  <input type="button" value="Get Nurseries" onclick="executeQueryTask(dojo.byId('wholesaler_id').value);">
  <div id="mapDiv" class="map"><div id="LocateButton"></div></div>
</body>
</html>

If I comment out lines 112-120, then the nursery locations get plotted on the map via the QueryTask. If I leave those lines uncommented, then the LocateButton appears and works, but the nursery locations do not get plotted. Try pasting it into the sandbox to see what I mean.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Steve,

  You had several issues.

  1. Get away from using window.onload.
  2. Add html element listeners in the js code by using on.
  3. You were defining the map twice.

<!DOCTYPE html>
<html>

<head>
  <title>Create a Web Map</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <link rel="stylesheet" type="text/css" href="http://js.arcgis.com/3.13/esri/css/esri.css">
  <style>
    html,
    body,
    #mapDiv,
    .map.container {
      padding: 20;
      margin: ;
      height: 650px;
      width: 650px;
    }

    #LocateButton {
      position: absolute;
      top: 200px;
      left: 20px;
      z-index: 50;
    }
  </style>
  <script src="http://js.arcgis.com/3.13compact/"></script>
  <script type="text/javascript">
    // TODO

    // zoom to 50 miles
    // center map on geolocation, else ZIP code, else CalPoly

    // Add Locate Button
    // https://developers.arcgis.com/javascript/jssamples/widget_locate.html
    //
    // Add search location widget
    // https://developers.arcgis.com/javascript/jshelp/intro_search_widget.html
    //
    // OR Add geocoder widget
    // https://developers.arcgis.com/javascript/jshelp/tutorial_geocoder.html
    // http://developers.arcgis.com/javascript/sandbox/sandbox.html?sample=widget_geocoder_tutorial

    var map;
    require([
      "esri/map",
      "esri/arcgis/utils",
      "esri/dijit/LocateButton", // locate button
      "esri/layers/DynamicMapServiceLayer",
      "esri/layers/ArcGISDynamicMapServiceLayer",
      "esri/tasks/query",
      "esri/tasks/QueryTask",
      "esri/symbols/SimpleMarkerSymbol",
      "esri/InfoTemplate",
      "dojo/_base/Color",
      "dojo/ready",
      "dojo/on",
      "dojo/_base/lang",
      "dojo/domReady!"
    ], function (
      Map, arcgisUtils, LocateButton, DynamicMapServiceLayer, ArcGISDynamicMapServiceLayer, Query, QueryTask,
      SimpleMarkerSymbol, InfoTemplate, Color, ready, on, lang) {

      //create symbol for selected features
      var symbol = new SimpleMarkerSymbol();
      symbol.setStyle(SimpleMarkerSymbol.STYLE_SQUARE);
      symbol.setSize(10);
      symbol.setColor(new Color([255, 255, 0, 0.5]));

      //create map and add layer
      arcgisUtils.createMap("bf27abedb4dd4197b0fd2237a56d1555", "mapDiv").then(function (response) {
        map = response.map;
        var geoLocate = new LocateButton({
          map: map
        }, "LocateButton");
        geoLocate.startup();
        executeQueryTask();
      });

      //initialize query task
      queryTask = new esri.tasks.QueryTask("https://services1.arcgis.com/0j6vZbECadDEXdAS/arcgis/rest/services/Retail_Nurseries/FeatureServer/0");

      //initialize query
      query = new Query();
      query.returnGeometry = true;
      query.outFields = ["name", "street_address", "city", "state", "zip_code", "telephone", "website"];

      on(dojo.byId('queryBtn'), 'click', lang.hitch(this, function(){
        executeQueryTask();
      }));

      //initialize InfoTemplate
      infoTemplate = new InfoTemplate();
      infoTemplate.setTitle(getTextTitle);
      infoTemplate.setContent(getTextContent);

      function getTextTitle(graphic) {
        return graphic.attributes.name;
      }

      function getTextContent(graphic) {
        return (graphic.attributes.street_address + "<br/>" + graphic.attributes.city + ", " + graphic.attributes.state + " " + graphic.attributes.zip_code + "<br/>" + graphic.attributes.telephone + (String(graphic.attributes.website).length > 0 & graphic.attributes.website !== null ? "<br/><a href=\"" + graphic.attributes.website + "\" target=\"_blank\">website</a>" : " "));
      }

      function executeQueryTask() {
        //set query based on what user typed in for id;
        query.where = "wholesaler_id IN(" + dojo.byId('wholesaler_id').value + ")";
        //execute query
        queryTask.execute(query, showResults);
      }

      function showResults(featureSet) {
        //remove all graphics on the maps graphics layer
        map.graphics.clear();

        //Performance enhancer - assign featureSet array to a single variable.
        var resultFeatures = featureSet.features;

        //Loop through each feature returned
        for (var i = 0, il = resultFeatures.length; i < il; i++) {
          //Get the current feature from the featureSet.
          //Feature is a graphic
          var graphic = resultFeatures;
          graphic.setSymbol(symbol);

          //Set the infoTemplate.
          graphic.setInfoTemplate(infoTemplate);

          //Add graphic to the map graphics layer.
          map.graphics.add(graphic);
        }
      }
    });
  </script>

</head>

<body>
  <h1>SelecTree Web Map</h1> Enter wholesaler_id (0, 1, 2, or 3):
  <input type="text" id="wholesaler_id" value="1,2,3">
  <input type="button" value="Get Nurseries" id="queryBtn">
  <div id="mapDiv" class="map">
    <div id="LocateButton"></div>
  </div>
</body>

</html>
StevePiercy1
New Contributor

Thank you, Robert!

Here is the example on a test server...

Create a Web Map

...and integrated with the site.

http://selectree-test.nreswebserver.calpoly.edu/tree-detail/afrocarpus-falcatus

0 Kudos