How to create a valid `FeatureCollection` I can interface with `GeoJSON`?

using GeoJSON

EPS = 5
MAD_BOUNDS = (40.2257307, 40.6072783, -3.9536568, -3.4525022)
grid = Dict("Lat" => range(MAD_BOUNDS[1], MAD_BOUNDS[2], EPS),
            "Lng" => range(MAD_BOUNDS[3], MAD_BOUNDS[4], EPS),
            "Eps" => EPS)

fc = Dict("type" => "FeatureCollection",
          "features" => [],
          "properties" => Dict{String, Any}())

tile_features = [Dict("type" => "Feature",
                      "properties" => Dict{String, Any}(),
                      "geometry" => Dict("type" => "Polygon",
                                         "coordinates" => [
                                            [
                                                [grid["Lng"][i], grid["Lat"][j]],
                                                [grid["Lng"][i+1], grid["Lat"][j+1]],
                                            ]
                                         ])
                      )
                 for i in 1:grid["Eps"]-1, j in 1:grid["Eps"]-1]

fc["features"] = tile_features

GeoJSON.parseFeature(fc["features"][1]) # works
geo_data = GeoJSON.parseFeatureCollection(fc)

Last line throws a MethodError on FeatureCollection(::Matrix{Feature})
I think it’s getting hung up on type of the coordinates
Any clues?

Well, it turns out I had a couple of mistakes. First and most importantly I wasn’t really defining a closed form polygon (make sure to follow the right-hand rule, most usually)


tile_features = [Dict("type" => "Feature",
                      "properties" => Dict{String, Any}(),
                      "geometry" => Dict("type" => "Polygon",
                                         "coordinates" => [
                                            [
                                                [grid["Lng"][i], grid["Lat"][j]],
                                                [grid["Lng"][i], grid["Lat"][j+1]],
                                                [grid["Lng"][i+1], grid["Lat"][j+1]],
                                                [grid["Lng"][i+1], grid["Lat"][j]],
                                                [grid["Lng"][i], grid["Lat"][j]]
                                            ]
                                         ])
                      )
                 for i in 1:grid["Eps"]-1, j in 1:grid["Eps"]-1]

And then I was able to turn it into a FeatureCollection object more properly by first

open("mad_grid.geojson", "w") do io
    JSON3.pretty(io, fc)
end

And reading it back on memory

jsonbytes = read("mad_grid.geojson")
fc = GeoJSON.read(jsonbytes)

Seems like a roundabout way of doing things, so won’t mark as a solution just in case someone has a more direct way of achieving this :smile:

What version of GeoJSON.jl are you using?

Hi Raf, I’m using v0.5.1

Ok. Much of this syntax has changed with v0.6, with GeoInterface.jl v1.0 and using JSON3.jl underneath rather than JSON.jl.

Seems like Turf.jl is restricting to me to v0.5.1
Everything is well for now, though. Will give a shout out if not :smile:

Ok seems you might be staying there! turf is 2 years without change.

It would be good to get Turf.jl moved to JuilaGeo so it gets updated with these changes, I didn’t even know it existed.

Oh I’m not married to it, but given that I don’t really know the ecosystem I chose it because it’s 100% Julia version a JS library by the same name (might as kill two birds with one stone type of thing… if I ever need the JS version :smile: ), its listed here: https://juliageo.org/, plus I thought it might be well tested.

I just need to do some spatial queries, like getting the area of the tiles above etc… I expect my FeatureCollection to get big so the above is not very efficient. What do you suggest?