Skip To Content

Drive times

<?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:esri="http://www.esri.com/2008/ags"
               xmlns:components="com.esri.ags.samples.components.*"
               initialize="application_initializeHandler(event)"
               pageTitle="Service Area">
    <!--
    Description:
    This sample demonstrates how you can use an ArcGIS Online geoprocessing service
    to determines network service areas around facilities, specifically service area analysis.

    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.

    This sample is setup so that computeServiceArea function is called
    when the map is clicked.
    <esri:Map click="computeServiceArea(event)">

    The computeServiceArea function sends a request to a GP task to create the geometries for the different drive times
    The return drivetime features are used as the graphicProvider for a graphics layer:
    graphicsLayer.graphicProvider = fs.features;

    The graphics layer uses  UniqueValueRenderer to draw the drive times in different colors
    <esri:GraphicsLayer id="graphicsLayer" renderer="{uniqueValueRenderer}"/>
    The uniqueValueRenderer uses the "ToBreak" attributes, which is returned by the GP task,
    to draw different symbols based on drive time.

    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/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/supportClasses/ParameterValue.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.geometry.MapPoint;
            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 driveTimes:String = "1 2 3";
            private var driveTimeUnits:Array = [ "Seconds", "Minutes", "Hours", "Days",
                                                 "Meters", "Kilometers", "Feet", "Yards",
                                                 "Miles", "Nautical Miles" ];

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

            private function computeServiceArea(mapPoint:MapPoint):void
            {
                graphicsLayer.clear();

                var graphic:Graphic = new Graphic(mapPoint);
                graphic.symbol = new SimpleMarkerSymbol("cross", 10, 0, 1, 0, 0, 0, new SimpleLineSymbol("solid", 0, 1, 2));
                graphic.attributes = { Name: "My Facility" };

                graphicsLayer.add(graphic);

                var featureSet:FeatureSet = new FeatureSet([ graphic ]);

                var params:Object =
                    {
                        "Facilities": featureSet,
                        "Break_Values": driveTimes,
                        "Break_Units": driveTimeUnits[1]
                    };

                gp.submitJob(params);
            }

            private function myMap_mapClickHandler(event:MapMouseEvent):void
            {
                progressMessage.showMessage("Determining drive times", true);
                computeServiceArea(event.mapPoint);
            }

            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 Message");
                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 times");
                    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)
                {
                    var serviceAreas:FeatureSet = event.parameterValue.value as FeatureSet;
                    graphicsLayer.graphicProvider = serviceAreas.features;
                    //Note: the zoomTo method was added at version 3.1
                    myMap.zoomTo(serviceAreas.features[0].geometry.extent);
                    progressMessage.clearMessage();
                }
                else
                {
                    Alert.show("Service did not return any results", "Drive times message");
                }
            }
        ]]>
    </fx:Script>

    <fx:Declarations>
        <esri:SimpleFillSymbol id="rFill"
                               alpha="0.5"
                               color="0xCA0013">
            <esri:SimpleLineSymbol color="0xB3B3B3"/>
        </esri:SimpleFillSymbol>
        <esri:SimpleFillSymbol id="gFill"
                               alpha="0.5"
                               color="0x008000">
            <esri:SimpleLineSymbol color="0xB3B3B3"/>
        </esri:SimpleFillSymbol>
        <esri:SimpleFillSymbol id="bFill"
                               alpha="0.5"
                               color="0x0080FF">
            <esri:SimpleLineSymbol color="0xB3B3B3"/>
        </esri:SimpleFillSymbol>

        <esri:UniqueValueRenderer id="uniqueValueRenderer" field="ToBreak">
            <esri:UniqueValueInfo symbol="{rFill}" value="1"/>
            <esri:UniqueValueInfo symbol="{gFill}" value="2"/>
            <esri:UniqueValueInfo symbol="{bFill}" value="3"/>
        </esri:UniqueValueRenderer>

        <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"/>
    </fx:Declarations>

    <s:controlBarContent>
        <s:RichText width="100%">
            This sample demonstrates how you can use an ArcGIS Online geoprocessing service 
            to determines network service areas around facilities, specifically service area analysis.
            Click anywhere on the map to calculate a 1, 2, and 3 minute drive time from the click location.
        </s:RichText>
    </s:controlBarContent>

    <esri:Map id="myMap" mapClick="myMap_mapClickHandler(event)">
        <esri:extent>
            <esri:WebMercatorExtent minlon="-122.515953" minlat="37.160194" maxlon="-121.595848" maxlat="37.704346"/>
        </esri:extent>
        <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"/>
        <esri:GraphicsLayer id="graphicsLayer" renderer="{uniqueValueRenderer}"/>
    </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>