Loosely Coupled, Reusable UI Components in Backbone.js

This article assumes a fairly good understanding of the Backbone.js MV* library. There is a lot of good material on the web for learning Backbone, including the Backbone home page at backbonejs.org.

Intro

One of the things that differentiates Backbone from other frameworks is that it is extremely lightweight. It specifies the framework for doing complex things, including making complex interactive user interfaces, but it doesn’t come with any usable UI widgets. The purpose of this article is to talk about some Backbone and JavaScript techniques that might make it possible to build reusable interface libraries to use with custom Backbone apps.

A typical pattern, tight view and model binding:

In a recent application, I added UI to modify the opacity and color ramp palette in a map raster layer. It essentially provides a user interface so that when the user slides the opacity slider, the data displayed becomes transparent, revealing the underlying base map. The application took advantage of Backbone Views, Models and event bindings to structure the components and interaction.


 

I am wary of trivial Backbone examples, but a simplified example is an opacity control in some sort of image editing app:

 

 

When the user slides the slider in the opacity view, it sets the opacity attribute of the image model. This fires a “change” event on the image model, which causes the image display view to update to the right opacity.

The problem with this structure is that what is basically a generic control, used for controlling the level of any numerical attribute, has been tightly couple to an image model, where it only controls opacity. What we’d really like to do is build a generic UI component called slider control, that we could then use for the example above. If we can do this, then we can create plug and play controls that conform to specifications. IE you might replace a slider control with a list-based control that still sets a numerical value.

So as a first shot at generalizing this interface, perhaps we could -parameterize- the Opacity Controller View. Perhaps its constructor takes not only a reference to its model, but also to an attribute parameter to change on that model. So for example, you might have the following instances:

var imageOpacityControlView = new LevelControlView({
    model: imageView,
    attribute: opacity,
});

var imageBrightnessControlView = new LevelControlView({
    model: imageView,
    attribute: brightness,
});

var image ContrastControlView = new LevelControlView({
    model: imageView,
    attribute: contrast,
})

The implementation of this LevelControlView could look like this:

views.LevelControlView = Backbone.View.extend({
    initialize: function initLevelControlview() {
        this.template = this.options.template;
        this.model = this.options.model;
        this.attribute = this.options.attribute;
    },

    events: {
        "change .slider" : "setLevel"
    },

    render: function {
        this.$el.html(this.template({}));
    },

    setLevel: function(evt) {
        // in a more advanced version we could map to a parameterized range 
        // of values.  For now just set the parameterized attribute 
        //(whether // thats opacity, contrast or brightness or something else). 
        this.model.set(this.attribute, this.$el.find(".slider").val());
    }
});

 

This is a pretty good first shot, but it’s slightly inflexible. If the view controls more than one model, or a model and a collection, they all have to be added explicitly. When our app changes, and the views must change to accommodate. This is true because there is too tight of a coupling between the views and their models. It also means that we overload people who are good at UI design and engineering with system integration and application architecture tasks. What you really want is to be able to write the view and view model once, in a generic, reusable way, and then forget about it, regardless if other aspects of your app changes.

The Solution

The solution is in two parts, first: lets create a model for our UI view that is dumb and doesn’t know anything about the application logic. For the level control above, the model has exactly 1 attribute, level. We then need to wire this up to our image model, so that it can update its own view.

It’s tempting to bind the models together directly, but this is probably not a good idea. The problem with this is that now we need to make either the Level Model, or the Image Model smart enough to respond to a change event in another model. There’s really no good place for this binding code with this architecture. It’s also not good for maintainability and managing complexity.

 

View to view model coupling is a pattern that we use a lot, and is well understood. On the other hand it is not good for our models to start listening to other models for change events. You end up with an application graph that looks like a total complex mess because there are no rules for how objects can communicate.

The second part of the solution is to bring the notion of a Controller back into Backbone application development. Let’s introduce an Image Controller. Its instance has references to the level model, and to the image model, and it wires these two models together.

