Showing attributes

1431
11
07-23-2022 06:51 AM
MazenTalaat
New Contributor III

Hello,

Is there a way to select an object and show its attributes?

Thanks in advance.

0 Kudos
11 Replies
Matt_Nelson
Esri Contributor

Hi Mazen, did you see the ArcGIS Hit test sample in our plugin? That shows you how to show the Object ID. After that you can reference our Feature Layer sample in the samples repo to see how to query additional information from the Feature Service's rest end point

0 Kudos
MazenTalaat
New Contributor III

Hello Matt,

Thanks for your reply, I did try the ArcGIS Hit test sample and got the featureId but it is different from Object ID. (screenshots 1 and 2)
I also noticed that the featureId changes depending on the number of objects seen by the camera. (screenshots 2 and 3)

Did I misunderstand something?

Regards.

0 Kudos
Matt_Nelson
Esri Contributor

So what you are seeing is that the feature ID is different based off the LOD that we are showing. In other words this is different than the Object ID. 

0 Kudos
MazenTalaat
New Contributor III

From what I understand, ArcGIS Hit test sample shows the featureId which is based off the LOD and the Feature Layer sample returns all the features with their attributes.

So how can I relate between the clicked object and its attributes without having the Object ID?
Maybe by comparing the latitude and longitude of the hit object?

0 Kudos
Matt_Nelson
Esri Contributor

Hi Mazen,

Haven't forgot about this question. So there was actually a bug where we were returning the FeatureIndex not the FeatureID in this result. The next release will contain this fix. IF you need it now I can recommend updating the function to be this 

public Physics.ArcGISRaycastHit GetArcGISRaycastHit(RaycastHit raycastHit)
{
Physics.ArcGISRaycastHit output;
output.featureId = -1;
output.featureIndex = -1;
output.layer = null;

var arcGISRendererComponent = rendererGO.GetComponent<ArcGISRendererComponent>();

if (raycastHit.collider != null && arcGISRendererComponent != null)
{
var sceneComponent = arcGISRendererComponent.GetSceneComponentByGameObject(raycastHit.collider.gameObject);

if (sceneComponent != null)
{
output.featureIndex = Physics.RaycastHelpers.GetFeatureIndexByTriangleIndex(raycastHit.collider.gameObject, raycastHit.triangleIndex);
output.layer = View.Map?.FindLayerById(sceneComponent.LayerId);

if (sceneComponent.Material.NativeMaterial.HasTexture("_FeatureIds"))
{
// gets the feature ID
var featureIds = (Texture2D)sceneComponent.Material.NativeMaterial.GetTexture("_FeatureIds");

var width = featureIds.width;
int y = (int)Mathf.Floor(output.featureIndex / width);
int x = output.featureIndex - y * width;

var color = featureIds.GetPixel(x, y);
var scaledColor = new Vector4(255f * color.r, 255f * color.g, 255f * color.b, 255f * color.a);
var shift = new Vector4(1, 0x100, 0x10000, 0x1000000);
scaledColor.Scale(shift);

output.featureId = (int)(scaledColor.x + scaledColor.y + scaledColor.z + scaledColor.w);
}
}
}

return output;
}


You will still have one more issue though, with that being the difference between some SceneServers. Some have an associated FeatureLayer resource which you can just use the query operation on. However if your SceneServer contains cached attributes it is significantly more complicated. 

If you share the service you are using I can help identify what it is.

IF it ends up being a cached service I can try to explain how you can use the AttributeProcessor to store all the attributes you need in a map for your later use. But we will be creating a better solution for this as well so I'll hold off on explaining this unless we end up confirming you are working with a cached SceneServer

0 Kudos
MazenTalaat
New Contributor III

Hello Matt,

Thank you for your support, I will give it a try.

Regards.

0 Kudos
MazenTalaat
New Contributor III

Hello again,

I tried updating the function but kept getting errors because featureIndex wasn't defined, so my approach is as follows:

ArcGIS Pro side:
* I uploaded a Scene Layer to show the 3D objects and Feature Layer to use the query operation on.
* The Feature Layer has some attributes like name, lon and lat.

Unity side:

1. I added the 3D layer to the scene and did the query operation while adding each feature attributes to a list.
2. When clicking a 3D object, I compare its location(lon, lat) with the location(lon, lat) in the list.
3. If the condition is true, I can break and get the rest of the attributes.

I still have one more issue, I can't get the location of the 3D object to be exactly the same as in the Feature layer every time so the comparison sometimes returns false in all iterations.

Here is how I get the location for the 3D object what I do:
I tried getting the ArcGISLocationComponent but it returns null, so I got the HPTransform.UniversePosition of the 3D object then converted it to ArcGISPoint by using arcGISMapComponent.View.WorldToGeographic( )

Regards.

0 Kudos
dun82
by
New Contributor II

We get the featureId from v1.1.0 but is there a way to retrieve the attribute info from a 3DObject scene layer?

I searched the REST API but could not figure out a way to query this piece of info from a scene layer. 

Tags (2)
0 Kudos
MazenTalaat
New Contributor III

Hello dun82,

Matt mentioned using the AttributeProcessor to store all the attributes, I tried to do that but I could only read string data.

0 Kudos