QGIS US User Group: Now on video!

For those who couldn’t attend the inaugural QGIS U.S. User Group last week, we managed to capture a lot of the event on video. Visit our album or check out the videos below!

QGIS US Introduction from Boundless on Vimeo.

Gretchen Peterson, Boundless from Boundless on Vimeo.

Gary Sherman, QGIS Project Founder from Boundless on Vimeo.

Kate Chapman, Humanitarian OpenStreetMap Team from Boundless on Vimeo.

Vivien Deparday and Yewondwossen Assefa, World Bank GFDRR from Boundless on Vimeo.

Tim Sutton, QGIS Project Steering Committee from Boundless on Vimeo.

QGIS US User Group: The beginning of something big

David Dubovsky

Last week, Boundless and others hosted the first ever QGIS U.S. User Group meeting with 75 attendees at OpenGovHub in Washington DC.

The event attracted a diverse group of experts and novices from organizations as varied as NOAA, the World Bank, USAID, the American Red Cross, Deloitte, LockHeed Martin, the CDC and many others. As a new member of QGIS community myself, I was floored by the energy of the group and how quickly the project is evolving.


Building QGIS

The day started with Jeff Johnson and Larry Shaffer setting the stage with presentations highlighting the history and evolution of QGIS from a shapefile viewer to full-fledged desktop application. Jeff went into detail about specific applications of QGIS, highlighting examples from NOAA and NASA. Larry picked it up from there and discussed the QGIS ecosystem and open source development community. He noted that plug-in development has been a long-time focus within the community and sees core development picking up steam in the coming year.


Next, Tim Sutton from the QGIS project steering committee joined remotely. Thanks to OpenGovHub’s fantastic conference abilities, Tim being in South Africa didn’t pose a challenge. Tim provided further context to Larry’s discussion on core and plugin development and the steering committee’s focus for 2014.


Later on, Gary Sherman joined remotely from Alaska and provided a brief history of QGIS development, including it’s origin as a shapefile viewer. Gary is also the author of the PyQGIS Programmer’s Guide on developing QGIS Plugins.

QGIS for Humanitarianism

After the remote sessions, Kate Chapman of the Humanitarian OpenStreet Map Team gave us an overview of InaSAFE, a QGIS plugin for emergency preparedness and response.


Vivien Depardy and Yewondwossen Assefa of GFDDR then presented on the role QGIS (and GeoNode) plays in their emergency response and disaster recovery efforts. Larry provided context to their efforts, applauding their development model calling it a leading example of development.




After a quick lunch we split into two groups for hands-on workshops. Jeff Johnson led “Using QGIS with OpenGeo Suite” and Larry Shaffer led “How to Become a QGIS Developer”. I attended Jeff’s session, which provided a good opportunity to review the fantastic QGIS documentation with an experienced instructor. Jeff used the documentation as a starting point but added his tips and tricks along the way. He ended by showing us how to use the OpenGeo Explorer plugin to publish data to GeoServer.


My colleague, Eva Shon, attended Larry’s workshop. Larry’s goal was to get more developers involved on the QGIS project. As the only core developer in the United States, he’s especially interested in increasing the number of developers from North America. He shared an early draft of QGIS core developer documentation and virtual machine images he’s working on intended to help new developers get started more quickly.


Next Steps

Whether you were looking for an introduction to QGIS or were already active in the community, the day had something for everyone. The event ended with a happy hour and the only question left was when we’d do it again. To learn more about QGIS, download and install it using the OpenGeo Suite installer and check out documentation to see what it can do. Stay tuned for next QGIS U.S. User Group meetings being planned in Atlanta and Seattle.


Thoughts from State of the Map US 2014

Gretchen PetersonThe State of the Map US 2014 conference, a two-day conference covering all things OpenStreetMap, was held this past weekend in Washington DC. It was nice to attend as part of the Boundless contingent and meet — in person — tons of people whom I had only heretofore known via the internets.

Aside from the inspiration provided by the gorgeous weather and the cherry blossoms, there was also inspiration in abundance at the conference for cartographers. Every cartographer should become familiar with OpenStreetMap data if they aren’t already. It’s a bit of a bear to work with because it is in a different structure than we are normally used to (nodes and ways mean anything to you?) but you’ll see the benefits if you download a state-wide or city-wide extract from one of several sites (such as geofabrik or Metro Extracts) and start using it in your map-making medium of choice. The dataset provides a comprehensive collection of roads, buildings and building types, points of interest, and so on. And it’s free!

