polygon feature class in WFS has two altitude fields (lower and upper). How can I extrude these into 3d in the javascript api?

1364
10
Jump to solution
10-03-2017 10:11 PM
FrankieEast
New Contributor III

I have many (640 or so) feature classes (polygon) that have lower and upper altitudes.  I can easily extrude polygons from the ground to a height in 3d using the javascript api, but have not found a way to do this using the lower altitude as the bottom rather than the ground.  This can be done in arc scene.  Can it be done in the javascript api?  I ask this because the data in the service is updated frequently (in some cases every five minutes).

0 Kudos
1 Solution

Accepted Solutions
RalucaNicola1
Esri Contributor

It seems our new 4.5 feature of driving elevation by an attribute comes right on time for your question. For the lower bound use an arcade expression in featureExpressionInfo. Here's a small sample: https://codepen.io/ralucanicola/pen/JrLqEm?editors=1000#0 

View solution in original post

10 Replies
RalucaNicola1
Esri Contributor

It seems our new 4.5 feature of driving elevation by an attribute comes right on time for your question. For the lower bound use an arcade expression in featureExpressionInfo. Here's a small sample: https://codepen.io/ralucanicola/pen/JrLqEm?editors=1000#0 

FrankieEast
New Contributor III

Perfect.  I was able to work from that.  The example used a single attribute both as the distance off the ground and as the size of the extrusion which wouldn't work for me, but did show me where and what I needed to change things to make it happen.  Changing to using the lower_alt as the distance above ground (and converting feet to meters) got them the right height off the ground..  Then subtraction of upper_alt - lower_alt to get the extrusion height and bingo! 

Can see it here: http://ibriefer.com/tfr.html

The restricted area in North Dakota is the most interesting.  In a 2d map it's not readily apparent that you can legally fly under that long leg of higher altitude restricted area.  You have to sleuth that from the text.  So, this is pretty cool to be able to visualize that.]

Thanks Raluca!

Frank

RalucaNicola1
Esri Contributor

Great, happy it helped! Interesting idea to map the flight restricted areas like that, thanks for sharing.

Yes, in my example I didn't have a second attribute. But the feature is really powerful, because you can then use Arcade and calculate a custom height based either on an initial z value or on one or several attributes.

0 Kudos
FrankieEast
New Contributor III

I love it.  I'm working on visualizing controlled airspace (upside down wedding cakes) and airmet/sigmets now.  The same code should work.  I'll post a link once I have those worked out so you can check them out.  I have another question, this one arcade-related.  Notice in the current example I linked the gray areas in California for the wildfires that are currently going on.  When entered as a hazard/disaster TFR these can contain multiple areas.  The type (tfr_type) for that would be 

Section_91_137_a_NN where NN is the area number.  

So, I'd like to set that up in the unique value renderer but if I put a list of values in I get many of the same entries in the legend, and also I'd have to guess and account for the number of areas.  e.g. if I account for up to 4 areas (I haven't seen one with that many yet) I could miss a fifth area if that ever occurs (with the way our climate is headed that's probably a when not an if).  Is there a way to regex or use Find:

uniqueValueInfos: [{
    value: "Section_99_7",
    symbol: ssiSym,
    label: "Special Security Instructions"
}, {
    value: Find("Section_91_137_a", $feature.TFR_TYPE,0), //catch any type beginning with Section_91_137_a
    symbol: hazardSym,
    label: "Disaster/Hazard Area"
}, {
    value: "Section_91_145",
    symbol: sportSym,
    label: "Aerial Demonstration / Sporting Event"
},

Find() is undefined when I try what's above.  I'll admit up front I'm just now needing to learn this so I could be missing something incredibly obvious.  But perhaps our going back and forth working this out (real life data scenarios) could yield some interesting examples that others could benefit from.  I could modify the data load in python to trim the area numbers off the type to make it work, but if possible I'd rather not modify data just to help my visualization.

Another idea stemming from data that I have... extrusion from a lower polygon to a higher altitude one (ie the sides won't be perfectly vertical).  Think icing, thunderstorms, turbulence... I have polygons for these at various altitudes that I allow the user to visualize in 2d using an altitude slider.  As you slide up in altitude the polygon layer changes to what's appropriate.  It would be seriously cool to be able to extrude between these to create a 3d icing volume (should look like a cloud that disappears flat-tops once the atmosphere becomes rarefied enough to no longer support icing), or thunderstorms...

0 Kudos
RalucaNicola1
Esri Contributor

Leave the uniqueValueInfos as they are

uniqueValueInfos: [{
    value: "Section_99_7",
    symbol: ssiSym,
    label: "Special Security Instructions"
}, {
    value: "Section_91_137_a"
    symbol: hazardSym,
    label: "Disaster/Hazard Area"
}, {
    value: "Section_91_145",
    symbol: sportSym,
    label: "Aerial Demonstration / Sporting Event"
},

but instead of the renderer field add a valueExpression that will extract the type from the tfr_type columns. I'm not an expert in Arcade, so I've put together something like this:

var s = "Section_21_7_a_21";

var splitArray = Split(s, "_");
var typeArray = [];
for (var i in splitArray) {
    IIf(i < Count(splitArray) - 1, typeArray[i] = splitArray[i], null);
}
return Concatenate(typeArray, "_");

Kristian Ekenes do you know if there is a straightforward way to remove the last 2 characters from a string with Arcade? This seems like a workaround.

We currently don't support your last idea...volume visualization will come, but it's not on our priority list right now. I was trying to think of a workaround, but I guess you can't really connect the vertices if the 2 polygons are not the same?

KristianEkenes
Esri Regular Contributor

First of all, the IIF() function is used improperly. You shouldn't be assigning variable values in the second param. IIF() returns a value based on a conditional expression. I think this is what you would want:

typeArray[i] = IIf(i < Count(splitArray) - 1, splitArray[i], null);

do you know if there is a straightforward way to remove the last 2 characters from a string with Arcade?

This is the simplest way I could think of to improve the above expression:

var s = "Section_21_7_a_21";
var stringLength = Count(Split(s, ""));
Left(s, stringLength-2);‍‍‍‍‍‍‍‍‍

But this returns "Section_21_7_a_". Do you actually want the final underscore removed? In that case, you could modify it to: 

var s = "Section_21_7_a_21";
var stringLength = Count(Split(s, ""));
Left(s, stringLength-3);‍‍‍‍‍‍‍‍‍

Is that what you're looking for? I tested this in the playground and it seems to work.

KristianEkenes
Esri Regular Contributor

This can actually be simplified even further:

var s = "Section_21_7_a_21";
Left(s, Count(s)-3);

The doc doesn't indicate that Count() takes a string input though, so we'll need to update that.

FrankieEast
New Contributor III

I'm experiencing drawing issues with larger extruded areas.  Thought you might like to see.

I'm trying to extrude sigmets into 3d.  (http://www.ibriefer.com/map/sigmets.html) Pretty much the same code from extruding the TFR areas.  But the sigmet areas are much larger seem to be drawing underground even though their altitudes are well above.  It appears to be extruding straight up and flat, if that makes sense, even though extruding from one altitude to another should curve along with the curve of the earth's surface.  

If you can see anything obvious that I'm missing I'm all ears.

0 Kudos
RalucaNicola1
Esri Contributor

There's nothing obvious that you are missing, it's a known issue... Only the vertices get information about how they should be aligned to the ground. We can't tell where the center of the polygon should be placed because there's no geometry there. Therefore polygons that spread along the globe will have their inner parts sunk into the ground. 

One thing you can do is use a local scene? that way the center of the polygon won't be underground because of the earth curvature.

I noticed that the polygons paths (the margins) are also sinking. That one you can fix by densifying the path using geometryEngine. Here's an example on how to do that client side on a line so that it follows the terrain: Edit fiddle - JSFiddle  You could apply it to polygons as well.

0 Kudos