Hey I'm simply looking to load a map and pan/zoom to a feature.
Here is the actual page. https://data.orangeville.ca/Apps/CrossingGuards/index.html?objectid=1
I'm looking for help to get the inline map to 'goto' or pan and zoom a feature based on object id
I'm getting the objectid from a url parameter using
var getUrlParameter = function getUrlParameter(sParam) {
var sPageURL = decodeURIComponent(window.location.search.substring(1)),
sURLVariables = sPageURL.split('&'),
sParameterName,
i;
for (i = 0; i < sURLVariables.length; i++) {
sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] === sParam) {
return sParameterName[1] === undefined ? true : sParameterName[1];
}
}
};
and calling it using >>> getUrlParameter('objectid')
also the map has 4 layers, the one to search is layer 3 of 4 called 'Crossing Guards VIEW'
here is my codepen code just for the map for testing, with the api key removed...
<!--
To run this demo, you need to replace 'YOUR_API_KEY' with an API key from the ArcGIS Developer dashboard.
Sign up for a free account and get an API key.
https://developers.arcgis.com/documentation/mapping-apis-and-services/get-started/
--><html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>ArcGIS API for JavaScript Tutorials: Display a map</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.21/esri/themes/light/main.css">
<script src="https://js.arcgis.com/4.21/"></script>
<script>
require(["esri/config","esri/WebMap", "esri/views/MapView","esri/widgets/ScaleBar","esri/widgets/Legend"], function (esriConfig,WebMap, MapView, ScaleBar, Legend) {
esriConfig.apiKey = "API_KEY_HERE";
const webmap = new WebMap({
portalItem: {
id: "4170f5e65bd8409896a906264e4c2c87"
}
});
const view = new MapView({
map: webmap,
container: "viewDiv" // Div element
});
const scalebar = new ScaleBar({
view: view
});
view.ui.add(scalebar, "bottom-left");
var parcelExtent = response.features[0].geometry.extent.clone().expand(0.5);
view.goTo(parcelExtent);
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
thanks for any assistance
Solved! Go to Solution.
Why don't you use the map and additionally add the layer? After zooming in or any other action just remove the layer again.
Awesome that was enough advice to get me there... here's what worked for me... it adds the layer to the map, zooms to it, then removes it... which also creates a better user experience because it doesn't snap back the map everytime you try to pan or zoom away...
require(["esri/config","esri/Map","esri/WebMap", "esri/views/MapView","esri/layers/FeatureLayer","esri/widgets/ScaleBar","esri/widgets/Legend"], function (esriConfig,Map,WebMap, MapView, FeatureLayer, ScaleBar, Legend) {
esriConfig.apiKey = "YOUR_KEY_HERE";
const webmap = new WebMap({
portalItem: {
id: "4170f5e65bd8409896a906264e4c2c87"
}
});
const view = new MapView({
map: webmap,
container: "viewDiv" // Div element
});
const layer = new FeatureLayer({
// URL to the service
url: "https://services3.arcgis.com/pCmV4YWmyIH9CmGq/ArcGIS/rest/services/Crossing_Guards_VIEW/FeatureServer/0",
definitionExpression: "OBJECTID = " + getUrlParameter('objectid')
});
view.map.add(layer);
const scalebar = new ScaleBar({
view: view
});
view.ui.add(scalebar, "bottom-left");
view.whenLayerView(layer).then(function(layerView){
layerView.watch("updating", function(val){
// wait for the layer view to finish updating
if(!val){
layerView.queryExtent().then(function(response){
// go to the extent of all the graphics in the layer view
view.goTo({target:response.extent, zoom: 17});
view.map.remove(layer);
});
}
});
});
});
Hey,
1. Add the Layer to map while using a definitionExpression
2. Wait for the LayerView and use the queryExtent Function
view.whenLayerView(layer).then(function(layerView) {
layerView.watch("updating", function(val) {
if (!val) {
layerView.queryExtent().then(function(response) {
view.goTo(response.extent);
});
}
});
});
So, I had this solution previously, however there is then only the one layer on the map...
The reason I'm trying to add the whole map is because I want all the layers and stylings from it. Then zoom to the one feature in the specific layer using the url parameter value.
Any suggestions for this setup?
Otherwise, I can just add the other layers to the map as well, but then styling them also just seems like way more effort than if I would just query and zoom on an existing layer in the map.
Why don't you use the map and additionally add the layer? After zooming in or any other action just remove the layer again.
Awesome that was enough advice to get me there... here's what worked for me... it adds the layer to the map, zooms to it, then removes it... which also creates a better user experience because it doesn't snap back the map everytime you try to pan or zoom away...
require(["esri/config","esri/Map","esri/WebMap", "esri/views/MapView","esri/layers/FeatureLayer","esri/widgets/ScaleBar","esri/widgets/Legend"], function (esriConfig,Map,WebMap, MapView, FeatureLayer, ScaleBar, Legend) {
esriConfig.apiKey = "YOUR_KEY_HERE";
const webmap = new WebMap({
portalItem: {
id: "4170f5e65bd8409896a906264e4c2c87"
}
});
const view = new MapView({
map: webmap,
container: "viewDiv" // Div element
});
const layer = new FeatureLayer({
// URL to the service
url: "https://services3.arcgis.com/pCmV4YWmyIH9CmGq/ArcGIS/rest/services/Crossing_Guards_VIEW/FeatureServer/0",
definitionExpression: "OBJECTID = " + getUrlParameter('objectid')
});
view.map.add(layer);
const scalebar = new ScaleBar({
view: view
});
view.ui.add(scalebar, "bottom-left");
view.whenLayerView(layer).then(function(layerView){
layerView.watch("updating", function(val){
// wait for the layer view to finish updating
if(!val){
layerView.queryExtent().then(function(response){
// go to the extent of all the graphics in the layer view
view.goTo({target:response.extent, zoom: 17});
view.map.remove(layer);
});
}
});
});
});
Is your response geometry a point? The goTo method won't zoom to its extent, since a point doesn't have an extent. You'll have to set the scale for the zoom.
view.goTo({
target: geometry,
scale: yourScale,
});