There were many talks I didn’t get to see because there were two concurrent tracks, but the ones that I attended focused heavily on tools that for using OpenStreetMap data, including GeoGit, TileMill, Esri, QGIS, and PostGIS. However, there were still some cartographic takeaways.

  • Kate Watkins, Seth Fitzsimmons and Alan McConchie told us that a great way to build a stylistically cohesive basemap is to focus on three main hues, along with variations on those hues.

  • In that same talk we saw some great examples of labels that break all the rules: the leading and kerning (that’s line spacing and character spacing, basically) are decreased to negative values and the halos are very large and black. Of course this is the opposite of what most texts will recommend but it just proves that breaking the rules once in a while can make for some neat cartographic effects.

  • Eric Theise showed us that applying some of the devices of experimental film to maps, such as perception distortion, can be a creative way to get people thinking. Eric and I were discussing this later on in the day when he mentioned that he thought it would be interesting to have a map that taunted you if you tried to click on a feature to find out more about it. Something like, “You’d like to know what this building is, wouldn’t you?!”

  • Kevin Bullock told a great story about a map of India that was produced in the 1800s with crude tools, took 70 years to complete, and astonishingly accurate despite these and other limitations. And you thought your map products took a long time to produce!

  • Our own Jeff Johnson rounded out the weekend with a more technical talk that examined the ways in which GeoGit could lead to a more distributed and decentralized architecture for OSM.

There was a lot more material covered, of course, and these points focused just on the cartography aspect of OpenStreetMap use. All the talks are now posted on the schedule part of the conference website so definitely take the time to watch them!

If you’re still curious about State of the Map, I recommend this great recap from Peter Batty which provides more details about the event and reviews other issues in the OpenStreetMap community including vector tiles, licensing, passive crowdsourcing, geocoding and more.

Support story: Deterministic rendering order in SLDs

MassGIS As with our first support story, this one comes from MassGIS, the official state agency assigned to the collection, storage, and dissemination of geographic data. When a layer has overlapping lines or polygons, we often want to control which ones are rendered on top and which ones are rendered below. The classic example is when we have a roads layer that contains overpasses that we want to appear above regular roads at ground level. MassGIS was dealing with a land-usage layer which required one type of polygon to be rendered with a solid color and other types to be rendered above with specific patterns.

The Aral Sea Example

We can simulate this problem by taking a layer that has both current and historical extents of bodies of water. In particular we’ll look at the Aral Sea, which shrunk considerably in the twentieth century. We’ll want to style the historical extents using hatching and then overlay the current lake in a plain blue style. What we don’t want is to have the historical bounds drawn over the modern lake.

You can test on your own GeoServer install with the data and SLDs in this ZIP.

SLD Rules

Our first attempt at creating an SLD to draw the two polygons in the correct order is to use two rule statements: the first will match our historical layer (where attribute type is equal to historical) and the second will match the modern layer (where the attribute type is equal to modern). We expect this to draw the historical lakes first and then the modern lakes on top:

<sld:StyledLayerDescriptor version="1.0.0" xmlns:sld="http://www.opengis.net/sld">
    <UserStyle xmlns="http://www.opengis.net/sld">
          <Name>Historical area</Name>
          <Name>Modern area</Name>

Unfortunately, this gives us the opposite effect: the historical area has been rendered above the modern area.

Since this ordering of the rules didn’t work, we can try switching them around in the SLD, putting the rule for modern lakes first and historical lakes second. If you test this in GeoServer, however, you will see that the image that we get back is not affected.

Since reordering rules in an SLD does not affect the output image, we had to provide another approach.

SLD FeatureTypeStyle

The answer to the problem is to use the rules in separate <FeatureTypeStyle> sections of our SLD document:

<sld:StyledLayerDescriptor version="1.0.0" xmlns:sld="http://www.opengis.net/sld">
    <UserStyle xmlns="http://www.opengis.net/sld">
          <Name>Historical area</Name>
          <Name>Modern area</Name>

Why does this work?

