Finished 1989 Flash Map

I had to dig this out of the depths of my computer today, and a quick search showed that I never posted the final version. So here it is in all it’s glory. 1989 Events

[kml_flashembed fversion=”8.0.0″ movie=”http://chnm.gmu.edu/staff/ammon/1989/1989events.swf” targetclass=”flashmovie” publishmethod=”static” width=”540″ height=”360″]Get Adobe Flash player

[/kml_flashembed]

The MA is done, but the map is not….

I just turned in my last thing for the MA! I’m a Master! I do the commencement and walking and stuff tomorrow night.

Well, I showed the Yahoo Map and the Flash movie to the 1989 group. They really liked it, but as is always the case, there are some very good suggestions for improvement. And since I have a vested interest in the project (my academic research interests are all about this topic), and since I’m pretty much the only one at work who can do this stuff, I will be continuing the project until it’s completion.

Some suggestions and modifications are:

  • Move the text out of the Flash and into the html. This makes it available to search engines and styling.
  • Have the timeline only be for 1989, and put tick marks, or some other designator for months on the bar.
  • Change the fading of countries. Russia, Latvia, Estonia, Lithuania, and Yugoslavia should not fade out.
  • Change Soviet Union to Russia, and outline or shade the Yugoslavia and Soviet Union groups to show they are a group.
  • Take out the events for China.
  • For the yahoo Map: recenter the map on marker click, and take out the word wrapping.

So here’s the latest version of the Flash movie. 1989events

Making progress

I took out the audio from the intro because it just wasn’t working. Perhaps a voice recording about the fall of communism would be better.

I worked on the timeline a lot the past couple of days. It took many, many attempts to finally get the dot that represents an event to look nice. Fifteenth times a charm, they say! I also have the events coming in by year, month, and day. There’s probably an easy way to do that with actionscript, but I couldn’t think of it. So instead I have a layer for the years, divided into the three years (1987-1989). Then another layer for the months. Each of the three years gets it’s own set of months. Then a third layer for days (1-31, depending on how many days in the month). The days layer only has frames for November and March of 1989, when most of the events happened. So, on each section of frames I wrote a variable like theYear, theMonth, and theDay in the actionscript. This variable is then checked for in the main actionscript, and matched against the events day, month, year before it is allowed to be displayed.

It works pretty well, except for the 1989 events for December. The all show up at the same time. So, now I have to fix that, and add another 40+ coordinates to the xml file by deciding where it is located, finding the x, y coords, then typing it into the xml file.

Anyhow, here’s the latest and greatest Intro_Timeline

How does the yahoo/flash map work…

There’s a lot of tutorials out there, but here’s how I got it to work.

The Plan

Got what? Oh, well, basically it’s being able to use yahoo maps, flash, xml, php, mysql, and data to display a bunch of markers on a map. Each marker contains data pulled from the database, and has a link to a page that displays the full information. For now, I just made a display page. But sometime latter, it will be implemented into the fine Omeka install that the 1989 project will use.

The Steps

Here’s an outline of what I did.

  1. Create a flash file using the yahoo flash map api component. Available at Yahoo.
  2. Add some ActionScript to the first frame that will import data from an xml file.
  3. Create a php page that pulls in data from a MySQL database and displays as an xml file.

Create the swf

In order to make Yahoo and flash play nicely, you need to install the component linked above. Follow directions there. This will add a new component to your Flash program, available in your components window (Window->Components->Yahoo->com.yahoo.maps.api.flash.YahooMap).

Once that’s installed, create a new empty fla. Make a keframe in the first frame on layer one. Drag the yahooMap component onto your stage.

Next, add another layer for your actionscript.

the ActionScript

Here’s the tricky part. Here’s the code I used, heavily commented:

[code lang=”Actionscript”]
/*********************************
* File: yahoomap.as
* Author: Ammon Shepherd
* based off of many tutorials and code snippets, mostly from Yahoo! documentation.
********************************/
//Set the URL where the xml file is.
var xmlURL = “http://chnm.gmu.edu/1989/maps/xml.php”;

//Import Yahoo map tools
import com.yahoo.maps.LatLon;
import com.yahoo.maps.markers.CustomPOIMarker;
import com.yahoo.maps.tools.PanTool;
import com.yahoo.maps.widgets.*;

//Create a listener associated with the instance of the Yahoo map component.
// Set the map to pull down the yahoo map and get the setting/changes from
// the onMap function.
euroMap.addEventListener(com.yahoo.maps.api.flash.YahooMap.EVENT_INITIALIZE, onMap);

//This will add a zoom tool and set it as closed by default
var zoomer:NavigatorWidget = new NavigatorWidget(“closed”);

//The onMap function adds the tools, settings, and markers to the map.
function onMap(eventData) {
//create a new PanTool and name it pantool
var pantool:PanTool = new PanTool();

//tell the instance of the map to use the new PanTool called pantool
euroMap.addTool(pantool, true);

//Add the Navigator widget
euroMap.addWidget(zoomer);

//Create a variable called xmlData of the type XML
var locations_xml:XML = new XML();

//igore white space
locations_xml.ignoreWhite = true;

//when the xml file is loaded, do the fuction within
locations_xml.onLoad = function(success){
//if the xml file loaded successfully run the function addMarkers
if (success) addMarkers(this);
};

//then actually load the xml file.
locations_xml.load(xmlURL);

/*******************************************
* Used this for testing, you don’t really need it. I was thinking of using
* this in the future to display the lat and long to the user.
//Get the center of the map and store them in the variable called points.
var points = euroMap.getCenter();
//trace(“before convert” + points);
//swap the points, so long->long and lat->lat
convert(points);
//trace(points);
******************************************/

}

//This is the function that adds the markers to the map.
function addMarkers(xml:XML):Void {
//the addresses variable holds the path to the right xml element.
//firstChild is the and childNodes is an array of the tags
var addresses = xml.firstChild.childNodes;

for(var i=0; i then the second and so on for all of them.
address = addresses[i];

/***************************************************************
* MarkerData is the object that holds the info for each marker.
* index: is the text that shows up on the marker (usually just A or
* what have you. you could use the variable i to show an
* incremented number (each marker has it’s own number).
* title: sets the title of the marker and corresponds to the title
* parameter in the location tags in the xml file.
* description: is the larger text. It corresponds with the description
* parameter in the location tag in the xml field.
* markerColor: sets the color of the marker, duh 🙂 It’s the border
* color, and the color when not expanded.
* strokeColor: is the background.
***************************************************************/
var MarkerData:Object = {index: ‘\’89’, title:address.attributes.info, description:address.attributes.description, markerColor:0xcc0000, strokeColor:0xceccc7};

/****************************************************************
* This actually adds the address to the map using the custom point of
* interest style of marker (you can use your own style if you like.
* the address.attributes.loc grabs the latitude and longitude from
* the loc=”” part of the location tag in the xml file. MarkerData
* is the stuff we just set above.
****************************************************************/
euroMap.addMarkerByAddress(CustomPOIMarker, address.attributes.loc, MarkerData);
}
}
[/code]
Download yahoomap.as

(Special thanks to CodeSnippet for providing a way to show code. This was the 5th one I tried that finally worked.)

The PHP/XML

Next we need an xml file. I need to pull the data from a database, so I used a php script which pretends to be an xml file. The basics of that is to put this in the php file:
[code lang=”php”]
// Date in the past
header(“Expires: Mon, 26 Jul 1997 05:00:00 GMT”);
// always modified
header(“Last-Modified: ” . gmdate(“D, d M Y H:i:s”) . ” GMT”);
// HTTP/1.1
header(“Cache-Control: no-store, no-cache, must-revalidate”);
header(“Cache-Control: post-check=0, pre-check=0”, false);
// HTTP/1.0
header(“Pragma: no-cache”);
//XML Header
header(“content-type:text/xml”);
[/code]

Then, because our database doesn’t store the geocodes by default yet, nor do the items have any type of specific address or what not associated with them, I created an array with specific places and their lat, long. Each of the items in the database have tags associated with them. The array corresponds to tags that have countries names on them. This poses a problem if the tag name is changed, but for now it works OK.

[code lang=”php”]
$countries = array(
array(“Poland”, “52.1874047455997”, “19.072265625”),
array(“East Germany”, “52.517474393230245”, “13.41156005859375”),
array(“Czechoslovakia”, “49.210420445650286”, “17.490234375”),
array(“Hungary”, “47.45780853075031”, “19.05029296875”),
array(“romania”, “45.98169518512228”, “25.07080078125”),
array(“Yugoslavia”, “44.26093725039923”, “18.96240234375”),
array(“Bulgaria”, “42.601619944327965”, “25.24658203125”),
array(“Soviet Union”, “55.70235509327093”, “37.79296875”)
);
[/code]

The problem I ran into next was that there were over 15 markers that would share the same lat an long. This makes it hard to click on a marker when it’s buried under 20 other markers. So at first I tried just adding a couple of digits to the lat and long as it looped through the array. This led to a long line of markers, and didn’t look very good. Random numbers to the rescue! To create a clustering affect I generated two random numbers, one for the lat and one for the long. This number was added giving the markers a clustered appearance. Here’s that part of the code:

[code lang=”php”]
echo “< ?xml version='1.0' ?>

“;

for($g=0; $g‘;

}
}

