Comment naviguer les points de terminaison REST et récupérer les informations de champ par programme

9

J'ajoute un service de carte dynamique à une carte d'API JavaScript ArcGIS Server, et je dois récupérer chaque couche de composant et ses champs, afin de pouvoir exécuter une requête.

Voir l'exemple de répertoire de services ArcGIS Server à http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/HomelandSecurity/operations/MapServer

Si vous ouvrez cette URL dans un navigateur, vous pouvez voir la liste des couches disponibles (0,1,2) et les champs de chaque couche .

Comment récupérer la liste des champs par programmation, au sein d'une fonction JavaScript? L'extrait de code ci-dessous montre comment récupérer les points de terminaison de la couche, mais je ne vois pas comment accéder aux champs.

(Une option consiste à ajouter les couches en tant que couches d'entités, mais je préférerais éviter cela si possible).

var url = "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/HomelandSecurity/operations/MapServer/";
var dynLayer = new esri.layers.ArcGISDynamicMapServiceLayer(url);
map.addLayer(dynLayer);

dojo.connect(dynLayer, "onLoad", function() {
   var infos = dynLayer.layerInfos;
   for (var i = 0; i <= infos.length - 1; i++) {
       var layerId = infos[i].id;
       var restEndPoint = url + layerId;
       //restEndPoint is the layer's URL - how can I retrieve its fields?
   }
});

Merci, Steve (mis en ligne sur le forum ArcGIS Server )

Stephen Lead
la source

Réponses:

6

Utilisez esri.request () pour atteindre le point de terminaison REST de chaque couche pour obtenir des informations sur les champs. Voici un exemple simple:

<html>
  <head>
    <script type="text/javascript">var djConfig = {parseOnLoad: true};</script>
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.4"></script>
    <script type="text/javascript">
      dojo.require("esri.map");
      // var service_url = 'http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Hurricanes/NOAA_Tracks_1851_2007/MapServer/layers';
      var service_url = 'http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Fire/Sheep/MapServer/layers';

      function init() {
        esri.request({
          url: service_url,
          content: { f: 'json' },
          callbackParamName: 'callback',
          load: processServiceInfo,
          error: errorHandler
        });
      }
      // Runs once
      function processServiceInfo(info) {
        console.log('svc info: ', info);
        dojo.byId('info').innerHTML = '';
        dojo.forEach(info.layers, function(lyr) {

          // Add a new div for each Layer
          var lyr_div = dojo.create('div', { 
            id: 'layer_' + lyr.id,
            innerHTML: '<strong>Layer: ' + lyr.name + '</strong><br />'
          }, dojo.byId('info'));

          dojo.forEach(lyr.fields, function(field) {
            lyr_div.innerHTML += 'Name: ' + field.name + '; Alias: ' + field.alias + '<br />';
          });
        });
      }

      function errorHandler(err) {
        console.log('error: ', err);
      }

      dojo.ready(init);
    </script>
  </head>
  <body>
    <div id="info">field names and aliases will show up here.</div>
  </body>
</html>

Ce code utilise la v2.0 de l'API mais la même chose fonctionnera en 2.3 ou 2.4. J'ai initialement publié sur le forum API Esri JS .

Modifier: mis à jour pour gérer toutes les couches d'un service. Le code utilise également désormais la version 2.4 de l'API.

Derek Swingley
la source
+1 Ça a l'air bien. Étant donné que l'utilisateur a 3 couches, il peut être plus utile d'avoir init appeler une fonction FieldsInit pour chaque couche.
Kirk Kuykendall
esri.request est le chemin à parcourir, mais au lieu d'interroger des couches individuelles, il suffit de les interroger toutes à la fois en utilisant http: //..../MapServer/layers? f = json comme URL.
Sasa Ivetic
Entre vous tous, je pense que nous avons une excellente réponse :) @Derek pouvez-vous modifier le code pour gérer toutes les couches selon la suggestion de Sasa, et je vais le marquer comme accepté? Merci à tous
Stephen Lead
Voilà Steve ... a mis à jour mon exemple de code pour fournir des informations sur toutes les couches d'un service de carte.
Derek Swingley
Merci. Je charge le résultat JSON dans une variable globale à laquelle je peux accéder à tout moment, pour déterminer les couches et les champs disponibles dans la carte. Brillant.
Stephen Lead
0

J'ai peut-être la mauvaise extrémité du bâton ici, mais ne vous contentez-vous pas d'effectuer une requête sur la couche en question et de récupérer les résultats sous forme de jeu de résultats? Si vous le demandez dans json, vous pouvez analyser les résultats?

Donc pour ça:

http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer/1/query?where=STATE_NAME%3D%27Florida%27&f=json

Le retour est:

{"displayFieldName": "STATE_NAME", "fieldAliases": {"STATE_NAME": "STATE_NAME"}, "geometryType": "esriGeometryPolygon", "spatialReference": {"wkid": 4326}, "fields": [{"" nom ":" STATE_NAME "," type ":" esriFieldTypeString "," alias ":" STATE_NAME "," longueur ": 25}]," features ": [{" attributs ": {" STATE_NAME ":" Florida "} , "géométrie": {"anneaux": [[[- 80.785662408630856,28.785194039580265], ... [-80.5878197219821,24.956376399079556], [- 80.249453677873134,25.354937642313288]]]}}]}

(J'ai supprimé la plupart de la géométrie pour en faciliter la lecture)

Poilu
la source
comment saviez-vous qu'il fallait interroger la couche 1 et qu'il y avait un champ appelé STATE_NAME? C'est ce que j'essaie de déterminer à la volée (c'est-à-dire que j'ai besoin de cela pour fonctionner pour N'IMPORTE QUEL point de terminaison de repos au moment de l'exécution, pas un que je connaisse à l'avance). Merci
Stephen Lead
eh bien, la réponse la plus simple serait de compter les couches dans le service de carte et les autres services de carte, et de les parcourir pour demander les données. Une requête peut simplement être nulle, donc vous ramenez tout. Vous pouvez ensuite parcourir la réponse répertoriant les données.
Hairy
donc dans mon exemple ci-dessus, je définirais une QueryTask basée sur chaque restEndPoint, et créerais une requête qui ne retournerait pas de géométrie - bonne idée. Je vais essayer - merci!
Stephen Lead
Voilà comment je l'aborderais
Hairy
Essayez ceci: URL vers la couche URL / YOURLAYERNAME / MapServer / layers? F = json - Cela devrait renvoyer une représentation json de toutes vos couches et de leurs champs ou URL / YOURLAYERNAME / MapServer / 1? F = json indiquant le numéro de couche que vous voulez
Hairy