2

My site is built on ArcGIS Server 10 with the JavaScript API 2.3, and uses Bing Maps as the background mapping. Although the site is aimed at NSW, Australia we allow the user to zoom anywhere in the world, at any of the supported scales (ie, the tiling scheme as specified in the ArcGIS Help File.)

Bing Maps road/satellite datasets are available at varying scale ranges, with populated areas supporting larger scales than empty rural areas. When zooming somewhere with no map/satellite data, a "broken camera" icon is shown. We'd like to avoid showing this ugly icon.

How can we restrict the maximum zoom scale where the map/satellite is not available, but allow full zoom-in where it is available?

Google Maps does this quite well - as you move around the world you can see the Zoom Slider expand/contract depending on what datasets are available at that location. They presumably have metadata showing the presence/absence of data, so we seek emulate this when using Bing Maps, with no access to the metadata.

  • Use the Interactive SDK as in the previous post - gis.stackexchange.com/questions/11285/… – Mapperz Jun 22 '11 at 14:05
  • Would that require rewriting my entire app in the Bing Maps SDK? If so, it's not really an option since this enhancement is a tiny "nice to have" feature – Stephen Lead Jun 22 '11 at 23:08
  • Did you ever find a solution to this problem? – Ely Fialkoff May 1 at 14:43
  • @ElyFialkoff sorry, nope I never did solve this. These days I use the ArcGIS Server default basemaps, which seem to work better than Bing basemaps – Stephen Lead May 2 at 1:01
  • 1
    @StephenLead I am pretty sure I came up with a solution I found somewhere else; for anyone else reading - I made a json request to the metadata, then looked at the start and end date, if these were null I assumed that the image is broken and request another image but with lower zoom values. Setting this up will be dependent on your language and set up (so I am not including my code). – Ely Fialkoff May 2 at 13:26
1

Bing Maps is a tiled map, so has levels of detail when zoomed in or out. I would fire a conditional statement on every extent change. Something like: event fired: Extent Change Conditional: if map style = aerial and (get level < desired): set level back at desired...

  • Josh, this also looks promising- but how do I determine the value of "desired"? This will vary across the map – Stephen Lead Jun 23 '11 at 1:16
1

Before zooming to a location, perhaps get the image metadata to see what the finest resolution is available there.

Determine the availability of imagery at a location at a specified zoom level

Since the response contains zoomMin and zoomMax, I suppose you could make the call just once at a low res zoom level and use the values from that, otherwise it seems like you might need to make multiple calls.

  • Kirk, this looks promising. A problem is that the returned ImageURL parameter may be valid, but show the "broken camera" icon I'm trying to avoid (eg ecn.t3.tiles.virtualearth.net/tiles/…{culture}). I can't see how to "Determine the availability of imagery at a location at a specified zoom level" since the camera icon is technically "available" – Stephen Lead Jun 23 '11 at 1:15
  • Wow, that sure seems like a poor design decision. Maybe if you convert the broken camera image to bytes then sum up the bytes you can know when you're zoomed too close. – Kirk Kuykendall Jun 23 '11 at 13:33
1
function getMapServerMetadata(Url) {
    var metadata = "";
    esri.request({
        url: Url + "?f=json",
        handleAs: "json",
        callbackParamName: "callback",
        load: function (response, io) {
            metadata += "Map Name: " + response.mapName;
            metadata += "\n\nCurrent Version: " + response.currentVersion;
            metadata += "\n\nService Description: " + response.serviceDescription;
            metadata += "\n\nCopyright: " + response.copyrightText;
            metadata += "\n\nNumber of Layers: " + response.layers.length;
            metadata += "\n\nNumber of Tables: " + response.tables.length;
            metadata += "\n\nSpatial Reference: " + response.spatialReference.wkid;
            alert(metadata);
        },
        error: function (error) {
            alert(error.message);
        }
    });
}

// Available json objects
//        currentVersion
//        serviceDescription
//        mapName
//        description
//        copyrightText
//        layers
//        tables
//        spatialReference
//        singleFusedMapCache
//        tileInfo
//        initialExtent
//        fullExtent
//        units
//        supportedImageFormatTypes
//        documentInfo
//        capabilities
//        _ssl

e.g. try using the above code with a regular basemap MapServer url from ESRI like: http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer

you can also use this on sublayers as well - to find out what metadata is there just use the base url and add ?f=json to have a json representation returned and iterate through the field names.

  • Hi Loran, welcome to GIS.se :) Please add a sentence or two above the code block describing it's purpose and what it does. Many readers won't be able to understand this with cursory review. (I'd also consider putting the list of json objects into columns so the code block doesn't take up as much screen real estate.) – matt wilkie Jan 25 '13 at 21:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.