The Community presentations for the 2010 ESRI Developer Summit are now listed on-line, and are open for voting. Since these presentations are all recorded, you don’t have to be attending the Dev Summit to vote – just setup an account (free) and vote for what you want to see – either live or recorded.
This year I’ve submitted two talks, and Brian Noyle and Mike Juniper have thrown one into the mix.
As noted in my last post, I’m dabbling with Ruby on Rails, and so I thought I’d do a talk about using ArcGIS Server from a Rails application. The basic idea is to build a simple data view that sits in front of data hosted by ArcGIS Server. In reality you would likely pull the attribute data from a database, but in order to make it more interesting from the ArcGIS perspective, we’ll pull it from ArcGIS Server via the SOAP API. Unlike .NET, Ruby does not have much in the way of web service proxy generators that work from WSDLs. What little there is, can’t handle the complexity of the ArcGIS Server WSDL files, so we need to get a little lower-level. I’m using the Savon gem for this project, and it does a good job of handling things – I’ll go into the details in a subsequent post, and in the talk.
Now, some people would say that I should just use the REST API, and call it good. Unfortunately at 9.3.1, the REST API is still a limited (but powerful) subset of the SOAP API. And some of what I need to do (i.e. draw custom graphics on a map image) can not be done via the REST API, so SOAP it is.
I’m also going to build the app using Behavior Driven Development using Cucumber, and I’ll show how the behavior of the system can be described in plain English, and yet they run complex tests. Apparently Cucumber can be used to drive .NET tests as well, so that should be an interesting spin-off from this.
As noted in the talk description, all the code will be put up on ArcScripts and on GitHub. I plan on using the Portland Landbase service hosted by ESRI so that there is no ArcGIS Server setup required to play with the app.
Why vote for this? Ruby is a lot of fun, and offers a different point of view on development… and James Fee says you should
We (somewhat) recently built an emergency response application based on the ESRI Javascript API, with lots of custom services (ASP.NET MVC if you care). When we were nearly done, we found out that “deployed on a DHS server” meant that everything had to be locked down. This means the full meal deal – all requests to the web server had to go over SSL and all ArcGIS Services used token based security. This would have been complex enough, but this particular application allows the administrators to dynamically add services from other ArcGIS Servers. Joy. Anyhow –we managed to whip this system into shape, and I’m going to run down the general ideas, and then dive into some of the code – particularly the proxy that handles the token security. You can watch a “high-level” version here http://vimeo.com/7557517 (presented at the 2009 ESRI South West Users Group). The Dev Summit version will be much more “deep dive”
Why vote for this? Who knows when you’ll find yourself needing a SSL certificate and token based security.
Why build a native app when you can build a pretty cool web app that leverages WebKit and the iPhone extensions? HTML5 here we come! Actually, I’m sure that Brian will have some sort of post on the details of what these guys are planning, so I’ll leave it at this for now. And, we’re going to try and work in an edge-cached, cloud front image service that some friends are cooking up. H-h-h-h-ot. We’re also going to try to get this working on Android as well.
Why vote for this? We’ll have the app up and running and you can bang along on it with us, and (if possible) we’ll be sharing the source.
So – that’s it – as usual these will be zen-style presentations, and we hope they will be entertaining. I hope you’ll head over to the voting site, check out all the talks and give us some love.
Ruby on Rails may not be on a Lovecraftian list of “Dark Arts”, but for someone who’s been developing on the Microsoft platform for the last 10 years, it’s close enough.
As anyone who’s read this blog in the last 2 years knows, I’m a pretty big fan of Microsoft ASP.NET MVC – it’s simple, gets out of your way, and gives you total control of the output. And it’s 1000% better than the mystery meat known as Web Forms – a nirvana so to speak. So, why would I take up Ruby on Rails?
Why Rails?
First, unless you’ve been under a rock for the last 5 years, you’ve likely heard that Ruby on Rails is *teh awesome*, so that counts for something. Then there is the fact that Andrew Turner (@ajturner for the Twitterati) / GeoCommons crew as well as Paul Bissett / James Fee and the WeoGeo team are all smart as hell, they all love Rails.
And the other reason is that realistically, Apache and Linux have won the web. Yeah there is a large slice of the pie (mainly Government) that runs Windows, but if you are starting a web based business, you’re likely going to run open source because of the costs to start and scale. Sure Microsoft is semi-mitigating this with BizSpark and a few other programs, but regardless, the difference was put in sharp contrast as I tried to negotiate may way around the Microsoft Open Licensing site while at the same time installing RedMine on Ubuntu Linux. For those who have not had the pain pleasure of dealing with the maze of Microsoft Licensing sites, they are among the least usable, obtuse sites anyone could imagine. It’s like they set out to win an award for painful web experiences. Really – I don’t mind paying for software – I love Visual Studio, but why, why, why must it be a living hell to actually login, locate, assign and activate licenses? I’m not joking here – I’m really considering changing from full MSDN subscriptions over to just buying Visual Studio because then we own it outright and don’t have to deal with this crap licensing site every year.
Anyhow… back to my point. On Ubuntu installing software is crazy simple – “sudo apt-get install <software of choice>”. Yes, the command line syntax is slightly more complex than a “Ok-Next-Next-Next” windows installer, but it’s also free, immediate and you’re always getting the latest and greatest.
When the main reason we use MSDN over just Visual Studio is for the SQL Server and OS licenses, it makes me question things – I can install MySQL in about 5 minutes, it’s 100% free and I don’t have to fight with the Microsoft sites? The OS is free, and Aptana RadRails (free) covers the IDE side of things? Why is it that I’m shelling out $15,000 a year in licensing, only to have the entire Microsoft interaction be painful? Ok this is degrading into a rant, but what the heck, I don’t rant very often, and it’s my blog anyhow… moving on
Ruby on Rails. Yeah. So, it seemed that expanding my horizons a little may be interesting, and worth some evening time. I started with “Rails for .NET Developers” from Pragmatic Press. This is a perfect read if you’re a WebForms developer, and pretty good if you’ve elevated your game to MVC. From there I moved onto “Agile Web Development with Rails” and this is a great follow up. If you like Pragmatic Press books, these are perfect.
Patterns nom nom nom…
Since Rails is based on the MVC pattern, and a major influence behind ASP.NET MVC, it’s not surprising that the carry over from ASP.NET MVC is huge. The View syntax is very very similar, the the extent that many of the HTML helpers are very similar. This is great because I was immediately comfortable with the general structure of things. However there are some differences… namely data access (aka ActiveRecord)
Because this post is rife with asides, let’s have another… It’s interesting that Rob Conery, of Hawaii and various levels of internet fame (creator of SubSonic, an ex-Microsoftie and now TekPub.com dude) seems to have been going through a similar thought process / experience as I have, although he seems to be a few weeks ahead of me. You see, while I really like ASP.NET MVC, there is still WAY too much time spent thinking about data access. In the last year, we’ve used the Repository pattern, with a mix of SubSonic, NHibernate and plain ADO.NET. On every project there is much hand wringing and thought about how the data access tier should work – how “POCO” should the POCO’s be, what handles the transition from the data tier to the models etc etc etc. In this post about Entity Framework and NHibernate Rob makes the point that we should be waaaaay past thinking about the data tier. It should be “done” – the fact that there are still flame wars about data persistence options is sad. Isn’t a framework supposed to *help* you with the mundane stuff?
I can haz Data Nao?
I my mind, time spent futzing with the data tier is time wasted. Yes, there are projects where you don’t control the database, and some DBA’s do some really wack stuff (if we meet, ask me about this, have I got stories!), but in an ideal world you turn down those projects. Any database that makes it a royal pain to get to the data the users need, is poorly designed in my opinion. The app is about users, and it succeeds or fails based on them, not based on some idealized 4th normal form, so let the app dictate the data model!
What rocks about Rails is that data access is “just done”. No thinking, it’s just done. And it works. Let me say that again – the data access is “just done”. You can go from zero to editing data in your database in about 30 seconds. Sure the styling of the scaffold sucks, and it’s not the best workflow, but the key feature – create / edit / update / delete data in your database is DONE. All that time you would have spend thinking about NHibernate caching or optimization can be spend working out a better workflow or UI styling. Under the covers, I’m sure there are more elegant solutions, and there are likely some performance issues, but realistically 99.99% of web apps are not FaceBook or Twitter, so the performance / scalability arguments are moot – we’ve got trivial numbers of users and heinously powerful servers. Let’s NOT sweat performance mmmkay?
The other thing about Rails that’s great is that it’s opinonated. And not just mildly, it’s got some really strong opinions, but if you can work with them, and not against them things flow so smoothly. I know, I know, I heard this same speil for a few years, but I have to say it’s true. If you can live in the 80% case, Rails makes things so smooth it puts a grin on my face.
What Now Brown Cow?
So, am I forsaking all that Redmond hath wrought? Not quite – this is good kool aid, but I’m not about to throw out ASP.NET MVC just yet (we did just shell out for another year of MSDN after all!) but Rails provides an exciting alternative that’s close enough to the tooling and workflow of my day job that it’s providing inspiration and ideas about how to be a better ASP.NET MVC developer. It’s a great developer exercise to learn a new language or framework, and I heartily recommend checking out Ruby and Rails.
Anyhow, to close out this rant of a post, I’ll be throwing more Ruby into the mix here and on GeoGeek.tv. At this point I’m certainly still very NOOB in terms of Rails, but what I’ve done, I’ve liked. Alot. And as far as “on my own time” projects, I’m sensing a definite shift to the dark side. Welcome to 2010!
I was going to cook up a full SOE example, but that was going to take way more time that I don’t have, so here’s the abridged version – just the major points…
Projects in the Solution
SOE’s have a lot of moving parts, so let’s think about all the parts in terms of servers & assemblies.
First – the SOE project. We’ll create the actual SOE’s in here. We can have references to all the ArcObjects / ADF goop we want in here, since this will of course be running on the SOC machine.
In the “client” application (ASP.NET MVC in my case) we’ll use an interface to access the SOE. Since we’ll want the interface definition on both the SOC machine(s) and the “client” machine, we put this in it’s own assembly. Remember that anything that moves between the SOE and the “client” is really doing DCOM under the covers, so all types need to be serializable.
Next up is the Utility assembly. We have a mess of static classes in here that are pure ArcObjects. This assembly will be used on the ArcGIS SOC box, by the SOEs. An upside of keeping this code “pure” ArcObjects (by that I mean there is no ServerObject cruft in here) we can use these same utility classes in ArcEngine or Desktop development.
Finally, we’ll want that “client” application I’ve be talking about. I’m a big fan of ASP.NET MVC, so I’ve been using that to host services. It’s worth noting that you can put standard ASMX SOAP web services into an MVC project. This is nice because you can expose your SOE methods as SOAP or JSON from the same project. Remember, this project will be using the ESRI ADF library to create the connection into the SOC and get access to the SOE, so it will need to run on a box that has these libraries accessible. Note that at 9.4 the ADF components are re-distributable with out incurring additional licensing.
Building
The build process can be a little hairy. First off, make sure you have ArcGIS Server on your development box – this way your build/test cycle will be manageable. If you need to copy dll’s to another server as part of your debugging process you will lose your mind.
So – we need to register all the COM assemblies – that would be the SOE, the SOEInterface, and the COMUtility assemblies at minimum. While you *CAN* tell visual studio to register these assemblies for COM interop, DON’T! That will register the assembles in \bin\debug.
A better plan is to copy these dll’s to a separate folder, and install them there. We call ours _install_ComUtilities. We have a post-build event that copies the SOE and it’s dependencies into that folder, and does all the dirty work. Jeff Germain just threw up a good post on a Post-Build Event that does all this, but here’s the basic process:
Stop the ArcGIS SOM Process (SC STOP ArcServerObjectManager)
Un-register the dll’s (regasm /unregister…)
delete the type libraries (*.tlb)
delete the dlls
copy the new dll’s from the build output folder into _install_ComUtilities
run regasm on them to create the type libraries
re-start the ArcGIS SOM process (SC START ArcServerObjectManager)
Now, of course you don’t want to do this every time your solution builds, as it takes ~15 seconds, so use the visual studio configuration manager to not build the SOE project automatically.
Registering the SOE with the Map Service
Get Vish’s SOExplorer app, and use that. You can do this manually or write some code to do it, but just use Vish’s tool. It rocks. Moving on…
Logging
Since you’ll likely have a bug or two in your code, having some logging is really important. We use Log4Net on the client side, but have never gotten this to work smoothly in COM land. Again, Jeff has saved the day with a ComLogger utility that he whipped up for this. I’ve asked him to post about this, but he has not gotten to it yet. If you want this, go to his blog and hassle him.
The upside is that when debugging the app, I’ve got two logs to watch – the log on the client (MVC) and from the SOC (via ComLogger). The ComLogger simply creates a \log folder next to the SOE dll – so you have to watch for permissions on this – make sure that the ArcSOC process has write permission to the folder where you install your dll’s!
Here’s an example of what I get in my SOE Log:
12/14/2009 3:11:37 PM INFO LrsSOE::GetRoute LrsSOE::GetRoute called. 12/14/2009 3:11:37 PM INFO LrsSOE::GetRoute params: routeId: 002B 12/14/2009 3:11:37 PM INFO LrsSOE::GetRoute whereclause: Route = ‘002B’
What shows up in here is up to you, but make sure you stuff all exceptions into the log because that’s where this will save you a ton of time. If you don’t you’ll just get an InteropException on the client side, and that’s completely useless. Also worth mentioning, I use NotePad++ and just keep these two files open in it. When they change, and you change focus to Notepad++, it will ask if you want to refresh the files. Vish is a big fan of BareTail, but from what we’ve see, it’s got wacky behavior on multi-monitor setups. Moving on…
SOAP and JSON in MVC
As noted above I needed to provide services to different clients – one is a Flex app where JSON is convenient, and the other is another MVC app that can speak SOAP fluently. To do this, I just created a standard MVC project, and created a /SOAP folder, inside of which I created a standard asmx web service. By default MVC maps all urls to routes, and so /SOAP would normally route to a class called SOAPController. However, we don’t want that behavior, so we tell MVC to ignore anything under /SOAP (this is in global.asax.cs)
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("SOAP/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" }
);
}
For the Json stuff, I setup a JsonController and thus we have routes like http://server/json/getroute?routeId=25b, which of course maps to a the GetRoute method on the JsonController, passing in a routeId of 25b. The logic in the JsonController is pretty simple – we just pass the arguments over to the SOE, and return the response.
Getting the SOE
Getting the SOE itself is a two step process. First you need to get a server context – ideally one that has your SOE registered with it, and then get the SOE from that. We’ve written a lot of these things, so we have lots of handy utilities to handle configuration sections, Identity etc etc. But it boils down to two methods:
public static IServerContext GetServerContext(string arcGISServerName,
string serviceName,
string serviceType,
ESRI.ArcGIS.ADF.Identity identity)
{
//Connect to ags
ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsConnection
= new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection(arcGISServerName, identity);
agsConnection.Connect();
if (!agsConnection.IsConnected)
{
agsConnection.Dispose();
return null;
}
//Get the som
IServerObjectManager som = agsConnection.ServerObjectManager;
//Get the server context and the mapserver
IServerContext serverContext = som.CreateServerContext(serviceName, serviceType);
return serverContext;
}
and…
private ILrsSOEInterface GetSOE(IServerContext serverContext, string soeName)
{
//Get the server object extension
IServerObjectExtensionManager serverObjExtMgr = serverContext.ServerObject as IServerObjectExtensionManager;
if (serverObjExtMgr == null)
{
throw new ApplicationException("Failed to get the ServerObjectExtensionManager from the server context.");
}
IServerObjectExtension serverObjExt = serverObjExtMgr.FindExtensionByTypeName(soeName);
if (serverObjExt == null)
{
throw new ApplicationException("Failed to get the ServerObjectExtension by extension type name" );
}
ILrsSOEInterface lrsSOE = (ILrsSOEInterface)serverObjExt;
if (lrsSOE == null)
{
throw new ApplicationException("Failed to create a reference to the {0} server object extension.", soeName));
}
return lrsSOE;
}
Notice that the second method returns the SOE typed as the interface we defined in the interfaces assembly.
Serialization
The last step is to get the results from our SOE back to the client. This is easy for simple types, but as usual Geometry is a pain. The Geometry we get back from our SOE is the SOAP Value type geometry. And as far as we know there is no open API for converting this into a Json geometry. Of course, using Reflector you can *see* that ESRI has all the handy methods you may want to use for this in the REST assembly, but alas they are all internal. What’s a dev to do? I’ve asked ESRI to provide public methods for this, and Morten mentioned being able to do this using the WPF components, but again, the needed methods are internal (and they don’t handle the SOAP value types). If you are working with GeoJSON, the Vish (did I mention Vish rocks?) whipped up GeoJson.NET, which you can get from SVN at Assembla (http://svn2.assembla.com/svn/GeoJSON/) . It cleanly handles the ESRI –> GeoJson formatting. All hail Vish.
So – that’s a pretty shot-gun style round up of SOE related stuff. If you have questions or ideas, just drop me a line and I’ll see what I can do.
The ESRI Flex Sample Viewer is a great starting point for creating map centric RIA’s. The widgetized nature of the starter kit facilitates significant re-use of components, and there are a couple dozen plug-and-play components available from the Flex Code Gallery. Woot!
The downside of this ease of re-use is that we are seeing a new wave of cookie cutter sites out there. It’s great that these sites can the whipped up so quickly, but it’s pretty clear that (for the most part) little or no thought is given to how the user should interact with the site. We see hordes of menus and tons of widgets, all gloriously trying to pseudo replicate ArcMap. Let’s be clear – if your users need ArcMap, give them ArcMap. If they actually know the data model to the point that an ad-hoc query tool will be useful, chances are they will need more functionality than you can build into the Flex app anyhow. Right tools, right place and all that…
Where was I… oh yeah… remixing the sample viewer. When I’m designing an application, I want to build it as focused as possible. Every mouse click and menu drop down I can remove, the better it is for the user. So – here are a few of the things that I wanted from a UI/behavior perspective…
I want top level menu items that do something on-click. I don’t want a pull down with a single item on it – I want a print icon that opens the print dialog when it’s clicked.
The shortcut menu is a great idea, but I want to have things that “only” appear on the short cut menu. Having something in two places in a UI is counter intuitive in most cases, and wastes UI space.
I want to have a limited set of base maps available, and I want them to be displayed as top level icons on the menu. Clicking them will turn on the layer. Active layer should have a “glow” indicating that it’s… well… active.
I want widgets that can’t be closed. One thing I’ve seen when letting clients run a Flex app is when they close widgets they are confused about how to re-open it. Thus I want a sub-type of widget that can only be minimized and not closed.
I want a full width banner across the top of the page – providing more room for top level items.
I want a search box in the top banner so it’s easy to search.
I want a zoom to / book mark tool on the top bar so it’s easy to jump to commonly accessed extents
And I want all the same level of flexibility in terms of configuration, and the ability to leverage existing widgets. Now.
Design Sketches
In coming up with this list of things I wanted, I did some sketches… (apparently my scanner is crap!)
In the past I’ve used visio or balsamiq to create wireframes, but more recently I’ve been getting back into sketching simply because it’s so fast. I’ve been using Jason Robb’s wireframe templates as a starting point (article and direct download of pdf).
More Tile Caches…
Since ESRI is changing their caches over to Web Mercator, I wanted to start working with some web mercator tile caches. ESRI has *some* services available now (google search here), but realistically most of these are pretty weak for base maps. So, I created tile layers for OpenStreetMap and CloudMade. Once I finish a few tweaks to these layers (need to display the copyright statements on the map) I’ll release them – likely to the ESRI Code Gallery, but I also want them on a SCM somewhere. Maybe GitHub? Thoughts?
Let’s take a peek…
Things are not fully dialed in yet, and I really need to focus on detailing this out for my client, but this is the generic starting point. I’ll post some live links when my client’s site is ready for beta testing.
This shows the full width banner, the address search, zoom to drop down (needs skinning), an “Always Open” widget, the two base map icons, and the top level print widget. The tiles are from the CloudMade Midnight Commander cache.
This one shows the locate dialog that’s opened by running a search from the banner bar. As you can see there are still a few issues with this widget. Since “locate” is not the key focus of the app, this widget can be closed. I’m also going to work on the actual search logic – right now it’s parsing out the address based on commas, and then sending to the ESRI geocoder. I may look at using another service that has more matching logic on the back end so I don’t have to figure out how to de-construct the address.
This shows the print widget, accessed by just clicking the printer icon (no drop down required). Oh, and the Open Street map cache in the background.
What’s nice about this is that the user does not need to go digging around in menus to access the functions they need. This template will be used for very focused applications – do one thing, and do it well is the mantra for the project – and so keeping things up front will really help out.
Behind the Scenes
So – the real question is – can we share this? Good question! I’ll be blogging more about how we (big shout out to Jeff Germain who whipped up the “toolbars” stuff) created various aspects of this, and at the very least, you can re-implement most of this stuff pretty quickly. We had to hack at the core of the Sample Viewer (specifically ControllerManager.as) and added a bunch of additional controls for our “toolbars”. At this point things are “working” for the scenarios we need right now, but I suspect we’ll have some refactoring in our future. I’ve got at least 3 apps that will build on this, and by the time all 3 are released, we should have tracked down all the weirdness, and have something that supports all the out-of-the-box Sample Viewer stuff, as well as our extensions. Stay tuned!
I finally got around to loading a video of my talk on Usability in Emergency Response Applications, given at the ESRI South West User Group (SWUG) meeting. In this talk I give a walk-through of an app we built using the ESRI Javascript API, focusing on design aspects that helped streamline the end-user experience. I also discuss the performance impact of token secured services and SSL.
I was building an edit task for ArcMap today, and got to a point where I had the geometry operations solid (using Test-Driven-Development for them) but when I got to iterating over sets of real data, I though it would be really handy to use a logger to kick out more detailed debug information. We use log4net in our web applications, so I thought I’d try dropping it in.
Turns out it took all of 5 minutes to get it working, so here’s the how-to (there’s some sample code at the end)
Now that you have the log4net zip archive, copy the log4net.dll from the \log4net-1.2.10\bin\net\2.0\release folder in the zip file into your \lib folder. I always have a \lib folder for external assemblies that are used in a project. This is preferable to storing these in a central location because the \lib folder get’s stored in source control along with everything else that your project required. So – if you don’t have a lib folder, make one!
Now that it’s in the create a reference to log4net from your project in Visual Studio.
Configure It
The easiest way to use log4net is with the standard log file appender which just writes to a text file. In order to configure this, we need to edit the ArcMap.exe.config file (located in \ArcGIS\bin). Of course you can store the log in other places (databases etc) – just Google for the details.
By default, this configuration file is almost empty, so you’ll need to add in the configSections as well as the log4net section.
Now we have to wire log4net into our code. In order to be useful, we’ll want to have access to the “logger” throughout our class, so we’ll make it a private member. Ideally we’d pass in the logger from a dependency injection framework, but we’ll keep things simple for this example (sometimes DI *is* overkill). Thus, we’ll setup the logger in the constructor of our class.
Would not be very much help if I did not show how to actually write to the log! Now that we have _logger, we can just pump data to it. There are a number of levels you use to send out data, depending on the severity. During development, I’ll use the Debug(<info>) method to see what’s going on inside the code, but you’ll also want to use the Warn, Error and Fatal methods when your code experiences errors. Using the different methods allows you to control what’s output to the log file via the configuration section. This way you can leave all that debug stuff in the code, but not have log files piling up on production systems.
In the sample code, I’m just pumping out examples of each type of log.
public void Activate(IEditor Editor, IEditTask oldTask)
{
_logger.Info("Task Activated.");
}
public void Deactivate()
{
_logger.Warn("Task Deactivated.");
}
public string Name
{
get { return "Log4Net Example Task"; }
}
public void OnDeleteSketch()
{
_logger.Fatal("On Delete Sketch Called");
}
public void OnFinishSketch()
{
_logger.Error("On Finish Sketch Called");
}
In the log file you’ll see something like this…
2009-10-15 15:32:25,631 [1] INFO Log4NetDemoTask.LogEditTask [(null)] – Task Activated. 2009-10-15 15:32:29,205 [1] ERROR Log4NetDemoTask.LogEditTask [(null)] – On Finish Sketch Called 2009-10-15 15:32:33,003 [1] FATAL Log4NetDemoTask.LogEditTask [(null)] – On Delete Sketch Called 2009-10-15 15:32:38,182 [1] WARN Log4NetDemoTask.LogEditTask [(null)] – Task Deactivated.
Post Build Tasks
This is a subtle thing, but as far as I can tell, if you want your code to be able to “see” the ArcMap.exe.config file, your dll must reside in the \bin folder right beside ArcMap.exe. This is easily accomplished by adding a post-build event in Visual Studio
Now, every time you build the project, it will copy your dll and any dependencies (log4net in our case) into the \bin folder.
A final note – when you start using logging, you’ll want to be able to look at the log without re-opening the file all the time. Thanks to Vish I’ve been using BareTail for quite some time now – this app will let you watch the file as lines are added to it.
Here’s a simple sample editing task, along with an ArcMap.exe.config file. Have fun!
Just a quick note that I’ll be giving two talks next week at the ESRI South West Users Group (#SWUG09) meeting in Pueblo, Colorado. It will be nice to attend another conference that I don’t have to fly to!
I’ll be giving an updated talk on Usability as related to “GeoWeb” applications on Thursday morning at 10:30am (Room “MR 4/5”). This will draw from some previous usability talks, but without the hard-core developer content, and more focus on the process of arriving at a usable application using ESRI technologies.
On Friday morning at 9:30am (also in room MR 4/5), I’ll be giving a talk for my usual accomplice, Brian Noyle (he got an elk tag, so he’ll be up in the mountains stalking large animals) that will also be about usability, but in the context of an emergency response application we built. I’ll go into the design decisions, the application architecture, and some of the complexities we ran into when building a highly configurable, high-security application that can consume remote map services. If you want to see how far you can push the ESRI Javascrip API, drop by.
Assuming the wireless is stable, we will also be streaming some of the sessions and hope to chat with people on GeoGeek.tv. At the very least, we’ll be recording my talks and hosting them somewhere.
I’ll also be tweeting about the various happenings using #SWUG09 as a hash tag, so you can follow along that way.
(Royce is on the right, Brian is on the left, and Jack is givin’ out the hugs)
We’ll talk about his background as a developer, what got him interested in Flex development, we’ll have him take us through the app and discuss various tools and how they were implemented.
Check out the apps, and join the chat to ask questions.
Posted by Dave Bouwman | Posted in Community, Conferences | Posted on 06-10-2009
16
Over the last year I’ve been to many geo-conferences, and been privileged enough to speak at most of them. However, I think that there is something amiss in the current conference landscape. To quote Mark Frost in Fortune Magazine…
We’ve all been there: the dull business conference. A half-empty room of half-asleep attendees answer their e-mail on laptops and BlackBerries, while some hapless speaker lumbers through a PowerPoint speech.
How did we get here? I’ve been to somewhere between 50 and 75 geo-conferences over my career, and the dynamic has really changed. It used to be that people we pumped up to attend and were there to contribute and learn. Now it seems that attendees at most main-stream conferences are there to do one of three things:
a) market a product, or
b) present “project work”, or
c) avoid the office.
The rest clearly are not there to contribute, discuss or learn. This becomes blatantly clear when there are no questions at the end of a 90 minute session with 3 speakers. Really? Were you awake? Or maybe everyone is an expert in this niche (if so why is it on the agenda?) Or maybe no one cares about the topic (again, why is it on the agenda?)
That said, some geo-conferences still have a pulse, and I’m thinking of the ESRI Developer Summit and the WhereCamps in particular, but overall, the patient is on life support. What happened?
It’s the Economy Stupid!
While I’m sure that the economy has had a large effect on the overall number of people at any given event, it does not explain the general atmosphere in the sessions. Somehow I doubt the economy been particularly harsh on enthusiastic people. Or maybe organizations are simply sending the “dead wood” out of the office since they are not doing anything anyhow. Regardless, this is something that’s been going on for awhile now, and can’t just be blamed on Wall Street, so lets look at some other possibilities…
Marketing Overload
It seems that an awful lot of sessions are overt or very thinly veiled marketing – typically poorly executed. Some will argue that conferences must support the marketing angle because the sponsors defer a lot of the cost of the event, and thus they need some sort of platform to pitch their wares. However, anyone who’s read Seth Godin’s work knows that the era of “interruption marketing” (follow the link for a video) is on the way out. Pitching your next generation lossless geo-positioned cloud enabled, SOAP serviced, WMS-ified CAD/CAMA integration system to a room of people who don’t know what you are talking about, let alone need one, is a waste of time for all involved. Even if you manage to find the right niche session at the right niche conference, at least make it less “infomercial” and more “how this can help you help others”. Remember – these people did not come to hear a marketing pitch and they are used to Tivo – make them not want to fast-forward you.
If you have to do some marketing at a conference, my advice is simple – give people value: show them how to accomplish something, maybe using your widget/data/process for part of the solution, but offer other options as well. Be authentic. Be open. Be helpful. If you do this, you will connect, and in the end, that’s what you need to make a sale anyhow (unless you’re pitching ShamWow! in which case, stick with the infomercials, and us Tivo owners will never hear you again)
The “Project” Presentation
This should be the meat of most “non-vendor” conferences. We’re here to hear about how our peers are using their skills to make the world a better place. The bizarre thing is that these are usually done like a 3rd grader doing their first “What I did on Summer Vacation” assignment. Reading a bullet list of the ESRI products you used in the production of the city bike lane map is just as boring and useless as it sounds.
Tell us why you did the project and what great things resulted (fewer accidents, better quality of life, lower air pollution). If you did some really awesome stuff integrating systems (and I’m talking about importing an Excel file), tell us both the HOW and the WHY. Context is important. I’ve seen plenty of talks about “boring” topics which were riveting, and many talks on “inspirational” topics killed by someone reading their slideument to a crowd.
Since most people rank public speaking as their #1 fear, here are some useful books – Slide:ology by Nancy Duarte and Presentation Zen by Garr Reynolds. Although commonly cited as resources for good slide design, both books discuss the importance of having a story, the delivery and how to connect with the audience. Anyone presenting at any conference should read these books And if you’re not a natural loud mouth public speaker, they are invaluable. If you need to do a lot of speaking, I’ve heard good things about Toast Masters. And to show you that anyone – even a 5th grader – can give an awesome talk, watch this YouTube video and start re-thinking how you’re going to do things.
Above all – come prepared. I saw one presentation this last year where the speaker ran into the room about a minute before the talk was to start, and clearly had not even run through her slides before. Sure, expectations are lower than for a TED talk (more on this later), but do us all the respect to bring at least your “B” game, or cancel. Watching someone flounder on stage is horrible (especially if you are not near a door).
Office Avoidance
These are the worst attendees. And what really baffles me is that if you are going to sleep through every session, WHY BOTHER? Just head out to the local attractions, and roll in later in the day for the social events. Having half a room nodding off (partly due to poor presentations) really kills any energy there may have been. So – if you are just avoiding the office, do us all a favor and avoid the sessions as well.
Moving Forward…
I’m not saying I have the definitive answer to the problems outlined above, but here are some ideas. Ideally this will become a conversation and we can set new expectations and chart a new course for our industry. Leave some comments here, or better – write a blog post of your own! Tweet this! Do whatever it takes to get others to think about this because if we all sit back, nothing will change. Let’s be honest – conferences live and die by attendance. Since we can vote with our feet, this is one area where the community has almost absolute power – lets exercise it!
Maybe Less is More?
First, why not scale things back? Who needs 100 conferences each with 10 tracks trying to cover every niche? This makes it more difficult to find great speakers and necessitates huge facilities. What if there were one-half or one-third the number of conferences, and just one or two big rooms at each? And only the most compelling presenters, talking about the most pertinent topics were given a slot on the stage? What if there was more time to actually talk to the speakers or the other people?
Taking a cue from TED
This is the key idea behind the TED Conference. TED started in 1984, and the idea was simple – lets get the best people from the Technology, Entertainment and Design industries together to share ideas. Now, these people are extreme. The cost for the 2010 Long Beach conference is a shocking $6000 a seat (already sold out in case you were wondering). Due to it’s popularity, they are adding a “remote” location called “TEDActive” in Palm Springs, where you can get a seat to watch the streamed coverage for a mere $3750. Not only that, you need to apply to attend – there are essay questions on the registration form (more info here). What’s awesome is that there is ONE conference, with the most kick-ass people across a wide-range of fields attending, and only the most amazing presenters are invited to talk. And even then, they only get between 6 and 15 minutes. Now, you may think that this is just some uber rich event like Davos, but check out these presentations by Hans Rosling, Jill Bolte-Tayor and Josh Silver and get back to me. These are amazing presenters, telling compelling stories about what they are doing, and how they are trying to change the world.
Ok, so TED takes this to an extreme, but right now the geo-conference circuit is so packed with events that we are at the opposite end of the spectrum. There are easily a dozen events a month just in the US. These range from the large events like GEOINT and FOSS4G to smaller events like the Texas GIS Forum or GeoWeb. Every one of these events is vying for and audience and presenters. Maybe cutting things down a little would help a lot? Maybe everyone could bring their “A” game, and we could actually work on solving some real problems? (wasn’t that what got most of us into GIS in the first place??)
It’s about Participation
One way to combat the nodding heads is to keep them involved from planning to the closing. Even at vendor conferences focused on technology transfer (ESRI Dev Summit, Microsoft TechEd & PDC etc.) involving the audience in the planning can have a huge impact. Face it – people are spending a lot of time and money to attend these things, so the more control they have over what they will get out of the event the better.
Conference Planning
The traditional model of peer reviewed conferences, where presenters had to submit a “real” paper, which was then reviewed and published in proceedings is now long gone. Although there are a few “GIS Journals” hanging on, they are a dying breed, and the “abstract” requirement at most conferences is only a formality and a nod to history. The reality is that the “abstract” is really just the elevator pitch. And I commend this – with a bunch of simultaneous sessions, I’m more likely to got to the one with the catchy description simply because the presenter may actually be excited about what they are talking about!
Nonetheless, the abstracts are mostly still selected by a panel, and this has some flaws. The first is transparency - the people involved in setting up conferences are usually also involved in the industry the conference serves, and thus have some vested interest in particular views. This is not always the case, as evidenced by the GeoWeb conference, which is run by Ron Lake (the father of GML) and Galdos. They had multiple sessions featuring speakers such as Andrew Turner and James Fee who are decidedly not GML apostles.
At the other end of the spectrum here, we have the “un-conference” where sessions are determined on the fly based on who shows up. While this is a really cool model, I suspect (correct me if I’m wrong) there are issues scaling it up and down. There’s likely a critical mass where it works really well, but I can’t see 2000 people coming to a consensus on technical sessions in any rapid manner. And if there are less than 50 participants, finding enough common interests can make things difficult (try being a .NET Developer at a WhereCamp!). In order to convince large numbers of people to spend money and travel, more pre-planned structure is needed. All that said, it looks like this is exactly what the ReadWrite “Real-Time” Web Summit is set to do next week, so maybe we’ll get a sense of how well that works.
Personally, I think something like the SXSW’s “panel picker” can play a huge role. In their system, the audience gets a 30% weighting in the acceptance formula. This sort of a system would help weed out a great many of presentations that people are not interested in, at the same time getting prospective attendees excited about attending.
On-site involvement is also critical. At some conferences, the organizers are now acknowledging the “back channel” by projecting IRC or Twitter streams onto a screen in the room. Since the back channel is going to happen (at any reasonably tech-savvy conference), surfacing it and making it part of the experience is a huge step in audience involvement. Sure, there are risks, like some of the panels at SXSW where the twitter back-channel took on a life of it’s own, but if nothing else it shows that the audience does have an agenda, expectations and since they are already empowered, you may as well work with them instead of against them. I’ll commend ESRI for jumping into the interactive social media pool in a big way following this year’s Dev Summit. Now we just need to get more of the average ESRI Developers/Users on twitter, but that’s a totally different blog post…
External Involvement
Once you accept that the back channel is there, and is public, why not simply stream the sessions? On-site participation will always be a premium because of the face-to-face networking opportunities, but why not chose venues that have solid network infrastructure so that the sessions can be streamed live? This goes back the the idea of smaller facilities – which may actually have better connections! Both WhereCamp5280 and GeoWeb 2009 were at university facilities that had great internet connections. If I can use a $50 webcam and free UStream.TV to broadcast from these events, it’s clear to me that this can be done by any conference. Streaming is not going to cannibalize the on-site audience – those people were not going to come anyhow, but you can enable them to become part of the conversation anyhow. If there is a huge on-line presence for a conference, I would expect that would improve the “brand” of the conference, and I’d bet that it will increase attendees in following years. It also shows that you genuinely care about the community you service. Times are tough, so fewer people can afford to attend, but streaming the sessions enables content to be distributed anyhow. I would hope that large vendor events such at the ESRI conferences would move to this model, but the facilities they host the events at have notoriously poor internet connections. At least they to post the session videos after the fact.
Who’s Leading?
Carsonified hosts a series of events each year – mostly in the UK, but they also have some US dates. While not “geo” specific, these conferences (Future of Web Apps, Future of Web Design, Future of Mobile) are based around the "one big room” model. They get great presenters, stick them in a room with an audience and film everything. You can browse the archives or jump right to a fully caffeinated Andrew Turner talking about “Beyond Google Maps” from 2008. What’s awesome is that the web site that archives the content is a first class citizen in the Carsonified world. There’s the video of the talk, the slides, a highlight reel and sometimes an interview after the talk. Combined with the rich tagging and comment capability, this is an awesome improvement over the current conference web-site model.
However, the <head> conference sounded like a good model for next generation conferences…
<head> is a web conference with all of the traditional elements. We have live speakers, presentations, question and answer sections, and networking opportunities. The twist is that the conference takes place everywhere — all over the world — and at real-world gatherings called local conference hubs.
Live presentations, streamed to local “hubs” all tied in through the internet! Talk about upside for everyone involved – people don’t have to travel long distances, yet the social aspect is still covered by having the local in-person venues! And talk about “Green” – way fewer flights were required, less rental cars and all that hotel laundry!
Who loses in this model? Lets see… those over priced hotels that charge $12.95 per day for unstable wireless, and the airlines. Boohoo.
It does not look like there was a follow up planned for 2009, but I could see this sort of thing changing the game significantly in years to come.
Call to Action!
In this era of cost containment, conference attendees really need to see more value. I’d wager that expenses to send a person to a 4 day conference run between $1000 and $1500. Add in their salary, and the opportunity cost (not having them do the work they are paid for) and you can easily hit $3000 to $5000. Multiply that by 500 or a 1000 attendees and you’re looking at a huge investment pool. The question is: What value are we all getting for that investment?
Right now, the return is pretty poor for most conferences. Between the marketing and the PowerPoint hell, it’s hard to make the case to attend. If they intend to remain part of the landscape, geo-conferences simply have to change. WhereCamps are showing that if the geo-conference community does not get on board, the user community will simply evolve – on it’s own. There are successful models out there, we just need to demand quality and vote with our feet!
Feedback:
I would hope that this post generates discussions around the geo-community, and perhaps some conference organizers might be interested in having a chat. So, if you’ve got some ideas, peeves, or gripes, leave some comments with your thoughts, and I’ll pass them on.
What would you change about the last conference you attended?
What would you most like to see in future events?
Could you attend more conferences if the travel was local (i.e. within 50 miles)?
Could you attend more conferences if they had a “real” on-line option (possibly involving some $$)
Now that we have the look and feel stubbed out, it’s time to build out the rest of the site.
Since nearly every page is data driven to some extent, the best place to start is with the domain objects. If we were doing this with Linq to SQL, we’d start by creating the database, and then having that drive our Linq to SQL “domain”, but I’m planning on using this project to get my feet wet with NHibernate, so I’ll just start with the domain.
Since the site is going to be pretty simple, we really don’t have a lot in the domain – really just a ShowModel and a TagModel as shown in the class diagram below.
As we can see, these are simple data containers. I had originally thought I’d have a separate “UpComingShowModel”, but it seemed like it would be a pain to copy the info from that model into the “ShowModel”, so I just added an IsPlanned flag. This way I can keep both the upcoming and the completed shows in the same table, side-stepping this entire problem.
Some may ask – why call your domain entities “Models”. Well, that’s a good question. In some other apps I’ve been working on we started off calling the entities Models, and then realized that we needed more than just the entity in the View – so we added a set of “ViewModels” into the mix. This seemed to work pretty well on these other projects, but it does seem a little forced on a project this simple.
Repository
Now that we have the models, we need a way for the Controllers to access them. For that we implement a repository pattern using dependency injection – sounds more complex than it really is.
Essentially we define an interface for a data repository – IShowRepository in this case. This interface represents the contract between the consuming classes (the controllers) and the implementing classes (the data access layer). We then use a dependency injection framework (Castle Windsor via the mvccontrib library) to pass an implementation of the repository into the controller’s constructor. Trust me, this is really easy.
I tend to build these interfaces in an iterative manner – I’ll start with one page of the site, determine what domain objects I need in the controller (and thus the view), then I add methods to the repository interface to get these objects, and then provide the implementation. Here’s the IShowRepository as it currently stands…
After futzing with Visual Studio to show the full signatures (Class Diagram –> Change Member Format –> Display Full Signature), we can see that this is a very simple data contract.
Fakes
Since I want to “prove” the design before getting into actually creating a real data access layer, I start by cooking up a simple fake implementation of the repository. As far as the Controller knows, this is a full blown real-deal repository, but it’s just returning junk. As you can see by hitting the site right now, we are showing lists of shows, but they’re all the same thing – that’s because behind the scenes pretty much everything hits this private method:
private ShowModel CreateFakeShow()
{
return new ShowModel(){
Description = @"Dave and Brian talking about recent work,
building GeoGeekTV.com, Flex, and NBB Hoptober",
Title = "Friday Streaming from DTSAgile",
ImageName="123abc.png",
IsPlanned = false,
DateLocation= "August 28th, Fort Collins",
StreamedLive = true,
ViewCount = 3,
ShowNumber = 323
};
}
Dependency Injection
Ok, so we have the interface and a fake implementation, and now we need to get this into the controllers. Since we will be using constructor based injection, the first thing to do is knock in some constructors for our controllers. This is pretty much the pattern for all the controllers.
Next, we need to register our “fake” with Castle Windsor so it can do the injection. I’ve already setup the basic Castle Windsor infrastructure in Global.asax.cs, so all I need to do is register the fake with the WindsorContainer…
protected virtual void InitializeWindsor()
{
if (_container == null)
{
_container = new WindsorContainer();
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(Container));
//add in the components...
_container.AddComponent<IShowRepository, GeoGeekTV.Fakes.ShowRepository>();
//Add the controllers...
_container.RegisterControllers(typeof(LoginController).Assembly);
}
}
You can get the basic Castle Windsor for MVC setup from looking at either the source code for this project, or from mvccontib’s examples.
That’s about it! With the Windsor container in place, ASP.NET MVC will use it’s factory to create the controller, and along the way all the dependencies get injected. See – I told you it was easy!
Controllers and Views
I’m not going to go the basics of ASP.NET MVC – I’d suggest reading the NerdDinner example from Scott Guthrie, Phil Haak, Scott Hanselman and Rob Conery. I’ll also throw out a pitch for their book, as it is quite good.
In the earlier post I defined the routes, which helped map out the controllers, and the needed methods. Since I’ve built a few sites, and have some handy code lying around, I also inherited my controllers from a BaseController than has some logging capabilities baked in.
Most of the controller methods are very simple – just populate a ViewModel from the repository, and pass that to the view.
This is pretty representative – it’s the Home Controller’s Index method, which is the main page of the site…
public ActionResult Index()
{
HomeViewModel model = new HomeViewModel();
model.MostViewedShows = _showRepository.GetMostViewedShows();
model.RecentShows = _showRepository.GetRecentShows(5);
return View("index",model);
}
In some projects I’ve had the repository build up the ModelViews, but in this one, it’s easier to have the controller’s handle this, as it results in much less code in the repository.
Summary
So – the project is coming together. Almost all the pages are built out – the Contact page needs serious CSS attention, as well as a back-end implementation. Looking forward, I still have a fair bit of work left to polish everything off. Luckily, I think the enhanced HtmlHelpers in ASP.NET MVC 2.0 will help out. Next up: The Admin Pages
I'm Dave and this is my blog. I'm usually writing about .NET Software Development, ArcGIS, or Agile Practices, but other stuff does creep in from time to time. I hope you find something of use, and feel free to contact me if you have any questions. You can also check out my profile on LinkedIn