客户端数据动态渲染

更新:这个例子比之前的更贴切:http://resources.arcgis.com/en/help/flex-api/samples/index.html#/DynamicLayerInfo_JoinDataSource/01nq00000088000000/

ArcGIS Server 10.1+Flex API 3.0(至少Server10.1和3.0的API才行)客户端执行GP服务,对得到的数据进行渲染,并生成图例(颜色可自定义)。

1.客户端设置好相应参数,并绘图确定分析范围,调用GP服务。

2.对GP服务返回的结果进行渲染(用到了DetailsTask和GenerateRendererTask)。

  参考在线Samples:http://resources.arcgis.com/en/help/flex-api/samples/index.html#/Generate_renderers/01nq0000006z000000/

3.若觉得颜色不好看,改变图例颜色。

另:有些细节还模糊,写的有点乱,敬请指正。

效果图:

具体:

1.在客户端选择好相应参数,确定分析范围,此处设置为绘图结束后立即调用GP服务。

   在名为“inputsLayer”的GraphicsLayer上绘制,并将结果转为FeatureSet,因为FeatureSet是GP输入参数的格式要求,而且包含更多属性信息等。

   然后异步提交这些确定好的GP参数,调用GP服务,并对GP事件的状态进行监听,为后续流程进行做准备。

protected function drawTool_drawEndHandler(event:DrawEvent):void
            {
                // reset after finished drawing a feature
                map.addLayer(inputsLayer);
                graphic=event.graphic;
                inputsLayer.add(graphic);
                var featureSet:FeatureSet=new FeatureSet([graphic]);
                
                var params:Object=
                    {
                        //"SQL":"1=1",
                        "Selecting_Features":featureSet,
                        "Cellsize_":cellsize.value.toString(),//"0.008", 
                        "ValueField_":roadCoverField.selectedItem['label'].toString()

                    };
                GP.submitJob(params);           //提交参数,调用GP服务
                //map.addLayer(refreshAddLayer);
                GP.addEventListener(GeoprocessorEvent.STATUS_UPDATE,AddLayer);
                GP.addEventListener(FaultEvent.FAULT,FaultInfo);
                myDrawTool.deactivate();
                tbb.selectedIndex = -1;
                
            }

2.对GP服务结果进行渲染。

   之前对GP事件状态进行监听,若成功则执行AddLayer,即将结果图层添加上来。flag是做什么的呢?等会解释,它的作用是为了避免犯错。

   并执行已经声明好的DetailsTask,来获取该结果图层的相关属性信息,为渲染做准备。

   当然还要对detailsTask事件进行监听,如果已经得到结果图层的相关信息,则执行detailsTask_getAllDetailsCompleteHandler(其实detailsTask执行完毕后它会自动派发)。

   这时,渲染参数都搞定了,就可以执行渲染了, 即“generateRenderer()”,然后就可以将已经渲染成功的结果图层添加上来了,即“refreshAddLayer”。

   

//GP状态改变后派发事件,即添加更新后的GP结果地图
            protected function AddLayer(event:GeoprocessorEvent):void
            {
                if (event.jobInfo.jobStatus == JobInfo.STATUS_SUCCEEDED)
                {
                    flag_generateRenderer=true;     
                    dynamicLayerInfosArr = refreshAddLayer.createDynamicLayerInfosFromLayerInfos();
                    detailsTask.getAllDetails();
                    detailsTask.addEventListener(DetailsEvent.GET_ALL_DETAILS_COMPLETE,detailsTask_getAllDetailsCompleteHandler);
                    generateRenderer();
                    map.addLayer(refreshAddLayer);
                    //map.addEventListener(MapEvent.LAYER_ADD,Refresh);
                }
                else
                {
                    Alert.show(event.jobInfo.jobStatus);
                    //Alert.show("GP服务似乎遇到一点问题,赶快检查一下吧!");
                }
                
            }

之前声明好的两个Task:"DetailsTask"和"GenerateRendererTask"

 另:第一次用DetailsTask和GenerateRendererTask这两个东西,不是很了解,大致过程是这样的,detailsTask.getAllDetails()获取到动态图层的相应属性信息,就派发detailsTask_getAllDetailsCompleteHandler,根据目标图层获取分类方法及渲染参数,然后开始渲染。

<esri:DetailsTask id="detailsTask"
                          fault="esriService_faultHandler(event)"
                          getAllDetailsComplete="detailsTask_getAllDetailsCompleteHandler(event)"
                          url="http://192.168.210.114:6080/arcgis/rest/services/gptest/MapServer"/>
<esri:GenerateRendererTask id="generateRendererTask"
                          executeComplete="generateRendererTask_executeCompleteHandler(event)"
                          fault="esriService_faultHandler(event)" 
                          url="http://192.168.210.114:6080/arcgis/rest/services/gptest/MapServer/0"/>

detailsTask执行完毕即获取了结果图层的信息后,派发detailsTask_getAllDetailsCompleteHandler,通过它可以提交渲染参数,怎么这里也generateRendererTask.execute?有点疑惑。。。————之前由于直接复制在线sample代码留下来的,确实是重复了。

