Creando un lector de GeoRSS con Adobe Flex 3

September 6, 2009 – 1:21 pm
Tags: , , ,

Uno de los ejemplos tradicionales que se desarrollan durante el aprendizaje de Flex 3 y Actionscript 3 es el de la creación de un lector de RSS. En el presente artículo se presenta una extensión de dicho ejemplo adicionando la capacidad de interpretar infomación publicada en el formato GeoRSS.

  • Qué es un RSS?

RSS es una familia de formatos de fuentes web codificados en XML. Se utiliza para suministrar a suscriptores de información actualizada frecuentemente. El formato permite distribuir contenido sin necesidad de un navegador, utilizando un software diseñado para leer estos contenidos RSS (agregador).

  • Qué es un GeoRSS?

GeoRSS es un conjunto de estándares para representar información geográfica mediante el uso de capas y está construido dentro de la familia de estándares RSS.

  • Cómo convertir un RSS en GeoRSS?

Si usted no dispone de una aplicación para convertir sus RSS en GeoRSS puede utilizar Geonames para realizar dicha traducción de formato.
El “RSS to GeoRSS Converter” de Geonames busca posibles ubicaciones (sitios geogràficos) en el texto del  rss.  Si alguna ubicación geográfica relevante es encontrada, adiciona la latitud y longitud al RSS durante la codificación a GeoRSS.

  • Que requiero para implementar el lector de GeoRSS utilizando Adobe Flex 3?

- Flex SDK

- Google Maps Flash API

  • Donde puedo descargar el código fuente del ejemplo?

Puede descargar el código fuente desde esta ubicación.

  • Que ejemplos de programación flex / actionscript  puedo encontrar en el código?

- Carga de datos en XML utilizando el objeto HTTPService

- Despliegue de datos utilizando componentes ComboBox, Datagrid e Image

- Formatear etiquetas de un ComboBox utilizando labelFunction.

- Despliegue de información HTML en el tooltip de la aplicación.

- Ejemplo básico de carga de Markers en Google Maps para Adobe Flex.

- Procesamiento de datos publicados en formatos XML, RSS y GeoRSS.

- Utilizar el servicio “Rss to GeoRSS” de Geonames con Flex y Actionscript.

  • Puedo ver en línea el código fuente del ejemplo y la aplicación resultante?

A continuación puede ver tanto la aplicación como el código fuente relacionado.






Código fuente del archivo Rss.mxml:

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
	layout="vertical"
	applicationComplete="onComplete();" 
	creationComplete="loadSourcesService.send();">
<mx:Style>
	Application{
		background-color:#ffffff;
		paddingBottom:5; 
		paddingLeft:5;
		paddingRight:5; 
		paddingTop:5;
	}
