-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(dictutil): Add a dictutil module to assist with serialization
* Add files via upload New "dictutil" for Ladybug Geometry, similar to the existing Honeybee "dictutil". Converts any input dict into a new Ladybug Object. * Add files via upload Tests for new Ladybug Geometry dictutil converter function * Updated dicutil tests, import Update to PR #311 - revised "test/dictutil_test.py" import statements, updated names (files, function) as per comments. Added new tests for completeness. Verified that all tests pass. * Updated styling/syntax as per @chriswmackey comments Co-authored-by: EM <Ed@bldgtyp.com>
- Loading branch information
Showing
3 changed files
with
278 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
*.pyc | ||
.venv/ | ||
test.py | ||
.pytest_cache | ||
*__pycache__ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# coding=utf-8 | ||
"""Utilities to convert any Ladybug Geometry dictionary to Python objects. | ||
Note that importing this module will import almost all modules within the | ||
Ladybug_geometry library in order to be able to re-serialize almost any | ||
dictionary produced from the library. | ||
""" | ||
|
||
from ladybug_geometry.geometry2d import Vector2D, Point2D, Ray2D, \ | ||
LineSegment2D, Arc2D, Polyline2D, Polygon2D, Mesh2D | ||
from ladybug_geometry.geometry3d import Vector3D, Point3D, Ray3D, \ | ||
LineSegment3D, Arc3D, Polyline3D, Polyface3D, Mesh3D,\ | ||
Plane, Face3D, Sphere, Cone, Cylinder | ||
|
||
def geometry_dict_to_object(ladybug_geom_dict, raise_exception=True): | ||
""" | ||
Args: | ||
ladybug_geom_dict (dict): A dictionary of any Ladybug Geometry object. | ||
raise_exception (bool): Boolean to note whether an exception should be raised | ||
if the object is not identified as a part of ladybug_geometry. | ||
Default: True. | ||
Returns: | ||
A Python object derived from the input ladybug_geom_dict. | ||
""" | ||
|
||
lbt_types = { | ||
'Vector2D': Vector2D, | ||
'Point2D': Point2D, | ||
'Ray2D': Ray2D, | ||
'LineSegment2D': LineSegment2D, | ||
'Arc2D': Arc2D, | ||
'Polyline2D': Polyline2D, | ||
'Polygon2D': Polygon2D, | ||
'Mesh2D': Mesh2D, | ||
'Vector3D': Vector3D, | ||
'Point3D': Point3D, | ||
'Ray3D': Ray3D, | ||
'LineSegment3D': LineSegment3D, | ||
'Arc3D': Arc3D, | ||
'Polyline3D': Polyline3D, | ||
'Mesh3D': Mesh3D, | ||
'Plane': Plane, | ||
'Polyface3D': Polyface3D, | ||
'Face3D':Face3D, | ||
'Sphere':Sphere, | ||
'Cone':Cone, | ||
'Cylinder':Cylinder, | ||
} | ||
|
||
# Get the ladybug_geometry object 'Type' | ||
try: | ||
obj_type = ladybug_geom_dict['type'] | ||
except KeyError: | ||
raise ValueError('Ladybug dictionary lacks required "type" key.') | ||
|
||
# Build a new Ladybug Python Object based on the "Type" | ||
try: | ||
lbt_class = lbt_types[obj_type] | ||
return lbt_class.from_dict( ladybug_geom_dict ) | ||
except KeyError: | ||
if raise_exception: | ||
raise ValueError('{} is not a recognized ladybug geometry type'.format(obj_type)) | ||
else: | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
"""Tests for Ladybug Geometry dict->Object converter. | ||
Note: Written in PyTest format. | ||
""" | ||
import pytest | ||
from ladybug_geometry.geometry2d import (Vector2D, Point2D, Ray2D, | ||
LineSegment2D, Arc2D, Polyline2D, Polygon2D, Mesh2D) | ||
from ladybug_geometry.geometry3d import (Vector3D, Point3D, Ray3D, | ||
LineSegment3D, Arc3D, Polyline3D, Polyface3D, Mesh3D, | ||
Plane, Face3D, Sphere, Cone, Cylinder) | ||
from ladybug_geometry.dictutil import geometry_dict_to_object | ||
|
||
#--- Test not Ladubug Geometry dict | ||
def test_not_valid_dict(): | ||
d = { 'key_1':'val_1' } # dict Does NOT inlcude 'type' key | ||
with pytest.raises(ValueError): | ||
obj = geometry_dict_to_object( d ) | ||
|
||
def test_not_valid_dict(): | ||
d = { 'type':'not_a_valid_type' } # Includes 'type', but is not a valid Ladybug Type | ||
with pytest.raises(ValueError): | ||
obj = geometry_dict_to_object( d ) | ||
|
||
#--- Test 2D Geometry | ||
def test_Point2D(): | ||
obj1 = Point2D() | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Arc2D(): | ||
pt1 = Point2D() | ||
obj1 = Arc2D(pt1, 2) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Vector2D(): | ||
obj1 = Vector2D(0,1) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Ray2D(): | ||
pt1 = Point2D() | ||
v1 = Vector2D(0,1) | ||
obj1 = Ray2D(pt1,v1) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_LineSegment2D(): | ||
pt1 = Point2D() | ||
v1 = Vector2D(0,1) | ||
obj1 = LineSegment2D(pt1,v1) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Polyline2D(): | ||
pt1 = Point2D(0,1) | ||
pt2 = Point2D(1,2) | ||
pt3 = Point2D(2,3) | ||
obj1 = Polyline2D([pt1, pt2, pt3], False) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Polygon2D(): | ||
pt1 = Point2D(0,1) | ||
pt2 = Point2D(1,1) | ||
pt3 = Point2D(1,0) | ||
pt4 = Point2D(0,1) | ||
obj1 = Polygon2D([pt1, pt2, pt3, pt4]) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Mesh2D(): | ||
pt1 = Point2D(0,1) | ||
pt2 = Point2D(1,1) | ||
pt3 = Point2D(1,0) | ||
pt4 = Point2D(0,1) | ||
obj1 = Mesh2D(vertices=(pt1, pt2, pt3, pt4), faces=[(0,1,2)] ) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
#--- Test 3D Geometry | ||
def test_Point3D(): | ||
obj1 = Point3D() | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Arc3D(): | ||
pl = Plane() | ||
obj1 = Arc3D(pl, 2) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Vector3D(): | ||
obj1 = Vector3D(0,1) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Ray3D(): | ||
pt1 = Point3D() | ||
v1 = Vector3D(0,1) | ||
obj1 = Ray3D(pt1,v1) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_LineSegment3D(): | ||
pt1 = Point3D() | ||
v1 = Vector3D(0,1) | ||
obj1 = LineSegment3D(pt1,v1) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Polyline3D(): | ||
pt1 = Point3D(0,1) | ||
pt2 = Point3D(1,2) | ||
pt3 = Point3D(2,3) | ||
obj1 = Polyline3D([pt1, pt2, pt3], False) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Polyface3D(): | ||
pt1 = Point3D(0,1) | ||
pt2 = Point3D(1,1) | ||
pt3 = Point3D(1,0) | ||
pt4 = Point3D(0,1) | ||
obj1 = Polyface3D(vertices=[pt1, pt2, pt3, pt4], face_indices=[ [[1]] ] ) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Mesh3D(): | ||
pt1 = Point3D(0,1) | ||
pt2 = Point3D(1,1) | ||
pt3 = Point3D(1,0) | ||
pt4 = Point3D(0,1) | ||
obj1 = Mesh3D(vertices=(pt1, pt2, pt3, pt4), faces=[(0,1,2)] ) | ||
|
||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Plane(): | ||
obj1 = Plane() | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Face3D(): | ||
pt1 = Point3D(0,1) | ||
pt2 = Point3D(1,2) | ||
pt3 = Point3D(2,3) | ||
obj1 = Face3D([pt1, pt2, pt3]) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Sphere(): | ||
pt1 = Point3D() | ||
obj1 = Sphere(pt1, 1) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Cone(): | ||
v1 = Point3D() | ||
axis = Vector3D(0,0,1) | ||
obj1 = Cone(v1, axis, 45) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 | ||
|
||
def test_Cylinder(): | ||
v1 = Point3D() | ||
axis = Vector3D(0,0,1) | ||
obj1 = Cylinder(v1, axis, 10) | ||
d = obj1.to_dict() | ||
obj2 = geometry_dict_to_object(d) | ||
|
||
assert obj2 == obj1 |