Our first approach did not work since rules inside a single FeatureTypeStyle are applied to features as they arrive from the data source. GeoServer was drawing the modern Aral Sea first and the historical Aral Sea second simply because that is the order in which they were stored in the shapefile.

Even if the order had been correct, it would have been dangerous to rely on it for styling since that order could change at any time.

To reliably control the rendering order, therefore, we need the multiple FeatureTypeStyle blocks. GeoServer will draw each of these independently and then merge them in the defined order as the last step.

Benjamin Trigona-Harany leads our global support team from our offices in Victoria, BC. Interested in support or training for your enterprise? Contact us to learn more.

Use QGIS for the Bay Area Bike Share Open Data Challenge

Gretchen PetersonThe San Francisco Bay Area Bike Share Open Data Challenge is now underway, with entries due April 25, 2014. The idea is to use their open data on bike stations, bicycle traffic patterns, and weather to create an interesting visualization, map, or other product that adds value to the program.

Using open source mapping tools is a great way to explore the data and create winning entries for the contest. For those who are new to making maps out of open data, we’re here to help you get started. In this tutorial we’ll show you how to use QGIS, a popular mapping software product, to create a simple map out of the data. Build on this foundation to create your own contest entries and learn about data and geospatial technology along the way.

To get started, download all four data files from the contest website here. After you unzip the data you’ll see that it’s in CSV format. This is a comma delimited text file format that’s useful for spreadsheets and geospatial tables.

Installing QGIS

First, download and install QGIS. Then install the OpenLayers plugin, which simplifies adding some of the most common base layers, such as Google Maps or OSM, and makes it easier to visualize the bike station locations. You can install it by opening the Plugin Manager, selecting the Get more section and then searching for OpenLayers.


Now in the Plugins menu you should have a new entry where you can select the layers to add.



Adding bike share data

Add whichever basemap you like. In the following screenshots, you will see that we’ve added the Bing Road layer, which is less saturated than some of the others. A less saturated basemap helps to highlight the data that will be overlaid. You can zoom into San Francisco now or wait until the bike share data is added. To create the bike share data overlay, use the Add Delimited Text Layer button.


Add the station data file using the browse button. Use the x and y drop down selectors under Geometry definition to tell QGIS which fields have the latitude coordinates and which have the longitude coordinates. Latitude is y and longitude is x.


Your input should look like the screenshot above. Press OK. In the Coordinate Reference System Selector, type in “4326” in the Filter box and select WGS 84 in the box directly beneath it. Many — but not all — datasets in open data formats are in the WGS 84, or EPSG 4326, coordinate system.


The QGIS map should now look similar to the screenshot below. If it isn’t zoomed in properly, you can right-click the station_data layer in the Layers list and choose Zoom to Layer Extent.


Joining and analyzing bike share data

There is a lot of data in the other three tables to explore but they need to be joined to the station data first since the station data contains the geometry for displaying the data on the map, while the other tables are related to the station data geometry via its station_id field. Fields that can be used for joining are often described in files that come with the data. The README.txt file that came with this data follows this convention.

In this tutorial we’ll use the trip_data table to perform an analysis and display the results on the map. First the trip_data table needs to be added to QGIS. Click Add Delimited Text Layer again, browse to the trip_data table, and choose “No geometry” next to Geometry layer definition. Press ok. The table is added to the Layers list in QGIS. Right-click the table name in the Layers list and click Open Attribute Table. You can see the data has loaded correctly. Notice that the station_id is used in the Start Terminal and End Terminal fields.


The average duration of a trip from each station is a good first analysis. To get the average duration we have to total up the durations of each trip by Start Terminal. This could be done in a spreadsheet program, exported as a CSV file, and then added into QGIS using the steps described above for loading non-spatial tables. Alternatively, we are providing avg.py, a script created that will do the calculation within QGIS.

In the Processing menu under Options and configuration, expand Scripts and view the folder path. This is the folder path in which to save the Python script. Once the script is saved to that path, restart QGIS.

Open the Processing Toolbox by clicking Processing > Toolbox. It will appear on the right-hand side of the QGIS window. Expand Scripts, Boundless, and double-click “avg.” Fill out the dialog with the following, making sure to save the table as a CSV file in the path of your choosing.


