Live Interactive Weather Observations Map for the United States of America

November 8th, 2005

Well after a larger number of changes than anticipated, I have ceated a Live USA Observations Map. This is an adaption my Australian Observations Map. This version is very similar to the Australian one with a few noteable differences. First though an overview of the functionality:

  • Zoomable map Live Observations from the US using Google Maps
  • Icons indicating temperature (F), along with wind strength and direction.
  • Clickable markers show a graph summarising the last 3 days worth of weather for that location along with a textual summary of the most recently available conditions.
  • The graph in the popup shows temperature, dew point, humidity, wind speed, wind direction, and pressure
  • Markers for all the radar sites around the country with a popup showing the latest scaled image, and a link to the current animation loop.
  • You can select a particular location from the station selector on the right hand side by selecting a state, then a station.
  • When you click on an observation marker, nearby locations are displayed in the top left hand side. From here you can select these stations for display
  • All observational markers in the shown area are displayed when you zoom in sufficiently to allow them to display without clutter, though you can at any zoom level, select a marker for display from the station selector on the top left hand side

The main differences from the Australian version are as follows. Some of these will be corrected, some are a little more difficult :

  • Observation markers don’t show up until you zoom in sufficiently, this is so that the map can operate efficiently, as well as prevent clutter of the map when zoomed out a long way. In future if this can be done more efficiently, then the observation markers would probably be enabled at a lower zoom (ie. more zoomed out) level. The Australian version always shows all observation markers
  • To accomodate the greater numerical range of farenheit I have had to make the observation markers larger. With centigrade in Australia, temperatures almost never requrie more than 2 characters (ie. -9 to around 55 degrees celcius) to be represented. Very rarely do temperatures get below -9 in Australia.
  • Shipping observations aren’t currently shown, but will be enabled soon hopefully.
  • Due to the larger number of observations, and the recent use of PdMarker I have not created separate label markers for each observation point. This improves efficiency, and you can still ‘hover’ over a marker to see what the location is.
  • All metric units have been converted to imperial units
  • The timezone for all observational data displayed is currently set to US Eastern Standard Time, though I hope to add in a timezone selector for all US timezones.
  • No rainfall data is displayed. Currently I can’t find a source of recent (ie last hour) rainfall for locations across the US. 24hour rainfall data is available and that at least will hopefully be presented soon.

Any comments, suggestions, or questions welcome!

Google Maps : ‘moveend’ and ‘zoom’ event ordering.

October 27th, 2005

I decided to implement a reduction in markers on my google maps weather site based on zoom level. The basic idea was to remove the label markers when you got to a zoom level of 11 or higher, as most became too cluttered, and it used more memory/resources.

I thought a simple listener on the ‘zoom’ event would do the trick, but it turns out that because I was also listening for ‘moveend’ and updating visibility based on that, it didn’t quite work out that way. Because ‘moveend’ was actually triggered before ‘zoom’ the visibility of all markers, including labels that I was about to hide, was updated. Then after this the ‘zoom’ was called, by which time the client had spent time displaying more labels, they would be (mostly) removed again. This also caused some issues due to the delayed caching mechanism where new labels would be displayed regardless of wether they were meant to be.

To me the ‘zoom’ event makes more sense to go before the ‘moveend’, but it seems that it would be a little trickier for google to implement given the layout of the code. So what we need here is a ‘zoomstart’ event… With some sample code & pointer from Mike Williams, I was able to very simply add in this event as an override to the ‘zoomTo’ function. This means now that I can hide my labels when the zoom starts, and then when the marker visibility is updated when ‘moveend’ is called, it doesn’t try to show the labels, only to remove them on ‘zoom’.

You can see it in action here, the overridden method ended up looking as below, with only the one line change :

GMap.prototype.zoomTo=function(a){
      if(!this.isLoaded()){
        return
      }
      if(a>=this.spec.numZoomLevels){
        a=this.spec.numZoomLevels-1
      }
      else if(a<0){
        a=0
      }
      var b=this.zoomLevel;
      GEvent.trigger(this,"zoomstart",b,a)   // New event
      if(a!=this.zoomLevel){
        if(!this.centerLatLng)this.centerLatLng=this.getCenterLatLng();
        this.zoomLevel=a;
        var c=this.spec.getBitmapCoordinate(
                this.centerLatLng.y,this.centerLatLng.x,this.zoomLevel);
        this.centerAtBitmap(c)
      }
      GEvent.trigger(this,"zoom",b,this.zoomLevel)
}

