func ColorValue(image, targetColor color.Color) float64 {
	ri, bi, gi, _ := targetColor.RGBA()
	r, b, g, _ := image.RGBA()
	ratio := float64(r) / float64(ri)
	if ratio*float64(gi) == float64(g) && ratio*float64(bi) == float64(b) {
		return ratio
	}
	return 0
}
ColorValue takes an image color and the targetColor to compute a value within the [0,1] for the surface.
Currently it does a simple ratio of image/base. However, this does not for for black.
TODO: improve this!
package image
import (
	"image"
	"image/color"
	"github.com/paulmach/go.geo"
	"github.com/paulmach/slide"
	"github.com/paulmach/slide/surfacers"
	"github.com/paulmach/slide/utils/smoothsurface"
)
const (
	suggestedGradientScale = 0.5
	suggestedDistanceScale = 0.01
	suggestedAngleScale    = 0.01
	suggestedMomentumScale = 0.0
)
type Surface struct {
	Surface       *geo.Surface
	SmoothSurface *smoothsurface.LazySmoothSurface
	SmoothingStdDev float64  
	lnglatBound *geo.Bound
	image       image.Image
	targetColor color.Color
	ColorValueFunc func(image, targetColor color.Color) float64
}
func New(
	lnglatBound *geo.Bound,
	img image.Image,
	targetColor color.Color,
	smoothingStdDev float64,
) *Surface {
	return &Surface{
		SmoothingStdDev: smoothingStdDev,
		image:       img,
		lnglatBound: lnglatBound.Clone(),
		targetColor: targetColor,
		ColorValueFunc: ColorValue,
	}
}
func (surfacer *Surface) Build() error {
	if surfacer.lnglatBound.Empty() {
		return surfacers.ErrBoundEmpty
	}
	if surfacer.SmoothingStdDev < 0.0 {
		return surfacers.ErrStdDevNegative
	}
	surfacer.Surface = geo.NewSurface(
		geo.NewBoundFromPoints(
			surfacer.lnglatBound.SouthWest().Clone().Transform(geo.Mercator.Project),
			surfacer.lnglatBound.NorthEast().Clone().Transform(geo.Mercator.Project),
		),
		surfacer.image.Bounds().Max.X-surfacer.image.Bounds().Min.X+1,
		surfacer.image.Bounds().Max.Y-surfacer.image.Bounds().Min.Y+1,
	)
	for i := surfacer.image.Bounds().Min.Y; i <= surfacer.image.Bounds().Max.Y; i++ {
		offset := surfacer.image.Bounds().Max.Y - surfacer.image.Bounds().Min.Y - i
		for j := surfacer.image.Bounds().Min.X; j <= surfacer.image.Bounds().Max.X; j++ {
			surfacer.Surface.Grid[j][offset] = surfacer.ColorValueFunc(surfacer.image.At(j, i), surfacer.targetColor)
		}
	}
	err := surfacer.smooth()
	if err != nil {
		return err
	}
	return nil
}
func (surfacer *Surface) GradientAt(point *geo.Point) *geo.Point {
	return surfacer.SmoothSurface.GradientAt(point)
}
func (surfacer *Surface) ValueAt(point *geo.Point) float64 {
	return surfacer.Surface.ValueAt(point)
}
func (surfacer *Surface) SuggestedOptions() *slide.SuggestedOptions {
	return &slide.SuggestedOptions{
		GradientScale: suggestedGradientScale,
		DistanceScale: suggestedDistanceScale,
		AngleScale:    suggestedAngleScale,
		MomentumScale: suggestedMomentumScale,
	}
}