Skip to main content

New MiniApp: Storm Drain

Posted by joshy on September 22, 2004 at 7:25 AM PDT

While playing around some more with this
miniapp idea, I came across geographer Tyler
Mitchell's href="http://www.oreillynet.com/pub/wlg/5542">weblog
post about hurricane tracking using Web Map
Service urls. I thought this would make an
interesting MiniApp and give me a good opportunity
to play with a few webservices. Starting from his
base (and with some greatly appreciated
clarification emails from Tyler), I've created
StormDrain, a simple program that loads WMS
data and displays it graphically. Here's what it
looks like:



Storm Drain: Jeanne Data

WMS data services give you access to lots of
useful information. It can render storm data for
any geographic area and resolution you want,
returned in a variety of image formats. It also
has a discovery mechanism that lets you
programmically find out what storm data is
available. href="http://dev.gomoos.org/cgi-bin/wms_nhc?request=getcapabilities">http://dev.gomoos.org/cgi-bin/wms_nhc?request=getcapabilities
will provide you with a XML list of every request
and format the service understands.

In my program you can left click to recenter
and zoom, and right click to zoom out. The
Storms menu gives you the list of storms
generated by the GetCapabilities request type. It
uses a zoom factor to determine which latitude and
longitude to use when requesting the maps.

The land map images have a light blue
background that I wanted to replace with something
more oceany. To pull this off I created a color
swap filter that will replace one color with
another. For the land data it replaces the
background with a dark blue. For the storm data it
replaces the background with the transparent color
(0,0,0,0) so that the other layers will shine
through.

Java2D's image APIs make this kind of a color
filter quite easy to implement. First you need a
custom RGBImageFilter called ColorSwapFilter:

class ColorSwapFilter extends RGBImageFilter {
    private int target;
    private int replacement;
    public ColorSwapFilter(Color target,
                           Color replacement) {
        this.target = target.getRGB();
        this.replacement = replacement.getRGB();
    }

    public int filterRGB(int x, int y, int rgb) {
        if(rgb == target) {
            return replacement;
        }
        return rgb;
    }
}

Any RGBImageFilter must implement the filterRGB
method, which will return a new color based on the
input color at the current x and y coordinates. In
this case it returns the replacment color when the
current color matches a target, otherwise it just
returns the original color. Note that I've used
getRGB() to work with the colors as integers
instead of color objects.

Filter in hand, you can now filter any image to
swap the colors. This is a utility function that
gets the source image, creates a new filter to
swap the target color with a transparent color,
then executes the filter with a call to createImage()
on any component (a new JPanel in this case). It's
that simple

public Image loadTransImage(URL url, Color target) {
        Image src = new ImageIcon(url).getImage();
        ImageFilter imgfilter =
           new ColorSwapFilter(target,new Color(0,0,0,0));
        Image img = new JPanel().createImage(
           new FilteredImageSource(src.getSource(),imgfilter));
        Image imgx = new ImageIcon(img).getImage();
        return imgx;
    }

StormDrain loads data from a WMS service provided by GoMoos.org

Storm Drain webstart link

updated webstart link

Related Topics >>