Select to view content in your preferred language

Identify Info Window/Tabs with 14 layers

2192
15
09-05-2012 03:12 PM
DorotheaKnigge
Deactivated User
Hi,

My application is based on jsapi version3.0. It features a GIS Server service called "All_Services2012" which has 14 layers. An 'on-click' event identifies the 14 layers and displays them in an info window with tabs. The problem is that it takes between 35-45 seconds for the info window to display.  I'm afraid that the client will not want to wait that long for the information to come up.
Is it possible to add an "hour glass" or somthing to show the process is working?  Better yet, what can I do to speed up the info window display?

I was wondering if maybe the duplication of the variable declaration
(var i=0, il=layerResults.features.length; i<il; i++)
in each 'case'  was  part of the problem. If so, how would I structure the code? 

Would it be better to have the client turn on the layers he would like to identify?

I would very much appreciate someone looking at the attached code.

Many thanks,

Dorothea

The identify portion  is based on this sample:
http://help.arcgis.com/en/webapi/javascript/arcgis/demos/find/find_drilldown.html
0 Kudos
15 Replies
GeorgeSimpson
Regular Contributor
Dojo has a Progress Bar that is pretty simple to use.  You could kick it off when the user clicks the map and then hide it during the callback from the service.

I've had a similar issue in the past.  I ended up issuing an Identify task for the active tab.  When the user switched tabs, I would send another request for the layer that corresponded to the newly active tab.
0 Kudos
derekswingley1
Deactivated User

Would it be better to have the client turn on the layers he would like to identify?


Absolutely, yes. The performance issue you're seeing is likely caused by one or both of the following: 

  1. the server querying 14 layers for features

  2. sending features from 14 layers across the network


It's likely a combination of both. The fastest way to improve performance is to do less stuff.

Have you looked at how much data is returned to the client per identify operation? You can see this info in the chrome dev tools network tab or in firefox/firebug's network tab. Also, showing a client features from 14 different layers is a bad idea from a user experience point of view...navigating 14 tabs to sort through information would be painful, IMO.

Also, in this case, optimizing your JavaScript loop(s) is premature.
0 Kudos
derekswingley1
Deactivated User

I've had a similar issue in the past.  I ended up issuing an Identify task for the active tab.  When the user switched tabs, I would send another request for the layer that corresponded to the newly active tab.


Also a good idea! But an info window with 14 tabs makes me cringe.
0 Kudos
AdrianMarsden
Honored Contributor
Hi

You may be interested in the code I just finished - basically doing away with tabs and re-creating the old ArcIMS html viewer look - see screen shot


[ATTACH=CONFIG]17513[/ATTACH]

My code does away with any hard coding in the script.  It takes ALL exposed fields and displays them (although not system fields like shape, ID etc), using their aliases, as defined in the MXD.  Also, it looks at the sublayer description to see if you want a specific field to act as contents in a hyperlink - so adding "http://www.eastdevon.gov.uk/my_neighbourhood?uprn=£UPRN£" in to the description will substitute the value of the UPRN filed for the string £UPRN£ (£ chosen as a delimiter as it is never used in javascript)

Reply here if you want the code - still a bit rough around the edges.

