???? 困擾了好幾天,一直在嘗試各種方法解決Geotools讀取shp格式對中文編碼的問題。可是昨天一個無意的舉動居然讓我發覺自己做了太多的無用之功。仔細的看了JavaDoc以及shapefile源代碼之后,可以可以明顯的看到ShapefileDataStore的構造函數已經發生了很大的變化:
????
public?static?final?Charset?DEFAULT_STRING_CHARSET?=?Charset.forName("ISO-8859-1");??? 這個是ShapefileDataStore對象中定義的字符編碼。也正是由于其使用ISO-8859-1編碼作為默認編碼,所以一直以來,解決geotools抑或geoserver的中文問題總是連綿不絕。
?? 來看看我在2.4中看到的ShapefileDataStore的新的構造函數(當然,貝塔和我聊天說過好像2.3也是作出了同樣修改的,可惜我沒下2.3的源碼,呵呵,但是2.2以前的版本這一塊貌似是不同的。權當其是2.4中的“新增”之處吧)
?1
????public?ShapefileDataStore(URL?url,?boolean?useMemoryMappedBuffer)
?2
????????throws?MalformedURLException
?3
????{
?4
????????this(url,?useMemoryMappedBuffer,?DEFAULT_STRING_CHARSET);
?5
????}
?6
?7
????public?ShapefileDataStore(URL?url,?boolean?useMemoryMappedBuffer,?Charset?dbfCharset)
?8
????????throws?MalformedURLException
?9
????{
10
????????readWriteLock?=?new?Lock();
11
????????namespace?=?null;
12
????????this.useMemoryMappedBuffer?=?true;
13
????????String?filename?=?null;
14
????????shpURL?=?ShapefileDataStoreFactory.toShpURL(url);
15
????????dbfURL?=?ShapefileDataStoreFactory.toDbfURL(url);
16
????????shxURL?=?ShapefileDataStoreFactory.toShxURL(url);
17
????????prjURL?=?ShapefileDataStoreFactory.toPrjURL(url);
18
????????xmlURL?=?ShapefileDataStoreFactory.toXmlURL(url);
19
????????this.dbfCharset?=?dbfCharset;
20
????} ?????
???
???? 列下使用Geotools 2.4操作shp格式的代碼如下:
??? 代碼1:
?1
public?class?ReadShape??{
?2
????public?static?void?main(String[]?args)?
?3
????????throws?FileNotFoundException,MalformedURLException,IOException{
?4
????????
?5
????????File?shpFile=new?File("shp/市區地物_point.dbf");
?6
????????ShapefileDataStore?shpDataStore=new?ShapefileDataStore(shpFile.toURL());
?7
????????shpDataStore.setStringCharset(Charset.forName("GBK"));
?8
????????FeatureSource?fs=shpDataStore.getFeatureSource();
?9
????????FeatureCollection?collection?=?fs.getFeatures();
10
????????FeatureIterator?iterator?=?collection.features();
11
????????int?numOfAttr=0;
12
????????try?{
13
???????????while(?iterator.hasNext()?){
14
????????????????Feature?feature?=?iterator.next();
15
????????????????numOfAttr?=?feature.getNumberOfAttributes();
16
????????????????for(int?i=0;i<numOfAttr;i++){
17
????????????????????String?temp=feature.getAttribute(i).toString();
18
????????????????????System.out.print(temp+"\t");
19
????????????????}
20
????????????????
21
????????????????System.out.println();
22
???????????}
23
????????}
24
????????finally?{
25
???????????iterator.close();
26
????????}
27
????}
28
} ??? 代碼2:
?1
public?class?ReadSHP??{
?2
????public?static?void?main(String[]?args)?
?3
????????throws?FileNotFoundException,MalformedURLException,IOException{
?4
?5
????????//初始化FileChannel對象
?6
????????FileChannel?in?=?new?FileInputStream("shp/市區地物_point.dbf").getChannel();
?7
????????DbaseFileReader?dr=new?DbaseFileReader(in,?true,Charset.forName("UTF-8"));
?8
????????DbaseFileHeader?dh?=?dr.getHeader();
?9
????????int?fields?=?dh.getNumFields();
10
????????for(int?i=0;i<fields;i++){
11
????????????System.out.print(dh.getFieldName(i)+"?");//打印當前屬性名
12
????????}
13
????????System.out.print("\n");
14
????????while(dr.hasNext()){
15
????????????DbaseFileReader.Row?row?=?dr.readRow();
16
????????????for?(int?i=0;i<fields;i++){
17
????????????????????Object?data?=?row.read(i);
18
????????????????????if(dh.getFieldName(i).equals("NAME")){
19
????????????????????????????System.out.print(data);
20
????????????????????}else{
21
????????????????????????????System.out.print(data);
22
????????????????????}
23
????????????????????System.out.print("\t");
24
????????????}
25
????????????System.out.println();
26
????????}
27
????????dr.close();
28
????}
29
} ????
????兩段代碼都可以直接運行。當然,從個人角度來看,代碼2是我比較推薦的。不管是效率還是安全性,FileChannel對象比File對象應該還是強一些。
??? 算是又解決了一個問題。
??? 十一期間準備自己寫一個shp2svg和shp2sql的小程序。第一呢,geoserver生成的svg樣式也好,標注名稱也好都好像不太好(也許是我自己對geoserver不熟悉的原因);第二呢,嚴重懷疑postgis自帶的shp2pgsql這個程序對編碼的支持度。除非我的數據庫編碼是EUN_CN,否則導入的數據是肯定有問題。
??? 不在考慮那些讓我煩心的事情,也不想做一個“人無遠慮,必有近憂”的思想者。一心一意專注于自己的愛好。其他時間也許“身不由己”,但是十一長假還是可以做到的。準備回鄉下,到我的那間田間小屋去,斷網6天!
??