I am trying to build a .NET SOI that logs the username associated with each query, as well as the GlobalIds of all features contained in the response. The SOI works fine when the outputFormat is "json", however, the format used with many web clients is "pbf".
I managed to find the Esri/arcgis-pbf/tree/main/proto/FeatureCollection github repo and generate the FeatureCollection class to convert the byte[] output of IRESTRequestHandler.HandleRESTRequest to a JSON string using the following code:
byte[] originalResponse = restRequestHandler.HandleRESTRequest(Capabilities, resourceName, operationName, operationInput, outputFormat, requestProperties, out responseProperties);
string resultJSONStr = null;
if(outputFormat == "pbf") {
var featureCollection = FeatureCollectionPBuffer.Parser.ParseFrom(originalResponse);
resultJSONStr = JsonFormatter.Default.Format(featureCollection);
}
ESRI.Server.SOESupport.JsonObject resultJSON = new ESRI.Server.SOESupport.JsonObject(resultJSONStr);
However, the structure of this JsonObject is completely different than that of the one generated when the output format is json. It does not resemble an Esri feature collection at all.
Is anybody aware of a library to convert the PBF JsonObject into an array of features?
Solved! Go to Solution.
After much Googling and gnashing of teeth, I found Rowan Winsemius' arcgis-pfb-parser GitHub repo that implements a javascript PBF featurecollection parser/decoder.
I used Claude AI to convert this to C#, and with a bit of spit-polishing I got it to work. The C# files are in the attached zip file.
Usage Example:
byte[] originalResponse = restRequestHandler.HandleRESTRequest(Capabilities, resourceName, operationName, operationInput, outputFormat, requestProperties, out responseProperties);
if (outputFormat == "pbf")
{
var decodedPBF = new FeatureCollectionDecoder().Decode(originalResponse);
decodedPBF.FeatureCollection.Features.ToList().ForEach(feature =>
{
if (feature.Properties != null && feature.Properties.TryGetValue("GlobalID", out var globalIdValue) && globalIdValue != null)
{
_serverLog.LogMessage(ServerLogger.msgType.infoSimple, "HandleRESTRequest()", 200, "PBF: Feature GlobalId: " + globalIdValue.ToString());
}
});
}
Hope this helps someone.
After much Googling and gnashing of teeth, I found Rowan Winsemius' arcgis-pfb-parser GitHub repo that implements a javascript PBF featurecollection parser/decoder.
I used Claude AI to convert this to C#, and with a bit of spit-polishing I got it to work. The C# files are in the attached zip file.
Usage Example:
byte[] originalResponse = restRequestHandler.HandleRESTRequest(Capabilities, resourceName, operationName, operationInput, outputFormat, requestProperties, out responseProperties);
if (outputFormat == "pbf")
{
var decodedPBF = new FeatureCollectionDecoder().Decode(originalResponse);
decodedPBF.FeatureCollection.Features.ToList().ForEach(feature =>
{
if (feature.Properties != null && feature.Properties.TryGetValue("GlobalID", out var globalIdValue) && globalIdValue != null)
{
_serverLog.LogMessage(ServerLogger.msgType.infoSimple, "HandleRESTRequest()", 200, "PBF: Feature GlobalId: " + globalIdValue.ToString());
}
});
}
Hope this helps someone.