Friday, December 26, 2008

NetBeans 6.5 and OpenPortal Portlet Container 2.0

One of the successful portlets I had built when I had been using NetBeans 6.1 made a WFS call and displayed the returned features on an OpenLayers map. I knew that I would be wanting to make some enhancements to that portlet and opened the project in my newly installed 6.5 version of Netbeans. The clean and build was successful but the Run and Deploy wouldn't work.

The Run/Deploy tab of the IDE showed these errors:

Deployment Started
Deployment Failed
C:\Documents and Settings\536116\My Documents\NetBeansProjects\TestWFS\nbproject\build-impl.xml:550: The module has not been deployed.BUILD FAILED (total time: 2 seconds)

Opening up the build-imp.xml file didn't provide any clues as to what might be causing the deployment failure.

The IDE log had a lot of incomprehensible messages related to the portlet. Many of them appeared before the message about the failed deployment of the portlet and were "java.lang.IllegalStateException" messages about trying to access a file from the "default package." There was a recommendation to

Please see http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/classpath.html#default_package

Looking at that web page didn't help. It was obviously outdated, not even having a "default_package" section.

The only thing I could think of was that maybe I hadn't installed everything that was needed for portlet development. Did I need to do some additional plugins or update plugins after going from 6.1 to 6.5? I had installed Portal Pack 2.0 when I was using the earlier NetBeans version. Was I now supposed to install the latest Portal Pack 3.0 M2? I thought I had read somewhere that those plugins were included with the IDE download. I thought I remembered that right after the installation I had gone to the Plugin Manager and enabled 5 plugins related to portlets that were already in the "to be installed" section. I spent a lot of time trying to find the right documentation for portal pack and NetBeans and Portlet Container wondering what I had overlooked. Surely if a portlet was built with NetBeans 6.1 there shouldn't be additional changes needed to import the project into NetBeans 6.5.

Finally I decided that I would do a simple test and build a HelloWorld portlet in NetBeans 6.5. I discovered that the same failure to deploy was occurring. But this time I noticed these errors in the Portlet Container tab:

CLI171 Command deploy failed : Deployment of application failed - Invalid user or password java.lang.Exception: Deployment on Glassfish failed at org.netbeans.modules.portalpack.servers.jnpc.impl.SunAppServerDeployHandler.deployOnGlassFish(SunAppServerDeployHandler.java:103) at org.netbeans.modules.portalpack.servers.jnpc.impl.SunAppServerDeployHandler.deploy(SunAppServerDeployHandler.java:175) at org.netbeans.modules.portalpack.servers.jnpc.impl.JNPCTaskHandler.deploy(JNPCTaskHandler.java:89) at org.netbeans.modules.portalpack.servers.core.PSDeployerImpl.run(PSDeployerImpl.java:148) at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:572) at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:997)PortalPack Message : Deployment Failed : Deployment on Glassfish failed

I went into the properties for Portlet Container and in the Server Config tab found fields for User Name and password. Admin was the User Name that was filled in but password field was blank. Apparently, that was the step that I missed. When I typed in the admin password and applied the change I was then able to deploy the portlet. Back in business for building GIS portlets, but, once again, wondering what documentation I had overlooked that would have explained about the extra configuration step for the Portlet Container.

Saturday, December 13, 2008

NetBeans 6.5 and GlassFish v2ur2

Having finally gotten NetBeans 6.5 successfully installed my next goal was to build and deploy an application developed by a member on my team that looked up geospatially-enabled information from geonames.org and created a KML file of the output. I had already successfully done this with the code and NetBeans project files provided by the team on a previous version of NetBeans using the instance of GlassFish v2ur2 that was configured within NetBeans. It compiled and deployed with no problems. It was a service that when it was running I could access and display the returned KML file on an OpenLayers map within a portlet that was on the same instance of GlassFish.

But, for a true test, rather than doing it all within NetBeans, I wanted to take the WAR file that NetBeans created and deploy it remotely to a different instance of GlassFish. That proved to not be as easy. The instance of GlassFish I wanted to deploy to was running on a laptop with Windows Vista. I zipped up the WAR file on the Windows XP laptop, emailed it to myself, and downloaded it to the Windows Vista laptop. Windows Vista, in all its wisdom, kept insisting that the WAR file was a file type of "Directory", which really it is, but to move it into the .autodeploy folder of GlassFish I didn't want it expanded like Vista kept insisting. I finally resorted to the DOS command line to get done what I needed to do.

Once the WAR file was in the autodeploy folder the war_deployed file appeared, indicating the deployment was successful. But when I tried to display the index.jsp of the servlet in the browser, it displayed a "service is not available" page. Now it was time to look in the logs.

