I am plotting some text graphics on a graphics layer and now I need to give an option on the map to search for a specific text and navigate to that location and zoom in.
Can someone please guide me with the approach?
Here is the sample code where if I search for 560001, the map should be zoom in to that location.
<html><head><meta charset="utf-8"><meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no"><style>html,body,#viewDiv {padding: 0;margin: 0;height: 100%;width: 100%;}</style><script>require(["esri/WebMap","esri/views/MapView","esri/Graphic","esri/layers/GraphicsLayer","esri/symbols/TextSymbol"], function (WebMap, MapView, Graphic, GraphicsLayer, TextSymbol) {const webmap = new WebMap({portalItem: {id: "36f72c8a71b542399ca09e10c5aa55f4"}});const view = new MapView({container: "viewDiv",map: webmap,center: [-37.731338217717074, 175.22263172713014],zoom: 10});this.objectTypeList = [{ Location: '560001', latitude: -37.731338217717074, longitude: 175.22263172713014 },{ Location: '560002', latitude: -37.487705856583744, longitude: 175.09324140306873 },{ Location: '560003', latitude: -37.505917118655056, longitude: 175.12036900524583 },{ Location: '560005', latitude: -37.67287982024181, longitude: 175.23882277753953 },{ Location: '560005', latitude: -37.67310492511848, longitude: 175.23890380457217 }];var graphicsLayer = new GraphicsLayer();webmap.layers.add(graphicsLayer);this.objectTypeList.forEach(item => {var point = {type: "point",longitude: item.longitude,latitude: item.latitude};var textSymbol = new TextSymbol({color: "#BB0000",haloColor: "black",haloSize: "1px",text: `${item.Location}`,font: { size: 12, family: "Josefin Slab", weight: "bold" }});var pointGraphic = new Graphic({geometry: point,symbol: textSymbol});graphicsLayer.add(pointGraphic);});});</script></head><body><div id="viewDiv"></div></body></html>
Have you tried the Search Widget?
Hi Blake
Can I use Search Widget with GraphicsLayer? Can you please give me some hints on how it should be done in the code in my case?
Also is it possible to navigate to a location based on the lat, long, and zoom in? I have tried view.navTo() but that didn't work.
Thanks.
If you want to zoom to a feature by attribute (560001), the Search widget or Query() method should both work on a graphics layer. The source for the Search widget will be a LayerSearchSource, which notes that "Feature layers created from client-side graphics are not supported." If using Query, you'll also need to use goTo() to zoom the map. The goTo() method will also accept lat, long coordinates to zoom in.
Can you please suggest why zoom is working but not the center when I try view.goTo?
view.goTo({
center: [175.22263172713014, -37.731338217717074],
zoom: 15
});
You just need to find the selected (somehow) location in the graphics of GraphicLayer using the symbol text property.Link
Now, you are using geographic (lon, lat) to create the geometries but your map is in another spatial reference system. In that order to zoom to the geometries you will have to project them.
Take a look a the example I put for you, I use a simple select to choose the graphic, and I use a on client projection method, another option would be server side projection.
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.22/esri/themes/light/main.css">
<script src="https://js.arcgis.com/4.22/"></script>
<script>
require([
"esri/WebMap",
"esri/views/MapView",
"esri/Graphic",
"esri/layers/GraphicsLayer",
"esri/symbols/TextSymbol",
"esri/geometry/SpatialReference",
"esri/geometry/projection"
], function (WebMap, MapView, Graphic, GraphicsLayer, TextSymbol, SpatialReference, projection) {
const webmap = new WebMap({
portalItem: {
id: "36f72c8a71b542399ca09e10c5aa55f4"
}
});
const view = new MapView({
container: "viewDiv",
map: webmap,
center: [-37.731338217717074, 175.22263172713014],
zoom: 10
});
this.objectTypeList = [
{ Location: '560001', latitude: -37.731338217717074, longitude: 175.22263172713014 },
{ Location: '560002', latitude: -37.487705856583744, longitude: 175.09324140306873 },
{ Location: '560003', latitude: -37.505917118655056, longitude: 175.12036900524583 },
{ Location: '560004', latitude: -37.67287982024181, longitude: 175.23882277753953 },
{ Location: '560005', latitude: -37.67310492511848, longitude: 175.23890380457217 }
];
var graphicsLayer = new GraphicsLayer();
webmap.layers.add(graphicsLayer);
this.objectTypeList.forEach(item => {
var point = {
type: "point",
longitude: item.longitude,
latitude: item.latitude
};
var textSymbol = new TextSymbol({
color: "#BB0000",
haloColor: "black",
haloSize: "1px",
text: `${item.Location}`,
font: { size: 12, family: "Josefin Slab", weight: "bold" }
});
var pointGraphic = new Graphic({
geometry: point,
symbol: textSymbol
});
graphicsLayer.add(pointGraphic);
});
projection.load().then(function() {
const outSR = new SpatialReference({wkid: 2193});
const dic = {};
graphicsLayer.graphics.forEach(g => dic[g.symbol.text] = projection.project(g.geometry, outSR));
view.when(function(){
const locationZoomButton = document.getElementById("locationZoomButton");
locationZoomButton.addEventListener("click", function(){
const locationSelect = document.getElementById("locationSelect");
const locationText = locationSelect.value;
if (dic.hasOwnProperty(locationText)) {
view.goTo(dic[locationText]);
}
});
});
});
});
</script>
</head>
<body>
<div>
<select id="locationSelect">
<option value="560001">560001</option>
<option value="560002">560002</option>
<option value="560003">560003</option>
<option value="560004">560004</option>
<option value="560005">560005</option>
</select>
<button id="locationZoomButton"> Zoom </button>
</div>
<div id="viewDiv"></div>
</body>
</html>