Saturday, November 15, 2008

More struggles with OpenLayers API

The problem that I thought I had solved to get the initial display of the map to be centered at the desired location was not really solved. When I came back to the project the next day I realized that if I tried to move the map around on the screen it was not displaying any part of the map outside the bounds I had set in the WMS call. Not only that, but the debugging code I had that would display the coordinates when I clicked on the map was giving values that were nowhere near what they should be. The upper left corner one day was latitude = 34 and longitude = -85.99609375; the next day it was latitude = 11.373535 longitude = 123.24755837499998. I spent a day and a half messing with that.

At the point where I finally decided I had to create a new project and build up piece by piece with a very basic map, the problem suddenly vanished. The portlet that was left on the page from the previous problem project was suddenly displaying the right coordinates after the server loaded the map in the portlet for the new project. I could come up with no explanation as to what caused the problem and then what fixed the problem. I was just glad that it was fixed.

Thanks to help from my friend Matt Zollinhofer, there was an answer to the problem of getting the map centered where I wanted it. The code from the FAQ that explained how to get a specific bounds to load was:

layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://labs.metacarta.com/wms/vmap0?",
{'layers': 'basic'},
{'maxExtent': new OpenLayers.Bounds(-180,-90,180,90), 'maxResolution': "auto"});
map.addLayer(layer);
map.zoomToMaxExtent();

I thought that all I had to do was change the (-180,-90,180,90) to the (-86,31,-84,34) BBOX that I wanted. What I didn't realize was that (-180,-90,180,90) represented the whole world and what I was doing with my BBOX was limiting the WMS layer to just that piece of the map. Matt suggested a better solution where I now create a point and a zoom level and after setting up the layers and events that I want I then make a map.setCenter call to get the map to display where I want it.

A whole lot more work went on in figuring out a way, once I had the map display with some features on it, for the user to be able to click on one of the features and see the data for that feature. I would have thought that was some function call that was built into OpenLayers WFS, but that isn't the case. A basic WFS example that I found was returning the whole set of WFS data when the user clicked anywhere on the map. I had to play around with the BBOX parameter in the getFullRequestString call.

Now, when the user clicks the map, I read the pixel value and the coordinate value and do some math to get 2 new pixels which represent a box around the original pixel. I then convert the pixels to coordinates and use those for bounds. Not real accurate and not a lot of error checking (what happens if one of the pixel values comes out to a negative number after I do the subtraction?), but most of the time it has the desired effect. There has to be a better way to do this.

No comments: