Java Topology Suite — Sweet!

by

We have been building a sophisticated mapping application in Adobe Flex that enables our internal advisors for Endorsed Local Providers (ELPs) to visualize the regions that our partners cover throughout the country. We’re using MapQuest’s Enterprise API, which has a pretty robust ActionScript 3 library along with a nice Java library.

We wanted to be able to display many zip code polygons on the map, and enable our advisors to click on a zip code and see the ELPs who cover that zip code, among other things. However, early in development, we found that the performance of the application suffered greatly when displaying a large number of zip code polygons.

With focused intensity, we took several steps to improve the performance of the map. These steps include:

  • Reduce the complexity of the zip code polygons.
  • Combine zip codes with multiple polygons into a single polygon.
  • Cache the resulting polygon definitions in our local database, as gzipped XML.

After several failed attempts to accomplish these tasks, we found the Java Topology Suite (JTS), an open source collection of geospacial data manipulation tools created by Vivid Solutions of Victoria, Canada. While capable of many other things, we used JTS to unify multiple polygons into a single polygon, and to reduce their complexity.

Here’s our process to unify and simplify polygons from MapQuest’s API through JTS:

  1. Extract the polygons from a MapQuest FeatureCollection to Well-Known Text (WKT) format.
  2. Create a JTS Geometry object for each polygon.
  3. Use JTS to create a GeometryCollection, then union the polygons with the Geometry.buffer() function.
  4. Simply the resulting polygon with JTS’s TopologyPreservingSimplifier.simplify() function.

Here is the most important portion of the code that does all of the above:

/**
 * Unifies and simplifies a MapQuest FeatureCollection using JTS.
 */
public synchronized FeatureCollection unifyFeatureCollection(
    FeatureCollection origFc, double simplifyTolerance) throws Exception
{
    // Extract polygons from FeatureCollection and convert to Well-Known Text
    ArrayList polygonsAsWTK = featureCollectionToWTK(origFc);

    // Create JTS Geometries
    WKTReader rdr = new WKTReader();
    Geometry[] geom = new Geometry[polygonsAsWTK.size()];
    for (int i = 0; i  0) {
        unifiedPolygon = TopologyPreservingSimplifier.simplify(
                                    unifiedPolygon, simplifyTolerance);
    }
    // Convert result back to FeatureCollection and return
    return jtsGeometryToFeatureCollection(origFc, unifiedPolygon);
}

/**
 * Called by unifyFeatureCollection(), returns
 * the union of the input Geometry array as a single
 * JTS Geometry.
 */
private Geometry unifyPolygonArray(Geometry[] geom)
{
    GeometryFactory fact = geom[0].getFactory();
    Geometry geomColl = fact.createGeometryCollection(geom);
    Geometry union = geomColl.buffer(0.0);
    return union;
}

/**
 * Changes a JTS Geometry into a MapQuest FeatureCollection
 */
private FeatureCollection jtsGeometryToFeatureCollection(
    FeatureCollection origFc, Geometry unifiedPolygon)
{
    FeatureCollection newFc  = new FeatureCollection();
    List polygons  = PolygonExtracter.getPolygons(unifiedPolygon);
    for (Geometry currPolygon : polygons)
    {
        // Parse: POLYGON ((-123.862898 46, -123.863671 46.000707, ....)
        String polygonAsWKT = currPolygon.toText();
        String [] wktPoints = polygonAsWKT.substring(
                                (polygonAsWKT.indexOf("((")+2),
                                 polygonAsWKT.indexOf(")")).split(", ");
        ArrayList newLatLngList = wktPointsToLatLngList(wktPoints);
        PolygonFeature newPf = makePolygonFeatureFromPoints(origFc, newLatLngList);
        newFc.add(newPf);
    }
    return newFc;
}

The result: it works really well. There is still room for performance improvement, but the gains we observed were extremely significant

If you’re working with mapping applications, we’d love to hear from you.  Leave us a comment and tell us about it.

Tags: , , , ,

4 Responses to “Java Topology Suite — Sweet!”

  1. jonwolski Says:

    Great post and great find with JTS—That is some cool stuff.

  2. Omniture Press Release featuring DaveRamsey.com « Tony Bradshaw’s Weblog Says:

    […] companies to leverage their new API toolset (visit post on webmonkeyswithlaserbeams.wordpress.com Post 1 Post […]

  3. rutgers webreg Says:

    rutgers webreg…

    Java Topology Suite — Sweet! « Web Monkeys with Laserbeams…

  4. AviationArticle.com for aeroplane news Says:

    AviationArticle.com for flight news…

    […]Java Topology Suite — Sweet! « Web Monkeys with Laserbeams[…]…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: