ruby-grads 1.0.3 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80635c24ddd173f6c639cb5d3923a93cb3004b99faea550cd8bfff5b5ece5893
4
- data.tar.gz: e80ad976dab30b0006287817c36b3630a0e598edc50552074e95f448c0007595
3
+ metadata.gz: d3ec3f629db574dd3245ce9ed04e371ead7d8646cce6ca964dfda1d8eafaadb1
4
+ data.tar.gz: bf5b28282a3d11cf3fcc5cbcf1a8fbd3cbadb50fc0195c4636729da957d78b9d
5
5
  SHA512:
6
- metadata.gz: 4b0740e3148f3d73b9ed1bf94ea35dc2fae48c93c888aa02abc5583f84e230f46f27f7361d4b0381d9b0fadf9a8c3d2e9d12bddfa0e3296b755df839d3ad682b
7
- data.tar.gz: 9e3641cfb796507372fdc745b8d541d55f22e3b6a2c56d8298324ff8dd78b595823b30e14427b6bb074690a6aa040d36636c8ed24a551e215bd4d1adda09d7ab
6
+ metadata.gz: 4e4e8fae8d55ad18f403a5c0c7ee5bef1c9c94f74e4e5efe0c90317838758b9dac3616fb27731b66bd7a1857e0ae286344aa511d94054f976912e71f77049207
7
+ data.tar.gz: 3e2f6b6d92682e0560e3db04cb27d2e467e10f3a8e90f1388b8d082975a2f5888799d1aa0b1530c6ac20f23a211b75cacb79cd6b458debef3a8d3996534fa530
data/README.md CHANGED
@@ -15,7 +15,6 @@ Execute grads command sequence
15
15
  GrADS#exec filename
16
16
  GrADS#exec_string text
17
17
 
18
-
19
18
  ### CArray -> GrADS variable
20
19
 
21
20
  Write block as GrADS::Gridded::Writer definition
@@ -27,5 +26,72 @@ Write block as GrADS::Gridded::Writer definition
27
26
 
28
27
  GrADS#save_image(filename, size="640", dpi=300)
29
28
 
29
+ ### parea, vpage
30
+
31
+ parea(x1, x2, y1, y2) { |area|
32
+
33
+ }
34
+
35
+ vpage(x1, x2, y1, y2) { |area|
36
+
37
+ }
38
+
39
+ ### plot
40
+
41
+ plot (expr, type) {
42
+ ... CONFIG ...
43
+ }
44
+
45
+ ### axis
46
+
47
+ axis (dummy_expr) {
48
+ ... CONFIG ...
49
+ }
50
+
51
+ #### axis_xtime
52
+
53
+ require "grads/lib/axis_xtime"
54
+ axis_xtime (dummy_expr, OPTIONS) {
55
+ ... CONFIG__
56
+ }
57
+
58
+ OPTIONS:
59
+ offset: TIME OFFSET in seconds
60
+ skip: TIME axis interval to skip labels
61
+
62
+ #### time_skip
63
+
64
+ Use with axis_xtime to calculate skip for x-time in vector plot.
65
+
66
+ skp = time_skip()
67
+ plot("skip(u,1,#{skp});v", :vector) {
68
+ ...
69
+ }
70
+
71
+ ### axis label
72
+
73
+ draw_ylabel(text, area: area, color: 1, just: "bc", thickness: 3, rot 0, offset: STRING, side: "l")
74
+ draw_xlabel(text, area: area, color: 1, just: "bc", thickness: 3, rot: 0, offset: STRING, side: "b")
75
+
76
+ ### COLOR NAMES
77
+
78
+ COLOR(COLOR_NAME)
30
79
 
