version: ArcGIS for JavaScript 4.9
I have a custom web app hosted on my own web server, not hosted on ArcGIS Online. It does, however, load an ArcGIS Online-hosted basemap and several ArcGIS Online-hosted layers upon visiting the URL.
Is there any way I can load the map already zoomed to a specific feature within the map by passing URL parameters to affect the extent?
I have seen this functionality for apps developed and hosted by ArcGIS Online but have not found any info about custom externally-hosted apps.
EXAMPLE
let's say the URL to my app is 'myapp.com' and I have a feature in my app called 'Building A'. Is there some text string I can add to the URL to load the map already zoomed to Building A?
e.g. 'myapp.com/search=Building A' or something similar?
I have looked through these threads for info already:
How do I pass an address into my javascript API map using URL parameters?
Use URL parameters to modify maps—ArcGIS Online Help | ArcGIS
Solved! Go to Solution.
Parker,
Here is a working sample:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Intro to FeatureLayer - 4.10</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.10/esri/css/main.css">
<script src="https://js.arcgis.com/4.10/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/core/urlUtils",
"esri/tasks/support/Query"
],
function(
Map, MapView,
FeatureLayer,
urlUtils,
Query
) {
var map = new Map({
basemap: "hybrid"
});
var view = new MapView({
container: "viewDiv",
map: map,
extent: { // autocasts as new Extent()
xmin: -9177811,
ymin: 4247000,
xmax: -9176791,
ymax: 4247784,
spatialReference: 102100
}
});
/********************
* Add feature layer
********************/
// Carbon storage of trees in Warren Wilson College.
var featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Landscape_Trees/FeatureServer/0"
});
map.add(featureLayer);
view.when(function(){
params = urlUtils.urlToObject("https://myapp.com?Scode=COKO");
query = new Query();
query.where = "Spp_Code = '" + params.query.Scode + "'";
featureLayer.queryExtent(query).then(function(results){
setTimeout(function(){
view.goTo(results.extent).then(function(){
featureLayer.definitionExpression = query.where;
});
}, 2000);
});
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Parker,
Yes it is possible but you would have to code your own handler for those url parameters in your app. There is not out of the box in the JS API for this. You would use urlToObject method in the urlUtils class to get the url parameters then execute some query for buildingA and use the results extent to set the view.extent.
Thanks for the lead Robert. I made some progress but am still unable to get this working all the way.
- I was able to import urlUtils and Query.
- In the code below I have hardcoded a string representing a URL, but in my app, I will replace that string with 'window.location.href'
- I then created an empty Query object and set the where property of that Query object using my params object
- I console logged query.where and it was formatted like so: BuildingName = 'My Building'
- I am now getting an error 'cannot read property 'has' of undefined', which I'm assuming is either me being out of scope or an empty result somewhere.
Perhaps the query string is formatted improperly, which would return an empty result?
Any idea where I may be going wrong?
Here is my code
params = urlUtils.urlToObject("https://myapp.com?BuildingName=My Building");
query = new Query();
query.where = "BuildingName = '" + params.query.BuildingName + "'";
layer_to_query.queryExtent(query).then(function(results){
view.goTo(results.extent);
});
Parker,
Here is a working sample:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Intro to FeatureLayer - 4.10</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.10/esri/css/main.css">
<script src="https://js.arcgis.com/4.10/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/core/urlUtils",
"esri/tasks/support/Query"
],
function(
Map, MapView,
FeatureLayer,
urlUtils,
Query
) {
var map = new Map({
basemap: "hybrid"
});
var view = new MapView({
container: "viewDiv",
map: map,
extent: { // autocasts as new Extent()
xmin: -9177811,
ymin: 4247000,
xmax: -9176791,
ymax: 4247784,
spatialReference: 102100
}
});
/********************
* Add feature layer
********************/
// Carbon storage of trees in Warren Wilson College.
var featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Landscape_Trees/FeatureServer/0"
});
map.add(featureLayer);
view.when(function(){
params = urlUtils.urlToObject("https://myapp.com?Scode=COKO");
query = new Query();
query.where = "Spp_Code = '" + params.query.Scode + "'";
featureLayer.queryExtent(query).then(function(results){
setTimeout(function(){
view.goTo(results.extent).then(function(){
featureLayer.definitionExpression = query.where;
});
}, 2000);
});
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Thanks for that. I'll try to adapt my script accordingly.
Don't forget to mark this question as answered by clicking on the "Mark Correct" link on the reply that answered your question.
Thanks to Robert Scheitlin, GISP's lead and some sample code, I was able to implement the desired functionality...on a desktop PC.
When testing on my admittedly ancient mobile device, I expected everything to work as smoothly as the desktop experience. However, on mobile load, the viewDiv containing my map had disappeared.
Is there some reason this would work on desktop devices but not mobile? Has anyone successfully implemented this functionality on a desktop but experienced similar issues on a mobile device? (code below)
FYI the mobile device was connected to the web via the same WiFi as the desktop device.
view.when(function(){
u = document.URL
params = urlUtils.urlToObject(u);
query = new Query();
query.where = "BUILDINGNAME = '" + params.query.building + "'";
query.returnGeometry = true;
buildings_lyr.queryExtent(query).then(function(results){
setTimeout(function(){
view.goTo(results.extent).then(function(){
var newZoom = view.zoom - 3
view.zoom = newZoom
})
}, 2000);
});
});