Google Vector Layers

There’s no shortage of geo data providers these days. It’s quite easy to publish data and make it available to the world in minutes using software like ArcGIS Server, Geocommons, Arc2Earth and CartoDB.

What’s sometimes not easy as it could be, is taking data from these providers and showing them on your slippy map of choice, Google Maps.

For the past few months in my downtime I’ve been working on a library that makes it much easier to view and interact with your data in these services — Google Vector Layers.

With just a few lines of code you can view data from a number of geo web services, symbolize it based on property values and create highly customized InfoWindows using the feature data.

The library works by listening to map events (pan and zoom) and then fetching features within the map’s extent after each event. This method works great for data sets with lots of features that you want to interact with, but not load all at once. But you can also load all data initially if you’ve only got a handful of features and prefer a less chatty approach.

Features

There are number of things that make this library quite handy:

  • Multi-Provider Support – Current support for ArcGIS Server, Arc2Earth, Geocommons and CartoDB (with more in mind)
  • Easy InfoWindow Templating – Create InfoWindow templates with a simple string with property names {mustached} or with a function that gets passed feature properties, and should return valid HTML for the InfoWindow
  • Dynamic Data Support – Easily visualize live data that auto-updates at an interval that you set (and makes sense for your data’s update frequency)
  • Simple, Powerful Symbology – Style your layers with a single symbology, a unique symbol for specific attribute values or set symbols to display if a feature’s attibutes are within a specific range. Or …
  • Use Your Current Styles – If you’re using an ArcGIS Server layer you can use the styles you’ve already spent time creating in ArcMap
  • Scale Dependent Rendering – You wouldn’t want to show lots of features with complex geometries at lower zoom levels – Using scaleRange lets you set the minimum and maximum scales a layer should be visible

The documentation and demo pages have much more detail about all of these features.


Links

  • The Main Page (Start Here) – This will link you to the source code, demos and documentation
  • The GitHub Repo – Please send issues, feature requests and code contributions here
  • Documentation – Go here when you get console errors
  • Demos – Some good code to get you started

Open Data Day Hack

Dec 4th was Open Data Day and coders across the globe were pushing, pulling, analyzing and scraping open data. Spare time has been hard to come by recently so I’m a little late to the party, but I’m happy with the outcome. I thought I’d share what I came up with and how it all came together.

So, what is it?

I created a Google Maps based application that lets users query Mecklenburg County, NC (Charlotte) building permits by location and a number of other parameters. Want to know how many building permits were pulled around 2319 Providence Rd? Sure. Only concerned with permits pulled in 2009? Filter by date. Only interested in finding the new McMansions in the neighborhood? Filter by square footage.

How does it work?

Users determine their search location by either entering an address or clicking the map. Setting the search location drops a marker on the map surrounded by a circular search area. This circle size can be easily changed to query a smaller or larger area. I limit the search area to a maximum radius of 2.5 km to keep the number of results from getting out of hand. My original design adjusted the search area with another slider in the left panel but I found that adjusting the size on the map was much more intuitive.

Once results are visible, we can narrow these down by a number of different parameters found on the left panel of the application. Currently you can filter by a range of square footage, project cost or permit issue date. I find that using sliders is much simpler that typing discrete values of upper and lower bounds. I can also limit the input range for parameters to keep users from searching for project costs with negative numbers. I made sure to style the “active” filters with a bolder look and a drop shadow (sorry IE) to let users know what filters they were using.

To get project details, users can click a marker and the results on the right side of the page should scroll to the corresponding building permit and highlight it. For now I’m showing fairly limited information but this could be easily expanded to show more or a link could be added to show full building permit information (I’m not sure if Mecklenburg County exposes this).

Under the hood

So it’s obvious I’m using Google Maps, nothing new here. With the latest release Google now allows you to animate your markers as they are added to the map. This is how I’m dropping/bouncing them onto the page. It took me a while to decide if this was tacky or cool. I chose cool.

This distance widget came from a Fun with MVC Objects article written by Luke Mahe from the Google Geo team. This is really where a lot of the magic happens. If I would have had to write this myself it would have taken much longer to push out this quick hack.

I’m sure a lot of you will notice right off the bat that I’m using jQuery UI for the sliders. It’s too easy not to.

As far as the “Open Data” goes, I’m pulling everything from Mecklenburg County’s DataPortal which was recently released to easily share spatial data. From here users can connect to WMS services, download KML, or link into the GIS Data Center to download data in other formats. But I prefer to pull straight from a series of RESTful Web Services that are powered by a great open source project.

Ok, show me.