controllers.ImageController = {
    initialize: function(options) {

        this.opacityControl = options.opacityControlModel;
        this.image = options.imageDisplayModel;

        // this binding is what wires the 2 models together through
        // the setOpacity method.
        this.opacityControl.on("change", this.onOpacityChange, this);
    },

    onOpacityChange: function() {
        this.image.set("opacity", this.opacityControl.get("level");)
    }

    /* We can do exactly the same thing for an arbitrary number of UI
       controls like rotation, brightness, contrast, etc.  (Of course
       it is beyond the scope of this exercise, and probably quite difficult
       to programmatically change some of these parameters because they are not
       exposed through CSS the way opacity and rotation are.
    */

};

So what you end up with is

 

It’s pretty clear how you could use this to wire up lots of disparate generic UI’s to their targets. You could have a levelControlModel, a brightnessControlModel and a contrastControlModel all wired up in the ImageController in similar fashion. (It would be up to your excellent, focused UI developer to figure out how you actually create a parameterized image view where you can set contrast and brightness.. no mean feat!)

Conclusion

This does a couple of things for us. First off, when it comes time to debug this application, we know that View -> Model bindings are where they always used to be, but that if there is a more complex binding, we probably need to look to the controller for the feature. The other advantage is that are user interfaces are now entirely decoupled from our application, and can therefor be extracted out to reusable UI libraries, and developed by people who focus on HCI engineering exclusively.

Going a step further, it would be entirely possible to create libraries of reusable UI components that other people could plug into their own apps. Everyone structures their backbone apps a little bit differently, some using Require.js, some using global namespaces. I think if you had a library that played as nicely as possible with all of these different approaches, you could produce a product that would be useful to a lot of different developers. Also it would be produced in a way that the UI was beautiful and highly decoupled from application logic by necessity.

Cicero API – Accepting Credit and Debit Card Payments with Stripe

Until recently any client who wanted to purchase Cicero API credits would contact us directly and request that the credits be added to their account. We then issued the client an invoice to be paid by check.  In order to enable customers to purchase credits immediately (at any time of day), eliminate the need for us to process orders by phone, and deposit paper checks, we decided to implement online payment processing accessible via the user account pages.

We considered PayPal, Google Payments and several other online payment processing services, but after extensive research we decided to go with Stripe, a secure online payment system. Despite being the “new kid on the block”, Stripe has quickly established itself as a super secure and easy-to-use alternative to some of the more well-known payment processing services available.

Processing online payments with Stripe is simple and secure. Great documentation, easy-to-use wrappers, and an extensive testing framework make developing applications a pleasure. The intuitive online dashboard makes it easy to manage and visualize customers, payments, and refunds.

How it works

After creating an account and obtaining an API key, you create a form on your website to collect your user’s payment information. Stripe’s JavaScript API is used to securely submit this data to Stripe’s servers. If the card info is valid, Stripe returns a single-use token that can be passed onto your backend to charge the customer. With this process, none of the user’s card information is sent to your servers, and the customer is never redirected to a third-party site to pay.

Stripe API libraries exist for over a dozen programming applications and frameworks. We use Stripe’s Python library to create and update customer records with contact and card information. As part of this step, Stripe checks the billing address against the information on the card (although not all banks support this).

If any of the fraud checks fail, we do not attempt to charge the customer. Otherwise, the card is charged and API credits are added to the user’s account.

For added redundancy, we also take advantage of Stripe’s webhooks. They send a web request to our Cicero servers, and we mark the payment confirmed. In the unlikely event that, say, the plug got pulled on our server right as a charge was being made, we would be able to add the credits upon receiving notification from Stripe that the payment went through successfully. (If our servers were to be down, Stripe would keep retrying the request until they come back up and an “OK” response is received.)

Testing

There is a way to test just about anything without anyone being charged real money. Developers can use a test account dashboard, API keys, and credit card numbers. Writing unit tests is easy because there are special card numbers to test each type of error, such as a declined card or mismatched ZIP code.

Pricing

The fee is 30 cents plus 2.9%. The customer’s country and type of card used do not matter. Volume discounts are offered for merchants that charge over $1 million per year.

Stripe Caveats

  • Only a customer’s last card used is stored in Stripe. This makes it easy to allow the user to use their previous card instead of reentering all of the information. However, if he or she wanted to use the a card used for an order before the last, it would have to be reentered.
  • Payments are disbursed with a seven-day float. This is not a major issue for us, but could be for a reseller taking a high-volume special order with a short lead time, for example. Waiting a week to get paid is certainly better than other providers that can sometimes freeze your account without warning.
  • Stripe is not yet available outside the United States.