</mx:Style>	
<mx:Script>
	<![CDATA[
		import com.google.maps.controls.ZoomControlOptions;
		import mx.collections.ArrayCollection;
		import com.google.maps.overlays.MarkerOptions;
		import com.google.maps.overlays.Marker;
		import ejemplo.HTMLToolTip;
		import mx.managers.ToolTipManager;
		import flash.net.navigateToURL;
		import mx.controls.List;
		import mx.controls.Alert;
		import mx.events.ListEvent;
		import mx.rpc.events.FaultEvent;
		import mx.rpc.events.ResultEvent;
		import com.google.maps.MapType;
		import com.google.maps.LatLng;
		import com.google.maps.controls.PositionControl;
		import com.google.maps.controls.MapTypeControl;
		import com.google.maps.controls.ZoomControl;
		import com.google.maps.Map;
		import com.google.maps.MapEvent;
 
		public var map:Map;
 
	    //se invoca en el evento 'creationComplete' 
		private function onComplete() :void{
			//configuración del tooltip para despliegue de HTML
			ToolTipManager.toolTipClass = HTMLToolTip; 
		}
 
		//Manejo de la respuesta del HTTPService loadSourcesService
		private function loadSourcesService_result(evt:ResultEvent):void {
		    var resultObj:Object = evt.result;
		    sourcesCb.dataProvider = resultObj.xml.lista.item;
		}
 
		//Iniciar el Mapa
		private function startMap(event:Event):void {
			map = new Map();
			//Key de google Maps: http://code.google.com/intl/es-ES/apis/maps/documentation/flash/
			map.key = map.key = "ABQIAAAAzP_X84EVzii7yEPHkonPNRRMdub8RYo7ePgaMtJOPXtU0LG1eBQz8J6xJi_XxLQ80ti-WlGkph7kVw";
			map.addEventListener(MapEvent.MAP_READY, onMapReady);
 
			var zoomopts:ZoomControlOptions = new ZoomControlOptions();
			zoomopts.hasScrollTrack = false;
			var zoomCtrl:ZoomControl = new ZoomControl(zoomopts);
			map.addControl(zoomCtrl);
 
			// add MapType Controller
			var mapTypeCtrl:MapTypeControl = new MapTypeControl();
			map.addControl(mapTypeCtrl);
 
			// add Position Controller
			var posCtrl:PositionControl = new PositionControl();
			map.addControl(posCtrl);
			mapContainer.addChild(map);
		}
 
		private function resizeMap(event:Event):void {
			map.setSize(new Point(mapContainer.width, mapContainer.height));
		}
 
		private function onMapReady(event:MapEvent):void {
			//setCenter:  Parámetros: Coordenada Punto Central, Nivel de Zoom, Tipo de Mapa
			map.setCenter(new LatLng(4,-73),3, MapType.NORMAL_MAP_TYPE);
			//Habilita el Zoom Continuo
			map.enableContinuousZoom();
			//Habilita el Scroll del mapa utilizando el Mouse 
			map.enableScrollWheelZoom();
		}
 
		// Se invoca cuando el usuario cambia de opcion en el combo box
		// se obtiene el rss y se pasa al HTTPService 'loadRssService'
		private function getFuenteNombre ( event: ListEvent) : void{					
			if(sourcesCb.selectedItem){
				//configura la llamada al servicio geonames que recibe como parámetro
				//la url del rss que se va a georreferenciar
				//http://www.geonames.org/rss-to-georss-converter.html
				loadRssService.url= "http://ws.geonames.org/rssToGeoRSS?feedUrl="+sourcesCb.selectedItem.url;
				loadRssService.send();
				//elimina todos los markers del mapa
				map.clearOverlays();
				rssList.dataProvider = new ArrayCollection();
			}
		}
 
		//Esta funcion se llama cuando cambia el DataGrid, tiene como objetivo
		//establecer el contenido a desplegar en la descripcion, tomandolo del xml.
		private function getPage(event: ListEvent) : void{
			var selectedEq:Object = rssList.selectedItem;
			titulo.text = rssList.selectedItem.title;
			contenido.htmlText=rssList.selectedItem.description;
			//Alert.show(rssList.selectedItem["encoded"])
			mas.visible=true;
			var latlng:LatLng = new LatLng(Number(rssList.selectedItem.lat),Number(rssList.selectedItem.long));
			//lo hace solo cuando geonames devuelva la latitud y la longitud
			if(rssList.selectedItem.lat!=undefined||rssList.selectedItem.long!=undefined){
				var marker:Marker = generateMarker(selectedEq); 
				map.setCenter(latlng , 3);	
				map.addOverlay(marker);
			}
		}
 
		private function generateMarker(item:Object ):Marker{
			//crea un objeto de tipo LatLng
				var latlng:LatLng = new LatLng(Number(item.lat),Number(item.long));				
				//tooltip del Marker  
				var markerOptions : MarkerOptions= new MarkerOptions();
			    markerOptions.tooltip = item.title;
			    var marker : Marker = new Marker( latlng, markerOptions );
				return marker;
		}
 
		//Esta funcion se llama cuando se hace click en el enlace 
		//que me envia a la pagina de la fuente, coge el campo link del xml.
		private function getUrl() : void{
			//configura el request del LinkButton con el objeto link del xml 
			var u:URLRequest = new URLRequest(rssList.selectedItem.link);
        	navigateToURL(u,"_blank");
		}
 
		//Se llama cuando hay un resultado en HTTPService loadRssService
		protected function onServiceResult(event:ResultEvent):void {
			rssList.dataProvider = event.result.rss.channel.item;
			//configura la ubicacion de la imagen con el campo image.url
			imagen.source=event.result.rss.channel.image.url;
			titulo.text = "";
			contenido.htmlText='Seleccione una Noticia';
			mas.visible=false;
		}
 
 
 
		//Se llama cuando hay un fault HTTPService loadEQService y en HTTPService loadRssService
		private function load_fault(evt:FaultEvent):void {
			Alert.show('Ocurrió un Error en el Servidor', evt.fault.faultString);
		}
 
		private function  sourcesCbLabelFunction(item:Object):String{
			return item.nombre + " ("+item.pais+")";
		}
 
	]]>
