我们能否在地图上显示当前城市的天气情况呢?当然可以,今天我们就自己来实现一个。我们继续以前的学习方法,尽量在一个示例中学习更多的知识点。今天我们做的这个地图天气预报就包含以下几个知识点:
1.调用WebService查询天气情况。
2.城市坐标数据使用JSON格式存储,在FLEX实现对JSON的操作。
3.在地图上显示不同天气情况图标。
4.自定义组件。
我们先来看看我们实现的效果是怎么样的:
我们可以放大后,点击每个城市的图标,可以显示详情信息:
看起来好像还不错吧?不过注意哦,这个天气预报的接口是使用www.webxml.com.cn的免费的接口,免费的每天会有次数限制,所以呀,不要刷得太多了,会被封的!
代码如下:


1
<?
xml version
=
"
1.0
"
encoding
=
"
utf-8
"
?>
2 < s:Application xmlns:fx = " http://ns.adobe.com/mxml/2009 "
3 xmlns:s = " library://ns.adobe.com/flex/spark "
4 xmlns:mx = " library://ns.adobe.com/flex/mx " minWidth = " 800 " minHeight = " 600 "
5 xmlns:maps = " com.fgmap.maps.* "
6 creationComplete = " creationCompleteHandler(event) " >
7 < s:layout >
8 < s:HorizontalLayout / >
9 < / s:layout>
10 < fx:Style source = " assets/style/style.css "/ >
11 < fx:Declarations >
12 <!-- 将非可视元素(例如服务、值对象)放在此处 -->
13 < mx:WebService id = " webService " wsdl = " http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl "
14 showBusyCursor = " true " result = " onLoad(event) " fault = " faultHandler(event) "/ >
15 < mx:HTTPService id = " service " resultFormat = " text "
16 url = " assets/data/citydata.josn "
17 result = " onJSONLoad(event) " fault = " service_faultHandler(event) "
18 showBusyCursor = " true "/ >
19 < / fx:Declarations>
20 < s:Panel width = " 100% " height = " 100% " title = " FGMap 天气预报 " >
21 < maps:Map id = " map " width = " 100% " height = " 100% "
22 mapevent_mapready = " map_mapevent_mapreadyHandler(event) "/ >
23 < / s:Panel>
24
25 < fx:Script >
26 <! [CDATA[
27 import com.adobe.serialization.json.JSON;
28 import com.fgmap.maps. * ;
29 import com.fgmap.maps.MapMouseEvent;
30 import com.fgmap.maps.controls.MapTypeControl;
31 import com.fgmap.maps.controls.NavigationControl;
32 import com.fgmap.maps.controls.OverviewMapControl;
33 import com.fgmap.maps.controls.ScaleControl;
34 import com.fgmap.maps.interfaces.IMapType;
35 import com.fgmap.maps.overlays. * ;
36
37 import com.fgmap.demo.weather.model.WeatherModel;
38 import com.fgmap.demo.weather.vo.CityDataVo;
39
40 import mx.collections.ArrayCollection;
41 import mx.controls.Alert;
42 import mx.controls.Image;
43 import mx.events.FlexEvent;
44 import mx.rpc.events.FaultEvent;
45 import mx.rpc.events.ResultEvent;
46 import mx.utils.ArrayUtil;
47
48 import spark.components.Group;
49
50 private var nowWeather:CityDataVo;
51 private var timer:Timer = new Timer( 500 , 0 );
52 private var num: int = 0 ;
53 private var latLngBounds:LatLngBounds = new LatLngBounds();
54
55 private var CityData:ArrayCollection = new ArrayCollection();
56
57 protected function map_mapevent_mapreadyHandler(event:MapEvent): void {
58 map.enableContinuousZoom(); // 启用连续平滑缩放。
59 map.enableScrollWheelZoom(); // 启用使用鼠标滚轮缩放。
60 map.addControl( new MapTypeControl()); // 供用户在地图类型之间进行切换的按钮。
61 map.addControl( new NavigationControl()); // 供用户更改地图的各项导航参数,包括缩放级别、中心位置和空间方位角。
62 map.addControl( new ScaleControl()); // 比例控件是用于指示当前地图的分辨率和缩放级别的可视指示器。
63
64 map.setCenter( new LatLng( 30.35 , 114.17 ), 5 );
65
66 timer.addEventListener(TimerEvent.TIMER,onTimerComplete);
67 timer.start();
68 // CityData.toString();
69 }
70
71 private function onTimerComplete(e:TimerEvent): void {
72 timer.stop();
73 if (num < CityData.length){
74 nowWeather = new CityDataVo(CityData[num]);
75 webService.getWeatherbyCityName(nowWeather.name);
76 num ++ ;
77 } else {
78 map.setCenter(latLngBounds.getCenter(), 5 );
79 }
80 }
81
82 private function onLoad(event:ResultEvent): void {
83 // Alert.show(event.result.toString(),"WebService Results");
84 var weatherInfo:ArrayCollection = (event.result) as ArrayCollection;
85
86 var markerOptions:MarkerOptions = new MarkerOptions();
87 markerOptions.icon = getIcon(weatherInfo[ 8 ]); // CityData.getIconClass(weatherInfo[8]);
88 markerOptions.draggable = true ;
89 markerOptions.iconAlignment = MarkerOptions.ALIGN_BOTTOM;
90 markerOptions.iconOffset = new Point( - 25 , - 69 );
91
92 var marker:Marker = new Marker(nowWeather.latlng,markerOptions);
93 var infoOptions:InfoWindowOptions = new InfoWindowOptions();
94 infoOptions.title = " 查看天气 " ;
95 infoOptions.width = 310 ;
96 infoOptions.height = 190 ;
97
98 marker.addEventListener(MapMouseEvent.CLICK, function (e:Event): void {
99 var weatherModel:WeatherModel = new WeatherModel();
100 weatherModel.weatherInfo = weatherInfo;
101 infoOptions.customContent = weatherModel;
102 infoOptions.customOffset = new Point( - 25 , - 69 );
103 infoOptions.drawDefaultFrame = true ;
104 marker.openInfoWindow(infoOptions);
105 });
106
107 marker.addEventListener(MapMouseEvent.DRAG_END, function (e:Event): void {
108 // Alert.show(marker.getLatLng().toUrlValue(4));
109 });
110
111 map.addOverlay(marker); // 在地图上显示这个标注
112
113 latLngBounds.extend(nowWeather.latlng);
114 timer.start();
115 }
116
117 private function faultHandler(event:FaultEvent): void {
118 Alert.show(event.fault.toString(), " WebService Error " );
119 }
120
121 // 设置图片
122 private function getIcon(icon:String):Image {
123 // var group:Group = new Group();
124 var img:Image = new Image();
125 if ( "" == icon){
126 icon = " b_nothing.gif " ;
127 }
128 img.source = " assets/icon/b_ " + icon;
129 // group.addChild(img);
130 return img;
131 }
132
133 private function onJSONLoad(event:ResultEvent): void {
134 var rawData:String = event.result.toString();
135 var arr:Array = (JSON.decode(rawData) as Array);
136 CityData = new ArrayCollection(arr);
137 }
138
139 protected function service_faultHandler(event:FaultEvent): void
140 {
141 Alert.show( " 城市数据加载未成功\n " + service.url, " FGMap天气预报 " );
142 }
143
144 protected function creationCompleteHandler(event:FlexEvent): void {
145 service.send();
146 }
147
148 ]] >
149 < / fx:Script>
150 < / s:Application>
2 < s:Application xmlns:fx = " http://ns.adobe.com/mxml/2009 "
3 xmlns:s = " library://ns.adobe.com/flex/spark "
4 xmlns:mx = " library://ns.adobe.com/flex/mx " minWidth = " 800 " minHeight = " 600 "
5 xmlns:maps = " com.fgmap.maps.* "
6 creationComplete = " creationCompleteHandler(event) " >
7 < s:layout >
8 < s:HorizontalLayout / >
9 < / s:layout>
10 < fx:Style source = " assets/style/style.css "/ >
11 < fx:Declarations >
12 <!-- 将非可视元素(例如服务、值对象)放在此处 -->
13 < mx:WebService id = " webService " wsdl = " http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl "
14 showBusyCursor = " true " result = " onLoad(event) " fault = " faultHandler(event) "/ >
15 < mx:HTTPService id = " service " resultFormat = " text "
16 url = " assets/data/citydata.josn "
17 result = " onJSONLoad(event) " fault = " service_faultHandler(event) "
18 showBusyCursor = " true "/ >
19 < / fx:Declarations>
20 < s:Panel width = " 100% " height = " 100% " title = " FGMap 天气预报 " >
21 < maps:Map id = " map " width = " 100% " height = " 100% "
22 mapevent_mapready = " map_mapevent_mapreadyHandler(event) "/ >
23 < / s:Panel>
24
25 < fx:Script >
26 <! [CDATA[
27 import com.adobe.serialization.json.JSON;
28 import com.fgmap.maps. * ;
29 import com.fgmap.maps.MapMouseEvent;
30 import com.fgmap.maps.controls.MapTypeControl;
31 import com.fgmap.maps.controls.NavigationControl;
32 import com.fgmap.maps.controls.OverviewMapControl;
33 import com.fgmap.maps.controls.ScaleControl;
34 import com.fgmap.maps.interfaces.IMapType;
35 import com.fgmap.maps.overlays. * ;
36
37 import com.fgmap.demo.weather.model.WeatherModel;
38 import com.fgmap.demo.weather.vo.CityDataVo;
39
40 import mx.collections.ArrayCollection;
41 import mx.controls.Alert;
42 import mx.controls.Image;
43 import mx.events.FlexEvent;
44 import mx.rpc.events.FaultEvent;
45 import mx.rpc.events.ResultEvent;
46 import mx.utils.ArrayUtil;
47
48 import spark.components.Group;
49
50 private var nowWeather:CityDataVo;
51 private var timer:Timer = new Timer( 500 , 0 );
52 private var num: int = 0 ;
53 private var latLngBounds:LatLngBounds = new LatLngBounds();
54
55 private var CityData:ArrayCollection = new ArrayCollection();
56
57 protected function map_mapevent_mapreadyHandler(event:MapEvent): void {
58 map.enableContinuousZoom(); // 启用连续平滑缩放。
59 map.enableScrollWheelZoom(); // 启用使用鼠标滚轮缩放。
60 map.addControl( new MapTypeControl()); // 供用户在地图类型之间进行切换的按钮。
61 map.addControl( new NavigationControl()); // 供用户更改地图的各项导航参数,包括缩放级别、中心位置和空间方位角。
62 map.addControl( new ScaleControl()); // 比例控件是用于指示当前地图的分辨率和缩放级别的可视指示器。
63
64 map.setCenter( new LatLng( 30.35 , 114.17 ), 5 );
65
66 timer.addEventListener(TimerEvent.TIMER,onTimerComplete);
67 timer.start();
68 // CityData.toString();
69 }
70
71 private function onTimerComplete(e:TimerEvent): void {
72 timer.stop();
73 if (num < CityData.length){
74 nowWeather = new CityDataVo(CityData[num]);
75 webService.getWeatherbyCityName(nowWeather.name);
76 num ++ ;
77 } else {
78 map.setCenter(latLngBounds.getCenter(), 5 );
79 }
80 }
81
82 private function onLoad(event:ResultEvent): void {
83 // Alert.show(event.result.toString(),"WebService Results");
84 var weatherInfo:ArrayCollection = (event.result) as ArrayCollection;
85
86 var markerOptions:MarkerOptions = new MarkerOptions();
87 markerOptions.icon = getIcon(weatherInfo[ 8 ]); // CityData.getIconClass(weatherInfo[8]);
88 markerOptions.draggable = true ;
89 markerOptions.iconAlignment = MarkerOptions.ALIGN_BOTTOM;
90 markerOptions.iconOffset = new Point( - 25 , - 69 );
91
92 var marker:Marker = new Marker(nowWeather.latlng,markerOptions);
93 var infoOptions:InfoWindowOptions = new InfoWindowOptions();
94 infoOptions.title = " 查看天气 " ;
95 infoOptions.width = 310 ;
96 infoOptions.height = 190 ;
97
98 marker.addEventListener(MapMouseEvent.CLICK, function (e:Event): void {
99 var weatherModel:WeatherModel = new WeatherModel();
100 weatherModel.weatherInfo = weatherInfo;
101 infoOptions.customContent = weatherModel;
102 infoOptions.customOffset = new Point( - 25 , - 69 );
103 infoOptions.drawDefaultFrame = true ;
104 marker.openInfoWindow(infoOptions);
105 });
106
107 marker.addEventListener(MapMouseEvent.DRAG_END, function (e:Event): void {
108 // Alert.show(marker.getLatLng().toUrlValue(4));
109 });
110
111 map.addOverlay(marker); // 在地图上显示这个标注
112
113 latLngBounds.extend(nowWeather.latlng);
114 timer.start();
115 }
116
117 private function faultHandler(event:FaultEvent): void {
118 Alert.show(event.fault.toString(), " WebService Error " );
119 }
120
121 // 设置图片
122 private function getIcon(icon:String):Image {
123 // var group:Group = new Group();
124 var img:Image = new Image();
125 if ( "" == icon){
126 icon = " b_nothing.gif " ;
127 }
128 img.source = " assets/icon/b_ " + icon;
129 // group.addChild(img);
130 return img;
131 }
132
133 private function onJSONLoad(event:ResultEvent): void {
134 var rawData:String = event.result.toString();
135 var arr:Array = (JSON.decode(rawData) as Array);
136 CityData = new ArrayCollection(arr);
137 }
138
139 protected function service_faultHandler(event:FaultEvent): void
140 {
141 Alert.show( " 城市数据加载未成功\n " + service.url, " FGMap天气预报 " );
142 }
143
144 protected function creationCompleteHandler(event:FlexEvent): void {
145 service.send();
146 }
147
148 ]] >
149 < / fx:Script>
150 < / s:Application>
源代码下载地址是:http://files.cnblogs.com/liongis/Weather.rar
下一个版需要改进的地方有:
1.增加其它城市的天气情况,目前只有省会城市的天气。
2.分级显示城市的天气情况,首先显示省会的,地图放大时,显示当前可见范围内城市的天气情况。
3.将天气数据获取到本地,不需要实时通过接口进行查询,避免次数限制。
4.。。。。。
如果你有更好的想法,可以跟我联系。欢迎赐教!