Visualization of shapefile - Meshes.jl viz! very slow

Hi. I am switching from using a low resolution GeoJSON file of the entire world (size 23 MB), which was used in the example given by GeoMakie, to a higher resolution shapefile of two countries (using Meshes I merged FRA_adm0 and ESP_adm0.shp geometries read by GeoIO, resulting in 7 MB size .shp).

I used to plot the GeoJSON-based data using poly! of GLMakie:

julia> @time p1 = poly!(ax1, countries; color=(:black,0.0), strokewidth = 1.25, overdraw = true)
  0.263541 seconds (108.53 k allocations: 66.155 MiB, 7.19% gc time)

It consistently loads very quickly. However, when I plot the geometry data of the shapefile, I get:

julia> @time p1 = viz!(ax1,countryshp.geometry,segmentsize=0.5,showsegments=true,segmentcolor=:green,alpha=0.0)
  4.659398 seconds (5.39 M allocations: 12.536 GiB, 37.29% gc time, 2.13% compilation time)

and this is the optimistic measurement, because many times it freezes the entire multi-axis plot window for more than 30 seconds. I suppose that is the GC trying to deal with the allocations. It is not even a large shapefile.

Any suggestions? Is it possible to convert this to a format that poly! can handle instead?

Another option (no need to download the country polygons)

using GMT

@time coast(DCW="FR,ES", region="FR,ES", show=1)
  1.161763 seconds (467 allocations: 28.766 KiB)

The option region="FR,ES" should not be needed here (must fix that).

@oscarvdvelde are you sure you are calling the function @time twice to remove compilation time? Makie does use precompilation to speedup the first plot commands. The viz recipe uses other steps that are not currently precompiled, as we we are evolving many details still.

Also, notice that viz calls the same Makie functions under the hood. So we need to either optimize some pre-processing step, or precompile these steps during package build.

@joa-quim off-topic as usual.

Looks convenient, however I am working with Makie (built an interactive dashboard), and unless I can save or transform that to a format I can load…

