Hello,
Is there a way to select an object and show its attributes?
Thanks in advance.
Thanks Mazen, but can you link the string data with the feature ID?
Hello @MazenTalaat , could you please help me on how you used the AttributeProcessor ?
Thank you in advance
Hello again,
Thank you dun82 for sharing your code in the other thread!
Finally, I managed to process the attributes and show the data, here are the used functions to do so.
(OBJECTID can be processed as Int)
private void Setup3DAttributes(ArcGIS3DObjectSceneLayer Layer)
{
if (Layer == null)
{
return;
}
var layerAttributes = ArcGISImmutableArray<String>.CreateBuilder();
layerAttributes.Add("OBJECTID");
var renderAttributeDescriptions = ArcGISImmutableArray<Esri.GameEngine.Attributes.ArcGISVisualizationAttributeDescription>.CreateBuilder();
renderAttributeDescriptions.Add(new Esri.GameEngine.Attributes.ArcGISVisualizationAttributeDescription("IsBuildingOfInterest", Esri.GameEngine.Attributes.ArcGISVisualizationAttributeType.Float32));
attributeProcessor = new Esri.GameEngine.Attributes.ArcGISAttributeProcessor();
attributeProcessor.ProcessEvent += (ArcGISImmutableArray<Esri.GameEngine.Attributes.ArcGISAttribute> layerNodeAttributes, ArcGISImmutableArray<Esri.GameEngine.Attributes.ArcGISVisualizationAttribute> renderNodeAttributes) =>
{
var fidAttribute = layerNodeAttributes.At(0);
/* Choose a function to process the data depending on the type
ForEachInt64(fidAttribute, (Int64 element, Int32 index) =>
{
//save in a list or print
});
ForEachString(fidAttribute, (string element, Int32 index) =>
{
//save in a list or print
});
ForEachDouble(fidAttribute, (float element, Int32 index) =>
{
//save in a list or print
});
*/
};
Layer.SetAttributesToVisualize(layerAttributes.MoveToArray(), renderAttributeDescriptions.MoveToArray(), attributeProcessor);
}
private void ForEachString(Esri.GameEngine.Attributes.ArcGISAttribute attribute, Action<string, Int32> predicate)
{
unsafe
{
var buffer = attribute.Data;
var unsafePtr = NativeArrayUnsafeUtility.GetUnsafePtr(buffer);
var metadata = (int*)unsafePtr;
var count = metadata[0];
// First integer = number of string on this array
// Second integer = sum(strings length)
// Next N-values (N = value of index 0 ) = Length of each string
IntPtr stringPtr = (IntPtr)unsafePtr + (2 + count) * sizeof(int);
for (var i = 0; i < count; ++i)
{
string element = null;
// If the length of the string element is 0, it means the element is null
if (metadata[2 + i] > 0)
{
element = Marshal.PtrToStringAnsi(stringPtr, metadata[2 + i] - 1);
}
predicate(element, i);
stringPtr += metadata[2 + i];
}
}
}
void ForEachInt64(Esri.GameEngine.Attributes.ArcGISAttribute attribute, Action<Int64, Int32> predicate)
{
unsafe
{
var buffer = attribute.Data;
var unsafePtr = NativeArrayUnsafeUtility.GetUnsafePtr(buffer);
var metadata = (int*)unsafePtr;
var count = attribute.Data.Length/4;
for (var i = 0; i < count; ++i)
{
predicate((Int64)metadata[i], i);
}
}
}
void ForEachDouble(Esri.GameEngine.Attributes.ArcGISAttribute attribute, Action<float, Int32> predicate)
{
unsafe
{
var buffer = attribute.Data;
var unsafePtr = NativeArrayUnsafeUtility.GetUnsafePtr(buffer);
var metadata = (double*)unsafePtr;
var count = attribute.Data.Length / 8;
for (var i = 0; i < count; ++i)
{
predicate((float)metadata[i], i);
}
}
}
Hello MazenTalaat,
I also have a Unity project with ArcGIS layers and with a raycast i get a Feature ID (with the Hit test example). Now i want to make the attribuut values visible in a text field of that Feature. Is adding your code above enough to get this values?
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
var arcGISRaycastHit = arcGISMapComponent.GetArcGISRaycastHit(hit);
var layer = arcGISRaycastHit.layer;
var featureId = arcGISRaycastHit.featureId;
if (layer != null && featureId != -1)
{
featureText.text = featureId.ToString();
}
}
}
}