Sunday, November 30, 2008

Groovy and Grails

I knew that I would need something to occupy my time on a 9-hour road trip traveling home from a Thanksgiving holiday trip. Groovy and Grails are not part of what I am supposed to be learning for GIS and portlets, but after attending a Grails talk by Scott Davis at the NFJS symposium November 7, I thought it would be something easy and fun to learn. I had purchased "Beginning Groovy and Grails" by Judd, Nusairat, and Shingler for light reading during the times I was not able to get online. Before leaving on Sunday morning I downloaded groovy-1.5.7-installer.exe and had read enough of the introductory chapters in the book that I felt comfortable beginning the installation.

After being sufficiently bored with the scenery, I pulled out my Dell Inspirion and set to work. The book had a few basic steps in the installation section that involved just unzipping the download and modifying a couple of environment variables. Then the book said that you could test the installation by issuing the "groovy -version" command. I'm sure I could have handled doing that. But when I looked in the download folder I realized that what I had downloaded was the installer and not just the zipped binary. I'd have to trust that all the "automagic" stuff used by the installer would be done correctly.

First, of course, is that it wanted to install to C:\Program Files, which is not where I wanted it. The installer seemed to accept my choice of location. It also seemed to be completing successfully until it got to an "Additional Modules" screen where it hung up and the title bar on the window showed "Module Not Responding". Windows Vista has a habit of getting hung up and there wasn't much I could do but wait it out. The screen finally went away and the installation appeared to have finished. I opened a command prompt window to see if it could recognize the "groovy -version" command. Nope, couldn't find the command. Checking the environment variables, including the PATH variable, showed that they had been set correctly.

Next, I changed to the groovy\bin directory and then it found the command but gave an error

Unrecognized option: -version
error: jvm creation failed with code -1: unknown error

OK, maybe something didn't install correctly. I used the uninstall.exe program and then started the installer over again. This time it only hesitated momentarily at the "Additional Modules" screen. There was more displayed in that screen than what I had seen the first time. There were also additional screens after that one. It looked like an error in the first installation is what caused the problem.

Back to the command line to try again. Windows still couldn't find the groovy command. And when I changed to the groovy\bin directory it was the same error. Did anything install correctly? How about if I just issue the groovy command at the command line with no parameters? Isn't that supposed to tell you what parameters the command will recognize? Sure enough, just typing groovy gave a list of all the allowable parameters. And, look there, where it tells you how to find the version. The parameter for finding the version is -v, not -version! Great--all this struggle and it boils down to one of those deals where somebody changed something in the usage and it happened too fast for the book world to catch up. We still don't know why Windows won't recognize the path to groovy that is in the PATH variable. Maybe that will clear up next time I reboot.

Monday, November 24, 2008

Virtual Server upgrade to WebSynergy Milestone 3

The system administrator of our virtual server is not very communicative. The fact that he lives in another state doesn't help matters. The last status I saw from him on Friday afternoon was that he was having some disk space issues, but was almost done.

For some reason, I missed the email he sent later saying it was installed. Over the weekend I checked the URL a couple of times but the browser said the page was not found. Maybe I wasn't using the right URL or sometimes the virtual machine will be down for various reasons. Anyway, Monday morning I checked and got a welcome screen that offered me the option to log in to Liferay. That meant that something new had gotten installed!

I logged in with one of the test accounts I had remembered from WebSynergy. All the pages were labeled Liferay. The Admin portlet on the Admin page had a statement: "Liferay Portal 5.2.0 (Augustine / Build 5200 / October 16, 2008)". The system administrator has had more experience with Liferay so I thought maybe he had installed that instead.

But, at least now the available menu options made more sense in light of advice I had received on the forums. I was familiar enough with the general idea of WSRP that I managed with very little trouble to create and display a portlet window that was consuming the WSRP producer portlet at http://wsrp.dyndns.org:10040/wps/wsdl/service.wsdl That's a big step in the right direction. Later, after I got back in touch with the system administrator, he explained that WebSynergy Milestone 3 has enabled Liferay as the default theme. I must have missed that memo.

Saturday, November 22, 2008

WebSynergy Wonderland