I believe the way to improve the issue is by sharing a MWE with the file and time comparison. We can then take a look to see if something can be optimized. viz does a lot of things that the raw poly command doesn`t do, so I would expect different times. Performance optimizations are always welcome though.

Thanks for looking into this, juliohm.
Here is a MWE (just replace the folder names)
EDIT: GeoMakie is also needed to use the collections of GeoJSON.
Country shapes: Dropbox - Shapefiles - Simplify your life

# julia> versioninfo()
# Julia Version 1.10.3
# Commit 0b4590a550 (2024-04-30 10:59 UTC)
# Build Info:
#   Official https://julialang.org/ release
# Platform Info:
#   OS: Windows (x86_64-w64-mingw32)
#   CPU: 16 Γ— 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz
#   WORD_SIZE: 64
#   LIBM: libopenlibm
#   LLVM: libLLVM-15.0.7 (ORCJIT, tigerlake)
# Threads: 16 default, 0 interactive, 8 GC (on 16 virtual cores)
# Environment:
#   JULIA_EDITOR = code
# 
#  relevant package versions:
# βŒƒ [e9467ef8] GLMakie v0.9.11
# [db073c08] GeoMakie v0.6.5
# [f5a160d5] GeoIO v1.12.15
# [61d90e0f] GeoJSON v0.8.1
# [e502b557] GeoTables v1.20.1
# [eacbb407] Meshes v0.42.2


using GLMakie, GeoMakie, GeoJSON, GeoIO, Meshes, BenchmarkTools, Random, Dates

map_area = ((-2.326427594209077, 3.590351594209077), (38.45669579113706, 42.95924220886294))
lon = randn(100_000)
lat = randn(100_000).+41
tim = 1.0:100000.0
GLMakie.activate!(; focus_on_show=true, fxaa=false, title="test")
countries = GeoJSON.read(read(raw"C:\Users\oscar\Documents\Work\Julia\LMA\map\countries.geojson"))
fig = Figure(size = (900,900))
ax1 = Axis(fig[1,1], limits=map_area, xticklabelsize=13,yticklabelsize=13,xtickformat = "{:.2f}Β°E", ytickformat = "{:.2f}Β°N",aspect=1.0)
@time p1 = poly!(ax1, countries; color=(:black, 0.0), strokecolor=:black, strokewidth=1.25, overdraw=true)
@time s1 = scatter!(ax1, lon,lat; strokecolor=:black, marker=:circle, markersize=3.0, strokewidth=0.05, color=tim, colorrange=(1, 100_000), colormap=:turbo)

fig

# To make merged France and Spain shapefiles, I used:
# 
# cd(raw"C:\Users\oscar\Documents\Work\Julia\LMA\map")
# france = GeoIO.load("FRA_adm0.shp")
# spain = GeoIO.load("ESP_adm0.shp")
# fs = vcat(france,spain)
# @show fs.geometry
# GeoIO.save("francespain_vcat.shp",fs)

# fsm = merge(france.geometry[1],spain.geometry[1])
# fs.geometry = fsm
# @show fsm
# GeoIO.save("francespain_merged.shp",fsm)


countries_shp_vcat = GeoIO.load(raw"C:\Users\oscar\Documents\Work\Julia\LMA\map\francespain_vcat.shp").geometry
countries_shp_merged = GeoIO.load(raw"C:\Users\oscar\Documents\Work\Julia\LMA\map\francespain_merged.shp").geometry

empty!(ax1)
@time p1 = viz!(ax1,countries_shp_vcat, segmentsize=1.25,showsegments=true,segmentcolor=:black,alpha=0.0)
@time s1 = scatter!(ax1, lon,lat; strokecolor=:black, marker=:circle, markersize=3.0, strokewidth=0.05, color=tim, colorrange=(1, 100_000), colormap=:turbo)
fig 

empty!(ax1)
@time p1 = viz!(ax1,countries_shp_merged, segmentsize=1.25,showsegments=true,segmentcolor=:black,alpha=0.0)
@time s1 = scatter!(ax1, lon,lat; strokecolor=:black, marker=:circle, markersize=3.0, strokewidth=0.05, color=tim, colorrange=(1, 100_000), colormap=:turbo)
fig

The 3-7 seconds I find viz! to take, is totally optimistic compared to my own GLMakie application, where I zoom into the map to adjust the data ranges, then update all subplots, etc. After a few mouse rectangle selections it hangs the window and never updates the plot, and I have to kill it. This never happened with the GeoJSON. Perhaps it has to do with the garbage collection or some memory leak.

[I noted also that the rectangle mouse zoom built into the axes can become sluggish, not in this example, but when watching finallimits change for custom data cuts. As if it triggers a ton of times before the mouse button is even released…]

With regard to the last part, I can now replicate the extreme sluggishness when used with observables. Just add this to the MWE above:

change = Observable(now())
selection = Observable(trues(100000))
ax1.limits.val = map_area
display(fig)

function lonlatkm(reflat)  # WGS84 ellipsoid, returns distance in km of 1 deg
    y_convfactor_km = (111132.954 - 559.822 * cos(2 * reflat * Ο€/180) + 1.175 * cos(4 * reflat * Ο€/180))/1000
    x_convfactor_km = (Ο€*6378137 * cos(reflat * Ο€/180) / (180 * sqrt(1 - 0.00669437999014 * sin(reflat * Ο€/180)*sin(reflat * Ο€/180))))/1000
    return x_convfactor_km, y_convfactor_km
end

o = on(ax1.finallimits) do xylims
    if (now() - change[]) > Millisecond(400)
        x1 = Float32(minimum(xylims)[1])
        x2 = Float32(maximum(xylims)[1])
        y1 = Float32(minimum(xylims)[2])
        y2 = Float32(maximum(xylims)[2])
        mx = 0.5*(x1 + x2)
        my = 0.5*(y1 + y2)
        dx = (x2 - x1)*lonlatkm(my)[1]
        dy = (y2 - y1)*lonlatkm(my)[2]
        dxy = 0.25*(dx + dy)
        lon1 = mx - dxy/lonlatkm(my)[1]
        lon2 = mx + dxy/lonlatkm(my)[1]
        lat1 = my - dxy/lonlatkm(my)[2]
        lat2 = my + dxy/lonlatkm(my)[2]
        ax1.limits.val = ((lon1,lon2),(lat1,lat2))
        change[] = now()
        selection[] = (lon1 .< lon .<= lon2) .&& (lat1 .< lat .<= lat2)
    end
end

s = on(selection) do sel
    @time begin
        empty!(ax1)
        # p1 = poly!(ax1, countries; color=(:black, 0.0), strokecolor=:black, strokewidth=1.25, overdraw=true)
        p1 = viz!(ax1,countries_shp_merged,segmentsize=0.5,showsegments=true,segmentcolor=:black,alpha=0.0)
        s1 = scatter!(ax1, lon[sel],lat[sel]; strokecolor=:black, marker=:circle, markersize=3.0, strokewidth=0.05, color=tim[sel], colorrange=(1, 100_000), colormap=:turbo)
    end
end

And after a rectangle selection it produces:

3.305668 seconds (5.24 M allocations: 14.742 GiB, 41.39% gc time)
  6.617784 seconds (10.48 M allocations: 29.484 GiB, 41.36% gc time)
  9.909639 seconds (15.72 M allocations: 44.226 GiB, 41.25% gc time)
 13.198308 seconds (20.96 M allocations: 58.968 GiB, 41.25% gc time)
 16.514987 seconds (26.21 M allocations: 73.710 GiB, 41.31% gc time)

Perhaps I am doing something wrong with my observables, but I don’t think it should enter on(selection) so often, and then grow the allocations to 73 GB.

In contrast, the poly! GeoJSON version:

0.318544 seconds (117.54 k allocations: 69.142 MiB, 25.45% gc time)

I made a surprising discovery regarding the big slowdown in the observable version.
It appears that when I call my function lonlatkm inside the on() block, the behavior as shown above (allocating sometimes over a hundred GB) occurs. However, when I comment those lines out, it corresponds to the same behavior as the version without observables (4 sec, 14 GB).

To try this, use:

o = on(ax1.finallimits) do xylims
    if (now() - change[]) > Millisecond(400)
        x1 = Float32(minimum(xylims)[1])
        x2 = Float32(maximum(xylims)[1])
        y1 = Float32(minimum(xylims)[2])
        y2 = Float32(maximum(xylims)[2])
        # mx = 0.5*(x1 + x2)
        # my = 0.5*(y1 + y2)
        # dx = (x2 - x1)*lonlatkm(my)[1]
        # dy = (y2 - y1)*lonlatkm(my)[2]
        # dxy = 0.25*(dx + dy)
        # lon1 = mx - dxy/lonlatkm(my)[1]
        # lon2 = mx + dxy/lonlatkm(my)[1]
        # lat1 = my - dxy/lonlatkm(my)[2]
        # lat2 = my + dxy/lonlatkm(my)[2]
        # ax1.limits.val = ((lon1,lon2),(lat1,lat2))
        # change[] = now()
        # selection[] = (lon1 .< lon .<= lon2) .&& (lat1 .< lat .<= lat2)
        ax1.limits.val = ((x1,x2),(y1,y2))
        change[] = now()
        selection[] = (x1 .< lon .<= x2) .&& (y1 .< lat .<= y2)
    end
end

Thank you for sharing the MWE @oscarvdvelde , we will take a look in the following days.

1 Like

@oscarvdvelde the MWE is producing an error in the first GLMakie.poly! call. Can you please double check it?

MethodError: no method matching convert_arguments(::PointBased, ::GeoJSON.FeatureCollection{2, Float32})

It is saying that some method is missing for GeoJSON.jl + GLMakie.jl.

@juliohm it seems to load normally when I execute all lines before calling poly!
I think you may not have loaded GeoMakie? It seems necessary for that method.
My result is:

Poly{Tuple{Vector{GeometryBasics.MultiPolygon{2, Float32, GeometryBasics.Polygon{2, Float32, GeometryBasics.Point{2, Float32}, GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}, Vector{GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}}}, Vector{GeometryBasics.Polygon{2, Float32, GeometryBasics.Point{2, Float32}, GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}, Vector{GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}}}}}}}}

Although, when I do not load GeoMakie, the error I get is different:

ERROR: `Makie.convert_arguments` for the plot type Scatter and its conversion trait PointBased() was unsuccessful.

The signature that could not be converted was:
::GeoJSON.FeatureCollection{2, Float32}```

