Update rasterizer to avoid callback boxing

Previously the rasterizer used a Function3 for the per-cell summary
callbacks. Something like:
```scala
      val f = (col:Int, row:Int, g:Geometry[_]) => {
        val z = r.get(col,row)
        if (z != NODATA && z < min) { min = z }
      }
```

Since Function3 is generic and isn't specialized this resulted in
boxing on every call. We fixed this by using a new trait
that is concrete in the important value members:
```scala
      val f = new Callback[Geometry,D] {
          def apply(col:Int, row:Int, g:Geometry[D]) {
            val z = r.get(col,row)
            if (z != NODATA && z < min) { min = z }
          }
        }
```

Performance benchmarks:
Old:
```
[info]   benchmark rasterSize     ms linear runtime
[info]  Rasterizer        512   3.12 =
[info]  Rasterizer       1024   9.82 =
[info]  Rasterizer       2048  34.91 =
[info]  Rasterizer       4096 165.10 ========
[info]  Rasterizer       8192 611.54 ==============================
```

New:
```
[info]   benchmark rasterSize     ms linear runtime
[info]  Rasterizer        512   1.54 =
[info]  Rasterizer       1024   3.72 =
[info]  Rasterizer       2048  10.45 =
[info]  Rasterizer       4096  44.88 ==
[info]  Rasterizer       8192 121.38 =====
```