echo ‘
‘;
[/code]

You may notice my call to the description function (which, in turn, calls a function called truncate, but you wouldn’t know that yet). This simply turns all HTML characters into their HTML entity characters. HTML in an XML file will break the XML file… more specifically the < and " ' characters. The truncate function I grabbed from php.net's comments for substr_replace. The truncate function shortens long text to a set number of words, and adds an ellipse at the end to signify more text. Here are those two functions:

[code lang=”php”]
function description($id,$text){
$description = wordwrap(htmlentities(truncate($text,200), ENT_QUOTES),30);

$fulltext = $description.”\n<a target=’_blank’ href=’http://chnm.gmu.edu/1989/maps/results.php?id=$id’>Show item</a>”;

return $fulltext;
}

function truncate($text,$numb) {
// source: www.kigoobe.com, please keep this if you are using the function
//$text = html_entity_decode($text, ENT_QUOTES);
if (strlen($text) > $numb) {
$text = substr($text, 0, $numb);
$text = substr($text,0,strrpos($text,” “));
$etc = ” …”;
$text = $text.$etc;
}
//$text = htmlentities($text, ENT_QUOTES);
return $text;
}
[/code]

Here’s the whole php file.
That basically does it.

xml, and lots of time.

Back again. Only two weeks left of school.

