Identifier les couches de plusieurs instances d'ArcGIS Server à l'aide de l'API ArcGIS pour JavaScript 2?

14

Cela s'applique à ArcGIS Server 9.3 avec l'API JavaScript 2.4.

Mon objectif est de cliquer sur la carte et d'exécuter la tâche Identifier sur toutes les couches dynamiques visibles.

IdentifyTask nécessite une URL vers le point de terminaison REST, IdentifyParameters spécifiant sur quels ID de couche l'opération d'identification doit être effectuée.

Il semble que l'outil Identifier s'attende à ce que toutes les couches soient accessibles à partir du même point de terminaison REST (c'est-à-dire le même ArcGIS Server).

Dans mon cas, les couches sont servies à partir de plusieurs instances d'ArcGIS Server - comment l'outil Identifier peut-il prendre en charge cela? Par exemple, si les couches Bâtiments et Parcelles de cette carte provenaient de serveurs ArcGIS distincts.

(Ceci est lié à ma question précédente , mais je me rends compte maintenant que je dois d'abord répondre à cette question)

Stephen Lead
la source
Y a-t-il eu des mises à jour de ces concepts? J'ai utilisé l'échantillon de violon référencé ci-dessus. Merci
phase
@phase pour autant que je sache, les concepts sont toujours les mêmes en utilisant ArcGIS Server 10 et JS API 2.6, en supposant que c'est ce que vous voulez dire
Stephen Lead

Réponses:

11

Tout d'abord, voici un exemple d'API JavaScript simplifié pour montrer le concept d'utilisation de DeferredList pour traiter plusieurs tâches d'identification:

//Assume that map is your map object
var idTask1, idTask2, idParams = new esri.tasks.IdentifyParameters();
var url1 = "<server1 url>", var url2 = "<server2 url>";
dojo.connect(map, "onLoad", initIdentifies);
function initIdentifies(map) { //map.onLoad passes in the map object
    idTask1 = new esri.tasks.IdentifyTask(url1);
    idTask2 = new esri.tasks.IdentifyTask(url2);
    //A few sample constant parameters. Set more or less as you need
    idParams.tolerance = 12;
    idParams.returnGeometry = true;
    idParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_ALL;
    dojo.connect(map, "onClick", runIdentifies);
}
function runIdentifies(evt) {
    var defTask1 = new dojo.Deferred(), defTask2 = new dojo.Deferred;
    var dlTasks = new dojo.DeferredList([defTask1, defTask2]);
    dlTasks.then(showResults); //defTasks will fire after defTask1 and defTask2 have completed
    //These parameters change with each request
    idParams.width = map.width;
    idParams.height = map.height;
    idParams.geometry = evt.mapPoint;
    idParams.mapExtent = map.extent;
    try {
        idTask1.execute(idParams, defTask1.callback, defTask1.errback); //Pass the response into the callback on defTask1
    } catch (e) {
        console.log("Error caught");
        console.log(e);
        defTask1.errback(e); //If you get an error, execute the errback
    }
    try {
        idTask2.execute(idParams, defTask2.callback, defTask2.errback); //Pass the response into the callback on defTask2
    } catch (e) {
        console.log("Error caught");
        console.log(e);
        defTask2.errback(e); //If you get an error, execute the errback
    }
}
function showResults(r) {
    //The format of 'r' is [[Boolean task 1 success, [task 1 results]],[Boolean task 2 success, [task 2 results]]]
    //using the array 'r', build and show your infoWindow as normal
}

Ensuite, voici un exemple dans jsFiddle qui, je pense, fait ce que vous voulez, fonctionne en utilisant toutes les couches visibles dans toutes les couches de carte dynamique visibles de la carte.

http://jsfiddle.net/blordcastillo/mULcz/

Toutes les fautes de frappe sont corrigées maintenant :)

L'idée de base est que chaque fois que la carte est cliquée ou que la visibilité est basculée, l'identifiant est réexécuté. Lorsque l'identification est exécutée, le nombre de tâches d'identité déclenchées dépend du nombre de couches visibles et attend que toutes les couches reviennent pour afficher ses résultats.

blord-castillo
la source
cela a beaucoup de sens - merci beaucoup d'avoir posté l'exemple de code
Stephen Lead
2
Il y a quelques petites fautes de frappe dans votre code - ce qui est en fait plus impressionnant car cela implique que vous l'avez tapé de la mémoire et n'avez même pas eu besoin de l'exécuter. Chapeau!
Stephen Lead
Oui, je viens de taper ça du haut de ma tête :) Faites-moi savoir ce que sont les fautes de frappe mineures et je les corrigerai.
blord-castillo
Changé en une version de travail dans jsFiddle. La version n'est pas parfaitement efficace; Idéalement, je voudrais enregistrer les résultats de ma requête et refaire la section showResults lorsque la visibilité est basculée par le point d'identification n'est pas modifiée. Mais, je pense que cela montre bien le concept de la façon de lier le basculement de la visibilité avec les tâches d'identification exécutées. En outre, vous souhaitez stocker un modèle avec chaque couche afin de pouvoir simplement retirer les modèles des couches, plutôt que d'utiliser la logique à l'intérieur des fonctions javascript comme je l'ai fait.
blord-castillo
4

La tâche d'identification ne peut référencer qu'un seul service de carte, vous devrez donc:

  • Mettez toutes les couches sur lesquelles vous souhaitez exécuter Identity dans un seul service de carte
  • Exécutez plusieurs IdentifyTasks par clic sur la carte

Je suis tombé sur des situations similaires avec une application où je voulais être en mesure d'identifier sur un service de carte DEM et sur un service de carte de résultat d'élévation du niveau de la mer à partir d'une tâche de géotraitement. J'ai choisi d'exécuter deux IdentifyTasks. La seule chose que vous devez vraiment ajouter est de savoir quand les deux tâches sont terminées.

Le flux de base est (c'était en utilisant Silverlight / C #)

  • configuration des variables booléennes pour DEM et SLR identifierTaskcomplete
  • Exécutez IdentifyTask pour DEM
  • définissez bool pour DEMidentifyTaskComplete sur false
  • Exécutez IdentifyTask pour SLR (en utilisant les mêmes paramètres généraux que pour DEM)
  • définissez bool pour SLRidentifyTaskComplete sur false
  • Dans l'écouteur d'événements DEMIdentifyTask_ExecuteCompleted, j'ai défini DEMidentifyTaskcomplete sur true, puis je vérifie si SLRidentifyTaskcomplete est vrai (configurez l'opposé pour SLRIdentifyTask_ExecuteCompleted)
  • Quelle que soit la tâche terminée en dernier, les deux booléens seront vrais et appellera IdentifyTasksComplete qui analysera les deux résultats dans un objet graphique personnalisé que j'ajouterai à la carte, puis définissez slr et demidentiftytaskcomplete sur false
wwnick
la source
merci - c'est ce que je craignais, mais il est bon d'entendre que vous l'avez trouvé réalisable. Si ce site est disponible, pouvez-vous me faire savoir l'URL?
Stephen Lead
Ce n'est pas public, et c'est d'ailleurs dans Silverlight. Bonne chance!
wwnick
+1 pour plusieurs tâches d'identification. Pour l'API JavaScript, vous pouvez les gérer avec dojo.DeferredList (s'applique également à plusieurs queryTasks).
Derek Swingley