First I tried looking in the logs through the admin console. The log was filling up faster than I could scroll through in the window with messages that said:
WARNING *********** NetBeans HTTP Monitor ************ The request cannot be recorded most likely because the NetBeans
HTTP Server is not running. Go to the IDE and start the HTTP Server from within the Runtime window to fix this problem.

Now isn't that an aggravation. I didn't have NetBeans running and I didn't want NetBeans to be running so why should the server be complaining about a NetBeans feature not working? That's one of the problems with downloading and installing server and IDE packaged as one. They get dependent in a way that you may not necessarily want.

Doing a Google query of the error message I found this very helpful solution:

http://javahowto.blogspot.com/2008/12/disable-netbeans-httpmonitor-in.html

Rather than take the time to implement that fix, I looked at the log in NotePad. This is the NPE that was there:

[#2008-12-11T12:20:21.484-0500SEVEREsun-appserver9.1javax.enterprise.system.container.web_ThreadID=18;_ThreadName=Timer-15;_RequestID=bc574187-48c7-45d6-8456-6042df2f372f;WebModule[/GeonamesDotOrgLookupService]PWC1275: Exception sending context initialized event to listener instance of class mil.nga.to6.GeonamesDotOrg.ServiceListenerjava.lang.NullPointerException at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:433) at org.apache.log4j.PropertyConfigurator.configure(PropertyConfigurator.java:336) at mil.nga.to6.GeonamesDotOrg.ServiceListener.contextInitialized(ServiceListener.java:40) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4523) at org.apache.catalina.core.StandardContext.start(StandardContext.java:5184) at com.sun.enterprise.web.WebModule.start(WebModule.java:326) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:973) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:957) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:688) at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1584) at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1222) at com.sun.enterprise.server.WebModuleDeployEventListener.moduleDeployed(WebModuleDeployEventListener.java:182) at com.sun.enterprise.server.WebModuleDeployEventListener.moduleDeployed(WebModuleDeployEventListener.java:278) at com.sun.enterprise.admin.event.AdminEventMulticaster.invokeModuleDeployEventListener(AdminEventMulticaster.java:974) at com.sun.enterprise.admin.event.AdminEventMulticaster.handleModuleDeployEvent(AdminEventMulticaster.java:961) at com.sun.enterprise.admin.event.AdminEventMulticaster.processEvent(AdminEventMulticaster.java:464) at com.sun.enterprise.admin.event.AdminEventMulticaster.multicastEvent(AdminEventMulticaster.java:176) at com.sun.enterprise.admin.server.core.DeploymentNotificationHelper.multicastEvent(DeploymentNotificationHelper.java:308) at com.sun.enterprise.deployment.phasing.DeploymentServiceUtils.multicastEvent(DeploymentServiceUtils.java:226) at com.sun.enterprise.deployment.phasing.ServerDeploymentTarget.sendStartEvent(ServerDeploymentTarget.java:298) at com.sun.enterprise.deployment.phasing.ApplicationStartPhase.runPhase(ApplicationStartPhase.java:132) at com.sun.enterprise.deployment.phasing.DeploymentPhase.executePhase(DeploymentPhase.java:108) at com.sun.enterprise.deployment.phasing.PEDeploymentService.executePhases(PEDeploymentService.java:919) at com.sun.enterprise.deployment.phasing.PEDeploymentService.deploy(PEDeploymentService.java:276) at com.sun.enterprise.deployment.phasing.PEDeploymentService.deploy(PEDeploymentService.java:294) at com.sun.enterprise.admin.mbeans.ApplicationsConfigMBean.deploy(ApplicationsConfigMBean.java:555) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:375) at com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:358) at com.sun.enterprise.admin.config.BaseConfigMBean.invoke(BaseConfigMBean.java:464) at com.sun.jmx.mbeanserver.DynamicMetaDataImpl.invoke(DynamicMetaDataImpl.java:213) at com.sun.jmx.mbeanserver.MetaDataImpl.invoke(MetaDataImpl.java:220) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:815) at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:784) at sun.reflect.GeneratedMethodAccessor14.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at com.sun.enterprise.admin.util.proxy.ProxyClass.invoke(ProxyClass.java:90) at $Proxy1.invoke(Unknown Source) at com.sun.enterprise.admin.server.core.jmx.SunoneInterceptor.invoke(SunoneInterceptor.java:304) at com.sun.enterprise.interceptor.DynamicInterceptor.invoke(DynamicInterceptor.java:174) at com.sun.enterprise.deployment.autodeploy.AutoDeployer.invokeDeploymentService(AutoDeployer.java:564) at com.sun.enterprise.deployment.autodeploy.AutoDeployer.deployJavaEEArchive(AutoDeployer.java:545) at com.sun.enterprise.deployment.autodeploy.AutoDeployer.deploy(AutoDeployer.java:492) at com.sun.enterprise.deployment.autodeploy.AutoDeployer.deployAll(AutoDeployer.java:267) at com.sun.enterprise.deployment.autodeploy.AutoDeployControllerImpl$AutoDeployTask.run(AutoDeployControllerImpl.java:374) at java.util.TimerThread.mainLoop(Timer.java:512) at java.util.TimerThread.run(Timer.java:462)


Here is the rest of the log file related messages that appear after the NPE, interesting that startup failed yet it was considered successfully auto-deployed.

[#2008-12-11T12:20:21.484-0500SEVEREsun-appserver9.1org.apache.catalina.core.StandardContext_ThreadID=18;_ThreadName=Timer-15;_RequestID=bc574187-48c7-45d6-8456-6042df2f372f;PWC1306: Startup of context /GeonamesDotOrgLookupService failed due to previous errors#] [#2008-12-11T12:20:21.593-0500INFOsun-appserver9.1javax.enterprise.system.tools.deployment_ThreadID=18;_ThreadName=Timer-15;[AutoDeploy] Successfully autodeployed : C:\servers\glassfish\domains\domain1\autodeploy\GeonamesDotOrgLookupService.war.#]

I had gotten the code from my team member so wasn't that familiar with what it was doing. He gave me several pointers on what to look for and we finally determined that there were 9 files in the WEB-INF/classes folder that were in the NetBeans project, but did not get copied over in to the NetBeans WAR file. That meant we had a build issue. I had just taken the project files "as-is" and assumed all was well since it built, ran and deployed from within NetBeans. Makes you wonder why NetBeans can't detect such a situation as this.

Not being that knowledgeable with how to tweak the build within NetBeans, I did the workaround of manually copying the missing files into the WAR. I redeployed the new WAR file and this time it worked. Whew, another learning experience. Thanks to all who helped.

Thursday, December 4, 2008

Nuts with NetBeans

My first attempts at developing applications in the NetBeans environment were back in February when I first loaded version 6.0 on my laptop. I was trying to understand the Web Services projects that my team members had been developing using NetBeans. The first project I was given to play with had been built using NetBeans 5.5. I was forewarned that I would see an error message associated with libraries and that "all" I needed to do was get rid of the reference to JAXWS20 because the JAX-WS libraries were included with JDK6. To this day, I don't understand all the implications of what happened when Sun started including those libraries with JDK6. Getting my coworker's project to compile wasn't as easy as his email implied. At one point I posted to a forum http://forums.sun.com/thread.jspa?messageID=10116236 which was never satisfactorily answered and now I can't remember anymore what workaround I finally came up with.

From those initial installs of 6.0, to get needed features that kept coming up, I've gone through 6.0.1, 6.1, 6.5 Beta, and now 6.5. I dread it every time that I have to install a new version. To get around some of the problems I have had to delete the .nbi and .netbean directories, which, I think, causes problems later on when you try to uninstall. A week or so ago I wanted to install 6.5 on a laptop where I had both 6.0.1 and 6.1 installed. I'd been using the 6.1 for quite awhile and wasn't ready to get rid of it. On the other hand, things on the laptop were getting a bit cluttered. I decided I would uninstall the 6.0.1, leave the 6.1 and install 6.5.

After selecting Remove in the Windows Add/Remove Programs GUI, a popup message appeared: "Missing target component. The specified target component - nb-base/6.0.1.1.200801291616 was not found in the registry. The installer can continue as if the target component was not specified." The options for the popup were Yes to continue, No to exit. Regardless of which option I chose the installer exited without uninstalling NetBeans 6.0.1. After trying with the Windows Add/Remove Programs, I used the uninstall.exe in the NetBeans 6.0.1 folder, but the behavior was the same.

I've had some success finding answers through Sun user forums for problems with Portlet Container, Glassfish, WSRP, etc., and decided to send an email to nbusers@netbeans.org. After several days of getting no response I decided to experiment and see what I could learn. But you know how it is when you think the answer is just around the corner. I was sure that if I copied and renamed the right combination of .netbeans folders and tweaked the registry.xml I could get the 6.0.1 version back into a state where the uninstaller would be able to cleanly get rid of it. I think I was worrying too much about uninstalling the correct way.

I finally gave up and went back to looking at the forum. It was then that I realized this forum did not work like the others. I had been expecting that when someone responded to my question an email would get sent to the address I had used to send the question. Instead, I saw that someone had responded to my question shortly after it was posted. Basically, the response recommended just deleting the appropriate folders as the way to uninstall. And all this time I had believed what the documentation said "Use the Add/Remove Programs utility. Do not manually delete the directories and files."

But you do what you have to do to keep going. So I deleted all (hopefully) the appropriate folders. I tried to use the registry cleaning utility recommended by the forum post but it didn't do much that I could see. I'm sure there are bits and pieces of NetBeans 6.0.1 hanging around yet on my laptop.

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.