最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解決Java中基于GeoTools的Shapefile讀取亂碼的問題

 更新時間:2025年03月22日 14:42:35   作者:夜郎king  
本文主要討論了在使用Java編程語言進行地理信息數據解析時遇到的Shapefile屬性信息亂碼問題,以及根據不同的編碼設置進行屬性信息解析的方法,感興趣的朋友跟隨小編一起看看吧

前言

文件編碼(File Encoding)是指文件在計算機中存儲時所使用的字符編碼方式。字符編碼是將字符(如字母、數字、標點符號等)轉換成計算機可以直接存儲和處理的數字或二進制代碼的過程。不同的編碼方式決定了文件中字符如何被表示和存儲,以及這些字符如何被不同的軟件或系統(tǒng)正確地讀取和顯示。在進行空間數據處理的時候,通常會涉及大量的空間數據,為了更加詳細且準確的描述這些空間數據,我們通過會配置一些屬性數據。

Shapefile屬性字段的編碼通常指的是存儲在shapefile的dbf(數據庫文件)中的屬性數據的字符編碼方式。Shapefile是一種用于存儲地理空間數據的文件格式,它由多個文件組成,其中dbf文件用于存儲每個幾何形狀的屬性數據。

1、Shapefile屬性字段編碼的情況:

默認編碼:
在不同的軟件或庫中,shapefile的默認編碼可能有所不同。例如,ArcGIS Desktop在較新版本(如10.2.1及以后)中,shapefile (.DBF) 的編碼頁的默認設置為UTF-8(UNICODE)。而在一些其他軟件或庫中,如Java GDAL庫,默認可能使用ISO-8859-1編碼,這會導致中文等非西歐字符出現亂碼問題。
編碼設置:
在使用某些軟件或庫處理shapefile時,可以通過設置來改變屬性字段的編碼方式。例如,在Java GDAL庫中,可以通過調GDAL.SetConfigOption("SHAPE_ENCODING","UTF-8")來設置GDAL庫的默認編碼為UTF-8,從而避免中文屬性亂碼的問題。在ArcGIS中,雖然默認編碼可能是UTF-8,但也可以通過修改注冊表中的dbfDefault值來指定不同的編碼方式。不過,這種方法主要影響ArcGIS Desktop生成的shapefile和dBASE文件的編碼類型,且僅對ArcGIS Desktop生效。
編碼轉換:
如果已經存在編碼不匹配的shapefile文件,可能需要通過編碼轉換工具來修改其屬性字段的編碼方式。例如,可以使用FME Workbench等GIS數據轉換工具來轉換shapefile的編碼。也可以使用編程方式,如利用geotools等庫來讀取原始編碼的shapefile文件,并以新的編碼方式重新寫入數據,從而實現編碼的轉換。
注意事項
在處理shapefile屬性字段編碼時,需要確保整個處理流程中的編碼方式一致,以避免出現亂碼或數據丟失等問題。如果shapefile文件是從不同來源獲取的,可能需要先確認其編碼方式,以便在后續(xù)處理中正確讀取和寫入數據。在進行編碼轉換時,應謹慎操作,以免損壞原始數據。建議在轉換前備份原始文件,并在轉換后進行驗證以確保數據的完整性和準確性。

本文主要講述使用Java編程語言進行地理信息數據解析的時候,遇到Shapefile的屬性信息亂碼的幾種情況,以及根據不同的編碼設置來進行屬性信息的解析。博文首先介紹采用不同的字符集編碼的shapefile文件,然后在Qgis中打開屬性表,查看相關的字符展示情況,接著說明在Java當中調用Geotools時,為經過字符編碼處理和經過字符編碼處理后的對比,讓大家熟悉在Geotools的開發(fā)過程中,掌握字符編碼的設置。

一、Shp文件常見的字符集編碼

為了講解使用不同的編碼來展示空間數據,我們首先來介紹基礎的數據,即三份不同的空間數據格式,其格式都是shapefile的。但是在不同的空間記錄中,其字段的值是采用不同的編碼的。在這里,采用QGIS這款軟件來進行屬性數據的展示,方便大家了解日常中的數據展示。

1、System編碼

第一種要介紹的就是System的編碼方式,這里采用的是用我國的Lake圖層信息,首先我們在Qgis中打開這份數據來看一下,文件的本地路徑為:

F:\vector_data\地理數據20240912\地理數據20240912\水系河流\1 全國1-5級標準河流-wgs84\主要湖泊面文件\Lake.shp

將數據在Qgis軟件中打開可以看到其主要的源信息描述如下:

可以在編碼一欄中看到,這份文件的編碼是System的。 為了看到其里面的屬性信息,可以右鍵點擊shp數據,點擊打開屬性表就可以看到這份數據的完整的數據信息,打開后相關信息如下所示:

