Skip To Content

Query using GP result

<?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:components="com.esri.ags.samples.components.*"
               initialize="application_initializeHandler(event)"
               pageTitle="Chaining Geoprocessor tasks">
    <!--
    Description:
    This sample demonstrates how to send multiple service requests
    through different tasks supporting advanced analysis workflows.

    Attention:
    To use this sample locally, delete the following line 'proxyURL="https://developers.arcgis.com/sproxy/"'
    from the '<esri:Geoprocessor id="gp"' task in the Declarations section.
    Note: Requires an ArcGIS Online Organizational subscription.

    The sample first issues a request to a geoprocessing service to
    calculate a 2 minute drive time around the click location, and then
    issues a second request to a census service using the drive time
    area/polygon from the first request to query the census blocks and
    calculate the total population.

    1. Click on map to start a DriveTime GP for that point
    2. When GP completed, draw the drivetimes as well as query for block groups with population data.
    3. When query completed, sum up the population

    Note:
    One of the most important things to notice when publishing your geoprocessing service is to notice
    the "Execution mode" in the parameters setting.  The execution mode will be either
    "Synchronous" or "Asynchronous".  When a service is set to synchronous, the client waits for the task
    to finish.  An asynchronous task typically takes longer to execute, and the client must periodically
    ask the server if the task has finished and, if it has finished, get the result.  In the ArcGIS API for Flex,
    if your service is "Synchronous" you will call the "gp.execute()" method or "gp.submitJob()" method
    if your service is "Asynchronous".  Another important item to observe is the parameter names and types, you
    can find out the name, case-sensitivity, and data type through exploring the service in the ArcGIS REST
    Services Directory.

    Documentation:
    For more information, see the API documentation.
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/FeatureSet.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/Graphic.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/events/GeoprocessorEvent.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/events/QueryEvent.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tasks/Geoprocessor.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tasks/Geoprocessor.html#submitJob()
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tasks/QueryTask.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tasks/QueryTask.html#execute()
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tasks/supportClasses/ParameterValue.html
    https://developers.arcgis.com/en/flex/api-reference/com/esri/ags/tasks/supportClasses/Query.html

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

    ArcGIS REST API documentation:
    http://resources.arcgis.com/en/help/rest/apiref/gpserver.html
    http://resources.arcgis.com/en/help/rest/apiref/gptask.html
    http://resources.arcgis.com/en/help/rest/apiref/gpexecute.html
    http://resources.arcgis.com/en/help/rest/apiref/gpsubmit.html
    http://resources.arcgis.com/en/help/rest/apiref/gpjob.html

    ArcGIS for Server documentation:
    What is a geoprocessing service?
    http://resources.arcgis.com/en/help/main/10.1/#/What_is_a_geoprocessing_service/0154000004v5000000/
    A quick tour of authoring and sharing geoprocessing services
    http://resources.arcgis.com/en/help/main/10.1/#/A_quick_tour_of_authoring_and_sharing_geoprocessing_services/01540000054n000000/
    Essential vocabulary for geoprocessing services
    http://resources.arcgis.com/en/help/main/10.1/#/Essential_vocabulary_for_geoprocessing_services/0154000004v2000000/
    Geoprocessing service settings: Parameters
    http://resources.arcgis.com/en/help/main/10.1/index.html#/Parameters/01540000054v000000/

    ArcGIS for Desktop documentation:
    A quick tour of creating custom tools
    http://resources.arcgis.com/en/help/main/10.1/index.html#//001500000001000000
    A quick tour of creating tools with ModelBuilder
    http://resources.arcgis.com/en/help/main/10.1/index.html#/A_quick_tour_of_creating_tools_with_ModelBuilder/00150000001t000000/
    A quick tour of creating tools with Python
    http://resources.arcgis.com/en/help/main/10.1/index.html#/A_quick_tour_of_creating_tools_with_Python/00150000002q000000/

    ArcGIS Network Analyst:
    Service Area Analysis
    http://resources.arcgis.com/en/help/arcgis-rest-api/#/Service_Area_service_with_asynchronous_execution/02r3000000n0000000/
    http://logistics.arcgis.com/arcgis/rest/directories/arcgisoutput/World/ServiceAreas_GPServer/World_ServiceAreas/GenerateServiceAreas.htm
    -->

    <fx:Script>
        <![CDATA[
            import com.esri.ags.FeatureSet;
            import com.esri.ags.Graphic;
            import com.esri.ags.components.IdentityManager;
            import com.esri.ags.events.GeoprocessorEvent;
            import com.esri.ags.events.MapMouseEvent;
            import com.esri.ags.events.QueryEvent;
            import com.esri.ags.geometry.MapPoint;
            import com.esri.ags.symbols.SimpleFillSymbol;
            import com.esri.ags.symbols.SimpleLineSymbol;
            import com.esri.ags.symbols.SimpleMarkerSymbol;
            import com.esri.ags.tasks.supportClasses.JobInfo;

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

            private var gpPending:Boolean = false;

            protected function application_initializeHandler(event:FlexEvent):void
            {
                IdentityManager.instance.enabled = true;
            }

            private function myMap_mapClickHandler(event:MapMouseEvent):void
            {
                if (gpPending)
                {
                    Alert.show("Please be patient while we determine your first analysis", "Drive Time");
                    return; // a new gp request has been started
                }
                myMap.defaultGraphicsLayer.clear();
                var mapPoint:MapPoint = event.mapPoint;
                var graphic:Graphic = new Graphic(mapPoint);
                graphic.symbol = new SimpleMarkerSymbol("cross", 10, 0, 1, 0, 0, 0, new SimpleLineSymbol("solid", 0, 1, 2));
                myMap.defaultGraphicsLayer.add(graphic);
                var featureSet:FeatureSet = new FeatureSet();
                featureSet.features = [ graphic ];
                var params:Object =
                    {
                        "Facilities": featureSet,
                        "Break_Values": "2",
                        "Break_Units": "Minutes"
                    };
                gp.submitJob(params);
                gpPending = true;
                progressMessage.showMessage("Determining 2 minute drive time", true);
            }

            protected function gp_faultHandler(event:FaultEvent):void
            {
                Alert.show("This service request an ArcGIS Organizational subscription\nYou can also try the example on the ArcGIS API for Flex Resource Center"
                           + event.fault.faultString, "Drive Time");
                progressMessage.clearMessage();
            }

            protected function gp_jobCompleteHandler(event:GeoprocessorEvent):void
            {
                if (event.jobInfo.jobStatus == JobInfo.STATUS_SUCCEEDED)
                {
                    var jobID:String = event.jobInfo.jobId;
                    progressMessage.setMessage("Retrieving drive time");
                    gp.getResultData(gp.submitJobLastResult.jobId, "Service_Areas");
                }
                else
                {
                    Alert.show(event.jobInfo.jobStatus, "Analysis Status");
                }
            }

            protected function gp_getResultDataCompleteHandler(event:GeoprocessorEvent):void
            {
                /* The parameterValue property is set when the type is getResultDataComplete,
                 * getInputComplete or getResultImageComplete.
                 */
                if (event.parameterValue)
                {
                    progressMessage.showMessage("Calculating population within drive time", true);
                    var serviceAreas:FeatureSet = event.parameterValue.value as FeatureSet;
                    var feature:Graphic = serviceAreas.features[0];
                    var symbol:SimpleFillSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, 0xCA0013, 0.1);
                    symbol.outline = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, 0xB3B3B3, 1.0, 2);
                    feature.symbol = symbol;
                    myMap.defaultGraphicsLayer.add(feature);
                    query.geometry = feature.geometry;
                    queryTask.execute(query);
                    //Note: the zoomTo method was added at version 3.1
                    myMap.zoomTo(feature.geometry.extent);
                }
                else
                {
                    Alert.show("Service did not return any results", "Drive Time");
                    gpPending = false;
                }
            }

            private function queryTask_executeCompleteHandler(event:QueryEvent):void
            {
                var fset:FeatureSet = event.featureSet;
                if (fset.features.length > 0)
                {
                    var symbol:SimpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_SQUARE, 8, 0xFFFF00, 0.5);
                    symbol.outline = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, 0xB3B3B3);

                    for each (var graphic:Graphic in fset.features)
                    {
                        graphic.symbol = symbol;
                        myMap.defaultGraphicsLayer.add(graphic);
                    }
                    var totalPopulation:Number = sumPopulation(fset);
                    messages.text = "Total population within the drive time area is " + numberFormatter.format(totalPopulation) + ".";
                }
                else
                {
                    messages.text = "We were unable to calculate the population within this region.";
                }
                progressMessage.clearMessage();
                gpPending = false;
            }

            private function sumPopulation(fset:FeatureSet):Number
            {
                var features:Array = fset.features;
                var popTotal:Number = 0;
                for each (var graphic:Graphic in features)
                {
                    popTotal += graphic.attributes.POP2000;
                }
                return popTotal;
            }
        ]]>
    </fx:Script>

    <fx:Declarations>
        <esri:Geoprocessor id="gp"
                           fault="gp_faultHandler(event)"
                           getResultDataComplete="gp_getResultDataCompleteHandler(event)"
                           jobComplete="gp_jobCompleteHandler(event)"
                           outSpatialReference="{myMap.spatialReference}"
                           proxyURL="https://developers.arcgis.com/sproxy/"
                           url="https://logistics.arcgis.com/arcgis/rest/services/World/ServiceAreas/GPServer/GenerateServiceAreas"/>

        <esri:QueryTask id="queryTask"
                        concurrency="last"
                        executeComplete="queryTask_executeCompleteHandler(event)"
                        showBusyCursor="true"
                        url="http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/0"/>

        <esri:Query id="query"
                    outSpatialReference="{myMap.spatialReference}"
                    returnGeometry="true">
            <esri:outFields>
                <fx:String>POP2000</fx:String>
                <fx:String>HOUSEHOLDS</fx:String>
                <fx:String>HSE_UNITS</fx:String>
                <fx:String>TRACT</fx:String>
                <fx:String>BLOCK</fx:String>
            </esri:outFields>
        </esri:Query>

        <s:NumberFormatter id="numberFormatter"/>
    </fx:Declarations>

    <s:controlBarLayout>
        <s:VerticalLayout gap="10"
                          paddingBottom="7"
                          paddingLeft="10"
                          paddingRight="10"
                          paddingTop="7"/>
    </s:controlBarLayout>
    <s:controlBarContent>
        <s:RichText width="100%">
            This sample demonstrates how to send multiple service requests
            through different tasks supporting advanced analysis workflows.
            The sample first issues a request to a geoprocessing service to
            calculate a 2 minute drive time around the click location, and then
            issues a second request to a census service using the drive time
            area/polygon from the first request to query the census blocks and
            calculate the total population. Click the map to begin.
        </s:RichText>
        <s:Label id="messages"
                 width="100%"
                 fontWeight="bold"/>
    </s:controlBarContent>

    <esri:Map id="myMap" mapClick="myMap_mapClickHandler(event)">
        <esri:extent>
            <esri:Extent xmin="-10605000" ymin="4712000" xmax="-10601000" ymax="4718000">
                <esri:SpatialReference wkid="102100"/>
            </esri:Extent>
        </esri:extent>
        <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"/>
    </esri:Map>

    <s:BorderContainer id="driveTime"
                       backgroundAlpha="0.5"
                       backgroundColor="0x353930"
                       borderColor="0x353930"
                       cornerRadius="5"
                       horizontalCenter="0"
                       verticalCenter="0"
                       visible="{progressMessage.visible}">
        <s:layout>
            <s:VerticalLayout horizontalAlign="center"
                              paddingBottom="5"
                              paddingLeft="5"
                              paddingRight="5"
                              paddingTop="5"/>
        </s:layout>
        <components:ProgressMessage id="progressMessage" textColor="0xE6E6E6"/>
    </s:BorderContainer>

    <s:BorderContainer id="Search"
                       width="250"
                       right="20" top="20"
                       backgroundAlpha="0.5"
                       backgroundColor="0x353930"
                       borderColor="0x353930"
                       cornerRadius="5">
        <s:layout>
            <s:HorizontalLayout horizontalAlign="center"
                                paddingBottom="5"
                                paddingLeft="5"
                                paddingRight="5"
                                paddingTop="5"/>
        </s:layout>

        <esri:Geocoder width="100%"
                       map="{myMap}"
                       prompt="Where do you want to go?"/>
    </s:BorderContainer>
</s:Application>