Now you can join the output table with the station data layer in order to visualize the average duration (in seconds) of trips from each station. Double-click the station_data layer in the Layers list to bring up the Properties window. Choose Joins and click the green plus sign near the bottom of the window. Pick the table from the list that contains the average data and the field that has the station ID number. If you used the QGIS script, these will be “output_table” and “class.” The Target field is “station_id.”


Now you can look at the attribute table for the station_data to make sure the join worked properly. If it did, the fields from station_data are now in the table. (If the fields are added to the table but the cells are populated with NULL values, the wrong id field was used in the join process.)

To visualize the duration field, double click the station_data in the Layers list to open the Layer Properties and choose Style. Choose Graduated, output_table_avg for the column to style, and change the color in the color ramp as per your preference. Change the mode to Natural Breaks and press ok. (Choosing a mode that makes sense for the data and for the map is an important part of the analytical process. Here is more information on modes).SmallScale1.png

Zoom in to the denser section to see that data more clearly. Enlarge the circles by double clicking station_data, Style, click the change symbol button and change the size to 3. Click OK twice.


The trips in San Francisco appear to be shorter than the trips in Redwood City. Hopefully this tutorial on using QGIS with the Bay Area Bike Share open data provides a springboard for contest entrants. Good luck!

Interested in QGIS? Learn more at the first QGIS user group meetup in the United States on Friday, April 11!

Boundless Connections: Matt Richards

Matt RichardsWe’re happy to welcome Matt Richards, our new web designer, to the team! Matt will be working from our brand new (and growing) DC office where he’ll be crafting interfaces and developing the user experience for hosted services like Mapmeter and other upcoming products.

Hi Matt. Welcome to Boundless! What were you doing before you joined us?

Most recently, I was at Cvent, a software-as-a-service company that has a platform for event management services. Think of it as Eventbrite for small-to-large businesses who host large events like conferences, meetings, company events, and tradeshows. Cvent manages and automates the more mundane aspects of logistics, marketing, and management for the entire event process.

While there, I worked as a web designer on the marketing team, so my projects were all public-facing. From landing pages, to new product announcements, to complete branding packages, my role was part visual design, part web development, and part creative guru. I led the design and development for Cvent’s most recent marketing project, the CrowdTorch website.

Before all of that though, I began my web design career at the ripe age of 16 in rural West Virginia.

You started a web design company prior to starting college?

There’s not a whole lot to do in West Virginia. <laughs> I stress that I lived in a very rural part of the state and wanted to do something cool out there. When I was younger, I ended getting into the competitive gaming scene. I designed graphics for gaming tournaments, leagues, and that sort of thing. From there I built up word-of-mouth referrals to build my client database, and I also did a lot of client work online.

Around the time I turned 16, I had enough of a client list and enough freelancers in my stable that I made an actual go of it. I registered as a business, began working with local and regional clients and had some pretty good successes along the way. I worked with developers — they do the programming and I would make it look cool. I built out websites, invitations, and collateral for gaming challenges. I was also building online networks for the competitive gaming scene. I became a well-known graphic designer within the gaming circle.

What excites you most about working on the new tools and products that Boundless is currently developing?

With an upcoming product that is taking on a new space in the market, I have the unique opportunity to design an interface and experience that isn’t really constrained by older, out-dated processes. This is really exciting as a designer — it means you can embrace the most recent design ideas and create a new user experience from the ground up. I’m really excited to start making what’ll hopefully be the best looking Boundless product to date.

What are your design resources and sources of inspiration?

Two pillars of the web design community are A List Apart and Smashing Magazine, both blogs I read regularly and find very useful. Some of the most interesting stuff I’ve seen recently has come out of Medium, specifically the Design/UX section. There’s a ton of other stuff scattered around though and I use sidebar.io and Panda to filter through the nonsense and find the best articles. I like to keep current.

What languages or programs are your main ways of working?

As a visual designer, I’m an expert at Photoshop use it quite frequently. But I’m also good at designing using HTML5, Canvas, and CSS3. I also have a some Javascript experience, namely jQuery. I’m also big into the principles of responsive design — all of my designs for the last year have been fully responsive. One area that I haven’t had a lot of experience is Less, but I’m excited to be using it at Boundless.

Do you have any experience with open source development?