Overall, Stripe’s transparency and ease-of-use from both a development and billing perspective makes it a great option. It is certainly worth looking into for anyone looking to accept payments online.

Asgard Calling: GeoTrellis Release Candidate 0.7.0-RC2

Erik and I are extremely excited to announce that the new release candidate (0.7.0-RC2) for GeoTrellis for version 0.7, also known as Asgard, is now available for review and testing. This is the code that will become GeoTrellis 0.7.0 unless issues turn up during user testing, so we’d love to hear any feedback, answer any questions, or resolve any issues that you find. The Getting Started documentation and the API documentation have been updated to reflect the new release.

Some fun big picture statistics: between 0.6 and 0.7, there have been 301 files changed, 10,566 lines of code added, and 7,385 lines of code deleted.

The rainbow bridge to GeoTrellis 0.7

The rainbow bridge to GeoTrellis Asgard

Here is a summary of some important changes:

  • Powerful new support for extremely large rasters through tiled raster data classes
  • New map/reduce-style definition of operations for data parallelism on large raster data
  • Support for a range of new raster data types for efficient memory utilization and performance improvements
  • Significant speed improvements through lazy evaluation
  • Improved geoprocessing operation hierarchy and operation naming scheme
  • Modernized benchmark structure with many new performance benchmarks, including tiled raster tests
  • First class support for floating point raster data values, with floating point raster interface, support in core operations for floating point values, and implementation of floating point ARG formats
  • The getting started documentation has been significantly expanded and improved (http://azavea.github.com/geotrellis/getting_started/GeoTrellis.html)
  • Executable geotrellis tools can now be installed via conscript
  • The geotrellis template has moved to the github repository geotrellis.g8, and can now be installed using giter8

Another exciting development since the 0.6 release: support for the ARG raster format was contributed to GDAL by David Zwarg. Using a recent build of GDAL, users can convert from other raster formats into ARG and also use GDAL’s full suite of raster conversion tools on existing ARG files. Future releases of GDAL will contain this ARG-support, as well as tools like QGIS which use GDAL internally.

Best,
GeoTrellis Team

Release Notes: http://notes.implicit.ly/post/30455035622/geotrellis-0-7-0
Github: http://github.com/azavea/geotrellis
Maven repository: https://oss.sonatype.org/content/repositories/releases/
Documentation: http://azavea.github.com/geotrellis/getting_started/GeoTrellis.html
API Scaladocs: http://azavea.github.com/geotrellis/0.7/api
Issue tracker: https://github.com/azavea/geotrellis/issues?milestone=3&state=open
Mailing list: https://groups.google.com/group/geotrellis-user
IRC: #geotrellis on freenode

Building delightful, draggable iOS annotations for OpenTreeMap mobile

The iOS MapKit framework makes it easy to mark a point on a map, but making a draggable annotation that is a joy to use requires some extra work.

Azavea is building an iOS compliment to the OpenTreeMap web application to allow tree management organizations and the public to easily add to and correct the information for their city’s tree inventory. There is no better time to add information about a tree than when you are standing right next to the tree itself, iPhone in hand.

Adding new trees means placing new dots on the map. MapKit makes adding point annotations to a map easy. The MKPointAnnotation class is a basic implementation of the MKAnnotation protocol and provides the required coordinate property.

We cannot expect or require a user to accurately tap the exact location of a tree on their first attempt, so the application must give the user the ability to drag the annotation around on the map to fine tune the annotation’s position.

MapKit provides a default method of creating movable annotations. An object that implements the MKAnnotation protocol acts as a model, storing the coordinate of the point. A user working with an annotation on the map is actually seeing and interacting with a subclass of MKAnnotationView.

The rendering code for an MKMapView loops over the collection of annotations that have been added to the MKMapView and attempts to call the following method on the MKMapView delegate.

(MKAnnotationView *)mapView:(MKMapView *)mapView
          viewForAnnotation:(id <MKAnnotation>)annotation

If this delegate method is not implemented, a default instance of MKPinAnnotationView, a subclass of MKAnnotationView, is used to represent the annotation. MKAnnotationView instances define the appearance and behavior of an annotation within an MKMapView and offer a boolean draggable property.

Our first prototype of the “add a tree” feature for OpenTreeMap on iOS used this built-in ‘draggable’ functionality. The DraggableAnnotationViewDemo project shows a default, draggable annotation in action. If you install the DraggableAnnotationViewDemo on an iOS device and play with it for a while, you quickly uncover some problems with usability.

  1. The default pin annotations are difficult to “grab” with your finger. Even though the annotation has a buffer around it so that you don’t have to tap exactly on the pin, it still requires too much dexterity to get it just right every time.
  2. If you succeed in picking up a pin annotation, you discover that it is even more difficult to drop the pin in the correct place. Your finger is larger than the annotation itself, completely obscuring the target area on the map. When you do lift your finger, the pin “hops” onto the map some distance away from where you last touched the screen. In my testing I often gave up before I was able to position the pin exactly where I wanted.
  3. Dragging an annotation is a gesture, and gestures, because they are not visible, are not easily discoverable. A large portion of users will try to correct a mis-dropped pin by tapping a second time, rather than trying to drag.
  4. At distant zoom levels, dragging annotations is smooth, as you would expect. The further you zoom into the map, however, the more “jittery” the dragging becomes.

We started tackling these these usability problems by first designing a new graphic for the annotation.

Draggable Annotation Icon

There are several benefits to this annotation image, the first being the greatly increased size. Creating an annotation that spans 1/3 of the horizontal space on an iPhone screen results in a large target that is easy to grab. Having nearly a full finger width on either side of the center dot ensures that your finger does not obscure the drop target, allowing for precise and mistake free positioning. The increased size also gives us space to incorporate a “four direction” icon as a clue to discovering that the annotation is, in fact, draggable.

The CustomDraggableAnnotationDemo project improves on the DraggableAnnotationDemo by replacing the default MKPinAnnotationView with a subclass of MKAnnotationView incorporating the new annotation image. If you play with this demo on an iOS device you will see that it is an improvement, but it is not quite good enough.

You may notice that dragging the annotation, dropping it, and then immediately trying to drag it again does not often work. It seems that the MapKit implementation of the draggable property may have some kind of built-in delay, or perhaps there is just a bug in the touch handling. The draggable property also does nothing to eliminate the problem of “jittery” movement at high zoom levels.

As an aside, these demo projects illustrate how the MVC pattern makes it easy to create new versions of an interface without altering the core functionality of the application. The MKMapView and MKPointAnnotation are unchanged throughout all the demo projects. Any backend or controler code which adds an instance of MKPointAnnotation to the MKMapView will work with any of these annotation interfaces. Separating concerns makes it easy to itterate and improve one part of the application without breaking another.

The solution to the remaining usability problems is to leave the draggable property set to NO, and replace the functionality with custom touch event handlers and to manualy update to the annotation’s position within the MKMapView. Apple provides sample code for this in the “Legacy Map Techniques” section of the iOS developer documentation. This code is a good foundation, but it still produces “jittery” movement at high zoom levels.

The FinalCustomDraggableAnnotationDemo project eliminates the “jitter” by updating the CLLocationCoordinate2D of the underlying MKAnnotation rather than the center property of the MKAnnotationView. This project also includes a pair of UIGestureRecognizer instances added to the MKMapView which allow for handling single-taps on the map without interfering with double-tap-to-zoom. The single-tap gesture is used to move the annotation to a new point, allowing the user to reposition the annotation even if they do not know that the annotation is draggable.

While the FinalCustomDraggableAnnotationDemo project shows a big improvement over the MapKit default annotation behavior, it is not perfect. There is inevitable tension when attemping to drag a moveable object across a movable surface. The gesture handling in UIKit manages this tension using delays. A quick swipe will always move the map. Moving the annotation requires that the user touch the annotation and pause briefly before the annotation becomes the “target” of the drag.

The final solution to creating a quality user exerience around dragging map annotation required a lot more code than using the default MapKit behavior. I agree that the best code is no code at all but, in this case, the maintenance cost of the feature is more than paid for by frustration-free users who may contribute more to OpenTreeMap than they would otherwise.

Modeling Urban Forest Growth

As part of a USDA Small Business Innovation Research Phase 1 grant, we recently developed the Urban Forest Modeling and Prioritization Toolkit, a prototype web-based tool that enables users to select and weight various parameters such as population density, urban heat island temperatures, health data, and biodiversity statistics that could potentially affect where trees were planted. A more general overview of the project is available in an entry on Azavea Atlas, but we wanted to go into more detail here about some of the calculations used in the software. Thanks to Carissa Brittain and Adam Hinz, the developers on the project, for pulling together these notes.

The application is divided into two areas: modeling location (determining where to plant trees) and modeling growth (extrapolating future benefits).

Modeling Location

To create heat maps that would indicate the best planting locations based on selected factors, we used a two-level weighted overlay algorithm that takes the following parameters:

Using these parameters, we define a decision raster as any function R:\mathbb{Z}\times\mathbb{Z}\rightarrow\mathbb{Z}\cup\{ \emptyset \} where \emptyset represents the “no data” element of the raster. Operations (+,-,\times,/) involving \emptyset as a parameter always return \emptyset. We also define other convenience operations:

Max(R) returns maximum value in the raster,

Min(R) returns the minimum value in the raster,

R'(x,y) = \text{Norm}(R(x,y)) normalizes the input raster R such that R'(x,y) = \frac{R(x,y) - \text{Min}(R)}{\text{Max}(R) - \text{Min}(R)}\times 100
The weighted overlay algorithm has two phases. The first phase calculates the weighted average of each group as a new raster and then normalizes the result to between 0 and 100.

Then we calculate the final weighted raster:

W(x,y) = \frac{1}{\sum_{g\in G}\beta_g}\sum_{g\in G}\beta_{g}W_g(x,y)

For Philadelphia, we created rasters from the data shown in the last equation. Our general process was to rasterize each dataset (if not already rasterized) and resample to a 10 meter resolution. To allow for comparability between disjointed datasets, we chose to normalize data to a 0-100 range and picked 100 to mean “an ideal place to plant trees.”

The goal the decision model is to allow the end user to prioritize the factors that they would like to affect by planting trees. Perhaps an organization wants to impact crime and heat island effects. Figure 1 shows the base crime raster. Green indicates good places to plant according to this raster, meaning areas of high crime rates that could be effected by the existence of more trees. As studies (by Kuo and Sullivan (2001) among others) have shown that additional tree planting can result in reduced crime, we would plant in the green areas of this raster in order to potentially reduce crime.

Figure 1: Crime Raster for Philadelphia

Figure 2 shows the scaled temperature of the city based on average summer temperatures calculated using Landsat data. Green areas indicate high temperatures and thus ideal places to plant trees in order to reduce those temperatures. Planting trees can result in a general decrease of temperature, helping to reduce the heat island effect (Akbari et al. (1990)).

Figure 2: Heat Raster for Philadelphia

Figure 3 shows both crime and heat equally weighted. Areas highlighted in green are recommended for planting and represent the areas that contribute the most, on average, to both high crime rates and high temperatures. Planting trees in these locations would thus have the greatest impact on both factors.

Figure 3: Combined Crime and Heat Raster for Philadelphia

After identifying key planting locations, the modeling growth component of the system enables users to determine the long-term economic and ecosystem benefits of trees planted in a certain location. We’ll walk through the algorithms for that feature in another blog entry.

The USDA grant funded the creation of a prototype application. While we won’t be releasing a public version of the prototype, you can sign up for a free demo or contact Deb Boyer at dboyer@azavea.com or 215-701-7506.

The development of the Urban Forestry Modeling and Prioritization Toolkit was funded by a Small Business Innovation Research grant (2011-33610-30511) from the U.S. Department of Agriculture National Institute of Food and Agriculture.

 

Sometimes you feel like using modules

I’m going to go out on a limb here, and admit I enjoy Javascript.

*deep sigh* Okay, now that that’s out of the way, lets talk about writing good code.

As javascript apps mature, the need for organization and modularity becomes more important. The days of simply inlining your code in the HTML, or keeping all your code in one giant file, or rolling your own class system are fading. If you’re experienced with Javascript, you’ve probably written your own class system at some point, or code loading solution, or had to stitch together plugins for one framework all while your code is written in another. These are all simple solutions to a complex problem, and as is a common theme in software, you probably missed some edge cases. Inlining your code is hard to maintain, and isn’t modular, developing with a team in a single giant file is a nightmare, and rolling your own class loader means lack of compatibility and dealing with cross browser issues. The truth is until recently your new jQuery plugin was written differently than your nice custom layer for Openlayers, was different from your custom Dojo widget, was… well you get the point. You couldn’t expect to write them in the same way, or expect them to arrive at the browser in the same file at the same time. (If you’ve used Dojo, Ext, OpenLayers, jQuery, or Node.JS then I hope you know what I mean)

So, what’s a Javascript developer to do? The language is flexible and forgiving, and there hasn’t been something to standardize your code around, until recently. You might have noticed that the internet is pretty good at coming up with standards for sharing information and software. That’s why I was excited to see the proposal and development of the AMD API. AMD in this case stands for Asynchronous Module Definition. Basically it’s a consistent way to package your code, and it makes it significantly easier to reuse later down the road. A number of major Javascript frameworks have already embraced AMD, including jQuery, Node.JS, Dojo, and others, and I’d like to give you a preview here to hopefully inspire developers to give it a try. More importantly modules, and module loaders are proposed to be part of the spec for the next version of Javascript named “Harmony“, see Modules, and Module Loaders.

So, you like jQuery, modules, and you’re ready to open up an example and tinker around? RequireJS has you covered with a great walkthrough here: http://requirejs.org/docs/download.html#samplejquery . I’d enjoy walking through it on this blog, but it might be beyond the scope of this article. Let me know in the comments if you’d like to see more about this.

So, I wanted to provide a more complicated example, which I hope will be helpful to those looking to make nicely namespaced, properly constructable objects in Javascript. Lets pretend we had the following spec:

1.) Our class should use a private static dictionary of globally unique names that have been booped.
2.) These should be kept long-term, in localStorage when possible
3.) Our class should accept verbs other than boop, and should be extendable

