Drawing Graphic at street layer/level only

3484
9
08-03-2014 12:15 AM
FrankyFergus
New Contributor

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

0 Kudos
9 Replies
OwenEarley
Occasional Contributor III

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

Spatial XP

FrankyFergus
New Contributor

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

0 Kudos
RiyasDeen
Occasional Contributor III

Ssuspect your base map has less than 17 cache level. Change streetLvlZoom variable to say 12 or last level ID.

0 Kudos
FrankyFergus
New Contributor

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?

0 Kudos
RiyasDeen
Occasional Contributor III

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);

            } 

        }); 

RiyasDeen
Occasional Contributor III

plz check the case for StreetLevelscale, i have made  a mistake in case.

FrankyFergus
New Contributor

Great. Thanks Riyas .

0 Kudos
OwenEarley
Occasional Contributor III

Hi Franky,

Note that map levels are predefined scales at which tiled images are created. For example:

LevelScale
116,000,000

2

8,000,000
34,000,000
42,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

FrankyFergus
New Contributor

Great. Thanks a lot Owen

0 Kudos