Exporting to json or csv


Can someone help me?
I am not able to export the data that I organized into lists, neither in CSV to Excel, nor in JSON, which would be my priority. I’ve tried a lot of things, but it doesn’t work in JSON, and the spreadsheet isn’t organized as it is in the list, and all the information isn’t included. What am I doing wrong? What else do I have to do? To convert directly to JSON, how can I do it?
Any help from you is always very welcome. Thanks
Exportando JSON.dyn (75.7 KB)

My first guess is that the data isn’t in a format excel understands.
Your’e trying to export actual Revit Elements.

image

Maybe start with basics and see if you can export some simple text to Excel.
Once you have managed this try something a little more difficult.

1 Like

But it is exporting. But it’s all on one line, see. I don’t know how to make all the information distributed across columns and lines in the same way I did with the lists.
I organized the lists, but I don’t know how to export them organized in the spreadsheet. But exporting the text, it is. And there are no errors in Dynamo.



Exportando JSON.dyn (78.9 KB)

@jacob.small , could you give me a reference?

You need to serialize those Revit elements into something else that json/Excel can understand. GUIDs would be my choice.

1 Like

Yes, but I did this process with Element.Id and Dictionary, see. And it’s giving an error at the end of the process that I still can’t identify. :disappointed: @jacob.small @Alban_de_Chasteigner Would you help me?

Lines are not strings. Nor are points.

It’s not just the Revit elements but anything more complex than what fits in a text document will need to be converted.

Geometry.ToSolidDef will do the work for most of that, but it may not be the right format (depending on how you plan on working with the data).

3 Likes

Hi,

if you have some experience with Python, you can create your custom objects to serialize them (with custom attributes)

example of Python code to save some data in a json file


import sys
import clr
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
import Autodesk.Revit.DB as DB

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

my_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments)

import json

class CustomRooms:
    # list of all room instances
    room_instances = []

    def __init__(self, room):
        """
        Initializes a new instance of the CustomRooms class with the given room.

        Parameters
        ----------
        room : Autodesk.Revit.DB.Architecture.Room
            The Revit room to be stored.
        """
        self.room_unique_id = room.UniqueId
        self.room_name = room.ToDSType(False).Name
        self.room_boundary = CustomRooms.Get_boundary(room)
        self.__class__.room_instances.append(self)

    @staticmethod
    def Get_boundary(room):
        """
        Gets the boundary segments of the given Revit room.
        Parameters
        ----------
        room : Autodesk.Revit.DB.Architecture.Room
            The Revit room to get the boundary segments from.
        Returns
        -------
        array_array_segments : list
            A list of dictionaries containing the boundary segments of the room.

        """
        space_opt = DB.SpatialElementBoundaryOptions()
        space_opt.SpatialElementBoundaryLocation = DB.SpatialElementBoundaryLocation.Finish
        array_array_segments = [{f"bound{idx}" : [seg.GetCurve().ToProtoType().ToString() for seg in array]} \
                                                for idx, array in enumerate(room.GetBoundarySegments(space_opt))]
        space_opt.Dispose()
        return array_array_segments

    def toDict(self):
        """
        Converts the CustomRooms instance to a dictionary.
        Returns
        -------
        dict
            A dictionary representation of the CustomRooms instance.
        """
        return json.loads(json.dumps(self, default=lambda o: o.__dict__, indent=4))

    @classmethod
    def Serialize_All_to_File(cls, file_path):
        """
        Serializes all room instances to a JSON file.
        Parameters
        ----------
        file_path : str
            The path to the JSON file to be created.
        """
        lst_serialzed = [x.toDict() for x in cls.room_instances]
        json_object = json.dumps(lst_serialzed, indent=4)
        with open(file_path, 'w', encoding='utf-8') as f:
            json.dump(json.loads(json_object), f, indent=4)
        # eventually return the json_object
        # return json_object

# main code
lst_rooms = UnwrapElement(IN[0])
out_json_path = my_path + '\\data.json'

for r in lst_rooms:
    CustomRooms(r)

CustomRooms.Serialize_All_to_File(out_json_path)
OUT  = out_json_path
4 Likes

Note that ToString() will result in loss of fidelity as it only keeps a few digits after the decimal.

I prefer to use ToSolidDef() will serialized the geometry and maintain the accuracy.

4 Likes

I tried to convert lines into texts, using several nodes, but no results.
Would it be this? I can’t get anywhere. :sob: :sob:

Unfortunately, I don’t master Python, nor Dynamo. But thank you for all this help. :pray:

You are mixing data types already in your dictionary, and so as a result you are in a bind. Before you build the dictionary you need to serialize the geometry into a string using a ToSolidDef node. Post the full graph and a sample data set containing say two rooms and the relevant info you are trying to serialize and I can have a look when I get the time.

1 Like



Yes, now I was able to understand and export to json. However look how the file comes.
All in one line, which doesn’t serve me in the other process.
At least it needed to appear as in the second print, the environment and the coordinates of the lines of that environment, each one in a line in json, or in excel.
It is possible? What can I do?
All my attempts at json keep mixing all the information into just one line.
Exportando JSON TESTE.dyn (46.4 KB)
Projeto3.rvt (4.3 MB)

Json and excel are very different formats. Json is more about storing attribute and value pairs versus rows and columns like excel.

I would suggest focusing purely on parseing json structures if your goal is to support more complex shapes of data than excel can provide.

It may be helpful to look into Jswan if you have access to Grasshopper or Rhino inside just to learn about structure and deconstruction of json, it really helped me learn about it as it can deconstruct json in layers many times in a row.

There are likely various packages and examples of json lurking on the forum also, but I’m not overly familiar with them. Some of your data likely is best deconstructed to more primitive representations, e.g. lines are better stored as XYX sets for start/end points possibly. Dictionaries will be important vs lists to research if you head further into json data structures, but each scenario for parseing will be unique to the levels at which you store data and the types of data you store.

1 Like

I phrase this a bit differently. JSON is about storing structured data. It can be in a dictionary format (key/value pairs), or it could be in a list format, or it can be a mix of the two. Most of the time we see key value pairs as they are easier to work with. If I sent you a random list of data you’d have to guess what was stored at each index in the sequence, while if I sent you a dictionary the key would inform you what the data was for. As JSON is very frequently used for interchange of data (over the web or between desktop applications) the dictionaries are more consistently used in terms of data extraction. When JSON is used internally to a process the list version can work just fine. This pages has some good info to start with: JSON

So @cintiamiranda21, knowing this and that you want to go out to JSON, the question becomes “How do you want your data structured?” We can’t answer that, but we can give some thoughts.

One method I have seen is a list of rooms stored as a dictionary, which have keys for Unique ID, Element ID, Name, Number, and Geometry. This graph will build just that using only out of the box nodes (no need for any 3rd party packages which is nice). Note that because an object can have multiple geometries I am storing that information as a list rather than a single element.
Export to JSON.dyn (28.7 KB)

Note I am moving the solids instead of the room boundaries, floor surfaces, whatever. The concept of ‘ToSolidDef’ applies to whatever geometry you want to serialize, however there are some limits which you’ll find as you experiment. One thing to note is that polycurves serialize as individual segments which then have to be joined back together on deserialization. You may prefer using a dictionary so you can call for a room by name, unique ID, or something else instead of having to iterate over the list to find the one you want.

Once written out, you likely will want to parse it into something else at some point. The second graph will do just that.
Import from JSON.dyn (15.4 KB)

3 Likes

Perfect! You are great! It helped me a lot. Thank you very much. I made some adaptations and now I’m doing it for other elements. But I understand and it’s working, thank you!

1 Like