So, lets get fancy for a second, and design something that is re-usable and modular. I’m picturing… A storage class, a smart globally static list class, and our main verb class that is configurable. Lets get to it:

Lets define a basic reusable storage module, something like:

define('storage', [ ], function( ) {
    //private static in-memory storage
    var _data = {};

    var that = {
        hasLocalStorage: function() { ... }
        set: function(key, value) { ... },
        get: function(key) { ... }
    };

    var ClassConstructor = function(name) {
        if (!name || name == "") { throw "Name not provided"; }
        this.prefix = name;
    };
    $.extend(ClassConstructor.prototype, that);
    return ClassConstructor;
});

Full Source for storage.js

and… lets define a class that uses that storage to maintain a globally unique list:

define('unique', ['storage'], function(Storage) {
    //private _globally static_ storage object -- will be shared with other instances of "Unique"
    //you probably wouldn't want this for this implementation, but hey, it's an example, so I wanted
    //to show how to do it.
    var _storage = null;

    var that = {
        setIfUnique: function(key) { ... }
    };

    var ClassConstructor = function(name) {
        if (!name || name == "") { throw "Name not provided"; }
        _storage = new Storage(name);
    };
    $.extend(ClassConstructor.prototype, that);
    return ClassConstructor;
});

Full Source for unique.js

