ArcGIS Arcade

This post presents a collection of Arcade expressions that can be used in ArcGIS to perform various tasks, including finding the nearest feature, adding links to a popup to display location in Google Maps, and converting point X and point Y to 4326.

  • geodatabase
  • attribute rule
  • geometry
  • Google Maps
  • geospatial
  • GIS
  • ArcGIS Arcade Expressions Reference
  • Arcade Expressions
  • Javascript
  • ArcGIS JavaScript API
  • Arcade
  • ESRI Developers Summit 2023
  • ESRI
  • ArcGIS
 

 

Find Nearest

I use this to copy address points to a nearest feature. It is pretty simple and it gets a lot of use in a few programs I maintain.

var AddressPointFC = FeatureSetByName($datastore, "Name Of Feature On Map", ["Name Of Field or * for All"]);
var SearchDistance = 3000;
var locations = Intersects(AddressPointFC, Buffer($feature, SearchDistance, "feet"));
var count = Count(locations);
var minDistance = Infinity;
var address = Null
if (count > 0) {
    for (var location in locations) {
        var distance = Distance(locations, $feature, "feet");
        if (distance < ShortestDistance) {
            address = locations.FIELD_NAME_IDENTIFIED_ON_LINE_1;
            ShortestDistance = distance
        }
    }
} else {
    // pass no features found within search distance, name remains null
}
return address;

 

Google Streetview and Mapview

I use this code to add links to a popup that will take the current location and display it in Google Maps. YOu need to use another arcade expression to populate pointX and PointY If you search around I believe there is atleast 1 public facing application using this code. I wonder where...???

// Streetview
var lat = Replace(Text($feature["Latitude Field Name"], "#.#######"), ",", ".");
var lon = Replace(Text($feature["Longitude Field Name"], "#.#######"), ",", ".");
var url = "http://maps.google.com/?cbll=" + lat + "," + lon + "&cbp=12,90,0,0,5&layer=c";
return url;

// Google maps search
var lat = Replace(Text($feature["Latitude Field Name"], "#.#######"), ",", ".");
var lon = Replace(Text($feature["Longitude Field Name"], "#.#######"), ",", ".");
var url = "https://www.google.com/maps/search/?api=1&query=" + lat + "," + lon;
return url;

// Google maps @ location (zoom level 19)
var lat = Replace(Text($feature["Latitude Field Name"], "#.#######"), ",", ".");
var lon = Replace(Text($feature["Longitude Field Name"], "#.#######"), ",", ".");
var url = "https://www.google.com/maps/@" + lat + "," + lon + ",19z";
return url;

 

Parcel Parent Name

This is used for the Parcel Fabric and helps return the parent record in a popup.

// popup to display parent parcel names
var RecordID = $feature.CreatedByRecord;
var sql = "RetiredByRecord = '" + RecordID + "'";
var fsHisoricParcels = FeatureSetByName($map, 'Historic Tax', ["Name"], false);
var fsParentParcels = Filter(fsHisoricParcels, sql);
var cnt = Count(fsParentParcels);
if (cnt ==0) {return "No Parent Parcels found"}
else{
    var ParentParcelsNames = cnt + " Parent Parcels =  ";

    for (var HistoricParcel in fsParentParcels){
        ParentParcelsNames += (HistoricParcel.Name + "; ");
    }
    return ParentParcelsNames;
}

 

Convert PointX and Point Y to 4326

This one I found on the Esri Community Forums a while ago and I use it or parts of it pretty regularly. By default this returns a Google Map point in the proper Spatial Reference. If I find the owner I will throw some credits their way.

var PointGeometry = Geometry($feature);
var ArcadeX = PointGeometry.x;
var ArcadeY = PointGeometry.y;
var ArcadeSr = PointGeometry.spatialReference.wkid;
var Latitude, Longitude;
//Longitude = ArcadeX;
//Latitude = ArcadeY;


function AuxSphereToLatLon(x, y) 
{  Console("Converting...");


var rMajor = 6378137;
var shift = PI * rMajor;
Longitude = x / shift * 180.0;
Latitude = y / shift * 180.0;
Latitude = 180 / PI * (2 * Atan(Exp(Latitude * PI / 180.0)) - PI / 2.0);
}

if (ArcadeSr == 4326) {  Console("4326 Spatial Reference - No Conversion Necessary");  Latitude = ArcadeY;  Longitude = ArcadeX;} else if (ArcadeSr == 102100) {  Console("102100 Spatial Reference - Conversion Necessary");  AuxSphereToLatLon(ArcadeX, ArcadeY);} else {  Console(ArcadeSr + " Spatial Reference is not supported - currently works with Web Maps where the basemap is in WGS84 (4326) or Web Mercator Auxiliary Sphere 102100");}
var url = "http://www.google.com/maps/@?api=1&map_action=pano&viewpoint=" + text(Latitude) + "," + text(Longitude);
return url;

 

Geometry Pass to S123 to Capture PointX and PointY in a related Table

This is used in a specific set of apps but could have a wide use for capturing data to a non spatial table.

// Returns generalized geometry based on extent.
function WebMercatorToWGS84 (x, y) {
    var lon = (x / 20037508.34) * 180;
    var lat = (y / 20037508.34) * 180;
    lat = 180/PI * (2 * Atan(Exp(lat * PI / 180)) - PI / 2);
    return {
        y: lat,
        x: lon
    }
}
var urlsource ='arcgis-survey123://?';
var geom = Geometry($feature)
var coords =  WebMercatorToWGS84(geom.x, geom.y)
var params = {
  itemID:'ITEMIDHERE',
  field:asset_id: $feature["asset_id"],
  center: coords.y + "," coords.x
};
return urlsource  + UrlEncode(params);

 

Find the Largest Area of an Intersects

This one I use on 2 different apps. Lets say 2 polygon features are crossing each other, in this case, a parcel and a region or zone. To determine which region or zone applies to the parcel we can find which intersection is greater.

//return intersects where overlap is greatest
var overlayFC = FeatureSetByName($map,"GEODATABSE_FEATURE_NAME", ["FIELD_NAMES"], true);
//I use xints a lot for my variables to define the interects of another layer. 
var xints = Intersects($feature, overlayFC)
var shpArea = 0
//shpID will return the field name of the xints that holds the name or defining //field value
var shpID = ''

For (var i in xints) {  
    var newArea = Area(Intersection($feature, i))
     If (newArea > shpArea) {
     shpArea = newArea
     shpID = i.FIELDNAME
     }
}
Return shpID

 

Update Multiple Fields in a Single Attribute Rule

This is pretty self explainatory but very useful for data maintenance.

return {
    //result is a dictionary or a scalar value
    "result" : {
          "attributes" : {
                   "field1" : Object, //update field1 in the $feature 
                   "field2" : Object  //update field2 in the $feature 
          },
          "geometry": Object    //update geometry in $feature
 }

}

 

Popup value control method

Not sure what to name this one. I loop through all the field names and values and return them as a string but I remove null values. I hate null values. Have I mentioned how much I hate unconfigured popups? I really do. I created this so users can atleast have this in their popup and not the standard table.

// Loop through all field values return values that are not null as Upper Case.
// I use this instead of the standard table view in a popup to control hiding NULLS
var fields = "";
for (var i in $feature) {
      if (!IsEmpty($feature[i])) {
            fields = Upper(fields + i + ":  " + $feature[i] + TEXTFORMATTING.NEWLINE)
            }
      }
return fields

You can also return html elements in the fields calc. example fields = (fields + "

" + i + "" + ": " + $feature[i] + "
")

 

If you figure out how to get a custom HTML table working with this I would love to see it. Image a world with no unconfigured popups...

 

Additional Display Regions

Primary Content