( ! ) Warning: call_user_func_array() [function.call-user-func-array]: First argument is expected to be a valid callback, 'WPtouchPlugin::wptouch_parse_request' was given in C:\Domains\adamestrada.com\wwwroot\wp-includes\plugin.php on line 414
Call Stack
#TimeMemoryFunctionLocation
10.002862072{main}( )..\wp-404-handler.php:0
20.003567864include( 'C:\Domains\adamestrada.com\wwwroot\index.php' )..\wp-404-handler.php:7
30.004168160require( 'C:\Domains\adamestrada.com\wwwroot\wp-blog-header.php' )..\index.php:17
40.42272611920wp( )..\wp-blog-header.php:14
50.42272612200WP->main( )..\functions.php:1434
60.42272612304WP->parse_request( )..\classes.php:490
70.43542632576do_action_ref_array( )..\classes.php:293
80.43562633696call_user_func_array ( )..\plugin.php:414
More on ESRI Flex and Config.xml | Adam Estrada

More on ESRI Flex and Config.xml

2009 December 15

More often than not, when building a Flex application that includes a URL that references a map service, you’ll have to swap out that URL from your development environment to production when you go live. The following script/technique is intended to alleviate having to completely rebuild your application during deployment.

Take a look at the following mxml file and note that there are 3 things in particular to note.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:esri="http://www.esri.com/2008/ags"
    layout="absolute"
    initialize="init()"
    styleName="plain"
    >
  </mx><mx :Script>
    < ![CDATA[
    	import mx.collections.XMLListCollection;
    	import mx.collections.ArrayCollection;
        	import com.esri.ags.Graphic;
        	import com.esri.ags.events.MapMouseEvent;        	
        	import com.esri.ags.geometry.MapPoint;
        	import com.esri.ags.geometry.Extent;
            import com.esri.ags.events.ExtentEvent;
            import mx.rpc.events.FaultEvent;
        	import mx.rpc.events.ResultEvent;
            import mx.controls.Alert;
            import flash.external.*;
            import mx.events.FlexEvent;
            import com.esri.ags.layers.TiledMapServiceLayer;
            import mx.controls.Button;
            import mx.controls.Text;
            import com.esri.ags.layers.ArcGISDynamicMapServiceLayer;
            import mx.rpc.http.HTTPService;
 
            private function initXML():void
        	{
        		var configService:HTTPService = new HTTPService();
        		configService.url = "config.xml";
        		configService.resultFormat = "e4x";
        		configService.addEventListener(ResultEvent.RESULT, configResult);
        		configService.addEventListener(FaultEvent.FAULT, configFault);
        		configService.send();
        	}
 
            private function configResult(event:ResultEvent):void
            {
            	var configXML:XML = event.result as XML;
            	var serviceList:XMLList = configXML..service;
            	for (var i:int = 0; i < serviceList.length(); i++)
            	{
             		var serviceName:String = serviceList[i].name;
            		var serviceURL:String = serviceList[i].url;
            		var serviceAlpha:int = serviceList[i].alpha;
            		var serviceVisible:Boolean = serviceList[i].visible;
            		var serviceLayers:ArrayCollection = new ArrayCollection(serviceList[i].layers.split(","));
 
            		var tLayer:ArcGISDynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer(serviceURL); 
            		tLayer.id = serviceName;
            		tLayer.visible = serviceVisible;
            		tLayer.alpha = serviceAlpha;
            		tLayer.visibleLayers = serviceLayers;
            		myMap.addLayer(tLayer);	
            	}          	
            }
 
            private function configFault(event:FaultEvent):void
            {
            	Alert.show(event.fault.faultString);
            }
 
 
            private function layerShowHandler(event:FlexEvent):void
            {
                // update the LODs/zoomslider to use/show the levels for the selected base map
                var tiledLayer:TiledMapServiceLayer = event.target as TiledMapServiceLayer;
                myMap.lods = tiledLayer.tileInfo.lods;
            }
 
			//add a callback for js to flex communication
			public function init():void
			{
				initXML();
			  if (flash.external.ExternalInterface.available)
			    flash.external.ExternalInterface.addCallback("changeExtent", changeExtent);     
			}
 
			//call from js
			public function changeExtent(sextent:String):void	
			{
				//var avals = sextent.split("|");
				//var ext:Extent = new Extent(new Number(avals[0]),new Number(avals[2]),new Number(avals[1]),new Number(avals[3]));
				//ext.spatialReference = myMap.spatialReference;
				//myMap.extent = ext;
			}
 
            public function onBasemapCreationComplete():void
			{
            	myMap.addEventListener(MouseEvent.CLICK, pushExtentEvent);
            }
 
     		//send extents to html/js
     		public function pushExtentEvent(event:MouseEvent):void           
      	 	{
      	 		if (flash.external.ExternalInterface.available)
			     {
			       const mapPoint:MapPoint = myMap.toMapFromStage(event.stageX, event.stageY);
			       var extent:Array = new Array();
			       flash.external.ExternalInterface.call("displayExtent", mapPoint.y.toFixed(6), mapPoint.x.toFixed(6));
			     }        
      	 	}
      	 	private function onMapClick(event:MapMouseEvent):void
      	 	{    	 		
      	 		myMap.infoWindow.label = "Event Location ";
      	 		myMap.infoWindow.show(event.mapPoint);
      	 	}
        ]]>
    </mx>
    <esri :Map id="myMap" width="100%" height="100%" mapClick="onMapClick(event)" >
      </esri><esri :extent>
        </esri><esri :Extent xmin="-122.2" ymin="24.89" xmax="-70.59" ymax="46.92"  >
          <esri :SpatialReference wkid="4326"/>
        </esri>
 
        <esri :ArcGISTiledMapServiceLayer
            visible="{bb.selectedIndex == 0}"
            show="layerShowHandler(event)"
            url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer" 
            creationComplete="onBasemapCreationComplete()" />
        <esri :ArcGISTiledMapServiceLayer
            visible="{bb.selectedIndex == 1}"
            show="layerShowHandler(event)"
            url="http://server.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer" 
            creationComplete="onBasemapCreationComplete()"/>
        <esri :ArcGISTiledMapServiceLayer
            visible="{bb.selectedIndex == 2}"
            show="layerShowHandler(event)"
            url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer" 
            creationComplete="onBasemapCreationComplete()" />
 
    <mx :ToggleButtonBar id="bb" horizontalGap="2" selectedIndex="0" themeColor="0x00FF00" right="5" top="5">
        </mx><mx :dataProvider>
            </mx><mx :Array>
                </mx><mx :String>Streets</mx>
                <mx :String>Topo</mx>
                <mx :String>Imagery</mx>

