So navigieren Sie durch die REST-Endpunkte und rufen Programminformationen programmgesteuert ab

9

Ich füge einen dynamischen Map-Service zu einer ArcGIS Server-JavaScript-API-Map hinzu und muss jeden Komponenten-Layer und seine Felder erfassen, damit ich eine Abfrage ausführen kann.

Weitere Informationen finden Sie im Beispielverzeichnis für ArcGIS Server-Dienste unter http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/HomelandSecurity/operations/MapServer

Wenn Sie diese URL in einem Browser öffnen, sehen Sie die Liste der verfügbaren Ebenen (0,1,2) und die Felder der einzelnen Ebenen .

Wie kann ich die Liste der Felder innerhalb einer JavaScript-Funktion programmgesteuert abrufen? Das folgende Codefragment zeigt, wie die Ebenenendpunkte abgerufen werden, aber ich kann nicht sehen, wie ich zu den Feldern komme.

(Eine Möglichkeit besteht darin, die Ebenen als Feature-Ebenen hinzuzufügen, aber ich würde dies nach Möglichkeit lieber vermeiden.)

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

Vielen Dank, Steve (im ArcGIS Server-Forum veröffentlicht )

Stephen Lead
quelle

Antworten:

6

Verwenden Sie esri.request (), um den REST-Endpunkt jeder Ebene zu erreichen und Informationen zu Feldern zu erhalten. Hier ist ein einfaches Beispiel:

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

Dieser Code verwendet v2.0 der API, aber dasselbe funktioniert bei 2.3 oder 2.4. Ich habe ursprünglich im Esri JS API-Forum gepostet .

Bearbeiten: Aktualisiert, um alle Ebenen in einem Dienst zu behandeln. Der Code verwendet jetzt auch Version 2.4 der API.

Derek Swingley
quelle
+1 Sieht gut aus. Da der Benutzer jedoch drei Ebenen hat, ist es möglicherweise nützlicher, wenn init eine FieldsInit-Funktion für jede Ebene aufruft.
Kirk Kuykendall
esri.request ist der richtige Weg, aber anstatt einzelne Ebenen abzufragen, fragen Sie sie einfach alle gleichzeitig ab, indem Sie http: //..../MapServer/layers? f = json als URL verwenden.
Sasa Ivetic
Ich denke, wir haben eine großartige Antwort :) @Derek, können Sie den Code so bearbeiten, dass alle Ebenen gemäß Sasas Vorschlag verarbeitet werden, und ich werde ihn als akzeptiert markieren? Vielen Dank an alle
Stephen Lead
Los geht's, Steve ... hat mein Codebeispiel aktualisiert, um Informationen für alle Ebenen in einem Kartendienst bereitzustellen.
Derek Swingley
Vielen Dank. Ich lade das JSON-Ergebnis in eine globale Variable, auf die ich jederzeit zugreifen kann, um die in der Karte verfügbaren Ebenen und Felder zu bestimmen. Brillant.
Stephen Lead
0

Ich habe hier möglicherweise das falsche Ende des Sticks, aber führen Sie nicht einfach eine Abfrage für die betreffende Ebene durch und erhalten die Ergebnisse als Ergebnismenge zurück? Wenn Sie in json danach fragen, können Sie die Ergebnisse analysieren?

Also dafür:

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

Die Rückkehr ist:

{"displayFieldName": "STATE_NAME", "fieldAliases": {"STATE_NAME": "STATE_NAME"}, "GeometryType": "esriGeometryPolygon", "SpatialReference": {"wkid": 4326}, "fields": [{" Name ":" STATE_NAME "," Typ ":" esriFieldTypeString "," Alias ​​":" STATE_NAME "," Länge ": 25}]," Features ": [{" Attribute ": {" STATE_NAME ":" Florida "} , "Geometrie": {"Ringe": [[[- 80.785662408630856,28.785194039580265], ... [-80.5878197219821,24.956376399079556], [- 80.249453677873134,25.354937642313288]]}}

(Ich habe den größten Teil der Geometrie entfernt, um das Lesen zu erleichtern.)

Behaart
quelle
Woher wussten Sie, dass Sie Schicht 1 abfragen müssen und dass es ein Feld namens STATE_NAME gibt? Das ist es, was ich versuche, im laufenden Betrieb zu trainieren (dh ich brauche dies, um zur Laufzeit für JEDEN Ruheendpunkt zu arbeiten, nicht für einen, den ich vorher kenne). Vielen Dank
Stephen Lead
Nun, die einfachste Antwort wäre, die Ebenen im Kartendienst und untereinander im Kartendienst zu zählen und sie zu durchlaufen, um die Daten anzufordern. Eine Abfrage kann nur eine Null sein, sodass Sie alles zurückbringen. Sie können dann die Antwort durchlaufen, in der die Daten aufgelistet sind.
Haarige
In meinem obigen Beispiel habe ich eine QueryTask basierend auf jedem restEndPoint festgelegt und eine Abfrage erstellt, die keine Geometrie zurückgibt - eine gute Idee. Ich werde es versuchen - danke!
Stephen Lead
So würde ich es angehen
Hairy
Versuchen Sie diese:? Url Schicht URL / YOURLAYERNAME / MapServer / Schichten f = json - Dies sollte zurückgeben eine json Darstellung aller Ihrer Schichten und ihre Felder oder URL / YOURLAYERNAME / MapServer / 1 f = json , welche die Schichtnummer , die Sie wollen
Haarige