geotools修改shapefile 属性名乱码问题
在GeoServer中文社区的讨论地址为:http://opengeo.cn/bbs/read.php?tid=1701&page=e&#a
使用geotools修改shapefile之后, 发现dbf文件内容中, 属性名都成了乱码, 但属性值就不是乱码。修改之前还没有乱码的。
而且在代码中也已经通过以下方式设置过编码方式了:
- ShapefileDataStore shape = new ShapefileDataStore(url);
- shape.setStringCharset(Charset.forName("GBK"));
我的修改代码如下:
- /**
- * 修改shapefile.
- * @param dataStore
- * @param fidStr 要修改的数据对应的featureID
- * @return
- */
- public static boolean updateShapeFile(ShapefileDataStore dataStore,String fidStr)
- {
- DefaultTransaction transaction = null;
- SimpleFeatureStore store = null;
- try {
- dataStore.setStringCharset(Charset.forName("GBK"));
- String[] featureNames = dataStore.getTypeNames();
- String featureName = featureNames[0];
- // 创建默认的事务对象
- transaction = new DefaultTransaction();
- // 同时标明数据源使用的要素名称,通常Shapefile文件名称和Shapefile类型名称通常是一样的。
- store = (SimpleFeatureStore) dataStore.getFeatureSource(featureName);
- // 关联默认事务和数据源
- store.setTransaction(transaction);
- //创建过滤器
- FilterFactory2 ff = (FilterFactory2) CommonFactoryFinder.getFilterFactory2(null);
- Set<FeatureId> fids = new HashSet<FeatureId>();
- FeatureId fid = ff.featureId(fidStr);
- fids.add(fid);
- Filter filter = (Filter) ff.id(fids);
- //根据过滤器对过滤的feature进行修改
- store.modifyFeatures("资料表编号", "test", filter);
- // 提交
- transaction.commit();
- } catch (IOException e) {
- e.printStackTrace();
- try {
- // 回滚
- transaction.rollback();
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- return false;
- }finally{
- if(transaction!=null){
- // 关闭
- transaction.close();
- transaction = null;
- }
- }
- return true;
- }
经过定位发现问题出在transaction.commit();
而且shp文件的文件内容中也有汉字,但是没有出现乱码的问题,那么就从dbf文件的文件头着手。
查看geotools的源代码,发现对dbf文件的操作都在org\geotools\data\shapefile\dbf这个包下,其中类DbaseFileWriter实现的是对dbf文件的写操作,包括属性名(head)的写入和属性值(body)的写入,而head的写入在
- public DbaseFileWriter(DbaseFileHeader header, WritableByteChannel out, Charset charset)
- throws IOException {
- //写header
- header.writeHeader(out);
- 。。。。。。
- }
而writeHeader方法的定义在DbaseFileHeader这个类中.
原来的代码如下:
- // write the field name
- for (int j = 0; j < 11; j++) {
- if (fields.fieldName.length() > j) {
- buffer.put((byte) fields.fieldName.charAt(j));
- } else {
- buffer.put((byte) 0);
- }
- }
意思就是,将属性名称以byte形式放到buffer中,一个属性名所占字节数不能超过11个,不足11个的用(byte)0补充。
关键就在(byte) fields.fieldName.charAt(j),对于汉字来说,占用两个字节,而这里从char转化成byte的时候除了问题.
就拿下面这个字符串来说:
String str = "资";
byte[] bytes = str.getBytes();
for(int i=0;i<bytes.length;i++)
System.out.println(bytes);
输出结果应该是:
-41
-54
这里占用两个字节,是对的.
如果按照它里面的方法的话:
char chars = '资';
byte[] bytes = {(byte)chars};
for(int i=0;i<bytes.length;i++)
System.out.println(bytes);
输出结果是:
68
这里明显是不对的.
就按照上面的逻辑,修改原代码如下(我这里只是方法,这段代码应该再优化一下):
int j = 0;
for(int counter=0; j<11&&counter<fields.fieldName.length(); counter++){
char cha = fields.fieldName.charAt(counter);
String str = new String(cha+"");
byte[] bytes = str.getBytes();
for(int k=0;k<bytes.length;k++){
buffer.put(bytes[k]);
j++;
}
}
if(j!=11){
for(int k=0;k<(11-j);k++){
buffer.put((byte) 0);
}
}
geotools修改shapefile 属性名乱码问题的更多相关文章
- JDK动态代理+反射实现动态修改注解属性值
这是最近朋友的一个需求,正好闲来无聊有些时间,跟着研究一下,如有不正确的地方,欢迎大家指正~ 一.准备自定义注解 注:如何实现自定义注解,请移步百度. 二.实现 1.实现方式1:通过反射+动态代理动态 ...
- Hive分区表新增字段及修改表名,列名,列注释,表注释,增加列,调整列顺序,属性名等操作
一.Hive分区表新增字段 参考博客:https://blog.csdn.net/yeweiouyang/article/details/44851459 二.Hive修改表名,列名,列注释,表注释, ...
- javascript动态修改对象的属性名
在做东钿业务系统的时候,经常碰到写很多重复的ajax对接,于是就想封装一个方法,但是接收data的字段名不一样,所以就需要用到动态对象属性名这个写法了.其实很简单.直接看一下代码吧.
- JS遍历对象修改属性名
根据接口返回数据中number属性值,对数据进行截取,并改变属性名.直接上码: 下面是需要处理的数据 let data={"minValue":7400, "maxVal ...
- 使用DOM解析XML文件,、读取xml文件、保存xml、增加节点、修改节点属性、删除节点
使用的xml文件 <?xml version="1.0" encoding="GB2312" ?> <PhoneInfo> <Br ...
- GDAL C#中文路径,中文属性名称乱码问题
昨天写的博客,将C#读取shp中文属性值乱码的问题应该可以解决,博客地址为:http://blog.csdn.net/liminlu0314/article/details/54096119,然后又测 ...
- C#基础系列:开发自己的窗体设计器(PropertyGrid显示中文属性名)
既然是一个窗体设计器,那就应该能够设置控件的属性,设置属性最好的当然是PropertyGrid了,我们仅仅需要使用一个PropertyGrid.SelectedObject = Control就可以搞 ...
- [Effective JavaScript 笔记]第39条:不要重用父类的属性名
假设想给上节讲的场景图库添加收集诊断信息的功能.这对于调试和性能分析很有用. 38条示例续 给每个Actor实例一个唯一的标识数. 添加标识数 function Actor(scene,x,y){ t ...
- ibernate学习笔记5---实体类或属性名与数据库关键字冲突、hql命名参数、hql实现通用分页
一.实体类或属性名与数据库关键字冲突问题1.实体类名与数据库中的关键字冲突比如:实体表User与oracle中的系统表冲突解决方式1:在xml中添加table属性,指定表名,使其不与name默认相等 ...
随机推荐
- Python爬虫爬取一篇韩寒新浪博客
网上看到大神对Python爬虫爬到非常多实用的信息,认为非常厉害.突然对想学Python爬虫,尽管自己没学过Python.但在网上找了一些资料看了一下,看到爬取韩寒新浪博客的视频.共三集,第一节讲爬取 ...
- 实时监控Cat之旅~分布式消息树的实现原理与测试
大众点评的老吴在InfoQ上讲了Cat之后,有不少同仁开始关注这个实时监控系统,但学习的文章甚少,在GitHub上也是一言代过,给我们这些开发人员留下了N多个疑问,一时间不知道去哪里问,向谁去问了,通 ...
- Windows平台下使用pthreads开发多线程应用
pthreads简介 POSIX 1003.1-2001标准定义了编写多线程应用程序的API(应用程序编程接口),这个接口通常被称为pthreads.在常见的操作系统中,例如Unix.Linux.Ma ...
- Spatial Pyramid Matching
转自:http://blog.csdn.net/jwh_bupt/article/details/9625469 SPM 全称是Spatial Pyramid Matching,出现的背景是bag o ...
- iOS基本UI控件总结
包括以下几类: //继承自NSObject:(暂列为控件) UIColor *_color; //颜色 UIImage *_image; //图像 //继承自UIView:只能相应手势UI ...
- IDEA 热启动,每次更改代码后不用重启服务
1.ctrl+Shift+Alt+/,选择Registry 2.勾选 compiler.automake.allow.when.app.running(可能不按首字母排序,可以多找找) 3.Setti ...
- C++ lambda表达式 (二)
#include <functional> #include <iostream> int main() { using namespace std; int i = 3; i ...
- Java Web学习总结(21)——http协议响应状态码大全以及常用状态码
http协议响应状态码大全以及常用状态码 当我们在浏览网页或是在查看服务器日志时,常会遇到3位数字的状态码,这3位数字是什么意思呢?其实,这3位数字是HTTP状态码,用来表示网页服务器HTTP响应状态 ...
- Android NDK课程录制完毕上线
近期依据公司安排,录制了Android NDK开发的内容,总体课程能够在www.iotekclass.com上看到.兴许会慢慢的用blog把这些内容展示出来. 此课程大纲例如以下: 第一章 NDK简单 ...
- Split Shape by Plane in OpenCASCADE
Split Shape by Plane in OpenCASCADE eryar@163.com Abstract. Sometimes you want to split a shape by p ...