Yes, that is probably the case. Let me retry here.

I am already seeing some conceptual issues in the MWE like the following:

In this code, fsm is a single geometry, and fs.geometry is a geometry column with 2 geometries. Can you please reduce the MWE further and make sure that we have two lines of code to compare with GLMakie.poly! and viz!?

The MWE could be as simple as

data1 = GeoJSON.read...
data2 = GeoIO.read...

poly!(ax1, data1)
viz!(ax1, data2)

Yes, let’s use just the Spain shapefile.
MWE:

using GLMakie, GeoMakie, GeoJSON, GeoIO, Meshes, BenchmarkTools, Random, Dates
map_area = ((-2.326427594209077, 3.590351594209077), (38.45669579113706, 42.95924220886294))
GLMakie.activate!(; focus_on_show=true, fxaa=false, title="test")
fig = Figure(size = (900,900))
ax1 = Axis(fig[1,1], limits=map_area, xticklabelsize=13,yticklabelsize=13,xtickformat = "{:.2f}Β°E", ytickformat = "{:.2f}Β°N",aspect=1.0)

data1 = GeoJSON.read(read(raw"C:\yourpath\countries.geojson"))
data2 = GeoIO.load(raw"C:\yourpath\ESP_adm0.shp")

@time p1 = poly!(ax1, data1)
@time p2 = viz!(ax1, data2.geometry)

