ruby-grads 1.0.3 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
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