Статьи

Очки с использованием Yahoo! Карты и RSS

В этом уроке я покажу вам, как начать работу с Yahoo! API Карт во Flash. Мы загрузим пару RSS-каналов и подготовим несколько предупреждений о стихийных бедствиях, используя их долготу и широту.




Перейдите по адресу http://developer.yahoo.com/flash/maps/ и зарегистрируйтесь для получения идентификатора приложения.

На странице Компонент Yahoo Map AS3 загрузите самую новую версию компонента.

Когда файл будет загружен, распакуйте zip-файл. Перейдите в папку Flash и установите файл MXP.

Запустите Flash и откройте новый файл ActionScript 3.0, затем сохраните его в новой папке как «yahoo_map.fla».

Измените размер сцены на 640×480. Перейдите на вкладку компонентов и перетащите копию компонента YahooMaps на сцену. Как только он окажется на сцене, удалите его. Это поместит копию в библиотеку, чтобы мы могли получить к ней доступ оттуда.

Перетащите копию TextArea со вкладки компонентов. На панели свойств измените размер TextArea на ширину 640 пикселей и высоту 100 пикселей. Задайте ему позицию X, равную 0, и позицию Y, равную 330. Наконец, присвойте ему имя экземпляра «textArea».

Затем перетащите копию RadioButton со вкладки компонентов. Скопируйте и вставьте его три раза, чтобы на сцене было четыре экземпляра компонента RadioButton. Выровняйте их по верху и равномерно расположите их так, чтобы они располагались по прямой линии рядом друг с другом. Затем перетащите их под компонент TextArea.

Выберите первый переключатель. Дайте ему имя экземпляра «radioAll». Пока кнопка выбрана, переключитесь на панель параметров. Дайте ему название группы «Бедствия». Измените свойство label на «All», а выбранное свойство на «true».

Выберите следующий переключатель. Дайте ему имя экземпляра «radioEarth», то же имя группы «Бедствия», метку «Землетрясения» и оставьте выбранное свойство как «false».

Выберите третий переключатель. Его имя экземпляра — «radioTsu», имя группы — «Бедствия», метка — «Цунами», а выбранное свойство — «ложь».

Наконец, выберите четвертый переключатель. У него есть имя экземпляра «radioVolcano», его групповое имя «Бедствия», у него есть метка «Volcanoes», и выбрано «false». Поскольку мы хотим иметь возможность переключаться между кнопками, мы дали им одинаковое имя группы. Расположите их соответственно, чтобы они были равномерно распределены.

Создайте отдельный слой. Поместите слой ниже слоя с компонентами TextArea и RadioButton. На панели библиотеки внизу выберите значок нового символа. Создайте новый пустой мувиклип. Перетащите экземпляр на сцену во вновь созданном слое, затем присвойте ему имя экземпляра «empty». Этот видеоклип будет содержать нашу карту, когда он будет загружен. Присвойте пустому мувиклипу позицию X и Y, равную 0. Таким образом, он выравнивается по левому верхнему углу сцены.

Перейдите в файл> новый и выберите новый файл ActionScript. Сохраните файл в том же каталоге, что и ваш FLA-файл «yahoo_map» с именем «yahoo_map.as». В вашем FLA-документе yahoo_map на панели свойств введите «yahoo_map» в поле класса документа. Это сделает ваш файл ActionScript классом Document для вашего FLA-файла yahoo_map.

Это базовая настройка для нашего класса документов:

01
02
03
04
05
06
07
08
09
10
11
12
13
package {
 
    import flash.display.Sprite;
 
    public class yahoo_map extends Sprite
    {
     
        public function yahoo_map()
        {
         
        }
    }
}

Это заявления, которые будут управлять API YahooMap

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
package {
 
    import com.yahoo.maps.api.YahooMap;
    import com.yahoo.maps.api.YahooMapEvent;
    import com.yahoo.maps.api.core.location.LatLon;
    import com.yahoo.maps.api.markers.Marker;
 
    import flash.display.Sprite;
 
    public class yahoo_map extends Sprite
    {
     
        public function yahoo_map()
        {
         
        }
    }
}

Просто добавьте их ниже в заявлении на импорт YahooMaps. Убедитесь, что они выше объявления класса.

