diff --git a/src/geoaxis.jl b/src/geoaxis.jl
index e3fb834f..e253c335 100644
--- a/src/geoaxis.jl
+++ b/src/geoaxis.jl
@@ -7,8 +7,9 @@ Makie.@Block GeoAxis begin
     targetlimits::Observable{Rect2d}
     # "Final limits in input space"
     finallimits::Observable{Rect2d}
-    # Final limits in transformed space
-    transformedlimits::Observable{Rect2d}
+    inputlimits::Observable{Union{Nothing, Rect2d}}
+    # The default transformation, to cache and save on calls to Proj!
+    transform_func::Observable{Any}
     # interaction stuff
     mouseeventhandle::Makie.MouseEventHandle
     scrollevents::Observable{Makie.ScrollEvent}
@@ -289,25 +290,23 @@ Makie.can_be_current_axis(::GeoAxis) = true
 
 function Makie.initialize_block!(axis::GeoAxis)
 
+    ptrans = create_transform(axis.source_projection, axis.target_projection)
+    setfield!(axis, :transform_func, ptrans)
+
     scene = axis_setup!(axis)
     setfield!(axis, :elements, Dict{Symbol,Any}())
 
-
-    ptrans = create_transform(axis.source_projection, axis.target_projection)
-
-    draw_geoaxis!(axis, axis.target_projection, axis.elements, false)
+    draw_geoaxis!(axis, axis.transform_func, axis.elements, false)
 
     return axis
 end
 
 # do the axis drawing
 
-function draw_geoaxis!(ax::GeoAxis, target_projection, elements, remove_overlapping_ticks)
+function draw_geoaxis!(ax::GeoAxis, transformation, elements, remove_overlapping_ticks)
     topscene = ax.blockscene
     scene = ax.scene
 
-    transformation = GeoMakie.create_transform(Observable("+proj=longlat +datum=WGS84"), target_projection)
-
     xgridpoints = Observable(Point2f[])
     ygridpoints = Observable(Point2f[])
 
@@ -333,7 +332,7 @@ function draw_geoaxis!(ax::GeoAxis, target_projection, elements, remove_overlapp
 
     # First we establish the spine points
 
-    lift(ax.finallimits, ax.xticks, ax.xtickformat, ax.yticks, ax.ytickformat, ax.xminorticks, ax.yminorticks, ax.scene.px_area, transformation, ax.npoints) do limits, xticks, xtickformat, yticks, ytickformat, xminor, yminor, pxarea, transform_func, npoints
+    lift(ax.inputlimits, ax.xticks, ax.xtickformat, ax.yticks, ax.ytickformat, ax.xminorticks, ax.yminorticks, ax.scene.px_area, transformation, ax.npoints) do limits, xticks, xtickformat, yticks, ytickformat, xminor, yminor, pxarea, transform_func, npoints
 
         lmin = minimum(limits)
         lmax = maximum(limits)
@@ -583,7 +582,7 @@ function draw_geoaxis!(ax::GeoAxis, target_projection, elements, remove_overlapp
     setproperty!.(values(elements), Ref(:yautolimits), Ref(false))
 
     # finally, make sure that lift runs again - for some reason, it doesn't work directly
-    notify(ax.transformedlimits)
+    notify(ax.inputlimits)
     notify(ax.finallimits)
 
     return nothing
diff --git a/src/makie-axis.jl b/src/makie-axis.jl
index 81f28c04..9d4f4d94 100644
--- a/src/makie-axis.jl
+++ b/src/makie-axis.jl
@@ -9,52 +9,69 @@ Base.convert(::Type{Rect2d}, x::Rect2) = Rect2d(x)
 # Makie.xautolimits(ga::GeoAxis) = (-180, 180)
 # Makie.yautolimits(ga::GeoAxis) = (-90, 90)
 
-function geodefaultlimits(::Tuple{Nothing, Nothing}, source_projection, target_projection)
-    return Rect2d(-180, -90, 360, 180)
+
+geodefaultlimits(axis::GeoAxis, limits) = geodefaultlimits(limits, axis.source_projection[], axis.target_projection[])
+
+# override for the automatic case
+function geodefaultlimits(axis::GeoAxis, ::Tuple{Nothing, Nothing})
+    # if isassigned(axis.scene)
+    #     transformed_data_limits = data_limits(axis.scene)
+    #     need_auto_limits = any(isinf.(origin(transformed_data_limits))) || any(isinf.(widths(transformed_data_limits)))
+    # else
+        need_auto_limits = true
+    # end
+
+    if need_auto_limits
+         # if the transformed data limits are infinite, nothing has been plotted
+        return Makie.apply_transform(axis.transform_func[], Rect2d(-180, -90, 360, 180)) # TODO: make this figure out what the appropriate limits are automagically
+    else
+        return transformed_data_limits
+    end
 end
 
-function geodefaultlimits(limits::Tuple{NTuple{2, <: Real}, Nothing}, source_projection, target_projection)
-    return Rect2d(limits[1][1], -90, limits[1][2] - limits[1][1], 180)
+function geodefaultlimits(axis::GeoAxis, limits::Tuple{NTuple{2, <: Real}, Nothing})
+    return Makie.apply_transform(axis.transform_func[], Rect2d(limits[1][1], -90, limits[1][2] - limits[1][1], 180))
 end
 
-function geodefaultlimits(limits::Tuple{ Nothing, NTuple{2, <: Real}}, source_projection, target_projection)
-    return Rect2d(-180, limits[2][1], 360, limits[2][2] - limits[2][1])
+function geodefaultlimits(axis::GeoAxis, limits::Tuple{ Nothing, NTuple{2, <: Real}})
+    return Makie.apply_transform(axis.transform_func[], Rect2d(-180, limits[2][1], 360, limits[2][2] - limits[2][1]))
 end
 
-function geodefaultlimits(limits::Tuple, source_projection, target_projection)
+function geodefaultlimits(axis::GeoAxis, limits::Tuple)
     (xmin, xmax), (ymin, ymax) = limits
-    return Rect2d(xmin, ymin, xmax - xmin, ymax - ymin)
+    return Makie.apply_transform(axis.transform_func[], Rect2d(xmin, ymin, xmax - xmin, ymax - ymin))
 end
 
-function geodefaultlimits(limits::Rect{2, <: Real}, source_projection, target_projection)
-    return Rect2d(limits)
+function geodefaultlimits(axis::GeoAxis, limits::Rect{2, <: Real})
+    return Makie.apply_transform(axis.transform_func[], Rect2d(limits))
 end
 
+
+
 function axis_setup!(axis::GeoAxis)
     # initialize either with user limits, or pick defaults based on scales
     # so that we don't immediately error
-    targetlimits = Observable{Rect2d}(geodefaultlimits(axis.limits[], axis.source_projection[], axis.target_projection[]))
+    targetlimits = Observable{Rect2d}(geodefaultlimits(axis, axis.limits[]))
     finallimits = Observable{Rect2d}(targetlimits[]; ignore_equal_values=true)
-    transformedlimits = Observable{Rect2d}(finallimits[]; ignore_equal_values=true)
+    inputlimits = Observable{Union{Nothing, Rect2d}}(; ignore_equal_values=true)
     setfield!(axis, :targetlimits, targetlimits)
     setfield!(axis, :finallimits, finallimits)
-    setfield!(axis, :transformedlimits, transformedlimits)
-
-    axis_transform = create_transform(axis.source_projection, axis.target_projection)
+    setfield!(axis, :inputlimits, inputlimits)
 
-    onany(finallimits, axis_transform) do finallims, tfunc
-        transformedlimits[] = Makie.apply_transform(tfunc, finallims)
+    onany(finallimits, axis.transform_func) do finallims, tfunc
+        result = Makie.apply_transform(Makie.inverse_transform(tfunc), finallims)
+        inputlimits[] = result
     end
-    notify(axis_transform)
+    notify(finallimits)
 
     # set up transformed limits
     # TODO get correct values rather than defaulting to all-Earth
 
     topscene = axis.blockscene
-    scenearea = Makie.sceneareanode!(axis.layoutobservables.computedbbox, transformedlimits, DataAspect())
+    scenearea = Makie.sceneareanode!(axis.layoutobservables.computedbbox, finallimits, DataAspect())
     scene = Scene(topscene, px_area=scenearea)
     axis.scene = scene
-    onany(Makie.update_axis_camera, camera(scene), scene.transformation.transform_func, transformedlimits, axis.xreversed, axis.yreversed)
+    onany(Makie.update_axis_camera, camera(scene), scene.transformation.transform_func, finallimits, axis.xreversed, axis.yreversed)
     notify(axis.layoutobservables.suggestedbbox)
     Makie.register_events!(axis, scene)
     on(axis.limits) do mlims
diff --git a/src/utils.jl b/src/utils.jl
index 817a58ae..af1a7f11 100644
--- a/src/utils.jl
+++ b/src/utils.jl
@@ -28,7 +28,7 @@ function Makie.apply_transform(t::Proj.Transformation, pt::V) where V <: VecType
     catch e
         # catch this annoying edge case
         # if pt[2] ≈ 90.0f0 || pt[2] ≈ -90.0f0
-        #     println("Caught a 90-lat")
+        #     println("Caught a 90° latitude")
         #     return Point(t(Vec(pt[1], 90.0f0)) ./ PROJ_RESCALE_FACTOR)
         # end
         println("Invalid point for transformation: $(pt)")
@@ -51,10 +51,40 @@ function Makie.apply_transform(f::Proj.Transformation, r::Rect2{T}) where {T}
     end
 end
 
+_apply_inverse(itrans, p) = Makie.apply_transform(itrans, p .* PROJ_RESCALE_FACTOR) .* PROJ_RESCALE_FACTOR
+
 function Makie.inverse_transform(trans::Proj.Transformation)
     itrans = Base.inv(trans)
-    return Makie.PointTrans{2}() do p
-        return Makie.apply_transform(itrans, p) .* PROJ_RESCALE_FACTOR
+    return Makie.PointTrans{2}(Base.Fix1(_apply_inverse, itrans))
+end
+
+function Makie.apply_transform(t::Makie.PointTrans{2, Base.Fix1{typeof(GeoMakie._apply_inverse), Proj.Transformation}}, r::Rect2{T}) where T
+    f = t.f.x
+    xmin, ymin = minimum(r) .* PROJ_RESCALE_FACTOR
+    xmax, ymax = maximum(r) .* PROJ_RESCALE_FACTOR
+    try
+    
+        (umin, umax), (vmin, vmax) = Proj.bounds(f, (xmin,xmax), (ymin,ymax))
+
+    if isinf(umin)
+        umin = -180.0
+    end
+    if isinf(umax)
+        umax = 180.0
+    end
+
+    if isinf(vmin)
+        vmin = -90.0
+    end
+    if isinf(vmax)
+        vmax = 90.0
+    end
+
+    return Rect(Vec2(T(umin), T(vmin)),
+                Vec2(T(umax-umin), T(vmax-vmin)))
+    catch e
+        @show r
+        rethrow(e)
     end
 end