解决GeoTools中CQL解析中文字段名的问题

时间:2021-08-15 07:50:27

GeoTools中CQL无法解析中文字段名的过滤条件,会报异常错误,经过一个下午的努力,终于通过简单有效的方式解决啦

String filterCondition = "temp='" + gbCodeString + "'"; //使用临时英文字段名temp作为字段名,若为中文字段名则无法正确创建Filter

  Filter filter =ECQL.toFilter(filterCondition); //创建Filter
  //解决字段名为中文的情况
  FilterUtil.decodeFilter(filter,fieldName); //用真正的中文字段名fieldName来替换临时字段名temp
  SimpleFeatureCollection features = source.getFeatures(filter);

 

public class FilterUtil {
 @SuppressWarnings("unchecked")
 public static void decodeFilter(Filter filter,String fieldName)
   throws UnsupportedEncodingException {
   if (filter instanceof IsEqualsToImpl) {
   IsEqualsToImpl impl = (IsEqualsToImpl) filter;
   decodeExpression(impl.getExpression1(),fieldName);
   }
 }

 private static void decodeExpression(Expression exp,String fieldName)
   throws UnsupportedEncodingException {
 
  if (exp instanceof AttributeExpressionImpl)
  {
   AttributeExpressionImpl impl = (AttributeExpressionImpl) exp;
   impl.setPropertyName(fieldName);
  }
 }

}

 

解决问题过程中参考了http://blog.csdn.net/warrenwyf/article/details/5864667中的FilterUtil类,但该类无法直接使用,存在一些问题,且对于一般应用过于繁琐。

原始类代码转载如下:

 

解决GeoTools中CQL解析中文字段名的问题解决GeoTools中CQL解析中文字段名的问题原始FilterUtil类
package com.gi.engine.util.gt;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Iterator;

import org.geotools.filter.AndImpl;
import org.geotools.filter.IsEqualsToImpl;
import org.geotools.filter.IsNotEqualToImpl;
import org.geotools.filter.LikeFilterImpl;
import org.geotools.filter.LiteralExpressionImpl;
import org.geotools.filter.NotImpl;
import org.geotools.filter.OrImpl;
import org.geotools.filter.text.ecql.ECQL;
import org.opengis.filter.Filter;
import org.opengis.filter.expression.Expression;

public  class FilterUtil {

     private  static  char startMark = 0x02;
     private  static  char endMark = 0x03;

     public  static Filter whereclauseToFilter(String where) {
        Filter filter =  null;
         try {
            StringBuilder sb =  new StringBuilder();
             for ( int i = 0, count = where.length(); i < count; i++) {
                 char c = where.charAt(i);
                 if (c < 256) {
                    sb.append(c);
                }  else {
                    String enc = URLEncoder.encode(String.valueOf(c), "UTF-8");
                    enc = enc.replaceAll("\\%", "");
                    sb.append(startMark + enc + endMark);
                }
            }
            String encode = sb.toString();
            Filter f = ECQL.toFilter(encode);
            decodeFilter(f);
            filter = f;
        }  catch (Exception ex) {
            ex.printStackTrace();
        }

         return filter;
    }

    @SuppressWarnings("unchecked")
     private  static  void decodeFilter(Filter filter)
             throws UnsupportedEncodingException {
         if (filter  instanceof OrImpl) {
            OrImpl impl = (OrImpl) filter;
             for (Iterator<Filter> itr = impl.getFilterIterator(); itr.hasNext();) {
                Filter f = itr.next();
                decodeFilter(f);
            }
        }  else  if (filter  instanceof AndImpl) {
            AndImpl impl = (AndImpl) filter;
             for (Iterator<Filter> itr = impl.getFilterIterator(); itr.hasNext();) {
                Filter f = itr.next();
                decodeFilter(f);
            }
        }  else  if (filter  instanceof NotImpl) {
            NotImpl impl = (NotImpl) filter;
            Filter f = impl.getFilter();
            decodeFilter(f);
        }  else  if (filter  instanceof LikeFilterImpl) {
            LikeFilterImpl impl = (LikeFilterImpl) filter;
            String encode = impl.getLiteral();
            impl.setLiteral(decodeString(encode));
        }  else  if (filter  instanceof IsEqualsToImpl) {
            IsEqualsToImpl impl = (IsEqualsToImpl) filter;
            decodeExpression(impl.getExpression1());
            decodeExpression(impl.getExpression2());
        }  else  if (filter  instanceof IsNotEqualToImpl) {
            IsNotEqualToImpl impl = (IsNotEqualToImpl) filter;
            decodeExpression(impl.getExpression1());
            decodeExpression(impl.getExpression2());
        }
    }

     private  static  void decodeExpression(Expression exp)
             throws UnsupportedEncodingException {
         if (exp  instanceof LiteralExpressionImpl) {
            LiteralExpressionImpl impl = (LiteralExpressionImpl) exp;
            String encode = String.valueOf(impl.getValue());
            impl.setValue(decodeString(encode));
        }
    }

     private  static String decodeString(String encode)
             throws UnsupportedEncodingException {
        StringBuilder sb =  new StringBuilder();
         int i = 0, count = encode.length();
         while (i < count) {
             int start = encode.indexOf(startMark, i);
             if (start >= 0) {
                sb.append(encode.substring(i, start));
            }  else {
                sb.append(encode.substring(i));
                 return sb.toString();
            }

             int end = encode.indexOf(endMark, i);
             if (end > 0) {
                i = end + 1;

                String enc = encode.substring(start + 1, end);
                StringBuilder sbEnc =  new StringBuilder();
                 for ( int j = 0, l = enc.length(); j < l; j += 2) {
                    sbEnc.append("%" + enc.charAt(j) + enc.charAt(j + 1));
                }
                String dec = URLDecoder.decode(sbEnc.toString(), "UTF-8");
                sb.append(dec);
            }  else {
                sb.append(encode.substring(i + 1));
                i = count;
            }
        }
         return sb.toString();
    }

}

 

 本博客声明:本人的技术探索过程中,得到了国信司南公司支持。今后,本人博客里的所有技术探索成果将归“无痕客”、“国信司南”和“博客园”三方共同所有,原创作品如需转载,请注明本博客声明