Reflections on Web Application Design for GIS – The User

To me, the biggest issue in coming up with an initial web application design and then steering it through to completion is having a good understanding of who the user is.  This is sometimes difficult to determine, for various reasons.  Maybe the application is new and there is not an existing user base to think about.  It could be that there is an existing application and user base, but you are tasked with creating a new application component for those users.  Maybe there are several types or classes of users to think about.  There are many possible combinations of factors, but whoever the user is, he or she is ultimately the one you are tasked with providing an application to.

So who is going to be using your application?  I always try to ask myself a few questions at the start of a project to help me figure this out.

  • Is the user computer-savvy?  Websites designed to serve the general public have to consider the reality that many (most?) people don’t spend 40+ hours a week on a computer.  Many people avoid them at all costs.  For this reason, websites designed for use by the average citizen must be simple enough so that at a glance, he or she can figure out what needs to be done.  Something I always fall back on when I think about this is a simple question:
    • Could my mom figure this out?  (Sorry Mom).

The reality is that most people make up their mind in a matter of seconds if it’s worth it to them to spend time figuring out what they’re supposed to do.  They’d often rather walk away than deal with the frustration.

  • Is the user GIS-savvy?  This is an easy one for us to overlook.  As GIS professionals, it’s easy for us to forget that using computer-based map applications is not something that is inherently intuitive to humans.  We GIS people are so used to “Zoom to Extent”, “Identify”, “Query”, etc., that it seems natural – but in reality, most people have never really thought about this stuff.  Think about it this way:
    • How do you explain to people what you do for your job?

This is a question which I’m sure any GIS professional can relate to.  I’ve been re-explaining my job to my dad (a smart guy) for about 15 years now.  He still tells people that his son “makes maps for the railroad” – because I worked on a big railroad mapping project in 1999. 

Because most people don’t “think GIS”, we have to be careful not to assume they are going to understand what a little “I” button icon does.  Knowing the level of GIS knowledge of your users is key in making a good design decision.

  • What, exactly, does this application need to allow the user to do?  The reality of the state of GIS in 2009 is that there are dozens of ways for people to go online and print out a pretty map easily – and for free.  Gone are the days when the engineering department had to call the GIS department to generate a simplistic site map.  Engineers can print one that’s “good enough” from various sources without having to dip into their budgets to pay us to make one for them.

What users really need is a tool or set of tools which allow them to complete their job or a specific task.  Our challenge is to provide them with core functionality that make their lives easier, their jobs simpler and more productive, and their businesses more profitable – while at the same time being usable and straightforward.

Keeping this core functionality in mind is often challenging, especially amid the glitz and glamour of all of the new technologies available to us.  While everyone wants their application to look great, be bug-free, and be the pride of their organization, without this solid core functionality, what’s the point?  It’s important throughout the design process to step back often and ask:

  • Are we still on track for providing the core functionality to the user?

Ultimately, the success of a design can be judged on how effectively it provides core functionality to the user.  Tailoring the application to cater to your user’s skill level, understanding of GIS, and functional requirements will go a long way toward ensuring a successful design.  Amid the difficulties of debugging code, meeting deadlines, and balancing workloads, keep in mind that someone out there is going to be using the application you’re creating (maybe even Mom!).

Keep an eye out for follow-on posts from me about similar topics related to application design, user experience, and workflows!

How to Implement Modeless Dialogs Using .NET (Part 2)

In my last article I showed how to implement a modeless dialog that floats on top of the ArcMap window. Unfortunately, that implementation lacks several behaviors that are standard for Windows Forms. These behaviors include tabbing between controls, pressing Enter to trigger the Accept button, pressing Esc to trigger the Cancel button, and mnemonics. The solution to these problems is a little more complicated than what we did to make the dialog modeless, but is still relatively simple.

The first step in the solution is to set the KeyPreview property on the dialog to True. This allows our modeless dialog to intercept keystrokes before the controls on the dialog get them. Next, we add code to the KeyDown event to process the Tab key, Esc key, Enter key, and Alt key. For each key, we explicitly implement the behavior we want. For example, when the Tab key is pressed we want to call the form’s ProcessTabKey method. This is all that is required but this solution is less than elegant because we would have to do this for each and every modeless dialog we create. A better solution is to create a Form class that we can inherit from each time we create a new form. This way, our new forms will inherit this behavior and we won’t have to copy and paste the same code over and over.

