In CityEngine the type of an object attribute’s value does not have to be the same across multiple shapes, but this is a requirement for Esri’s FileGDB format. If such a type mismatch is present in your scene, the export to FileGDB will fail with the following message:
The batch export completed but at least one error occurred. See export logfile for detailed error information.
If you inspect the details of the entry in the Log (Window -> Log -> Select entry -> Context Menu -> Event Details) you can find a line similar to the one below at the top of the Exception Stack Trace:
java.lang.IllegalArgumentException: esriFieldTypeDouble
The reason for this is that CityEngine checks the type of the value and sets it accordingly when adding object attributes to a shape. A typical example are house numbers: A number with the value 12 will be of type float but one with 12a will be of type string. This is very common for shapes imported from Get Map Data / OSM.
The simple workaround is to not export the object attributes in the first place by unchecking the “Export object attributes” option under General Settings in the FileGDB export.
If object attributes are required for further processing, you need to make sure that the value of all attributes with the same name are of the same type before exporting. This can be achieved using python scripting:
'''
@version: 1.0
@author: Esri R&D Center Zurich
'''
from scripting import *
# get a CityEngine instance
ce = CE()
def findTypeMismatches(objects):
allAttributes = {}
mismatchAttributes = []
print("object attributes type mismatch:")
for object in objects:
attributes = ce.getAttributeList(object)
for attr in attributes:
if not attr.startswith('/'): # only check object attributes
attrType = type(ce.getAttribute(object, attr))
if attr not in allAttributes:
allAttributes[attr] = [attrType,ce.getOID(object)]
else:
if allAttributes[attr][0] != 0:
if allAttributes[attr][0] != attrType:
mismatchAttributes.append(attr)
print("Attribute " + attr +
" is of " + str(attrType) +
" in OID: " + ce.getOID(object) +
" ref is of " + str(allAttributes[attr][0]) +
" in OID: " + allAttributes[attr][1])
allAttributes[attr][0] = 0
return mismatchAttributes
@noUIupdate
def resolveTypeMismatch(mismatches, objects):
# object attributes needed by ESRI.lib rules as type float
exceptionAttributes = ["building__levels", "roof__height",
"roof__direction", "building__levels__underground",
"building__min_level", "min_heigh", "width", "lanes"]
for object in objects:
attributes = ce.getAttributeList(object)
for attr in attributes:
if attr in mismatches:
attrValue = ce.getAttribute(object, attr)
if attr in exceptionAttributes:
if not isinstance(attrValue, float):
ce.deleteAttribute(object, attr)
print("Deleting " + attr +
" of type " + str(type(attrValue)) +
" in OID: " + ce.getOID(object))
else:
if not isinstance(attrValue, str):
newValue = str(attrValue)
ce.setAttribute(object, attr, newValue)
print("Updating " + attr +
" from " + str(type(attrValue)) +
" to <type 'str'> in OID: " + ce.getOID(object))
print("Done!")
def main():
#objects = ce.getObjectsFrom(ce.scene)
objects = ce.getObjectsFrom(ce.selection)
mismatches = findTypeMismatches(objects)
resolveTypeMismatch(mismatches,objects)
if __name__ == '__main__':
main()
The script is divided into two parts:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.