</mx:Script>
	<mx:HTTPService id="loadSourcesService"
	            url="sources.xml"
	            resultFormat="object"
	            result="{loadSourcesService_result(event);}"
	            fault="load_fault(event);"
	            showBusyCursor="true" />
 
	<mx:HTTPService id="loadRssService"
	            resultFormat="object"
	            result="onServiceResult(event);"
	            fault="load_fault(event);"
	            showBusyCursor="true" />
 
	<mx:HDividedBox width="100%" height="100%">
		<mx:Panel id="panel1" width="50%" height="100%" title="Lector de GeoRSS">
			<mx:VBox id="box"  height="100%" width="100%">
				<mx:HBox width="100%">			
					<mx:ComboBox id="sourcesCb"  textAlign="left" width="100%"  
						labelFunction="sourcesCbLabelFunction"
						change="getFuenteNombre(event)" rowCount="10"
						prompt="Seleccione una opción..." />
				</mx:HBox>
				<mx:DataGrid id="rssList" width="100%" height="100%"  change="getPage(event)">
					<mx:columns>
						<mx:DataGridColumn dataField="title" headerText="Titular" 
							dataTipField="description" showDataTips="true" />
					</mx:columns>		
				</mx:DataGrid>
			</mx:VBox>
		</mx:Panel>
		<mx:Panel  width="50%" height="100%" title="Detalle de la Noticia">
			<mx:VDividedBox width="100%" height="100%">
				<mx:VBox width="100%" height="30%">
					<mx:HBox width="100%" >
						<mx:Image id="imagen" />
						<mx:LinkButton id="mas" visible="false" label="Ver mas..." click="{getUrl()}"/>	
					</mx:HBox>
					<mx:Text id="titulo" width="100%" fontWeight="bold"/>
					<mx:Text id="contenido" width="100%"/>
				</mx:VBox>
				<mx:VBox width="100%" height="70%">
					<mx:UIComponent id="mapContainer" 
			        initialize="startMap(event);" 
			        resize="resizeMap(event)" 
			        width="100%" height="100%"/>
				</mx:VBox>
			</mx:VDividedBox>	
		</mx:Panel>
	</mx:HDividedBox>
</mx:Application>

Código fuente del archivo ejemplo/HTMLToolTip.as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package ejemplo
{
//Esta es la clase que maneja el tooltip para que muestre el contenido
//que esta en html y no como un string.
     import mx.containers.*;  
     import mx.controls.Text;  
     import mx.controls.ToolTip;  
     import mx.core.*;  
 
     public class HTMLToolTip extends ToolTip  
     {  
         public function HTMLToolTip()  
         {    super(); }  
 
         override protected function commitProperties():void{  
             super.commitProperties();  
             textField.htmlText = text;  
         }  
     } 
}

Archivo sources.xml:

<xml>
	<lista>
		<item>
			<nombre>El Tiempo - Mundo</nombre>
			<url>http://www.eltiempo.com/mundo/rss.xml</url>
			<pais>Colombia</pais>
		</item>
		<item>
			<nombre>El Tiempo - Colombia</nombre>
			<url>http://www.eltiempo.com/colombia/rss.xml</url>
			<pais>Colombia</pais>
		</item>
		<item>
			<nombre>El Espectador</nombre>
			<url>http://www.elespectador.com/rss.xml </url>
			<pais>Colombia</pais>
		</item>
		<item>
			<nombre>El Pais - America Latina</nombre>
			<url>http://www.elpais.com/rss/feed.html?feedId=17041</url>
			<pais>España</pais>
		</item>
		<item>
			<nombre>ABC - Portada</nombre>
			<url>http://www.abc.es/rss/feeds/abcPortada.xml</url>
			<pais>España</pais>
		</item>
		<item>
			<nombre>BBC Mundo</nombre>
			<url>http://www.bbc.co.uk/mundo/index.xml</url>
			<pais>Inglaterra</pais>
		</item>
		<item>
			<nombre>CNN - World</nombre>
			<url>http://rss.cnn.com/rss/edition_world.rss</url>
			<pais>Estados Unidos</pais>
		</item>
		<item>
			<nombre>Reuters - World News</nombre>
			<url>http://feeds.reuters.com/reuters/worldNews</url>
			<pais>Estados Unidos</pais>
		</item>
		<item>
			<nombre>BusinessWeek.com</nombre>
			<url>http://rss.businessweek.com/bw_rss/bwdaily</url>
			<pais>Estados Unidos</pais>
		</item>
		<item>
			<nombre>Google News</nombre>
			<url>http://news.google.com/news?output=rss</url>
			<pais>Alemania</pais>
		</item>
</lista>
</xml>
Share
  1. 1 Trackback(s)

  2. Nov 9, 2009: uberVU - social comments

Post a Comment

Switch to our mobile site