The sample project that accompanies this article shows how to create this customized form. The form is named EnhancedModelessDialog. If you open the code module for this form you will see that the KeyPreview property gets set to True in the class constructor. The KeyDown event has the code we need to handle the various keys. Notice how it handles forward and reverse tabbing by calling the ProcessTabKey method when the Tab key is pressed. If the form’s AcceptButton and/or CancelButton properties have been set, the code will handle them appropriately if the Enter or Esc keys are pressed. Finally, the code will handle mnemonics when the Alt key is pressed. You will also notice a line of code in the KeyPress event that sets the Handled property on the event arguments object to True when the Tab key is pressed. This prevents an annoying beep when tabbing out of textboxes and comboboxes.

The SampleDialog form shows our inherited code in action but it may not be so obvious how to set it up. When you create a new form you need to choose Windows Forms in the Categories tree of the Add New Item dialog. Select Inherited Form in the Templates pane, give the form a name, and click Add. You will be prompted to choose the class that the new form should inherit from. Select the EnhancedModelessDialog class and you’re done! You can then continue adding controls and code to your new form. It will automatically inherit the properties and code of our base form class, so remember this if you need to add code to the new form’s KeyDown or KeyPress events.

For all of the forms you’ve already created, don’t worry. You can still make them inherit from our base form. In your project’s Solution Explorer pane, click the Show All Files button on the toolbar just above the Solution treeview. Click the Plus next to your form and open the Designer.vb code file. Change the Inherits statement at the top so that it inherits from our base form instead of System.Windows.Forms.Form. Make sure you do this in the Designer code file and not the standard code file for your form. If you add an Inherits statement at the top of the standard code file you will create a problem because the form can only inherit from one class.

There are several ways you can use this base form in your own projects. The simplest way is to add the dialog to each project. Of course, this isn’t optimal because if you ever want to change anything you have to change it everywhere. A better way would be to put this sample project on your development machine and add it to each solution. This way, if you ever need to change the base form you can open this sample project and make whatever changes you need. Anytime you compile your other solutions, this project will compile as well and whatever changes you made will be applied to the solution at that time. There are even better ways than these but those are entirely different subjects so I’ll skip them for now.

I have several more ideas for future articles that will continue along the lines of developing Windows forms. These topics will involve working within the ArcMap application framework and ArcObjects. If you have an idea for something you would like to hear more about feel free to leave a comment or send me an email. My goal is to write an article every week and I’d like for them to be about the things you folks are interested in!

Is it our job to spatially enable the people around us?

This weekend I attended one of my favorite events: the Birmingham Artwalk. First of all I’m sure many of you have trouble believing that Birmingham, Alabama has a local artist community and that it’s large enough to spend an entire weekend going from gallery to loft admiring the new works. Come on down next year and I’ll even buy you a slab of Dreamland ribs to make sure you feel welcome.

I was particularly interested in seeing my friend Jess Walker’s Mountain Maker Cohort’s, which is an effort to capture the spirit of the world’s most beloved mountains. I almost never found her. Instead of a map they had a hand-drawn “schematic” (I use the word generously) that I could barely interpret, and I’ve worked with some ugly maps in my day.

My first urge was to find the event organizer and plead, “Please let me help you next time!” But then I thought of all the community events I attend that need the same kind of help and by the time I finally fought my way out of my own head I was facing an insurmountable task that no single GIS Geek could ever accomplish.

I know most of you have had the same experience. What should we do? A little bit of our collective skills could be an immense contribution to our communities.  So is it just a matter of individual conscience where each of us makes some contribution when moved?  Or should the local chapters of our professional organizations add this to our geographic literacy mission? Or is there a way to crowd source, making organizations aware of what can be done and give them a vehicle to reach out to the local Geek community?

These aren’t rhetorical questions and I’d love to hear your personal or local experiences. I would like to make a difference, but this problem is beyond my problem solving skills. Please feel free to use this forum to share your personal or local experiences. And I really don’t want to feel guilty at the next community event.

Experimenting with Map Services in 9.3.1

It’s 0600, I’m in Germany and I am pondering on what I could possibly write about that fellow GIS comrades would find enlightening.  Well, why not start with why I’m in Germany. I am here to deploy a web-based mapping solution built on ESRI’s server technology (version 9.3.1). Specifically, it uses the .NET ADF (I know what you’re thinking, NOT THE ADF), but I have to admit I have been impressed. The biggest ticket item that has caught my attention is the Mach 5 renderer and how it works with the new map service definitions (MSD) map services. While I am still working on quantifying them (see Dan Levine’s recent blog), I have to say that the gains have been noticeable.

Unfortunately, we have encountered some limitations that will, by the looks of things, possibly force us to go with a different ESRI development framework. The ADF is actually a really solid solution, but there are a few little things that are causing issues. Things like the use of sessions and the inability to handle switching the viewer’s core map projection – note, this is not to be confused with on the fly projection (want to throw that out there before I start getting pinged by all the super geeks).