在上圖的紅線框中很明顯可以看到,有一列叫NAME的,它的值是有亂碼的,并沒有是我們常見的編碼。 因此這算是亂碼的第一種情況。

2、ISO-8859-1編碼

第二種也是常見的ISO-8859-1編碼,這里準備的數據是一份湖南省的鄉(xiāng)鎮(zhèn)邊界數據,其在文件磁盤中目錄如下,:

C:\BaiduDownload\湖南省\湖南省_鄉(xiāng)鎮(zhèn)邊界.shp

同樣的,我們使用QGis軟件打開上面的鄉(xiāng)鎮(zhèn)邊界.shp文件,打開后可以看到很明確的字符編碼信息:

同樣的我們使用QGIS來進行屬性數據的打開查看, 詳細如下圖所示:

3、UTF-8編碼

這應該算是比較標準的編碼方式,如果進行數據制作的時候,都是統(tǒng)一采用UTF-8的模式,那么這種方式無疑是最好的,估計也不存在字符編碼的問題了。

這個時候,在QGIS中打開屬性表,其屬性字段的內容是正??梢灾苯宇A覽的,詳情如下圖所示。

當然,字符編碼的處理方式根據項目的不同,也會有不同的設置,種類繁多,不甚枚舉,這里僅以這幾項為例作為例子來講解,如果以后在開發(fā)過程中,遇到這種情況,可以根據實際來進行編碼的擴充和修復。

二、GeoTools解析實戰(zhàn)

在上面的一節(jié)中,我們簡單的對三種不同的編碼方式的shapefile文件進行了簡單的介紹,本節(jié)則重點介紹如何使用Java開發(fā)語言,使用GeoTools的開發(fā)組件進行編碼的處理和轉換,將屬性數據可以成功讀取到我們的應用程序中。在這里需要統(tǒng)一說明的是,在進行數據的處理和轉換的時候,為了進行數據的演示,我們僅將數據的前10行數據記載處理,這樣如果有亂碼的問題,我們就可以直接進行干預,通過修改其它的字符集函數的方式來保證文字的識別與處理。

1、未進行字符處理

首先我們來加載UTF-8的矢量數據,測試一下使用UTF-8的情況下,如何使用GeoTools的方法來進行屬性表格的解析。下面來看如何使用GeoTools來進行空間屬性數據的解析與展示,關鍵代碼如下所示:

/**
* * 不做任何處理展示shp文件數據詳情
* 
* @param shpFile shp文件地址
* @throws Exception
*/
protected static void showShpDetails(String shpFile) throws Exception {
	File file = new File(shpFile);
	if (!file.exists()) {
		System.out.println("文件不存在");
		return;
	}
	ShapefileDataStore store = new ShapefileDataStore(file.toURI().toURL());
	String typeName = store.getTypeNames()[0];
	// 創(chuàng)建一個Query對象
	Query query = new Query(typeName);
	// 設置查詢返回的最大特征數為10
	query.setMaxFeatures(10);
	SimpleFeatureSource featureSource = store.getFeatureSource();
	// 執(zhí)行查詢
	SimpleFeatureCollection simpleFeatureCollection = featureSource.getFeatures(query);
	SimpleFeatureIterator itertor = simpleFeatureCollection.features();
	// 遍歷featurecollection
	while (itertor.hasNext()) {
		SimpleFeature feature = itertor.next();
		Collection<Property> p = feature.getProperties();
		Iterator<Property> it = p.iterator();
		// 遍歷feature的properties
		while (it.hasNext()) {
			Property pro = it.next();
			if (null != pro && null != pro.getValue()) {
				String field = pro.getName().toString();
				String value = pro.getValue().toString();
				System.out.println(field + "===" + value);
			}
		}
		System.out.println("-----------------------------------------------------");
	}
}

在上面的代碼中,需要注意的地方就是,我們想要在查詢的時候只查10條,那么就需要使用到GeoTools的查詢Query對象,通過結合Query對象來實現只查10條。10條的設置是個經驗值,可以根據服務器的速度和性能來進行平衡,可以一次處理更多的數據。運行測試用例來看其讀取的結果如下:

可以看到,在IDE的控制臺中,讀取出來的空間屬性信息都是亂碼。

2、亂碼問題的解決

要想解決亂碼的問題,首先要找到根源。我們需要對屬性信息字段進行字符集編碼的控制。因此我們在互聯網上查詢一下,時候有相應的方案。在這里哪怕不管具體的方案,也要了解為什么會出現這個問題。我們來看下ShapefileDataStore這個對象,這個對象是有一個關于字符集的編碼的,如下所示:

如果看過源碼的話,各位小伙伴會發(fā)現,在GeoTools中有默認的編碼集,即:Charset charset = DEFAULT_STRING_CHARSET;