80
+ "background" => 0,
81
+ "foregraound" => 1,
82
+ "red" => 2,
83
+ "green" => 3,
84
+ "dark blue" => 4,
85
+ "light blue" => 5,
86
+ "magenta" => 6,
87
+ "yellow" => 7,
88
+ "orange" => 8,
89
+ "purple" => 9,
90
+ "yellow green" => 10,
91
+ "medium blue" => 11,
92
+ "dark yellow" => 12,
93
+ "aqua" => 13,
94
+ "dark purple" => 14,
95
+ "gray" => 15,
96
+
31
97
 
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+
2
+ GEMSPEC = "ruby-grads.gemspec"
3
+
4
+ # gem install #{spec.full_name}.gem -- --with-gnuplotting-palette
5
+
6
+ task :install do
7
+ spec = eval File.read(GEMSPEC)
8
+ system %{
9
+ gem build #{GEMSPEC}; gem install --no-document #{spec.full_name}.gem
10
+ }
11
+ end
12
+
13
+ require 'rspec/core/rake_task'
14
+ RSpec::Core::RakeTask.new
data/bin/ncdef2ctl ADDED
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "grads"
4
+ require "stringio"
5
+
6
+ def scan_vars (vars)
7
+ items = {:namelist=>[]}
8
+ nvars = nil
9
+ vars.each_line do |line|
10
+ case line
11
+ when /\A\s*\*/, /\A\s*\Z/
12
+ next
13
+ when /\A\s*vars\s+(\d+)/i
14
+ nvars = $1.to_i
15
+ when /\A\s*endvars/i
16
+ break
17
+ when /\A\s*(\w+)\s*(.*)\Z/
18
+ name = $1
19
+ items[:namelist].push(name)
20
+ items[name] = line
21
+ end
22
+ end
23
+ if items[:namelist].size != nvars
24
+ raise "invalid vars number"
25
+ end
26
+ return items
27
+ end
28
+
29
+ def scan_control_file (ctltxt)
30
+ io = StringIO.new(ctltxt)
31
+ items = {}
32
+ buffer = ""
33
+ while line = io.gets
34
+ case line
35
+ when /\A\s*\*/, /\A\s*\Z/
36
+ next
37
+ when /\A\s*(dtype|dset|title|undef|options|pdef|xdef|ydef|zdef|tdef|vectorpairs)\s*(.*)\Z/i
38
+ name = $1.downcase
39
+ if items[name]
40
+ items[name] = [items[name]]
41
+ items[name] << $2.rstrip
42
+ buffer = items[name].last
43
+ else
44
+ items[name] = $2.rstrip
45
+ buffer = items[name]
46
+ end
47
+ when /\A\s*(chsub|fileheader|theader|tailerbyts|xyheader)\s*(.*)\Z/i
48
+ raise "#{$1} entry is not supported, sorry"
49
+ when /\A\s*vars/
50
+ vars = scan_vars(line + io.read)
51
+ break
52
+ else
53
+ line = line.chomp.sub(/\\\z/,'').rstrip
54
+ buffer.replace(buffer + " " + line)
55
+ end
56
+ end
57
+ return items, vars
58
+ end
59
+
60
+
61
+ def levels2linear (axis, line)
62
+ list = line.split(/\s+/)
63
+ num = list.shift.to_i
64
+ type = list.shift
65
+ data = list
66
+ case type
67
+ when "levels"
68
+ case axis
69
+ when "tdef"
70
+ return axis + " " + line
71
+ else
72
+ data = data.to_ca.double
73
+ diff = (data[1..-1]-data[0..-2]).mean
74
+ return format("%s %i %s %f %f", axis, num, "linear", data[0], diff)
75
+ end
76
+ when "linear"
77
+ return axis + " " + line
78
+ else
79
+ raise "invalid #{defname} definition"
80
+ end
81
+
82
+ end
83
+
84
+ GrADS.start("grads -b") {
85
+
86
+ sdfopen(ARGV[0])
87
+
88
+ ctl = query(:ctlinfo)
89
+
90
+ header, var = scan_control_file(ctl)
91
+
92
+ header.keys.each do |key|
93
+ case key
94
+ when "xdef", "ydef", "zdef", "tdef"
95
+ puts levels2linear(key, header[key])
96
+ else
97
+ puts "#{key} #{header[key]}"
98
+ end
99
+ end
100
+
101
+ puts "vars #{var[:namelist].size}"
102
+ var[:namelist].each do |name|
103
+ puts var[name]
104
+ end
105
+ puts "endvars"
106
+
107
+ }
data/lib/grads.rb CHANGED
@@ -9,3 +9,4 @@ require "grads/command"
9
9
  require "grads/lib/makecpt"
10
10
  require "grads/lib/colorbar"
11
11
  require "grads/lib/save_image"
12
+ require "grads/lib/axis_xtime"
data/lib/grads/command.rb CHANGED
@@ -183,7 +183,11 @@ class GrADS::Command
183
183
  attr_reader :log
184
184
 
185
185
  def method_missing (id, *argv)
186
- return id, *argv
186
+ if argv.empty?
187
+ return id
188
+ else
189
+ super
190
+ end
187
191
  end
188
192
 
189
193
  def quit
@@ -409,7 +413,6 @@ class GrADS::Command
409
413
  "reinit",
410
414
  "reset",
411
415
  "run",
412
- "sdfwrite",
413
416
  "swap",
414
417
  "undefine",
415
418
  ].each do |name|
@@ -420,9 +423,21 @@ class GrADS::Command
420
423
  }
421
424
  end
422
425
 
426
+ [
427
+ "sdfwrite",
428
+ ].each do |name|
429
+ class_eval %{
430
+ def #{name} (*argv)
431
+ if argv.empty?
432
+ return :#{name}
433
+ else
434
+ put "#{name} " + argv.join(" ")
435
+ end
436
+ end
437
+ }
438
+ end
439
+
423
440
  def clear (*argv)
424
- @ccols = nil
425
- @clevs = nil
426
441
  put "clear " + argv.join(" ")
427
442
  end
428
443
 
@@ -525,13 +540,20 @@ class GrADS::Command
525
540
  end
526
541
 
527
542
  def set_clevs (*argv)
528
- @clevs = argv
529
543
  set :clevs, *argv
530
544
  end
531
545
 
532
546
  def set_ccols (*argv)
533
- @ccols = argv
534
- set :ccols, *argv
547
+ list = []
548
+ argv.each do |arg|
549
+ case arg
550
+ when RGB
551
+ list << set_rgb(arg)
552
+ else
553
+ list << arg
554
+ end
555
+ end
556
+ set :ccols, *list
535
557
  end
536
558
 
537
559
  def import (*args)
@@ -653,7 +675,7 @@ class GrADS::Command
653
675
  end
654
676
 
655
677
  begin
656
- require "netcdflib"
678
+ require "simple-netcdf"
657
679
  def get_var (expr)
658
680
  @var_id ||= 0
659
681
  @var_id += 1
@@ -737,6 +759,395 @@ class GrADS::Command
737
759
  end
