mon, 01-mar-2010, 18:24

Who owns it?

Updated web app
http://swingleydev.com/gis/loc.html
(for GPS enabled phones within the Fairbanks North Star Borough)

Now that my two year web hosting contract with BlueHost is coming up, I’ve decided to migrate over to Linode. It’s about twice as expensive, but you get your own Xen virtual machine to do with as you want. With BlueHost I wound up needing to compile a whole bunch of software packages (gnuplot, remind, spatialite, a variety of Python modules, etc.) just to get my site to work. And I couldn’t upgrade PostgreSQL, which left me unable to use PostGIS. With my Linode, I put the latest Ubuntu on it, and was able to install all the software I need.

As mentioned, PostGIS is one of the benefits of this. Instead of loading the Fairbanks North Star Borough tax parcel database into spatialite and using a CGI program to extract data, I’m able to query the same data in PostGIS directly from PHP. That means I can do all sorts of cool stuff with the data I’m extracting.

Here, I am using the Google Maps API to draw the property polygon and put a marker at the location from the iPhone’s GPS. You can see the result on the right, taken while eating lunch at the office. If you’ve got a GPS-enabled smart device and you’re in the Fairbanks North Star Borough, the link is http://swingleydev.com/gis/loc.html.

The code that drives the map is at the bottom of this post. The complicated query in the middle of it gets the outermost ring from the polygon, and dumps each vertex as a separate row. This section is in the middle of the Google Maps JavaScript that builds the overlay polygon. Note that this doesn’t handle the few properties in the database that have multiple polygons in their geometry, and it ignores the holes that might be present (if a small chunk out of the middle of a property was sold, for example). I expect these cases are pretty infrequent.

One enhancement would be to include a circular buffer around the point marker so you could get a sense of where the GPS accuracy places you on the map. This is complicated with Google because of the custom projection they’re using. I think it’s called “Google Mercator,” but spatialreference.org lists several projections that look like they might be compatible. I’ll have to give those projections a try to see if I can make a projected circular buffer that looks like a circle. It would also be nice to set the map extent to match the extent of the parcel you’re inside. I don’t know if that’s part of the Google Maps API or not.

Here’s the code:

<script type="text/javascript">
function initialize() {
  if (GBrowserIsCompatible()) {
      var map = new GMap2(document.getElementById("map_canvas"));
      var mapControl = new GMapTypeControl();
      map.addControl(mapControl);
      map.setCenter(new GLatLng(<?php echo $lat; ?>, <?php echo $lon; ?>), 14);
      var polygon = new GPolygon([
        <?php
            $query = "
SELECT
    ST_X(ST_PointN(ST_ExteriorRing(ST_GeometryN(wkb_geometry, 1)),
        generate_series(1, ST_NPoints(ST_ExteriorRing(ST_GeometryN(wkb_geometry, 1))))))
        AS x,
    ST_Y(ST_PointN(ST_ExteriorRing(ST_GeometryN(wkb_geometry, 1)),
        generate_series(1, ST_NPoints(ST_ExteriorRing(ST_GeometryN(wkb_geometry, 1))))))
        AS y
FROM tax_parcels
WHERE ST_Intersects(wkb_geometry, ST_SetSRID(ST_MakePoint($lon, $lat), 4326));";
            $result = pg_query($query);
            $num_rows = pg_num_rows($result);
            for ($i = 0; $i < $num_rows - 1; $i++) {
                $row = pg_fetch_row($result);
                list($vlon, $vlat) = $row;
                echo "new GLatLng($vlat, $vlon),";
            }
            $row = pg_fetch_row($result);
            list($vlon, $vlat) = $row;
            echo "new GLatLng($vlat, $vlon)";
            pg_free_result($result);
        ?>
      ], "#f33f00", 2, 1, "#ff0000", 0.2);
    map.addOverlay(polygon);
    var point = new GLatLng(<?php echo $lat; ?>, <?php echo $lon; ?>);
    map.addOverlay(new GMarker(point));
  }
}
</script>

tags: GIS  GPS  iPhone 
Meta Photolog Archives