and… lets define a class that uses the unique list, and takes a verb to ‘boop.’

define('booper', ['unique'], function(Unique) {
    var that = {
        //private storage, but not static, local to this object
        _unique: null,
        _verb: 'unset',

        verbObject: function(name) { ...  }
    };

    var ClassConstructor = function(verb) {
        this._verb =  verb || "boop";
        this._unique = new Unique(this._verb);
        this[this._verb] = this.verbObject;
    };
    $.extend(ClassConstructor.prototype, that);
    return ClassConstructor;
});

Full Source for booper.js

so, now we just need a basic web page to test this with:

<html>
    <head>
        <script data-main="js/index-main.js" src="js/require-jquery.js"></script>
    </head>
    <body>
        <h3>Boop em!</h3>
        <input type="text" id="name" name="name"
            style="width:300px"
            placeholder="Enter name to boop, limit once per name"
        />
    </body>
</html>

and how about some basic page code:

require(["jquery", "booper"], function($, Booper) {

    //prep
    var b = new Booper();

    //events
    var doBoop = function(evt) {
        b.boop( $("#name").val() );
    };

    $("#name").on('change', doBoop);
    $("#btnBoop").on('click', doBoop);
});

Full Source for index-main.js

Putting it all together with a working example:
Working Example!

Obviously, this example didn’t need to be this complicated, but we gained a lot from a little bit of extra work. We’ve built three easy modules, that can be easily maintained, extended, and reused. We have a hugely open and flexible page, and when we’re ready for production, we can compact and minify all those files into a single optimized build.

