ArcGIS Integration Guide

How to get AXIOM Exchange property polygons (or lines, or points) onto an ArcGIS map, in either direction the ArcGIS ecosystem expects data.

1. ArcGIS JS API — GeoJSONLayer (recommended)

The ArcGIS JS API's GeoJSONLayer class consumes a GeoJSON FeatureCollection URL directly — no transformation needed. Point it straight at any AXIOM Exchange geo endpoint:

require(["esri/Map", "esri/views/MapView", "esri/layers/GeoJSONLayer"], (Map, MapView, GeoJSONLayer) => {

  // Everything currently in the map viewport — refresh on extent change:
  function viewportLayer(view) {
    const e = view.extent;
    const url = `https://your-axiom-host/api/v1/geo/bbox` +
      `?min_lon=${e.xmin}&min_lat=${e.ymin}&max_lon=${e.xmax}&max_lat=${e.ymax}`;
    return new GeoJSONLayer({ url });
  }

  const map = new Map({ basemap: "topo-vector" });
  const view = new MapView({ container: "viewDiv", map, center: [-97.74, 30.27], zoom: 9 });

  let currentLayer = viewportLayer(view);
  map.add(currentLayer);

  view.watch("stationary", (isStationary) => {
    if (!isStationary) return;
    map.remove(currentLayer);
    currentLayer = viewportLayer(view);
    map.add(currentLayer);
  });
});

/geo/bbox, /geo/query, and /geo/query/radius all return a proper FeatureCollection, so those are the endpoints to point a GeoJSONLayer at directly. /assets and /assets/{id}/geometry return a plain list and a single Feature respectively — fine for fetch()-and-render workflows.

Styling by reseller or cost key

Every feature carries reseller_id, customer_id, cost_key, and state in its properties, so you can drive a renderer straight off tenancy without a second round trip:

const layer = new GeoJSONLayer({
  url: "https://your-axiom-host/api/v1/geo/bbox?min_lon=-110&min_lat=25&max_lon=-90&max_lat=50",
  renderer: {
    type: "unique-value",
    field: "reseller_id",
    uniqueValueInfos: [
      { value: "7fe24e63-ae59-4183-a4a2-d313e483a64d",
        symbol: { type: "simple-fill", color: [88,166,255,0.35], outline: { color: "#58a6ff", width: 1.5 } } },
      { value: "ed4d52c7-67af-4c93-9fb0-1800839737f8",
        symbol: { type: "simple-fill", color: [210,153,34,0.35], outline: { color: "#d29922", width: 1.5 } } }
    ]
  }
});

Auth

GeoJSONLayer doesn't attach headers itself — use esriConfig.request.interceptors, and include the reseller scope if you want the layer to show only one reseller's properties:

import esriConfig from "@arcgis/core/config";

esriConfig.request.interceptors.push({
  urls: "https://your-axiom-host/api/v1",
  headers: {
    "X-API-Key": "axiom-local-dev-key",
    "X-Axiom-Reseller-Id": "7fe24e63-ae59-4183-a4a2-d313e483a64d"
  },
});

2. Drawing a polygon in ArcGIS and sending it to AXIOM

The reverse direction: a user sketches an area of interest, and you want every customer and utility status inside it.

require(["esri/widgets/Sketch", "esri/layers/GraphicsLayer"], (Sketch, GraphicsLayer) => {
  const sketchLayer = new GraphicsLayer();
  map.add(sketchLayer);

  const sketch = new Sketch({ layer: sketchLayer, view, creationMode: "update" });
  view.ui.add(sketch, "top-right");

  sketch.on("create", async (event) => {
    if (event.state !== "complete") return;
    const geojsonPolygon = { type: "Polygon", coordinates: event.graphic.geometry.rings };
    const headers = { "Content-Type": "application/json", "X-API-Key": "axiom-local-dev-key" };

    // Who do I have in this territory?
    const customers = await (await fetch("https://your-axiom-host/api/v1/geo/customers/search", {
      method: "POST", headers, body: JSON.stringify({ geometry: geojsonPolygon })
    })).json();

    // What's the utility situation there?
    const utilities = await (await fetch("https://your-axiom-host/api/v1/geo/utilities/status", {
      method: "POST", headers, body: JSON.stringify({ geometry: geojsonPolygon })
    })).json();

    console.log(customers.customers, utilities.utilities);
  });
});

For anything beyond simple polygons, use a proper conversion library (e.g. @terraformer/arcgis) rather than reading .rings directly.

3. Esri JSON / ArcGIS REST-style clients

Older ArcGIS Runtime SDKs (or code written against the ArcGIS REST API's FeatureSet format) expect Esri JSON. Every geo endpoint supports ?format=esri:

GET /api/v1/geo/bbox?min_lon=-98&min_lat=30&max_lon=-97.4&max_lat=30.6&format=esri
{
  "geometryType": "esriGeometryPolygon",
  "spatialReference": {"wkid": 4326},
  "features": [
    {
      "geometry": {"rings": [[]], "spatialReference": {"wkid": 4326}},
      "attributes": {"id": "...", "name": "Austin Distribution Center",
                     "reseller_id": "7fe24e63-...", "cost_key": "7fe24e63-...", "state": "TX"}
    }
  ]
}

This matches the shape a real ArcGIS Feature Service query returns (.../FeatureServer/0/query?f=json), so code already written against an Esri feature service can largely be pointed at AXIOM with a URL change.

4. Publishing AXIOM data into ArcGIS Online / Enterprise

  1. GET /api/v1/geo/bbox?...&format=geojson (or /geo/query with a large boundary) to pull the full dataset for a reseller or asset type.
  2. Upload the resulting FeatureCollection as a GeoJSON item in ArcGIS Online (Content → Add Item → From your computer), or script it with the ArcGIS REST API's addItem + publish operations.
  3. For data that needs to stay live, prefer the direct GeoJSONLayer approach in section 1 — publishing takes a snapshot.

5. Coordinate system notes