I’m limited in this regard. I was exposed early on to the virtues of open source from my Dad, who was a passionate open source developer. I remember that he was always on Slashdot — this was back in the days when Slashdot was just the worst looking website around. <laughs> He was really passionate about using open source tools and was a big Linux advocate. I was very pro-Windows in those days, due mostly to my interest in gaming. I just didn’t have the appreciation for anything beyond the Windows gaming world back then. But now that I’m older I can see what my dad was excited about it. I’m really excited to be at a company that has open source values.

What do open source values means to you?

To me, it means the willingness to select tools and components that are the right ones for the task at hand. At proprietary companies, I see that there is more of a business decision process that leads development. That leads to tools and solutions being chosen based on political or cultural factors. Boundless seems to have a strong culture of embracing the best ideas and products and using the right tools for the job. An open source foundation provides a lot more flexibility and control.

What has been your favorite project to have worked on?

Professionally, my favorite project was the company career microsite for Cvent. I was able to go off-brand with colors and treatments, which was a satisfying technical and aesthetic challenge. There is a lot of video and photo assets that I incorporated into the site and I was able to make it more friendly and approachable than the typical branding was. It was immensely satisfying being able to stretch my design wings.

Another project that I really enjoyed working on was a the full brand build-out for CrowdTorch. I worked on the color, typography, icons, website design, and development. It was a really exciting project, because most what resulted was stuff that I conceptualized, designed, and eventually developed.

What’s an interesting facts about yourself (that you haven’t already said)?

When I was 15 years old, my family moved out to middle of nowhere: Thomas, West Virginia. Our parents decided to homeschool my two sisters and me. As part of that, we opened a music venue and cafe called The Purple Fiddle in an old general store. It was a bar/cafe/performing space in a small town. It was a much-needed venue for the area. The town had a population of about 250 people, and basically cafe was the highlight of the area’s entertainment.

For those of us not familiar with competitive online gaming, what are some popular trends right now?

There’s a growing industry known as “esports” that basically boils down to a bunch of gamers sitting in a room and playing video games — mostly Starcraft II, Defense of the Ancients 2, League of Legends, and Counter-Strike: Global Offensive. It doesn’t sound that competitive or interesting, but I assure you it is. At the largest tournaments, tens of millions of people tune in to watch gamers from all over the world compete for millions of dollars in prize money.  The numbers can be staggering at times; the biggest live viewership was 32 million. In comparison, NBA games usually get under 2 million viewers. It’s a bit crazy to comprehend how much it’s grown, but the scene is exploding and I was happy to be a part of it during it’s early stages.

What other hobbies do you have?

I’m a creative at heart, so my hobbies are basically just other creative outlets. I’m a DSLR geek, so I take photography whenever the opportunity arises. Even though there’s not much on it yet, I do plan on posting more photography to my 500px profile. I’ve also made quite a few short films. Here’s a few videos I’ve been proud of: an indie-rock music video, a short film about finding yourself (won an award!), and a trailer for an utopian sci-fi film that never was finished.

 Interested in joining Boundless? We have an amazing team of passionate, creative, and incredibly bright people and we’re hiring more!

GeoGit for Python: Announcing geogit-py

Victor OlayaAt Boundless, we usually describe GeoGit not as an application itself, but as a library. We see it as a basic component of geospatial data management on top of which other applications can be built. While GeoGit currently has a command-line interface (CLI), adding new ways of interacting with GeoGit will increase the possibilities for creating new projects that rely on GeoGit to manage changes to geospatial data. We hope to see GeoGit as the core of an ecosystem of tools that solve a variety of problems.

We have started developing a Python library, the geogit-py library, to make it much easier to create GeoGit-based applications. Since Python is a widespread scripting language, this will allow other developers to incorporate GeoGit-based capabilities into many other applications. In fact, we are already using it to create a plugin to bring the versioning capabilities of GeoGit into QGIS.

Basic GeoGit Automation

The geogit-py library will also make it easier to automate tasks when working with a GeoGit repository, since all the great features of the Python language can be used alongside GeoGit methods. This represents a great feature for all GeoGit users, especially those that use it in a workflow that can be partially of fully automated.

Here are some examples to provide an idea of what using the library is like. A basic workflow should start with something like this:

# Create repo
repo = Repository('path/to/repo/folder', init = True)

