How to create a featureset from two other featuresets

1247
8
Jump to solution
09-02-2021 07:16 AM
KenKoleda
New Contributor II

Hello,

I need to combine data from two featuresets that are 1) hosted by someone else 2) of different geometries.

They contain project information.  Projects in one layer are lines, the other layer is points.  Each has an attribute representing total project cost.   I can access each featureset, but cannot figure out how to essentially merge together the attribute data for display in say an indicator or some other widget.  I do not need the geometry.

I created a data expression as the data source as shown below.

It seems like I could use FeatureSet(defintiion) where the definition is JSON, but I am not finding good examples of the format needed or how to go from one to the other.

Any pointers to documentation, examples or suggestions appreciated.

Thanks

==================

var featureDataPoint = FeatureSetByPortalItem(Portal('https://gccountymi.maps.arcgis.com'), 'd600a66fe6ac48a098cb94a36d97a48b', 3);
var featureDataLine = FeatureSetByPortalItem(Portal('https://gccountymi.maps.arcgis.com'), 'd600a66fe6ac48a098cb94a36d97a48b', 4);

//TOT_PRJ_COST
// need to create a featureSet with TOT_PRJ_COST from two featuresets and put in 'featureData'

return featureData

- Genesee County GIS Department
Tags (1)
0 Kudos
2 Solutions

Accepted Solutions
jcarlson
MVP Esteemed Contributor

Well, that is much simpler. Try something like this:

var feat_arr = []

var i = 0

var featureDataPoint = FeatureSetByPortalItem(Portal('https://gccountymi.maps.arcgis.com'), 'd600a66fe6ac48a098cb94a36d97a48b', 3, ['TOT_PRJ_COST'], false);

var featureDataLine = FeatureSetByPortalItem(Portal('https://gccountymi.maps.arcgis.com'), 'd600a66fe6ac48a098cb94a36d97a48b', 4, ['TOT_PRJ_COST'], false);

for(var a in featureDataPoint){
    feat_arr[i] = {attributes: {total_cost: a.TOT_PRJ_COST}}
    i++
}

for(var b in featureDataLine){
    feat_arr[i] = {attributes: {total_cost: b.TOT_PRJ_COST}}
    i++
}

var combinedDict = {
  fields: [{ name: "total_cost", type: "esriFieldTypeInteger"}],
  geometryType: "",
  features: feat_arr,
};

FeatureSet(Text(combinedDict))

jcarlson_0-1630606102844.png

By the way, I specified only the total cost attribute in the FeatureSet functions and explicitly stated false to exclude the geometry. That should help your expression's performance some.

- Josh Carlson
Kendall County GIS

View solution in original post

jcarlson
MVP Esteemed Contributor

Well, this is certainly strange. When I add console messages to my own expression, it returns the correct totals for the FeatureSets and layers, but the FeatureSet at the end is smaller.

jcarlson_3-1631223329813.png

I can't account for the different totals you're getting in your FeatureSets, but I did dig into why the FeatureSet has different outputs. Take a look here at the output, and you'll see that the ID columns (I added the variable i as an integer field for testing) skip some values. What's going on here?

jcarlson_4-1631223360520.png

We can see that 81-84 are missing, so I'll call up a few of them from feat_arr to see what their values are.

jcarlson_5-1631223661227.png

The culprit: floating point values. I didn't anticipate these based on a quick sample of the input data, but odds are when it hits those floats and tries inserting them into our defined integer field, it errors out and skips.

 

100% solutions (pick one):

  1. Round off the values before inserting them into the array, i.e., Round(a.TOT_PRJ_CO)
  2. Change the field to a floating point type

I like integers myself, so here's the output with a rounding function in the loop.

jcarlson_6-1631224122097.png

Again, I'm still not sure why your FeatureSets are reading out a different total. I even get the correct totals when including the additional fields.

- Josh Carlson
Kendall County GIS

View solution in original post

8 Replies
jcarlson
MVP Esteemed Contributor

Do the lines and points have a spatial relationship? Or is there an attribute they have in common? Merging the attributes of these is going to depend a lot on the specifics.

Or do you simply want one row in your output for each feature in both inputs? That would be easier.

- Josh Carlson
Kendall County GIS
0 Kudos
KenKoleda
New Contributor II

No spatial or other relationship, I just need to append their attributes.  I was presuming that the featureset can be just a table since I have dashboards for COVID that are reading CSVs and populating indicators and graphs.

- Genesee County GIS Department
0 Kudos
jcarlson
MVP Esteemed Contributor

Well, that is much simpler. Try something like this:

var feat_arr = []

var i = 0

var featureDataPoint = FeatureSetByPortalItem(Portal('https://gccountymi.maps.arcgis.com'), 'd600a66fe6ac48a098cb94a36d97a48b', 3, ['TOT_PRJ_COST'], false);

var featureDataLine = FeatureSetByPortalItem(Portal('https://gccountymi.maps.arcgis.com'), 'd600a66fe6ac48a098cb94a36d97a48b', 4, ['TOT_PRJ_COST'], false);

