引言
在 GIS 开发或数据可视化场景中,GeoJSON 是常用格式,但存在明显痛点:冗余度极高。相邻行政区的公共边界在 GeoJSON 中会被重复存储,导致文件体积大、加载慢。尤其在大数据量场景下,如全国行政区地图,GeoJSON 文件动辄几兆甚至几十兆,极大影响前端加载速度和用户体验。而 TopoJSON 作为 GeoJSON 的拓扑扩展,通过拓扑结构重构地理数据,将重复的地理线段提取为共享弧段,能让文件体积缩小 80% 以上。目前主流的 TopoJSON 生成方案多依赖 Node.js 工具库,对于纯 Java 后端技术栈的开发者极不友好。因此,本文带你纯 Java 手写 TopoJSON 生成器,全程不依赖任何 GIS 库、第三方 JSON 库,原生 JDK 即可运行。
一、原理:为什么需要 TopoJSON
1.1 核心区别
要理解 TopoJSON 的优势,首先要明确它与 GeoJSON 的核心差异——本质是「数据存储方式的不同」。GeoJSON 采用「独立存储」模式,每个地理要素都完整存储自身的所有坐标点,即便两个要素共享一段边界,这段边界的坐标也会在两个要素中分别存储一次。这种方式的优点是结构简单,但缺点也极其明显:数据冗余严重。
而 TopoJSON 采用「共享复用」模式,核心思路是「提取共性、复用弧段」。它会先遍历所有地理要素,将其中重复出现的线段(即共享边界)提取出来,封装成「弧段(Arc)」,再通过索引引用的方式组合成各个地理要素。简单理解:GeoJSON 是「每个图形单独画」,TopoJSON 是「先画所有公共线条,再用这些线条拼接成每个图形」。
1.2 核心结构
标准 TopoJSON 是一个 JSON 对象,包含三个核心部分。第一部分是「type」,固定值为「Topology」。第二部分是「arcs(弧段集)」,本质是一个二维数组,外层存储所有共享弧段,每个弧段包含多个坐标点。第三部分是「objects(要素集)」,用于存储具体的地理要素,每个要素通过「索引引用」的方式关联 arcs 中的弧段。例如,一个多边形要素,其 geometry 中的 arcs 属性,存储的不是具体坐标,而是 arcs 数组的索引。
二、开发环境与前置准备
本项目零依赖、纯原生,仅需基础 JDK 环境即可运行:
- JDK 1.8 及以上
- 任意 Java 开发工具
无需 GIS 专业知识,只需掌握两点:
- 经纬度坐标格式:
[经度,纬度]; - 多边形/线段由连续坐标点组成,相邻要素共享坐标点即可生成共享弧段。
三、纯 Java 代码实现 TopoJSON 生成
前面了解了 TopoJSON 的核心原理,接下来直接上「生产级简易工具类」,拆分核心模块实现,代码可直接复制到项目中使用。
3.1 基础结构与构造函数
先搭建工具类的基础结构,继承抽象转换器,定义核心常量和构造函数,支持默认配置和自定义配置。
package com.example;
import com.example.model.Feature;
import com.example.model.Geometry;
import java.io.IOException;
import java.util.*;
/**
* TopoJSON 生成器工具类(基础版本)
* 实现 {@link TopologyConverter} 接口,使用纯 Java 实现将 GeoJSON 格式转换为 TopoJSON 格式。
* 不依赖任何第三方地理空间库
*/
public class TopoJsonGenerator extends AbstractTopologyConverter {
public ;
;
{
();
}
{
(config);
}
String {
NAME;
}
}


