Creando un lector de GeoRSS con Adobe Flex 3
September 6, 2009 – 1:21 pmTags: adobe flex 3, mashup, Rich Internet Applications, Tutorial
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
- 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> |
1 Trackback(s)