Graphics for on Map click

6599
8
Jump to solution
06-02-2020 04:29 AM
MatildaOtiede
New Contributor II

Hi All,

Need help to achieve the following

What works at the moment, you click on a map and it returns the coordinates of that location

You do a search and it returns a popup info.

I would like to click on the map using a graphic point

Also when the search result is on the map, I want the graphic point to be used.

I have the graphic symbol  in the code, not sure how to  use it on the locator and evt.mapPoint. 

Thanks in advance

*****************************************************************************************

function(Map, MapView, Search, Graphic, FeatureLayer) {

var map = new Map({
basemap: "topo"
});

// Add the layer to the map


//map.add(trailsLayer); // Optionally add layer to map

var view = new MapView({
container: "viewDiv",
map: map,
center: [-0.14718, 51.51161],
zoom: 17
});


// Search

var search = new Search({
view: view
});
search.defaultSource.withinViewEnabled = false; // Limit search to visible map area only
view.ui.add(search, "top-right"); // Add to the map

// Add instruction to the map
view.ui.add("instruction", "bottom-left")

// Find address
var simpleMarkerSymbol = {
type: "simple-marker",
color: [226, 119, 40], // orange
outline: {
color: [255, 255, 255], // white
width: 1
}
};

var pointGraphic = new Graphic({
geometry: point,
symbol: simpleMarkerSymbol
});

view.graphics.add(pointGraphic);

function showPopup(address, pt) {
view.popup.open({
title: "Find Address Result",
content: address + "<br><br> Lat: " + Math.round(pt.latitude * 100000)/100000 + " Lon: " + Math.round(pt.longitude * 100000)/100000,
location: pt,
actions: [{
id: "find-brewery",
image: "beer.png",
title: "get xy"
}]
});
}

view.on("click", function(evt){
search.clear();
view.popup.clear();
var locatorSource = search.defaultSource;
locatorSource.locator.locationToAddress(evt.mapPoint)
.then(function(response) {
var address = response.address.Match_addr;
// Show the address found
showPopup(address, evt.mapPoint);
}, function(err) {
// Show no address found
showPopup("No address found for this location.", evt.mapPoint);
});
});

});</script>

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
ChristianBischof
Esri Contributor

Is this what you're looking for?

<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <!--
  ArcGIS API for JavaScript, https://js.arcgis.com
  For more information about the intro-graphics sample, read the original sample description at developers.arcgis.com.
  https://developers.arcgis.com/javascript/latest/sample-code/intro-graphics/index.html
  -->
    <title>DevLabs - Search and Geocode</title>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.15/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.15/"></script>

    <style>
      html,
      body {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }

      #viewDiv {
        padding: 0;
        margin: 0;
        height: 80%;
        width: 60%;
      }

      #instruction {
        padding: 15px;
        background: white;
        color: black;
        border: 5px solid gold;
        font-family: sans-serif;
        font-size: 1.2em;
      }

      #instruction2 {
        width: 60%;
        margin-top: 4px;
      }
      #getLocBtn {
        float: left;
        margin-top: 4px;
      }
    </style>

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/Graphic",
        "esri/widgets/Search",
        "esri/tasks/Locator",
      ], function (Map, MapView, Graphic, Search, Locator) {
        var map = new Map({
          basemap: "topo",
        });

        var view = new MapView({
          container: "viewDiv",
          map: map,
          center: [-0.14718, 51.51161],
          zoom: 17,
        });

        var search = new Search({
          view: view,
        });
        //search.defaultSource.withinViewEnabled = false; // Limit search to visible map area only
        view.ui.add(search, "top-right"); // Add to the map
        // Add instruction to the map
        view.ui.add("instruction", "bottom-left");

        view.on("click", function (evt) {
          // Create a graphic and add the geometry and symbol to it
          var graphic = new Graphic({
            geometry: {
              type: "point",
              latitude: evt.mapPoint.latitude,
              longitude: evt.mapPoint.longitude,
              spatialReference: view.spatialReference,
            },
            symbol: {
              type: "simple-marker", // autocasts as new SimpleFillSymbol
              color: [255, 10, 10],
              outline: {
                // autocasts as new SimpleLineSymbol()
                color: [255, 255, 255],
                width: 2,
              },
            },
          });
          view.graphics.removeAll();
          view.graphics.add(graphic);

          search.search(evt.mapPoint);
          search.resultGraphicEnabled = false;
        });
      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
    <div id="instruction">
        Click on the map to retrieve coordinates and address
      </div>
  </body>
</html>

View solution in original post

8 Replies
ChristianBischof
Esri Contributor
view.on("click", function (event) {
            view.popup
              .fetchFeatures(event.screenPoint)
              .then(function (response) {
                  console.log(response);
                // Access the response from fetchFeatures
                response.allGraphicsPromise.then(function (graphics) {
                  // Set the feature widget's graphic to the returned graphic from fetchFeatures
                  console.log(graphics[0]);
                });
              });
            view.popup.open({
              location: event.mapPoint,
            });
          });

This code snippet gets you the data of the features (if there are any) at the event.mapPoint. Sorry I'm not sure if I got your problem right.

With graphics.attributes you can get the information from the feature you clicked on.

0 Kudos
MatildaOtiede
New Contributor II

Thanks Christian.

See the full code below. Using the search to search for an address, the search result should have a red graphic point and a popup window.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>DevLabs - Search and Geocode</title>
<style>

html,

body {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}

#viewDiv {
padding: 0;
margin: 0;
height: 80%;
width: 60%;
}