protected function detailsTask_getAllDetailsCompleteHandler(event:DetailsEvent):void
            {
                var details:AllDetails = event.allDetails;
                layerDetailsArr = details.layersDetails;
                var layerDetails:LayerDetails;
                for (var i:int = 0; i < layerDetailsArr.length; i++)
                {
                    
                    layerDetails = layerDetailsArr[i];
                    if (layerDetails.name == "Zoncover" )   //目标图层的图层名
                    {
                        
                        layerMapSource = DynamicLayerInfo(dynamicLayerInfosArr[i]).source as LayerMapSource;
                        generateRendererTask.source = layerMapSource;
                        classBreaksDefinition.breakCount = _breakCount;                    //分类级数,之前已设置,其实分类级数和方法也可以弄成客户端来选择
                        classBreaksDefinition.classificationField = _classificationField;               //目标图层的目标属性字段,用以分类,这里已经预设好了。
                        classBreaksDefinition.classificationMethod = ClassBreaksDefinition.CLASSIFY_QUANTILE;       //分类方法这里已经写死
                        classBreaksDefinition.colorRamp =colorRamp1;                                         //colorRamp1为预先设置好的色带参数。
                        generateRendererParams.classificationDefinition = classBreaksDefinition;
                        generateRendererTask.execute(generateRendererParams);
                    }
                }

执行渲染的函数generateRenderer(),colorRamp1是预先设好的色带参数。

    [Bindable]
    private var fromColorValue:uint=uint("0xF9F900");
     //private var fromColorValue:uint=uint(c1.colorField); 
    [Bindable]
    private var toColorValue:uint=uint("0xFF0000");
<esri:AlgorithmicColorRamp id="colorRamp1"
			  algorithm="esriHSVAlgorithm"
			  fromColor="{fromColorValue}"  
			  toColor="{toColorValue}"/>    
//符号渲染
            protected function generateRenderer():void
            {
                classBreaksDefinition.breakCount = 9;
                classBreaksDefinition.classificationMethod = _classificationMethod;
                classBreaksDefinition.classificationField = _classificationField; //在此也添加字段,看是否能解决第一次渲染找不到字段的问题
                generateRendererParams.classificationDefinition = classBreaksDefinition;
                classBreaksDefinition.colorRamp = colorRamp1;
                generateRendererTask.execute(generateRendererParams);
            }

渲染完毕后把图例加上来。

    protected function generateRendererTask_executeCompleteHandler(event:GenerateRendererEvent):void
            {
                var renderer:ClassBreaksRenderer = event.renderer as ClassBreaksRenderer;
                var layerDrawingOptions:LayerDrawingOptions = new LayerDrawingOptions();
                layerDrawingOptions.layerId = layerMapSource.mapLayerId; 
                
                layerDrawingOptions.renderer = renderer;
                refreshAddLayer.alpha = 0.7;
                var layerDrawingOptionsArr:Array = [layerDrawingOptions];
                refreshAddLayer.layerDrawingOptions = layerDrawingOptionsArr;
                legend.map=map;
                refreshAddLayer.name="图例";
                legend.layers = [refreshAddLayer];
                
            }

3.改变图例颜色,颜色选择用来Flex自带的ColorPicker控件

    <!--色带选择横行-->
                    <s:HGroup>
                        <s:Label fontSize="12" paddingTop="5"  paddingBottom="5" fontWeight="bold" 
                                 
                                 height="20" width="60" text="选择色带:" fontFamily="中易宋体"/>
                        <!--
                        <s:ComboBox id="roadpic"  selectedIndex="0" width="183" 
                                    
                                    dataProvider="{roadpicchoice}"  change="color_changeHandler(event)" />-->
                        
                        <mx:ColorPicker id="c1" showTextField="true" selectedColor="0xF9F900"  width="88.5" 
                                        change="c1_changeHandler(event)"/>
                        <mx:ColorPicker id="c2" showTextField="true" selectedColor="0xFF0000"  width="85.5"
                                        change="c2_changeHandler(event)"/>
                        
                        
                    </s:HGroup>

不改变则按预设的色带进行渲染,改变颜色则重新渲染一次。

该说明一下flag的作用了,试想如果在设置GP执行需要的相应参数时(最后一步是绘图确定分析范围),如果改变了颜色,则会触发执行渲染的函数generateRenderer(),而之前设置的是绘图结束自动调用GP服务,并执行一系列流程,其中就有获取GP结果图层和渲染参数等,而这时GP服务没有执行,渲染参数更是没有得到,执行渲染函数是会出错的,于是之前设置了一个flag,若GP执行,且执行成功,则为flag赋值为true(默认flag是false),这样改变色带颜色时,如果还没有成功调用GP任务,是不会去进行渲染的,避免出错。

//颜色选择
            protected function c1_changeHandler(event:ColorPickerEvent):void
            {
                fromColorValue=c1.selectedColor;
                if(flag_generateRenderer==true)  //在GP成功完成后为true值
                {
                    generateRenderer();
                }
            }


            protected function c2_changeHandler(event:ColorPickerEvent):void
            {
                //toColorValue=uint(c2.colorField);
                toColorValue=c2.selectedColor;
                if(flag_generateRenderer==true)  //在GP成功完成后为true值
                {
                    generateRenderer();
                }
            }

 

posted @ 2012-12-15 19:09  colinhou  阅读(1429)  评论(0编辑  收藏  举报