I spent the past two days trying to work XML into the picture for the time line aspect. The thought was, if all of the data for the ‘flash point’ or points of the events of 1989 were kept in an xml file, the the flash could dynamically add them in at the right place and time.  I can bring in the xml data, but I can’t get it to display the correct information for each event. It always shows the last events data. I have a for loop to grab all of the data from the xml file, then it attaches the ‘flash point’ movie clip in the correct place. Then I assign an onRollOver and onRollOut to that movie clip (dynamically named). But the onRollOver just holds the data from the last element in the xml instead of each attached movie clip holding the data for it’s respective event.

This would be really cool to do, because then to add or remove events from the timeline, just edit the xml file.  The xml filed could even theoretically pull the data in from the database, making so that each person can have their own specific timeline.  That would be way cool. But it unfortunately seems a bit beyond me. The other obstacle is about the time aspect. How can I get the flash point to show up at the right time. I’d have to come up with a bunch of mathematical voodo on where the timeline bar is (the _x position on the stage) and the percentage left and compare that with the date of the event somehow. Aargh! Way too confusing for my feeble brain.

I’ll just have to do the easy hard code the events into the timeline. Anyhow, here’s what I have so far on the intro/timeline (which, I’m realizing, I’ll need to have a front page where you select which one you want to view, or have them separate instead of one after the other). Version 0.0.2.3.9.5 (or something like that)

Getting it to work.