public static final Charset DEFAULT_STRING_CHARSET =
            (Charset) ShapefileDataStoreFactory.DBFCHARSET.getDefaultValue();

其實現的實際邏輯代碼如下:

/**
* Optional - character used to decode strings from the DBF file. If none is provided, the
* factory will instruct {@link ShapefileDataStore} to try to guess a charset from CPG file,
* before using a default value.
*
* @see ShapefileDataStore#setTryCPGFile(boolean)
*/
public static final Param DBFCHARSET =
       new Param(
           "charset",
           Charset.class,
           "character used to decode strings from the DBF file",
           false,
           StandardCharsets.ISO_8859_1,
           new KVP(Param.LEVEL, "advanced")) {
         /*
         * This is an example of a non simple Param type where a custom parse method is required.
        *
         * @see org.geotools.data.DataStoreFactorySpi.Param#parse(java.lang.String)
         */
         @Override
         public Object parse(String text) throws IOException {
              return Charset.forName(text);
         }
         @Override
         public String text(Object value) {
              return ((Charset) value).name();
         }
      };

通過上面的代碼可以看到,這里使用的默認編碼是:StandardCharsets.ISO_8859_1,也就是ISO-8859-1的方式。

3、轉碼支持

了解了亂碼的產生原理之后,我們來進行相應的代碼轉換,關于編碼的轉換有兩種方式,第一種統(tǒng)一在Store一層就進行轉碼。這樣比較單一,也比較簡單。第二種就是在每一個value中進行編程式轉碼,這樣不僅麻煩,而且效率低。為了支持全局處理編碼等,我們將函數進行已統(tǒng)一的封裝,增加了自定義編碼的支持:

/**
* *展示shp文件數據詳情
* 
* @param shpFile      shp文件地址
* @param unifySetting 是否統(tǒng)一設置字符
* @param chartSet     需要設置的字符編碼
* @throws Exception
*/
protected static void showShpDetails(String shpFile, boolean unifySetting, String chartSet) throws Exception {
	File file = new File(shpFile);
	if (!file.exists()) {
		System.out.println("文件不存在");
		return;
	}
	ShapefileDataStore store = new ShapefileDataStore(file.toURI().toURL());
	String typeName = store.getTypeNames()[0];
	// 創(chuàng)建一個Query對象
	Query query = new Query(typeName);
	// 設置查詢返回的最大特征數為10
	query.setMaxFeatures(10);
	if (unifySetting) {
			store.setCharset(Charset.forName(chartSet));// 設置中文字符編碼
	}
	SimpleFeatureSource featureSource = store.getFeatureSource();
	System.out.println(featureSource);
	// 執(zhí)行查詢
	SimpleFeatureCollection simpleFeatureCollection = featureSource.getFeatures(query);
	SimpleFeatureIterator itertor = simpleFeatureCollection.features();
	// 遍歷featurecollection
	while (itertor.hasNext()) {
		SimpleFeature feature = itertor.next();
		Collection<Property> p = feature.getProperties();
		Iterator<Property> it = p.iterator();
		// 遍歷feature的properties
		while (it.hasNext()) {
			Property pro = it.next();
			if (null != pro && null != pro.getValue()) {
				String field = pro.getName().toString();
				String value = pro.getValue().toString();
				if (!unifySetting) {
					// byte[]bytes= value.getBytes("iso8859-1");
					byte[] bytes = value.getBytes();
					value = new String(bytes, chartSet);
				}
				System.out.println(field + "===" + value);
			}
		}
	System.out.println("-------------------------------------------------------------");
	}
}

4、屬性字段編碼結果

下面對集中情況的屬性數據進行解析,將輸出的成果在編輯器的控制臺進行綜合展示。

可以在控制臺中看到以下的數據都是正常的,

org.geotools.data.shapefile.ShapefileFeatureStore@1b6e1eff
the_geom===POINT (113.24947489555838 28.625229546432124)
名稱===南門橋(公交站)
大類===交通設施服務
中類===公交車站
小類===公交車站相關
地址===星通2路
省===湖南省
市===長沙市
區(qū)===長沙縣
WGS84_經===113.249474896
WGS84_緯===28.6252295464

同理,其它的數據如湖南省鄉(xiāng)鎮(zhèn)邊界數據,我們使用編碼后來查看具體的輸出。

同樣的,在控制臺中可以看到以下的輸出,

gml_id===layer_township_pg.15847
Name===星子鎮(zhèn)
layer===鄉(xiāng)鎮(zhèn)
code===441882101000
grade===4
----------------------------------------------------------------------
gml_id===layer_township_pg.15849
Name===三水瑤族鄉(xiāng)
layer===鄉(xiāng)鎮(zhèn)
code===441882201000
grade===4

同樣的,編碼方式是ISO-8859-1的數據經過編碼后正常顯示。 到此,使用Java語言進行GeoTools解析Shp文件的屬性信息時亂碼的問題得到解決。