# Configure
repo.config(geogit.USER_NAME, 'myuser')
repo.config(geogit.USER_EMAIL, 'myuser@mymail.com')

# Add some data and create a snapshot
repo.addandcommit('first import')

You can automate this first step and easily import a set of layers , creating a different snapshot for each one. Assuming that we have a set of shapefiles in a folder, the following code will do it.

for f in os.listdir(folder):
if f.endswith('.shp'):
   path = os.path.join(folder, f)
   repo.addandcommit('Imported ' + f)

Editing Features

In a normal GeoGit workflow, you export from a GeoGit repository, edit the exported data using the tool of your choice (i.e. a desktop GIS like QGIS), and then import the changed layer so GeoGit can compute the changes that have been introduced, which are later used to create a new snapshot.

With geogit-py, that approach is still possible, but you can also edit without exporting while directly modifying a feature. Internally, geogit-py still calls GeoGit import/export commands but wraps them to expose them in a more practical way. It is also more efficient, since it does not import/export the whole layer. Here’s an example.

# Take a feature and modify its geometry
feature = repo.feature(geogit.HEAD, 'parks/1')
geom = feature.geom
attributes = feature.attributesnogeom
newgeom = geom.buffer(5.0)

# insert the modified geometry and create a new snapshot with the changes
repo.insertfeature(feature.path, attributes, newgeom)
repo.addandcommit('modified parks/1 (buffer computed)')

In this case we have computed a buffer, but you can modify the geometry as you like. Geometries are Shapely objects, so you can use all the methods in that powerful library to work with them. You can also modify the non-geometry attributes in the feature (though we haven’t done so in that example).

Working with GeoGit Branches

Working with branches is also rather simple:

# Create a branch at the current HEAD commit to work on it
repo.createbranch(repo.head, 'mybranch', checkout = True)

# [...] Perform some work on the branch, modifying the repo data and creating new commits

# Bring changes to master branch (which might itself have changes)
        print 'Merge correctly executed. No merge conflicts'
except GeoGitConflictException, e:
        print 'Cannot merge. There are merge conflicts'

Growing GeoGit

Although most of the functionality of GeoGit is already available through geogit-py, some features are not yet supported. Unsupported features mostly correspond to convenience options that can very easily be implemented, or replicated with a few lines of Python code.

A side effect of developing geogit-py is that it has helped us improve GeoGit itself. Several new features have been added to GeoGit commands to allow for a better integration, and some new commands have even been implemented. Using GeoGit from geogit-py has given us more insight into ways that GeoGit can be used by different applications and services, and has helped us shaping it and improving it.

A comprehensive test suite is included with geogit-py, which represents a real test suite for GeoGit itself, adding to the large collection of sets that GeoGit has. Moreover, we have plans to use geogit-py as part of our quality assurance, specifically for testing GeoGit and prototyping GeoGit use cases.

Soon we will release some of the projects that we are working on that rely on geogit-py. Stay tuned for further updates.

Code Sprinting in Vienna

Over 50 people came together in Vienna last week for five days of working on open source geospatial software. This code sprint merged the annual “C tribe” sprint — PostGIS, MapServer, GDAL, PDAL, and others — with the regular sprints held by the QGIS and GRASS communities. As a result, the attendance was at a record level, and the opportunities for collaboration much greater.

PostGIS 2.1.2 & 2.0.5 Released

I attended to work on PostGIS development, as usual, and achieved my modest goal: closing all the remaining tickets and getting 2.1.2 and 2.0.5 released. These are both bug fix releases, so no new functionality is included, but there are some important issues in the 2.1 branch that were resolved with the 2.1.2 release.

More QGIS in Our Future

Wearing my OpenGeo Suite product manager hat, the sprint was an excellent opportunity to sit down and talk with leaders in the QGIS community about our plans for bundling QGIS with OpenGeo Suite. When OpenGeo Suite 4.1 is released later this year, it will include builds of QGIS for all our supported platforms (Windows, OSX, Linux). It will also have some specialized plugins for managing map composition and versioned editing within QGIS. Our own Victor Olaya is a QGIS community member and a developer of the the Processing framework (formerly Sextante) in QGIS. We’re looking forward to being a part of the QGIS community, in the same way that we are a part of the OpenLayers, GeoServer and PostGIS communities.

Building Community