I did title this blog "Building Portlets for GIS". If you are going to build portlets you need to have a portal, right? We look for Open Source software on our project and it was decided that WebSynergy would be the portlet sandbox that would host our GIS portlets. You thought I was a newbie with Open Layers, didn't you? I started this venture just as ignorant about portals as I was about Open Source JavaScript libraries for displaying map data. Here, though, I don't have to feel as alone in my ignorance. There are many users of Open Layers out there but WebSynergy is pretty much unknown territory for everyone but a few Sun engineers and companies in Germany or other foreign lands (judging from postings on the forums). It rides upon the GlassFish server, which is also not exactly widely used.

One of the events at the Northern Virginia Software Symposium 2 weeks ago was a panel discussion, attended by several hundred Java web developers. Before kicking off the panel discussion the host took an informal "show of hands" survey of the audience to ask folks what servers and development IDEs they were using. More than half were Weblogic, lots of JBoss, some WebSphere, etc. Remember, this is an audience of Java developers so we don't even mention SharePoint. But, then, almost as an afterthought, the host says "Oh, well, GlassFish, no one's using that, right?" Do you think I was about to raise my hand--no way.

So I'll admit it here to an imaginary audience. I've been struggling for months trying to install and learn the rapidly changing versions of GlassFish on my company-issued IBM ThinkPad laptop running Windows XP Professional. I've learned a lot about port conflicts because the different versions I needed to keep for continued testing always want to use the same ports. Then when you want to install the rapidly changing versions of NetBeans and plug-ins for Portlet Container and WSRP so that they match the versions of the server things get really confusing.

We finally got a Virtual Machine running Solaris and the system administrator loaded WebSynergy on that. But I had too many problems understanding how to interact with it and decided I should have a WebSynergy sandbox version of my own. Rather than keep cluttering up my work laptop and losing the ability to develop with the GlassFish and PC tools that I was getting somewhat comfortable, with I decided I would install WebSynergy on my Dell laptop. Ha Ha. Its OS is Windows Vista. And, unfortunately, Vista Basic, not Vista Professional. WebSynergy does run on it, but it's dog-slow. I make sure I have another task at hand to work on whenever I bring up the NetBeans 6.5 Beta with the WebSynergy instance I finally got working on my Dell laptop. That way I'll have something to do after I click an icon or button besides stare at the little revolving circle that replaces the spinning hourglass as Windows huffs and puffs along on the Dell laptop that also suffers from having only 1 GB of RAM.

After many laborious hours I finally figured out how I could create a portlet with an OpenLayers map on NetBeans 6.5 Beta and display it on the WebSynergy running on my laptop. Next step, theoretically, is to take the WAR file that NetBeans creates and upload it to the remote WebSynergy. I found an admin portlet that enabled me to do the upload. There was a message that the file was uploaded successfully and the portlet was being installed. The file was listed with a number of other installed portlets within the admin portlet. But the menu listing that allows you to add the portlet as an application, making it visible on a page in its own window, did not have my portlet anywhere on it. There was no way I could get my portlet with an OpenLayers map displayed on WebSynergy. The system administrator and the forums could provide no guidance.

During the course of troubleshooting another problem, though, I did get some information from one of the forums. We were told that our version of WebSynergy was not the latest version! Don't ask me how that happened so fast. Before we had time to get comfortable with the Stable Build 2 version that had come out the end of August to replace the beta version there was already a new version. That version is now being installed on the virtual machine and then I will start my tests over again. Plus I have to ponder if I want to go through yet another go-round of uninstall/reinstall on my hopelessly slow Dell laptop so I will have a matching version in my sandbox.

Monday, November 17, 2008

OpenLayers ProxyHost

One of the most difficult problems for me to solve with OpenLayers was how to set up a ProxyHost. The FAQ was helpful to a certain point but it assumes that you will be using a php or python scipt like the example they provide. There is no information on how to do it within the Java code of the project.

It took a long time for me to figure out that the best way to do it was to create a servlet inside the NetBeans portlet project. Then what I struggled with was the path to the servlet not being known by the JavaScript code that was on the jsp page with the OpenLayers map because the servlet was not in the same context as the portlet. For a number of weeks I was able to get it working by hardcoding the URL string into the OpenLayers.Layer.WFS call. But I knew that wouldn't work once I moved from the portlet I developed locally to a remote host.