1
package { import com.yahoo.maps.api.YahooMap;

Здесь мы собираемся delcare глобальные переменные. Нам понадобится идентификатор приложения, который вы получили со страницы YahooMaps, и позже нам понадобится использовать несколько php для загрузки фидов во Flash. Вот почему у нас есть константа CURL. Убедитесь, что они размещены ниже объявления класса, но над основной публичной функцией.

01
02
03
04
05
06
07
08
09
10
11
12
13
public class yahoo_map extends Sprite
    {
        private static const APPID:String = «YOUR APP ID»;
        private static const CURL:String = «curl.php»;
        private var map:YahooMap;
        private var ds:DropShadowFilter;
        private var geo:Namespace;
        private var tsuArray:Array;
        private var tsuCounter:int = 0;
        private var color:ColorTransform;
        private var group:RadioButtonGroup;
         
        public function yahoo_map()

Здесь мы создадим все наши переменные. После поиска в Google я нашел четыре RSS-канала для предупреждений о цунами от weather.gov. Я загрузил их в переменную tsuArray, чтобы я мог загрузить их по одному. Пространство имен geo поможет найти широту и долготу всех RSS-каналов. Кроме того, есть новая RadioButtonGroup, которая будет обрабатывать переключение компонентов RadioButton на сцене. Наконец, я вызываю функцию handleMap. Это запустит процесс загрузки карты.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
public function yahoo_map()
        {
            init();
        }
         
        private function init():void
        {
            tsuArray = new Array(«http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_pacific.xml», «http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_hawaii.xml», «http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_indian.xml», «http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_caribe.xml»);
            geo = new Namespace(«http://www.georss.org/georss»);
            ds = new DropShadowFilter(2,90,0×00000,0.75,2,2,1,3);
            color = new ColorTransform();
            group = new RadioButtonGroup(«Disasters»);
            handleMap();
        }

Это где мы начинаем работать с основами карты и где мы будем использовать наш идентификатор приложения. Кроме того, когда мы вызываем метод map.init (), мы указываем размер, которым мы хотим, чтобы карта была. Карта будет иметь ширину сцены и иметь высоту, которая касается верхней части компонента TextArea. Мы также слушаем событие MAP_INITALIZE.

1
2
3
4
5
6
private function handleMap():void
        {
            map = new YahooMap();
            map.addEventListener(YahooMapEvent.MAP_INITIALIZE, onInit);
            map.init(APPID, stage.stageWidth, 330);
        }

Когда карта инициализируется, она запускает функцию onInit. Здесь мы добавим карту к пустому фрагменту ролика, который был размещен на сцене. Таким образом, карта будет загружаться под компонентами TextArea и RadioButton — на всякий случай. Затем мы добавляем виджеты масштабирования, панорамирования и ввода. Они управляют типом карты, добавляют возможность панорамирования карты и добавляют элементы управления масштабированием. Мы центрируем карту до 0,0.

Карта ищет новую переменную LatLon, к которой вы подключаете два числа. Я использовал 0,0, чтобы установить карту, где встречаются экватор и меридиан. После этого устанавливается уровень масштабирования карт. Это установлено на максимально возможную высоту. Таким образом, мы можем увидеть все предупреждения о стихийных бедствиях по всему миру. Затем мы вызываем функцию, чтобы начать загрузку наших RSS-каналов.

01
02
03
04
05
06
07
08
09
10
private function onInit(event:YahooMapEvent):void
        {
            empty.addChild(map);
            map.addZoomWidget();
            map.addPanControl();
            map.addTypeWidget();
            map.zoomLevel = 17;
            map.centerLatLon = new LatLon(0,0);
            volcanoes();
        }

Мы должны выйти из Flash на секунду и немного поработать над PHP. Когда я начал делать этот проект, я понял, что каналы не будут загружаться на мой сайт. Быстрый и простой способ обойти это — использовать cURL. Я нашел полезный пример кода от Google. Я не очень уверен, откуда именно это взялось, но я уже некоторое время использую тот же сценарий. Откройте новый файл PHP, вставьте следующий код и сохраните его как «curl.php»

01
02
03
04
05
06
07
08
09
10
<?php
$ch = curl_init();
 
curl_setopt($ch, CURLOPT_URL, $_POST[‘earl’]);
curl_setopt($ch, CURLOPT_HEADER, 0);
 
curl_exec($ch);
 
curl_close($ch);
?>

Теперь, когда мы вызвали функцию, чтобы начать загрузку канала вулкана, мы можем взглянуть на то, что происходит внутри функции. Проще говоря, мы загружаем нашу страницу curl.php, которая загружает канал RSS. Затем мы добавляем прослушиватель для загрузки страницы.

01
02
03
04
05
06
07
08
09
10
11
private function volcanoes():void
        {
            var url:URLLoader = new URLLoader();
            url.addEventListener(Event.COMPLETE, onVolcano);
            var vars:URLVariables = new URLVariables();
            var req:URLRequest = new URLRequest(CURL);
            req.method = URLRequestMethod.POST;
            vars.earl = «http://volcanoes.usgs.gov/rss/vhpcaprss.xml»
            req.data = vars;
            url.load(req);
        }

В первом ленте есть несколько интересных функций. Наиболее важным из них является гео: точка. Это широта и долгота предупреждения. Кроме того, в этом фиде есть цветовой код для отображения уровня оповещения об активности. С загруженным каналом есть два списка XML, которые будут загружены. Один для широты и долготы. Другой для цветового кода.

Списки перебираются, и новые маркеры создаются на карте. Пользовательские видеоклипы добавляются к маркерам, они сделаны с использованием функций, которые я скоро опишу. Цвет вложенных фрагментов ролика контролируется с помощью свойства «colorTransform». После загрузки канала и размещения маркеров следующий канал RSS загружается. Я также передаю текст описания во вновь созданный мувиклип, чтобы я мог получить его позже, используя имя, которое было присвоено мувиклипу.

1
2
3
4
5
6
7
8
private function onVolcano(event:Event):void
        {
            var vol:Namespace = new Namespace(«http://volcano.wr.usgs.gov/rss/volcanons/1.0»);
            var xml:XML = new XML(event.target.data);
            var pointList:XMLList = xml..geo::point.text();
            var colorList:XMLList = xml..vol::colorcode.text();
            var string:String;
            for(var i:uint; i

Теперь пришло время загружать RSS-ленту о землетрясениях. Функции работают почти так же, как и раньше.

01
02
03
04
05
06
07
08
09
10
11
private function earthQuakes():void
        {
            var url:URLLoader = new URLLoader();
            var vars:URLVariables = new URLVariables();
            var req:URLRequest = new URLRequest(CURL);
            req.method = URLRequestMethod.POST;
            vars.earl = «http://earthquake.usgs.gov/eqcenter/catalogs/1day-M2.5.xml»
            req.data = vars;
            url.addEventListener(Event.COMPLETE, onEarthQuake);
            url.load(req);
        }

Разница в том, что для этого канала нет цветового кода. Вместо этого я просто меняю цвет на коричневый. Кроме того, описание предупреждения содержит html. Я использовал регулярное выражение, которое недавно натолкнулось на Google, чтобы убрать из него весь HTML. Без этого компонент TextArea загрузит изображение, которое я не хотел.

Еще одна вещь, которую стоит отметить, это то, что это другой тип RSS-канала. По некоторым причинам (по моему опыту) каналы Atom не любят анализировать должным образом. Чтобы обойти это, нужно было спуститься по дочернему дереву к первому предмету. Кроме того, узел элемента не всегда имеет одинаковое количество дочерних элементов. Я добавил простое заявление if, чтобы объяснить это. Наконец, мы вызываем функцию для загрузки последнего из RSS-каналов.

01
02
03
04
05
06
07
08
09
10
11
private function onEarthQuake(event:Event):void
{
    var xml:XML = new XML(event.target.data);
    var list:XMLList = xml..geo::point.text();
    var string:String
    for(var i:uint; i<\/?\w+((\s+(\w|\w[\w-]*\w)(\s*=\s*(?:\».*?\»|’.*?’|[^’\»>\s]+))?)+\s*|\s*)\/?>/gi;
        string = string.replace(pattern, «»);
        earth.desc = string;
    }
    tsunamis();
}

Это где мы начинаем загружать каналы цунами. Мы создали tsuCounter, чтобы мы могли увеличивать число при каждой загрузке канала. Когда счетчик достигнет конца tsuArray, мы добавим прослушиватели изменений в созданную группу RadioButtonGroup. Поскольку я хочу иметь доступ к каждому маркеру, созданному в каждом массиве, я добавил tsuCounter в начало названия фрагмента ролика. Таким образом, я смогу получить доступ к описанию от 0Tsunami1 и 1Tsunami1.

Наконец, когда все каналы загружены, мы добавляем прослушиватель событий в RadioButtonGroup.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private function tsunamis():void
        {
            var url:URLLoader = new URLLoader();
            var vars:URLVariables = new URLVariables();
            var req:URLRequest = new URLRequest(CURL);
            req.method = URLRequestMethod.POST;
            vars.earl = tsuArray[tsuCounter]
            req.data = vars;
            url.addEventListener(Event.COMPLETE, onTsu);
            url.load(req);
        }
        private function onTsu(event:Event):void
        {
            tsuCounter++;
            if(tsuCounter == tsuArray.length)
            {
                group.addEventListener(Event.CHANGE, onChange);
            } else
            {
                tsunamis();
            }
            var xml:XML = new XML(event.target.data);
            var list:XMLList = xml..geo::point.text();
            var string:String;
            for(var i:uint; i

Это функции, которые добавляют маркеры, управляют внешним видом маркеров, устанавливают долготу и широту маркеров и создают видеоклипы в маркерах. Функция drawMarker создает новый маркер, добавляет тень, затем добавляет к ней фрагмент ролика, передает ему то же имя, что и фрагмент ролика, получает широту и долготу из загруженного канала RSS и, наконец, добавляет прослушиватели событий. В маркер добавлен маркер-менеджер карты. Функция drawCircle просто рисует круг шириной 10 пикселей. Функция getLatlon берет переданную ей строку, разбивает ее на части и возвращает LatLon. Последняя функция, Color, обрабатывает различные цвета, передаваемые ей через канал вулкана.

01
02
03
04
05
06
07
08
09
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
private function drawMarker(mc:MovieClip, string:String, name:String):void
        {
            var marker:Marker = new Marker();
                marker.filters = [ds];
                marker.addChild(mc);
                marker.latlon = getLatlon(string);
                marker.name = name;
                map.markerManager.addMarker(marker);
                marker.addEventListener(MouseEvent.ROLL_OVER, onOver);
                marker.addEventListener(MouseEvent.CLICK, onClick);
        }
        private function drawCircle():MovieClip
        {
            var mc:MovieClip = new MovieClip();
            mc.graphics.beginFill(0xFF0000, 1);
            mc.graphics.drawCircle(5,5,5);
            mc.graphics.endFill();
            return mc;
        }
        private function getLatlon(string:String):LatLon
        {
            var array:Array = string.split(/[\s]/);
            var latlon:LatLon = new LatLon(array[0], array[1]);
            return latlon;
        }
        private function theColor(string:String):ColorTransform
        {
            var int:uint;
            switch (string)
            {
                case «ORANGE» :
                int = 0xFD8000;
                break;
                case «GREEN» :
                int = 0x225E33;
                break;
                default :
                int = 0xFF0000;
            }
            var ct:ColorTransform = new ColorTransform();
            ct.color = int;
            return ct;
        }

Когда пользователь переворачивает маркер, описание предупреждения отображается в компоненте TextArea. Это обрабатывается с помощью функции onOver. Цель ставится как маркер, используя имя, которое ей передали. Затем мы получаем текст описания, который был передан в мувиклип, вложенный в маркер, и отправляем его компоненту TextArea. Событие onClick перемещает карту в зависимости от того, какой маркер был нажат. Это делается с помощью метода map.panToLatLon ().

01
02
03
04
05
06
07
08
09
10
11
private function onOver(event:MouseEvent):void
        {
            var marker:Marker = Marker(map.markerContainer.getChildByName(event.target.name))
            var mc:MovieClip = MovieClip(marker.getChildByName(event.target.name));
            textArea.htmlText = mc.desc;
        }
        private function onClick(event:MouseEvent):void
        {
            var marker:Marker = Marker(map.markerContainer.getChildByName(event.target.name))
            map.panToLatLon(marker.latlon);
        }

Финальным событием является событие onChange. Это событие отключает все видеоклипы, кроме выбранных кнопок. Кроме того, она отображает карту на самое последнее предупреждение, полученное в ленте RSS.

01
02
03
04
05
06
07
08
09
10
private function onChange(event:Event):void
{
    var g:RadioButtonGroup = RadioButtonGroup(event.target);
    var i:uint;
    var marker:Marker;
    var panTo:Marker;
    switch(g.selection.name)
    {
        case «radioVolcano» :
        for(i = 0; i

Вот как выглядит окончательный код.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package {
     
    import com.yahoo.maps.api.YahooMap;
    import com.yahoo.maps.api.YahooMapEvent;
    import com.yahoo.maps.api.core.location.LatLon;
    import com.yahoo.maps.api.markers.Marker;
     
    import fl.controls.RadioButtonGroup;
    import fl.controls.RadioButton;
     
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.DropShadowFilter;
    import flash.geom.ColorTransform;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.net.URLRequestMethod;
    import flash.net.URLVariables;
    import flash.text.AntiAliasType;
    import flash.text.Font;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
 
    public class yahoo_map extends Sprite
    {
        private static const APPID:String = «YOUR APP ID»;
        private static const CURL:String = «curl.php»;
        private var map:YahooMap;
        private var ds:DropShadowFilter;
        private var geo:Namespace;
        private var tsuArray:Array;
        private var tsuCounter:int = 0;
        private var color:ColorTransform;
        private var group:RadioButtonGroup;
         
        public function yahoo_map()
        {
            init();
        }
        private function init():void
        {
            color = new ColorTransform();
            tsuArray = new Array(«http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_pacific.xml», «http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_hawaii.xml», «http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_indian.xml», «http://www.prh.noaa.gov/ptwc/feeds/ptwc_rss_caribe.xml»);
            geo = new Namespace(«http://www.georss.org/georss»);
            ds = new DropShadowFilter(2,90,0×00000,0.75,2,2,1,3);
            group = new RadioButtonGroup(«Disasters»);
            handleMap();
        }
        private function handleMap():void
        {
            map = new YahooMap();
            map.addEventListener(YahooMapEvent.MAP_INITIALIZE, onInit);
            map.init(APPID, stage.stageWidth, 330);
        }
        private function onInit(event:YahooMapEvent):void
        {
            empty.addChild(map);
            map.addZoomWidget();
            map.addPanControl();
            map.addTypeWidget();
            map.zoomLevel = 17;
            map.centerLatLon = new LatLon(0,0);
            volcanoes();
        }
        private function volcanoes():void
        {
            var url:URLLoader = new URLLoader();
            url.addEventListener(Event.COMPLETE, onVolcano);
            var vars:URLVariables = new URLVariables();
            var req:URLRequest = new URLRequest(CURL);
            req.method = URLRequestMethod.POST;
            vars.earl = «http://volcanoes.usgs.gov/rss/vhpcaprss.xml»
            req.data = vars;
            url.load(req);
        }
        private function onVolcano(event:Event):void
        {
            var vol:Namespace = new Namespace(«http://volcano.wr.usgs.gov/rss/volcanons/1.0»);
            var xml:XML = new XML(event.target.data);
            var pointList:XMLList = xml..geo::point.text();
            var colorList:XMLList = xml..vol::colorcode.text();
            var string:String;
            for(var i:uint; i<\/?\w+((\s+(\w|\w[\w-]*\w)(\s*=\s*(?:\».*?\»|’.*?’|[^’\»>\s]+))?)+\s*|\s*)\/?>/gi;
                string = string.replace(pattern, «»);
                earth.desc = string;
            }
            tsunamis();
        }
        private function tsunamis():void
        {
            var url:URLLoader = new URLLoader();
            var vars:URLVariables = new URLVariables();
            var req:URLRequest = new URLRequest(CURL);
            req.method = URLRequestMethod.POST;
            vars.earl = tsuArray[tsuCounter]
            req.data = vars;
            url.addEventListener(Event.COMPLETE, onTsu);
            url.load(req);
        }
        private function onTsu(event:Event):void
        {
            tsuCounter++;
            if(tsuCounter == tsuArray.length)
            {
                group.addEventListener(Event.CHANGE, onChange);
            } else
            {
                tsunamis();
            }
            var xml:XML = new XML(event.target.data);
            var list:XMLList = xml..geo::point.text();
            var string:String;
            for(var i:uint; i

Я только поцарапал поверхность для того, что YahooMaps имеет под капотом. Прочитайте документацию и сходите с ума!