738
760
  end
739
761
 
762
+ class Area
763
+
764
+ def initialize (x1, x2, y1, y2)
765
+ @x1 = x1
766
+ @x2 = x2
767
+ @y1 = y1
768
+ @y2 = y2
769
+ end
770
+
771
+ attr_reader :x1, :x2, :y1, :y2
772
+
773
+ def w
774
+ return @x2 - @x1
775
+ end
776
+
777
+ def h
778
+ return @y2 - @y1
779
+ end
780
+
781
+ def center
782
+ return @x1 + w/2
783
+ end
784
+
785
+ def mid
786
+ return @y1 + h/2
787
+ end
788
+
789
+ end
790
+
791
+ def len (str)
792
+ ans = query("string #{str}")
793
+ return subwrd(ans, 4).to_f
794
+ end
795
+
796
+ def parea (x1, x2, y1, y2)
797
+ set :parea, x1, x2, y1, y2
798
+ set :clip, x1, x2, y1, y2
799
+ yield Area.new(x1, x2, y1, y2)
800
+ end
801
+
802
+ def vpage (x1, x2, y1, y2)
803
+ set :vpage, x1, x2, y1, y2
804
+ yield Area.new(x1, x2, y1, y2)
805
+ end
806
+
807
+ def display_nothing (dummy)
808
+ ans = query("dims")
809
+ case ans.scan("varying").size
810
+ when 2
811
+ set :gxout, :contour
812
+ set :clevs, -9.99e99
813
+ set :ccolor, -1
814
+ set :clab, :off
815
+ set :cmark, 0
816
+ when 1
817
+ set :gxout, :line
818
+ set :line, -1
819
+ set :ylab, :off
820
+ set :vrange, -9.99e99, -9.99e98
821
+ end
822
+ if block_given?
823
+ yield
824
+ end
825
+ case dummy
826
+ when String
827
+ put "display #{dummy}"
828
+ else
829
+ display dummy
830
+ end
831
+ end
832
+
833
+ def axis_off
834
+ set :frame, :off
835
+ set :xlab, :off
836
+ set :ylab, :off
837
+ set :grid, :off
838
+ set :grads, :off
839
+ set :mpdraw, :off
840
+ end
841
+
842
+ def axis_on
843
+ set :frame, :on
844
+ set :xlab, :on
845
+ set :ylab, :on
846
+ set :grid, :on
847
+ set :grads, :on
848
+ set :mpdraw, :on
849
+ end
850
+
851
+ def plot (var, *args)
852
+ begin
853
+ axis_off
854
+ if block_given?
855
+ yield
856
+ end
857
+ set :gxout, *args
858
+ case var
859
+ when String
860
+ put "display #{var}"
861
+ else
862
+ display var
863
+ end
864
+ ensure
865
+ axis_on
866
+ end
867
+ end
868
+
869
+ def axis (dummy, &block)
870
+ begin
871
+ axis_on
872
+ display_nothing(dummy, &block)
873
+ ensure
874
+ axis_off
875
+ end
876
+ end
877
+
878
+ def draw_ylabel (text, area:, color: 1, just: "bc", thickness: 3, rot: 90, offset: "M", side: "l")
879
+ set :string, color, just, thickness, rot
880
+ case side
881
+ when "l"
882
+ draw :string, area.x1-len(offset), area.mid, text
883
+ when "r"
884
+ draw :string, area.x2+len(offset), area.mid, text
885
+ else
886
+ raise "invalid side sepecification"
887
+ end
888
+ end
889
+
890
+ def draw_xlabel (text, area:, color: 1, just: "bc", thickness: 3, rot: 0, offset: "M", side: "b")
891
+ set :string, color, just, thickness, rot
892
+ case side
893
+ when "b"
894
+ draw :string, area.center, area.y1-len(offset), text
895
+ when "t"
896
+ draw :string, area.center, area.y2+len(offset), text
897
+ else
898
+ raise "invalid side sepecification"
899
+ end
900
+ end
901
+
902
+ COLOR_TABLE = {
903
+ "background" => 0,
904
+ "foregraound" => 1,
905
+ "red" => 2,
906
+ "green" => 3,
907
+ "dark blue" => 4,
908
+ "light blue" => 5,
909
+ "magenta" => 6,
910
+ "yellow" => 7,
911
+ "orange" => 8,
912
+ "purple" => 9,
913
+ "yellow green" => 10,
914
+ "medium blue" => 11,
915
+ "dark yellow" => 12,
916
+ "aqua" => 13,
917
+ "dark purple" => 14,
918
+ "gray" => 15,
919
+ }
920
+
921
+ def COLOR (name)
922
+ if COLOR_TABLE.has_key?(name)
923
+ COLOR_TABLE[name]
924
+ else
925
+ -1
926
+ end
927
+ end
928
+
929
+ class LINE
930
+
931
+ def initialize (type = 1, color: 1, thickness: 3)
932
+ case type
933
+ when "","solid"
934
+ @type = 1
935
+ when "--", "long dash"
936
+ @type = 2
937
+ when "-", "short dash"
938
+ @type = 3
939
+ when "-- -", "long dash short dash"
940
+ @type = 4
941
+ when ".", "dotted"
942
+ @type = 5
943
+ when ". -", "dot dash"
944
+ @type = 6
945
+ when ". . -", "dot dot dash"
946
+ @type = 7
947
+ else
948
+ @type = type
949
+ end
950
+ @color = color
951
+ @thickness = thickness
952
+ end
953
+
954
+ attr_reader :type, :color
955
+
956
+ def to_a
957
+ return [@color, @type, @thickness]
958
+ end
959
+
960
+ end
961
+
962
+ class TILE
963
+
964
+ def self.reset
965
+ @@number = 0
966
+ end
967
+
968
+ def self.next_number
969
+ @@number += 1
970
+ if @@number > 2047
971
+ reset
972
+ end
973
+ return @@number
974
+ end
975
+
976
+ reset
977
+
978
+ def initialize (type, width: 6, height: nil, thickness: 3, color: 1, bgcolor: -1)
979
+ case type
980
+ when "."
981
+ @type = 2
982
+ when "\\"
983
+ @type = 3
984
+ when "/"
985
+ @type = 4
986
+ when "x"
987
+ @type = 5
988
+ when "|"
989
+ @type = 6
990
+ when "-"
991
+ @type = 7
992
+ when "#", "+"
993
+ @type = 8
994
+ else
995
+ @type = type
996
+ end
997
+ @width = width
998
+ @height = height || width
999
+ @thickness = thickness
1000
+ @color = color
1001
+ @bgcolor = bgcolor
1002
+ end
1003
+
1004
+ attr_reader :type, :color
1005
+
1006
+ def to_a
1007
+ return [@type, @width, @height, @thickness, @color, @bgcolor]
1008
+ end
1009
+
1010
+ end
1011
+
1012
+ class RGB
1013
+
1014
+ @@number = nil
1015
+ @@table = {}
1016
+
1017
+ def self.reset
1018
+ @@number = 100
1019
+ end
1020
+
1021
+ def self.next_number
1022
+ @@number += 1
1023
+ if @@number > 2047
1024
+ reset
1025
+ end
1026
+ return @@number
1027
+ end
1028
+
1029
+ reset
1030
+
1031
+ def initialize (r, g, b, a=255)
1032
+ @r = r
1033
+ @g = g
1034
+ @b = b
1035
+ @a = a
1036
+ end
1037
+
1038
+ attr_reader :r, :g, :b, :a
1039
+
1040
+ def to_s
1041
+ return format("%i %i %i %i", @r, @g, @b, @a)
1042
+ end
1043
+
1044
+ def to_a
1045
+ return [@r, @g, @b, @a]
1046
+ end
1047
+
1048
+ def % (alpha)
1049
+ if alpha >= 0 and alpha <= 1
1050
+ a = (@a*alpha).to_i
1051
+ else
1052
+ raise "invalid alpha value"
1053
+ end
1054
+ return RGB.new(@r, @g, @b, a)
1055
+ end
1056
+
1057
+ def * (scale)
1058
+ if scale >= 0 and scale <= 1
1059
+ return RGB.new((@r*scale).to_i, (@g*scale).to_i, (@b*scale).to_i, @a)
1060
+ else
1061
+ raise "invalid scale value"
1062
+ end
1063
+ end
1064
+
1065
+ def / (scale)
1066
+ if scale >= 1
1067
+ return RGB.new((@r/scale).to_i, (@g/scale).to_i, (@b/scale).to_i, @a)
1068
+ else
1069
+ raise "invalid scale value"
1070
+ end
1071
+ end
1072
+
1073
+ def + (other)
1074
+ r = [self.r, other.r].max
1075
+ g = [self.g, other.g].max
1076
+ b = [self.b, other.b].max
1077
+ a = [self.a, other.a].max
1078
+ return RGB.new(r,g,b,a)
1079
+ end
1080
+
1081
+ end
1082
+
1083
+ def LINE (*argv)
1084
+ return LINE.new(*argv)
1085
+ end
1086
+
1087
+ def TILE (*argv)
1088
+ return TILE.new(*argv)
1089
+ end
1090
+
1091
+ def RGB (*argv)
1092
+ case argv.size
1093
+ when 1
1094
+ return GrADS::Command::RGB_TABLE[argv[0]]
1095
+ else
1096
+ return GrADS::Command::RGB.new(*argv)
1097
+ end
1098
+ end
1099
+
1100
+ def self.RGB (*argv)
1101
+ case argv.size
1102
+ when 1
1103
+ return GrADS::Command::RGB_TABLE[argv[0]]
1104
+ else
1105
+ return GrADS::Command::RGB.new(*argv)
1106
+ end
1107
+ end
1108
+
1109
+ RGB_TABLE = {
1110
+ "red" => RGB(255,0,0),
1111
+ "green" => RGB(0,255,0),
1112
+ "blue" => RGB(0,0,255),
1113
+ }
1114
+ RGB_TABLE.update({
1115
+ "cyan" => RGB("green") + RGB("blue"),
1116
+ })
1117
+
1118
+ def set_line (obj)
1119
+ args = obj.to_a
1120
+ if obj.color.is_a?(RGB)
1121
+ args[0] = set_rgb(obj.color)
1122
+ end
1123
+ set :line, *args
1124
+ set :ccolor, args[0]
1125
+ set :cstyle, args[1]
1126
+ set :cthick, args[2]
1127
+ end
1128
+
1129
+ def set_rgb (*argv)
1130
+ list = []
1131
+ argv.each do |obj|
1132
+ num = RGB.next_number
1133
+ case obj
1134
+ when TILE
1135
+ nt = TILE.next_number
1136
+ args = obj.to_a
1137
+ if obj.color.is_a?(RGB)
1138
+ c = set_rgb(obj.color)
1139
+ args[4] = c
1140
+ end
1141
+ set :tile, nt, *args.to_a
1142
+ set :rgb, num, :tile, nt
1143
+ when RGB
1144
+ set :rgb, num, *obj.to_a
1145
+ end
1146
+ list << num
1147
+ end
1148
+ return list
1149
+ end
1150
+
740
1151
  end
