- 新增时标、ΔT 模型、质心时间与 UT1 支持 - 改进日月食、月掩、行星事件及路径边界计算 - 完善恒星三维自行与动态距离传播 - 扩展 SVG、GeoJSON、KML 输出与底层距离换算工具 - 整理中英文手册、示例资源及回归测试
25 KiB
天象地图、GeoJSON 与 KML
本手册的完整示例以仓库根目录为工作目录执行,生成的图片写入
doc/img/。
目录
导出日食 GeoJSON
package main
import (
"fmt"
"log"
"time"
"b612.me/astro/eclipse"
"b612.me/astro/geojson"
)
func main() {
cst := time.FixedZone("CST", 8*3600)
date := time.Date(2009, 7, 22, 0, 0, 0, 0, cst)
partial, ok := eclipse.SolarEclipsePartialFootprints(date,
eclipse.SolarEclipsePartialFootprintOptions{Step: 10 * time.Minute, BoundaryPoints: 180})
if !ok {
log.Fatal("no solar eclipse")
}
path, ok := eclipse.SolarEclipseCentralPath(date,
eclipse.SolarEclipsePathOptions{Step: time.Minute, TargetSpacingKM: 20})
var centralPath *eclipse.SolarEclipsePath
if ok {
centralPath = &path
}
data, err := geojson.MarshalSolarEclipseWithTimeMarkers(partial, centralPath,
geojson.TimeMarkerOptions{Step: 30 * time.Minute, Location: cst})
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data))
}
偏食可以没有中心路径,因此 centralPath 允许为 nil。本例把 GeoJSON 写到标准输出,可重定向到文件;SVG 与 KML 用法见后文。
API 参考
SVG 片段使用导入别名 eclipsesvg "b612.me/astro/eclipse/svg";月掩图使用 moonsvg "b612.me/astro/moon/svg"。日期和时区沿用首例。
| 名称 | 用途 | 备注 |
|---|---|---|
eclipsesvg.EclipseMapProjectionAuto / ...Equirectangular / ...NorthPolar / ...SouthPolar / ...Orthographic |
日月食地图投影 | 零值即自动 |
moonsvg.MapProjectionAuto / ...Equirectangular / ...NorthPolar / ...SouthPolar / ...Orthographic |
月掩地图投影 | 同上 |
SolarEclipseMapSVG / LunarEclipseMapSVG |
日食、月食全球图 | 返回 (string, bool) |
StarOccultationPathSVG / PlanetOccultationPathSVG |
月掩全球掩带图 | 返回 (string, error) |
MarshalSolarEclipse / MarshalSolarEclipseWithTimeMarkers |
日食 GeoJSON | 无/带时间标记 |
MarshalLunarEclipse / MarshalLunarEclipseWithTimeMarkers / MarshalLunarEclipseWithOptions |
月食 GeoJSON | 同上 |
MarshalStarOccultation / MarshalPlanetOccultation(及 ...WithTimeMarkers) |
月掩 GeoJSON | 同上 |
NewSolarEclipseShadowSolver / MarshalSolarEclipseShadowInstant |
单时刻足迹及其 GeoJSON | 拖动时间轴用 |
TimeMarkerOptions |
时间标记 Step、Location、TimeScale |
Step 零值 30 分钟,最多 1440 个 |
astro.TimeScaleUT1 / astro.DUT1 |
UT1 口径与 DUT1 差值 | UT1 时 Location 必须为 UTC |
kml.FromGeoJSON |
把 GeoJSON 转成 KML 2.2 | 只依赖标准库;按 role 分层并给默认调色板 |
常用场景
给事件选投影
for _, spec := range []struct {
name string
p eclipsesvg.EclipseMapProjection
}{
{"equirectangular", eclipsesvg.EclipseMapProjectionEquirectangular},
{"north-polar", eclipsesvg.EclipseMapProjectionNorthPolar},
{"south-polar", eclipsesvg.EclipseMapProjectionSouthPolar},
{"orthographic", eclipsesvg.EclipseMapProjectionOrthographic},
} {
svg, ok := eclipsesvg.SolarEclipseMapSVG(date, eclipsesvg.SolarEclipseMapSVGOptions{
Width: 1200, Height: 800, Location: cst, Projection: spec.p,
})
fmt.Println(spec.name, ok, len(svg))
}
equirectangular true 265827
north-polar true 181602
south-polar true 91902
orthographic true 537001
投影只影响 SVG 表达、不改变底层 WGS84 地理结果;Auto(零值)按事件自动选极图,需要固定版式时才显式指定。正射球面视点取食甚点、只画朝向视点的半球,并切换成 NASA 摆法版式——代价与底图反解过程见地图投影。
导出 GeoJSON 与时间标记
data, err := geojson.MarshalSolarEclipseWithTimeMarkers(partial, centralPath,
geojson.TimeMarkerOptions{Step: 30 * time.Minute, Location: cst})
fmt.Println(err, json.Valid(data), len(data))
<nil> true 426253
WithTimeMarkers会追加role=time-marker的 Point 要素:label按Location本地化显示,time始终是 UTC RFC 3339。Step零值为 30 分钟,正值至少 1 分钟,单次导出最多 1440 个标记;不需要标记就用不带后缀的MarshalSolarEclipse。- 月食与月掩有对称入口(
MarshalLunarEclipse*、MarshalStarOccultation*、MarshalPlanetOccultation*);GeoJSON 不携带底图、边界、样式或投影,Web Mercator 与瓦片选择由应用决定。
时标声明与 UT1
fmt.Println(astro.DUT1(date)) // UT1−UTC,单位秒
0.23
出图默认按 UTC 口径并在图上或图注声明;TimeScale: astro.TimeScaleUT1 改成 UT1 读数并在图里写出 DUT1 = UT1−UTC = +0.23 s,此时 Location 必须是 UTC。GeoJSON 的对应成员是 time_scale(UTC 口径省略,UT1 口径写 "UT1"),完整约定见时标声明。
单时刻足迹与图层词表
solver := eclipse.NewSolarEclipseShadowSolver(eclipse.SolarEclipseShadowSolverOptions{})
instant, ok := solver.ShadowAt(date)
shadow, err := geojson.MarshalSolarEclipseShadowInstant(instant)
fmt.Println(ok, err, json.Valid(shadow), len(shadow))
true <nil> true 4217
- 单时刻接口只算"这一瞬间的本影/半影足迹"与站心日月几何,不产生可见带、食分线、升落边界或南北界;本影不在地球上时返回空值而不是错误。
- 插值前先比
interp_signature:只有相同的相邻时刻才适合按顶点插值,closed翻转、段数/顶点数变化、空↔非空(U1/U4 附近)都必须改取精确几何。 - 可降级图层用
data-source标注实际几何来源,取值词表见地图投影。
地图投影
日食、月食与月掩的 SVG 共用同一套投影:等经纬、北极方位等距、南极方位等距与正射球面。投影只影响 SVG 表达,不改变底层 WGS84 地理结果;日食与月掩的自动投影(零值 ...Auto)会在适合时选择极图,月食默认使用等经纬投影。
| 投影 | 常量(日食/月食 · 月掩) | 适用场景 | 画布建议 |
|---|---|---|---|
| 自动 | EclipseMapProjectionAuto · MapProjectionAuto |
默认;按事件自动选极图 | 1200×800 |
| 等经纬 | ...Equirectangular |
跨反经线的长食带或掩带 | 1200×800、1414×1000 |
| 北极/南极方位等距 | ...NorthPolar / ...SouthPolar |
事件整体落在高纬 | 1200×800、1000×1414 |
| 正射球面 | ...Orthographic |
NASA 版式的半球图,视点取事件中心 | 1000×1414 |
EclipseMapProjectionOrthographic / MapProjectionOrthographic 以食甚点(月掩取事件中心)为视点,只显示朝向视点的半球。该投影使用 NASA 风格的居中球面版式,建议画布为 1000×1414。
同一事件批量出四种投影:
date := time.Date(2009, 7, 22, 12, 0, 0, 0, cst)
for _, spec := range []struct {
name string
p eclipsesvg.EclipseMapProjection
}{
{"equirectangular", eclipsesvg.EclipseMapProjectionEquirectangular},
{"north-polar", eclipsesvg.EclipseMapProjectionNorthPolar},
{"south-polar", eclipsesvg.EclipseMapProjectionSouthPolar},
{"orthographic", eclipsesvg.EclipseMapProjectionOrthographic},
} {
options := eclipsesvg.SolarEclipseMapSVGOptions{
Width: 1200, Height: 800, Location: cst, Projection: spec.p,
}
svg, ok := eclipsesvg.SolarEclipseMapSVG(date, options)
if !ok {
continue
}
_ = os.WriteFile("solar-eclipse-"+spec.name+".svg", []byte(svg), 0o644)
}
各族的选项、图层开关与带图示例见日食与月食手册与月掩手册;GeoJSON 侧只携带地理结果,投影由应用自行选择。
可降级的图层用 data-source 标注实际几何来源,取值词表见 eclipse/svg 包注释:partial-band-union、sampled-footprint-sweep、partial-band-contours、rise-set-phase-lines、magnitude-contours、greatest-time-isochrones、besselian-critical-envelope、paired-limit-chords、sampled-open-sweep、central-path-limits、penumbral-outlines、central-shadow-outlines、p1-p4-visibility-regions、p1-p4-horizon-boundaries。
时标声明
图内时刻的口径由 TimeScale 选项决定,日食全球图、月食全球图、月食详细版式与月掩三族图都会在图上或图注里写明:
- 默认(
astro.TimeScaleUTC,零值):写图中时刻为 UTC;展示时区不是 UTC 时写图中时刻为 UTC(显示时区 CST,UTC+08:00),把时标与展示时区分开声明。 astro.TimeScaleUT1:写图中时刻为 UT1(世界时),DUT1 = UT1−UTC = +0.05 s。,差值随事件日期变化;此时Location必须是 UTC,否则渲染返回false(月掩侧直接返回错误)。
GeoJSON 侧的对应成员是 time_scale:UTC 口径省略该成员,UT1 口径写 "UT1",表示所有 time 字符串与 HH:MM 标注都是 UT1 读数(RFC 3339 的 Z 后缀严格说不等于 UT1)。切时标不改掩带、足迹、地平线与等值线几何,只有写出的时刻文字换成 UT1 读数;时间标记按输出时标的整点取点(整点读数本身就是另一个物理时刻),位置随所标时刻移动。
GeoJSON
geojson 接收已经计算好的日食、月食或月掩结果,返回 []byte。这段字节是完整的 UTF-8 RFC 7946 FeatureCollection JSON,不是图片,也不是压缩数据,可以直接写入 .geojson、交给 encoding/json,或发送给前端地图组件。
package main
import (
"encoding/json"
"fmt"
"time"
"b612.me/astro/eclipse"
"b612.me/astro/geojson"
)
func main() {
date := time.Date(2024, 4, 8, 0, 0, 0, 0, time.UTC)
partial, ok := eclipse.SolarEclipsePartialFootprints(
date,
eclipse.SolarEclipsePartialFootprintOptions{
Step: 10 * time.Minute, BoundaryPoints: 180,
},
)
if !ok {
return
}
central, hasCentral := eclipse.SolarEclipseCentralPath(
date,
eclipse.SolarEclipsePathOptions{Step: time.Minute, TargetSpacingKM: 20},
)
var centralPath *eclipse.SolarEclipsePath
if hasCentral {
centralPath = ¢ral
}
data, err := geojson.MarshalSolarEclipseWithTimeMarkers(
partial, centralPath,
geojson.TimeMarkerOptions{
Step: 30 * time.Minute,
Location: time.FixedZone("CST", 8*3600),
},
)
fmt.Println(err, json.Valid(data))
}
对应的无时间标记和带时间标记入口包括:
MarshalSolarEclipse/MarshalSolarEclipseWithTimeMarkersMarshalLunarEclipse/MarshalLunarEclipseWithTimeMarkersMarshalLunarEclipseWithOptions:用LunarEclipseOptions一次给出时间标记、SkipRoles与时间包络的采样档位。SkipRoles可跳过时间包络和仅见半影带;跳过两个时间包络时不会执行包络采样。EnvelopeSweepSamples默认 48,限制在[2, 192];EnvelopeLongitudePoints默认max(360, boundaryPoints),限制在[12, 720]。MarshalStarOccultation/MarshalStarOccultationWithTimeMarkersMarshalPlanetOccultation/MarshalPlanetOccultationWithTimeMarkersMarshalSolarEclipseWithOptions:用SolarEclipseOptions一次给出时间标记与SkipRoles,等价于上面的日食入口再加图层裁剪。SkipRoles里最常用的是partial-footprint(瞬时半影轮廓);partial-band是日食带边缘(食分 0 界限),通常要留着。
图层筛选
SolarEclipseOptions.SkipRoles 按 role 排除输出要素,零值保留全部图层。可通过 MarshalSolarEclipseWithOptions 同时指定时间标记与筛选条件。
筛选发生在编码阶段,几何仍按完整采样计算。因此,跳过 partial-footprint 会去掉逐时刻的半影足迹,但不会降低总偏食区边缘 partial-band 的精度,也不影响中心带、食分线和升落边界。全部要素被排除时返回错误。
坐标、时间与反经线
坐标为 WGS84 [经度, 纬度],单位度。跨反经线的线和面会拆分,并在接缝两侧补出同一个交点。触及极点的环用 [±180, ±90] 两个坐标表示同一极点。
闭合环含有用于闭合的 ±180° 接缝段。填充时需要这些边;描绘真实边界时应跳过接缝。band-outline、total-band-outline 等闭合轮廓线也需按此规则处理。
带时间路径的 times 与各段坐标逐点对应。WithTimeMarkers 额外加入 role=time-marker 的 Point 要素:label 用于显示,默认 time 为 UTC RFC 3339;显式选择 UT1 时由 time_scale 区分。详见时标。
TimeMarkerOptions 字段 |
行为 |
|---|---|
Step |
零值为 30 分钟,正值至少 1 分钟;一次导出最多 1440 个标记 |
Location |
标签的显示时区,nil 使用 UTC |
TimeScale |
默认 UTC;UT1 要求 Location 为 nil 或 time.UTC |
GeoJSON 不携带底图、样式或投影,应用可自行选择瓦片、Web Mercator 或极区投影。
按时刻计算日食阴影
交互地图按时间查询阴影时,可复用 eclipse.NewSolarEclipseShadowSolver 返回的求解器:
| 方法 | 输入与结果 |
|---|---|
ShadowAt(date) |
民用 time.Time,返回瞬时全球阴影足迹 |
ShadowAtJDE(jdeTT) |
TT 儒略日,返回相同类型的足迹 |
StationStateAt / StationStateAtJDE |
指定时刻与站点的食分、遮蔽率、站心角距、视半径、太阳高度/方位与全食/环食状态 |
ShadowBetween(start, end, step) |
按步长返回足迹序列,无阴影的时刻保留空条目 |
StationStatesBetween |
按时间采样站点状态 |
默认计算本影或反本影;Kind: SolarEclipseShadowPenumbra 改为半影。单时刻接口不计算整场事件的可见带、食分线、南北限或中心线;阴影不在地球上时返回空结果。
geojson.MarshalSolarEclipseShadowInstant(instant) 将结果编码为 GeoJSON。输出属性包括 time、source_boundary_closed、geometry_role、closure、delta_t_seconds、model 与 interp_signature。没有阴影时返回空 FeatureCollection。
| 阴影 | 区域 role | 物理边界 role |
|---|---|---|
| 本影/反本影 | central-shadow-footprint |
central-shadow-boundary |
| 半影 | partial-footprint |
partial-footprint-boundary |
单时刻半影与整场偏食采样使用相同的默认边界参数(96 点、200 km 加密),可以对照同一时刻的结果。已有单机测量中,96 点瞬时足迹约 64 µs,站点瞬时状态约 20 µs;这些数据只用于估算成本,首次查询和批量查询会受缓存状态影响。
地平线闭合与插值
central-shadow-footprint 只输出 Polygon 或 MultiPolygon。被地平线切断时,物理边界延伸到两个地平擦地点,再沿地平弧闭合为覆盖区域;此时 source_boundary_closed=false,closure 用 kind、time、subsolar 描述闭合弧。
只画真实阴影边缘时使用 central-shadow-boundary;需要填色时使用 footprint。阴影在 U1/U4 收缩为空时不输出该要素,不会退化成折线。source_boundary_closed=true 表示物理边界本身已经闭合。
采样的半影足迹也带这些属性。足迹是瞬时覆盖区域,静态掩带是整场事件的包络,两者不能互相替代。
相邻帧可先比较 interp_signature,例如 umbra-closed-seg1-pt97。只有签名一致、分段数与顶点数对应时才适合按顶点插值;这不代表插值具有严格误差上界。闭合状态改变、反经线分段改变或空/非空切换时,应查询精确几何。
移动距离也会随事件阶段变化:已有两分钟采样的对照中,足迹质心在中段移动约 78–232 km,接触附近可达约 520 km。因此不能仅凭固定时间步长判断动画误差。
ΔT 与地面位置
求解器的 DeltaTSeconds > 0 可为该句柄指定 ΔT;小于等于 0 时采用进程级模型。结果回传实际使用的值。
同一 TT 下,改变 ΔT 会改变地球自转相位,而不改变日月在空间中的相对几何。地面经向位移的近似量级为 0.4651 × |ΔΔT| × cos(纬度) 千米,函数 basic.DeltaTGroundShiftKM 可用于换算。库不提供 ΔT 不确定度模型,误差输入需由调用方给出。
月掩瞬时足迹
moon.StarOccultationFootprintAt / moon.PlanetOccultationFootprintsAt 的结果可传给 geojson.MarshalStarOccultationFootprint / MarshalPlanetOccultationFootprints。
它们同样输出 delta_t_seconds、source_boundary_closed、geometry_role 和 interp_signature。月球地平线闭合采用 closure.kind=target-horizon、body=moon 与 sublunar 月下点。月掩计算沿用进程级 ΔT,并在结果中报告实际值。
先查事件再计算几何
只需要事件列表时,可先用 eclipse.SolarEclipseCandidates(start, end, options) 获取食甚时刻、食型、中心食类型、食分、伽马和可选沙罗信息;这个结果不包含地理几何。
固定地点的中心食搜索使用 SearchLocalCentralSolarEclipse,选项包括 Kind、MaxYears、Backward、Geometric、Model,返回 (info, status)。status.Exhausted 表示已用尽搜索范围。
MaxYears<=0 使用默认搜索预算(6000 次候选步进,约 992 年)。找到事件后再计算路径、足迹或 SVG,可以避免为不需要的事件生成地图数据。
KML
kml.FromGeoJSON(data []byte, options kml.Options) ([]byte, error) 把 GeoJSON FeatureCollection 转成 KML 2.2。输入可来自本库,也可以是第三方文件;转换器读取已有几何和时间属性,不计算新的星历或动画帧。
转换文件
下面的程序把 eclipse.geojson 转成 eclipse.kml,可在 Google Earth 中打开:
package main
import (
"log"
"os"
"b612.me/astro/kml"
)
func main() {
data, err := os.ReadFile("eclipse.geojson")
if err != nil {
log.Fatal(err)
}
result, err := kml.FromGeoJSON(data, kml.Options{
Name: "2009-07-22 日食",
})
if err != nil {
log.Fatal(err)
}
if err := os.WriteFile("eclipse.kml", result, 0644); err != nil {
log.Fatal(err)
}
}
Options
| 字段 | 零值或默认行为 | 设置后的作用 |
|---|---|---|
Name |
按事件类型与最早时刻推导文档名 | 指定 Document/name |
Language |
"zh" |
"en" 使用英文图层名;未收录的角色保留原始 role |
Styles |
内置配色 | 以 role 或 event/role 为键覆盖样式,后者优先 |
NoLookAt |
自动设置取景 | true 不写 Document/LookAt |
SkipRoles |
保留所有角色 | 按 role 删除整层,包括几何、样式和取景贡献 |
FillContext |
只填充高亮中心带和掩星带 | true 为其他面图层添加浅灰半透明填充 |
NoTimes |
写入输入中存在的时间 | true 不输出时间元素,生成静态叠加 |
图层与样式
要素按 event 和 role 分组到 Folder。同一集合含多个事件类型时,图层名带事件前缀;第三方 event 与 role 也可使用相同的样式覆盖规则。
| 图层 | role | 默认样式 |
|---|---|---|
| 日食中心带与本影 | central-band、central-shadow、central-shadow-footprint、central-shadow-sweep、total-footprint |
红色;面填充约 35% 不透明度 |
| 中心线 | center-line |
黑色,3 px |
| 日食食甚等时线 | greatest-time-line |
绿色 |
| 食分线 | magnitude-line、magnitude-one-envelope |
黄色 |
| 掩星全掩与偏掩带 | total-band、partial-band、total-band-outline、occultation-band |
黄色,带半透明填充 |
| 升落可见边界、月食时间包络、日食偏食带边缘 | visibility-boundary、p1-horizon、p4-horizon、visible-at-p1、visible-at-p4、visible-during-eclipse、visible-throughout-eclipse、日食的 partial-band |
橙色 |
| 仅见半影的月出/月落带 | penumbra-moonrise、penumbra-moonset |
月出蓝紫、月落紫红,带半透明填充 |
| 其他限界、轮廓、足迹与时间标记 | 其他 role |
灰色,面默认只画轮廓 |
Style 的零值字段沿用默认样式:
| 字段 | 含义 |
|---|---|
LineColor |
线色,KML aabbggrr 十六进制 |
FillColor |
面填充色;点和线忽略此项 |
LineWidth |
像素;小于等于 0 时使用默认线宽 |
NoFill |
强制不填充,优先于 FillColor 与默认配色 |
KML 颜色顺序是透明通道、蓝、绿、红。例如 ff0000ff 为不透明红,590000ff 为约 35% 不透明度的红;它与 CSS rrggbb 的顺序不同。
options := kml.Options{
Language: "zh",
Styles: map[string]kml.Style{
"center-line": {LineColor: kml.ColorBlack, LineWidth: 4},
"solar-eclipse/central-band": {FillColor: "590000ff"},
"partial-footprint": {NoFill: true},
},
}
result, err := kml.FromGeoJSON(data, options)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(result))
无填充的面会转成轮廓线。有填充的面与描边分别表示,反经线拆分产生的接缝不作为真实边界绘制。这样既可保持面闭合,也可避免沿 ±180° 经线出现贯穿地图的描边。
时间轴与静态叠加
| GeoJSON 时间数据 | KML 输出 |
|---|---|
单个 time 属性 |
包含该要素全部子几何的 Placemark 带一个 TimeStamp |
MultiLineString 的 times |
按线段拆成 Placemark,各段取首个时间作为 TimeStamp |
| 至少一个有效时间戳 | Document 带覆盖最早至最晚时间戳的 TimeSpan |
time_scale: "UT1" |
先按当前时标模型换回 UTC,再写 <when> |
NoTimes: true |
不输出 TimeStamp 或 TimeSpan |
时间戳保留源数据的小数秒。要素含 label 时用它作名称;自动生成的名称只显示到秒。UT1 数据的原 time_scale 保留在属性中;转换时应与生成 GeoJSON 时使用同一 ΔT 模型。
时间轴中的帧来自输入数据。times 不会让折线上的每个顶点自动变成独立动画帧;需要本影或半影逐时刻变化时,应先用 GeoJSON 侧的采样选项生成这些要素。
Google Earth 会按所选时间窗口隐藏带时间戳的要素。查看静态全路径时可设置 NoTimes: true;播放时则将时间窗口移到事件日期,并调整可见时间段的宽度。
控制文件大小和取景
半影足迹通常覆盖很大区域。密集采样、大量顶点与半透明面重叠都会增加客户端绘制开销;可增大采样步长,或按用途去掉部分图层。
只需要总偏食区边缘和中心食路径时,可跳过 partial-footprint,保留 partial-band:
result, err := kml.FromGeoJSON(data, kml.Options{
SkipRoles: []string{"partial-footprint"},
NoTimes: true,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(string(result))
若在生成 GeoJSON 时已经确定不需要某层,可通过 geojson.MarshalSolarEclipseWithOptions 的 SkipRoles 先排除,减少中间数据。KML 的 SkipRoles 适用于已有文件。
自动取景优先使用中心线、中心带、限界和本影等路径图层,缺少这些图层时再使用全部要素。包络考虑跨反经线情况,LookAt/range 的单位为米,下限 200 km。需要客户端自行定位时设 NoLookAt: true。
属性与输入校验
通过 SkipRoles 筛选后,所有保留要素都具有且值相同的属性才提升到 Document/ExtendedData。其余属性留在各自 Placemark,嵌套对象也会保留;times 已转换成时间戳,不重复写入属性。
坐标至少含经纬度两项。经度超出 ±180° 时回绕,原本的 +180° 与 −180° 保持不变;纬度必须在 ±90° 内。额外的高度分量被忽略,输出采用 clampToGround。
多边形环会补闭合,并调整为外环逆时针、内环顺时针。支持 Point、MultiPoint、LineString、MultiLineString、Polygon、MultiPolygon 和 GeometryCollection。
以下情况返回错误:JSON 或几何类型无效、坐标非有限或纬度越界、时间数组与线段结构不匹配、过滤后没有剩余要素,或所有要素均没有可绘制几何。两个相同坐标组成的单点路径片段会被跳过。输入本来就是空 FeatureCollection 时,返回合法的空 Document。