# comparable execution time, but:

empty!(ax1)
@time p1 = poly!(ax1, data1; color=(:black, 0.0), strokecolor=:black, strokewidth=1.25)
@time p2 = viz!(ax1, data2.geometry, segmentsize=1.25,showsegments=true,segmentcolor=:black,alpha=0.0)

Above, the showsegments=true makes the time increase from 0.2 s to 3-6 s.

1 Like

Before I try to reproduce, can you please confirm that data1 and data2 represent the same dataset, just in different formats? i.e., same geometries, variables, etc.

Well, they currently are not (low resolution world country shapes versus high-resolution Spain shape). I agree it would be the better test to do. I may be able to convert and save the Spain shapefile to a GeoJSON.

Or we can use a data source that offers the same data in both formats. Update:
going to try this one: World - country shapes β€” Opendatasoft

I will try to run the code anyways in the meantime. But yes, comparing the visualization of different datasets makes it difficult to spot bottlenecks.

I am getting opposite results after pre-compilation, with viz! being faster:

  0.326489 seconds (108.53 k allocations: 66.156 MiB, 7.90% gc time)
Poly{Tuple{Vector{GeometryBasics.MultiPolygon{2, Float32, GeometryBasics.Polygon{2, Float32, GeometryBasics.Point{2, Float32}, GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}, Vector{GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}}}, Vector{GeometryBasics.Polygon{2, Float32, GeometryBasics.Point{2, Float32}, GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}, Vector{GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}}}}}}}}

  0.147037 seconds (8.33 k allocations: 27.223 MiB)
Plot{Meshes.viz, Tuple{GeometrySet{2, MultiPolygon{2, PolyArea{2, Meshes.Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}, Ring{2, Meshes.Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}, CircularArrays.CircularVector{Meshes.Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}, Vector{Meshes.Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}}}}}}}}}

I also confirm that the option showsegmnts slows things down:

  0.298819 seconds (108.53 k allocations: 66.155 MiB)
