Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
RestfulSpice.cpp
1
2// #include <iostream>
3// #include <Preference.h>
4// #include "spiceql.h"
5// #include "restincurl.h"
6// #include <string>
7
8// using json=nlohmann::json;
9
10// namespace SpiceQL{
11// std::map<std::string, std::string> spiceql_mission_map = {
12// {"AMICA", "amica"},
13// {"CHANDRAYAAN-1_M3", "m3"},
14// {"CHANDRAYAAN-1_MRFFR", "mrffr"},
15// {"CASSINI_ISS_NAC", "cassini"},
16// {"CASSINI_ISS_WAC", "cassini"},
17// {"DAWN_FC2_FILTER_1", "fc2"},
18// {"DAWN_FC2_FILTER_2", "fc2"},
19// {"DAWN_FC2_FILTER_3", "fc2"},
20// {"DAWN_FC2_FILTER_4", "fc2"},
21// {"DAWN_FC2_FILTER_5", "fc2"},
22// {"DAWN_FC2_FILTER_6", "fc2"},
23// {"DAWN_FC2_FILTER_7", "fc2"},
24// {"DAWN_FC2_FILTER_8", "fc2"},
25// {"GLL_SSI_PLATFORM", "galileo"},
26// {"HAYABUSA_AMICA", "amica"},
27// {"HAYABUSA_NIRS", "nirs"},
28// {"HAYABUSA2_ONC-W2", ""},
29// {"JUNO_JUNOCAM", "juno"},
30// {"JUPITER", "voyager1"},
31// {"LRO_LROCNACL", "lroc"},
32// {"LRO_LROCNACR", "lroc"},
33// {"LRO_LROCWAC_UV", "lroc"},
34// {"LRO_LROCWAC_VIS", "lroc"},
35// {"LRO_MINIRF", ""},
36// {"M10_VIDICON_A", "m10_vidicon_a"},
37// {"M10_VIDICON_B", "m10_vidicon_b"},
38// {"MARS", "mro"},
39// {"MSGR_MDIS_WAC", "mdis"},
40// {"MSGR_MDIS_NAC", "mdis"},
41// {"MEX_HRSC_SRC", "src"},
42// {"MEX_HRSC_IR", "hrsc"},
43// {"MGS_MOC_NA", "mgs"},
44// {"MGS_MOC_WA_RED", "mgs"},
45// {"MGS_MOC_WA_BLUE", "mgs"},
46// {"MOON", "apollo15"},
47// {"MRO_MARCI_VIS", "marci"},
48// {"MRO_MARCI_UV", "marci"},
49// {"MRO_CTX", "ctx"},
50// {"MRO_HIRISE", "hirise"},
51// {"MRO_CRISM_VNIR", "crism"},
52// {"NEAR EARTH ASTEROID RENDEZVOUS", ""},
53// {"MSL_MASTCAM_RIGHT", ""},
54// {"MSL_MASTCAM_LEFT", ""},
55// {"NH_LORRI", "lorri"},
56// {"NH_RALPH_LEISA", "leisa"},
57// {"NH_MVIC", "mvic_tdi"},
58// {"ISIS_NH_RALPH_MVIC_METHANE", "mvic_framing"},
59// {"THEMIS_IR", "odyssey"},
60// {"THEMIS_VIS", "odyssey"},
61// {"ORX_OCAMS_MAPCAM", ""},
62// {"ORX_OCAMS_POLYCAM", ""},
63// {"ORX_OCAMS_SAMCAM", ""},
64// {"LISM_MI-VIS1", "kaguya"},
65// {"LISM_MI-VIS2", "kaguya"},
66// {"LISM_MI-VIS3", "kaguya"},
67// {"LISM_MI-VIS4", "kaguya"},
68// {"LISM_MI-VIS5", "kaguya"},
69// {"LISM_MI-NIR1", "kaguya"},
70// {"LISM_MI-NIR2", "kaguya"},
71// {"LISM_MI-NIR3", "kaguya"},
72// {"LISM_MI-NIR4", "kaguya"},
73// {"LISM_TC1_WDF", "kaguya"},
74// {"LISM_TC1_WTF", "kaguya"},
75// {"LISM_TC1_SDF", "kaguya"},
76// {"LISM_TC1_STF", "kaguya"},
77// {"LISM_TC1_WDN", "kaguya"},
78// {"LISM_TC1_WTN", "kaguya"},
79// {"LISM_TC1_SDN", "kaguya"},
80// {"LISM_TC1_STN", "kaguya"},
81// {"LISM_TC1_WDH", "kaguya"},
82// {"LISM_TC1_WTH", "kaguya"},
83// {"LISM_TC1_SDH", "kaguya"},
84// {"LISM_TC1_STH", "kaguya"},
85// {"LISM_TC1_SSH", "kaguya"},
86// {"LO1_HIGH_RESOLUTION_CAMERA", ""},
87// {"LO2_HIGH_RESOLUTION_CAMERA", ""},
88// {"LO3_HIGH_RESOLUTION_CAMERA", ""},
89// {"LO4_HIGH_RESOLUTION_CAMERA", ""},
90// {"LO5_HIGH_RESOLUTION_CAMERA", ""},
91// {"NEPTUNE", "voyager1"},
92// {"SATURN", "voyager1"},
93// {"TGO_CASSIS", "cassis"},
94// {"VIKING ORBITER 1", "viking1"},
95// {"VIKING ORBITER 2", "viking2"},
96// {"VG1_ISSNA", ""},
97// {"VG1_ISSWA", ""},
98// {"VG2_ISSNA", ""},
99// {"VG2_ISSWA", ""},
100// {"ULTRAVIOLET/VISIBLE CAMERA", "uvvis"},
101// {"Near Infrared Camera", "nir"},
102// {"High Resolution Camera", "clementine1"},
103// {"Long Wave Infrared Camera", "clementine1"},
104// {"Visual and Infrared Spectrometer", "vir"}
105// };
106
107
108// std::vector<std::vector<double>> getTargetStates(std::vector<double> ets, std::string target, std::string observer, std::string frame, std::string abcorr, std::string mission, std::string ckQuality, std::string spkQuality, std::vector<std::string> kernel_list){
109// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
110// if (useWeb){
111// // @TODO validity checks
112// json args = json::object({
113// {"target", target},
114// {"observer", observer},
115// {"frame", frame},
116// {"abcorr", abcorr},
117// {"ets", ets},
118// {"mission", mission},
119// {"ckQuality", ckQuality},
120// {"spkQuality", spkQuality}
121// });
122// // @TODO check that json exists / contains what we're looking for
123// json out = spiceAPIQuery("getTargetStates", args);
124// return out["body"]["return"].get<std::vector<std::vector<double>>>();
125// } else {
126// return SpiceQL::getTargetStates(ets, target, observer, frame, abcorr, mission, ckQuality, spkQuality, true, kernel_list);
127// }
128// }
129
130
131// std::vector<std::vector<double>> getTargetOrientations(std::vector<double> ets, int toFrame, int refFrame, std::string mission, std::string ckQuality) {
132// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
133// if (useWeb){
134// json args = json::object({
135// {"ets", ets},
136// {"toFrame", toFrame},
137// {"refFrame", refFrame},
138// {"mission", mission},
139// {"ckQuality", ckQuality}
140// });
141// json out = spiceAPIQuery("getTargetOrientations", args);
142// return out["body"]["return"].get<std::vector<std::vector<double>>>();
143// } else {
144// return SpiceQL::getTargetOrientations(ets, toFrame, refFrame, mission, ckQuality, true);
145// }
146// }
147
148// double strSclkToEt(int frameCode, std::string sclk, std::string mission) {
149// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
150// if (useWeb){
151// json args = json::object({
152// {"frameCode", frameCode},
153// {"sclk", sclk},
154// {"mission", mission}
155// });
156// json out = spiceAPIQuery("strSclkToEt", args);
157// return out["body"]["return"].get<double>();
158// }else{
159// return SpiceQL::strSclkToEt(frameCode, sclk, mission, true);
160// }
161// }
162
163// double doubleSclkToEt(int frameCode, double sclk, std::string mission){
164// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
165// if (useWeb){
166// json args = json::object({
167// {"frameCode", frameCode},
168// {"sclk", sclk},
169// {"mission", mission}
170// });
171// json out = spiceAPIQuery("doubleSclkToEt", args);
172// return out["body"]["return"].get<double>();
173// }else{
174// return SpiceQL::doubleSclkToEt(frameCode, sclk, mission, true);
175// }
176// }
177
178// double utcToEt(std::string utc){
179// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
180// if (useWeb){
181// json args = json::object({
182// {"utc", utc}
183// });
184// json out = spiceAPIQuery("utcToEt", args);
185// return out["body"]["return"].get<double>();
186
187// }else{
188// return SpiceQL::utcToEt(utc, true);
189// }
190// }
191
192
193// std::string etToUtc(double et, std::string format, double precision){
194// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
195// // TODO Add etToUtc to web api
196// if (useWeb){
197// json args = json::object({
198// {"et", et},
199// {"format", format},
200// {"precision", precision}
201// });
202// json out = spiceAPIQuery("etToUtc", args);
203// return out["body"]["return"].get<std::string>();
204// }else{
205// return SpiceQL::etToUtc(et, format, precision, true);
206// }
207// }
208
209// std::string doubleEtToSclk(int frameCode, double et, std::string mission) {
210// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
211// if (useWeb){
212// json args = json::object({
213// {"frameCode", frameCode},
214// {"et", et},
215// {"mission", mission}
216// });
217// json out = spiceAPIQuery("doubleEtToSclk", args);
218// return out["body"]["return"].get<std::string>();
219// }else{
220// return SpiceQL::doubleEtToSclk(frameCode, et, mission, true);
221// }
222
223// }
224
225// int translateNameToCode(std::string frame, std::string mission){
226// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
227// if (useWeb){
228// json args = json::object({
229// {"frame", frame},
230// {"mission", mission}
231// });
232// json out = spiceAPIQuery("translateNameToCode", args);
233// return out["body"]["return"].get<int>();
234// }else{
235// return SpiceQL::translateNameToCode(frame, mission, true);
236// }
237// }
238
239// std::string translateCodeToName(int code, std::string mission){
240// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
241// if (useWeb){
242// json args = json::object({
243// {"code", code},
244// {"mission", mission}
245// });
246// json out = spiceAPIQuery("translateCodeToame", args);
247// return out["body"]["return"].get<std::string>();
248// }else{
249// return SpiceQL::translateCodeToName(code, mission, true);
250// }
251// }
252
253// std::vector<int> getFrameInfo(int frame, std::string mission) {
254// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
255// if (useWeb){
256// json args = json::object({
257// {"frame", frame},
258// {"mission", mission}
259// });
260// json out = spiceAPIQuery("getFrameInfo", args);
261// return out["body"]["return"].get<std::vector<int>>();
262
263// }else{
264// return SpiceQL::getFrameInfo(frame, mission, true);
265// }
266// }
267
268// json getTargetFrameInfo(int targetId, std::string mission) {
269// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
270// if (useWeb){
271// json args = json::object({
272// {"targetId", targetId},
273// {"mission", mission}
274// });
275// json out = spiceAPIQuery("getTargetFrameInfo", args);
276// return out["body"]["return"];
277// }else{
278// return SpiceQL::getTargetFrameInfo(targetId, mission, true);
279// }
280// }
281
282// json findMissionKeywords(std::string key, std::string mission){
283// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
284// if (useWeb){
285// json args = json::object({
286// {"key", key},
287// {"mission", mission}
288// });
289// json out = spiceAPIQuery("findMissionKeywords", args);
290// return out["body"]["return"];
291// }else{
292// return SpiceQL::findMissionKeywords(key, mission, true);
293// }
294// }
295
296// json findTargetKeywords(std::string key, std::string mission){
297// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
298// if (useWeb){
299// json args = json::object({
300// {"key", key},
301// {"mission", mission}
302// });
303// json out = spiceAPIQuery("findTargetKeywords", args);
304// return out["body"]["return"];
305// }else{
306// return SpiceQL::findTargetKeywords(key, mission, true);
307// }
308// }
309
310// std::vector<std::vector<int>> frameTrace(double et, int initialFrame, std::string mission, std::string ckQuality) {
311// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
312// if (useWeb){
313// json args = json::object({
314// {"et", et},
315// {"initialFrame", initialFrame},
316// {"mission", mission},
317// {"ckQuality", ckQuality}
318// });
319// json out = spiceAPIQuery("frameTrace", args);
320// return out["body"]["return"].get<std::vector<std::vector<int>>>();
321// }else{
322// return SpiceQL::frameTrace(et, initialFrame, mission, ckQuality, true);
323// }
324// }
325
326// std::vector<double> extractExactCkTimes(double observStart, double observEnd, int targetFrame, std::string mission, std::string ckQuality) {
327// bool useWeb = QString(Preference::Preferences().findGroup("SpiceQL")["UseSpiceQL"]).toUpper() == "TRUE";
328// if (useWeb){
329// json args = json::object({
330// {"observStart", observStart},
331// {"observEnd", observEnd},
332// {"targetFrame",targetFrame},
333// {"mission", mission},
334// {"ckQuality", ckQuality}
335// });
336// json out = spiceAPIQuery("extractExactCkTimes", args);
337// return out["body"]["return"].get<std::vector<double>>();
338// }else{
339// return SpiceQL::extractExactCkTimes(observStart, observEnd, targetFrame, mission, ckQuality, true);
340// }
341// }
342
343// json spiceAPIQuery(std::string functionName, json args, std::string method){
344// restincurl::Client client;
345// // std::string queryString = "https://spiceql-slot1.prod-asc.chs.usgs.gov/" + functionName;
346// std::string queryString = "127.0.0.1:8080/" + functionName;
347
348// json j;
349
350// if (method == "GET"){
351// queryString += "?";
352// for (auto x : args.items()) {
353// queryString+= x.key();
354// queryString+= "=";
355// queryString+= x.value().dump();
356// queryString+= "&";
357// }
358// std::string encodedString = url_encode(queryString);
359// client.Build()->Get(encodedString).Option(CURLOPT_FOLLOWLOCATION, 1L).AcceptJson().WithCompletion([&](const restincurl::Result& result) {
360// std::cout << "[SpiceQL] spiceAPIQuery GET result = " << result.body << std::endl;
361// j = json::parse(result.body);
362// }).ExecuteSynchronous();
363// }else{
364// client.Build()->Post(queryString).Option(CURLOPT_FOLLOWLOCATION, 1L).AcceptJson().WithJson(args.dump()).WithCompletion([&](const restincurl::Result& result) {
365// j = json::parse(result.body);
366// }).ExecuteSynchronous();
367// }
368// client.CloseWhenFinished();
369// client.WaitForFinish();
370
371// // @TODO throw exception if no json or invalid json is returned
372// return j;
373// }
374
375// std::string url_encode(const std::string &value) {
376// std::ostringstream escaped;
377// escaped.fill('0');
378// escaped << std::hex;
379
380// for (std::string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
381// std::string::value_type c = (*i);
382
383// // Keep alphanumeric and other accepted characters intact
384// if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~' || c == '&' || c == '/' || c == '?' || c == '=' || c == ':') {
385// escaped << c;
386// continue;
387// }
388
389// if (c == '"'){
390// continue;
391// }
392
393// // Any other characters are percent-encoded
394// escaped << std::uppercase;
395// escaped << '%' << std::setw(2) << int((unsigned char) c);
396// escaped << std::nouppercase;
397// }
398
399// return escaped.str();
400// }
401
402// }