GeoJSONcn
GeoJSONcn / 技术专栏 / GeoJSON 转 KML / …

GeoJSON 转 KML / SVG / CSV / PNG:四种格式怎么选、怎么转

发布于 2026-07-15 · GeoJSONcn 技术团队 · 阅读约 8 分钟

前面两篇把坐标系和 GeoJSON 本身讲明白了,这篇聊点落地的:数据到手了,怎么变成别人要的格式。这事儿我在 GeoJSONcn 项目里天天干,用户的诉求五花八门。有人要 KML 丢进 Google Earth,有人要 SVG 进设计稿,有人要 CSV 做数据分析,还有人要一张透明背景的 PNG 大图。

先想清楚:你要的是"画"还是"数"?

选格式得先想清楚一件事:

别用错。我见过有人非要把边界导成 CSV 再手动描点,纯属跟自己过不去。

1) GeoJSON → KML(丢进 Google Earth)

KML 是 XML,核心是把坐标从 [lon,lat] 变成 lon,lat,alt。简化版:

function geojsonToKml(geojson) {
  const placemarks = geojson.features.map(f => {
    const coords = f.geometry.coordinates[0]
      .map(c => `${c[0]},${c[1]},0`).join(' ');
    return `<Placemark><name>${f.properties.name || 'unnamed'}</name>
      <Polygon><outerBoundaryIs><LinearRing><coordinates>${coords}</coordinates>
      </LinearRing></outerBoundaryIs></Polygon></Placemark>`;
  }).join('');
  return `<?xml version="1.0"?>
    <kml xmlns="http://www.opengis.net/kml/2.2">
    <Document>${placemarks}</Document></kml>`;
}

注意 KML 坐标是 lon,lat,alt 逗号分隔,跟 GeoJSON 的数组不一样。

2) GeoJSON → SVG(进设计稿 / 前端矢量)

SVG 说白了就是一堆 。把多边形坐标拼成 M x y L x y ... Z 即可(注意 SVG 用屏幕坐标,y 轴朝下,要做个简单的经纬度到像素映射):

function project(lon, lat, bounds, w, h) {
  const x = (lon - bounds.minLon) / (bounds.maxLon - bounds.minLon) * w;
  const y = (bounds.maxLat - lat) / (bounds.maxLat - bounds.minLat) * h;
  return [x, y];
}
function geojsonToSvg(geojson, w = 800, h = 600) {
  const paths = geojson.features.map(f => {
    const d = f.geometry.coordinates[0]
      .map((c, i) => (i === 0 ? 'M' : 'L') + project(...c).join(' ')).join(' ') + ' Z';
    return `<path d="${d}" fill="#cde" stroke="#369" stroke-width="1"/>`;
  }).join('');
  return `<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${h}">${paths}</svg>`;
}

3) GeoJSON → CSV(给数据分析)

这个最简单,把每个要素的核心属性摊平:

function geojsonToCsv(geojson) {
  const rows = geojson.features.map(f =>
    [f.properties.name, f.properties.code, f.geometry.type].join(','));
  return 'name,code,geom_type\n' + rows.join('\n');
}

适合做统计、做透视表。但 CSV 不带几何细节,只能存属性,要还原形状得另存坐标。所以它适合属性分析,不适合空间表达。

4) GeoJSON → PNG(透明背景大图)

这个要在 Canvas 上把多边形画出来再 toDataURL。关键点:导出是用数据重画,不是截图 DOM(这点后面讲水印的时候还会提到)。1080p / 2K / 4K 只是改 Canvas 尺寸,逻辑一样:

function drawToCanvas(geojson, size = 1920) {
  const cv = document.createElement('canvas');
  cv.width = cv.height = size;
  const ctx = cv.getContext('2d');
  // 先投影到像素,再 fill 每个多边形
  geojson.features.forEach(f => ctx.fill());
  return cv.toDataURL('image/png');
}

最后用一张表收一下

目标选原因
Google Earth / 三维地球KML原生支持
设计稿 / 矢量排版SVG无损缩放
Excel / 统计CSV表格友好
静态图片 / 印刷PNG栅格化、可透明

我在 GeoJSONcn 上把这四种导出全做了,用户选省市区一键下载,后端就是上面这几段逻辑的强化版(加了精度控制和批量)。

最后

格式转换不难,难的是别选错格式。记住"看地图用 KML、排版用 SVG、分析用 CSV、出图用 PNG",代码都是几十行的活儿。下一篇聊聊前端怎么把这些 GeoJSON 真正画到屏幕上,Canvas、SVG、地图库到底怎么选。