In any event, back to the solution we’re deploying. Most of you reading this have probably, during some implementation, encountered server performance issues (whether they are map services falling asleep or reaching the max number of map service instances allowable on your machine and the services dying).  Well, in this solution we introduced a new approach to serving up map services to the browser; we’re controlling them via an intermediate data model. Let me caveat this by saying that initially this was a solution specifically for the JavaScript API, but since we’re in the ‘pushing the boundaries’ industry, we said “ah what the heck, let’s push the ADF.”

This solution isn’t earth shattering, but what it does do is allow us to work with regionalized map services. Within these regionalized map services we have a few core geographic extents that we’re interested in. Each of those core extents have a series of associated features with it. Now, it’s not an eloquent solution– there is some overhead on the administration of the data model (not to fret we plan to build an admin module to it), but it does allow us to do a couple of things:

1 – Dynamically load the available features into the applications tools without overwhelming the tools with all the map services features.

2 – Make the tools map service agnostic, the tools don’t go to the map service to figure out what features are available, instead it goes to the data model and through some quick data filtering identifies the available features.

3 – Start to break the dependency on the map services, focus being to reduce the load on them, which directly relates to their availability.

Unfortunately we did not achieve all of our goals. As most of you are aware, there are limitations with the number of features in any map service before you start to experience degradation in performance. What we were hoping, was that via the data model not only would we be able to control which map features were made available to the tools, but also which features in the map service were rendered. The theory being that if we were able to control the features that got rendered in any map service we could potentially dramatically increase the map services usability. This is how it would work:

One map service would be built out with three times the allowable features, say the magic number was 60. So we’d be looking at a map service with 180 different unique features. The geographic extent for the map services would be Southern California. 60 of those 180 features would be dedicated to some geographic area of interest, say Los Angeles. The other 120 would be distributed between San Diego and Menifee. Well if this worked, then we’d be able to publish a 180 feature map service but the server would render the map service with only the 60 features pertinent to the geographic extent the user chose to visit. I mean come on, how hard can that be, right? Well, it’s hard enough that we haven’t cracked the nut on it….yet.

In any event, let me caveat this by saying I am not a developer. I’m actually an analyst by trade, project manager by day (I think that’s actually up for debate right now), and dare I say it, a technical architect somewhere in between.

Well, stay posted; if (when) we get the breakthrough we believe is possible, I’ll provide an update to the story.

How to Implement Modeless Dialogs Using .NET

A common question I see on the ESRI forums is how to create a dialog that behaves like ArcMap’s Identify dialog, which floats on top of the ArcMap window and allows the user to interact with the map without having to close the dialog.  In order for the user to be able to click on the map you have to show the dialog as modeless.  You show a modeless dialog by calling the dialog’s Show() method instead of the ShowDialog() method.  As many of you have probably noticed, making your dialog float on top of the ArcMap window isn’t quite that simple.  As soon as the user clicks the map, your dialog disappears behind the ArcMap window.  This can be confusing, not to mention annoying, for your users.  Thankfully, there is a simple solution to this.

When you call the Show() method without any parameters, your dialog will not have an owner.  This is why it jumps behind the ArcMap window.  The solution is to make the ArcMap window the owner of your dialog.  So the question is how do we do that?  If you look at the Show() method, you’ll see that one of the method overloads takes a parameter of type IWin32Window.  The .NET help topic for IWin32Window shows us that this interface has a single property named Handle of type IntPtr.  This is great because we can get the handle of the ArcMap window from the hWnd property on the IApplication interface and easily convert it to an IntPtr.  Our only problem now is that we don’t have a class that implements IWin32Window that we can use.  The good thing about programming with interfaces is that when you don’t have a class that does what you need, you can always create your own.  So, all we have to do is create a class that implements IWin32Window.  We can then create a new instance of that class, give it the ArcMap window handle, and pass it into the Show() method when we show our dialog.

The sample code project that accompanies this article has the complete code for this class.  The first thing you will notice is that the class implements IWin32Window and has a property named Handle.  You will also see that the class has two constructors.  One takes the owner’s handle as an IntPtr and the other takes the owner’s handle as an Integer.  There is no default constructor for this class because we don’t want to be able to create an instance of it without specifying the owner’s handle.

The sample project also has a class for a simple ArcMap command that will show a modeless dialog when clicked.  Notice in the OnClick() method how the new instance of our class is created and passed into the Show() method.  This is all there is to it.  Now we have a class that we can use in all of our projects.

To view the sample, download the zip file and unzip it.  Open the solution using Visual Studio 2008 and compile it.  You can then open ArcMap, go to the Customize dialog and find the sample command in the GISi Samples category.