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
Solved! Go to Solution.
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))
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.
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.
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?
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.
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.
I like integers myself, so here's the output with a rounding function in the loop.
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.
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.
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.
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))
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.
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!
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.
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.
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?
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.
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.
I like integers myself, so here's the output with a rounding function in the loop.
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.
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.
We did this by creating a database view that combined our Primavera and GIS data. It updates automatically