Also, unless you really NEED the geometry, you can speed things up with returnGeometry = false or by simplifying what is returned by increasing the maxAllowableOffset (see http://help.arcgis.com/en/webapi/javascript/arcgis/help/jsapi_start.htm#jsapi/identifyparameters.htm).

Cheers

ACM
0 Kudos
DorotheaKnigge
Deactivated User
Thank you all for your responses, they are appreciated.

George, I like the idea of having a Progress Bar. 
Is there a sample on how to incorporate that into an identify event?   It would be great whether one had two layers or 14!  (I don't mean to make you cringe, Derek).  Deep down I knew I was overtaxing the services and network by requesting that amount of data.  I guess I just needed to hear it from a pro. I'll also take your tips for posting code or html samples to heart.

George, I also like the idea of issuing an Identify task for the active tab or layer.  Would you be willing to share code on how you solved your issue with identify?

Because I need to quickly replace out ArcIMS viewers I am interested in your code Adrian.  I would like to see how you achieved that old ArcIMS viewer look without IMS. 

At this point I do need the geometry so I'll have to follow through on some of the above options.



Dorothea
0 Kudos
GeorgeSimpson
Regular Contributor
Here's some code I used to create a progress bar for querying multiple layers.  This code is old, but should give you an idea.  When calling show(numParts), numParts is the number of layers.  This will divide the progress bar into parts that will show each when each stage is complete.  When a search is done on a layer, you can call update() which will change the progress bar to show how much of the operation is complete

var ProgressBar = function() {

    var _id;
    var _bar = dijit.byId("progressBar");
    var _numParts;
    var _progress;

    var _show = function(numParts) {
        if (numParts) {
            _bar.update({ indeterminate: false, maximum: numParts, progress: 0 });
            _progress = 0;
            _numParts = numParts;
        } else {
            _bar.update({ indeterminate: true });
            _progress = 0;
            _numParts = 0;
        }
        
        dojo.style("progressBarContainer", "display", "block");
        dojo.style("waitingDiv", "display", "block");
        centerElement(dojo.byId("divMapTabs"), dojo.byId("progressBarContainer"));
    };

    var _hide = function() {
        dojo.style("progressBarContainer", "display", "none");
        dojo.style("waitingDiv", "display", "none");
    };

    var _update = function() {
        _progress++;
        _bar.update({ progress: (_progress) });
        if (_progress >= _numParts) {
            _hide();
        }
    };

    return {
        show: function(num) {
            _show(num);
        },
        update: function() {
            _update();
        },
        hide: function() {
            _hide();
        }
    };

};

0 Kudos
GeorgeSimpson
Regular Contributor
I can't put together the code for the tabs since my code is so spread out.  You'll have to store the geometry that you used for the identify, and have an event for when a tab is selected that will fire a new identify task.  You'll also have to have a way for each tab to know which layer it corresponds to.  I actually used a dropdown instead of tabs when I did this and each value in the dropdown actually pointed to a collection of layers.  For instance, one value was "Historic Properties", but actually represented 3 layers (points,lines,polys).  That allowed me to have fewer options in the dropdown and provided information to the user that was grouped logically.


The general idea for you is something like:


var geom; //store the shape used for the identify task
var map; //the map
var tabs;//collection of tabs that each corresponds to a layer

//when tab is selected
//create identify task for corresponding layer using geom
//display results

0 Kudos
GeorgeSimpson
Regular Contributor
Here's a link to the public version (limited data) of the actual application.  You'll see how I handled the Identify and the Progress Bar. 

https://fortress.wa.gov/dahp/wisaard/
0 Kudos
AdrianMarsden
Honored Contributor
Dorothea

Here's my code.  Hopefully I've not missed anything from it.  Like you I will be having many layers.  Our current ArcIMS internal system has about 50 feature layers and about 12 raster layers.  Obviously not all on at once, but adding a layer in ArcIMS is a task, so I wanted to simplify it for my replacement.

If you require the feature I've added to use the MXD layer description to power a hyperlink, then you need to add this to your init function

    dojo.connect(dynamicMapServiceLayer, "onLoad", function () {        var content = ""
        //return the layer descriptions into an array - we use this later for the info dialog to generate hyperlinks
        dojo.forEach(dynamicMapServiceLayer.layerInfos, function (layer) {
            var restAPIServicePage = {
                url: mapservice2 + "/" + layer.id + "?f=json",
                callbackParamName: "callback",
                load: function (data) {
                    LayerDescriptions[layer.id] = data.description;
                }
            };
            dojo.io.script.get(restAPIServicePage);
        })

    });


I can't claim credit for that - see this post on the old forums.

You'll also need a few "var"s at the start of your code

var LayerDescriptions = []

(maybe more, but you'll need to work them out)

Then reference the attached file (renamed with .js  extension)

If you want to use the hyperlink feature then add, to your description a valid, full URL, including parameter, but surround where you  want the value of a field with the field alias (see earlier post for example)

Hopefully that'll all work - it is still a bit rough - as it stands it will fail if one layer name is a substring of another "So if you have a layer called "Wards" and another "County Wards" it will get confused,but the bit where it checks if the result is in a new layer or not can easily be re-written to use layer ID.

The one other suggestion to improving return speed is to look at your data.  Is it all in an SDE?  If any shapefiles then have they got good spatial indexes?  Do you have any very large polygons that get returned a lot? I had this issue on one of my maps, one polygon covering most of our district.  Returning the geometry of this took about the time you have got.  So for just that one feature I created a duplicate polygon with simplified features (if you haven't got ArcINFO license, you haven't got this feature , but QGIS can do it for free) - this layer was added to a different service, which was used purely for the ID task.  A bit of a bodge but worked.

Have fun

ACM

PS Just looked at the file - the test and create popup function are not needed, and looking at my screen shot I realize I haven't got the code working that alternates the row format - but I'm sure that that is a quick fix, moving my row counter increment. - I'll add any new version, plus my CSS sometime later, when I've got it working
0 Kudos