I’m finally getting somewhere with the Yahoo/Flash map. The latest is always viewable at http://chnm.gmu.edu/1989/maps/yahoo.html. Tonight I worked on getting the title and description to show up nice. The description is usually really long, so I found a php function that truncates it (without cutting of mid-word), and adds an elipse to show more text. I also figured out how to add html links to the xml data. There’s apparently a couple of different ways. I opted to have the first < in the a tag be written in as &lt ; (the HTML entity). That did the trick. Now the marker has a link to see the whole of the data. This should be a link back to the page that’s part of the real site (in Omeka).

Another idea: Add the ability in the admin side of things, to select an item, and then enter the geocodes for that item by clicking on the map in the appropriate spot. Flickr does something like that. It would make it really easy for admins to enter the geocodes.

The Continuing Saga of Map Making

So, I’ve decided to use the yahoo/flash option because it looks better, and it’s a bit easier to implement. The biggest impediment is not having geocodes for each item in the database. Here are some steps that must be taken before the map can work.

  1. The database needs to add a longitude and latitude field for items.
  2. Each item then needs their long/lat entered in.
  3. After that happens use the commented code below in the xml.php file:
  1. //$sql = “SELECT item_title, item_description, item_longlat FROM items ORDER BY item_date”;

There’s a couple of options for the field names and what they contain. This is, of course, all to be determined by the Omeka makers, and not me, but here’s my take on it anyway.

  1. item_longlat = would hold the longitude and latitude in format lon,lat
  2. item_long & item_lat = hold the long and lat separately, that might be cool for searching on items that are on the same long or lat.
  3. item_geocode = same as item_longlat, but a different name.

As for the Flash introduction, I still need to get the list of events that should be displayed. I also played with creating a new flash intro based on the new yahoo map of Europe, and the style of the markers. I’ll also need to think of a way to deal with markers whose information would tend to go off screen. I’ll have to make them ‘stage’ aware, or place them individually.

The last item is creating a map, that, when a country is clicked on, will return all of the items from that country. A couple of options on that are to have it return a yahoo map with markers showing items from that country, or to just return a normal list.

I think I’ll Yahoo!

I did some more researching and playing around with the Yahoo and Flash options and I think this will be the better way.  As an example of why, look at Justin Everett-Church’s work creating custom ‘themes’ for the maps.

Also in my search I came across some neato projects Trippermap plots your flickr photos on a map that you can host or plug into your own web page.

Plazes.com if for those of you who like to let everyone know where you are at any moment of the day. A bit too much of an information overload for me, but there’s 6 billion people in this world, so there’s bound to be a few thousand that get hooked by this idea.

Of course Flickr’s own map deal would be the ideal set up for this project. I’ll get some of the functionality, but it would be awesome to get something like this going.

I’ll be back with more results…

To Google, or not to Google. That is the question.

So, I am now in the stage where I decide how to plot the objects from the database onto a map. The question becomes, which map technology do I use. There are several options.

  1. Google Map, using the Google Map API.
  2. Yahoo! Maps, using the Yahoo! Maps API
  3. Build the map in Flash.
  4. Some form of GIS map.

The first two are relatively easy to accomplish. I just need to pull the info from the database (the longitude and latitude if available, or at least the city and country), make an xml file from that. Have the map page read that xml file for plotting and displaying. The issues with these two methods are getting them to properly display in all browsers, and figuring out how to work the API’s to get the map to look like I want it to.

The third option (Flash) will be much more difficult. It would be really easy to make the map look like I want, but I’m not sure how the plotting of the points would work. I would think each object would have to be identified with a certain point on the Flash movie stage. I don’t know how to be able to use the longitude and latitude to place the objects in the right place on the map. I actually just did a quick search and found this article which might swing the tide to a ‘mashup’ of both 2 and 3, Yahoo! and Flash.

The last option is to use a form of GIS map. While these can generate some pretty cool looking maps, it is mostly due to geographical data compiled by others (elevation, population density, political boundaries, etc). It would require learning a whole new set of tools, programs and technology.

I’m going to try the Yahoo! and Flash setup and see if that will do what I need it to.