Mercurial > hg > orthanc
changeset 35:f6d12037f886
full json vs. simplified json
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 30 Aug 2012 12:24:31 +0200 |
parents | 96e57b863dd9 |
children | dfb159a079ea |
files | Core/DicomFormat/DicomTag.cpp Core/DicomFormat/DicomTag.h PalantirExplorer/explorer.html PalantirExplorer/explorer.js PalantirServer/FromDcmtkBridge.cpp PalantirServer/PalantirRestApi.cpp |
diffstat | 6 files changed, 143 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/Core/DicomFormat/DicomTag.cpp Thu Aug 30 11:22:21 2012 +0200 +++ b/Core/DicomFormat/DicomTag.cpp Thu Aug 30 12:24:31 2012 +0200 @@ -24,6 +24,7 @@ #include <iostream> #include <iomanip> +#include <stdio.h> namespace Palantir { @@ -51,6 +52,14 @@ } + std::string DicomTag::Format() const + { + char b[16]; + sprintf(b, "%04x,%04x", group_, element_); + return std::string(b); + } + + const DicomTag DicomTag::ACCESSION_NUMBER = DicomTag(0x0008, 0x0050); const DicomTag DicomTag::IMAGE_INDEX = DicomTag(0x0054, 0x1330); const DicomTag DicomTag::INSTANCE_UID = DicomTag(0x0008, 0x0018);
--- a/Core/DicomFormat/DicomTag.h Thu Aug 30 11:22:21 2012 +0200 +++ b/Core/DicomFormat/DicomTag.h Thu Aug 30 12:24:31 2012 +0200 @@ -54,6 +54,8 @@ bool operator< (const DicomTag& other) const; + std::string Format() const; + friend std::ostream& operator<< (std::ostream& o, const DicomTag& tag); // Alias for the most useful tags
--- a/PalantirExplorer/explorer.html Thu Aug 30 11:22:21 2012 +0200 +++ b/PalantirExplorer/explorer.html Thu Aug 30 12:24:31 2012 +0200 @@ -178,6 +178,10 @@ <div style="padding:10px"> <div class="ui-body ui-body-b"> <h1>DICOM Tags</h1> + <p align="right"> + <input type="checkbox" id="show-tag-name" checked="checked" class="custom" data-mini="true" /> + <label for="show-tag-name">Show tag description</label> + </p> <div id="dicom-tree"></div> </div> </div>
--- a/PalantirExplorer/explorer.js Thu Aug 30 11:22:21 2012 +0200 +++ b/PalantirExplorer/explorer.js Thu Aug 30 12:24:31 2012 +0200 @@ -381,33 +381,42 @@ var result = []; for (var i in dicom) { - if (dicom [i] != null) { - if (typeof dicom[i] == 'string') + if (dicom[i] != null) { + var label = i + '<span class="tag-name"> (<i>' + dicom[i]["Name"] + '</i>)</span>: '; + + if (dicom[i]["Type"] == 'String') { result.push({ - label: i + ': <strong>' + dicom[i] + '</strong>', + label: label + '<strong>' + dicom[i]["Value"] + '</strong>', children: [] }); } - else if (typeof dicom[i] == 'number') + else if (dicom[i]["Type"] == 'TooLong') { result.push({ - label: i + ': <i>Too long</i>', + label: label + '<i>Too long</i>', children: [] }); } - else + else if (dicom[i]["Type"] == 'Null') + { + result.push({ + label: label + '<i>Null</i>', + children: [] + }); + } + else if (dicom[i]["Type"] == 'Sequence') { var c = []; - for (var j = 0; j < dicom[i].length; j++) { + for (var j = 0; j < dicom[i]["Value"].length; j++) { c.push({ label: 'Item ' + j, - children: ConvertForTree(dicom[i][j]) + children: ConvertForTree(dicom[i]["Value"][j]) }); } result.push({ - label: i + '[]', + label: label + '[]', children: c }); } @@ -438,7 +447,7 @@ .listview('refresh'); $.ajax({ - url: '/instances/' + instance.ID + '/all-tags', + url: '/instances/' + instance.ID + '/tags', dataType: 'json', success: function(s) { $('#dicom-tree').tree('loadData', ConvertForTree(s)); @@ -531,7 +540,7 @@ $('#instance-download-json').live('click', function(e) { // http://stackoverflow.com/a/1296101 e.preventDefault(); //stop the browser from following - window.location.href = '/instances/' + $.mobile.pageData.uuid + '/all-tags'; + window.location.href = '/instances/' + $.mobile.pageData.uuid + '/tags'; }); @@ -643,3 +652,12 @@ } }); }); + + +$('#show-tag-name').live('change', function(e) { + var checked = e.currentTarget.checked; + if (checked) + $('.tag-name').show(); + else + $('.tag-name').hide(); +});
--- a/PalantirServer/FromDcmtkBridge.cpp Thu Aug 30 11:22:21 2012 +0200 +++ b/PalantirServer/FromDcmtkBridge.cpp Thu Aug 30 12:24:31 2012 +0200 @@ -298,14 +298,20 @@ { assert(target.type() == Json::objectValue); - const std::string tagName = FromDcmtkBridge::GetName(FromDcmtkBridge::GetTag(element)); + DicomTag tag(FromDcmtkBridge::GetTag(element)); + const std::string tagName = FromDcmtkBridge::GetName(tag); + const std::string formattedTag = tag.Format(); if (element.isLeaf()) { + Json::Value value(Json::objectValue); + value["Name"] = tagName; + std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(element)); if (v->IsNull()) { - target[tagName] = Json::nullValue; + value["Type"] = "Null"; + value["Value"] = Json::nullValue; } else { @@ -313,18 +319,21 @@ if (maxStringLength == 0 || s.size() <= maxStringLength) { - target[tagName] = s; + value["Type"] = "String"; + value["Value"] = s; } else { - // An integer value of 0 in JSON indicates too long field - target[tagName] = 0; + value["Type"] = "TooLong"; + value["Value"] = Json::nullValue; } } + + target[formattedTag] = value; } else { - target[tagName] = Json::Value(Json::arrayValue); + Json::Value children(Json::arrayValue); // "All subclasses of DcmElement except for DcmSequenceOfItems // are leaf nodes, while DcmSequenceOfItems, DcmItem, DcmDataset @@ -334,9 +343,13 @@ for (unsigned long i = 0; i < sequence.card(); i++) { DcmItem* child = sequence.getItem(i); - Json::Value& v = target[tagName].append(Json::objectValue); + Json::Value& v = children.append(Json::objectValue); StoreItem(v, *child, maxStringLength); } + + target[formattedTag]["Name"] = tagName; + target[formattedTag]["Type"] = "Sequence"; + target[formattedTag]["Value"] = children; } }
--- a/PalantirServer/PalantirRestApi.cpp Thu Aug 30 11:22:21 2012 +0200 +++ b/PalantirServer/PalantirRestApi.cpp Thu Aug 30 12:24:31 2012 +0200 @@ -38,6 +38,71 @@ output.AnswerBufferWithContentType(s, "application/json"); } + + static void SimplifyTagsRecursion(Json::Value& target, + const Json::Value& source) + { + assert(source.isObject()); + + target = Json::objectValue; + Json::Value::Members members = source.getMemberNames(); + + for (size_t i = 0; i < members.size(); i++) + { + const Json::Value& v = source[members[i]]; + const std::string& name = v["Name"].asString(); + const std::string& type = v["Type"].asString(); + + if (type == "String") + { + target[name] = v["Value"].asString(); + } + else if (type == "TooLong" || + type == "Null") + { + target[name] = Json::nullValue; + } + else if (type == "Sequence") + { + const Json::Value& array = v["Value"]; + assert(array.isArray()); + + Json::Value children = Json::arrayValue; + for (size_t i = 0; i < array.size(); i++) + { + Json::Value c; + SimplifyTagsRecursion(c, array[i]); + children.append(c); + } + + target[name] = children; + } + else + { + assert(0); + } + } + } + + + static void SimplifyTags(Json::Value& target, + const FileStorage& storage, + const std::string& fileUuid) + { + std::string s; + storage.ReadFile(s, fileUuid); + + Json::Value source; + Json::Reader reader; + if (!reader.parse(s, source)) + { + throw PalantirException("Corrupted JSON file"); + } + + SimplifyTagsRecursion(target, source); + } + + bool PalantirRestApi::Store(Json::Value& result, const std::string& postData) { @@ -468,7 +533,7 @@ uri[0] == "instances" && (uri[2] == "file" || uri[2] == "tags" || - uri[2] == "named-tags")) + uri[2] == "simplified-tags")) { std::string fileUuid, contentType; if (uri[2] == "file") @@ -477,7 +542,7 @@ contentType = "application/dicom"; } else if (uri[2] == "tags" || - uri[2] == "named-tags") + uri[2] == "simplified-tags") { existingResource = index_.GetJsonFile(fileUuid, uri[1]); contentType = "application/json"; @@ -485,8 +550,18 @@ if (existingResource) { - output.AnswerFile(storage_, fileUuid, contentType); - return; + if (uri[2] == "simplified-tags") + { + Json::Value v; + SimplifyTags(v, storage_, fileUuid); + SendJson(output, v); + return; + } + else + { + output.AnswerFile(storage_, fileUuid, contentType); + return; + } } }