Google Maps with lots of custom icons

October 24th, 2005

Getting google maps to load effectively with Internet Explorer has been a real battle. Due to issues with both Apache 1.3 and Internet Explorer I have had to do a number of things to get my Australian Observations Map to work efficiently. The main reason for the problem is that I want to load a lot (hundreds) of icons, with most of them being different. By default IE wouldn’t cache these properly, and would tend to re-request these icons even if it had just loaded, or was currently loading them. This had the effect of locking up the browser for up to minutes at a time, and made scrolling around the map painfull when it needed to load new icons. It all works fine in Firefox.

Anyway, here is some javascript that illustrates the solution, the basic flow of this code is :

  • When the map moves or first loads iterate over each ‘marker’ you have ‘updateMarkerVisibility’.
  • Check if the marker is in the current map bounds and not visible.
  • If it is, then see if we have the icon for that marker cached.
  • If we do, then add it to the list of markers to be made visible (via addOverlays, which it seems is now redundant)
  • If it isn’t cached, then indicate, we have markers ‘yet to display’ (incomplete)
  • The ‘completeVisibilityUpdate’ is called to periodically look for any new markers that have since loaded (every 1 second here), and if the icon is loaded, only then to display the marker

A variant of the code below can be found at the example here : Australian Observations Map.

I have ‘extracted’ this code from where it was being used, so let me know if anyone has problems!

// Globals :
var iconCache = new Array();
var loadingMarkers = null; // Markers currently needing loading.
var delay_time = 100; // 100 = 1 second.
// Load up the given image URL. Returning true if it is loaded :
function cacheImage(url) {
if (iconCache[url]) {
// We have a cached image, see if it is loaded :
if (iconCache[url].complete) {
return true; // Cached!
} else {
return false; // Still Loading
}
} else {
// Cache the image :
iconCache[url] = new Image();
iconCache[url].src= url;
return false; // Loading started
}
}
// Finish updating visibility of markers once the icons have finished loading :
function completeVisibilityUpdate() {
var additions = new Array();
var incomplete = 0;
var deleteIndexes = new Array();
for (var i in loadingMarkers) {
m = loadingMarkers[i];
if ((m != null) && (! m.attached)) {
if (cacheImage(m.icon.image)) {
m.attached = true;
additions[additions.length] = m;
} else {
incomplete +=1;
}
}
}
if (additions.length) {
map.addOverlays(additions);
}
if (incomplete) {
setTimeout("completeVisibilityUpdate()", delay_time); // Set the timer for the next update.
}
}
// Update markers based on being visible in the current region.
function updateMarkerVisibility() {
var additions = new Array();
var incomplete = 0;
var bounds = map.getBoundsLatLng();
loadingMarkers = new Array();
// Update main markers :
var count = 0;
for (var i in markers) {
if (! visibleLayers[i])
continue; // Don't update non-visible layers.
for (var id in markers[i]) {
m = markers[i][id];
if (
(m != undefined) && (
(m.attached == false && m.point.x >= bounds.minX && m.point.x < = bounds.maxX && m.point.y >= bounds.minY && m.point.y < = bounds.maxY))
)
{
ready = cacheImage(m.icon.image)
if (ready) {
m.attached = true; // Image ready for display
additions[additions.length] = m;
} else {
incomplete += 1;
loadingMarkers[loadingMarkers.length] = m;
}
}
}
}
// Add in loaded markers :
map.addOverlays(additions);
if (incomplete) {
setTimeout("completeVisibilityUpdate()", delay_time); // Finish loading these markers.
}
}

Photography Discussions Added

September 22nd, 2005

I have just added the first lot of usenet photography discussions. These discussions have been analysed to present links to other possibly relevant posts using a domain specific keyword matching technique. This provides a ’see also’ type functionality where an article that isn’t part of the same discussion as the current article, that also ‘matches’ the current article best is displayed along with it. I will be refining this algorithm and updating the look and feel of the pages as this develops. The content will also be regularly updated. Anyway to see what’s there, have a look at the Photography Discussion Resources. There is also a lot of ‘rubbish’ content in this data so I will be looking at ways of filtering this out.

In the beginning!

September 21st, 2005

Well this is the first post in this new blog… This blog will cover a very broad range of topics, but initially will focus on photography, the main focus of this website. Stay tuned for more articles…