gps_pvt 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,248 @@
1
+ /*
2
+ * Copyright (c) 2022, M.Naruoka (fenrir)
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without modification,
6
+ * are permitted provided that the following conditions are met:
7
+ *
8
+ * - Redistributions of source code must retain the above copyright notice,
9
+ * this list of conditions and the following disclaimer.
10
+ * - Redistributions in binary form must reproduce the above copyright notice,
11
+ * this list of conditions and the following disclaimer in the documentation
12
+ * and/or other materials provided with the distribution.
13
+ * - Neither the name of the naruoka.org nor the names of its contributors
14
+ * may be used to endorse or promote products derived from this software
15
+ * without specific prior written permission.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
21
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
22
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ *
30
+ */
31
+
32
+ /** @file
33
+ * @brief Helper class/functions for text processing
34
+ *
35
+ */
36
+
37
+ #ifndef __TEXT_HELPER_H__
38
+ #define __TEXT_HELPER_H__
39
+
40
+ #include <istream>
41
+ #include <ostream>
42
+ #include <sstream>
43
+ #include <string>
44
+ #include <iomanip>
45
+ #include <ctime>
46
+ #include <cstddef>
47
+ #include <cstring>
48
+ #include <limits>
49
+
50
+ template <class U = void>
51
+ struct TextHelper {
52
+ struct crlf_stream_t : public std::istream {
53
+ crlf_stream_t(std::istream &is) : std::istream(is.rdbuf()) {}
54
+ /**
55
+ * getline() for multi-platform (in addition to \n, \r\n and \r are supported)
56
+ *
57
+ * @see https://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf
58
+ * @see https://en.cppreference.com/w/cpp/io/basic_istream/getline
59
+ * TODO gcount() mismatch
60
+ */
61
+ std::istream& getline(
62
+ typename std::istream::char_type* s,
63
+ std::streamsize n){
64
+ std::streamsize i(1), consumed(0);
65
+ typename std::istream::sentry se(*this, true);
66
+ if((bool)se){
67
+ std::streambuf* sb(this->rdbuf());
68
+ for(; i < n; ++i){
69
+ int c(sb->sbumpc());
70
+ if(c == std::streambuf::traits_type::eof()){
71
+ this->setstate(std::ios::eofbit);
72
+ break;
73
+ }
74
+ ++consumed;
75
+ if(c == '\n'){
76
+ break;
77
+ }else if(c == '\r'){
78
+ if(sb->sgetc() == '\n'){
79
+ sb->sbumpc();
80
+ ++consumed;
81
+ }
82
+ break;
83
+ }
84
+ *(s++) = (typename std::istream::char_type)c;
85
+ }
86
+ }
87
+ if(((i == 1) && (consumed == 0)) || (i == n)){
88
+ this->setstate(std::ios::failbit);
89
+ }else{
90
+ *s = '\0';
91
+ }
92
+ return *this;
93
+ }
94
+ };
95
+
96
+ template <class T, bool is_integer = std::numeric_limits<T>::is_integer>
97
+ struct format_t {
98
+ static bool d(
99
+ std::string &buf, const int &offset, const int &length, void *value, const int &opt = 0, const bool &str2val = true){
100
+ if(str2val){
101
+ std::stringstream ss(buf.substr(offset, length));
102
+ ss >> *(T *)value;
103
+ return (ss.rdstate() & std::ios_base::failbit) == 0;
104
+ }else{
105
+ std::stringstream ss;
106
+ ss << std::setfill(opt == 1 ? '0' : ' ') << std::right << std::setw(length) << *(T *)value;
107
+ buf.replace(offset, length, ss.str());
108
+ return true;
109
+ }
110
+ }
111
+ static bool d_blank(
112
+ std::string &buf, const int &offset, const int &length, void *value,
113
+ const int &opt = 0, const bool &str2val = true){
114
+ if((!str2val) && (*(T *)value == 0)){return true;}
115
+ return d(buf, offset, length, value, opt, str2val);
116
+ }
117
+ static bool f(
118
+ std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
119
+ if(str2val){
120
+ std::stringstream ss(buf.substr(offset, length));
121
+ ss >> *(T *)value;
122
+ return (ss.rdstate() & std::ios_base::failbit) == 0;
123
+ }else{
124
+ std::stringstream ss;
125
+ ss << std::setfill(' ') << std::right << std::setw(length)
126
+ << std::setprecision(precision) << std::fixed
127
+ << *(T *)value;
128
+ buf.replace(offset, length, ss.str());
129
+ return true;
130
+ }
131
+ }
132
+ static bool f_dot_head(
133
+ std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
134
+ bool res(f(buf, offset, length, value, precision, str2val));
135
+ if((!str2val) && res){
136
+ if((*(T *)value) >= 0){
137
+ if((*(T *)value) < 1){
138
+ int i(length - precision - 2);
139
+ // 0.12345 => .12345
140
+ if(i >= 0){buf[i + offset] = ' ';}
141
+ }
142
+ }else{
143
+ if((*(T *)value) > -1){
144
+ int i(length - precision - 2);
145
+ // -0.12345 => -.12345
146
+ if(i >= 0){buf[i + offset] = '-';}
147
+ if(--i >= 0){buf[i + offset] = ' ';}
148
+ }
149
+ }
150
+ }
151
+ return res;
152
+ }
153
+ };
154
+ template <class T>
155
+ struct format_t<T, true> : public format_t<T, false> {
156
+ static bool f(
157
+ std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
158
+ double v(*(T *)value);
159
+ bool res(
160
+ format_t<double, false>::f(buf, offset, length, &v, precision, str2val));
161
+ *(T *)value = static_cast<T>(v);
162
+ return res;
163
+ }
164
+ static bool f_dot_head(
165
+ std::string &buf, const int &offset, const int &length, void *value, const int &precision = 0, const bool &str2val = true){
166
+ double v(*(T *)value);
167
+ bool res(
168
+ format_t<double, false>::f_dot_head(buf, offset, length, &v, precision, str2val));
169
+ *(T *)value = static_cast<T>(v);
170
+ return res;
171
+ }
172
+ };
173
+
174
+ struct convert_item_t {
175
+ bool (*func)(
176
+ std::string &buf, const int &offset, const int &length, void *value,
177
+ const int &opt, const bool &str2val);
178
+ int offset;
179
+ int length;
180
+ int value_offset;
181
+ int opt;
182
+ };
183
+
184
+ /**
185
+ * @param recovery if conversion fails, then this functor is invoked.
186
+ * If recovery is successfully performed, this functor should return true.
187
+ * The return value of this function reflects it.
188
+ * @return (bool) if all conversion are successfully performed, true is returned; otherwise false.
189
+ */
190
+ static bool str2val(
191
+ const convert_item_t *items, const int &size, const std::string &buf, void *values,
192
+ bool (*recovery)(const int &, const std::string &, void *) = NULL){
193
+ // str => value
194
+ bool res(true);
195
+ for(int i(0); i < size; ++i){
196
+ if((*items[i].func)(
197
+ const_cast<std::string &>(buf), items[i].offset, items[i].length, (char *)values + items[i].value_offset,
198
+ items[i].opt, true)){continue;}
199
+ res &= (recovery ? (*recovery)(i, buf, values) : false);
200
+ }
201
+ return res;
202
+ }
203
+ template <int N>
204
+ static inline bool str2val(
205
+ const convert_item_t (&items)[N], const std::string &buf, void *values,
206
+ bool (*recovery)(const int &, const std::string &, void *) = NULL){
207
+ return str2val(items, N, buf, values, recovery);
208
+ }
209
+
210
+ /**
211
+ * @return If all conversion are successfully performed, then true; otherwise false;
212
+ */
213
+ static bool val2str(
214
+ const convert_item_t *items, const int &size,
215
+ std::string &buf, const void *values){
216
+ // value => string
217
+ bool res(true);
218
+ for(int i(0); i < size; ++i){
219
+ res &= (*items[i].func)(
220
+ buf, items[i].offset, items[i].length, (char *)(const_cast<void *>(values)) + items[i].value_offset,
221
+ items[i].opt, false);
222
+ }
223
+ return res;
224
+ }
225
+ template <int N>
226
+ static inline bool val2str(
227
+ const convert_item_t (&items)[N], std::string &buf, const void *values){
228
+ return val2str(items, N, buf, values);
229
+ }
230
+ };
231
+
232
+ template <>
233
+ template <>
234
+ struct TextHelper<>::format_t<char, false> {
235
+ static bool c(
236
+ std::string &buf, const int &offset, const int &length, void *value,
237
+ const int &opt = 0, const bool &str2val = true){
238
+ if(str2val){
239
+ return buf.copy(static_cast<char *>(value), length, offset) == (std::size_t)length;
240
+ }else{
241
+ if((length <= 0) || (!(static_cast<char *>(value)[0]))){return true;}
242
+ buf.replace(offset, length, static_cast<char *>(value), length);
243
+ return true;
244
+ }
245
+ }
246
+ };
247
+
248
+ #endif /* __TEXT_HELPER__ */
@@ -627,5 +627,29 @@ class Receiver
627
627
  }