After a full day's struggle I finally got the key piece of code into the view.jsp. First a bit of servlet code to create the URL:

<% String proxy = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/ionic_proxy"; %><% String proxy = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/ionic_proxy"; %>< % String proxy = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/ionic_proxy"; % >

Then, within the OpenLayer.Layer.WMS the call becomes:

var wfs = new OpenLayers.Layer.WFS( "NID",
"< %=proxy% ><%=proxy%>",
{typename: "iwfs:NID_GEOM", maxfeatures:30},
{featureClass: OpenLayers.Feature.WFS} );

Whew, what a bother.

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.

Tuesday, November 11, 2008

BBOX in OpenLayers calls

I made some headway in modifying the BBOX that I had in my OpenLayers portlet example. When I started I wasn't even sure if OpenLayers uses the same Coordinate Reference System as the data from the National Inventory of Dams that I was trying to display.

My OpenLayers wfs call was limiting the number of features to 10 and I knew the approximate geographic area where these 10 dams were located. When the portlet first displayed I wanted the 10 maps to be visible in the window. That wasn't happening and I had spent a lot of time experimenting with the OpenLayers map constructor and Bounds constructor. The numbers didn't seem to match up to what I was seeing. I was also using Firebug to look at the URL that was being sent to the WFS by the code in my proxy servlet. After the Scott Davis GIS talk at this past weekend's Software Symposium I thought the problem might be related to the map projections.

By examining the XML in a WFS file that I had previously created from accessing the WFS I could see that the data used EPSG:4326. This was a good page that helped me understand what that meant: http://en.wikipedia.org/wiki/European_Petroleum_Survey_Group Then I went to OpenLayers and did some research and found that the default projection used by OpenLayers is also EPSG:4326. That meant that the problem was not that I had 2 different projections. Finally on one of the OpenLayers FAQs I found a suggested way to get the map to appear where I wanted it to appear.
http://faq.openlayers.org/map/how-do-i-get-a-specific-bounds-to-load-just-right-into-my-map-div/

There was still some tweaking that was needed to get the proportions in the window to be correct but I now have the features showing in the map when it first displays. The Bounds parameters I used were (-90,31,-80,40). The BBOX that is in the URL being sent to the WFS is BBOX=-95,25.5,-75,45.5. I need to do some more research to understand the correlation between these two. ie, how does OpenLayers come up with that BBOX? My next goal is to pinpoint the location where the user clicks the mouse and have the information for that feature returned in the portlet. Always more to learn in this stuff. I sure wish I knew where there was a book on OpenLayers.

Sunday, November 9, 2008

Northern Virginia Software Symposium

The Friday night keynote address, "Career 2.0: Take Control of Your Life", given by Jared Richardson, provided the impetus for this blog. Learning new technologies is exciting and it's necessary for moving forward, but it's also important to share what's learned. There are many options for doing that and one that's easy and possible for any level of knowledge is to write a blog. So here I am finally getting started on something I've been meaning to do for quite awhile.

My current employeer has me investigating portlet technologies and how to apply them to the field of Geographic Information Systems. Yes, the Google Maps API is ubiquitous and a wonderful tool. But the world of government contracting, where I live, is hesitant to tie themselves to proprietary data and systems. The focus in my department is on Open Source solutions, in particular, Sun Java technologies.

I still have 4 sessions today to attend at the Symposium. The sessions Friday and yesterday were all terrific and, for me, the absolute best was "GIS for Web Developers: Adding Where to Your Application", given by Scott Davis. There was a "Eureka" moment where I may have the solution to a problem that's been bugging me on one of the map portlets I've been building. At least I know where I will start looking as soon as I get back to work tomorrow. If I don't win one of today's raffles, I will be investing the $ to get Scott's book on GIS for Web Developers. He didn't have time in his talk to get into the level of detail that I hope to find in his book on the OpenLayers chapter. Sometimes a book is what I most need and with OpenLayers I haven't yet found good documentation. Open Source is awesome, but, of course, we can't expect to find the level of documentation that comes with a commercial product. But, as Jared pointed out in his talk that just means there's another opportunity for someone like me to share my experiences in using and learning OpenLayers.