Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add package extension on RecipesBase #143

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

Conversation

evetion
Copy link
Member

@evetion evetion commented Jul 12, 2024

This moves all the plots related code, including the macro(!) into GeoInterface. This now works:

using GeoInterface, Plots
Precompiling GeoInterface
  1 dependency successfully precompiled in 1 seconds. 1 already precompiled.
[ Info: Precompiling RecipesBaseExt [b9601432-96b0-576e-9c4b-47fc12d2b5bf]
points = GeoInterface.Point.(rand(10),rand(10))
julia> plot(points)
Screenshot 2024-07-12 at 10 28 16

Since we now export the macros, I think the existing GeoInterfacesRecipes continues to work, even though it's now empty.

@evetion evetion requested review from rafaqz, visr and asinghvi17 July 12, 2024 08:29
Project.toml Outdated Show resolved Hide resolved
src/plots.jl Outdated
Comment on lines 144 to 151
macro enable(typ)
esc(expr_enable(typ))
end

# Compat
macro enable_geo_plots(typ)
esc(expr_enable(typ))
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, this is no longer available as a "name" to import from GeoInterface / some other package. Do you want to keep the package GeoInterfaceRecipes and just load that code path as the extension?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The macro is exported by GeoInterface now, so it should be usable. I've answered your other question in the general comments.

@evetion
Copy link
Member Author

evetion commented Jul 12, 2024

This at least fixes #110 (for people that forget to do using GeoInterfaceRecipes).

I still have to check whether this can be used to deprecate GeoInterfaceRecipes completely, and how that would work. Essentially, as soon as a package uses RecipesBase, it would trigger this package extension, but if it triggers in an extension on RecipesBase, then the macro would not be available.

evetion and others added 2 commits July 12, 2024 11:39
src/plots.jl Outdated Show resolved Hide resolved
@asinghvi17
Copy link
Member

I'm also not sure about defining @enable as being only for Plots. Since RecipesBase is pretty small, (as is MakieCore), is there an issue with keeping the packages as they are, and simply using an include trick on GeoInterfaceRecipes for a package extension?

@evetion
Copy link
Member Author

evetion commented Jul 12, 2024

Yeah the other solution that I considered is just duplicating the code. I'm pretty unsure about include, as it's a standalone package, even though it's in a monorepo here right?

@rafaqz
Copy link
Member

rafaqz commented Jul 15, 2024

Can we just do the include("../GeoInterfaceRecipes/src/GeoInterfaceRecipes.jl") and include("../GeoInterfaceMakie/src/GoInterfaceMakie.jl") tricks in extensions GeoInterfaceRecipesExt and GeoInterfaceMakieExt?

Then we don't have the circular dep on the sub-packages but we can use the same code and not break anything.

It does end up using a bit more compilation and memory as its the same code used twice, but I think that's ok.

Edit: we may need to move code out of the modules into separate files for this to work.

@asinghvi17
Copy link
Member

GIMakieExt is circular but RecipesExt could work

@rafaqz
Copy link
Member

rafaqz commented Jul 15, 2024

Oh of course because Makie depends directly on GeoInterface.jl via GeometryOps.jl, forgot for a second.

Maybe... could we just move the GeometryBasics.jl geointerface code to an extension in GeoInterface.jl?

We need to solve this somehow

@asinghvi17
Copy link
Member

I think we tried to in a GeometryBasics PR but I ended up not wanting to do that for some reason. We can in theory just have Makie depend on GeoInterfaceMakie too...

@evetion
Copy link
Member Author

evetion commented Oct 12, 2024

Can we just do the include("../GeoInterfaceRecipes/src/GeoInterfaceRecipes.jl") and include("../GeoInterfaceMakie/src/GoInterfaceMakie.jl") tricks in extensions GeoInterfaceRecipesExt and GeoInterfaceMakieExt?

Then we don't have the circular dep on the sub-packages but we can use the same code and not break anything.

It does end up using a bit more compilation and memory as its the same code used twice, but I think that's ok.

Edit: we may need to move code out of the modules into separate files for this to work.

While it seems to work locally, I at least get cache misses for precompiling. I don't think it's intended for code to be included outside of the ext folder/file.

[ Info: Precompiling RecipesBaseExt [b9601432-96b0-576e-9c4b-47fc12d2b5bf] (cache misses: include_dependency fsize change (2))

@evetion
Copy link
Member Author

evetion commented Oct 12, 2024

Ok, moved all the conversion code to the extension so it doesn't slow down GeoInterface itself by default. Only the macro stubs are now left in.

GeoInterfaceRecipes is now empty, it imports RecipesBase and GeoInterface and only re-exports the enable macros. It depends on Julia 1.9 and this version of GeoInterface, so if someone loads this new version it will trigger the package extension. If you have an older version, even though the package extension will trigger, you should get the macro from GeoInterfaceRecipes itself. This effectively deprecates GeoInterfaceRecipes.

I will test this with ArchGDAL (it depends directly on GeoInterfaceRecipes).

@rafaqz
Copy link
Member

rafaqz commented Oct 12, 2024

Cool! Now we need to figure out how to do this with Makie. If we move the GeoInterface code in GeometryBasics to an extension here instead that should work too?

There will be some juggling to do to not break things in the handover

@evetion
Copy link
Member Author

evetion commented Oct 12, 2024

Cool! Now we need to figure out how to do this with Makie. If we move the GeoInterface code in GeometryBasics to an extension here instead that should work too?

There will be some juggling to do to not break things in the handover

It should work, although I'm not that familiar with the triangle of Makie(Core?)/GeometryBasics/GeoInterface. But thinking about it, it might clash on the @enable macro if you also load RecipesBase, since we moved the stub to the shared GeoInterface here.

@rafaqz
Copy link
Member

rafaqz commented Oct 12, 2024

Oh no the @enable macro. Can we rename it in this PR? It shouldn't be @enable in GeoInterface anyway because it unclear what that is, where GeoInterfaceRecipes.@enable was clear

Probably we need to define e.g. @enable_plots here and call the same internal code as @enable, rather than actually moving @enable here.

@evetion
Copy link
Member Author

evetion commented Oct 12, 2024

Oh no the @enable macro. Can we rename it in this PR? It shouldn't be @enable in GeoInterface anyway because it unclear what that is, where GeoInterfaceRecipes.@enable was clear

Probably we need to define e.g. @enable_plots here and call the same internal code as @enable, rather than actually moving @enable here.

We need two, or weird stuff with Module dispatch in the macro (1.10+). So I would go with

  • @enable_plots
  • @enable_makie

src/plots.jl Outdated Show resolved Hide resolved
@rafaqz
Copy link
Member

rafaqz commented Oct 12, 2024

Yeah thats what I mean @enable_plots now, and @enable_makie later

@evetion
Copy link
Member Author

evetion commented Oct 13, 2024

With the latest commits, this now works:

using Plots
using GeoInterface

GeoInterface.geoplot(rand(Tuple{Float64, Float64}, 100))
Screenshot 2024-10-13 at 17 50 07

Using the extension, we can plot any GeoInterface compatible geometry/feature/collection. It required some more hacking of RecipesBase, mostly macroexpanding @userplot (for geoplot) and @recipe (for collections).

This should be fully backwards compatible with GeoInterfaceRecipes. I've anticipated a Makie(Core) extension, so geoplot could work with Makie in the future as well. The only problem is when both extensions are loaded, we'll need some fix for that in a future PR.

@evetion evetion requested review from asinghvi17 and rafaqz October 13, 2024 15:57
@asinghvi17
Copy link
Member

What's the motivation for geoplot? I thought plot from Plots worked fine for all featurecollections / geometries?

@rafaqz
Copy link
Member

rafaqz commented Oct 13, 2024

Yes isn't the idea that plot just works?

@evetion
Copy link
Member Author

evetion commented Oct 13, 2024

plot works if a package also depends on GeoInterfaceRecipes/RecipesBase and does @enable_plot. geoplot works for all GeoInterface enabled geometries.

@asinghvi17
Copy link
Member

I get the feeling that the number of geometries that are GeoInterface enabled but don't have @enable macros in extensions has got to be pretty low by now...also, shouldn't it be the solution to tell people to use @enable instead of a new function they'll have to learn? Enable is generic across all plot types so trying lines or scatter will work equally well - it just gives more options.

Now that the macros will actually be accessible it seems reasonable to do, at least to me...

@rafaqz
Copy link
Member

rafaqz commented Oct 13, 2024

I was also hoping plot would work universally, it almost does already

@evetion
Copy link
Member Author

evetion commented Oct 13, 2024

Ah fair enough, my two major gripes were

  • forgetting to do use GeoInterfaceRecipes as user (fixed by extension in this PR)
  • forgetting to depend on GeoInterfaceRecipes as producer (fixed by geoplot in this PR)

The latter is indeed rarer, and not that important. And geoplot is a new thing indeed, so let's say that this was just a nice exercise in hacking RecipesBase.

I'll revert the geoplot thing, and then this should be good to go.

@asinghvi17
Copy link
Member

forgetting to depend on GeoInterfaceRecipes as producer

That will probably continue to be an issue AFAICT, we can document it better though.

forgetting to do use GeoInterfaceRecipes as user

My understanding is that this PR makes it so that this should not be an issue?


[deps]
GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"

[compat]
GeoInterface = "1"
GeoInterface = "1.3.7"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
GeoInterface = "1.3.7"
GeoInterface = "1.3.8"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants