3

I have a polygon feature layer and a table, both stored in ArcGIS Online. Is it possible to join them on-the-fly in the ArcGIS Server JS API?

For example, here are some sample ArcGIS Server services for:

Is it possible to join the layer and the table, and therefore to symbolize the polygons using the table's values?

5
  • Since this is just sample data, how frequently will your real data be updated? That will be a big factor in deciding how to proceed. Aug 8, 2016 at 16:28
  • @JeffJacobson the dataset may be updated frequently. I assume from your comment you're suggesting that I need to flatten the datasets, eg join them in ArcMap and publish the joined table to ArcGIS Online? I was hoping it would be possible to do the join programatically, to avoid this if at all possible Aug 8, 2016 at 22:56
  • One thing you could do would be to load the data the first time the user visits the site, do the two queries, and then store the joined results in the browser's local storage using IndexedDB. Another thing you can do to improve performance is to do the queries and join in a separate thread using Web Workers. Aug 10, 2016 at 16:07
  • ...You won't be able to use the ArcGIS API for JavaScript to do the queries in a Web Worker, though. You'll need to query the ArcGIS Servers' REST APIs directly. I have some code on GitHub that demonstrates how to do this. Aug 10, 2016 at 16:09
  • @JeffJacobson thanks for the tips. I was hoping to avoid this due to the large size of the datasets but maybe it's necessary to just publish the joined tables directly to ArcGIS Online Aug 10, 2016 at 23:32

1 Answer 1

3

I finally got around to answering this one. This solution uses 2 separate queries to fetch the geometry and attributes, then joins the JSON arrays to form a combined layer definition.

enter image description here

app = {};
app.map = new Map("map", {
  basemap: "gray",
  center: [-80, 38],
  zoom: 5
});
app.spatialReference = new SpatialReference({wkid:4326});

app.map.on("layers-add-result", function(results) {
  console.log("Added joined layer to map")
});

app.sfs = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,
  new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,
  new Color([255,0,0]), 2),new Color([255,255,0,0.25])
);

// Request the geometry
var geomParams = {
  where: "1=1",
  outFields: ["state_name"],
  returnGeometry: true,
  f: "json"
}

$.ajax({
  dataType: "json",
  data: geomParams,
  url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/2/query/",
  success: function (data1){
    console.log("Got geometry");
    app.data1 = data1;

    // Now request the attribute data
    var tableParams = {
      where: "1=1",
      outFields: "*",
      returnGeometry: false,
      f: "json"
    }

    $.ajax({
      dataType: "jsonp",
      jsonpCallback: "callback",
      data: tableParams,
      url: "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5/query/",
      success: function (data2){
        console.log("Got attributes")
        app.data2 = data2;

        // Join the geometry to the attributes
        $.extend( true, app.data1, app.data2 );
        console.log("Joined geometry to attributes");

        // Create a feature layer from the joined JSON
        app.featureCollection = {
          layerDefinition: {
            geometryType: app.data1.geometryType,
            spatialReference: app.spatialReference,
            objectIdField: "ObjectID",
            fields: app.data1.fields,
            drawingInfo: {
              renderer: {
                type: "simple",
                symbol: app.sfs
              }
            }
          },
          featureSet: {
            features: app.data1.features,
            geometryType: app.data1.geometryType,
            spatialReference: app.spatialReference
          }
        };
        var infoTemplate = new esri.InfoTemplate("Attributes", "${*}");  
        app.featureLayer = new FeatureLayer(app.featureCollection, {
          id: "Joined Layer",
          infoTemplate: infoTemplate
        });
        app.map.addLayers([app.featureLayer]);
      }
    });
  }
});

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.