#instruction {
padding: 15px;
background: white;
color: black;
border: 5px solid gold;
font-family: sans-serif;
font-size: 1.2em;
}

#instruction2 {
width: 60%;
margin-top: 4px;
}
#getLocBtn {
float: left;
margin-top: 4px;
}

</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.3/esri/css/main.css">
<script src="https://js.arcgis.com/4.3/"></script>

<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/widgets/Search",
"esri/layers/FeatureLayer",
"esri/widgets/Locate",
"esri/Graphic",
"dojo/domReady!"
], function(Map, MapView, Search, Graphic, FeatureLayer, Locate) {

var map = new Map({
basemap: "topo"
});

// Add the layer to the map


//map.add(trailsLayer); // Optionally add layer to map

var view = new MapView({
container: "viewDiv",
map: map,
center: [-0.14718, 51.51161],
zoom: 17
});


// Search

var search = new Search({
view: view
});
search.defaultSource.withinViewEnabled = false; // Limit search to visible map area only
view.ui.add(search, "top-right"); // Add to the map

// Add instruction to the map
view.ui.add("instruction", "bottom-left")

// Find address
var simpleMarkerSymbol = {
type: "simple-marker",
color: [226, 119, 40], // orange
outline: {
color: [255, 255, 255], // white
width: 1
}
};

var pointGraphic = new Graphic({
geometry: point,
symbol: simpleMarkerSymbol
});

view.graphics.add(pointGraphic);

function showPopup(address, pt) {
view.popup.open({
title: "Find Address Result",
content: address + "<br><br> Lat: " + Math.round(pt.latitude * 100000)/100000 + " Lon: " + Math.round(pt.longitude * 100000)/100000,
location: pt,
actions: [{
id: "find-brewery",
image: "beer.png",
title: "get xy"
}]
});
}

view.on("click", function(evt){
search.clear();
view.popup.clear();
var locatorSource = search.defaultSource;
locatorSource.locator.locationToAddress(evt.mapPoint)
.then(function(response) {
var address = response.address.Match_addr;
// Show the address found
showPopup(address, evt.mapPoint);
}, function(err) {
// Show no address found
showPopup("No address found for this location.", evt.mapPoint);
});
});
view.on("click", function (event) {
view.popup
.fetchFeatures(event.screenPoint)
.then(function (response) {
console.log(response);
// Access the response from fetchFeatures
response.allGraphicsPromise.then(function (graphics) {
// Set the feature widget's graphic to the returned graphic from fetchFeatures
console.log(graphics[0]);
});
});
view.popup.open({
location: event.mapPoint,
});
});

});</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="instruction">
Click on the map to retrieve coordinates and address
</div>

</body>
</html>

0 Kudos
ChristianBischof
Esri Contributor
//############ point variable was missing above pointGraphic declaration ###########
var point = {
     type: "point", // autocasts as new Point()
};‍‍‍‍