Five days is a long time to hunker down in a room slinging a code, and there were a lot of valuable side meetings: developers showed off some of their latest work (I saw some great 3D work from the PDAL’s Howard Butler and Oslandia’s Olivier Courtin); the QGIS community worked through important design decisions; and Tim Sutton and Anita Graser collected lots of interviews for the QGIS podcast.

Code Sprint Beer Mat

The “beer track” (not run concurrently with the other tracks) was also great, thanks to Stephan Meißl’s organizing: some onsite events, a walk and dinner in downtown Vienna, and a dinner in the local neighborhood. Most importantly, opportunities to get to know developers from other communities and bring the whole open source geo community closer together.

Next year, the sprint will once again combine as many communities as possible (hopefully adding some!), this time in a North American venue (likely Philadelphia). I’ll certainly be in attendance. If you write open source geo software, I hope you will too.


Support Stories: Styling with GeoScript


NYC DoITT, the New York City Department of Information Technology and Telecommunications, oversees the use of existing and emerging technologies in government operations and delivers various services to city residents. Since we have an office in NYC, we’re particularly proud to support them as OpenGeo Suite customers.

The Issue

Not long ago, they asked for ways to create styles based on the number of hours that had elapsed since a feature was created, a calculation that would otherwise have been impossible using a regular SLD. In a previous support story, we described using WPS in SLD to alter a geometry prior to rendering. While some rendering transforms — such as heatmaps and contour maps — are relatively well-known, GeoServer facilitates the use of Python or other scripting languages to help style data. By writing the logic in Python, NYC DoITT would be able to use the standard datetime module to style features. Below we’ll review how to use GeoScript to perform more advanced styling programmatically.

Installing GeoScript

Before we start, we will need to install the right extensions to OpenGeo Suite, particularly the GeoServer Python scripting extension. On Linux, you can simply install the geoserver-script package. On Windows, scripting is an option in the OpenGeo Suite installer.

On OSX, you will need to manually install the plugin by downloading the community build, selecting “Open Webapps Directory” from the menu, and dropping the .jar into geoserver/WEB-INF/lib.

Deploying scripts

Once GeoScript is installed, we can add our Python scripts to the scripts/functions directory in the GeoServer data directory. A simple test is to create a script named random_colour.py that returns a random colour:

import random

def run(value, args):
 return random.choice(["#000000", "#ff0000", "#00ff00", "#0000ff"])

We can then create an SLD that calls this function. The following SLD is based on the default polygon style in GeoServer, with one line changed:

<?xml version="1.0" encoding="ISO-8859-1"?>
<StyledLayerDescriptor version="1.0.0"
 xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
    <Name>geoscript test</Name>
          <Name>random colour</Name>
              <CssParameter name="fill">
                <ogc:Function name='random_colour'/>
              <CssParameter name="stroke">#000000</CssParameter>
              <CssParameter name="stroke-width">1</CssParameter>

Instead of referencing a fixed grey colour, <ogc:Function name='random_colour'/> calls random_colour.py and uses the evaluated value as the polygon fill colour. The Python code simply selects at random from a list of colors — in this case: #000000, #ff0000, #00ff00 and #0000ff — and then returns it.

We can test this new style with the default opengeo:countries layer that ships with OpenGeo Suite. Every time a new request is made, the polygon colours should be randomly generated again.


Using Arguments

To make our SLD functions more useful, we can style based on attribute values by passing arguments to the function. Let’s create a new Python script to manage the values of each colour by mapping the value of the mapcolor9 attribute of the opengeo:countries to a colour. We will call this script colour_9.py and put it in the same scripts/functions directory:

def run(value, args):
  colour = args[0]

  if colour == 1:
    return "#fbb4ae"
  if colour == 2:
    return "#b3cde3"
  if colour == 3:
    return "#ccebc5"
  if colour == 4:
    return "#decbe4"
  if colour == 5:
    return "#fed9a6"
  if colour == 6:
    return "#ffffcc"
  if colour == 7:
    return "#e5d8bd"
  if colour == 8:
    return "#fddaec"
  if colour == 9:
    return "#f2f2f2"

This will use the value of the first argument as the colour for the feature. Our SLD needs to call this function and pass the mapcolor9 attribute as the argument:

<CssParameter name="fill">
  <ogc:Function name='colour_9'>               

