From 49fa679d9a5a0318413f9614f05cfcb454f5faad Mon Sep 17 00:00:00 2001 From: qwjyh Date: Sun, 7 Jan 2024 18:28:38 +0900 Subject: [PATCH] interactive edits --- src/CoordVisualize.jl | 4 ++- src/edit.jl | 33 +++++++++++++++-- src/interactive_edit.jl | 79 +++++++++++++++++++++++++++++++++++------ src/print.jl | 9 ++++- src/recipes.jl | 15 +++++++- src/typedef.jl | 4 +++ 6 files changed, 127 insertions(+), 17 deletions(-) diff --git a/src/CoordVisualize.jl b/src/CoordVisualize.jl index e848564..5726392 100644 --- a/src/CoordVisualize.jl +++ b/src/CoordVisualize.jl @@ -3,7 +3,9 @@ module CoordVisualize using Dates export CoordLog -export interactive_edit_log +export iedit_log +export isplit_log!, iedit_note!, ijoin_logs! +export export_log export ColorMapFuncs include("typedef.jl") diff --git a/src/edit.jl b/src/edit.jl index 3458d34..7a432dd 100644 --- a/src/edit.jl +++ b/src/edit.jl @@ -3,7 +3,12 @@ Split `log` at `at`, i.e. to `1:at` and `(at + 1):end` then assign `notes_1` and `notes_2` to notes for each other. """ -function split_log(log::CoordLog, at::Unsigned, notes_1::AbstractString, notes_2::AbstractString)::Tuple{CoordLog, CoordLog} +function split_log( + log::CoordLog, + at::Unsigned, + notes_1::AbstractString, + notes_2::AbstractString, +)::Tuple{CoordLog, CoordLog} @assert at < size(log.coords)[1] "Split index must be less than original log length($(size(log.coords)[1]))" ( CoordLog(log.coords[1:at, :], log.logdate, notes_1), @@ -11,11 +16,15 @@ function split_log(log::CoordLog, at::Unsigned, notes_1::AbstractString, notes_2 ) end -function split_log(log::CoordLog, at::Integer, notes_1::AbstractString, notes_2::AbstractString)::Tuple{CoordLog, CoordLog} +function split_log( + log::CoordLog, + at::Integer, + notes_1::AbstractString, + notes_2::AbstractString, +)::Tuple{CoordLog, CoordLog} split_log(log, UInt(at), notes_1, notes_2) end - """ assign_note!(log::CoordLog, new_note::AbstractString) @@ -24,3 +33,21 @@ Replace `note` in `log` with `new_note`. function assign_note!(log::CoordLog, new_note::AbstractString) log.note = new_note end + +""" + join_log( + log1::CoordLog{T}, + log2::CoordLog{T}, + note::AbstractString, + )::CoordLog{T} where {T} + +Join two logs. +""" +function join_log( + log1::CoordLog{T}, + log2::CoordLog{T}, + note::AbstractString, +)::CoordLog{T} where {T} + newdate = min(log1.logdate, log2.logdate) + CoordLog(vcat(log1.coords, log2.coords), newdate, note) +end diff --git a/src/interactive_edit.jl b/src/interactive_edit.jl index 1277c44..298a8f8 100644 --- a/src/interactive_edit.jl +++ b/src/interactive_edit.jl @@ -2,7 +2,7 @@ using Statistics using Dates using Printf -function interactive_edit_log(filenames...; writetofile = true) +function iedit_log(filenames...; writetofile = true) printstyled(stdout, "[CoordLog Editor] \n", color = :blue, bold = true) logs = CoordLog[] printstyled(stdout, "loading log files\n", color = :blue) @@ -10,7 +10,7 @@ function interactive_edit_log(filenames...; writetofile = true) append!(logs, parse_log(file)) end printstyled(stdout, "all files loaded\n", color = :blue) - edited_logs = CoordLog[] + edited_logs = CoordLog{Float64}[] for (i, log) in enumerate(logs) printstyled(stdout, "LogEdit: editing log $(i) / $(length(logs))\n", color = :blue) printstyled(stdout, "summary\n", color = :cyan) @@ -60,14 +60,16 @@ function interactive_edit_log(filenames...; writetofile = true) note_1 = readline(stdin) new_log, log = split_log(log, at, note_1, "") push!(edited_logs, new_log) - print(""" - summary of the remaining log: - mean : $(mean(eachrow(log.coords)) .|> round |> Tuple) - start : $(log.coords[1, :] .|> round |> Tuple) - end : $(log.coords[end, :] .|> round |> Tuple) - datetime : $(Dates.format(log.logdate, DateFormat("yyyy-mm-dd HH:MM:SS"))) - number of coords: $(size(log.coords)[1]) - """) + print( + """ + summary of the remaining log: + mean : $(mean(eachrow(log.coords)) .|> round |> Tuple) + start : $(log.coords[1, :] .|> round |> Tuple) + end : $(log.coords[end, :] .|> round |> Tuple) + datetime : $(Dates.format(log.logdate, DateFormat("yyyy-mm-dd HH:MM:SS"))) + number of coords: $(size(log.coords)[1]) + """, + ) @goto ask end elseif ans == "n" || ans == "N" || ans == "" @@ -98,7 +100,10 @@ function interactive_edit_log(filenames...; writetofile = true) ans = readline() if ans == "y" || ans == "Y" elseif ans == "n" || ans == "N" || ans == "" - printstyled("Skip exporting to a file. Please export the returned log manually.\n", color = :magenta) + printstyled( + "Skip exporting to a file. Please export the returned log manually.\n", + color = :magenta, + ) @goto finish end end @@ -112,3 +117,55 @@ function interactive_edit_log(filenames...; writetofile = true) printstyled("Edit completed.\n", color = :blue, bold = true) return edited_logs end + +function isplit_log!( + logs::AbstractVector{CoordLog{T}}, + logid::Integer, + pointid::Integer, +) where {T} + 1 ≤ logid ≤ length(logs) || + throw(ArgumentError("logid out of index: ¬ 1 ≤ $(logid) ≤ $(length(logid))")) + if !(1 < pointid < n_coords(logs[logid])) + throw( + ArgumentError( + "pointid($(pointid)) out of index: min=2, max=$(n_coords(logs[logid]) - 1)", + ), + ) + end + + log = popat!(logs, logid) + printstyled("note for the first log: ", color = :green, italic = true) + note_1 = readline() + printstyled("note for the second log: ", color = :green, italic = true) + note_2 = readline() + new_logs = split_log(log, pointid, note_1, note_2) + insert!(logs, logid, new_logs[1]) + insert!(logs, logid + 1, new_logs[2]) +end + +function iedit_note!(logs::AbstractVector{CoordLog{T}}, logid::Integer) where {T} + 1 ≤ logid ≤ length(logs) || + throw(ArgumentError("logid out of index: ¬ 1 ≤ $(logid) ≤ $(length(logid))")) + printstyled("new note for the log: ", color = :green, italic = true) + note = readline() + logs[logid].note = note +end + +function ijoin_logs!(logs::AbstractVector{CoordLog{T}}, logid1::Integer, logid2::Integer) where {T} + 1 ≤ logid1 ≤ length(logs) || + throw(ArgumentError("logid1 out of index: ¬ 1 ≤ $(logid1) ≤ $(length(logid1))")) + 1 ≤ logid2 ≤ length(logs) || + throw(ArgumentError("logid2 out of index: ¬ 1 ≤ $(logid2) ≤ $(length(logid2))")) + logid1 == logid2 && throw(ArgumentError("logid1 and logid2 cannot be the same")) + if logid1 > logid2 + logid1, logid2 = logid2, logid1 + end + + log_1 = popat!(logs, logid1) + log_2 = popat!(logs, logid2 - 1) + + printstyled("note for the new log: ", color = :green, italic = true) + note = readline() + log = join_log(log_1, log_2, note) + insert!(logs, logid1, log) +end diff --git a/src/print.jl b/src/print.jl index f10c038..035f76c 100644 --- a/src/print.jl +++ b/src/print.jl @@ -11,13 +11,20 @@ function export_log(log::CoordLog) )""" end -function export_log(logs::Vector{CoordLog}) +function export_log(logs::Vector{CoordLog{T}}) where {T} logs .|> export_log |> (vs -> join(vs, ",\n")) |> (s -> "[\n" * s * "\n]") end +function export_log(logs::Vector{CoordLog{T}}, filename::AbstractString) where {T} + open(filename, "w") do f + println(f, "using Dates") + println(f, export_log(logs)) + end +end + """ export_log(io::IO, log) """ diff --git a/src/recipes.jl b/src/recipes.jl index b18f1ea..813c30c 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -142,6 +142,7 @@ function Makie.plot!(tr2d::Trace2Ds) linesegs = Observable(Point2f[]) points = Observable(Point2f[]) altitudes = Observable(Float64[]) + point_ids = Observable(Tuple{Int64, Int64}[]) notes = Observable(String[]) if tr2d.markercolormap[] isa Symbol tr2d.markercolormap[] = getproperty(ColorSchemes, tr2d.markercolormap[]) @@ -174,6 +175,7 @@ function Makie.plot!(tr2d::Trace2Ds) empty!(linesegs[]) empty!(points[]) empty!(altitudes[]) + empty!(point_ids[]) empty!(markercolors[]) if linecolors[] isa AbstractVector empty!(linecolors[]) @@ -187,11 +189,12 @@ function Makie.plot!(tr2d::Trace2Ds) mcolors, mticks[] = mcolormapfunc(mcolormap, logs, tr2d.nmcolorticks[]) for (i, log) in enumerate(logs) first = true - for point in eachrow(log.coords) + for (j, point) in enumerate(eachrow(log.coords)) push!(linesegs[], Point2f(point[1], point[3])) push!(linesegs[], Point2f(point[1], point[3])) push!(points[], Point2f(point[1], point[3])) push!(altitudes[], point[2]) + push!(point_ids[], (i, j)) push!(linecolors[], lcolors[colors_count]) push!(linecolors[], lcolors[colors_count]) push!(markercolors[], mcolors[colors_count]) @@ -256,6 +259,16 @@ function Makie.plot!(tr2d::Trace2Ds) markersize = tr2d.markersize, strokewidth = tr2d.strokewidth, visible = tr2d.showmarker, + inspector_label = (self, i, pos) -> begin + logid, pointid = point_ids[][i] + """ + log: $(logid), point: $(pointid) + x: $(lpad(round(pos[1], digits = 1), 7)) + y: $(lpad(round(altitudes[][i], digits = 1), 7)) + z: $(lpad(round(pos[2], digits = 1), 7)) + $(tr2d.log[][logid].note) + """ + end, ) # @info "dump" dump(tr2d, maxdepth = 1) # @info "attributes" dump(tr2d.attributes, maxdepth = 3) diff --git a/src/typedef.jl b/src/typedef.jl index 20ce80c..8ee6182 100644 --- a/src/typedef.jl +++ b/src/typedef.jl @@ -21,3 +21,7 @@ end Base.:(==)(x::CoordLog, y::CoordLog) = begin x.note == y.note && x.logdate == y.logdate && x.coords == y.coords end + +function Base.getindex(log::CoordLog{T}, i) where {T} + log.coords[i, :] +end