在 CityEngine 中,对象属性值的类型不必在多个形状中相同,但这是 Esri 的 FileGDB 格式的要求。如果场景中存在此类类型不匹配,则导出到 FileGDB 将失败,并显示以下消息:
批处理导出已完成,但至少发生一个错误。有关详细的错误信息,请参阅导出日志文件。
如果在日志(窗口 -> 日志 ->选择条目 ->上下文菜单 ->事件详细信息)中检查条目的详细信息,则可以在异常堆栈跟踪的顶部找到类似于以下行的行:
java.lang.IllegalArgumentException:esriFieldTypeDouble
这样做的原因是 CityEngine 会检查值的类型,并在向形状添加对象属性时相应地设置该值。一个典型的例子是门牌号:值为 12 的数字类型为 float,而值为 12a 的数字类型为 string。这对于从“获取地图数据/OSM”导入的形状非常常见。
解决方案:不导出对象属性
简单的解决方法是首先不导出对象属性,方法是取消选中 FileGDB 导出中“常规设置”下的“导出对象属性”选项。
解决方案:使用 python 对齐对象属性类型
如果需要进一步处理对象属性,则在导出前需要确保所有同名属性的值都属于同一类型。这可以使用 python 脚本来实现:
'''
@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()
该脚本分为两部分:
- 查找类型不匹配的属性。
- 解决不匹配问题:
- 如果 ESRI.lib OSM 建筑物/街道规则类型为 float 所需的属性类型为字符串,则会将其从形状中删除,因为字符串到浮点数转换的预期结果可能不明确。
- 所有其他不匹配的属性都将转换为字符串类型。
没有回复内容