Poly{Tuple{Vector{GeometryBasics.MultiPolygon{2, Float32, GeometryBasics.Polygon{2, Float32, GeometryBasics.Point{2, Float32}, GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}, Vector{GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}}}, Vector{GeometryBasics.Polygon{2, Float32, GeometryBasics.Point{2, Float32}, GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}, Vector{GeometryBasics.LineString{2, Float32, GeometryBasics.Point{2, Float32}, Base.ReinterpretArray{GeometryBasics.Line{2, Float32}, 1, Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, GeometryBasics.TupleView{Tuple{GeometryBasics.Point{2, Float32}, GeometryBasics.Point{2, Float32}}, 2, 1, Vector{GeometryBasics.Point{2, Float32}}}, false}}}}}}}}}

  1.086268 seconds (2.80 M allocations: 6.076 GiB, 21.56% gc time)
Plot{Meshes.viz, Tuple{GeometrySet{2, MultiPolygon{2, PolyArea{2, Meshes.Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}, Ring{2, Meshes.Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}, CircularArrays.CircularVector{Meshes.Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}, Vector{Meshes.Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}}}}}}}}}

This is probably because we needed to emulate showsegments with another Makie call in the past (it didn’t support plotting the boundary back in the days). Will investigate it further.

I think that is the issue.
Using the GeoJSON and Shapefile from the link I posted above,

julia> @btime p1 = poly!(ax1, data1);
  89.230 ms (52212 allocations: 25.81 MiB)

julia> @btime p2 = viz!(ax1, data2.geometry);
  96.113 ms (55132 allocations: 34.56 MiB)

julia> @btime p1 = poly!(ax1, data1; color=(:black, 0.0), strokecolor=:black, strokewidth=1.25);        
  89.852 ms (52211 allocations: 25.81 MiB)

@btime p2 = viz!(ax1, data2.geometry, segmentsize=1.25,showsegments=true,segmentcolor=:black,alpha=0.0);
  2.353 s (2308361 allocations: 5.44 GiB)

ax1 = Axis(fig[1,1], limits=((-180,180),(-90,90)), xticklabelsize=13,yticklabelsize=13,xtickformat = "{:.2f}Β°E", ytickformat = "{:.2f}Β°N",aspect=1.0)

@btime p2 = viz!(ax1, data2.geometry, segmentsize=1.25,showsegments=true,segmentcolor=:black,alpha=0.0);
3.899 s (2308361 allocations: 5.44 GiB)
# sometimes I get it faster (after recreated figure, etc)
  1.570 s (2308341 allocations: 5.44 GiB)

Thanks for checking this out!

So the issue is in the showsegments option, right? We will dive deeper into it, and will report back with updates. Thanks for the MWE and additional details :100:

1 Like

The issue is fixed in Meshes.jl v0.43.5, which will be available in a few minutes:

Here is the reduced MWE:

using Meshes
using GeoIO

import GLMakie as Mke

spain = GeoIO.load("data/ESP_adm0.shp")

fig = Mke.Figure()
ax = Mke.Axis(fig[1,1])

@time viz!(ax, spain.geometry)
@time viz!(ax, spain.geometry, showsegments=true)
  0.145493 seconds (6.75 k allocations: 24.336 MiB)
MakieCore.Plot{Meshes.viz, Tuple{GeometrySet{2, MultiPolygon{2, PolyArea{2, Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}, Ring{2, Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}, CircularArrays.CircularVector{Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}, Vector{Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}}}}}}}}}

  0.148814 seconds (6.76 k allocations: 24.337 MiB)
MakieCore.Plot{Meshes.viz, Tuple{GeometrySet{2, MultiPolygon{2, PolyArea{2, Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}, Ring{2, Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}, CircularArrays.CircularVector{Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}, Vector{Point{2, CoordRefSystems.Cartesian{CoordRefSystems.NoDatum, 2, Unitful.Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}}}}}}}}}}

Is there any additional issue regarding Observable @oscarvdvelde ?