Skip To Content

SOE GetElevationData

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               xmlns:esri="http://www.esri.com/2008/ags"
               xmlns:layers="com.esri.ags.samples.layers.*"
               xmlns:tasks="com.esri.ags.samples.tasks.*"
               currentState="selectionState"
               pageTitle="Example - SOE GetElevationData">
    <!--
    Description:
    This sample demonstrates the programming patterns to create your own
    custom Task which extends BaseTask.  The sample calculates the elevation
    values within a user defined extent.  To use this sample: Select a mountain
    from the list of buttons, next activate the draw tool to sketch an area/region
    over the mountain surface, when the surface is generated you can change its
    transparency or mouse over the surface to get more information.

    It also demonstrates the extensibility of ArcGIS for Flex in using a custom
    layer to display the Elevation Data returned from the ElevationsSOE.

    Documentation:
    For more information, see the API documentation.
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/events/DrawEvent.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/events/DrawEvent.html#graphic
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/events/LocatorEvent.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tasks/BaseTask.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tasks/Locator.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tasks/supportClasses/AddressCandidate.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tasks/supportClasses/AddressToLocationsParameters.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tools/DrawTool.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tools/DrawTool.html#graphicsLayer
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tools/DrawTool.html#map
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tools/DrawTool.html#activate()
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tools/DrawTool.html#deactivate()
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tools/DrawTool.html#event:drawStart
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tools/DrawTool.html#event:drawEnd
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/utils/WebMercatorUtil.html

    http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/formatters/NumberFormatter.html

    http://sampleserver4.arcgisonline.com/ArcGIS/rest/services/Elevation/ESRI_Elevation_World/MapServer/exts/ElevationsSOE "Live service"
    http://blogs.esri.com/Dev/blogs/apl/archive/2010/10/07/Elevation-Server-Object-Extension.aspx "Blog article on SOE"
    http://resources.arcgis.com/gallery/file/arcobjects-net-api/details?entryID=87BEC705-1422-2418-34B5-308930DE323A "Source code for SOE"
    http://www.arcgis.com/home/item.html?id=b9d247c297f144459854751740f59f68 "FlexViewer SOE widgets"

    For more details on the World Geocoding Service follow the link below.
    http://geocode.arcgis.com/arcgis/index.html

    ArcGIS REST API documentation:
    http://sampleserver4.arcgisonline.com/ArcGIS/rest/services/Elevation/ESRI_Elevation_World/MapServer/exts/ElevationsSOE/ElevationLayers/1/GetElevationData

    ArcGIS for Server documentation:
    http://resources.arcgis.com/en/help/main/10.1/index.html#/What_is_a_server_object_extension/0154000004s5000000/
    http://resources.arcgis.com/en/help/main/10.1/index.html#/Steps_for_developing_and_deploying_a_server_object_extension/0154000004s7000000/
    http://resources.arcgis.com/en/help/main/10.1/index.html#/Alternatives_to_server_object_extensions/015400000528000000/

    This sample also uses the following files:
    com/esri/ags/samples/tasks/ElevationsSOETask.as
    com/esri/ags/samples/tasks/supportClasses/ElevationsSOEParameters.as
    com/esri/ags/samples/tasks/supportClasses/ElevationsSOEResult.as
    com/esri/ags/samples/tasks/supportClasses/InterpolatedRasterProperties.as
    com/esri/ags/samples/events/ElevationsSOEEvent.as
    com/esri/ags/samples/layers/ArcGISElevationsSOELayer.as
    -->

    <!-- STATES -->
    <s:states>
        <s:State name="selectionState"/>
        <s:State name="selectionProcessingState"/>
        <s:State name="drawingState"/>
        <s:State name="drawingProcessingState"/>
        <s:State name="resultsState"/>
    </s:states>

    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        @namespace mx "library://ns.adobe.com/flex/mx";
        s|Panel
        {
            backgroundColor: #C0C2B7;
            chromeColor: #9D7037;
        }
        s|ButtonBar
        {
            chromeColor: #AF8E56;
        }
        mx|ToolTip
        {
            font-size: 14;
            backgroundColor: #EEEEEE;
        }
    </fx:Style>

    <fx:Script>
        <![CDATA[
            import com.esri.ags.Graphic;
            import com.esri.ags.events.DrawEvent;
            import com.esri.ags.events.LocatorEvent;
            import com.esri.ags.geometry.Extent;
            import com.esri.ags.geometry.MapPoint;
            import com.esri.ags.geometry.Polygon;
            import com.esri.ags.samples.events.ElevationsSOEEvent;
            import com.esri.ags.samples.tasks.supportClasses.ElevationsSOEParameters;
            import com.esri.ags.samples.tasks.supportClasses.ElevationsSOEResult;
            import com.esri.ags.tasks.supportClasses.AddressCandidate;
            import com.esri.ags.tasks.supportClasses.AddressToLocationsParameters;
            import com.esri.ags.utils.WebMercatorUtil;

            import mx.controls.Alert;
            import mx.rpc.events.FaultEvent;

            import spark.events.IndexChangeEvent;

            []private var placeElevation:Number = 0.0;
            []private var placeResultDescription:String = "";

            protected function placeSelectedChangeHandler(event:IndexChangeEvent):void
            {
                var selectedItem:Object = ButtonBar(event.currentTarget).selectedItem as Object;
                if (selectedItem)
                {
                    var params:AddressToLocationsParameters = new AddressToLocationsParameters();
                    var place:Object = { SingleLine: selectedItem.data };
                    params.address = place;
                    params.outFields = [ 'Match_Addr' ];
                    placesLocator.addressToLocations(params);
                    currentState = 'selectionProcessingState';
                    setProgress("Locating " + selectedItem.data + "...", true);
                }
            }

            protected function placesLocator_addressToLocationsCompleteHandler(event:LocatorEvent):void
            {
                placesButtonBar.selectedIndex = -1;
                var placesResults:Array = event.addressCandidates as Array;
                if (placesResults[0])
                {
                    var placeCandidate:AddressCandidate = placesResults[0] as AddressCandidate;
                    placeResultDescription = placeCandidate.attributes["Match_Addr"];
                    var mapPoint:MapPoint = placeCandidate.location as MapPoint;
                    var webMercatorGeom:MapPoint = WebMercatorUtil.geographicToWebMercator(mapPoint) as MapPoint;
                    addPlace(webMercatorGeom, placeResultDescription);
                    map.level = 12;
                    map.centerAt(webMercatorGeom);
                    currentState = 'drawingState';
                }
            }

            protected function drawTypeSelectedChangeHandler(event:IndexChangeEvent):void
            {
                var selectedItem:Object = ButtonBar(event.currentTarget).selectedItem as Object;
                if (selectedItem)
                {
                    drawTool.activate(selectedItem.data);
                }
            }

            protected function drawTool_drawEndHandler(event:DrawEvent):void
            {
                drawTool.deactivate();
                drawingButtonBar.selectedIndex = -1;

                var elevationInterpolationArea:Extent;
                if (event.graphic.geometry is Extent)
                {
                    elevationInterpolationArea = event.graphic.geometry as Extent;
                }
                else if (event.graphic.geometry is Polygon) // drawing on multiple worlds, we take the first ring of the resulting Polygon
                {
                    var polygon:Polygon = event.graphic.geometry as Polygon;
                    var ring:Array = polygon.rings[0];
                    elevationInterpolationArea = new Extent(ring[0].x, ring[0].y, ring[2].x, ring[1].y, polygon.spatialReference);
                }
                var params:ElevationsSOEParameters = new ElevationsSOEParameters();
                params.extent = elevationInterpolationArea;
                //Ask for the most data we can get returned from the server, makes for a better surface (100 * 100 = 10,0000)
                //Requesting more than this will error: Requesting too much data; please reduce inputs so Rows * Columns = 10,000
                params.columns = 100;
                params.rows = 100;
                soeTask.executeGetElevationData(params);

                currentState = 'drawingProcessingState';
                setProgress("Calculating elevation values...", true);
            }

            protected function soeTask_executeCompleteHandler(event:ElevationsSOEEvent):void
            {
                drawGraphicsLayer.clear();
                var elevationResult:ElevationsSOEResult = event.elevationsSOEResult;

                var llXYGraphic:Graphic = new Graphic(new MapPoint(elevationResult.xCoordLLCenter, elevationResult.yCoordLLCenter, elevationResult.spatialReference), lowerLeftSymbol);
                llXYGraphic.toolTip = "Western (left) x-coordinate: " + numberFormatter.format(elevationResult.xCoordLLCenter) + "\nSouthern (bottom) y-coordinate: " + numberFormatter.format(elevationResult.yCoordLLCenter);
                drawGraphicsLayer.add(llXYGraphic);

                elevationsSOELayer.elevationResult = elevationResult;
                var tt:String = "Interpolated Raster Properties\nCell Size: " + numberFormatter.format(elevationResult.cellSizeH) + "\n" + numberFormatter.format(elevationResult.elevationData.length) + " elevation values used in this surface.";
                elevationsSOELayer.toolTip = tt;

                currentState = 'resultsState';
            }

            protected function esriService_faultHandler(event:FaultEvent):void
            {
                placesButtonBar.selectedIndex = -1;
                Alert.show("Error: " + event.fault.faultString, "Error code: " + event.fault.faultCode);
                currentState = 'selectionState';
            }

            protected function addPlace(value:MapPoint, description:String):void
            {
                map.defaultGraphicsLayer.clear();
                var gra:Graphic = new Graphic(value, elevationAtSymbol);
                gra.toolTip = description;
                map.defaultGraphicsLayer.add(gra);
            }

            protected function setProgress(value:String, visible:Boolean):void
            {
                if (progressBar)
                {
                    progressBar.visible = visible;
                    progressBar.label = value;
                }
            }

            protected function drawAnother_clickHandler(event:MouseEvent):void
            {
                drawGraphicsLayer.clear();
                elevationsSOELayer.clear();
                elevationsSOELayer.toolTip = "";
                currentState = 'drawingState';
            }

            protected function startOver_clickHandler(event:MouseEvent):void
            {
                map.defaultGraphicsLayer.clear();
                drawGraphicsLayer.clear();
                elevationsSOELayer.clear();
                elevationsSOELayer.toolTip = "";
                currentState = 'selectionState';
            }
        ]]>
    </fx:Script>

    <fx:Declarations>
        <esri:SimpleMarkerSymbol id="lowerLeftSymbol"
                                 alpha="0.7"
                                 color="0xCECECE"
                                 size="15"
                                 style="circle">
            <esri:outline>
                <esri:SimpleLineSymbol color="0x000000"/>
            </esri:outline>
        </esri:SimpleMarkerSymbol>
        <esri:SimpleFillSymbol id="drawFillColor"
                               alpha="0.7"
                               color="0x1B009F"
                               outline="{smsOutline}"/>
        <esri:DrawTool id="drawTool"
                       drawEnd="drawTool_drawEndHandler(event)"
                       fillSymbol="{drawFillColor}"
                       graphicsLayer="{drawGraphicsLayer}"
                       map="{map}"/>
        <esri:SimpleMarkerSymbol id="elevationAtSymbol"
                                 color="0xB5804E"
                                 outline="{smsOutline}"
                                 size="30"
                                 style="triangle"/>
        <esri:SimpleLineSymbol id="smsOutline"
                               width="1"
                               color="0x578DB8"
                               style="solid"/>
        <tasks:ElevationsSOETask id="soeTask"
                                 executeComplete="soeTask_executeCompleteHandler(event)"
                                 fault="esriService_faultHandler(event)"
                                 url="http://sampleserver4.arcgisonline.com/ArcGIS/rest/services/Elevation/ESRI_Elevation_World/MapServer/exts/ElevationsSOE/ElevationLayers/1"/>
        <esri:Locator id="placesLocator"
                      addressToLocationsComplete="placesLocator_addressToLocationsCompleteHandler(event)"
                      fault="esriService_faultHandler(event)"
                      url="http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer"/>
        <s:NumberFormatter id="numberFormatter"
                           decimalSeparator=""
                           fractionalDigits="2"/>
    </fx:Declarations>

    <s:controlBarContent>
        <s:RichText width="100%">
            This sample demonstrates the programming patterns to create your own
            custom Task which extends BaseTask.  The sample calculates the elevation
            values within a user defined extent.  To use this sample: Select a mountain
            from the list of buttons, next activate the draw tool to sketch an area/region
            over the mountain surface, when the surface is generated you can change its
            transparency or mouse over the surface to get more information.
        </s:RichText>
    </s:controlBarContent>

    <esri:Map id="map" wrapAround180="true">
        <esri:ArcGISTiledMapServiceLayer url="http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer"/>
        <!-- CUSTOM LAYER FOR ELEVATIONS SOE SERVICE -->
        <layers:ArcGISElevationsSOELayer id="elevationsSOELayer" alpha="{elevationDisplaySlider.value}"/>
        <esri:GraphicsLayer id="drawGraphicsLayer"/>
    </esri:Map>
    <s:Panel width="440" height="130"
             right="20" top="20"
             title="Get Elevation Data for a Surface">
        <s:layout>
            <s:VerticalLayout gap="10"
                              paddingBottom="7"
                              paddingLeft="10"
                              paddingRight="10"
                              paddingTop="7"/>
        </s:layout>
        <s:Group id="selectionState" includeIn="selectionState">
            <s:ButtonBar id="placesButtonBar" change="placeSelectedChangeHandler(event)">
                <s:ArrayList>
                    <fx:Object data="Mount St. Helens" label="Mount St. Helens"/>
                    <fx:Object data="Gunung Merapi" label="Mount Merapi"/>
                    <fx:Object data="Mount Pinatubo" label="Mount Pinatubo"/>
                    <fx:Object data="Kilauea Volcano" label="Kilauea Volcano"/>
                </s:ArrayList>
            </s:ButtonBar>
        </s:Group>
        <s:Group id="drawingState" includeIn="drawingState">
            <s:layout>
                <s:VerticalLayout gap="10"
                                  paddingBottom="7"
                                  paddingLeft="10"
                                  paddingRight="10"
                                  paddingTop="7"/>
            </s:layout>
            <s:Label id="placeResult"
                     width="100%"
                     fontSize="14"
                     text="{placeResultDescription}"
                     visible="{placeResultDescription != ''}"/>
            <s:ButtonBar id="drawingButtonBar" change="drawTypeSelectedChangeHandler(event)">
                <s:ArrayList>
                    <fx:Object data="{DrawTool.EXTENT}" label="Click to draw an Area / Region"/>
                </s:ArrayList>
            </s:ButtonBar>
        </s:Group>
        <s:Group id="results" includeIn="resultsState">
            <s:layout>
                <s:VerticalLayout gap="10"
                                  paddingBottom="7"
                                  paddingLeft="10"
                                  paddingRight="10"
                                  paddingTop="7"/>
            </s:layout>
            <s:HGroup>
                <s:Label text="Surface transparency:"/>
                <s:HSlider id="elevationDisplaySlider"
                           liveDragging="true"
                           maximum="1"
                           minimum="0"
                           stepSize="0.1"
                           value="0.4"/>
            </s:HGroup>
            <s:Button click="drawAnother_clickHandler(event)" label="Click to draw another area/region over the mountain."/>
            <s:Button click="startOver_clickHandler(event)" label="Click to Start Over"/>
        </s:Group>
        <mx:ProgressBar id="progressBar"
                        width="80%"
                        includeIn="selectionProcessingState,drawingProcessingState"
                        indeterminate="true"
                        visible="false"/>
    </s:Panel>
</s:Application>