三、總結

以上就是本文的主要內容,本文主要講述使用Java編程語言進行地理信息數據解析的時候,遇到Shapefile的屬性信息亂碼的幾種情況,以及根據不同的編碼設置來進行屬性信息的解析。博文首先介紹采用不同的字符集編碼的shapefile文件,然后在Qgis中打開屬性表,查看相關的字符展示情況,接著說明在Java當中調用Geotools時,為經過字符編碼處理和經過字符編碼處理后的對比,讓大家熟悉在Geotools的開發(fā)過程中,掌握字符編碼的設置。行文倉促,定有許多不足之處,如有不當之處,還懇請各位專家和博主在評論區(qū)留言支持,不勝感激。

博文在寫作過程中,參考以下,在此表示表示:

1、shapefile與字符集編碼設置。

2、java gdal 創(chuàng)建shapefile屬性中文亂碼。

3、shapefile與字符集編碼設置

4、GeoTools讀取shp文件中文亂碼解決方案匯總。

到此這篇關于在Java中基于GeoTools的Shapefile讀取亂碼的問題解決辦法的文章就介紹到這了,更多相關Java GeoTools的Shapefile讀取亂碼內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳解Mybatis-plus中更新date類型數據遇到的坑

    詳解Mybatis-plus中更新date類型數據遇到的坑

    這篇文章主要介紹了詳解Mybatis-plus中更新date類型數據遇到的坑,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • Springboot+hibernate實現簡單的增刪改查示例

    Springboot+hibernate實現簡單的增刪改查示例

    今天小編就為大家分享一篇Springboot+hibernate實現簡單的增刪改查示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • Spring中管理bean對象的方式(專業(yè)級說明)

    Spring中管理bean對象的方式(專業(yè)級說明)

    在Spring框架中,Bean的管理是核心功能,主要通過IoC(控制反轉)容器實現,下面給大家介紹Spring中管理bean對象的方式,感興趣的朋友一起看看吧
    2025-06-06
  • Redis結合AOP與自定義注解實現分布式緩存流程詳解

    Redis結合AOP與自定義注解實現分布式緩存流程詳解

    項目中如果查詢數據是直接到MySQL數據庫中查詢的話,會查磁盤走IO,效率會比較低,所以現在一般項目中都會使用緩存,目的就是提高查詢數據的速度,將數據存入緩存中,也就是內存中,這樣查詢效率大大提高
    2022-11-11
  • springboot?去掉netflix?禁用Eureka的解決方法

    springboot?去掉netflix?禁用Eureka的解決方法

    這篇文章主要介紹了springboot?去掉netflix?禁用Eureka的解決方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • Java 同步關鍵字 synchronized用法 、場景及避坑指南

    Java 同步關鍵字 synchronized用法 、場景及避坑指南

    synchronized 是 Java 最基礎、最常用的線程同步方式,優(yōu)點是 簡單易用、無需手動釋放鎖、JVM 自動優(yōu)化,適合解決大多數線程安全問題,本文給大家介紹Java 同步關鍵字 synchronized用法 + 場景 + 避坑指南,感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • Spring @Order注解的使用小結

    Spring @Order注解的使用小結

    本文主要介紹了Spring @Order注解的使用小結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-01-01
  • 利用java監(jiān)聽器實現在線人數統(tǒng)計

    利用java監(jiān)聽器實現在線人數統(tǒng)計

    過去使用ASP和ASP.NET兩種編程的時候,都寫過在線人數統(tǒng)計能,實現功能挺簡單的!今天使用java來實現在線人數統(tǒng)計有點另類,是通過Java監(jiān)聽器實現的,需要的朋友可以參考下
    2015-09-09
  • 一文梳理Java超大型文件讀取的18種方法和性能

    一文梳理Java超大型文件讀取的18種方法和性能

    這篇文章主要為大家詳細介紹了Java中超大型文件讀取的18種方法和性能對比,文中的示例代碼簡潔易懂,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-02-02
  • Mybatis使用@param注解四種情況解析

    Mybatis使用@param注解四種情況解析

    這篇文章主要介紹了Mybatis使用@param注解四種情況解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08

最新評論

怀来县| 思茅市| 丰顺县| 沙洋县| 育儿| 汝阳县| 柏乡县| 荥经县| 衡东县| 伊宁县| 休宁县| 延津县| 年辖:市辖区| 留坝县| 凌源市| 韩城市| 徐水县| 旬邑县| 林州市| 叶城县| 屏东县| 峨眉山市| 石首市| 库伦旗| 乌苏市| 盐城市| 隆化县| 三门县| 马山县| 依安县| 苍梧县| 林芝县| 盐池县| 乐清市| 聊城市| 碌曲县| 舒城县| 华安县| 崇仁县| 娄底市| 雅江县|