741
1152
 
742
1153
  def GrADS.start (*argv, &block)
@@ -755,4 +1166,3 @@ def GrADS.script (name, definition)
755
1166
  end
756
1167
 
757
1168
 
758
-
data/lib/grads/gridded.rb CHANGED
@@ -34,6 +34,16 @@
34
34
  require "carray"
35
35
  require "strscan"
36
36
 
37
+ begin
38
+ require "simple-proj"
39
+ require "simple-proj-carray"
40
+ rescue LoadError
41
+ begin
42
+ require "proj4r"
43
+ rescue LoadError
44
+ end
45
+ end
46
+
37
47
  module GrADS
38
48
  end
39
49
 
@@ -320,7 +330,13 @@ class GrADS::Gridded
320
330
  end
321
331
 
322
332
  def parse_pdef_lcc (args)
323
- require "proj4r"
333
+ if defined? PROJ4 and defined? PROJ4::Proj
334
+ projlib = "proj4r"
335
+ elsif defined? PROJ
336
+ projlib = "simple-proj"
337
+ else
338
+ raise "can't find proj related library"
339
+ end
324
340
  rlat = args[1].to_f
325
341
  rlon = args[2].to_f
326
342
  xi = args[3].to_f
@@ -331,29 +347,57 @@ class GrADS::Gridded
331
347
  dx = args[8].to_f