While this could be done in pure SLD, it can be easier to manage complex styling rules using scripts rather than XML.

Logging to geoserver.log

Any print statements in the Python script will appear in the GeoServer logs. Let’s modify our SLD to add a second argument:

<CssParameter name="fill">
  <ogc:Function name='colour_9'>               

Then let’s print out all our arguments from the script:

def run(value, args):
  print args
  colour = args[0]


We should now see lines like the following in geoserver.log:

[2.0, Aruba]
[6.0, Angola]
[6.0, Anguilla]
[1.0, Albania]
[4.0, Aland]
[1.0, Andorra]
[3.0, United Arab Emirates]
[2.0, Armenia]
[5.0, Antigua and Barbuda]
[3.0, Austria]
[5.0, Azerbaijan]
[5.0, Burundi]
[1.0, Belgium]
[2.0, Benin]
[5.0, Burkina Faso]
[1.0, Bulgaria]
[1.0, Bahrain]

Using feature geometries

Attentive readers will have noted that in addition to args, our scripts have an additional value parameter. This variable contains an instance of GeoScript’s org.geotools.feature.simple.SimpleFeatureImpl. This means we have access to the feature’s geometry and, since these geometries are JTS objects, we can use methods such as getArea() in our script:

def run(value, args):
  geom = value.getDefaultGeometry()
  print "%s: %f" % (args[1], geom.getArea())


The modified script above will simply record the area of each geometry in the GeoServer logs before styling it.

Scale-dependent styling

DoITT also identified scale-dependent styling as another use for GeoScript. Rather than writing filter functions in our SLD, we can instead pass our current scale as an argument to a new function and use this to format the label. Our script, country_label.py, can use the current scale to decide which of the three possible labels to use:

def run(value, args):
  abbrev = args[0]
  normal = args[1]
  formal = args[2]
  scale  = args[3]

  if scale > 10000000:
    return abbrev
  if scale < 5000000:
    return formal
  return normal

The three arguments are an abbreviated name, a regular name and a formal (long) name for each country. The corresponding SLD appears as:

    <ogc:Function name='country_label'>      
      <ogc:Function name="env">
    <CssParameter name="font-family">DejaVuSans</CssParameter>
    <CssParameter name="font-size">10.0</CssParameter>
    <CssParameter name="font-style">normal</CssParameter>
    <CssParameter name="font-weight">normal</CssParameter>
      <CssParameter name="fill">#FFFFFF</CssParameter>
    <CssParameter name="fill">#000000</CssParameter>

Once again, we could have written these rules directly into our SLD, but using GeoScript allows us to maintain complex styling more efficiently.

Adding Nuance

We might want to combine our scale-dependent rule with the area calculation so that we do not have instances of large countries with the abbreviated labels (as in the case of France being labelled Fr. in the image above):

def run(value, args):
  abbrev = args[0]
  normal = args[1]
  formal = args[2]
  scale  = args[3]
  area   = value.getDefaultGeometry().getArea()

  if scale > 10000000 and area < 5000:
    return abbrev
  if scale < 5000000:
    return formal
  return normal

Now, countries with a large area will use the country name rather than the abbreviations that we saw in the earlier example. Smaller countries, such as most of those in the Balkans, still have their names abbreviated.


Another use of GeoScript in SLDs is creating filter functions. To continue the example of using country names, we might want to find all countries whose formal designations are comprised of five or more separate words. In this case, Federal Republic of Germany would not be shown on our map, but Independent State of Papua New Guinea would.


Using Python, we can create a file called long_names.py with this relatively simple calculation:

def run(value, args):
  formal  = args[0]

  if len(formal.split()) >= 5:
    return True
  return False

We can then use this filter in our SLD by adding a filter after our rule name:

  <Name>long country names</Name>
      <ogc:Function name="long_names">               

When the script returns True, the feature will be displayed.



Organisations like NYC DoITT choose to use GeoScript because it allows them to do complex time calculations which would have been impossible in SLD but are simple in Python or JavaScript. There are other similar applications for dealing with complex data types; however, incorporating GeoScript can also make regular styling rules more concise and therefore easier to understand and maintain.

Benjamin Trigona-Harany leads our global support team from our offices in Victoria, BC. Interested in support or training for your enterprise? Contact us to learn more.