First, note the code block that references an external XML file (config.xml). It really doesn’t get any easier than this. What’s really cool about this XML file is that basically, all the web service configuration options from the ArcGIS Service are configured through here. You can traverse through the config.xml file by referencing the node you want in the XMLList or serviceList:XMLList.

var serviceName:String = serviceList[i].name;
var serviceURL:String = serviceList[i].url;
var serviceAlpha:int = serviceList[i].alpha;
var serviceVisible:Boolean = serviceList[i].visible;
var serviceLayers:ArrayCollection = new ArrayCollection(serviceList[i].layers.split(“,”));

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
private function initXML():void
        	{
        		var configService:HTTPService = new HTTPService();
        		configService.url = "config.xml";
        		configService.resultFormat = "e4x";
        		configService.addEventListener(ResultEvent.RESULT, configResult);
        		configService.addEventListener(FaultEvent.FAULT, configFault);
        		configService.send();
        	}
 
            private function configResult(event:ResultEvent):void
            {
            	var configXML:XML = event.result as XML;
            	var serviceList:XMLList = configXML..service;
            	for (var i:int = 0; i < serviceList.length(); i++)
            	{
             		var serviceName:String = serviceList[i].name;
            		var serviceURL:String = serviceList[i].url;
            		var serviceAlpha:int = serviceList[i].alpha;
            		var serviceVisible:Boolean = serviceList[i].visible;
            		var serviceLayers:ArrayCollection = new ArrayCollection(serviceList[i].layers.split(","));
 
            		var tLayer:ArcGISDynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer(serviceURL); 
            		tLayer.id = serviceName;
            		tLayer.visible = serviceVisible;
            		tLayer.alpha = serviceAlpha;
            		tLayer.visibleLayers = serviceLayers;
            		myMap.addLayer(tLayer);	
            	}          	
            }
 
            private function configFault(event:FaultEvent):void
            {
            	Alert.show(event.fault.faultString);
            }

The XML is below: Note the configuration options that you would normally have to set in your compiled code. I just included the service name, url, alpha and visibility in this demonstration. There are many more options to choose from…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
< ?xml version="1.0"?>
<configuration>
<service>
	<name>
	Service Name
	</name>
	<url>
	http://yoururl.com/yourserver/rest/services/BaseMap/MapServer/
	</url>
	<alpha>
	1.0
	</alpha>
	<visible>
	true
	</visible>
	<layers>
	0,1
	</layers>
</service>
</configuration>

The next thing to take a look at is the fact that there is an Event that grabs the Latitude and Longitude from your map when it's clicked on (MouseEvent.CLICK). Moreover, it passes them to an HTML Input text box in the host page through an ExternalInterface call. The corresponding javascript should resemble the following. Note the < %= this.latitude.ClientID %> and < %= this.longitude.ClientID %> as they are required if you are embedding this in a ASP.NET for C# application.

?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script language="JavaScript" type="text/javascript">
//call flex function changeExtent
function mapextentchange(value)
{
	if(value != ''){
		getFlexApp('FlexMaps').changeExtent(value);
	}	
}
 
//called from flex
function displayExtent(latitude,longitude)
{
	document.getElementById("< %= this.latitude.ClientID %>").value = latitude;
	document.getElementById("< %= this.longitude.ClientID %>").value = longitude;
}
</script>

Finally, I snagged an example off of the ESRI Flex Community page that allowed me to toggle between Streetmap, Topographic Maps and Imagery data. As the selected Index changes, the base map changes...

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        <esri :ArcGISTiledMapServiceLayer
            visible="{bb.selectedIndex == 0}"
            show="layerShowHandler(event)"
            url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer" 
            creationComplete="onBasemapCreationComplete()" />
        <esri :ArcGISTiledMapServiceLayer
            visible="{bb.selectedIndex == 1}"
            show="layerShowHandler(event)"
            url="http://server.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer" 
            creationComplete="onBasemapCreationComplete()"/>
        <esri :ArcGISTiledMapServiceLayer
            visible="{bb.selectedIndex == 2}"
            show="layerShowHandler(event)"
            url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer" 
            creationComplete="onBasemapCreationComplete()" />
 
    <mx :ToggleButtonBar id="bb" horizontalGap="2" selectedIndex="0" themeColor="0x00FF00" right="5" top="5">
        </mx><mx :dataProvider>
            </mx><mx :Array>
                </mx><mx :String>Streets</mx>
                <mx :String>Topo</mx>
                <mx :String>Imagery</mx>

So, I've had fun playing with this an I've actually been able to use the entire script in a project I was a part of. I hope that someone else gets as much use out of it as I did.

Bookmark and Share
No comments yet

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS

Spam protection by WP Captcha-Free