628
628
  $stderr.puts ", %d epochs."%[count]
629
629
  end
630
+
631
+ def attach_sp3(src)
632
+ fname = Util::get_txt(src)
633
+ @sp3 ||= GPS::SP3::new
634
+ read_items = @sp3.read(fname)
635
+ raise "Format error! (Not SP3) #{src}" if read_items < 0
636
+ $stderr.puts "Read SP3 file (%s): %d items."%[src, read_items]
637
+ sats = @sp3.satellites
638
+ @sp3.class.constants.each{|sys|
639
+ next unless /^SYS_(?!SYSTEMS)(.*)/ =~ sys.to_s
640
+ idx, sys_name = [@sp3.class.const_get(sys), $1]
641
+ next unless sats[idx] > 0
642
+ next unless @sp3.push(@solver, idx)
643
+ $stderr.puts "Change ephemeris source of #{sys_name} to SP3"
644
+ }
645
+ end
646
+
647
+ def attach_antex(src)
648
+ fname = Util::get_txt(src)
649
+ raise "Specify SP3 before ANTEX application!" unless @sp3
650
+ applied_items = @sp3.apply_antex(fname)
651
+ raise "Format error! (Not ANTEX) #{src}" unless applied_items >= 0
652
+ $stderr.puts "SP3 correction with ANTEX file (%s): %d items have been processed."%[src, applied_items]
653
+ end
630
654
  end
