Moore Spatial

GIS and Related Pursuits


Bulk Solar Analysis of Lidar Data

I’ve been working with a group of other students on a student led project to make a solar suitability map for the whole state of Minnesota. A full writeup will come after the project is over, but here’s a quick look at what we’ve been doing.

We are using the MN State LiDAR data as the input data. There’s just under a terabyte of compressed LiDAR files.

We used Lastools to generate a raster Digital Elevation Model (DEM) data set.  The DEM data set was another terrabyte of data.

The DEM was used as input to ArcGIS’s Area Solar Radiation tool.

We scripted both the DEM generation and the use of the Area Solar Radiation tool. Both scripts use a PostGIS database to store fishnets representing areas which need to be processed. The PostGIS database effectively acts as a job queue, which means we can run multiple instances of the scripts without re-processing the same area multiple times. This is important because the Area Solar Radiation tool is very slow.

The computer we are testing on is a Quad-core Xeon machine with 32 Gigs of RAM, so it’s a pretty powerful machine. If we ran a single Area Solar Radiation on that machine, it would take over 942 days to complete. With the script and the job queue, we can run 7 instances of the script concurrently (which uses up nearly 100% of the CPU) which brings us down to 134 days if we used just the one computer.

Fortunately, we are working with the Minnesota Supercomputing Institute on this project. With their resources we expect that we’ll be able to run the Solar Radiation tool on the whole state before the semester is over. At this point our scripts are running cleanly on our test computer. We should be running on the super computer in the next week or so.

In the mean time, here are some sample results of our testing. These images are actually measurements of how many kilowatts of solar energy any given point would receive during the year. Brighter points receive more sunlight during the course of the year.


Blegen Hall

Blegen Hall

Minnesota State Capitol

Minnesota State Capitol



Minneapolis Convention Center

Minneapolis Convention Center

Low and High Density Lidar

1.5 points per square meter on the left, 8 points on the right.


Leaflet Tutorial: Using Plugins

I was asked to present at the U-Spatial GIS Brown Bag Series about how to use Leaflet.js.

Michael Moore, Flat Rock Geographics

Wednesday, March 5, 12:00 – 1:00 pm, Blegen 445

Web Mapping Using the Leaflet API: An introduction to the basics of creating a simple web map using Leaflet.js. Topics will include setting up a new map, configuring center and zoom levels, adding points of interest, and creating popups. A breif introduction to HTML and GeoJSON will also be provided. This presentation will be code heavy, and basic familiarity with programming terms (functions, variables) is expected.

The sample code and presentation are available on GitHub.


Stupid Simple Map

Stupid Simple Map (SSMap) might be the easiest way ever to add a map to your website. You just have to add the <script> tags where you want the map to show up. There’s no making divs, no finding tile URLs, etc.

SSMap loads the Leaflet JavaScript and CSS if needed then adds a map right after the <script> tag in your HTML document.

For example, if you place

<script src=''></script>

in your HTML document, you would see something like this:

Default SSMap map

Default SSMap map

Odds are you’d like to have some control over your map, and you do that by setting a query string to the ssmap.js file. For example:

<script src=''></script>

would give you:

SSMap with arguments

SSMap with arguments

The marker appears at the center of the map any time the coordinates are not (0,0).



Each of these options are set in the query string. All options are optional, and I tried to provide sane defaults.

Option Default Values Notes
lat 0 Latitude (decimal degrees) -90 to 90
lon 0 Longitude (decimal degrees) -180 to 180
div random ID string Map div ID. The div also get class ssmap
h 500px Valid CSS height Height of the map div (including units)
w 500px Valid CSS Width Width of the map div (including units)
z 1 1-18 Initial zoom level
tiles sat map (street map) or sat (satelite) Which tiles to use
mark t t (true) or f (false) Place a marker at the map centerpoint if coordinates are not set to 0,0?


Notes For Advanced Users

For advanced usage, you’ll want to use Leaflet directly. It’s not hard, and you can customize just about anything.

You can use the JavaScript directly off of my site by linking to or you can download it and host it on your own site.

You can download the uncompressed version on Github or here.

This script won’t work with SSL. I don’t have SSL configured on this host, and the script itself loads the Leaflet libraries via http (https isn’t available).


Upsidedown Maps With OpenLayers3!

Openlayers3 lets you rotate the 2d viewport. This functionality can be used to make upsidedown maps, so I did.

Code on GitHub
Demo on


Adding To the Leaf Pile

I recently presented at the 2013 MN GIS/LIS conference on leaflet plugin development. You can now see my demo and presentation online.

I demonstrate three ways to write leaflet plugins.

  1. Adding a new method to an existing Leaflet object
  2. Overriding an existing method in an existing Leaflet object
  3. Extending an existing Leaflet object to create your own object


The presentation can be found here:

PDF, Google Docs PDF, SlideShare


The Demo can be found here:

Leaflet-Spiders Demo on

Leaflet-Spiders Demo on GitHub


The code can be found here:



Happy Hacking!



