Solution for supporting fieldLength when creating shapefile by Geotools

解决GeoTools中创建具有长度约束属性字段的问题。当尝试设置除数值类型外的字段长度时,默认情况下长度总是被设为255字符。通过生成自定义过滤器,使用PropertyIsLessThan或PropertyIsLessThanOrEqualTo类型,可以成功实现期望的字段长度。
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:
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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值