332
348
  dy = args[9].to_f
333
349
  slat0 = slat1 > 0 ? 90 : -90
334
- if @radius
335
- proj = PROJ4::Proj.new %{
336
- +ellps=sphere +a=#{@radius} +b=#{@radius} +proj=lcc \
337
- +lat_1=#{slat1} +lat_2=#{slat2} +lon_0=#{slon}
338
- }
339
- else
340
- proj = PROJ4::Proj.new %{
341
- +ellps=sphere +proj=lcc \
342
- +lat_1=#{slat1} +lat_2=#{slat2} +lon_0=#{slon}
343
- }
350
+ case projlib
351
+ when "proj4r"
352
+ if @radius
353
+ proj = PROJ4::Proj.new %{
354
+ +ellps=sphere +a=#{@radius} +b=#{@radius} +proj=lcc \
355
+ +lat_1=#{slat1} +lat_2=#{slat2} +lon_0=#{slon}
356
+ }
357
+ else
358
+ proj = PROJ4::Proj.new %{
359
+ +ellps=sphere +proj=lcc \
360
+ +lat_1=#{slat1} +lat_2=#{slat2} +lon_0=#{slon}
361
+ }
362
+ end
363
+ when "simple-proj"
364
+ if @radius
365
+ proj = PROJ.new %{
366
+ +ellps=sphere +a=#{@radius} +b=#{@radius} +proj=lcc \
367
+ +lat_1=#{slat1} +lat_2=#{slat2} +lon_0=#{slon}
368
+ }
369
+ else
370
+ proj = PROJ.new %{
371
+ +ellps=sphere +proj=lcc \
372
+ +lat_1=#{slat1} +lat_2=#{slat2} +lon_0=#{slon}
373
+ }
374
+ end
344
375
  end
345
376
  rx, ry = proj.forward(rlon, rlat)
346
377
  rx0 = rx - (xi-1)*dx
347
378
  ry0 = ry - (yi-1)*dy
