Select to view content in your preferred language

Autonumbering arcade expression works in the Map Viewer but not in Field Maps

2228
15
Jump to solution
07-19-2023 04:25 PM
HollyTorpey_LSA
Occasional Contributor III

I have written this script to autonumber trees our arborists are surveying: 

// if this feature already has a Tree Number, return that
if(!IsEmpty($feature.TreeNumber)) { 
  return $feature.TreeNumber 
} else {

  // get the feature with the greatest Tree Number for the current project in the featureset
  var projectNumber = $feature.ProjectNum
  var Tree_features = Filter($featureset, "(TreeNumber IS NOT NULL) AND (ProjectNum = @projectNumber)")
  var max_Tree_feature = First(OrderBy(Tree_features, "TreeNumber DESC"))

  // for an empty featureset, this will be null, so return a 1
  if(max_Tree_feature == null) { return 1 }

  // calculate the max tree number for this project and return the next tree number for the current feature
  var max_TreeNumber = max_Tree_feature.TreeNumber
  var next_TreeNumber = max_TreeNumber + 1
  return next_TreeNumber
}

The script works great in the map viewer. If I add a new feature in the particular project I'm working in, it autonumbers the new feature 10 because there are already nine other features. However, if I open the same map in Field Maps and add a new feature, it autonumbers every new feature 1 regardless of the other tree numbers already in the project.
 
Map Viewer:
HollyTorpey_LSA_0-1689808836116.png

 

Field Maps mobile app:
HollyTorpey_LSA_1-1689809074136.png
 
The quick fix is to hard code the project number. We already have to update the Arcade expression that calculates the Project Number field each time we set up a Field Maps map with this layer for a new project, so we could also pop into this script and enter the project number here too. But I don't want to do that because it's an extra step for us to remember to do and because typing in (or pasting in) the project number twice is just an opportunity to introduce error. Plus I just want to know why this works in the Map Viewer but not in the Field Maps mobile app.
 
Thanks in advance for any help you can provide!
- Holly
0 Kudos
1 Solution

Accepted Solutions
RhettZufelt
MVP Notable Contributor

Well, whether you are entering the project number in the field, or if it is being calculated, you need some way for that to get populated.  If it is populated, then this script will find the highest tree number for that project and populate the tree number field.

// if this feature already has a Tree Number, return that
if(!IsEmpty($feature.TreeNumber)) { 
  return $feature.TreeNumber 
}
else {
var trees = FeatureSetByName($datastore,"TreeTest",['TreeNumber'],false)
var projectNumber = $feature.ProjectNum
var Tree_features = Filter(trees, "ProjectNum = @projectNumber")
var numarray = []
for (var n in Tree_features){
    var nn = Number(n.TreeNumber)
    Push(numarray, nn)
}
var maxnum = Max(numarray)
var newnum = maxnum + 1

return newnum
}

This works if the project number is typed in manually, calculated by the form, picked from a dropdown list, or populated with a template, etc.  So, depending on how may projects you have, there may be a less cumbersome way to deal with it than editing the arcade all the time.

Could make a separate map for each project, create a domain so there is a dropdown list to pick the project number in the form, (can always have them type it in), or, could create templates so there is a button for each project that has projectNum default value.  That way, when you add a new feature with it, the correct project number is entered, then it has enough info to find/update the tree number.

By what ever method used to assign the project number, this should work fine 'once' the project number is in the field so the form has access to it.

R_

View solution in original post

0 Kudos
15 Replies
KerriRasmussen
Esri Contributor

Hi Holly,

Thank you for sharing this issue. I do have a few questions for you regarding your workflow.

Is this number meant to be a unique identifier?

Will those in the field be using the maps online/offline/both?

What is your ultimate goal for the field you are calculating?

And would you be willing to share the map with us so we can take a look and offer suggestion? If so, you can share it with arcgisfieldmaps.

Lastly, you had asked why your expression worked in the Map Viewer, but it wasn’t working in Field Maps. When you are working with your data in Map Viewer, you have access to the whole table in that feature service, which allows you to see the other feature and their data. That allows your expression to run correctly since you have access to those other records. In Field Maps, when you are working in a form, it takes a much more microscopic view of your data, and you are only working with/looking at one feature at a time. Basically, you can’t run that calculation off other features, because as far as the form is concerned, that is the only feature that exists at the time.

Thank you,

Kerri

0 Kudos
HollyTorpey_LSA
Occasional Contributor III

Thanks for the reply and apologies for the delayed response. For some reason I'm not seeing notifications in the Esri Community lately...

Here are my reponses to your questions:

The number is not meant to be a unique identifier, but it is meant to be unique for each individual project number. So for each project number, trees should be numbered starting at 1.

So far it hasn't been used for offline use. I'm assuming it wouldn't work offline... or am I wrong?

The goal is to sequentially number trees within a project area so that arborists don't have to remember/figure out what the next tree number will be. These numbers then are used to label surveyed trees on a map figure that arborists include in their report.

The explanation in your last paragraph is a little confusing to me because when I hardcode the project number, the script works just fine (e.g., var projectNumber = "12345678"). We were running it like that for months before it occurred to me that I could pull the project number from another field in the form itself and avoid having to update the Arcade for the tree number field. So it was able to query the whole layer to get and sort the range of existing tree numbers for that project number. Am I misunderstanding what you meant?

Thanks again for the response! I'm going to try @RhettZufelt's solution and if that doesn't work out, I'll share the layer with the account you mentioned. 

 

 

- Holly
0 Kudos
HollyTorpey_LSA
Occasional Contributor III

@KerriRasmussen I just invited arcgisfieldmaps to a group called LSA - Esri Support. I'd appreciate any help you can provide!

- Holly
0 Kudos
RhettZufelt
MVP Notable Contributor

My autonumber script seems to work just fine in Map Viewer, and Field Maps App (on iOS).  

 

var vals = FeatureSetByName($datastore,"Sign",['TestInt'],false)
var numarray = []
for (var n in vals){
    var nn = Number(n.TestInt)
    Push(numarray, nn)
}
var maxnum = Max(numarray)
var newnum = maxnum + 1

return newnum

 

This finds the largest number in the ['TestInt'] field of the feature class named "Sign", adds 1 to it, and populates the TestInt field in the new feature with the incremented value.

Even works offline, but will only find max value of features within the offline area**.  So would only use offline if you can download your entire area, AND, there are no other users editing the data.

Have not tested to see if there is a limit to the number of features.

If you have a lot of features in your dataset, it will defiantly increase the time it takes to submit.

Edit:  Just tested, and with 2000 records I don't notice any delay.  With11,500 records, can take over 10 seconds longer to submit.

R_

HollyTorpey_LSA
Occasional Contributor III

Thank you so much!! I will try this out later today and report back.

- Holly
0 Kudos
RhettZufelt
MVP Notable Contributor

How are you getting the ProjectNum on a 'new' feature?  Is this something that you are entering in the form right at first?  Do you have separate Field Maps map per project?

Trying to figure out how to filter on a value that doesn't exist on initial feature creation.

R_

0 Kudos
HollyTorpey_LSA
Occasional Contributor III

It's a hardcoded field calculation on the Project Number field (e.g. return "12345678"). And yes, we create a new field map for each project, and this data collection template layer gets added to the project. We just have to update the project number field calculation in the smart form (and formerly also the tree numbering script... I updated the script in hopes of only having to add that project number in once place, but then realized it didn't work in the Field Maps mobile app).

- Holly
0 Kudos
RhettZufelt
MVP Notable Contributor

Guess I'm a bit confused.  If it is always hardcoded to the same number, why the need for a Filter?

In any case, this works for me to auto populate the next sequential number to the TreeNumber field (Calculated expression on TreeNumber field in form).  

// if this feature already has a Tree Number, return that
if(!IsEmpty($feature.TreeNumber)) { 
  return $feature.TreeNumber 
}
else {
var vals = FeatureSetByName($datastore,"TreeTest",['TreeNumber'],false)
var numarray = []
for (var n in vals){
    var nn = Number(n.TreeNumber)
    Push(numarray, nn)
}
var maxnum = Max(numarray)
var newnum = maxnum + 1

return newnum
}

 

R_

0 Kudos
HollyTorpey_LSA
Occasional Contributor III

It's not always the same project number... I update the project number in the Arcade expression used to calculate that field for each new Field Maps map I set up with this template.

The weird thing is that this works in both the Map Viewer and Field Maps:

// if this feature already has a Tree Number, return that
if(!IsEmpty($feature.TreeNumber)) { 
  return $feature.TreeNumber 

// Otherwise, get the set of trees with the same project number  
} else {

  // Get the Project Number from the ProjectNum field
  var projectNumber = '12345678' //$feature.ProjectNum

  // get the feature with the greatest Tree Number for the current project in the featureset
  
  var Tree_features = Filter($featureset, "(TreeNumber IS NOT NULL) AND (ProjectNum = @projectNumber)")
  var max_Tree_feature = First(OrderBy(Tree_features, "TreeNumber DESC"))

  // for an empty featureset, this will be null, so return a 1
  if(max_Tree_feature == null) { return 1 }

  // calculate the max tree number for this project and return the next tree number for the current feature
  var max_TreeNumber = max_Tree_feature.TreeNumber
  var next_TreeNumber = max_TreeNumber + 1
  return next_TreeNumber
}

But this only works in the map viewer (the only thing that changes here is line 9):

// if this feature already has a Tree Number, return that
if(!IsEmpty($feature.TreeNumber)) { 
  return $feature.TreeNumber 

// Otherwise, get the set of trees with the same project number  
} else {

  // Get the Project Number from the ProjectNum field
  var projectNumber = $feature.ProjectNum

  // get the feature with the greatest Tree Number for the current project in the featureset
  
  var Tree_features = Filter($featureset, "(TreeNumber IS NOT NULL) AND (ProjectNum = @projectNumber)")
  var max_Tree_feature = First(OrderBy(Tree_features, "TreeNumber DESC"))

  // for an empty featureset, this will be null, so return a 1
  if(max_Tree_feature == null) { return 1 }

  // calculate the max tree number for this project and return the next tree number for the current feature
  var max_TreeNumber = max_Tree_feature.TreeNumber
  var next_TreeNumber = max_TreeNumber + 1
  return next_TreeNumber
}

 If I add a "return $feature.ProjectNum" in line 7, the script populates the TreeNumber with my project number, so I know it's able to pull the calculated project number from the feature. 

- Holly
0 Kudos