for(var a in featureDataPoint){
    feat_arr[i] = {attributes: {total_cost: a.TOT_PRJ_COST}}
    i++
}

for(var b in featureDataLine){
    feat_arr[i] = {attributes: {total_cost: b.TOT_PRJ_COST}}
    i++
}

var combinedDict = {
  fields: [{ name: "total_cost", type: "esriFieldTypeInteger"}],
  geometryType: "",
  features: feat_arr,
};

FeatureSet(Text(combinedDict))

jcarlson_0-1630606102844.png

By the way, I specified only the total cost attribute in the FeatureSet functions and explicitly stated false to exclude the geometry. That should help your expression's performance some.

- Josh Carlson
Kendall County GIS
KenKoleda
New Contributor II

This worked!  I did need to add two more fields to read them from the data source and then output to the featureset, but was able to figure that out from the example you provided!  Thanks!

- Genesee County GIS Department
0 Kudos
KenKoleda
New Contributor II

Hello, as it turned out the solution appears not to be 100% correct and I am at a loss to figure out why.

It seems that each array contains less features that the source featureclass and  the combined set has still fewer features.

For example, I have 3197 points.  immediately after created the 'featureDataPoint is shows 3095 -- as reported via a console message using the count() function.

The total number of the two layers combined starts at 7011 and in the arrays are 6855 and in the final "newSet" is 5303

Here is my current code:

// Write an expression that returns a FeatureSet.
// Documentation: https://arcg.is/3c419TD
// Samples: https://arcg.is/38SEWWz

var feat_arr = []

var i = 0

var featureDataPoint = FeatureSetByPortalItem(Portal('https://gccountymi.maps.arcgis.com'), '9396510de4514d27a344ad12dbecdbfa', 0, ['TOT_PRJ_CO','BNDRY_DESC','JOB_OPERT_'], false);

console(count(featureDataPoint))

var featureDataLine = FeatureSetByPortalItem(Portal('https://gccountymi.maps.arcgis.com'), '9396510de4514d27a344ad12dbecdbfa', 1, ['TOT_PRJ_CO', 'BNDRY_DESC','JOB_OPERT_'], false);

console(count(featureDataLine))

for(var a in featureDataPoint){
feat_arr[i] = {attributes: {total_cost: a.TOT_PRJ_CO, mpo: a.BNDRY_DESC, status: a.JOB_OPERT_}}
i++
}

console(count(featureDataPoint))

for(var b in featureDataLine){
feat_arr[i] = {attributes: {total_cost: b.TOT_PRJ_CO, mpo: b.BNDRY_DESC, status: b.JOB_OPERT_}}
i++
}

console(count(featureDataLine))

var combinedDict = {
fields: [{ name: "total_cost", type: "esriFieldTypeInteger"},
{ name: "mpo", type: "esriFieldTypeString"},
{ name: "status", type: "esriFieldTypeString"}],
geometryType: "",
features: feat_arr,
};

var newSet = FeatureSet(Text(combinedDict))

console(count(newSet))

return newSet

 

Console messages showing the counts.

KenKoleda_0-1631221223596.png

 

- Genesee County GIS Department
0 Kudos
jcarlson
MVP Esteemed Contributor

Well, this is certainly strange. When I add console messages to my own expression, it returns the correct totals for the FeatureSets and layers, but the FeatureSet at the end is smaller.

jcarlson_3-1631223329813.png

I can't account for the different totals you're getting in your FeatureSets, but I did dig into why the FeatureSet has different outputs. Take a look here at the output, and you'll see that the ID columns (I added the variable i as an integer field for testing) skip some values. What's going on here?

jcarlson_4-1631223360520.png

We can see that 81-84 are missing, so I'll call up a few of them from feat_arr to see what their values are.

jcarlson_5-1631223661227.png

The culprit: floating point values. I didn't anticipate these based on a quick sample of the input data, but odds are when it hits those floats and tries inserting them into our defined integer field, it errors out and skips.

 

100% solutions (pick one):

  1. Round off the values before inserting them into the array, i.e., Round(a.TOT_PRJ_CO)
  2. Change the field to a floating point type

I like integers myself, so here's the output with a rounding function in the loop.

jcarlson_6-1631224122097.png

Again, I'm still not sure why your FeatureSets are reading out a different total. I even get the correct totals when including the additional fields.

- Josh Carlson
Kendall County GIS
KenKoleda
New Contributor II

Once again, you came to the rescue!  The code is now working 100% I believe.

We are in fact getting the correct record count.  It was my error thinking we were not.  The issue was that we have been trying to access a server that is super slow and intermittent.  I had copied the data to our AGO, but it was an older version because the other site is SO slow I would not even download both files yesterday.  The difference in the files account for the apparent different count. 

Now, we just gotta hope that the hosting entity gets their server straightened out so we can access it directly.

- Genesee County GIS Department
0 Kudos
RobertBorchert
Frequent Contributor III

We did this by creating a database view that combined our Primavera and GIS data.  It updates automatically 

0 Kudos