348
- @forward = lambda { |lon, lat|
349
- mx, my = proj.forward(lon, lat)
350
- [(mx - rx0)/dx, (my - ry0)/dy]
351
- }
352
- @inverse = lambda { |fi, fj|
353
- mx = fi*dx + rx0
354
- my = fj*dy + ry0
355
- proj.inverse(mx, my)
356
- }
379
+ case projlib
380
+ when "proj4r"
381
+ @forward = lambda { |lon, lat|
382
+ mx, my = proj.forward(lon, lat)
383
+ [(mx - rx0)/dx, (my - ry0)/dy]
384
+ }
385
+ @inverse = lambda { |fi, fj|
386
+ mx = fi*dx + rx0
387
+ my = fj*dy + ry0
388
+ proj.inverse(mx, my)
389
+ }
390
+ when "simple-proj"
391
+ @forward = lambda { |lon, lat|
392
+ mx, my = proj.forward_carray(lon, lat)
393
+ [(mx - rx0)/dx, (my - ry0)/dy]
394
+ }
395
+ @inverse = lambda { |fi, fj|
396
+ mx = fi*dx + rx0
397
+ my = fj*dy + ry0
398
+ proj.inverse_carray(mx, my)
399
+ }
400
+ end
357
401
  @xy = lambda {
358
402
  x = CArray.float(xsize).seq(rx0, dx)
359
403
  y = CArray.float(ysize).seq(ry0, dy)
@@ -0,0 +1,217 @@
1
+ #
2
+ #
3
+ # draw_xlab_time(dummy, offset: nil, skip: nil)
4
+ #
5
+ #
6
+ #
7
+ #
8
+
9
+ class GrADS::Command
10
+
11
+ def time_skip
12
+ ans = query("dims")
13
+ t1 = subwrd(sublin(ans, 5), 11).to_i
14
+ t2 = subwrd(sublin(ans, 5), 13).to_i
15
+ d1 = Time.parse(subwrd(sublin(ans, 5), 6).sub(/Z/," "))
16
+ d2 = Time.parse(subwrd(sublin(ans, 5), 8).sub(/Z/," "))
17
+ nt = t2 - t1 + 1
18
+ nd = (d2 - d1)/86400.0
19
+ dt = ((d2-d1)/(t2-t1)).round
20
+
21
+ type = nil
22
+ skip = nil
23
+
24
+ if nd <= 1
25
+ type = "day"
26
+ elsif nd <= 3
27
+ type = "3days"
28
+ elsif nd <= 7
29
+ type = "week"
30
+ elsif nd <= 14
31
+ type = "2weeks"
32
+ elsif nd <= 31
33
+ type = "month"
34
+ elsif nd <= 120
35
+ type = "season"
36
+ elsif nd <= 360
37
+ type = "year"
38
+ else
39
+ type = "years"
40
+ end
41
+
42
+ unless skip
43
+ case type
44
+ when "day"
45
+ skip = dt.to_i/3600
46
+ when "3days"
47
+ skip = 3*dt.to_i/3600
48
+ when "week"
49
+ skip = 6*dt.to_i/3600
50
+ when "2weeks"
51
+ skip = 12*dt.to_i/3600
52
+ when "month"
53
+ skip = 24*dt.to_i/3600
54
+ when "season"
55
+ skip = 3*24*dt.to_i/3600
56
+ when "year", "years"
57
+ skip = 10*24*dt.to_i/3600
58
+ end
59
+ end
60
+
61
+ return skip
62
+ end
63
+
64
+
65
+ def axis_xtime (dummy, offset: nil, skip: nil, &block)
66
+ puts ans = query("dims")
67
+ t1 = subwrd(sublin(ans, 5), 11).to_i
68
+ t2 = subwrd(sublin(ans, 5), 13).to_i
69
+ d1 = Time.parse(subwrd(sublin(ans, 5), 6).sub(/Z/," "))
70
+ d2 = Time.parse(subwrd(sublin(ans, 5), 8).sub(/Z/," "))
71
+ nt = t2 - t1 + 1
72
+ nd = (d2 - d1)/86400.0
73
+ dt = ((d2-d1)/(t2-t1)).round
74
+ time = CArray.object(nt).seq(d1,dt)
75
+
76
+ type = nil
77
+ skip = nil
78
+
79
+ if offset
80
+ time = time + offset
81
+ end
82
+
83
+ if nd <= 1
84
+ type = "day"
85
+ elsif nd <= 3
86
+ type = "3days"
87
+ elsif nd <= 7
88
+ type = "week"
89
+ elsif nd <= 14
90
+ type = "2weeks"
91
+ elsif nd <= 31
92
+ type = "month"
93
+ elsif nd <= 120
94
+ type = "season"
95
+ elsif nd <= 360
96
+ type = "year"
97
+ else
98
+ type = "years"
99
+ end
100
+
101
+ unless skip
102
+ case type
103
+ when "day"
104
+ skip = dt.to_i/3600
105
+ when "3days"
106
+ skip = 3*dt.to_i/3600
107
+ when "week"
108
+ skip = 6*dt.to_i/3600
109
+ when "2weeks"
110
+ skip = 12*dt.to_i/3600
111
+ when "month"
112
+ skip = 24*dt.to_i/3600
113
+ when "season"
114
+ skip = 3*24*dt.to_i/3600
115
+ when "year", "years"
116
+ skip = 10*24*dt.to_i/3600
117
+ end
118
+ end
119
+
120
+ xlabs = []
121
+ xlabs2 = []
122
+ flag = false
123
+
124
+ case type
125
+ when "day", "3days", "week"
126
+ hour0 = 0
127
+ time[[nil,skip]].each do |t|
128
+ if not flag
129
+ xlabs << t.strftime("%d%b%Y").upcase
130
+ flag = true
131
+ elsif hour0 > t.hour
132
+ xlabs << t.strftime("%d%b").upcase
133
+ else
134
+ xlabs << t.strftime("")
135
+ end
136
+ hour0 = t.hour
137
+ end
138
+ time[[nil,skip]].each do |t|
139
+ if nt > 73
140
+ if t.hour % 3 == 0
141
+ xlabs2 << t.strftime("%H")
142
+ end
143
+ else
144
+ xlabs2 << t.strftime("%H")
145
+ end
146
+ end
147
+ units = ["hour", "day"]
148
+ when "2weeks"
149
+ hour0 = 0
150
+ time[[nil,skip]].each do |t|
151
+ if not flag
152
+ xlabs << t.strftime("%d%b%Y").upcase
153
+ flag = true
154
+ elsif hour0 > t.hour
155
+ xlabs << t.strftime("%d").upcase
156
+ else
157
+ xlabs << t.strftime("")
158
+ end
159
+ hour0 = t.hour
160
+ end
161
+ time[[nil,skip]].each do |t|
162
+ if nt > 73
163
+ if t.hour % 3 == 0
164
+ xlabs2 << t.strftime("%H")
165
+ end
166
+ else
167
+ xlabs2 << t.strftime("%H")
168
+ end
169
+ end
170
+ units = ["hour", "day"]
171
+ when "month","season", "year"
172
+ day0 = 1
173
+ time[[nil,skip]].each do |t|
174
+ if not flag
175
+ xlabs << t.strftime("%d%b%Y").upcase
176
+ flag = true
177
+ elsif day0 > t.day
178
+ xlabs << t.strftime("%b").upcase
179
+ else
180
+ xlabs << t.strftime("")
181
+ end
182
+ day0 = t.day
183
+ end
184
+ time[[nil,skip]].each do |t|
185
+ if nt > 73
186
+ if t.hour % 3 == 0
187
+ xlabs2 << t.strftime("%d")
188
+ end
189
+ else
190
+ xlabs2 << t.strftime("%d")
191
+ end
192
+ end
193
+ units = ["day", "month"]
194
+ end
195
+
196
+ begin
197
+ axis_off
198
+ set :xlab, :on
199
+ set :xlabs, xlabs2.join(" | ")
200
+ set :xlpos, 0, :b
201
+
202
+ display_nothing(dummy)
203
+
204
+ axis_on
205
+ set :xlab, :on
206
+ set :xlabs, xlabs.join(" | ")
207
+ set :xlpos, -0.3, :b
208
+
209
+ display_nothing(dummy, &block)
210
+ ensure
211
+ set :xlpos, 0, b
212
+ end
213
+
214
+ return units
215
+ end
216
+
217
+ end
@@ -10,12 +10,6 @@ class GrADS::Command
10
10
 
11
11
  def setcpt (file)
12
12
  io = Kernel::open(file)
13
- while line = io.gets
14
- if line =~ /COLOR_MODEL\s*=\s*\+?(HSV|RGB)/
15
- model = $1
16
- break
17
- end
18
- end
19
13
  bgrb = nil
20
14
  frgb = nil
21
15
  list = []
@@ -24,12 +18,12 @@ class GrADS::Command
24
18
  when /\A[\#N]/
25
19
  next
26
20
  when /\AB\s/
27
- brgb = line.split(/\s+/)[1..3].map{|v| v.to_f}
21
+ brgb = line.split(/[\s\/]+/)[1..3].map(&:to_f)
28
22
  when /\AF\s/
29
- frgb = line.split(/\s+/)[1..3].map{|v| v.to_f}
23
+ frgb = line.split(/[\s\/]+/)[1..3].map(&:to_f)
30
24
  else
31
- list << line.lstrip.split(/\s+/)[0..3].map{|v| v.to_f}
32
- last = line.lstrip.split(/\s+/)[4..7].map{|v| v.to_f}
25
+ list << line.split(/[\s\/]+/)[0..3].map(&:to_f)
26
+ last = line.split(/[\s\/]+/)[4..7].map(&:to_f)
33
27
  end
34
28
  end
35
29
  list << last
@@ -38,49 +32,32 @@ class GrADS::Command
38
32
  ccols = []
39
33
  ic = 16
40
34
  if brgb
41
- if model == "HSV"
42
- set :rgb, ic, *_hsv2rgb(*brgb)
43
- else
44
- set :rgb, ic, *brgb
45
- end
35
+ set :rgb, ic, *brgb.map(&:round)
46
36
  ccols << ic
47
37
  else
48
- ccols << 0
38
+ ccols << -1
49
39
  end
50
40
  ic += 1
51
41
  list.each_with_index do |(v,r,g,b),i|
52
- if model == "HSV"
53
- set :rgb, i+ic, *_hsv2rgb(r, g, b)
54
- else
55
- set :rgb, i+ic, r, g, b
56
- end
42
+ set :rgb, i+ic, r.round, g.round, b.round
57
43
  clevs << v
58
44
  if ! frgb and i == list.size - 1
59
- ccols << 0
45
+ ccols << -1
60
46
  else
61
47
  ccols << i+ic
62
48
  end
63
49
  end
64
50
  ic += list.size - 1
65
51
  if frgb
66
- if model == "HSV"
67
- set :rgb, ic, *_hsv2rgb(*frgb)
68
- else
69
- set :rgb, ic, *frgb
70
- end
52
+ set :rgb, ic, *frgb.map(&:round)
71
53
  end
72
54
  set_clevs *clevs
73
55
  set_ccols *ccols
56
+ return clevs, ccols
74
57
  end
75
58
 
76
59
  def makecpt (*args)
77
- io = IO::popen("makecpt #{args.join(' ')}", "r")
78
- while line = io.gets
79
- if line =~ /COLOR_MODEL\s*=\s*\+?(HSV|RGB)/
80
- model = $1
81
- break
82
- end
83
- end
60
+ io = IO::popen("makecpt -Fr #{args.join(' ')}", "r")
84
61
  bgrb = nil
85
62
  frgb = nil
86
63
  list = []
@@ -89,12 +66,12 @@ class GrADS::Command
89
66
  when /\A[\#N]/
90
67
  next
91
68
  when /\AB\s/
92
- brgb = line.split(/\s+/)[1..3].map{|v| v.to_f}
69
+ brgb = line.split(/[\s\/]/)[1..3].map(&:to_f)
93
70
  when /\AF\s/
94
- frgb = line.split(/\s+/)[1..3].map{|v| v.to_f}
71
+ frgb = line.split(/[\s\/]/)[1..3].map(&:to_f)
95
72
  else
96
- list << line.split(/\s+/)[0..3].map{|v| v.to_f}
97
- last = line.split(/\s+/)[4..7].map{|v| v.to_f}
73
+ list << line.split(/[\s\/]/)[0..3].map(&:to_f)
74
+ last = line.split(/[\s\/]/)[4..7].map(&:to_f)
98
75
  end
99
76
  end
100
77
  list << last
@@ -103,39 +80,28 @@ class GrADS::Command
103
80
  ccols = []
104
81
  ic = 16
105
82
  if brgb
106
- if model == "HSV"
107
- set :rgb, ic, *_hsv2rgb(*brgb)
108
- else
109
- set :rgb, ic, *brgb
110
- end
83
+ set :rgb, ic, *brgb.map(&:round)
111
84
  ccols << ic
112
85
  else
113
- ccols << 0
86
+ ccols << -1
114
87
  end
115
88
  ic += 1
116
89
  list.each_with_index do |(v,r,g,b),i|
117
- if model == "HSV"
118
- set :rgb, i+ic, *_hsv2rgb(r, g, b)
119
- else
120
- set :rgb, i+ic, r, g, b
121
- end
90
+ set :rgb, i+ic, r.round, g.round, b.round
122
91
  clevs << v
123
92
  if ! frgb and i == list.size - 1
124
- ccols << 0
93
+ ccols << -1
125
94
  else
126
95
  ccols << i+ic
127
96
  end
128
97
  end
129
98
  ic += list.size - 1
130
99
  if frgb
131
- if model == "HSV"
132
- set :rgb, ic, *_hsv2rgb(*frgb)
133
- else
134
- set :rgb, ic, *frgb
135
- end
100
+ set :rgb, ic, *frgb.map(&:round)
136
101
  end
137
102
  set_clevs *clevs
138
103
  set_ccols *ccols
104
+ return clevs, ccols
139
105
  end
140
106
 
141
107
  def _hsv2rgb(h, s, v)
data/ruby-grads.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  Gem::Specification::new do |s|
3
- version = "1.0.3"
3
+ version = "1.0.6"
4
4
 
5
5
  files = Dir.glob("**/*") - [
6
6
  Dir.glob("ruby-grads*.gem"),
@@ -18,5 +18,6 @@ Gem::Specification::new do |s|
18
18
  s.homepage = 'https://github.com/himotoyoshi/ruby-grads'
19
19
  s.files = files
20
20
  # s.extensions = [ "extconf.rb" ]
21
+ s.executables << 'ncdef2ctl'
21
22
  s.required_ruby_version = ">= 1.8.1"
22
23
  end
@@ -0,0 +1,23 @@
1
+
2
+ Gem::Specification::new do |s|
3
+ version = "1.0.5"
4
+
5
+ files = Dir.glob("**/*") - [
6
+ Dir.glob("ruby-grads*.gem"),
7
+ ].flatten
8
+
9
+ s.platform = Gem::Platform::RUBY
10
+ s.name = "ruby-grads"
11
+ s.summary = "Library for driving GrADS from Ruby"
12
+ s.description = <<-HERE
13
+ Library for driving GrADS from Ruby
14
+ HERE
15
+ s.version = version
16
+ s.author = "Hiroki Motoyoshi"
17
+ s.email = ""
18
+ s.homepage = 'https://github.com/himotoyoshi/ruby-grads'
19
+ s.files = files
20
+ # s.extensions = [ "extconf.rb" ]
21
+ s.executables << 'ncdef2ctl'
22
+ s.required_ruby_version = ">= 1.8.1"
23
+ end
metadata CHANGED
@@ -1,32 +1,37 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-grads
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroki Motoyoshi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-07 00:00:00.000000000 Z
11
+ date: 2021-02-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: " Library for driving GrADS from Ruby\n"
14
14
  email: ''
15
- executables: []
15
+ executables:
16
+ - ncdef2ctl
16
17
  extensions: []
17
18
  extra_rdoc_files: []
18
19
  files:
19
20
  - README.md
21
+ - Rakefile
22
+ - bin/ncdef2ctl
20
23
  - extconf.rb
21
24
  - lib/grads.rb
22
25
  - lib/grads/binary.rb
23
26
  - lib/grads/command.rb
24
27
  - lib/grads/gridded.rb
28
+ - lib/grads/lib/axis_xtime.rb
25
29
  - lib/grads/lib/colorbar.rb
26
30
  - lib/grads/lib/makecpt.rb
27
31
  - lib/grads/lib/save_image.rb
28
32
  - lib/grads/lib/xcbar_with_ccols.rb
29
33
  - ruby-grads.gemspec
34
+ - ruby-grads.gemspec~
30
35
  - test/gradsdraw.rb
31
36
  - test/test.rb
32
37
  homepage: https://github.com/himotoyoshi/ruby-grads
@@ -47,8 +52,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
47
52
  - !ruby/object:Gem::Version
48
53
  version: '0'
49
54
  requirements: []
50
- rubyforge_project:
51
- rubygems_version: 2.7.7
55
+ rubygems_version: 3.1.2
52
56
  signing_key:
53
57
  specification_version: 4
54
58
  summary: Library for driving GrADS from Ruby