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;
+        }
       }
     }