additionally I've commented out my first suggestion because I think you don't need it

Full code:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1, maximum-scale=1, user-scalable=no"
    />
    <title>DevLabs - Search and Geocode</title>
    <style>
      html,
      body {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }

      #viewDiv {
        padding: 0;
        margin: 0;
        height: 80%;
        width: 60%;
      }

      #instruction {
        padding: 15px;
        background: white;
        color: black;
        border: 5px solid gold;
        font-family: sans-serif;
        font-size: 1.2em;
      }

      #instruction2 {
        width: 60%;
        margin-top: 4px;
      }
      #getLocBtn {
        float: left;
        margin-top: 4px;
      }
    </style>
    <link rel="stylesheet" href="https://js.arcgis.com/4.3/esri/css/main.css" />
    <script src="https://js.arcgis.com/4.3/"></script>

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/widgets/Search",
        "esri/layers/FeatureLayer",
        "esri/widgets/Locate",
        "esri/Graphic",
        "dojo/domReady!",
      ], function (Map, MapView, Search, Graphic, FeatureLayer, Locate) {
        var map = new Map({
          basemap: "topo",
        });

        // Add the layer to the map

        //map.add(trailsLayer); // Optionally add layer to map

        var view = new MapView({
          container: "viewDiv",
          map: map,
          center: [-0.14718, 51.51161],
          zoom: 17,
        });

        // Search

        var search = new Search({
          view: view,
        });
        search.defaultSource.withinViewEnabled = false; // Limit search to visible map area only
        view.ui.add(search, "top-right"); // Add to the map

        // Add instruction to the map
        view.ui.add("instruction", "bottom-left");

        // Find address
        var simpleMarkerSymbol = {
          type: "simple-marker",
          color: [226, 119, 40], // orange
          outline: {
            color: [255, 255, 255], // white
            width: 1,
          },
        };

        //############ point variable was missing above pointGraphic declaration ###########
        var point = {
          type: "point", // autocasts as new Point()
        };

        var pointGraphic = new Graphic({
           geometry: point,
          symbol: simpleMarkerSymbol,
        });

        view.graphics.add(pointGraphic);

        function showPopup(address, pt) {
          view.popup.open({
            title: "Find Address Result",
            content:
              address +
              "<br><br> Lat: " +
              Math.round(pt.latitude * 100000) / 100000 +
              " Lon: " +
              Math.round(pt.longitude * 100000) / 100000,
            location: pt,
            actions: [
              {
                id: "find-brewery",
                image: "beer.png",
                title: "get xy",
              },
            ],
          });
        }

        view.on("click", function (evt) {
          search.clear();
          view.popup.clear();
          var locatorSource = search.defaultSource;
          locatorSource.locator.locationToAddress(evt.mapPoint).then(
            function (response) {
              var address = response.address.Match_addr;
              // Show the address found
              showPopup(address, evt.mapPoint);
            },
            function (err) {
              // Show no address found
              showPopup("No address found for this location.", evt.mapPoint);
            }
          );
        });
        //############ my first suggestion #################

        // view.on("click", function (event) {
        //   view.popup.fetchFeatures(event.screenPoint).then(function (response) {
        //     console.log(response);
        //     // Access the response from fetchFeatures
        //     response.allGraphicsPromise.then(function (graphics) {
        //       // Set the feature widget's graphic to the returned graphic from fetchFeatures
        //       console.log(graphics[0]);
        //     });
        //   });
        //   view.popup.open({
        //     location: event.mapPoint,
        //   });
        // });
       });
    </script>
  </head>
  <body>
    <div id="viewDiv"></div>
    <div id="instruction">
      Click on the map to retrieve coordinates and address
    </div>
  </body>
</html>
MatildaOtiede
New Contributor II

Hi Christian,

Thanks for your help.

How do I assign the Point graphics on click function so it returns the searched address using the graphic point symbol

As shown below the code displays the location of the search. But I would like the graphic to be used to pinpoint location

Hope this helps a bit.

Thanks in advance

0 Kudos
ChristianBischof
Esri Contributor

Draw polyline | ArcGIS API for JavaScript 4.15 

Maybe this sample code could additionally help you achieve what you want.

