使用Geotools中的Shapefile plugin支持小数位精确控制
2017-02-03 11:57
453 查看
1背景
当前Java语言实现的Shapefile读写库中,Geotools中的shapefile插件是使用最多的开源实现,实现比较全面,成熟。但是可能为了与Geotools的核心概念一致,其对小数位DecimalCount的控制支持没有在适配层实现,只是默认了小数位的位数(其底层还是支持小数位的控制的)。改进有几种方式,其一是参考Shapefile插件自己实现一个独立的干净的Shapefile类库,但是又有不少细节需要考虑;其二是完全实现一套新的Shapefile库,但是意义有多大呢?所以改进的方式就是简单的利用目前Geotools的扩展机制,修改一下适配层,解决一下精确控制小数位的问题。
2解决方法
通过对Shapefile源代码的分析,发现控制DecimalCount的位置有两处:第一处:org.geotools.data.shapefile.ShapefileDataStore类中createDbaseHeader方法,修改对Number类型的适配,通过AttributeDescriptor的getUserData()数据来获取对decimalCount属性的设定。
修改如下:
else if (Number.class.isAssignableFrom(colType)) { int l = Math.min(fieldLen, 33); int d = Math.max(l - 2, 0); //通过自定义属性支持小数点位数,decimalCount Map<Object, Object> user_data = type.getUserData(); if (user_data != null) { try { d = Integer.parseInt(user_data.getOrDefault("decimalCount", d).toString()); } catch (Exception ex) { // } } header.addColumn(colName, 'N', l, d); } |
其是读取DBF文件,重建AttributeDescriptor,原来的实现没有读取DecimalCount信息,这里加上,同样加入到UserData之中。
实现如下:
int decimalCount=header.getFieldDecimalCount(i); if(decimalCount>0){ build.addUserData("decimalCount", decimalCount); } |
通过修改上诉两处,重新编译Shapefile插件,就可以支持对小数位的精确控制了。
3使用方法
1)引入Shapefile以及依赖的库,这里使用Maven命令可以直接提取依赖库Shapefile依赖库可以参考上图。
2)在定义属性表的时候使用UserData来存放需要设定的decimalCount信息。
示例如下:
protected SimpleFeatureType createFeatureType() { SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); builder.setName("buildiong"); builder.setCRS(DefaultGeographicCRS.WGS84); // add attributes in order builder.add("the_geom", Point.class); builder.length(9).add("ID", Integer.class); builder.length(150).add("NAME", String.class); builder.length(10).userData("decimalCount",6).add("X", Double.class); builder.length(10).userData("decimalCount",6).add("Y", Double.class); final SimpleFeatureType BUILDING = builder.buildFeatureType(); return BUILDING; } |
上面例子通过SimpleFeatureTypeBuilder的userData("decimalCount",6)来设定小数位为6位。
4附注,对长度与小数位的理解
DBF使用的是字符串来存储数值类型,其长度的概念是字符数概念,而且所有字段都是定长概念。如果不够长度,则是先补充小数位(用零补充),然后补充整数位(用空格)补充。
在QGIS里面,显示带小数位的属性表的时候,其长度显示去掉了小数点,就是说会显示长度比我们的定义少一。如我们定义(10,6)在QGIS里面会显示长度为9,小数位为6。
通常我们定义WGS84坐标来讲,若要保留小数点后6位,则定义N(10,6)就可以,因为整数位不会超过三位。
5编译后的插件以及依赖库,可以从下面的链接下载:
点击打开链接
相关文章推荐
- 使用geotools导入shp文件到Oracle数据库时表名带下划线问题的解决方法
- Java用GDAL读写shapefile的方法示例
- 使用geotools导入shp文件到Oracle数据库时表名带下划线问题的解决方法
- shapfile中文读取乱码
- Geoserver 标准乱码、属性查询源码分析
- ArcGIS ModelBuilder批量导出SHP文件中的要素
- shapefile格式说明及读写代码示例
- shapefile格式说明及读写代码示例
- ORG/GDAL利用csv文件生成shapefile点文件
- Geotools 对shp数据的样式修改
- 使用GMap控件读取.shp多边形文件(shapefile)
- EXCEL中的空间数据转换为shapefile和GDB中的feature class
- oracle spatial格式空间数据表导出为shapefile文件
- 解决 GeoServer 2.8.1 无法发布 Oracle Spatial 表名带下划线的图层
- 解决GeoTools中CQL解析中文字段名的问题
- GeoTools-数据组织结构
- GeoTools-Swing显示原理
- Troubleshooting:Shapefile 乱码与字符截断问题
- 获取shapefile文件最小包围矩形的c++程序
- Shapefile 文件的局限性