Arch: Import/export Site data (longitude, latitude, etc..) to/from IFC
This commit is contained in:
@@ -117,7 +117,7 @@ def addComponents(objectsList,host):
|
||||
if hostType in ["Floor","Building","Site","BuildingPart"]:
|
||||
for o in objectsList:
|
||||
host.addObject(o)
|
||||
elif hostType in ["Wall","Structure","Window","Roof","Stairs","StructuralSystem","Panel"]:
|
||||
elif hostType in ["Wall","Structure","Window","Roof","Stairs","StructuralSystem","Panel","Component"]:
|
||||
import DraftGeomUtils
|
||||
a = host.Additions
|
||||
if hasattr(host,"Axes"):
|
||||
@@ -161,7 +161,7 @@ def removeComponents(objectsList,host=None):
|
||||
if not isinstance(objectsList,list):
|
||||
objectsList = [objectsList]
|
||||
if host:
|
||||
if Draft.getType(host) in ["Wall","Structure","Window","Roof","Stairs","StructuralSystem","Panel"]:
|
||||
if Draft.getType(host) in ["Wall","Structure","Window","Roof","Stairs","StructuralSystem","Panel","Component"]:
|
||||
if hasattr(host,"Tool"):
|
||||
if objectsList[0] == host.Tool:
|
||||
host.Tool = None
|
||||
|
||||
@@ -329,11 +329,13 @@ class _Site(ArchFloor._Floor):
|
||||
if not "Terrain" in pl:
|
||||
obj.addProperty("App::PropertyLink","Terrain","Site",QT_TRANSLATE_NOOP("App::Property","The base terrain of this site"))
|
||||
if not "Address" in pl:
|
||||
obj.addProperty("App::PropertyString","Address","Site",QT_TRANSLATE_NOOP("App::Property","The street and house number of this site"))
|
||||
obj.addProperty("App::PropertyString","Address","Site",QT_TRANSLATE_NOOP("App::Property","The street and house number of this site, with postal box or appartment number if needed"))
|
||||
if not "PostalCode" in pl:
|
||||
obj.addProperty("App::PropertyString","PostalCode","Site",QT_TRANSLATE_NOOP("App::Property","The postal or zip code of this site"))
|
||||
if not "City" in pl:
|
||||
obj.addProperty("App::PropertyString","City","Site",QT_TRANSLATE_NOOP("App::Property","The city of this site"))
|
||||
if not "Region" in pl:
|
||||
obj.addProperty("App::PropertyString","Region","Site",QT_TRANSLATE_NOOP("App::Property","The region, province or county of this site"))
|
||||
if not "Country" in pl:
|
||||
obj.addProperty("App::PropertyString","Country","Site",QT_TRANSLATE_NOOP("App::Property","The country of this site"))
|
||||
if not "Latitude" in pl:
|
||||
|
||||
@@ -141,6 +141,25 @@ def doubleClickTree(item,column):
|
||||
addr[0].setSelected(True)
|
||||
|
||||
|
||||
def dd2dms(dd):
|
||||
|
||||
"converts decimal degrees to degrees,minutes,seconds"
|
||||
|
||||
dd = abs(dd)
|
||||
minutes,seconds = divmod(dd*3600,60)
|
||||
degrees,minutes = divmod(minutes,60)
|
||||
if dd < 0:
|
||||
degrees = -degrees
|
||||
return (int(degrees),int(minutes),int(seconds))
|
||||
|
||||
def dms2dd(degrees, minutes, seconds, milliseconds=0):
|
||||
|
||||
"converts degrees,minutes,seconds to decimal degrees"
|
||||
|
||||
dd = float(degrees) + float(minutes)/60 + float(seconds)/(3600)
|
||||
return dd
|
||||
|
||||
|
||||
def getPreferences():
|
||||
|
||||
"""retrieves IFC preferences"""
|
||||
@@ -944,6 +963,27 @@ def insert(filename,docname,skip=[],only=[],root=None):
|
||||
if r.RepresentationIdentifier == "FootPrint":
|
||||
annotations.append(product)
|
||||
break
|
||||
|
||||
# additional properties for specific types
|
||||
|
||||
if product.is_a("IfcSite"):
|
||||
if product.RefElevation:
|
||||
obj.Elevation = product.RefElevation*1000
|
||||
if product.RefLatitude:
|
||||
obj.Latitude = dms2dd(*product.RefLatitude)
|
||||
if product.RefLongitude:
|
||||
obj.Longitude = dms2dd(*product.RefLongitude)
|
||||
if product.SiteAddress:
|
||||
if product.SiteAddress.AddressLines:
|
||||
obj.Address = product.SiteAddress.AddressLines[0]
|
||||
if product.SiteAddress.Town:
|
||||
obj.City = product.SiteAddress.Town
|
||||
if product.SiteAddress.Region:
|
||||
obj.Region = product.SiteAddress.Region
|
||||
if product.SiteAddress.Country:
|
||||
obj.Country = product.SiteAddress.Country
|
||||
if product.SiteAddress.PostalCode:
|
||||
obj.PostalCode = product.SiteAddress.PostalCode
|
||||
|
||||
try:
|
||||
progressbar.next(True)
|
||||
@@ -1640,7 +1680,11 @@ def export(exportList,filename):
|
||||
else:
|
||||
kwargs.update({"CompositionType": "ELEMENT"})
|
||||
elif ifctype == "IfcSite":
|
||||
kwargs.update({"CompositionType": "ELEMENT"})
|
||||
kwargs.update({"RefLatitude":dd2dms(obj.Latitude),
|
||||
"RefLongitude":dd2dms(obj.Longitude),
|
||||
"RefElevation":obj.Elevation.Value/1000.0,
|
||||
"SiteAddress":buildAddress(obj,ifcfile),
|
||||
"CompositionType": "ELEMENT"})
|
||||
elif ifctype == "IfcBuilding":
|
||||
kwargs.update({"CompositionType": "ELEMENT"})
|
||||
elif ifctype == "IfcBuildingStorey":
|
||||
@@ -1915,32 +1959,37 @@ def export(exportList,filename):
|
||||
treated = []
|
||||
defaulthost = []
|
||||
|
||||
# buildingParts can be exported as any "normal" IFC type. In that case, gather their elements first
|
||||
for bp in Draft.getObjectsOfType(objectslist,"BuildingPart"):
|
||||
if not bp.IfcRole in ["Site","Building","Building Storey","Space","Undefined"]:
|
||||
if bp.Name in products:
|
||||
subs = []
|
||||
for c in bp.Group:
|
||||
if c.Name in products:
|
||||
subs.append(products[c.Name])
|
||||
treated.append(c.Name)
|
||||
if subs:
|
||||
ifcfile.createIfcRelAggregates(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'Assembly','',products[bp.Name],subs)
|
||||
|
||||
# floors/buildingparts
|
||||
for floor in Draft.getObjectsOfType(objectslist,"Floor")+Draft.getObjectsOfType(objectslist,"BuildingPart"):
|
||||
if (Draft.getType(floor) == "Floor") or (hasattr(floor,"IfcRole") and floor.IfcRole == "Building Storey"):
|
||||
objs = Draft.getGroupContents(floor,walls=True)
|
||||
objs = Draft.getGroupContents(floor,walls=True,addgroups=True)
|
||||
objs = Arch.pruneIncluded(objs)
|
||||
children = []
|
||||
for c in objs:
|
||||
if c.Name in products.keys():
|
||||
if not (c.Name in treated):
|
||||
children.append(products[c.Name])
|
||||
treated.append(c.Name)
|
||||
if c.Name != floor.Name: # getGroupContents + addgroups will include the floor itself
|
||||
if c.Name in products.keys():
|
||||
if not (c.Name in treated):
|
||||
children.append(products[c.Name])
|
||||
treated.append(c.Name)
|
||||
f = products[floor.Name]
|
||||
if children:
|
||||
ifcfile.createIfcRelContainedInSpatialStructure(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'StoreyLink','',children,f)
|
||||
floors.append(f)
|
||||
defaulthost = f
|
||||
elif (Draft.getType(floor) == "BuildingPart") and (not floor.IfcRole in ["Site","Building","Building Storey","Space","Undefined"]):
|
||||
# buildingParts can be exported as any "normal" IFC type. In that case, gather their elements
|
||||
if floor.Name in products:
|
||||
subs = []
|
||||
for c in floor.Group:
|
||||
if c.Name in products:
|
||||
subs.append(products[c.Name])
|
||||
treated.append(c.Name)
|
||||
if subs:
|
||||
ifcfile.createIfcRelAggregates(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'Assembly','',products[floor.Name],subs)
|
||||
|
||||
# buildings
|
||||
for building in Draft.getObjectsOfType(objectslist,"Building")+Draft.getObjectsOfType(objectslist,"BuildingPart"):
|
||||
if (Draft.getType(building) == "Building") or (hasattr(building,"IfcRole") and building.IfcRole == "Building"):
|
||||
objs = Draft.getGroupContents(building,walls=True,addgroups=True)
|
||||
@@ -1966,6 +2015,7 @@ def export(exportList,filename):
|
||||
if not defaulthost and not ADDDEFAULTSTOREY:
|
||||
defaulthost = b
|
||||
|
||||
# sites
|
||||
for site in Draft.getObjectsOfType(objectslist,"Site"):
|
||||
objs = Draft.getGroupContents(site,walls=True,addgroups=True)
|
||||
objs = Arch.pruneIncluded(objs)
|
||||
@@ -1979,8 +2029,6 @@ def export(exportList,filename):
|
||||
childbuildings.append(products[c.Name])
|
||||
treated.append(c.Name)
|
||||
sites.append(products[site.Name])
|
||||
#if not defaulthost:
|
||||
#defaulthost = products[site.Name]
|
||||
|
||||
if not sites:
|
||||
if DEBUG: print("No site found. Adding default site")
|
||||
@@ -2160,6 +2208,19 @@ def export(exportList,filename):
|
||||
del ifcbin
|
||||
|
||||
|
||||
def buildAddress(obj,ifcfile):
|
||||
|
||||
|
||||
a = obj.Address.encode("utf8") or None
|
||||
p = obj.PostalCode.encode("utf8") or None
|
||||
t = obj.City.encode("utf8") or None
|
||||
r = obj.Region.encode("utf8") or None
|
||||
c = obj.Country.encode("utf8") or None
|
||||
if a or p or t or r or c:
|
||||
addr = ifcfile.createIfcPostalAddress("SITE",'Site Address','',None,[a],None,t,r,p,c)
|
||||
else:
|
||||
addr = None
|
||||
return addr
|
||||
|
||||
def createFromProperties(propsets,ifcfile):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user