1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.models.earth;
18
19 import java.util.Collection;
20 import java.util.NavigableMap;
21 import java.util.SortedMap;
22 import java.util.TreeMap;
23
24 import org.hipparchus.util.FastMath;
25 import org.orekit.data.DataProvidersManager;
26 import org.orekit.errors.OrekitException;
27 import org.orekit.errors.OrekitMessages;
28 import org.orekit.models.earth.GeoMagneticFieldFactory.FieldModel;
29
30
31
32
33
34
35
36
37
38 public class LazyLoadedGeoMagneticFields implements GeoMagneticFields {
39
40
41 private NavigableMap<Integer, GeoMagneticField> igrfModels = null;
42
43
44 private NavigableMap<Integer, GeoMagneticField> wmmModels = null;
45
46
47 private final DataProvidersManager dataProvidersManager;
48
49
50
51
52
53
54
55 public LazyLoadedGeoMagneticFields(final DataProvidersManager dataProvidersManager) {
56 this.dataProvidersManager = dataProvidersManager;
57 }
58
59 @Override
60 public GeoMagneticField getField(final FieldModel type, final double year) {
61 switch (type) {
62 case WMM:
63 return getWMM(year);
64 case IGRF:
65 return getIGRF(year);
66 default:
67 throw new OrekitException(OrekitMessages.NON_EXISTENT_GEOMAGNETIC_MODEL, type.name(), year);
68 }
69 }
70
71 @Override
72 public GeoMagneticField getIGRF(final double year) {
73 synchronized (this) {
74 if (igrfModels == null) {
75 igrfModels = loadModels("^IGRF\\.COF$");
76 }
77 return getModel(FieldModel.IGRF, igrfModels, year);
78 }
79 }
80
81 @Override
82 public GeoMagneticField getWMM(final double year) {
83 synchronized (this) {
84 if (wmmModels == null) {
85 wmmModels = loadModels("^WMM\\.COF$");
86 }
87 return getModel(FieldModel.WMM, wmmModels, year);
88 }
89 }
90
91
92
93
94
95
96
97 private NavigableMap<Integer, GeoMagneticField> loadModels(final String supportedNames) {
98
99 NavigableMap<Integer, GeoMagneticField> loadedModels = null;
100 final GeoMagneticModelLoader loader = new GeoMagneticModelLoader();
101 dataProvidersManager.feed(supportedNames, loader);
102
103 if (!loader.stillAcceptsData()) {
104 final Collection<GeoMagneticField> models = loader.getModels();
105 if (models != null) {
106 loadedModels = new TreeMap<>();
107 for (GeoMagneticField model : models) {
108
109 final int epoch = (int) FastMath.round(model.getEpoch() * 100d);
110 loadedModels.put(epoch, model);
111 }
112 }
113 }
114
115
116 if (loadedModels == null || loadedModels.size() == 0) {
117 throw new OrekitException(OrekitMessages.UNABLE_TO_FIND_RESOURCE, supportedNames);
118 }
119
120 return loadedModels;
121 }
122
123
124
125
126
127
128
129
130
131
132 private static GeoMagneticField getModel(final FieldModel type,
133 final NavigableMap<Integer, GeoMagneticField> models,
134 final double year) {
135
136 final int epochKey = (int) (year * 100d);
137 final SortedMap<Integer, GeoMagneticField> head = models.headMap(epochKey, true);
138
139 if (head.isEmpty()) {
140 throw new OrekitException(OrekitMessages.NON_EXISTENT_GEOMAGNETIC_MODEL, type.name(), year);
141 }
142
143 GeoMagneticField model = models.get(head.lastKey());
144 if (model.getEpoch() < year) {
145 if (model.supportsTimeTransform()) {
146 model = model.transformModel(year);
147 } else {
148 final SortedMap<Integer, GeoMagneticField> tail = models.tailMap(epochKey, false);
149 if (tail.isEmpty()) {
150 throw new OrekitException(OrekitMessages.NON_EXISTENT_GEOMAGNETIC_MODEL, type.name(), year);
151 }
152 final GeoMagneticField secondModel = models.get(tail.firstKey());
153 if (secondModel != model) {
154 model = model.transformModel(secondModel, year);
155 }
156 }
157 }
158 return model;
159 }
160
161 }