In Geotools, there is a bug when trying to create fieldlength constrained attribute,
Which leads to the attribute field length are always set to 255 chars (except the Number class).
Even if you use following to create the AttributeType:
By stepping into the source of the Geotools, I found the problem is caused by the procedure where
the geotools convert the fieldLength to a filter, it always generate the type of PropertyEqualsTo,
but when the geotools generate the DB file header, it only apply the length value in case of following condition (in ShapefileDataStore.java):
if (f != null && f != Filter.EXCLUDE && f != Filter.INCLUDE &&
( (f instanceof PropertyIsLessThan )
|| (f instanceof PropertyIsLessThanOrEqualTo))) {
then the problem raised, all the fieldLength in previous step are ignored when creating db header and with length of the default 255!
Then , we could easily get our solution to work around those issues by generate customized filter with type
of PropertyIsLessThan or PropertyIsLessThanOrEqualTo, see following utility function:
public AttributeType createAttributeType(String attrName, Class<?> cls,
boolean isNillable,int fieldLength) {
LengthFunction length = (LengthFunction)ff.function("LengthFunction",
new Expression[]{ff.property(attrName)});
Filter cf = null;
try {
cf = ff.lessOrEqual(length, ff.literal(fieldLength));
} catch (IllegalFilterException e) {
e.printStackTrace();
}
if(cf == null){
cf = Filter.EXCLUDE;
}
return DefaultAttributeTypeFactory.newAttributeType(attrName,cls,isNillable,cf,null,null);
}
Then we could use above method to create our fieldLength valid attributeType as following:
//create feature schema
AttributeType geom = createAttributeType("geom",Polygon.class);
AttributeType ID = createAttributeType("id",String.class,true,10);
AttributeType name = createAttributeType("Name",String.class,true,50);
//19 = length of (yyyy-MM-dd hh:mm:ss)
AttributeType date = createAttributeType("BirthDate",Date.class,true,19);
FeatureType ft= FeatureTypeBuilder .newFeatureType(new AttributeType[]
{ geom,ID,name,date},featureName);
then the field-length works fine as we expect, and it will greatly decrease the size of .dbf file especially there is many records and many string attributes type in the shapefile.
Which leads to the attribute field length are always set to 255 chars (except the Number class).
Even if you use following to create the AttributeType:
DefaultAttributeTypeFactory.newAttributeType(String name, Class clazz, boolean isNillable, int fieldLength)
By stepping into the source of the Geotools, I found the problem is caused by the procedure where
the geotools convert the fieldLength to a filter, it always generate the type of PropertyEqualsTo,
but when the geotools generate the DB file header, it only apply the length value in case of following condition (in ShapefileDataStore.java):
if (f != null && f != Filter.EXCLUDE && f != Filter.INCLUDE &&
( (f instanceof PropertyIsLessThan )
|| (f instanceof PropertyIsLessThanOrEqualTo))) {
then the problem raised, all the fieldLength in previous step are ignored when creating db header and with length of the default 255!
Then , we could easily get our solution to work around those issues by generate customized filter with type
of PropertyIsLessThan or PropertyIsLessThanOrEqualTo, see following utility function:
public AttributeType createAttributeType(String attrName, Class<?> cls,
boolean isNillable,int fieldLength) {
LengthFunction length = (LengthFunction)ff.function("LengthFunction",
new Expression[]{ff.property(attrName)});
Filter cf = null;
try {
cf = ff.lessOrEqual(length, ff.literal(fieldLength));
} catch (IllegalFilterException e) {
e.printStackTrace();
}
if(cf == null){
cf = Filter.EXCLUDE;
}
return DefaultAttributeTypeFactory.newAttributeType(attrName,cls,isNillable,cf,null,null);
}
Then we could use above method to create our fieldLength valid attributeType as following:
//create feature schema
AttributeType geom = createAttributeType("geom",Polygon.class);
AttributeType ID = createAttributeType("id",String.class,true,10);
AttributeType name = createAttributeType("Name",String.class,true,50);
//19 = length of (yyyy-MM-dd hh:mm:ss)
AttributeType date = createAttributeType("BirthDate",Date.class,true,19);
FeatureType ft= FeatureTypeBuilder .newFeatureType(new AttributeType[]
{ geom,ID,name,date},featureName);
then the field-length works fine as we expect, and it will greatly decrease the size of .dbf file especially there is many records and many string attributes type in the shapefile.
解决GeoTools中创建具有长度约束属性字段的问题。当尝试设置除数值类型外的字段长度时,默认情况下长度总是被设为255字符。通过生成自定义过滤器,使用PropertyIsLessThan或PropertyIsLessThanOrEqualTo类型,可以成功实现期望的字段长度。

被折叠的 条评论
为什么被折叠?