SSTiles — Stupid Simple Tile Maker

SSTiles is a small project I’ve been working on. It’s a simple PHP script that generates XYZ slippy map tiles on demand.

Ideally you’ll use a correctly projected base image (a square image, in Web Mercator projection). Since the image is square, SSTiles will just slice it up, no scaling is needed.


Usage is simple. Place the sstiles.php library and the tile.php or pad.php helper script in a directory with your base map, and add the layer to your map like so:$Z/$X/$Y.png

For Leaflet, you would do:


For OpenLayers you would do:
var basemap = new OpenLayers.Layer.XYZ("Basemap", "${z}/${x}/${y}.png");

Basemap types


A Nice Square Map

A Nice Square Map

Other times it might not matter if the map is correctly projected, in which case you can use a non-square image which will be sliced and scaled so that resulting tiles are square.


A Non-Square Map Is Stretched To Be Square


And finally, for the real use case that I wrote this script, if you want to abuse Leaflet (or OpenLayers, etc.) to make a tiled image viewer for high-resolution images you can ask SSTiles to pad the image so that resulting tiles won’t be distorted.




  • Lets you use any image as a slippy map!
  • Generates slippy-map tiles from a single top-level image!
  • Stretches the image if it’s not square!
    • OR Pads the image if it’s not square!
  • Caches generated tiles!
  • Auto-updates cache when source file is updated!
  • Sends HTTP caching headers!
  • Supports GD and ImageMagick!


What Slippy Map Zoom Level Is Ideal For My Source Map?

If you’re creating XYZ tiles for your slippy map (eg. Leaflet or OpenLayers), and your source is a raster image, you might wonder which zoom level will display the map with the least artifacts.

Or you might not. In any case, if you do want to know what zoom level is ideal, here’s how you find it. The code is in PHP, but should be easy to translate to other languages.

$min_dimension = min($image_width_in_pixels,$image_height_in_pixels);
$zoom_level = round(log($min_dimension/256,2)

Take the smaller of the height or width[1], divide it by 256 and find the base-2 logarithm of that. You will likely need to round that result to get an integer value. That integer will be the zoom level which has to resize your image the least to produce the appropriate tiles.

[1] Really, your source map should likely be square since you’re probably using Web Mercator


Leaflet WFS-T Project

Leaflet.js WFS-T Plugin

I forgot to mention it here, but the WFS-T Plugin was released as planned in the fall of 2013. You can download it here:

…Old Stuff…

This summer I’m going to be implementing WFS-T and some GML simple features support for Leaflet.js. Since I hate seeing vaporware projects — projects which announce grand intentions then never deliver — I’m going to lay out my deadlines ahead of time. The deadline for this project is October, 2013. I have applied to present about it at the fall MN GIS/LIS conference. I will also be using this work as part of a class which I’m counting towards my Master of GIS at the University of Minnesota, so I really do need to get it finished!

This code is being developed by me personally on my own time, but with the support, encouragement and advice of my bosses at Flat Rock Geographics. The initial code and climb up the WFS-T learning curve was done on company time for a project where we were already using Leaflet.js.

Leaflet.js WFS-T and GML Simple Features Support

The goal of this project is to enable WFS-T creation and editing of the shapes created by the Leaflet.draw plugin. Since I will be using GML in the requests I will also implement enough of the GML Simple Feature Profile to fill the needs of the WFS-T plugin.

Work Environment

I will be using Leaflet.js, the Leaflet.draw plugin, Geoserver running on Jetty and Postgres/PostGIS. An initial code commit will be coming very shortly after I separate it out from the rest of the project.

The initial database I will be using can be created as follows:

-- Sequence: idinc


  MAXVALUE 9223372036854775807
  CACHE 1;
  OWNER TO michael;

-- Table: wfstproject

-- DROP TABLE wfstproject;

CREATE TABLE wfstproject
  id integer NOT NULL,
  name character varying,
  ts timestamp with time zone,
  count integer,
  really boolean,
  the_geom geometry,
ALTER TABLE wfstproject
  OWNER TO michael;



Stupid Simple Geocoder

I just released the Stupid Simple Geocoder over on GitHub.

Stupid Simple Geocoder is a PHP geocoder that geocodes to the city level with the GeoNames free geocoding service. In order to reduce web requests and speed up your own page loads it’s backed up by an SQLite cache.

It has a single method named geocode which accepts either a single place name string, or an array of place name strings. In the single case it returns a single GeoJSON Feature object on success, or FALSE on failure. When given an array of place name strings it returns an Array of places it successfully geocoded (NOTE: this means the array could be empty!).

The returned Feature objects could be used to create a GeoJSON FeatureCollection, or for whatever you want. But mainly to construct FeatureCollections. That’s what I do!


Dual Chloropleth With Proportional Symbols.

About: Dual chloropleth maps with proportional symbols. These maps show some figures about Minnesota’s population. Done in ArcGis 10.1
Date: April 16, 2013
Dual Chloropleths with proportional symbology

Dual Chloropleths with proportional symbology