631
655
  end
data/lib/gps_pvt/util.rb CHANGED
@@ -1,27 +1,45 @@
1
1
  require 'open-uri'
2
2
  require 'tempfile'
3
3
  require 'uri'
4
- require 'zlib'
5
4
 
6
5
  module GPS_PVT
7
6
  module Util
8
7
  class << self
9
- def inflate(src)
10
- Zlib::GzipReader.send(*(src.kind_of?(IO) ? [:new, src] : [:open, src]))
8
+ def inflate(src, type = :gz)
9
+ case type
10
+ when :gz
11
+ require 'zlib'
12
+ Zlib::GzipReader.send(*(src.kind_of?(IO) ? [:new, src] : [:open, src]))
13
+ when :Z
14
+ res = IO::popen("uncompress -c #{src.kind_of?(IO) ? '-' : src}", 'r+')
15
+ res.print(src.read) if src.kind_of?(IO)
16
+ res.close_write
17
+ res
18
+ else
19
+ raise "Unknown compression type: #{type} of #{src}"
20
+ end
11
21
  end
12
22
  def get_txt(fname_or_uri)
13
23
  is_uri = fname_or_uri.kind_of?(URI)
14
24
  ((is_uri && (RUBY_VERSION >= "2.5.0")) ? URI : Kernel) \
15
25
  .send(:open, fname_or_uri){|src|
16
- is_gz = (src.content_type =~ /gzip/) if is_uri
17
- is_gz ||= (fname_or_uri.to_s =~ /\.gz$/)
26
+ compressed = proc{
27
+ case src.content_type
28
+ when /gzip/; next :gz
29
+ end if is_uri
30
+ case fname_or_uri.to_s
31
+ when /\.gz$/; next :gz
32
+ when /\.Z$/; next :Z
33
+ end
34
+ nil
35
+ }.call
18
36
  is_file = src.kind_of?(File) || src.kind_of?(Tempfile)
19
37
 
20
- return src.path if ((!is_gz) and is_file)
38
+ return src.path if ((!compressed) and is_file)
21
39
 
22
40
  Tempfile::open(File::basename($0, '.*')){|dst|
23
41
  dst.binmode
24
- dst.write((is_gz ? inflate(is_file ? src.path : src) : src).read)
42
+ dst.write((compressed ? inflate(is_file ? src.path : src, compressed) : src).read)
25
43
  dst.rewind
26
44
  dst.path
27
45
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GPS_PVT
4
- VERSION = "0.5.1"
4
+ VERSION = "0.6.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gps_pvt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - fenrir(M.Naruoka)
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-07 00:00:00.000000000 Z
11
+ date: 2022-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -62,6 +62,8 @@ files:
62
62
  - ext/gps_pvt/SylphideMath/SylphideMath_wrap.cxx
63
63
  - ext/gps_pvt/extconf.rb
64
64
  - ext/ninja-scan-light/tool/algorithm/integral.h
65
+ - ext/ninja-scan-light/tool/algorithm/interpolate.h
66
+ - ext/ninja-scan-light/tool/navigation/ANTEX.h
65
67
  - ext/ninja-scan-light/tool/navigation/EGM.h
66
68
  - ext/ninja-scan-light/tool/navigation/GLONASS.h
67
69
  - ext/ninja-scan-light/tool/navigation/GLONASS_Solver.h
@@ -76,6 +78,7 @@ files:
76
78
  - ext/ninja-scan-light/tool/navigation/RINEX.h
77
79
  - ext/ninja-scan-light/tool/navigation/SBAS.h
78
80
  - ext/ninja-scan-light/tool/navigation/SBAS_Solver.h
81
+ - ext/ninja-scan-light/tool/navigation/SP3.h
79
82
  - ext/ninja-scan-light/tool/navigation/WGS84.h
80
83
  - ext/ninja-scan-light/tool/navigation/coordinate.h
81
84
  - ext/ninja-scan-light/tool/param/bit_array.h
@@ -92,6 +95,7 @@ files:
92
95
  - ext/ninja-scan-light/tool/swig/makefile
93
96
  - ext/ninja-scan-light/tool/swig/spec/GPS_spec.rb
94
97
  - ext/ninja-scan-light/tool/swig/spec/SylphideMath_spec.rb
98
+ - ext/ninja-scan-light/tool/util/text_helper.h
95
99
  - gps_pvt.gemspec
96
100
  - gps_pvt.rbs
97
101
  - lib/gps_pvt.rb