|
| 1 | +get_main_key(d) = nothing |
| 2 | +function get_main_key(d::Dict) |
| 3 | + @assert d |> keys |> length == 1 |
| 4 | + return d |> keys |> first |
| 5 | +end |
| 6 | + |
| 7 | +# From a Vector{Dict}, get Dict items that all has a particular key |
| 8 | +function get_items_with_key(key::Symbol, list::Vector) |
| 9 | + filter(x->get_main_key(x)==key, list) |
| 10 | +end |
| 11 | + |
| 12 | +wktdict_crs_type(wkt::Dict) = get_main_key(wkt) |
| 13 | + |
| 14 | +### |
| 15 | +# Construct projjson compliant Dict from From WKT2 Dict |
| 16 | +### |
| 17 | + |
| 18 | +function wktdict2jsondict(wkt::Dict) |
| 19 | + type = get_main_key(wkt) |
| 20 | + if type == :GEOGCRS |
| 21 | + return wktdict2jsondict_geog(wkt) |
| 22 | + elseif type == :GEODCRS |
| 23 | + error("Unimplemented CRS type: $type") |
| 24 | + elseif type == :PROJCRS |
| 25 | + error("Unimplemented CRS type: $type") |
| 26 | + else |
| 27 | + error("Unimplemented CRS type: $type") |
| 28 | + end |
| 29 | +end |
| 30 | + |
| 31 | +function wktdict2jsondict_geog(wkt::Dict) |
| 32 | + @assert wkt |> keys |> collect == [:GEOGCRS] |
| 33 | + jsondict = Dict{String, Any}() |
| 34 | + jsondict["type"] = "GeographicCRS" |
| 35 | + jsondict["name"] = wkt[:GEOGCRS][1] |
| 36 | + |
| 37 | + # design: bit of redundancy between the [2] and [:ENSEMBLE] inside the function |
| 38 | + jsondict["datum_ensemble"] = wktdict2jsondict_ensemble(wkt[:GEOGCRS][2]) |
| 39 | + |
| 40 | + # decision, either pass specifically the CS and AXIS arr elements or all the dict. Caveate, for later projected there is cs nested inside |
| 41 | + # jsondict["coordinate_system"] = wktdict2jsondict_cs(wkt) |
| 42 | + |
| 43 | + jsondict["id"] = wktdict2jsondict_id(wkt[:GEOGCRS][end]) |
| 44 | + # return Dict(:root => jsondict) |
| 45 | + return jsondict |
| 46 | +end |
| 47 | + |
| 48 | +function wktdict2jsondict_ellipsoid(wkt::Dict) |
| 49 | + @assert wkt |> keys |> collect == [:ELLIPSOID] |
| 50 | + jsondict = Dict() |
| 51 | + jsondict["ellipsoid"] = Dict() |
| 52 | + jsondict["ellipsoid"]["name"] = wkt[:ELLIPSOID][1] |
| 53 | + jsondict["ellipsoid"]["semi_major_axis"] = wkt[:ELLIPSOID][2] |
| 54 | + jsondict["ellipsoid"]["inverse_flattening"] = wkt[:ELLIPSOID][3] |
| 55 | + return jsondict |
| 56 | +end |
| 57 | + |
| 58 | +function wktdict2jsondict_id(id_dict::Dict)::Dict |
| 59 | + @assert id_dict |> keys |> collect == [:ID] |
| 60 | + jsondict = Dict{String, Any}() # "list" of key value pairs |
| 61 | + jsondict["authority"] = id_dict[:ID][1] |
| 62 | + jsondict["code"] = id_dict[:ID][2] |
| 63 | + return jsondict |
| 64 | +end |
| 65 | + |
| 66 | +function wktdict2jsondict_ensemble(wkt::Dict) |
| 67 | + @assert wkt |> keys |> collect == [:ENSEMBLE] |
| 68 | + jsondict = Dict{String, Any}() |
| 69 | + jsondict["name"] = wkt[:ENSEMBLE][1] |
| 70 | + |
| 71 | + members = get_items_with_key(:MEMBER, wkt[:ENSEMBLE]) |
| 72 | + jsondict["members"] = [] |
| 73 | + for m in members |
| 74 | + mdict = Dict{String, Any}() |
| 75 | + mdict["name"] = m[:MEMBER][1] |
| 76 | + mdict["id"] = wktdict2jsondict_id(m[:MEMBER][2]) |
| 77 | + push!(jsondict["members"], mdict) |
| 78 | + end |
| 79 | + |
| 80 | + jsondict["id"] = wktdict2jsondict_id(wkt[:ENSEMBLE][end]) |
| 81 | + |
| 82 | + return jsondict |
| 83 | +end |
| 84 | + |
| 85 | + |
| 86 | +### |
| 87 | +# From WKT2 string to Julia Dict conversion |
| 88 | +### |
| 89 | + |
| 90 | +function epsg2wktdict(epsg::Int)::Dict |
| 91 | + str = CoordRefSystems.wkt2(EPSG{epsg}) |
| 92 | + expr = Meta.parse(str) |
| 93 | + dict = expr2dict(expr) |
| 94 | +end |
| 95 | +epsg2wktdict(::Type{EPSG{I}}) where I = epsg2wktdict(I) |
| 96 | + |
| 97 | +function expr2dict(e::Expr) |
| 98 | + p = Dict(:root => []) |
| 99 | + process_expr(e, p) |
| 100 | + return p[:root][1] |
| 101 | +end |
| 102 | + |
| 103 | +function process_expr(elem, dict::Dict) |
| 104 | + k = dict |> keys |> collect |> first |
| 105 | + if elem isa Expr |
| 106 | + expr_name = elem.args[1] |
| 107 | + child_dict = Dict(expr_name => []) |
| 108 | + push!(dict[k], child_dict) |
| 109 | + # dict[k] = child_dict |
| 110 | + for child_elem in elem.args[2:end] |
| 111 | + process_expr(child_elem, child_dict) |
| 112 | + end |
| 113 | + elseif elem isa Union{String, Number, Symbol} |
| 114 | + push!(dict[k], elem) |
| 115 | + else |
| 116 | + @error "Unhandled case" |
| 117 | + end |
| 118 | + return dict |
| 119 | +end |
0 commit comments