So, you’ll notice I added a somewhat generic three line chunk at the end of each class module. This is just some basic constructor logic so you get the nice internal reference to ‘this’, and you can initialize new objects with “new Foo()”, instead of only having one copy, etc, etc.

I hope you enjoyed this example, and if you’re interested in Azavea’s other projects, checkout our GitHub!

Geoserver Timestamp Styling and PostgreSQL DateTime Fields

Think for a moment about how many ways we talk about dates and time. In regular language, we can say things like “last Tuesday” or “week after the week after next” or “Friday the 12th” and people generally can figure out when we’re talking about. Add time into the mix and phrases start getting strange: “noon-thirty” and “half-past midnight” are my favorite oddities.

The actual date-time standard is published as ISO 8601 and talks about what date-time data should look like, but programming languages, databases and other programs implement this standard with sometimes vastly different interfaces and rules.

PostgreSQL’s handling of date-time data takes the form of 6 different field types, all suited to different data needs. For the OpenTreeMap project, we’re using the timestamp data type which allows us to store both dates and times for events down to the microsecond.

Geoserver accepts a single date-time type (also called timestamp) that stores dates and times at the same resolution as PostgreSQL’s data type, so it reads PostgreSQL’s date-time data easily. Adding a date filter to Geoserver’s SLD files is also fairly easy so long as you know how Geoserver wants date-time data to be formatted. The various formats that Geoserver knows how to interpret are located here. So, if we have a field in a database table called “last_updated”, then an example SLD filter might look like this:

<Filter>
  <PropertyIsLessThan>
     <PropertyName>last_updated</PropertyName>
     <Literal>2012-01-01 00:00:00</Literal>
  </PropertyIsLessThan>
</Filter>

This filter would display any updates made before midnight on January 01, 2012. Another example (from the OGC 1.0 encoding specification’s examples) catches updates between certain dates:

<ogc:Filter>
  <ogc:PropertyIsBetween>
    <ogc:PropertyName>last_updated</ogc:PropertyName>
    <ogc:LowerBoundary>
      <ogc:Literal>2011-12-01 00:00:00</ogc:Literal>
    </ogc:LowerBoundary>
    <ogc:UpperBoundary>
      <ogc:Literal>2011-12-31 23:59:59</ogc:Literal>
    </ogc:UpperBoundary>
  </ogc:PropertyIsBetween>
</ogc:Filter>

This filter would display any updates made during the month of December, 2011. Anything that was updated outside the specified date and time parameters would bypass these filters and go on to check any other rules in the SLD file. This works great if we’re only interested in static date comparisons. But what if we want to see updates less than a week old? Or objects that haven’t been updated for more than three months? This kind of dynamic filtering is a little harder to do.

After digging through the Geoserver documentation and a lot of googling, we decided to shift the dynamic part of the filter into a PostgreSQL view. Our test view included an id field, a geometry field and a field that calculates the number of days since the last update to that object. The view sql looks like this:

CREATE OR REPLACE VIEW timestamp_test AS
  SELECT
    treemap_tree.id,
    date_part('days'::text, now() - treemap_tree.last_updated) AS days,
    treemap_tree.geometry
  FROM treemap_tree;

So now we can add this view to Geoserver as a source layer and it will see the new days field as a static number field. We can use any of the property filters on this field and style recently added data in a dynamic fashion.