DWG → KML Conversion (one-shot)
Overview
Turn a CAD .dwg into a Google-Earth-ready .kml with a single command. The skill runs a headless pipeline:
DWG ──accoreconsole.exe──▶ DXF ──ezdxf+pyproj──▶ KML ──(optional)──▶ Google Earth
It assumes NOTHING about the coordinate system — it scans the DXF bounds first and decides whether the geometry is WGS84 lon/lat or UTM meters (the #1 cause of "blank / tiny / offset" KML). It then produces a clean KML: one <Folder> per CAD layer, curves smoothed, lines colored by their AutoCAD layer color, red-line / boundary layers highlighted in thick red, and configured closed polylines filled (e.g. 0-j1-1 → yellow 50% transparent).
When to Use
- User sends/attaches a
.dwgand wants a KML or a Google Earth view. - Phrases: "把这个CAD转成KML", "转KML导入Google Earth", "DWG to KML", "总平面图放到地球上", "把红线边界在地球上标出来".
- User already has a
.dxfand just wants the KML → usescripts/dxf_to_kml.pydirectly (skip the DWG→DXF step).
Prerequisites
- AutoCAD installed (any 2013+) on the Windows machine that runs the conversion.
accoreconsole.exeis located automatically; pass--accoreonly if auto-detect fails. - Python packages
ezdxfandpyprojfor the DXF→KML stage:pip install ezdxf pyproj - Google Earth Pro (optional) only if you pass
--geto auto-launch.
Core Workflow — One Command
From the skill's scripts/ directory:
python dwg_to_kml.py "F:/path/总平面布置图.dwg" "output.kml" --ge
That does everything. Common option overrides:
| Option | Default | Meaning |
|--------|---------|---------|
| --epsg | 32748 | UTM EPSG for reprojection (32748 = UTM 48S, used for Indonesian projects). Change per region. |
| --coord | auto | Force utm / lonlat / auto (auto-detect from bounds). |
| --boundary-layer | auto (name match) | Substring to treat as boundary/red-line (thick red). |
| --fill | 0-j1-1:yellow:80 | Repeatable: layer:color:alphahex, e.g. --fill "0-j1-1:yellow:80". |
| --flat | 1.5 | Curve smoothing tolerance in meters (smaller = denser/smoother). |
| --min-x / --min-y | 10000 / 100000 | Drop non-geographic entities (title blocks / frames) below these. |
| --ge | off | Launch Google Earth after writing. |
| --ge-path | auto-detect | Explicit GE exe path (else auto-detect: common dirs / registry / PATH / GOOGLE_EARTH_PATH). |
Core Workflow — Two Steps (if you already have a DXF)
# Step 1: DWG -> DXF (headless, needs AutoCAD)
python dwg_to_dxf.py "input.dwg" "input.dxf"
# Step 2: DXF -> KML (needs ezdxf + pyproj)
python dxf_to_kml.py "input.dxf" "output.kml" --ge
Step Detail: Coordinate-System Detection (READ THIS — the #1 failure mode)
A DXF is useless in Google Earth until you know its coordinate system. Never assume a "谷歌底图" (Google-Earth-backed) DWG stores lon/lat — it almost always stores UTM meters.
The converter auto-detects by scanning coordinate bounds:
| Range pattern | System | Action |
|---------------|--------|--------|
| X≈106~107, Y≈-6~-7 | WGS84 lon/lat | Use directly as lon,lat,0 |
| X≈720000, Y≈9297000 | UTM Zone 48S (EPSG:32748) meters | Reproject before KML |
| X≈0~42000, Y≈0~30000 | Drawing/sheet coords (title block) | Filtered out by --min-x/--min-y |
Real case: 谷歌底图-总平面布置图20260708.dwg had X≈722072, Y≈9297782 → UTM 48S meters, NOT lon/lat. Reprojecting to WGS84 gave 106.9878~107.0076, -6.3606~-6.3491, correctly overlapping the PSEL red-line KML. If you had fed those numbers straight into KML as lon/lat, Google Earth would have shown nothing.
If a new project is outside UTM 48S (e.g. another Indonesian zone or another country), set --epsg accordingly. The converter prints the detected bounds and chosen system so you can verify.
China / CGCS2000 (高斯-克吕格) 用法
中国 DWG 多为 2000 国家大地坐标系 (CGCS2000) 的高斯-克吕格投影米坐标。与 UTM 的关键差异:
- CGCS2000 椭球 = GRS80(与 WGS84 工程尺度下一致,反算经纬度写 KML 误差可忽略)。
- 高斯-克吕格用 k=1.0(UTM 用 0.9996),中央经线 = 3°×带号(3度带)。
- 很多图的坐标不带带号前缀(如
X≈497000, Y≈3058000),此时纯数值无法反推带号——必须用户提供中央经线/带号,否则位置会偏 300km/带。 - 若坐标带带号前缀(如
50497000= 50带),可取 X 高位为带号,自动推中央经线 = 3×带号。
用 --src-crs 传入 proj4 字符串,绕过自动 UTM 判定:
python dxf_to_kml.py input.dxf output.kml \
--src-crs "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs" --ge
lon_0= 中央经线(度)= 3度带带号 × 3(如 39带 → 117)。k=1高斯比例因子;x_0=500000假东偏移;ellps=GRS80= CGCS2000。- 无带号前缀时务必向用户确认带号,再设
lon_0。
实测:Drawing2.dwg(KZD 控制点层,X≈497000 / Y≈3058000,无前缀)→ 萍乡安源区(113.87°E) → 标准计算:带号=round(113.87/3)=38,CM=3×38=114°E → 落 113.97°E, 27.64°N(安源区东部),正确。
标准 3°带优先,自定义任意带仅作兜底: 流程:问用户项目所在区县 → 查区县中心经度 → 带号=round(经度/3),CM=3×带号 → 用标准 CM 反投影。不要默认用项目中心经度做任意带(差 0.1°~0.3° → 偏 10~30km)。仅当用户明确说"独立坐标系/任意带"时才用项目中心经度本身。Drawing2 曾误用 113.87°E 自定义 → 落 113.84°E(偏西 12.8km),后改回标准 114°E 修正。
Step Detail: Curve Smoothing (do NOT read LWPOLYLINE XY directly)
LWPOLYLINE stores arcs as bulge (凸度). Naive get_points('xy') drops them → curves render as straight segments ("不平滑"). The converter uses ezdxf.path.make_path + .flattening(dist) to honor bulge / ARC / SPLINE / ELLIPSE automatically. Tune --flat (meters) for density.
Step Detail: Layer Coloring & Highlight
- Each CAD layer's ACI color is read via
ezdxf.colors.aci2rgband written as a KMLAABBGGRRcolor (alpha first, then BGR). - Boundary / red-line highlight: any layer whose name contains
红线 / 边界 / BOUNDARY / RED(or whose ACI == 1) is drawnwidth=3pure red. Override the match with--boundary-layer.- Note: a layer literally named
1-红线may contain NO geometric entities in some DWGs — verify with the bounds scan /analyze_layers.pyfrom the dwg-to-dxf workflow.
- Note: a layer literally named
- Closed-line fill: for closed polylines on a configured fill layer, emit a
<Polygon>with<PolyStyle>. Default config fills0-j1-1→ yellow, 50% transparent (alpha=0x80). Add more with--fill "layer:color:alphahex".
Step Detail: Launch Google Earth (Windows)
--ge copies the KML to an ASCII temp name (gmap_plan.kml) and launches GE via a generated PowerShell script. This avoids the UTF-8-BOM mojibake that breaks Chinese-path launches, and auto-dismisses the "Crash Detected" dialog (sends TAB+ENTER) — the validated recovery flow.
GE path is auto-detected (no hardcoding). Resolution order: ① --ge-path arg ② GOOGLE_EARTH_PATH env var ③ common paths (Program Files / x86 / LOCALAPPDATA, Pro + standard, also D:/E: drives) ④ Windows Registry ⑤ where.exe PATH lookup. If none found, it prints the KML path and skips launch — the KML is still valid, just open it manually. Supports non-standard installs, other drive letters, non-Pro editions, and shared machines out of the box.
Critical Pitfalls (accumulated from real runs)
DWG → DXF stage (accoreconsole.exe)
- Chinese CAD edition → use
_.prefix. BareDXFOUThangs forever on localized command names. Always_.DXFOUT "out.dxf" 16. - Missing precision arg hangs.
_.DXFOUT "path"with no number waits for interactive input → infinite hang. Always append the precision (16 = full). - UTF-16LE log output. accoreconsole stdout is UTF-16LE; decode with
utf-16lewhen debugging. - Unix-style
/c/...paths break it. accoreconsole is a native Windows binary — usec:/Users/...forward slashes everywhere (input,.scroutput path). - Version match. Match accoreconsole version to the DWG's source CAD version when possible; newer engines may fail silently on older DWGs.
DXF → KML stage
- Coordinate system (see above). Wrong assumption = blank/tiny/offset KML. Always check the printed bounds.
- Title blocks / frames. Non-geographic entities in small coordinates pollute the KML. Filtered by
--min-x/--min-y(default 10000 / 100000). - ACI function name. It is
aci2rgb, NOTaci_to_rgb. - KML color order is AABBGGRR, not RGB. A pure red line is
ff0000ff; 50%-yellow fill is8000ffff. - ACI 7 = white renders as
ffffffff— visible on dark imagery but can vanish on bright satellite. Keep true color; override if needed. - China CGCS2000 with no zone prefix is NOT auto-detectable. If X≈497000 / Y≈3058000 (no
50xxxxxxprefix), the zone number cannot be derived from the numbers alone — Gauss-Kruger and UTM are mathematically equivalent once the prefix is dropped. You MUST ask the user for the project district/county, look up its center longitude, then calculate: zone=round(lon/3), CM=3×zone. Use standard 3° zone by default — do NOT use custom central meridian (project center longitude) unless the user explicitly says "独立坐标系/任意带". A 0.13° CM error → ~13km position offset.
Customization
- Different UTM zone / country: pass
--epsg(e.g.32650for UTM 50N,32749for UTM 49S). - China CGCS2000 Gauss-Kruger: pass
--src-crswith a proj4 string (see "China / CGCS2000" section above).lon_0= 3° × zone number. - Different fill layer:
--fill "你的图层名:green:99"(alpha in hex:80≈50%,99≈60%,CC≈80%). - Different boundary layer name:
--boundary-layer "征地红线". - No AutoCAD on this machine: produce the DXF elsewhere, then run
dxf_to_kml.pydirectly — it only needs Python.
Validation Checklist
After a run, confirm:
[detect]line shows bounds and the correct system (utmfor Indonesian "谷歌底图" files).[ok]line showsentities,layers, andfillscounts > 0.- Open the KML in Google Earth: geometry overlaps the correct location; curves are smooth; boundary layer is thick red; fill polygons render at the right transparency.
- Reused real case:
谷歌底图-总平面布置图20260708→ 11 layers, 2076 points, 0-j1-1 yellow fill, correctly overlapping PSEL red-line at 106.99, -6.35.
Scripts
dwg_to_kml.py— entry point: DWG → DXF → KML (→ GE). One command.dwg_to_dxf.py— DWG → DXF only (accoreconsole wrapper, auto-locates the binary).dxf_to_kml.py— DXF → KML only (coordinate detect, reproject, smooth, color, fill, boundary).launch_ge.py— Windows GE launcher with Crash-dialog auto-dismiss.
Scan to join WeChat group