Extrude Elevation Layer in Local Scene 4.4?

1340
7
Jump to solution
08-31-2017 05:13 AM
RichardReinicke
Occasional Contributor II

Hello,

I was wondering if there`s a way to extrude a 3d surface in the Esri JavaScript API 4.4 to a specific height or maybe another surface. This was a very vommon task in good old ArcScene and it can be very helpful to create a 3d body from a 3d surface.

Actually I have a local scene with a custom Elevation Layer and Topographic Map. That looks as follows:

Now I would like to visualize the scene as a block scene so not only a surface but more like a block cutted out of the landscape to give the scene so more plasticity. Is this possible with build in functionality?

Otherwise I would try to construct sides and border as single graphics and add them to the scene.

Any help is very appreciated!

Richard

0 Kudos
1 Solution

Accepted Solutions
ThomasSolow
Occasional Contributor III

That's similar to the approach I'm using.  Try shifting the the "bottom" x and y values by a very small amount, something like this: 

// assuming your SR uses meters
polygonPointArray.push([xmax - 0.0001, ymin - 0.0001, 0]);
polygonPointArray.push([xmin - 0.0001, ymin - 0.0001, 0]);‍‍‍‍‍

Polygons aren't filled properly if they're perfectly "vertical."

I just deleted my sample by accident, but it was drawing for 2/4 sides of the scene. The other two sides weren't drawing probably due to incorrect polygon winding.

View solution in original post

0 Kudos
7 Replies
ThomasSolow
Occasional Contributor III

I'm not aware of any built in way to do this but I think it's a good idea.

I'll give some thought to how you might be able to do this yourself and post a sample if I can figure something out.

0 Kudos
RichardReinicke
Occasional Contributor II

Thank you Thomas, that would be great. I was now able to get the necessary points from my underlying ElevationService to construct a side polygon this way:

var url = "http://ripsraster.lubw.bwl.de/arcgis/rest/services/Imageservices/

   DGM025_cache_3D/ImageServer/getSamples";

var options = {
   query: {
      geometry: '{"paths" : [ [ [3450000, 5400000], [3455000, 5400000] ] ],

                  "spatialReference" : {"wkid" : 31463}}',
      geometryType: 'esriGeometryPolyline',
      returnFirstValueOnly: false,
      sampleDistance: stepSize,
      f: 'pjson'
   },
   responseType: 'json'
};

esriRequest(url, options).then(function(response){
   var polygonPointArray = [];
   for (var i = 0; i < response.data.samples.length; i++) {
      polygonPointArray.push(

         [xmin + (i * stepSize),

         ymin,

         parseFloat(response.data.samples.value)]);
   }
   polygonPointArray.push([xmax, ymin, 0]);
   polygonPointArray.push([xmin, ymin, 0]);
   polygonPointArray.push([xmin, ymin, parseFloat(response.data.samples[0].value)]);

      // This constuctor with sr is necessary due to special coordinate system
   var polygon = new Polygon({
      rings: polygonPointArray,
      spatialReference: {
         wkid: 31463
      }
   });

   var fs = new SimpleFillSymbol({
      color: [227, 139, 79, 0.8],
      outline: {
         color: [255, 255, 255],
         width: 1
      }
   });

  

   var polygonGraphic = new Graphic({
     geometry: polygon,
     symbol: fs
   });

   graphicsLayer.add(polygonGraphic);

});

But it ends with a strange symbol behaviour, outline is drown but fill is missing!

A similar behaviour was described here but never really cleared:
SimpleFillSymbol style does not work 

In my case I need it in a SceenView and it works in this example:
Add Graphics to a SceneView - 4.4 

maybe related to local scene? I've no clue.

0 Kudos
ThomasSolow
Occasional Contributor III

That's similar to the approach I'm using.  Try shifting the the "bottom" x and y values by a very small amount, something like this: 

// assuming your SR uses meters
polygonPointArray.push([xmax - 0.0001, ymin - 0.0001, 0]);
polygonPointArray.push([xmin - 0.0001, ymin - 0.0001, 0]);‍‍‍‍‍

Polygons aren't filled properly if they're perfectly "vertical."

I just deleted my sample by accident, but it was drawing for 2/4 sides of the scene. The other two sides weren't drawing probably due to incorrect polygon winding.

0 Kudos
ThomasSolow
Occasional Contributor III

Okay, here's a sample: https://jsbin.com/qosutebuyi/edit?html,output 

I couldn't get the getSample request to work for the world elevation service so I queried the elevation in the client.  I had to increment the "bottom" of each edge so it isn't directly under the top.

Two of the polygons are still drawing incorrectly in that sample: you can see the fill is off by looking at the top.  I think this is a winding issue, those rings may be wound incorrectly.  I'll keep playing with it.

0 Kudos
ThomasSolow
Occasional Contributor III

Here's an updated sample that fixes the winding issues and uses the elevationLayer.queryElevation method rather than a client-side query: rather JS Bin - Collaborative JavaScript Debugging

0 Kudos
RichardReinicke
Occasional Contributor II

Hello Thomas,

thank you very much for your examples and effort. Your solution worked perfectly for me. I had to make a slight change because it seems to triangulate the side polygons to the lower corner which in case of a relatively flat block results in some artifacts on top.

So I wrote the triangles on my own as rings inside the sidePolygon. Using your code I add a second loop over the topRing vertices and add two triangles for each pair to fill the space to the bottom.

The result looks as follows:

Thank you very much for your help. I'll close the question and mark your answer as solution .

I'll publish  a new question related to the example. Maybe you can help me there again.

0 Kudos
ThomasSolow
Occasional Contributor III

Cool, looks great.

I've been meaning to continue looking into why the polygons are being drawn incorrectly here.  My understanding is that the rings need to be wound clockwise to be filled (holes are counter clockwise), and in situations like this you can view a ring "from above" to determine its winding.

That means the winding needs to be different depending on which direction the "bottom half" is offset from the "top half."  Hope to get a chance to keep playing with this at some point.