Compare commits
No commits in common. "efc37be0879d7892d691dabe60d7f13756edb627" and "39b5a334c7695a912189b57c8b49debd15e1080e" have entirely different histories.
efc37be087
...
39b5a334c7
18 changed files with 7 additions and 993 deletions
|
@ -1,13 +0,0 @@
|
||||||
# See https://domluna.github.io/JuliaFormatter.jl/stable/ for a list of options
|
|
||||||
whitespace_ops_in_indices = true
|
|
||||||
remove_extra_newlines = true
|
|
||||||
always_for_in = true
|
|
||||||
whitespace_typedefs = true
|
|
||||||
normalize_line_endings = "unix"
|
|
||||||
# format_docstrings = true
|
|
||||||
# format_markdown = true
|
|
||||||
align_assignment = true
|
|
||||||
align_struct_field = true
|
|
||||||
align_conditional = true
|
|
||||||
align_pair_arrow = true
|
|
||||||
align_matrix = true
|
|
|
@ -1,19 +1,12 @@
|
||||||
name = "CoordVisualize"
|
name = "CoordVisualize"
|
||||||
uuid = "4c41ebcf-33aa-4478-9aac-83d12758d145"
|
uuid = "4c41ebcf-33aa-4478-9aac-83d12758d145"
|
||||||
authors = ["qwjyh <urataw421@gmail.com>"]
|
authors = ["qwjyh <urataw421@gmail.com>"]
|
||||||
version = "1.0.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
|
ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
|
||||||
ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
|
|
||||||
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||||||
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
|
|
||||||
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
|
|
||||||
GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
|
GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"
|
||||||
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
|
|
||||||
MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b"
|
|
||||||
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
|
||||||
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
|
|
||||||
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
|
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
|
||||||
|
|
||||||
[extras]
|
[extras]
|
||||||
|
|
18
README.adoc
18
README.adoc
|
@ -13,24 +13,8 @@
|
||||||
* Visualize with GLMakie (or CairoMakie)
|
* Visualize with GLMakie (or CairoMakie)
|
||||||
** Inspecting with GUI
|
** Inspecting with GUI
|
||||||
|
|
||||||
== Docs
|
|
||||||
Clone this repo, and
|
|
||||||
```sh
|
|
||||||
$ cd docs
|
|
||||||
|
|
||||||
$ julia --project -e 'using Pkg; Pkg.instantiate()'
|
|
||||||
|
|
||||||
$ julia --project make.jl
|
|
||||||
|
|
||||||
$ cd build
|
|
||||||
|
|
||||||
$ python -m http.server --bind localhost
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
== TODO
|
== TODO
|
||||||
- [x] Printing
|
- [ ] Printing
|
||||||
- [ ] visualize
|
- [ ] visualize
|
||||||
- [ ] interactive edit
|
|
||||||
- [ ] doc
|
- [ ] doc
|
||||||
|
|
||||||
|
|
2
docs/.gitignore
vendored
2
docs/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
build/
|
|
||||||
site/
|
|
|
@ -1,3 +0,0 @@
|
||||||
[deps]
|
|
||||||
CoordVisualize = "4c41ebcf-33aa-4478-9aac-83d12758d145"
|
|
||||||
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
|
|
19
docs/make.jl
19
docs/make.jl
|
@ -1,19 +0,0 @@
|
||||||
using Documenter
|
|
||||||
using CoordVisualize
|
|
||||||
|
|
||||||
makedocs(
|
|
||||||
sitename = "CoordVisualize",
|
|
||||||
format = Documenter.HTML(),
|
|
||||||
modules = [CoordVisualize],
|
|
||||||
pages = [
|
|
||||||
"Top" => "index.md",
|
|
||||||
"API list" => "apis.md"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Documenter can also automatically deploy documentation to gh-pages.
|
|
||||||
# See "Hosting Documentation" and deploydocs() in the Documenter manual
|
|
||||||
# for more information.
|
|
||||||
#=deploydocs(
|
|
||||||
repo = "<repository url>"
|
|
||||||
)=#
|
|
|
@ -1,14 +0,0 @@
|
||||||
# API list
|
|
||||||
|
|
||||||
```@index
|
|
||||||
```
|
|
||||||
|
|
||||||
```@autodocs
|
|
||||||
Modules = [CoordVisualize]
|
|
||||||
```
|
|
||||||
|
|
||||||
# ColorMapFuncs
|
|
||||||
|
|
||||||
```@autodocs
|
|
||||||
Modules = [CoordVisualize.ColorMapFuncs]
|
|
||||||
```
|
|
|
@ -1,95 +0,0 @@
|
||||||
```@meta
|
|
||||||
CurrentModule = CoordVisualize
|
|
||||||
```
|
|
||||||
|
|
||||||
# CoordVisualize.jl
|
|
||||||
|
|
||||||
Documentation for CoordVisualize.jl
|
|
||||||
|
|
||||||
## Tutorial
|
|
||||||
Readers are expected to be familiar with basics of julia.
|
|
||||||
|
|
||||||
### Preparing
|
|
||||||
This will take a few minutes.
|
|
||||||
|
|
||||||
```julia-repl
|
|
||||||
julia> # type ]
|
|
||||||
|
|
||||||
(@v1.10) Pkg> activate .
|
|
||||||
|
|
||||||
(CoordVisualize) Pkg> instantiate
|
|
||||||
```
|
|
||||||
|
|
||||||
### Parse log
|
|
||||||
```julia-repl
|
|
||||||
julia> using CoordVisualize
|
|
||||||
|
|
||||||
julia> iedit_log("coord_log_1.txt", "coord_log_2.txt")
|
|
||||||
...
|
|
||||||
Follow the instruction
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Visualize the log
|
|
||||||
Get map image file and place it as "map.png" beforehand.
|
|
||||||
|
|
||||||
```julia-repl
|
|
||||||
julia> using GLMakie, CoordVisualize
|
|
||||||
|
|
||||||
julia> tlog = Observable(include("<exported log file>"))
|
|
||||||
...
|
|
||||||
|
|
||||||
julia> # or
|
|
||||||
|
|
||||||
julia> tlog = Observable(interactive_edit_log("log files", "log file2"))
|
|
||||||
...
|
|
||||||
|
|
||||||
julia> include("<path to root>/interactive_viz.jl")
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
Available colorschemes at https://juliagraphics.github.io/ColorSchemes.jl/stable/catalogue/ .
|
|
||||||
Available colors at https://juliagraphics.github.io/Colors.jl/stable/constructionandconversion/#Color-Parsing and https://juliagraphics.github.io/Colors.jl/stable/namedcolors/ .
|
|
||||||
|
|
||||||
### Edit the log
|
|
||||||
```julia-repl
|
|
||||||
julia> isplit_log!(tlog[], 3, 30)
|
|
||||||
... <with some prompts>
|
|
||||||
|
|
||||||
julia> iedit_note!(tlog[], 3)
|
|
||||||
... <with some promots>
|
|
||||||
|
|
||||||
julia> ijoin_logs!(tlog[], 5, 7)
|
|
||||||
... <with some prompts>
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### Export the log
|
|
||||||
```julia-repl
|
|
||||||
julia> export_log(tlog[], "<filename>")
|
|
||||||
```
|
|
||||||
|
|
||||||
## Low level
|
|
||||||
|
|
||||||
### Log structure
|
|
||||||
CoordVisualize.jl treats coordination trace log with some additional information,
|
|
||||||
datetime when log was taken and supplemental note to annotate the log.
|
|
||||||
This set of log is represented by the type [`CoordLog`](@ref).
|
|
||||||
|
|
||||||
### Parsing Log
|
|
||||||
Use [`parse_log`](@ref) to parse log files generated with Tracecoords CSM mod.
|
|
||||||
Set the keyword argument `interactive` to `true` to supply notes interactively.
|
|
||||||
It automatically get datetime.
|
|
||||||
Notes can be also supplied in the following section.
|
|
||||||
|
|
||||||
### Editing
|
|
||||||
You sometimes want to split logs and to give more appropriate notes for each of them.
|
|
||||||
You can do this with [`split_log`](@ref) function.
|
|
||||||
|
|
||||||
You can also edit existing notes with [`assign_note!`](@ref).
|
|
||||||
|
|
||||||
### Exporting
|
|
||||||
Use [`export_log`](@ref) to export log to `io` or `file`.
|
|
||||||
|
|
||||||
### Importing
|
|
||||||
Do `using Dates` first and just `include("filename")` and it will return `Vector{CoordLog}`.
|
|
|
@ -1,205 +0,0 @@
|
||||||
true || include("src/CoordVisualize.jl")
|
|
||||||
true || using GLMakie
|
|
||||||
using CoordVisualize
|
|
||||||
using FileIO
|
|
||||||
using ColorSchemes
|
|
||||||
using ColorTypes
|
|
||||||
|
|
||||||
mappath = "map.png"
|
|
||||||
map = load(mappath)
|
|
||||||
map_height, map_width = size(map)
|
|
||||||
|
|
||||||
fig = Figure(; size = (1000, 700))
|
|
||||||
ax = Axis(
|
|
||||||
fig[1:2, 1],
|
|
||||||
limits = (
|
|
||||||
-map_width ÷ 2 * 1.1,
|
|
||||||
map_width ÷ 2 * 1.1,
|
|
||||||
-map_height ÷ 2 * 1.1,
|
|
||||||
map_height ÷ 2 * 1.1,
|
|
||||||
),
|
|
||||||
aspect = DataAspect(),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Options
|
|
||||||
options_width = 200
|
|
||||||
button_reset = Button(fig, label = "reset view")
|
|
||||||
toggle_inspector = Toggle(fig, active = false, tellwidth = false)
|
|
||||||
menu_lcolormapfunc =
|
|
||||||
Menu(fig, options = ["log", "altitude", "date", "constant"], default = "log")
|
|
||||||
menu_mcolormapfunc =
|
|
||||||
Menu(fig, options = ["log", "altitude", "date", "constant"], default = "log")
|
|
||||||
toggle_line = Toggle(fig, active = true, tellwidth = false)
|
|
||||||
toggle_marker = Toggle(fig, active = false, tellwidth = false)
|
|
||||||
slider_linewidth = Slider(fig, range = unique([1:1:5..., 5:2:15..., 15, 20:10:100...]))
|
|
||||||
slider_markersize = Slider(fig, range = unique([1:1:10..., 10:5:100...]), startvalue = 5)
|
|
||||||
# menu_linecolormap =
|
|
||||||
# Menu(fig, options = string.(keys(ColorSchemes.colorschemes)), default = "viridis")
|
|
||||||
# menu_markercolormap =
|
|
||||||
# Menu(fig, options = string.(keys(ColorSchemes.colorschemes)), default = "viridis")
|
|
||||||
textbox_linecolormap =
|
|
||||||
Textbox(fig, validator = (s -> s in string.(keys(ColorSchemes.colorschemes))))
|
|
||||||
textbox_markercolormap =
|
|
||||||
Textbox(fig, validator = (s -> s in string.(keys(ColorSchemes.colorschemes))))
|
|
||||||
textbox_linecolor = Textbox(fig, validator = (s -> begin
|
|
||||||
try
|
|
||||||
parse(Colorant, s)
|
|
||||||
catch
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end), stored_string = "green")
|
|
||||||
lineconstcolor =
|
|
||||||
@lift(ColorMapFuncs.Constant(parse(Colorant, $(textbox_linecolor.stored_string))))
|
|
||||||
textbox_markercolor = Textbox(fig, validator = (s -> begin
|
|
||||||
try
|
|
||||||
parse(Colorant, s)
|
|
||||||
catch
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end), stored_string = "green")
|
|
||||||
markerconstcolor =
|
|
||||||
@lift(ColorMapFuncs.Constant(parse(Colorant, $(textbox_markercolor.stored_string))))
|
|
||||||
line_options = grid!(
|
|
||||||
[1, 1] => Label(fig, "color"),
|
|
||||||
[1, 2:3] => menu_lcolormapfunc,
|
|
||||||
[2, 1] => Label(fig, "show line"),
|
|
||||||
[2, 2:3] => toggle_line,
|
|
||||||
[3, 1] => Label(fig, "width"),
|
|
||||||
[3, 2] => slider_linewidth,
|
|
||||||
[3, 3] => Label(fig, @lift(string($(slider_linewidth.value)))),
|
|
||||||
[4, 1] => Label(fig, "color scheme"),
|
|
||||||
[4, 2:3] => textbox_linecolormap,
|
|
||||||
[5, 1] => Label(fig, "color"),
|
|
||||||
[5, 2:3] => textbox_linecolor,
|
|
||||||
width = options_width,
|
|
||||||
)
|
|
||||||
marker_options = grid!(
|
|
||||||
[1, 1] => Label(fig, "color"),
|
|
||||||
[1, 2:3] => menu_mcolormapfunc,
|
|
||||||
[2, 1] => Label(fig, "show marker"),
|
|
||||||
[2, 2:3] => toggle_marker,
|
|
||||||
[3, 1] => Label(fig, "size"),
|
|
||||||
[3, 2] => slider_markersize,
|
|
||||||
[3, 3] => Label(fig, @lift(string($(slider_markersize.value)))),
|
|
||||||
[4, 1] => Label(fig, "color scheme"),
|
|
||||||
[4, 2:3] => textbox_markercolormap,
|
|
||||||
[5, 1] => Label(fig, "color"),
|
|
||||||
[5, 2:3] => textbox_markercolor,
|
|
||||||
width = options_width,
|
|
||||||
)
|
|
||||||
inspector_options = grid!(
|
|
||||||
[1, 1] => Label(fig, "inspector"),
|
|
||||||
[1, 2] => toggle_inspector,
|
|
||||||
width = options_width,
|
|
||||||
)
|
|
||||||
fig[1:2, 3] = grid!(
|
|
||||||
[0, :] => Label(fig, "Line", font = :bold),
|
|
||||||
[1, :] => line_options,
|
|
||||||
[2, :] => Label(fig, "Marker", font = :bold),
|
|
||||||
[3, :] => marker_options,
|
|
||||||
[4, :] => Label(fig, "Axis", font = :bold),
|
|
||||||
[5, :] => inspector_options,
|
|
||||||
[6, :] => button_reset,
|
|
||||||
tellheight = false,
|
|
||||||
width = options_width,
|
|
||||||
)
|
|
||||||
|
|
||||||
# tlog = vcat(CoordVisualize.parse_log.(["coord_log_5.txt", "coord_log_6.txt"])...)
|
|
||||||
|
|
||||||
# Main
|
|
||||||
heatmap!(
|
|
||||||
ax,
|
|
||||||
(1:map_width) .- map_width ÷ 2 .- 1,
|
|
||||||
(1:map_height) .- map_height ÷ 2 .- 1,
|
|
||||||
rotr90(map),
|
|
||||||
inspectable = false,
|
|
||||||
)
|
|
||||||
|
|
||||||
tr2d = CoordVisualize.trace2ds!(
|
|
||||||
ax,
|
|
||||||
tlog,
|
|
||||||
linewidth = slider_linewidth.value,
|
|
||||||
markersize = slider_markersize.value,
|
|
||||||
)
|
|
||||||
|
|
||||||
# legend
|
|
||||||
cbl = Colorbar(
|
|
||||||
fig,
|
|
||||||
colormap = tr2d.linecolormap,
|
|
||||||
ticks = tr2d.lcolorticks,
|
|
||||||
# ticklabelrotation = π / 2,
|
|
||||||
ticklabelsize = 10,
|
|
||||||
label = menu_lcolormapfunc.selection,
|
|
||||||
# vertical = false,
|
|
||||||
# flipaxis = false,
|
|
||||||
)
|
|
||||||
cbm = Colorbar(
|
|
||||||
fig,
|
|
||||||
colormap = tr2d.markercolormap,
|
|
||||||
ticks = tr2d.mcolorticks,
|
|
||||||
# ticklabelrotation = π / 2,
|
|
||||||
ticklabelsize = 10,
|
|
||||||
label = menu_mcolormapfunc.selection,
|
|
||||||
)
|
|
||||||
fig[1:2, 2] = grid!(
|
|
||||||
[0, 1] => Label(fig, "line", font = :bold),
|
|
||||||
[1, 1] => cbl,
|
|
||||||
[2, 1] => Label(fig, "marker", font = :bold),
|
|
||||||
[3, 1] => cbm,
|
|
||||||
tellheight = true,
|
|
||||||
)
|
|
||||||
|
|
||||||
inspector = DataInspector(tr2d)
|
|
||||||
inspector.attributes.enabled[] = false
|
|
||||||
|
|
||||||
on(menu_lcolormapfunc.selection) do s
|
|
||||||
if s == "log"
|
|
||||||
tr2d.lcolormapfunc[] = ColorMapFuncs.ColorMap()
|
|
||||||
elseif s == "altitude"
|
|
||||||
tr2d.lcolormapfunc[] = ColorMapFuncs.Altitude()
|
|
||||||
elseif s == "date"
|
|
||||||
tr2d.lcolormapfunc[] = ColorMapFuncs.Date()
|
|
||||||
elseif s == "constant"
|
|
||||||
tr2d.lcolormapfunc[] = lineconstcolor[]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
on(lineconstcolor) do c
|
|
||||||
tr2d.lcolormapfunc[] = c
|
|
||||||
end
|
|
||||||
on(menu_mcolormapfunc.selection) do s
|
|
||||||
if s == "log"
|
|
||||||
tr2d.mcolormapfunc[] = ColorMapFuncs.ColorMap()
|
|
||||||
elseif s == "altitude"
|
|
||||||
tr2d.mcolormapfunc[] = ColorMapFuncs.Altitude()
|
|
||||||
elseif s == "date"
|
|
||||||
tr2d.mcolormapfunc[] = ColorMapFuncs.Date()
|
|
||||||
elseif s == "constant"
|
|
||||||
tr2d.mcolormapfunc[] = markerconstcolor[]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
on(markerconstcolor) do c
|
|
||||||
tr2d.mcolormapfunc[] = c
|
|
||||||
end
|
|
||||||
on(button_reset.clicks) do n
|
|
||||||
reset_limits!(ax)
|
|
||||||
# slider_markersize.value[] = 5
|
|
||||||
# slider_linewidth.value[] = 1
|
|
||||||
# toggle_line.active[] = true
|
|
||||||
# toggle_marker.active[] = false
|
|
||||||
end
|
|
||||||
on(textbox_linecolormap.stored_string) do s
|
|
||||||
tr2d.linecolormap[] = ColorSchemes.colorschemes[Symbol(s)]
|
|
||||||
end
|
|
||||||
on(textbox_markercolormap.stored_string) do s
|
|
||||||
tr2d.markercolormap[] = ColorSchemes.colorschemes[Symbol(s)]
|
|
||||||
end
|
|
||||||
on(toggle_inspector.active) do f
|
|
||||||
inspector.attributes.enabled[] = f
|
|
||||||
end
|
|
||||||
|
|
||||||
connect!(tr2d.showline, toggle_line.active)
|
|
||||||
connect!(tr2d.showmarker, toggle_marker.active)
|
|
||||||
|
|
||||||
display(fig)
|
|
|
@ -2,18 +2,8 @@ module CoordVisualize
|
||||||
|
|
||||||
using Dates
|
using Dates
|
||||||
|
|
||||||
export CoordLog
|
|
||||||
export iedit_log
|
|
||||||
export isplit_log!, iedit_note!, ijoin_logs!
|
|
||||||
export export_log
|
|
||||||
export ColorMapFuncs
|
|
||||||
|
|
||||||
include("typedef.jl")
|
include("typedef.jl")
|
||||||
include("parser.jl")
|
include("parser.jl")
|
||||||
include("edit.jl")
|
include("edit.jl")
|
||||||
include("interactive_edit.jl")
|
|
||||||
include("print.jl")
|
|
||||||
include("recipes.jl")
|
|
||||||
include("visualize.jl")
|
|
||||||
|
|
||||||
end # module CoordVisualize
|
end # module CoordVisualize
|
||||||
|
|
33
src/edit.jl
33
src/edit.jl
|
@ -3,12 +3,7 @@
|
||||||
|
|
||||||
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.
|
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(
|
function split_log(log::CoordLog, at::Unsigned, notes_1::AbstractString, notes_2::AbstractString)::Tuple{CoordLog, CoordLog}
|
||||||
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]))"
|
@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),
|
CoordLog(log.coords[1:at, :], log.logdate, notes_1),
|
||||||
|
@ -16,15 +11,11 @@ function split_log(
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
function split_log(
|
function split_log(log::CoordLog, at::Integer, notes_1::AbstractString, notes_2::AbstractString)::Tuple{CoordLog, CoordLog}
|
||||||
log::CoordLog,
|
|
||||||
at::Integer,
|
|
||||||
notes_1::AbstractString,
|
|
||||||
notes_2::AbstractString,
|
|
||||||
)::Tuple{CoordLog, CoordLog}
|
|
||||||
split_log(log, UInt(at), notes_1, notes_2)
|
split_log(log, UInt(at), notes_1, notes_2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
assign_note!(log::CoordLog, new_note::AbstractString)
|
assign_note!(log::CoordLog, new_note::AbstractString)
|
||||||
|
|
||||||
|
@ -33,21 +24,3 @@ Replace `note` in `log` with `new_note`.
|
||||||
function assign_note!(log::CoordLog, new_note::AbstractString)
|
function assign_note!(log::CoordLog, new_note::AbstractString)
|
||||||
log.note = new_note
|
log.note = new_note
|
||||||
end
|
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
|
|
||||||
|
|
|
@ -1,193 +0,0 @@
|
||||||
using Statistics
|
|
||||||
using Dates
|
|
||||||
using Printf
|
|
||||||
|
|
||||||
"""
|
|
||||||
Interactively parse log files and edit the log.
|
|
||||||
"""
|
|
||||||
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)
|
|
||||||
for file in filenames
|
|
||||||
append!(logs, parse_log(file))
|
|
||||||
end
|
|
||||||
printstyled(stdout, "all files loaded\n", color = :blue)
|
|
||||||
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)
|
|
||||||
println(
|
|
||||||
stdout,
|
|
||||||
"""
|
|
||||||
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])
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
@label ask
|
|
||||||
printstyled(stdout, "split log?(y/N): ", color = :green, italic = true)
|
|
||||||
ans = readline(stdin)
|
|
||||||
if ans == "y" || ans == "Y"
|
|
||||||
while true
|
|
||||||
maximum = size(log.coords)[1]
|
|
||||||
printstyled(
|
|
||||||
stdout,
|
|
||||||
"split at where (1 to n, n to end), max = $(maximum): ",
|
|
||||||
color = :green,
|
|
||||||
italic = true,
|
|
||||||
)
|
|
||||||
at = try
|
|
||||||
parse(UInt64, readline(stdin))
|
|
||||||
catch
|
|
||||||
printstyled("invalid input, please type number\n", color = :red)
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
if at ≥ maximum
|
|
||||||
printstyled("too large number; max = $(maximum)\n", color = :red)
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
if at == 0
|
|
||||||
printstyled("must be larger than 0\n", color = :red)
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
print("""
|
|
||||||
summary of the first log:
|
|
||||||
mean : $(mean(eachrow(log.coords)[1:at]) .|> round |> Tuple)
|
|
||||||
start : $(log.coords[1, :] .|> round |> Tuple)
|
|
||||||
end : $(log.coords[at, :] .|> round |> Tuple)
|
|
||||||
""")
|
|
||||||
printstyled("note for the first log: ", color = :green, italic = 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])
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
@goto ask
|
|
||||||
end
|
|
||||||
elseif ans == "n" || ans == "N" || ans == ""
|
|
||||||
printstyled("note for the log: ", color = :green, italic = true)
|
|
||||||
note = readline()
|
|
||||||
assign_note!(log, note)
|
|
||||||
push!(edited_logs, log)
|
|
||||||
else
|
|
||||||
printstyled("invalid ans; type y or n\n", color = :red)
|
|
||||||
@goto ask
|
|
||||||
end
|
|
||||||
end
|
|
||||||
println()
|
|
||||||
printstyled("Finish editing\n", color = :blue, bold = true)
|
|
||||||
printstyled("number of logs: $(length(edited_logs))\n", color = :cyan)
|
|
||||||
printstyled("summary: length, note\n", color = :cyan)
|
|
||||||
len_ncoords = maximum(ndigits.(n_coords.(edited_logs)))
|
|
||||||
for log in edited_logs
|
|
||||||
println(" ", lpad(n_coords(log), len_ncoords), " ", log.note)
|
|
||||||
end
|
|
||||||
if writetofile
|
|
||||||
printstyled("Writing to file\n", color = :blue, bold = true)
|
|
||||||
printstyled("filename: ", color = :green, italic = true)
|
|
||||||
filename = readline()
|
|
||||||
if filename in readdir()
|
|
||||||
printstyled("$(filename) already exists.", color = :magenta)
|
|
||||||
printstyled("Are you sure to overwrite? (y/N)", color = :magenta, italic = 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,
|
|
||||||
)
|
|
||||||
@goto finish
|
|
||||||
end
|
|
||||||
end
|
|
||||||
open(filename, "w") do f
|
|
||||||
println(f, "using Dates")
|
|
||||||
println(f, export_log(edited_logs))
|
|
||||||
end
|
|
||||||
printstyled("Exported log to the file: $(filename)\n", color = :blue)
|
|
||||||
end
|
|
||||||
@label finish
|
|
||||||
printstyled("Edit completed.\n", color = :blue, bold = true)
|
|
||||||
return edited_logs
|
|
||||||
end
|
|
||||||
|
|
||||||
"""
|
|
||||||
isplit_log!(
|
|
||||||
logs::AbstractVector{CoordLog{T}},
|
|
||||||
logid::Integer,
|
|
||||||
pointid::Integer,
|
|
||||||
) where {T}
|
|
||||||
|
|
||||||
Split the log. Supply notes interactively.
|
|
||||||
"""
|
|
||||||
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
|
|
||||||
|
|
||||||
"""
|
|
||||||
iedit_note!(logs::AbstractVector{CoordLog{T}}, logid::Integer) where {T}
|
|
||||||
|
|
||||||
Edit the note at `logid`. Supply new note interactively.
|
|
||||||
"""
|
|
||||||
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
|
|
||||||
|
|
||||||
"""
|
|
||||||
ijoin_logs!(logs::AbstractVector{CoordLog{T}}, logid1::Integer, logid2::Integer) where {T}
|
|
||||||
|
|
||||||
Join the logs at `logid1` and `logid2`. Supply new note interactively.
|
|
||||||
"""
|
|
||||||
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
|
|
|
@ -11,10 +11,10 @@ If keyword argument `interactive` is set to `true`, prompts will be shown to
|
||||||
receive custom notes for each `CoordLog`.
|
receive custom notes for each `CoordLog`.
|
||||||
Otherwise the note is set to ""(empty string).
|
Otherwise the note is set to ""(empty string).
|
||||||
"""
|
"""
|
||||||
function parse_log(filepath::AbstractString; interactive=false)::Vector{CoordLog{Float64}}
|
function parse_log(filepath::AbstractString; interactive=false)::Vector{CoordLog}
|
||||||
istracing::Bool = false
|
istracing::Bool = false
|
||||||
coords_trace = Vector{Vector{Float64}}(undef, 0) # SVector ?
|
coords_trace = Vector{Vector{Float64}}(undef, 0) # SVector ?
|
||||||
ret = Vector{CoordLog{Float64}}()
|
ret = Vector{CoordLog}()
|
||||||
log_date = DateTime(0)
|
log_date = DateTime(0)
|
||||||
for (i, l) in enumerate(readlines(filepath))
|
for (i, l) in enumerate(readlines(filepath))
|
||||||
# skip logs not from tracecoord
|
# skip logs not from tracecoord
|
||||||
|
|
43
src/print.jl
43
src/print.jl
|
@ -1,43 +0,0 @@
|
||||||
"""
|
|
||||||
Export `log` to a file or `io::IO`.
|
|
||||||
"""
|
|
||||||
function export_log end
|
|
||||||
|
|
||||||
function export_log(log::CoordLog)
|
|
||||||
"""
|
|
||||||
CoordLog(
|
|
||||||
$(log.coords),
|
|
||||||
Dates.DateTime("$(log.logdate)"), "$(log.note)"
|
|
||||||
)"""
|
|
||||||
end
|
|
||||||
|
|
||||||
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)
|
|
||||||
"""
|
|
||||||
function export_log(io::IO, log)
|
|
||||||
write(io, export_log(log))
|
|
||||||
end
|
|
||||||
|
|
||||||
"""
|
|
||||||
export_log(file::AbstractString, log)
|
|
||||||
"""
|
|
||||||
function export_log(file::AbstractString, log)
|
|
||||||
open(file, "w") do f
|
|
||||||
export_log(f, log)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
291
src/recipes.jl
291
src/recipes.jl
|
@ -1,291 +0,0 @@
|
||||||
using GLMakie
|
|
||||||
using ColorTypes
|
|
||||||
using ColorSchemes
|
|
||||||
|
|
||||||
"""
|
|
||||||
Predefined color map functions.
|
|
||||||
Receives
|
|
||||||
- `cmap`: colormap
|
|
||||||
- `logs`: vector of `CoordLog`
|
|
||||||
- `n`: number of returning ticks
|
|
||||||
|
|
||||||
and returns tuple of
|
|
||||||
1. vector of `Colorant`
|
|
||||||
2. ticks to pass to `Colorbar`, which is a Tuple of
|
|
||||||
1. vector of tick location (0 to 1)
|
|
||||||
2. vector of tick labels (strings)
|
|
||||||
|
|
||||||
Any function (or struct) which behaves like this can be used for
|
|
||||||
`lcolormapfunc` and `mcolormapfunc` kwargs of `trace2ds`.
|
|
||||||
|
|
||||||
# Types
|
|
||||||
|
|
||||||
[`ColorMapFunc`](@ref) is a supertype of all of these.
|
|
||||||
|
|
||||||
# Interface
|
|
||||||
|
|
||||||
Define these methods for the ColorMapFunc.
|
|
||||||
|
|
||||||
(cmap, logs, n) -> Vector{Colorant}, ticks
|
|
||||||
"""
|
|
||||||
module ColorMapFuncs
|
|
||||||
|
|
||||||
using ..CoordVisualize: CoordLog, n_coords
|
|
||||||
using ColorTypes
|
|
||||||
using Dates: DateTime, DateFormat, @dateformat_str, format
|
|
||||||
using Makie: wong_colors, Scene
|
|
||||||
|
|
||||||
"""
|
|
||||||
# Methods
|
|
||||||
(f::ColorMapFunc)(cmap, logs)
|
|
||||||
|
|
||||||
Helper struct for those use vector of 0 to 1 floats.
|
|
||||||
Example functions are [`Date`](@ref) and [`Altitude`](@ref).
|
|
||||||
"""
|
|
||||||
abstract type ColorMapFunc end
|
|
||||||
|
|
||||||
function (f::ColorMapFunc)(cmap, logs, n)
|
|
||||||
steps, ticklabels = f(logs, n)
|
|
||||||
ticks = collect(LinRange(0, 1, n))
|
|
||||||
return get.(Ref(cmap), steps), (ticks, ticklabels)
|
|
||||||
end
|
|
||||||
|
|
||||||
"Use same color."
|
|
||||||
struct Constant <: ColorMapFunc
|
|
||||||
color::Colorant
|
|
||||||
end
|
|
||||||
|
|
||||||
Constant(c::Symbol) = Constant(parse(Colorant, c))
|
|
||||||
|
|
||||||
function (c::Constant)(map, logs, n)
|
|
||||||
# Iterators.repeated(c.color, length(logs))
|
|
||||||
fill(c.color, sum(n_coords, logs)), ([], [])
|
|
||||||
end
|
|
||||||
|
|
||||||
"Use colormap."
|
|
||||||
struct ColorMap <: ColorMapFunc
|
|
||||||
colormap::AbstractVector{<:Colorant}
|
|
||||||
end
|
|
||||||
|
|
||||||
ColorMap() = ColorMap(wong_colors())
|
|
||||||
ColorMap(cmap::Vector{Symbol}) = ColorMap(map(cmap) do s
|
|
||||||
parse(Colorant, s)
|
|
||||||
end)
|
|
||||||
function ColorMap(scene::Scene)
|
|
||||||
ColorMap(theme(scene, :linecolor))
|
|
||||||
end
|
|
||||||
|
|
||||||
function (cm::ColorMap)(map, logs, n)
|
|
||||||
cm = Iterators.cycle(cm.colormap)
|
|
||||||
nlog_s = Iterators.map(n_coords, logs)
|
|
||||||
colors =
|
|
||||||
Iterators.map(zip(cm, nlog_s)) do (color, count)
|
|
||||||
Iterators.repeated(color, count)
|
|
||||||
end |> Iterators.flatten |> collect
|
|
||||||
return colors, ([], [])
|
|
||||||
end
|
|
||||||
|
|
||||||
"Color depending on log date."
|
|
||||||
struct Date <: ColorMapFunc end
|
|
||||||
|
|
||||||
function (::Date)(logs::AbstractVector{CoordLog{T}}, n) where {T}
|
|
||||||
dformat = dateformat"yyyy-m-d"
|
|
||||||
logdates::Vector{DateTime} = map(logs) do log
|
|
||||||
fill(log.logdate, n_coords(log))
|
|
||||||
end |> (v -> vcat(v...))
|
|
||||||
fst, lst = extrema(logdates)
|
|
||||||
normeddate = (logdates .- fst) ./ (lst - fst)
|
|
||||||
diff = (lst - fst) / (n - 1)
|
|
||||||
ticklabels = format.(fst:diff:lst, dformat)
|
|
||||||
return normeddate, ticklabels
|
|
||||||
end
|
|
||||||
|
|
||||||
"Color depending on altitude."
|
|
||||||
struct Altitude <: ColorMapFunc end
|
|
||||||
|
|
||||||
function (f::Altitude)(logs::AbstractVector{CoordLog{T}}, n) where {T}
|
|
||||||
altitudes = map(logs) do log
|
|
||||||
Iterators.map(eachrow(log.coords)) do c
|
|
||||||
c[2]
|
|
||||||
end
|
|
||||||
end |> Iterators.flatten |> collect
|
|
||||||
low, high = extrema(altitudes)
|
|
||||||
normedalt = (altitudes .- low) ./ (high - low)
|
|
||||||
ticklabels = string.(round.(LinRange(low, high, n)))
|
|
||||||
return normedalt, ticklabels
|
|
||||||
end
|
|
||||||
|
|
||||||
end # module ColorMapFunc
|
|
||||||
|
|
||||||
# TODO: alpha?
|
|
||||||
"""
|
|
||||||
trace2ds(log::Vector{CoordLog})
|
|
||||||
|
|
||||||
# Arguments
|
|
||||||
TODO
|
|
||||||
"""
|
|
||||||
@recipe(Trace2Ds, log) do scene
|
|
||||||
Attributes(;
|
|
||||||
showmarker = false,
|
|
||||||
marker = theme(scene, :marker),
|
|
||||||
markercolormap = theme(scene, :colormap),
|
|
||||||
markersize = theme(scene, :markersize),
|
|
||||||
strokewidth = 0,
|
|
||||||
showline = true,
|
|
||||||
linecolormap = theme(scene, :colormap),
|
|
||||||
linestyle = theme(scene, :linestyle),
|
|
||||||
linewidth = theme(scene, :linewidth),
|
|
||||||
inspectable = theme(scene, :inspectable),
|
|
||||||
lcolormapfunc = ColorMapFuncs.ColorMap(), # or func like in ColorMapFunc
|
|
||||||
mcolormapfunc = ColorMapFuncs.ColorMap(),
|
|
||||||
lcolorticks = nothing,
|
|
||||||
nlcolorticks = 5,
|
|
||||||
mcolorticks = nothing,
|
|
||||||
nmcolorticks = 5,
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Makie.plot!(tr2d::Trace2Ds)
|
|
||||||
# @info "logs" tr2d
|
|
||||||
# @info "fieldnames" tr2d.log
|
|
||||||
# @info "" theme(tr2d, :colormap)
|
|
||||||
|
|
||||||
lcolormapfunc = tr2d.lcolormapfunc
|
|
||||||
|
|
||||||
ntraces = length(tr2d.log[]) # number of CoordLog
|
|
||||||
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[])
|
|
||||||
end
|
|
||||||
markercolors = Observable(
|
|
||||||
tr2d.mcolormapfunc[](tr2d.markercolormap[], tr2d.log[], tr2d.nmcolorticks[])[1],
|
|
||||||
)
|
|
||||||
mticks = tr2d.mcolorticks
|
|
||||||
if tr2d.linecolormap[] isa Symbol
|
|
||||||
tr2d.linecolormap[] = getproperty(ColorSchemes, tr2d.linecolormap[])
|
|
||||||
end
|
|
||||||
# @info "lcolormapfunc" lcolormapfunc
|
|
||||||
linecolors =
|
|
||||||
Observable(lcolormapfunc[](tr2d.linecolormap[], tr2d.log[], tr2d.nlcolorticks[])[1])
|
|
||||||
lticks = tr2d.lcolorticks
|
|
||||||
|
|
||||||
# helper function which mutates observables
|
|
||||||
function update_plot(
|
|
||||||
logs::AbstractVector{<:CoordLog{T}},
|
|
||||||
lcolormap,
|
|
||||||
mcolormap,
|
|
||||||
lcolormapfunc, #::Union{Symbol, Tuple{Symbol, Symbol}},
|
|
||||||
mcolormapfunc,
|
|
||||||
) where {T}
|
|
||||||
@info "update_plot"
|
|
||||||
markercolors[]
|
|
||||||
linecolors[]
|
|
||||||
# @info "logs on update_plot" logs
|
|
||||||
# init
|
|
||||||
empty!(linesegs[])
|
|
||||||
empty!(points[])
|
|
||||||
empty!(altitudes[])
|
|
||||||
empty!(point_ids[])
|
|
||||||
empty!(markercolors[])
|
|
||||||
if linecolors[] isa AbstractVector
|
|
||||||
empty!(linecolors[])
|
|
||||||
else
|
|
||||||
linecolors[] = []
|
|
||||||
end
|
|
||||||
|
|
||||||
# update
|
|
||||||
colors_count = 1
|
|
||||||
lcolors, lticks[] = lcolormapfunc(lcolormap, logs, tr2d.nlcolorticks[])
|
|
||||||
mcolors, mticks[] = mcolormapfunc(mcolormap, logs, tr2d.nmcolorticks[])
|
|
||||||
for (i, log) in enumerate(logs)
|
|
||||||
first = true
|
|
||||||
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])
|
|
||||||
colors_count += 1
|
|
||||||
|
|
||||||
# # marker
|
|
||||||
# if !isnothing(mcolormapfunc)
|
|
||||||
# push!(markercolors[], mcolormapfunc(logs)[i])
|
|
||||||
# end
|
|
||||||
|
|
||||||
if first
|
|
||||||
pop!(linesegs[])
|
|
||||||
pop!(linecolors[])
|
|
||||||
first = false
|
|
||||||
else
|
|
||||||
# # colors
|
|
||||||
# if !isnothing(lcolormapfunc)
|
|
||||||
# push!(linecolors[], lcolormapfunc(logs)[i])
|
|
||||||
# end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
pop!(linesegs[])
|
|
||||||
pop!(linecolors[])
|
|
||||||
push!(notes[], log.note)
|
|
||||||
end
|
|
||||||
|
|
||||||
markercolors[] = markercolors[]
|
|
||||||
linecolors[] = linecolors[]
|
|
||||||
end
|
|
||||||
|
|
||||||
Makie.Observables.onany(
|
|
||||||
update_plot,
|
|
||||||
tr2d.log,
|
|
||||||
tr2d.linecolormap,
|
|
||||||
tr2d.markercolormap,
|
|
||||||
lcolormapfunc,
|
|
||||||
tr2d.mcolormapfunc,
|
|
||||||
)
|
|
||||||
|
|
||||||
# init
|
|
||||||
update_plot(
|
|
||||||
tr2d.log[],
|
|
||||||
tr2d.linecolormap[],
|
|
||||||
tr2d.markercolormap[],
|
|
||||||
lcolormapfunc[],
|
|
||||||
tr2d.mcolormapfunc[],
|
|
||||||
)
|
|
||||||
|
|
||||||
linesegments!(
|
|
||||||
tr2d,
|
|
||||||
linesegs,
|
|
||||||
color = linecolors,
|
|
||||||
linewidth = tr2d.linewidth,
|
|
||||||
linestyle = tr2d.linestyle,
|
|
||||||
visible = tr2d.showline,
|
|
||||||
# inspector_label = (self, i, pos) ->
|
|
||||||
)
|
|
||||||
scatter!(
|
|
||||||
tr2d,
|
|
||||||
points,
|
|
||||||
color = markercolors,
|
|
||||||
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)
|
|
||||||
|
|
||||||
tr2d
|
|
||||||
end
|
|
|
@ -1,8 +1,4 @@
|
||||||
using Dates
|
using Dates
|
||||||
import Base
|
|
||||||
"""
|
|
||||||
Stores a set of logs with its taken date datetime and supplemental note.
|
|
||||||
"""
|
|
||||||
mutable struct CoordLog{T <: AbstractFloat}
|
mutable struct CoordLog{T <: AbstractFloat}
|
||||||
coords::Matrix{T}
|
coords::Matrix{T}
|
||||||
logdate::DateTime
|
logdate::DateTime
|
||||||
|
@ -17,11 +13,3 @@ Get number of coordinates in `log`.
|
||||||
function n_coords(log::CoordLog)::Integer
|
function n_coords(log::CoordLog)::Integer
|
||||||
size(log.coords)[1]
|
size(log.coords)[1]
|
||||||
end
|
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
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
using GLMakie
|
|
||||||
using ColorTypes
|
|
||||||
using ColorSchemes
|
|
||||||
using FileIO
|
|
||||||
|
|
||||||
function _plot_map!(ax, mappath::AbstractString)
|
|
||||||
map = load(mappath)
|
|
||||||
let
|
|
||||||
heigh, width = size(map)
|
|
||||||
heatmap!(
|
|
||||||
ax,
|
|
||||||
(1:width) .- width ÷ 2,
|
|
||||||
(1:heigh) .- heigh ÷ 2,
|
|
||||||
rotr90(map),
|
|
||||||
inspectable = false,
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function view_with_map(log::CoordLog; map = "map.png")
|
|
||||||
fig = Figure()
|
|
||||||
ax = Axis(fig[1, 1], aspect = AxisAspect(1))
|
|
||||||
_plot_map!(ax, map)
|
|
||||||
|
|
||||||
return fig
|
|
||||||
end
|
|
||||||
|
|
|
@ -5,15 +5,11 @@ using Test
|
||||||
@testset "CoordVisualize" begin
|
@testset "CoordVisualize" begin
|
||||||
"Must be same as the first log in `sample_log.txt`"
|
"Must be same as the first log in `sample_log.txt`"
|
||||||
sample_log_1 = CoordVisualize.CoordLog[CoordVisualize.CoordLog{Float64}([-54.0 -10.000000953674 -35.000003814697; -54.0 -10.000000953674 -35.000003814697; -54.0 -10.000000953674 -36.013381958008; -54.0 -10.000000953674 -37.615753173828; -54.0 -10.000000953674 -39.261665344238; -54.0 -10.000000953674 -40.727695465088; -54.0 -10.000000953674 -42.168701171875; -54.0 -10.000000953674 -43.820377349854; -54.0 -11.018865585327 -47.018901824951; -54.0 -14.0 -51.176284790039; -54.663269042969 -14.0 -55.0; -58.297706604004 -14.0 -55.0; -63.16588973999 -16.0 -55.0; -66.000007629395 -16.0 -55.526763916016; -66.000007629395 -16.0 -59.460041046143; -66.000007629395 -16.0 -63.24658203125; -66.000007629395 -16.0 -67.261924743652; -66.000007629395 -16.0 -71.199310302734], Dates.DateTime("2023-10-22T10:02:04"), "")]
|
sample_log_1 = CoordVisualize.CoordLog[CoordVisualize.CoordLog{Float64}([-54.0 -10.000000953674 -35.000003814697; -54.0 -10.000000953674 -35.000003814697; -54.0 -10.000000953674 -36.013381958008; -54.0 -10.000000953674 -37.615753173828; -54.0 -10.000000953674 -39.261665344238; -54.0 -10.000000953674 -40.727695465088; -54.0 -10.000000953674 -42.168701171875; -54.0 -10.000000953674 -43.820377349854; -54.0 -11.018865585327 -47.018901824951; -54.0 -14.0 -51.176284790039; -54.663269042969 -14.0 -55.0; -58.297706604004 -14.0 -55.0; -63.16588973999 -16.0 -55.0; -66.000007629395 -16.0 -55.526763916016; -66.000007629395 -16.0 -59.460041046143; -66.000007629395 -16.0 -63.24658203125; -66.000007629395 -16.0 -67.261924743652; -66.000007629395 -16.0 -71.199310302734], Dates.DateTime("2023-10-22T10:02:04"), "")]
|
||||||
sample_log_1_2 = CoordVisualize.CoordLog[CoordVisualize.CoordLog{Float64}([-54.0 -10.000000953674 -35.000003814697; -54.0 -10.000000953674 -35.000003814697; -54.0 -10.000000953674 -36.013381958008; -54.0 -10.000000953674 -37.615753173828; -54.0 -10.000000953674 -39.261665344238; -54.0 -10.000000953674 -40.727695465088; -54.0 -10.000000953674 -42.168701171875; -54.0 -10.000000953674 -43.820377349854; -54.0 -11.018865585327 -47.018901824951; -54.0 -14.0 -51.176284790039; -54.663269042969 -14.0 -55.0; -58.297706604004 -14.0 -55.0; -63.16588973999 -16.0 -55.0; -66.000007629395 -16.0 -55.526763916016; -66.000007629395 -16.0 -59.460041046143; -66.000007629395 -16.0 -63.24658203125; -66.000007629395 -16.0 -67.261924743652; -66.000007629395 -16.0 -71.199310302734], Dates.DateTime("2023-10-22T10:02:04"), "")]
|
|
||||||
|
|
||||||
"Must be same as the second log in `sample_log.txt`"
|
"Must be same as the second log in `sample_log.txt`"
|
||||||
sample_log_2 = CoordVisualize.CoordLog{Float64}([895.0 7.0 -978.0; 895.0 7.0 -978.0; 895.0 7.0 -977.38684082031; 895.0 7.0 -975.71923828125; 897.0 7.0 -974.39855957031; 898.80633544922 7.0 -973.0; 901.38275146484 7.0 -973.0; 904.18518066406 7.0 -973.0; 907.25793457031 7.0 -973.0; 911.19061279297 7.0 -973.0; 915.05682373047 7.0 -973.0; 919.1259765625 7.0 -973.0; 923.12609863281 7.0 -973.0; 926.94378662109 7.0 -973.0; 930.82952880859 7.0 -973.0; 934.84539794922 7.0 -973.0; 938.83020019531 7.0 -973.0; 944.04681396484 8.0 -973.0; 948.01483154297 8.0148372650146 -973.0; 951.48193359375 9.0000009536743 -973.0; 955.5927734375 10.000000953674 -973.0; 954.96008300781 10.000000953674 -973.0; 958.39764404297 11.000000953674 -973.0; 962.41009521484 12.000000953674 -973.0; 966.17108154297 12.000000953674 -973.0; 969.40936279297 12.000000953674 -973.0; 969.47576904297 13.0 -973.0; 973.32684326172 13.0 -973.0; 977.21990966797 13.0 -973.0; 981.09814453125 13.0 -973.0; 985.05871582031 13.0 -973.0; 989.03479003906 13.0 -973.0; 992.83026123047 13.0 -973.0; 996.90203857422 13.0 -973.0], DateTime("0000-01-01T00:00:00"), "")
|
sample_log_2 = CoordVisualize.CoordLog{Float64}([895.0 7.0 -978.0; 895.0 7.0 -978.0; 895.0 7.0 -977.38684082031; 895.0 7.0 -975.71923828125; 897.0 7.0 -974.39855957031; 898.80633544922 7.0 -973.0; 901.38275146484 7.0 -973.0; 904.18518066406 7.0 -973.0; 907.25793457031 7.0 -973.0; 911.19061279297 7.0 -973.0; 915.05682373047 7.0 -973.0; 919.1259765625 7.0 -973.0; 923.12609863281 7.0 -973.0; 926.94378662109 7.0 -973.0; 930.82952880859 7.0 -973.0; 934.84539794922 7.0 -973.0; 938.83020019531 7.0 -973.0; 944.04681396484 8.0 -973.0; 948.01483154297 8.0148372650146 -973.0; 951.48193359375 9.0000009536743 -973.0; 955.5927734375 10.000000953674 -973.0; 954.96008300781 10.000000953674 -973.0; 958.39764404297 11.000000953674 -973.0; 962.41009521484 12.000000953674 -973.0; 966.17108154297 12.000000953674 -973.0; 969.40936279297 12.000000953674 -973.0; 969.47576904297 13.0 -973.0; 973.32684326172 13.0 -973.0; 977.21990966797 13.0 -973.0; 981.09814453125 13.0 -973.0; 985.05871582031 13.0 -973.0; 989.03479003906 13.0 -973.0; 992.83026123047 13.0 -973.0; 996.90203857422 13.0 -973.0], DateTime("0000-01-01T00:00:00"), "")
|
||||||
|
|
||||||
sample_result = CoordVisualize.parse_log("sample_log.txt"; interactive=false)
|
sample_result = CoordVisualize.parse_log("sample_log.txt"; interactive=false)
|
||||||
@testset "equality" begin
|
|
||||||
@test sample_log_1 == sample_log_1_2
|
|
||||||
end
|
|
||||||
@testset "parse" begin
|
@testset "parse" begin
|
||||||
@debug sample_result
|
@debug sample_result
|
||||||
@testset "parse with datetime" begin
|
@testset "parse with datetime" begin
|
||||||
|
@ -53,9 +49,4 @@ using Test
|
||||||
@test splitted_2.note == "latter one"
|
@test splitted_2.note == "latter one"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@testset "export" begin
|
|
||||||
re_evaled_log = CoordVisualize.export_log(sample_log_1) |> Meta.parse |> eval
|
|
||||||
@test re_evaled_log[1] == sample_log_1[1]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue