news 2026/9/5 23:28:09

做GIS开发的看过来,用java获取shapefile的编码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
做GIS开发的看过来,用java获取shapefile的编码

在 Java 中判断 Shapefile(.shp)的编码(特别是属性表 .dbf 的编码),由于 Shapefile 本身不直接存储编码信息(除非有.cpg文件),我们可以采取以下策略:

  1. 优先检查是否存在.cpg文件,若有则直接读取其内容;
  2. 若无.cpg文件,则尝试用常见编码(如 UTF-8、GBK)读取 .dbf 文件的字段名或记录内容,通过是否出现乱码或解码异常来判断。

Java 生态中常用读取 Shapefile 的库是GeoTools。下面提供一个完整的 Java 示例代码,使用 GeoTools 实现自动检测编码。具体代码实现如下:

import org.geotools.data.shapefile.ShapefileDataStore; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.data.simple.SimpleFeatureIterator; import org.geotools.data.simple.SimpleFeatureSource; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import java.io.BufferedReader; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; public class ShapefileEncodingDetector { private static final List<String> CANDIDATE_ENCODINGS = Arrays.asList("UTF-8", "GBK", "GB2312"); private static final Pattern CHINESE_PATTERN = Pattern.compile("[\u4e00-\u9fff]"); private static final Pattern OBVIOUS_GARBAGE_PATTERN = Pattern.compile(".*[\?]{2,}.*|[\x00-\x08\x0B\x0C\x0E-\x1F].*"); /** * 严谨检测 Shapefile 编码(JDK 8 兼容) */ public static String detectEncoding(String shpFilePath) { Path shpPath = Paths.get(shpFilePath); if (!shpPath.toString().toLowerCase().endsWith(".shp")) { shpPath = Paths.get(shpFilePath + ".shp"); } // Step 1: Check .cpg file (JDK 8 compatible read) Path cpgPath = shpPath.resolveSibling(shpPath.getFileName().toString().replace(".shp", ".cpg")); if (Files.exists(cpgPath)) { String encodingFromCpg = readCpgFile(cpgPath); if (encodingFromCpg != null && Charset.isSupported(encodingFromCpg)) { System.out.println("[INFO] Encoding from .cpg: " + encodingFromCpg); return encodingFromCpg; } } String bestEncoding = null; // Step 2: Try candidate encodings for (String encoding : CANDIDATE_ENCODINGS) { try { ShapefileDataStore store = new ShapefileDataStore(shpPath.toUri().toURL()); store.setCharset(Charset.forName(encoding)); SimpleFeatureSource source = store.getFeatureSource(); SimpleFeatureType schema = source.getSchema(); boolean valid = true; boolean currentHasChinese = false; // Validate field names for (int i = 0; i < schema.getAttributeCount(); i++) { String fieldName = schema.getDescriptor(i).getLocalName(); if (isObviousGarbage(fieldName)) { valid = false; break; } if (containsChinese(fieldName)) { currentHasChinese = true; } } if (!valid) { store.dispose(); continue; } // Validate first few feature attribute values SimpleFeatureCollection features = source.getFeatures(); SimpleFeatureIterator iter = features.features(); try { int count = 0; while (iter.hasNext() && count < 5) { SimpleFeature feature = iter.next(); for (Object attr : feature.getAttributes()) { if (attr == null) continue; String value = attr.toString(); if (isObviousGarbage(value)) { valid = false; break; } if (containsChinese(value)) { currentHasChinese = true; } } if (!valid) break; count++; } } finally { iter.close(); // JDK 8 没有 try-with-resources for AutoCloseable in older GeoTools? } store.dispose(); if (valid) { if (currentHasChinese) { System.out.println("[INFO] Valid encoding with Chinese detected: " + encoding); return encoding; } else { if (bestEncoding == null) { bestEncoding = encoding; } } } } catch (Exception e) { // Skip this encoding continue; } } if (bestEncoding != null) { System.out.println("[INFO] No Chinese found, using safe fallback: " + bestEncoding); return bestEncoding; } System.out.println("[WARN] All encodings failed, defaulting to UTF-8"); return "UTF-8"; } /** * JDK 8 兼容方式读取 .cpg 文件(纯文本,单行编码名) */ private static String readCpgFile(Path cpgPath) { try { // 使用默认字符集(通常是 UTF-8)读取 .cpg,因为 .cpg 本身是 ASCII/UTF-8 StringBuilder content = new StringBuilder(); try (BufferedReader reader = Files.newBufferedReader(cpgPath)) { String line; while ((line = reader.readLine()) != null) { content.append(line.trim()); break; // .cpg 通常只有一行 } } return content.toString().trim(); } catch (IOException e) { System.err.println("[WARN] Failed to read .cpg file: " + e.getMessage()); return null; } } /** * 判断字符串是否包含中文字符 */ private static boolean containsChinese(String s) { return s != null && CHINESE_PATTERN.matcher(s).find(); } /** * 判断是否为明显乱码 */ private static boolean isObviousGarbage(String s) { if (s == null || s.isEmpty()) return false; if (OBVIOUS_GARBAGE_PATTERN.matcher(s).matches()) { return true; } long badCharCount = 0; for (char c : s.toCharArray()) { if (c == '?' || c == '\ufffd') { badCharCount++; } } return badCharCount >= 2 || (s.length() > 0 && (double) badCharCount / s.length() > 0.3); }

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/24 16:53:48

潮玩一番赏小程序开发玩法分析(附技术落地要点)

随着潮玩经济持续升温&#xff0c;一番赏凭借“梯度奖池100%中奖稀缺性刺激”的核心逻辑&#xff0c;成为小程序开发的热门赛道。不同于普通盲盒的单一抽奖模式&#xff0c;一番赏小程序的核心竞争力在于玩法设计&#xff0c;而玩法落地的关键是技术适配与合规管控。本文立足CS…

作者头像 李华
网站建设 2026/9/4 8:17:42

离谱!裁员裁出新高度了。。。

还记得今年某大厂公布了2024年财报&#xff0c;数据显示&#xff0c;截至2024年12月31日&#xff0c;员工总数为194320人&#xff0c;而截至2023年12月31日&#xff0c;这一数字为219260人。这也意味着&#xff0c;过去一年减员了近24940人。这不是个例——在互联网全面进入存量…

作者头像 李华
网站建设 2026/9/3 14:24:53

php BC MATH扩展函数巧妙进行财务金额四舍五入

结论&#xff1a;bcadd函数操作 0.5 能够实现“四舍五入”。✅ 核心原理&#xff1a;加 0.5 的作用 在十进制中&#xff0c;“四舍五入”的本质是&#xff1a; 如果小数部分 大于等于 0.5&#xff0c;则向上取整&#xff1b;如果小数部分 小于 0.5&#xff0c;则向下取整。 通过…

作者头像 李华
网站建设 2026/8/23 19:15:56

多智能体协作封神!MultiAgentPPT让高质量PPT生成效率暴涨10倍

相信每个职场人都有过被PPT支配的恐惧&#xff1a;为了一份汇报&#xff0c;翻遍十几份资料找数据&#xff0c;熬到半夜梳理逻辑结构&#xff0c;反复调整排版格式&#xff0c;最后还可能因为内容不全面、逻辑不清晰被打回重改。学生党做课题报告、创业者准备融资演示、市场人员…

作者头像 李华
网站建设 2026/8/22 20:11:48

一文讲透|专科生必备的AI论文软件 —— 千笔·专业学术智能体

你是否曾为论文选题发愁&#xff0c;绞尽脑汁却无从下手&#xff1f;是否在深夜面对空白文档&#xff0c;思绪枯竭、无从下笔&#xff1f;又或者&#xff0c;反复修改却总对表达不满意&#xff0c;查重率高得让人心慌&#xff1f;专科生的论文之路本就充满挑战&#xff0c;而千…

作者头像 李华