Select to view content in your preferred language

Feature layer rendering

1081
6
09-08-2022 03:27 AM
alex_p
by
Emerging Contributor

From my understanding feature layers aren't supported yet in the SDK, is this correct?

Essentially, I'm trying to receive a feature layer (via the REST API) which is all straightforward.

Then I want to take the geometry from the feature layer (e.g. points, polylines, polygons etc) and render it in Unity.

I can see the geometry documentation lists operations to store and manipulate this data, but I don't see anything regarding the Maps SDK rendering it in Unity. I was hoping I could point the Map SDK's layer manager at a feature layer, it would in turn parse the data and then draw the geometry in Unity.

Any information about this would be great. Thanks.

0 Kudos
6 Replies
coryeicher
Frequent Contributor

Check out this sample if you have not already

https://github.com/Esri/arcgis-maps-sdk-unity-samples/tree/main/samples_project/Assets/SampleViewer/...

CORY EICHER
www.eichcorp.com
cory@eichcorp.com
0 Kudos
alex_p
by
Emerging Contributor

Hi Cory,

Yep, I've looked through this sample.

The sample receives a feature layer and uses the point attribute (x, y) to instantiate a stadium prefab at that point. Additionally it grabs meta data (attributes) from the feature layer to use (e.g. stadium name.) However, it doesn't do anything with geometry data commonly found in feature layers.

What I'm hoping the Maps SDK can do (if it can't do it already) is to read the geometry of a feature layer and then translate their geometry data to Unity's mesh format and get Unity to render it out-of-the-box.

For instance:

  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": 1,
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [
            -3.41770078167651,
            55.9958294387919
          ],
          [
            -3.42366735136942,
            55.9895078115871
          ],
          [
            -3.42351237760985,
            55.9852929594802
          ],
          [
            -3.43965707686417,
            55.9860091004313
          ],

This "linestring" would be parsed by the maps SDK and then drawn as a mesh or linerenderer in Unity.

The same approach with polygons, multi-polygons or any other geometry ArcGIS provides.

0 Kudos
Matt_Nelson
Esri Alum

Hi Alex,

You are really close, what you can do is for each of those points that you want to be in a line create a GO and set the location component to be those values just like we are doing in the sample Cory mentioned.

The one difference for you, is that instead those GO's should be invisible and then you can create a Unity LineRenderer object and set all the points on the line to be from the invisible GO's.

So for example in pseudo code.
GameObject vertex = //invisible GO prefab with a location component

var location = vertex.GetComponent<ArcGISLocationComponent>();
location.Position = //values from Rest api
//repeat for each point in the line from the rest api

LineRender lr = new LineRender();

lr.point[i] = location.transform.position; //do this for each point in the line

This will render the line renderer where you want it.
There is one last thing you need to consider, the Unity LineRender gets distorted as the camera moves because we are rebasing the scene. You have 2 options
1. Remove the ArcGISRebaseComponent from the camera, this is fine in small scale scenes but won't work on a global scale
2. Look at the measurement and routing sample. We have logic in their to rebase a line renderer as the HPRoot changes.

0 Kudos
coryeicher
Frequent Contributor

Check out the logic starting at this line:

https://github.com/Esri/arcgis-maps-sdk-unity-samples/blob/main/samples_project/Assets/SampleViewer/...

double Longitude = feature.geometry.coordinates[0];
            double Latitude = feature.geometry.coordinates[1];

            ArcGISPoint Position = new ArcGISPoint(Longitude, Latitude, StadiumSpawnHeight, new ArcGISSpatialReference(FeatureSRWKID));

            var NewStadium = Instantiate(StadiumPrefab, this.transform);
            NewStadium.name = feature.properties.NAME;
            Stadiums.Add(NewStadium);
            NewStadium.SetActive(true);

            var LocationComponent = NewStadium.GetComponent<ArcGISLocationComponent>();
            LocationComponent.enabled = true;
            LocationComponent.Position = Position;

 

The sample code _is_ using the feature geometry (from the feature service response). It then creates an ArcGISPoint and goes on from there -- as you said -- to add a prefab at that point.

I haven't tried this, but when querying a feature service with line or polygon geometries, you should be able to use similar code, but create instead a new ArcGISPolyline or ArcGISPolygon. I understand what you are saying,  and I have a personal "knowledge gap" after this. I do not know how to render those geometry types.

Regardless, hope this helps get you further towards your solution.

CORY EICHER
www.eichcorp.com
cory@eichcorp.com
0 Kudos
alex_p
by
Emerging Contributor

You should be able to new up any geometry instance e.g. a polyline as found in the docs here

// define some map points (airports: LA, Chicago, Paris)
var laxPoint = new ArcGISPoint(-118.408, 33.943, ArcGISSpatialReferences.Wgs84);
var ordPoint = new ArcGISPoint(-87.905, 41.979, ArcGISSpatialReferences.Wgs84);
var orlyPoint = new ArcGISPoint(2.379, 48.723, ArcGISSpatialReferences.Wgs84);

// add the points to a collection
var stops = new ArcGISPoint[] { laxPoint, ordPoint, orlyPoint };

// create a new Polyline from the points
var myFlightPath = new Esri.GameEngine.Geometry.ArcGISPolyline(stops);

I guess what would be useful for me (and no doubt lots of other developers out there) is for the Maps SDK to include rendering functionality for these geometry classes too.

Ideally, 2 goals:

1) Add a feature layer to the map's layer manager. The Map SDK reads the layer, parses the geometry and draws it to screen. Much the same way that scene layers are handled in the SDK.

2) Given an ArcGIS geometry the ability for Unity to render it via the Maps SDK. For instance, you receive the feature data, either add it to a var polyline = new PolyLine(args) object or better yet, it automatically creates all these from the JSON payload and then you simply do polyline.Draw() or via a component new GameObject().AddComponent<ArcGISPolylineComponent>().Init(polyline) and given the polyline data it creates it within the Unity scene. Otherwise, the geometry classes (albeit super useful) purpose are just to store geometry data with some very clever utility functions, but no way to visualise them in Unity.

0 Kudos
MatildaOkuneva
New Contributor

I'm not sure if I understand your question correctly, but it sounds like you are trying to use the Maps SDK to render features from a feature layer in Unity. Unfortunately, at this time the Maps SDK does not support rendering feature layers in Unity. You may be able to find a third-party library that can do this for you, or alternatively you could create your own solution using the geometry operations listed in the documentation. Hope that helps! update on Technoajeet for more help.

0 Kudos