Hello,
I am new to ArcGIS JavaScript API and would like some help. I have a scenario where a user has to draw a graphic, mainly a polyline and some points on a map. To avoid confusion I want to limit the user to zoom in to street level prior to start drawing.
What I am trying to achieve here is when the user clicks on the locality he/she wants to draw on, on click event the map zooms in to street layer/level. I have been looking around but can't find a way to do it.
I'll appreciate any kind of help.
Thanks
Frank
Hi Franky,
Check out this example that I created (based on an ESRI sample): Zoom-in Draw
The key parts to do what you are after are:
1. Set the minimum zoom level to enable the draw buttons:
// Set the zoom level to enable draw buttons
var streetLvlZoom = 17;
2. Create a map click event to zoom in to a locality:
// Zoom in to local area
map.on("click", function(e){
if (map.getLevel() < streetLvlZoom){
map.centerAndZoom(e.mapPoint, streetLvlZoom)
}
});
3. When the map zoom level changes check if you should enable the draw buttons:
// Check if draw buttons should be enabled when zoom level changes
map.on("zoom-end", function(e){
var drawBtns = document.getElementById("draw-btns").children;
for(var i = 0; i < drawBtns.length; i++) {
drawBtns.disabled = (e.level < streetLvlZoom);
}
});
Hope this helps to outline the process.
Owen
Hi Owen,
Thanks for your help.
I modified a bit the example above by including an ArcGISDynamicMapServiceLayer and instead of zooming in it is doing the opposite.
Is there something else I should be including or enabling?
Here is what I did:
var streetLvlZoom = 17;
require([
"esri/map", "esri/toolbars/draw",
"esri/symbols/SimpleMarkerSymbol",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/CartographicLineSymbol",
"esri/graphic",
"esri/Color",
"dojo/dom",
"dojo/on",
"dojo/domReady!"
], function(
Map, Draw,
SimpleMarkerSymbol, ArcGISDynamicMapServiceLayer, SimpleLineSymbol,
SimpleFillSymbol, CartographicLineSymbol,
Graphic,
Color, dom, on
) {
map = new Map("mapDiv", {
zoom: 12
});
// Base map
var basemap = new ArcGISDynamicMapServiceLayer("http://myserver/Basemap/map/");
basemap.setVisibleLayers([0, 1, 2, 3, 4, 5, 6, 7]);
map.addLayer(basemap);
map.on("load", initToolbar);
// Zoom in to local area
map.on("click", function(e){
if (map.getLevel() < streetLvlZoom){
map.centerAndZoom(e.mapPoint, streetLvlZoom)
}
});
The rest wasn't modified.
Frank
Ssuspect your base map has less than 17 cache level. Change streetLvlZoom variable to say 12 or last level ID.
Thanks Riyas,
Adjusted the streetLvlZoom but still going outwards. About the last level ID, where can I modify it or is it a server attribute?
Sorry din't notice that you are trying to add a dynamic map service to your map, in this case you can't use scale level. When using dynamic map service centerAndZoom's second variable will be a zoom factor.
Try below code:
var StreetLevelScale = 2500;
require([
"esri/map", "esri/toolbars/draw",
"esri/symbols/SimpleMarkerSymbol",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/CartographicLineSymbol",
"esri/graphic",
"esri/Color",
"dojo/dom",
"dojo/on",
"dojo/domReady!"
], function(
Map, Draw,
SimpleMarkerSymbol, ArcGISDynamicMapServiceLayer, SimpleLineSymbol,
SimpleFillSymbol, CartographicLineSymbol,
Graphic,
Color, dom, on
) {
map = new Map("mapDiv", {
zoom: 12
});
// Base map
var basemap = new ArcGISDynamicMapServiceLayer("http://myserver/Basemap/map/");
basemap.setVisibleLayers([0, 1, 2, 3, 4, 5, 6, 7]);
map.addLayer(basemap);
map.on("load", initToolbar);
// Zoom in to local area
map.on("click", function(e){
if (map.getScale() > StreetLevelscale){
map.centerAt(e.mapPoint);
map.setScale(StreetLevelscale);
}
});
plz check the case for StreetLevelscale, i have made a mistake in case.
Great. Thanks Riyas .
Hi Franky,
Note that map levels are predefined scales at which tiled images are created. For example:
Level | Scale |
---|---|
1 | 16,000,000 |
2 | 8,000,000 |
3 | 4,000,000 |
4 | 2,000,000 |
etc |
This is important as the map level value increases as you zoom in. However, the map scale value decreases as you zoom in.
To use dynamic map layers and map scale you will need to change the streetLvlZoom variable to a scale value and also update the map click and zoom-end handler functions.
var streetLvlZoom = 5000;
Also, change the way you create the map:
map = new Map("mapDiv", {
center: [151.15,-33.86],
scale:250000 // Use scale when creating the map
});
Modify the map click handler to test the map scale and not the zoom level:
// Zoom in to local area
map.on("click", function(e){
// Notice that this is now a 'greater than' test
if (map.getScale() > streetLvlZoom){
map.centerAt(e.mapPoint);
map.setScale(streetLvlZoom);
}
});
Modify the map zoom-end handler to test the map scale and not the zoom level:
// Check if draw buttons should be enabled when zoom level changes
map.on("zoom-end", function(e){
var scale = Math.floor(map.getScale())
var drawBtns = document.getElementById("draw-btns").children;
for(var i = 0; i < drawBtns.length; i++) {
// disable btns if map scale > minimum required scale
drawBtns.disabled = (scale > streetLvlZoom);
}
});
As mentioned previously the map level value increases as you zoom in. However, the map scale value decreases as you zoom in. This means that when checking to disable buttons - instead of checking if the zoom level is less than the streetLvlZoom, you need to check if the map scale is greater than the streetLvlZoom.
Also, note the use of the floor function. I have noticed that when setting the map scale to 1:5000 and then checking map.getScale() you end up with a value like 1:5000:000000000704. This ends up messing with the scale > streetLvlZoom test and the buttons remain disabled.
This should fix the problem where the zoom is going in the opposite direction.
This modified example should work even if you also use a tiled base map with your dynamic map service layer.
Example using tiled map service basemap.
Example using dynamic map service basemap.
Owen
Great. Thanks a lot Owen