Mapscript and XNA (3)

July 8th, 2007

Continuing with our program that combines Mapserver (via the Mapscript API) and XNA, we next added functionality to the update method our of XNA program. We check for a mouse click to initiate a map pan and also for key presses to zoom in, out and return to full extent. At the end, if any map event has occurred, the map will be updated. It is in the updating that a new Mapserver image is generated and prepared for displaying on-screen.

protected override void Update(GameTime gameTime)
{
    // check if a mouse click has occured
    mouse.Update();
    if (mouse.LeftButton == ButtonState.Pressed)
    {
        mapserver.ZoomMap(1, mouse.X, mouse.Y);
    }
 
    // check if a key has been pressed
    KeyboardState keyState = Keyboard.GetState();
    if (keyState.IsKeyDown(Keys.F))
    {
        graphics.ToggleFullScreen();
    }
    else if (keyState.IsKeyDown(Keys.Z))
    {
        mapserver.ZoomMap(2, mapserver.MapPixelCenter.X, 
                      mapserver.MapPixelCenter.Y);
    }
    else if (keyState.IsKeyDown(Keys.X))
    {
        mapserver.ZoomMap(-2, mapserver.MapPixelCenter.X, 
                      mapserver.MapPixelCenter.Y);
    }
    else if (keyState.IsKeyDown(Keys.C))
    {
        mapserver.ZoomMapFullExtent();
    }
    else if (keyState.IsKeyDown(Keys.Escape))
        this.Exit();
 
    // check if a new mapserver image needs to be generated
    if (mapserver.RefreshMap)
    {
        mapserver.UpdateMap(graphics.GraphicsDevice);
    }
 
    base.Update(gameTime);
}


Each option relies on our MapserverXNA class discussed in the last post. Since all the functionality is hidden within this class, coding our main program is very straightforward. Additionally, zooming in and out is performed with the help of our Image Swapping class we created in a previous post. This adds a fading in/out effect but none of this code is even visible in the main program.

As shown above, a mouse click invokes a pan of the map (click here for more information on zooming and panning with Mapscript). The mouse’s X/Y click coordinates will become the new center of the map. Within the MapserverXNA class, we added a shift effect when a pan occurs using the previously mentioned Image Swapping class. Upon the mouse click, the existing image is shifted and then the new image then just replaces it. This sliding effect is an alternative to the fading effect used for zooming b/c it wouldn’t make sense to pan the map and then fade in the new image.

The last portion of code added is in the draw method. Here we draw our map image, mouse cursor, and some text.

protected override void Draw(GameTime gameTime)
{
    graphics.GraphicsDevice.Clear(Color.White);
    spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
 
    mapserver.DrawMap(spriteBatch, gameTime);
 
    mouse.Draw(spriteBatch);
 
    spriteBatch.DrawString(font, "Z = Zoom in", new Vector2(5, 4), Color.Black);
    spriteBatch.DrawString(font, "X = Zoom out", new Vector2(5, 16), Color.Black);
    spriteBatch.DrawString(font, "C = Full Extent", new Vector2(5, 28), Color.Black);
    spriteBatch.DrawString(font, "Click to pan", new Vector2(5, 40), Color.Black);
 
    spriteBatch.End();
 
    base.Draw(gameTime);
}

Conclusion

This post concludes probably the most complex project we have demonstrated so far. Some of the Mapserver-related code was not discussed because it has been covered in our previous projects (Mapserver – 10 Minute Tutorial, Mapscript Demo). The entire source code for this project is available to download below. The program’s requirements (C#, XNA, Mapserver, and a valid Mapserver map file) have all been discussed in our other projects. Questions and comments are always welcome at james [at] spatialhorizons.com.

Download 
Source Code