news 2026/4/18 12:10:14

做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/4/18 11:02:19

让AI听懂“宫商角徵羽”:基于Qwen2-Audio的传统音乐语义解析系统实战

一个能够辨别古琴“羽”音、解析京剧“宫调转徵调”的AI系统是如何炼成的&#xff1f; 当传统五声音阶遇上现代大模型&#xff0c;AI不仅“听见”了音乐&#xff0c;更“听懂”了千年的文化密码。 项目背景&#xff1a;从“听见”到“听懂” 在数字化浪潮的推动下&#xff0c;音…

作者头像 李华
网站建设 2026/4/18 11:00:58

2026年量化交易新手工具清单_从入门到实盘必备

免责声明&#xff1a;本文基于个人使用体验&#xff0c;与任何厂商无商业关系。内容仅供技术交流参考&#xff0c;不构成投资建议。 一、前言 作为一名在期货量化领域深耕了二十年的老交易员&#xff0c;经常有新手朋友问我&#xff1a;“想学量化交易&#xff0c;需要准备哪些…

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

python+vue开发的摄影作品分享活动参与网站-pycharm DJANGO FLASK

文章目录 技术栈选择核心功能模块开发工具配置部署示例注意事项 大数据系统开发流程主要运用技术介绍源码文档获取定制开发/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 技术栈选择 Python后端框架可选Django或Flask&#xff1a; Django&#x…

作者头像 李华
网站建设 2026/4/18 10:18:25

支持多用户独立运营的会员积分营销系统源码,低成本搭建商家会员体系

温馨提示&#xff1a;文末有资源获取方式在数字化营销成为主流的今天&#xff0c;商家对于会员管理与积分营销系统的需求日益迫切。我们全新推出的会员卡积分收银系统源码商业运营版&#xff0c;正是为满足这一市场刚需而生。该系统经过深度优化与重磅升级&#xff0c;现已成为…

作者头像 李华
网站建设 2026/4/18 5:37:57

完美支持多门店统一管理会员营销系统源码 带完整的搭建部署教程

温馨提示&#xff1a;文末有资源获取方式面对激烈的市场竞争&#xff0c;商家如何有效留住顾客并激发持续消费&#xff1f;一套专业的会员卡积分营销系统已成为不可或缺的工具。我们隆重推介这款全新升级的会员卡积分收银系统源码商业运营版&#xff0c;它专为终端商家设计&…

作者头像 李华