有时候是完整Geojson,有时候用Geojson片段,用哪个好,官方推荐用哪个?
✅ 很好的问题!
在 GeoTools 中,处理 GeoJSON 时有两种主要工具:
- GeometryJSON ------ 处理 GeoJSON 片段(纯 Geometry)
- FeatureJSON ------ 处理 完整 GeoJSON(Feature / FeatureCollection)
1. 官方推荐 & 最佳实践
| 场景 | 推荐使用 | 原因 |
|---|---|---|
| 只有 Geometry 部分(片段) | GeometryJSON(推荐) | 更轻量、直接得到 Geometry 对象 |
| 完整 GeoJSON(含 properties) | FeatureJSON | 可以同时解析属性(properties)和几何 |
| 不确定是什么格式 | 先判断 type 字段 | 动态选择 |
GeoTools 官方更推荐 :根据输入内容选择对应的解析器,而不是强行用一个。
2. 推荐代码(统一处理两种情况)
Java
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.geojson.feature.FeatureJSON;
import org.locationtech.jts.geom.Geometry;
import java.io.Reader;
import java.io.StringReader;
/**
* 智能判断并解析 GeoJSON(推荐写法)
*/
public static Geometry parseGeoJSON(String jsonText) throws Exception {
String trimmed = jsonText.trim();
// 判断是完整 Feature 还是纯 Geometry
if (trimmed.contains("\"FeatureCollection\"") ||
trimmed.contains("\"Feature\"") && trimmed.contains("\"properties\"")) {
// 完整 GeoJSON → 用 FeatureJSON
FeatureJSON featureJSON = new FeatureJSON();
try (Reader reader = new StringReader(jsonText)) {
// 如果是 FeatureCollection,返回第一个 Feature 的 Geometry(可自行扩展)
return featureJSON.readFeature(reader).getDefaultGeometry();
}
} else {
// 纯 Geometry 片段 → 用 GeometryJSON(最常见)
GeometryJSON geometryJSON = new GeometryJSON(15); // 精度
try (Reader reader = new StringReader(jsonText)) {
return geometryJSON.read(reader);
}
}
}
3. 两种方式详细对比
GeometryJSON(推荐用于片段):
-
优点:简单、轻量、速度快
-
输入示例: JSON
{ "type": "Polygon", "coordinates": [[[116.3,39.9], ...]] } -
输出:直接是 Polygon、MultiPolygon 等 Geometry 对象
FeatureJSON(推荐用于完整 GeoJSON):
-
优点:能同时拿到 properties 属性信息
-
输入示例: JSON
{ "type": "Feature", "properties": { "name": "测试区域", "id": 123 }, "geometry": { "type": "Polygon", ... } }
总结建议
- 大多数情况 (尤其是你之前说的"网格 + GeoJSON"场景)→ 优先使用 GeometryJSON。
- 如果 GeoJSON 里面带有业务属性(name、id、人口等)→ 使用 FeatureJSON。
- 最佳实践 :写一个如上面一样的智能判断方法,兼容两种输入。
你目前遇到的 GeoJSON 主要是哪种?
- 大部分是纯 Geometry 片段?
- 还是经常带 properties 的完整 Feature?
- 需要我给你同时返回 Geometry + 属性 的完整方案吗?
告诉我你的具体使用场景,我可以给你更精确的代码。
postgis求4326坐标多边形面积
在 PostGIS 中,计算 EPSG:4326(WGS84 经纬度)多边形的面积同样面临"单位是度而不是米"的问题。如果你直接调用 ST_Area(geom),得到的结果将是毫无意义的平方度。
PostGIS 提供了两种非常优雅且高效的解决方案,直接在 SQL 层面就能搞定。
方法一:转换为 geography 类型(最推荐、最简便)
PostGIS 专门设计了 geography(地理)类型来处理球面计算。当你把 geometry 强制转换为 geography 时,PostGIS 会自动在地球椭球面上沿着测地线计算面积,返回的单位直接是平方米(m²)。
SQL 语法:
SQL
-- 使用 ::geography 进行类型强转
SELECT ST_Area(geom::geography) AS area_m2 FROM your_table;
-- 如果想换算成平方公里 (km²)
SELECT ST_Area(geom::geography) / 1000000.0 AS area_km2 FROM your_table;
-
优点:极其简单,不需要知道任何投影坐标系代码,全世界任何地方的多边形都能算。
-
缺点:由于是在椭球面上做复杂的三角函数计算,速度比普通的平面几何计算稍慢。
方法二:使用 ST_Transform 动态投影(结合你的业务最精准)
既然你前面的网格数据使用的是 EPSG:4549(CGCS2000 / 3度带高斯克吕格投影),那么最完美的做法是将 4326 的多边形实时投影到 4549 坐标系,然后再计算面积。
SQL 语法:
SQL
-- 先用 ST_Transform 转成平面坐标系,再计算面积
SELECT ST_Area(ST_Transform(geom, 4549)) AS area_m2 FROM your_table;
-
优点:计算速度极快(平面几何公式计算);由于投影坐标系与你的网格数据完全一致,算出来的面积和网格覆盖的实际空间大小能实现完美的空间对应。
-
缺点:只适合局部区域(如中国境内),不能用于跨国或全球大范围的多边形。
总结与选型指南
| 核心函数 | 计算原理 | 返回单位 | 适用场景 |
|---|---|---|---|
ST_Area(geom::geography) |
椭球面几何计算 (WGS84) | 平方米 (m²) | 懒得查坐标系、多边形范围极大、或者跨国数据 |
ST_Area(ST_Transform(geom, 4549)) |
平面高斯投影计算 | 平方米 (m²) | 国内局部区域、需要与其他 4549 数据进行精确空间套合 |
避坑提示 :如果你的 geom 字段在建表时没有指定 SRID(即默认为 0),在使用方法二之前,需要先用 ST_SetSRID(geom, 4326) 告诉数据库它是经纬度,否则 ST_Transform 会因为不知道源坐标系而报错。
Geometry,SimpleFeature,SimpleFeatureCollection分别对应什么geojson格式
这是一个非常敏锐的问题!实际上,GeoTools 的这三个核心类,与 GeoJSON 的规范格式是完全 1:1 完美对应的。它们都遵循了 OGC(开放地理空间联盟)制定的"简单要素标准(Simple Features Standard)"。
为了让你一目了然,我们直接拿一段标准的 GeoJSON 代码来进行"解剖对照":
JSON
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "西湖",
"area_size": 6.39
},
"geometry": {
"type": "Polygon",
"coordinates": [
[ [120.13, 30.25], [120.15, 30.25], [120.14, 30.23], [120.13, 30.25] ]
]
}
}
]
}
下面是它们在数据结构上的绝对映射关系:
1. Geometry 对应 GeoJSON 中的 "geometry" 对象
-
在 JSON 中: 就是上述代码里
"geometry": { ... }包裹的那部分。它只包含两样东西:形状类型(如"Polygon"、"Point")和纯粹的坐标数组("coordinates")。 -
在 GeoTools 中: 它是
org.locationtech.jts.geometry.Geometry(及其子类Point,Polygon,LineString等)。 -
对应关系: 它就是那个纯粹的数学骨架,不带任何业务属性。
2. SimpleFeature 对应 GeoJSON 中的 "Feature" 对象
-
在 JSON 中: 就是上述代码里
"type": "Feature"的整个代码块。它是一个复合体,并列包含了"geometry"(几何)和"properties"(属性字典)。 -
在 GeoTools 中: 它是
org.opengis.feature.simple.SimpleFeature。 -
对应关系: 当你在 Java 中拿到一个
SimpleFeature,你可以调用feature.getDefaultGeometry()拿到上面的形状,也可以调用feature.getAttribute("name")拿到对应的属性值(比如"西湖")。
3. SimpleFeatureCollection 对应 GeoJSON 中的 "FeatureCollection" 对象
-
在 JSON 中: 就是整段代码的最外层,它的
"type"是"FeatureCollection",并且它包含一个名为"features"的数组。 -
在 GeoTools 中: 它是
org.geotools.data.simple.SimpleFeatureCollection。 -
对应关系: 它就是一个大容器。对应在 JSON 里,它负责装载那个包含了成百上千个 Feature 的
[ ... ]数组。
对照总结表
为了方便你后续写代码时快速查阅,可以参考这个对照表:
| GeoTools Java 接口 / 类 | GeoJSON 节点类型 | 包含的内容本质 |
|---|---|---|
SimpleFeatureCollection |
"FeatureCollection" |
整个数据集、图层大容器 |
SimpleFeature |
"Feature" |
一条完整的记录(包含属性 + 形状) |
Geometry (JTS 提供) |
"Geometry" (如 Point/Polygon) |
纯数学坐标组,无业务属性 |
feature.getAttribute("xxx") |
"properties" 里的键值对 |
纯业务属性数据 |