<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <!--
  ArcGIS API for JavaScript, https://js.arcgis.com
  For more information about the intro-graphics sample, read the original sample description at developers.arcgis.com.
  https://developers.arcgis.com/javascript/latest/sample-code/intro-graphics/index.html
  -->
    <title>Intro to graphics - 4.15</title>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.15/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.15/"></script>

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }
    </style>

    <script>
      require(["esri/Map", "esri/views/MapView", "esri/Graphic"], function (
        Map,
        MapView,
        Graphic
      ) {
        var map = new Map({
          basemap: "hybrid",
        });

        var view = new MapView({
          center: [-80, 35],
          container: "viewDiv",
          map: map,
          zoom: 3,
        });

        view.on("click", function (evt) {

          // Create a graphic and add the geometry and symbol to it
          var graphic = new Graphic({
            geometry: {
              type: "point",
              latitude: evt.mapPoint.latitude,
              longitude: evt.mapPoint.longitude,
              spatialReference: view.spatialReference
            },
            symbol: {
              type: "simple-marker", // autocasts as new SimpleFillSymbol
              color: [226, 119, 40],
              outline: {
              // autocasts as new SimpleLineSymbol()
              color: [255, 255, 255],
              width: 2,
              },
            }
          });
          view.graphics.removeAll();
          view.graphics.add(graphic);
        });
      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
  </body>
</html>
0 Kudos
KenBuja
MVP Esteemed Contributor

You have a problem with the function arguments not matching the require modules. These have to be in the same order, moving "Graphic" to after "Locate"

require([
 "esri/Map",
 "esri/views/MapView",
 "esri/widgets/Search",
 "esri/layers/FeatureLayer",
 "esri/widgets/Locate",
 "esri/Graphic",
 "dojo/domReady!"
], function(Map, MapView, Search, FeatureLayer, Locate, Graphic) {
ChristianBischof
Esri Contributor

Is this what you're looking for?

<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <!--
  ArcGIS API for JavaScript, https://js.arcgis.com
  For more information about the intro-graphics sample, read the original sample description at developers.arcgis.com.
  https://developers.arcgis.com/javascript/latest/sample-code/intro-graphics/index.html
  -->
    <title>DevLabs - Search and Geocode</title>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.15/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.15/"></script>

    <style>
      html,
      body {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }

      #viewDiv {
        padding: 0;
        margin: 0;
        height: 80%;
        width: 60%;
      }

      #instruction {
        padding: 15px;
        background: white;
        color: black;
        border: 5px solid gold;
        font-family: sans-serif;
        font-size: 1.2em;
      }

      #instruction2 {
        width: 60%;
        margin-top: 4px;
      }
      #getLocBtn {
        float: left;
        margin-top: 4px;
      }
    </style>

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/Graphic",
        "esri/widgets/Search",
        "esri/tasks/Locator",
      ], function (Map, MapView, Graphic, Search, Locator) {
        var map = new Map({
          basemap: "topo",
        });

        var view = new MapView({
          container: "viewDiv",
          map: map,
          center: [-0.14718, 51.51161],
          zoom: 17,
        });

        var search = new Search({
          view: view,
        });
        //search.defaultSource.withinViewEnabled = false; // Limit search to visible map area only
        view.ui.add(search, "top-right"); // Add to the map
        // Add instruction to the map
        view.ui.add("instruction", "bottom-left");

        view.on("click", function (evt) {
          // Create a graphic and add the geometry and symbol to it
          var graphic = new Graphic({
            geometry: {
              type: "point",
              latitude: evt.mapPoint.latitude,
              longitude: evt.mapPoint.longitude,
              spatialReference: view.spatialReference,
            },
            symbol: {
              type: "simple-marker", // autocasts as new SimpleFillSymbol
              color: [255, 10, 10],
              outline: {
                // autocasts as new SimpleLineSymbol()
                color: [255, 255, 255],
                width: 2,
              },
            },
          });
          view.graphics.removeAll();
          view.graphics.add(graphic);

          search.search(evt.mapPoint);
          search.resultGraphicEnabled = false;
        });
      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
    <div id="instruction">
        Click on the map to retrieve coordinates and address
      </div>
  </body>
</html>
MatildaOtiede
New Contributor II

Thanks. This is what I was looking for.