View the application live at http://jasonsanford.github.io/open-data-day-hack/

I also created a short screen cast showing it in action.

GeoJSON to Google Maps Utility

A few months back I posted code on my demo page for converting GeoJSON polygons to Google Maps polygons. Since then I’ve needed to create similar code for points and lines as well. I’ve pulled all of them together and pushed them to GitHub. This should work for most (all?) GeoJSON types.

A quick example

var geojson = {
    "type": "LineString",
    "coordinates": [
        [-80.661983228058659, 35.042968081213758],
        [-80.662076494242413, 35.042749414542243],
        [-80.662196794397431, 35.042626481357232],
        [-80.664238981504525, 35.041175532632963]
    ]
};

var googleOptions = {
    strokeColor: "#FFFF00",
    strokeWeight: 7,
    strokeOpacity: 0.75
};

googleVector = new GeoJSON(geojson, googleOptions);

googleVector.setMap(map);

See my GeoJSON to Google Maps GitHub repository for “full” documentation and a demo page. I’m sure there’s room for improvement so feel free to fork it and notify me of any changes.

Moving From ArcGIS Server to Google Maps API

I’ve been converting Union County’s Community Mapper application from ArcGIS Server to the Google Maps API.

Why?

Do I have anything against an ArcGIS Server solution? Not at all. ArcGIS Server still takes up a lot of room in my tool chest. I just wanted to freshen up the look and feel of a stale application and take a deep dive into the ever-changing API v3.

Benefits

Let Google handle the base map and related traffic. Forget scheduling a map caching job to run for hours (and hours, and hours) every week.

Users are comfortable with Google Maps. Web mapping trends show Google Maps continues to catch (surely have surpassed by now) MapQuest.

The Google Maps API is powerful and has an active community developing applications with it. Got a question? Send it to the group and you’ll get replies within hours, maybe minutes.

Disadvantages

The biggest downer that I see is that you lose complete control over your base map. Sure Google lets your report a problem but there is no guarantee when, or even if, they’ll get around to fixing it. Luckily the Street View crew made it around to a good third or so of Union County so our base map isn’t in bad shape.

With Google there’s always a chance of advertisements popping in at some point in the future. Personally, I have no problem with spatially relevant advertising. That’s the price we pay for someone hosting and updating your web map services. Although, end users might not like the idea of an ad for Jim’s Tire and Lube appearing near their parcel ownership information.

How does it work?

Users select one or many parcels by either clicking the map or using a single search text box. This eliminates the need for having a text box for every type of search a user might use (owner name, parcel number, subdivision, address, etc). With some simple logic on the back end we can query only the tables whose data matches what the user entered. For example: if a user types “8620 Elmsworth” we can be almost certain they are searching for an address. In this case only one table is queried. Alternatively if a user types “Poplin” they could be searching for Poplin Elementary School, the Poplin Farms subdivision, or Poplin Rd. In this scenario more tables are queried for potential results but I haven’t heard any complaining from Postgres yet.

Once parcels are selected a user can uncover lots of spatial data by clicking various tabs within an info window. Questions like “What school district am I in?”, “What flood zones are on my property?” and “Where are my closest parks, libraries and bus stops located?” are just a few mouse clicks away.

On the front end mapping is handled by the Google Maps API (obviously). I’m using a few JavaScript libraries as well. jQuery makes coding by browser unnecessary and makes HTTP requests a breeze. jQuery Tools helps out with some simple tabs and modal overlays and is a much lighter weight UI tool than jQuery UI. For all that autocomplete goodness, the folks over at Devbridge have put together a powerful, yet very simple jQuery autocomplete plugin. jQuery Layout keeps things orderly and helps with some nice collapsible panels. Okay, maybe I went a little overkill on the JS libraries.

On the back end I’m using Union County’s GeoData API to do all of my spatial analysis. These are a series of RESTful web services that allow you to execute spatial queries on a PostgreSQL/PostGIS database through simple HTTP requests. I won’t go into detail here but feel free to check out the documentation for a better explanation.

A few other new features to note:

  • parcel export in kml, csv and xml formats
  • add to your current parcel selection by holding ctrl and clicking the map

Where’s it at?

The old Community Mapper is actually still live but users can choose to try out the new application while I work out a few kinks with the newer version.

Community Mapper 1.0http://gisapps.co.union.nc.us/cm

Community Mapper 2.0 http://gisapps.co.union.nc.us/community-mapper

If you have any questions or comments about the application or you get some errors feel free to let me know. Styling and documentation are lacking as these are the last things I’ll be working on.