# NanoDXF **Repository Path**: magicxie/nano-dxf ## Basic Information - **Project Name**: NanoDXF - **Description**: NanoDXF是一个专注于DXF文件格式解析与生成的开源项目,提供简洁高效的API,支持多种CAD应用开发。 - **Primary Language**: Java - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 7 - **Created**: 2026-07-11 - **Last Updated**: 2026-08-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # NanoDXF **Lightweight DXF file parser, writer, and GIS analysis toolkit for surveying use cases.** Pure Java, no third-party CAD dependencies. Auto-detects GBK / UTF-8 encoding. Outputs JTS geometry objects, GeoJSON, Shapefile, GeoPackage, SVG, CSV, ESRI ASCII Grid, and more. --- ## Features - **All major entity types**: LINE / ARC / CIRCLE / ELLIPSE / POINT / TEXT / MTEXT / LWPOLYLINE / POLYLINE / SPLINE / HATCH / INSERT / 3DFACE / SOLID / DIMENSION / LEADER / MULTILEADER / ATTDEF / MLINE / WIPEOUT / IMAGE / TOLERANCE - **OCS/WCS coordinate transform**: Arbitrary Axis Algorithm, correctly restores 3D/rotated entity coordinates (v1.6.0) - **Recursive INSERT expansion**: affine transform (scale → rotate → translate), path-set cycle detection - **Chinese surveying software support**: CASS / EPS / MapMatrix / MapGIS / SuperMap XDATA feature code extraction, ~80 built-in GB/T 20257 mappings - **BYLAYER color inheritance**: ACI 256-color table → layer color → entity color full chain - **Auto encoding detection**: UTF-8 BOM → juniversalchardet → version inference → GBK fallback - **Fault-tolerant parsing**: truncated files, corrupted entities, unknown entity types never abort parsing; errors collected with severity levels (FATAL / WARN / INFO) - **Parse filtering**: `includeLayers` / `excludeLayers` / `includeTypes`, skip irrelevant layers on large files (v1.6.0) - **Multiple output formats**: GeoJSON, Shapefile (2D/3D), GeoPackage, SVG (v1.6.0, zero-dependency vector preview), point-cloud CSV (v1.7.0), ESRI ASCII Grid DEM (v1.7.0) - **DXF write**: 16 entity types + block definitions, R12 / R2007 dual-path, verified with GstarCAD / AutoCAD - **Streaming parse API**: `parseStream(Path)` two-phase lazy stream, low memory for large files - **Spatial index**: `EntityIndex` (JTS STRtree), `query(Envelope)` / `byLayer` / `byType` (v1.5.0) - **Surveying API**: `ContourHelper` (contour grouping/validation), `ElevationAnnotation` (elevation annotation matching) (v1.6.0) - **Topology check API**: `TopologyChecker` with 5 rules (duplicate / self-intersection / zero-length / dangling endpoint / contour crossing) (v1.6.0) - **Topology repair API**: `TopologyFixer` — auto dedup, zero-length removal, endpoint snapping (v1.7.0) - **Polygon reconstruction**: `PolygonBuilder` — LinearRing → Polygon, JTS Polygonizer hole detection (v1.7.0) - **Geometry simplification**: `GeomSimplifier` — vertex reduction (topology-preserving / Douglas-Peucker) (v1.7.0) - **Layer statistics**: `LayerStats` — per-layer count / total length / total area, with unit conversion (v1.7.0) - **DEM construction + ASCII Grid output**: `DemBuilder` Delaunay TIN interpolation, `AscGridWriter` ESRI .asc format (v1.7.0) - **Slope / aspect analysis**: `SlopeAnalyzer` Horn's method 3×3 finite-difference neighborhood (v1.7.0) - **Sheet edge matching**: `SheetEdgeMatcher` — endpoint gap check along vertical/horizontal/arbitrary join edges (v1.7.0) --- ## Quick Start ### Maven Dependency ```xml io.github.z-double nano-dxf 1.7.0 ``` ### Minimal Usage ```java import com.nanodxf.CADParser; import com.nanodxf.ParseResult; import com.nanodxf.entity.CADEntity; // Parse file (auto-detects GBK / UTF-8 encoding) ParseResult result = new CADParser().parse(Paths.get("drawing.dxf")); // Iterate entities for (CADEntity entity : result.getEntities()) { System.out.println(entity.getType() + " layer=" + entity.getLayer()); System.out.println(" geometry=" + entity.geometry()); } result.getErrors().forEach(System.err::println); System.out.println(result.getStats()); ``` ### With Configuration ```java ParseConfig config = ParseConfig.builder() .crs("EPSG:4545") // CGCS2000 3-Degree GK CM 117E .arcTolerance(0.001) // arc discretization chord-height tolerance .includeLayers("等高线", "建筑") // layer whitelist (v1.6.0) .build(); ParseResult result = new CADParser(config).parse(Paths.get("drawing.dxf")); ``` ### Streaming Parse (Low Memory) ```java try (Stream stream = new CADParser().parseStream(Paths.get("large.dxf"))) { stream.filter(e -> CADEntity.Types.LWPOLYLINE.equals(e.getType())) .limit(10_000) .forEach(myProcessor::accept); } ``` --- ## Surveying & Analysis API (v1.6.0 / v1.7.0) ### Contour Grouping and Validation ```java import com.nanodxf.survey.ContourHelper; import com.nanodxf.survey.ContourSet; ContourSet cs = ContourHelper.extract(result.getEntities(), "等高线", "计曲线"); System.out.println(cs.summary()); // Validate: all elevations must be multiples of contour interval List bad = cs.validate(5.0); // 5m contour interval if (!bad.isEmpty()) System.err.println("Anomalous elevations: " + bad); ``` ### Topology Check ```java import com.nanodxf.topology.*; TopologyReport report = TopologyChecker.check(result.getEntities(), TopologyCheckConfig.builder() .rules(TopologyRule.DUPLICATE_ENTITY, TopologyRule.DANGLING_ENDPOINT, TopologyRule.CONTOUR_CROSSING) .contourLayers("等高线", "计曲线") .lineConnectLayers("道路", "水系") .snapTolerance(0.001) .build()); System.out.println(report.summary()); ``` ### Topology Repair ```java import com.nanodxf.topology.*; TopologyFixResult fixed = TopologyFixer.fix(result.getEntities(), TopologyFixConfig.builder() .rules(TopologyRule.DUPLICATE_ENTITY, TopologyRule.ZERO_LENGTH, TopologyRule.DANGLING_ENDPOINT) .snapTolerance(0.01) .build()); System.out.println(fixed.summary()); List cleanEntities = fixed.getEntities(); ``` ### Polygon Reconstruction (LinearRing → Polygon) ```java import com.nanodxf.geometry.PolygonBuilder; List buildings = result.getEntities().stream() .filter(e -> "建筑".equals(e.getLayer())).toList(); List polygons = PolygonBuilder.build(buildings); // hole detection double totalArea = polygons.stream() .mapToDouble(e -> e.geometry().getArea()).sum(); ``` ### Geometry Simplification ```java import com.nanodxf.geometry.GeomSimplifier; import com.nanodxf.geometry.SimplifyMode; // Contour simplification before SVG/Shapefile export List slim = GeomSimplifier.simplify(result.getEntities(), 0.1); // Or simplify ContourSet directly ContourSet simplified = GeomSimplifier.simplifyContours(cs, 0.5); ``` ### Layer Statistics ```java import com.nanodxf.stat.LayerStats; // Raw coordinate units Map stats = LayerStats.compute(result.getEntities()); System.out.println(LayerStats.summary(stats)); // With unit conversion (→ meters / m²) Map stats = LayerStats.compute( result.getEntities(), result.getMetadata()); ``` ### Point Cloud CSV Export ```java import com.nanodxf.output.*; CsvWriteConfig cfg = CsvWriteConfig.builder() .fields(CsvField.X, CsvField.Y, CsvField.Z, CsvField.LAYER, CsvField.FEATURE_CODE) .delimiter(',') .build(); CsvWriter.write(result.getEntities(), Path.of("output.csv"), cfg); ``` ### DEM Construction and Slope Analysis ```java import com.nanodxf.dem.*; import com.nanodxf.survey.*; ContourSet cs = ContourHelper.extract(result.getEntities(), "等高线"); // Build DEM (1m cell size) DemGrid dem = DemBuilder.build(cs, 1.0); // Write ESRI ASCII Grid AscGridWriter.write(dem, Path.of("dem.asc")); // Slope / aspect (Horn's method) SlopeGrid sg = SlopeAnalyzer.analyze(dem); System.out.printf("Mean slope: %.2f°%n", sg.meanSlope()); ``` ### Sheet Edge Matching ```java import com.nanodxf.sheet.*; // Vertical join edge at x = 50000, band ±2m, gap tolerance 0.5m SheetEdgeReport report = SheetEdgeMatcher.matchVertical( entitiesA, entitiesB, 50000.0, 2.0, 0.5); System.out.println(report.summary()); if (!report.isClean()) { for (EdgeGap gap : report.getGaps()) { System.out.printf("Gap: A=%s B=%s dist=%.4f%n", gap.getEntityA().getHandle(), gap.getEntityB().getHandle(), gap.getDistance()); } } ``` --- ## Output Formats ### GeoJSON ```java GeoJsonSerializer ser = new GeoJsonSerializer(result.getMetadata()); String geojson = ser.serialize(result.getEntities(), result.getMetadata()); Files.writeString(Paths.get("output.geojson"), geojson); ``` ### Shapefile ```java ShapefileWriteConfig cfg = ShapefileWriteConfig.builder() .crs("EPSG:4545") .encoding("GBK") .build(); new ShapefileWriter(cfg).write(result.getEntities(), Paths.get("output.shp")); ``` ### SVG (v1.6.0) ```java SvgWriteConfig cfg = SvgWriteConfig.builder() .width(1200).background("#ffffff").build(); String svg = new SvgWriter(cfg).serialize(result.getEntities()); Files.writeString(Paths.get("output.svg"), svg); ``` ### GeoPackage ```java GeoPackageWriteConfig cfg = GeoPackageWriteConfig.builder() .layerName("drawing").crs("EPSG:4545").build(); new GeoPackageWriter(cfg).write(result.getEntities(), Paths.get("output.gpkg")); ``` --- ## API Reference ### ParseResult | Method | Return | Description | |---|---|---| | `getEntities()` | `List` | Model-space entities (INSERT blocks expanded) | | `getErrors()` | `List` | Leveled error list | | `getStats()` | `ParseStats` | Parse time, entity count, error counts | | `getMetadata()` | `DrawingMetadata` | Version, units, CRS metadata | | `index()` | `EntityIndex` | Lazy-built spatial index (STRtree) | ### CADEntity ```java entity.getType() // "LINE" / "ARC" / "LWPOLYLINE" etc. entity.getLayer() // layer name entity.getHandle() // DXF unique ID entity.geometry() // JTS Geometry entity.getProperties() // Map ``` Common property keys (`EntityProperty.*`): | Key | Type | Description | |---|---|---| | `colorRgb` | `int[3]` | RGB color (True Color > ACI > BYLAYER chain) | | `colorAci` | `Integer` | ACI color number | | `text` | `String` | Cleaned TEXT / MTEXT content | | `elevation` | `Double` | Elevation (Z) from LWPOLYLINE / POINT code 38 | | `featureCode` | `String` | CASS / EPS XDATA feature code | | `featureType` | `String` | GB/T 20257 feature name | --- ## Supported DXF Versions | Version string | AutoCAD | Status | |---|---|---| | AC1009 | R12 | ✅ | | AC1015 | R2000 | ✅ | | AC1018 | R2004 | ✅ | | AC1021 | R2007 | ✅ | | AC1024+ | R2010~R2018 | ✅ | --- ## Dependencies | Dependency | Version | Purpose | |---|---|---| | `org.locationtech.jts:jts-core` | 1.19.0 | JTS geometry (includes `DelaunayTriangulationBuilder`) | | `com.googlecode.juniversalchardet:juniversalchardet` | 1.0.3 | Encoding auto-detection | No other runtime dependencies. Requires **Java 17+**. --- ## Build ```bash mvn clean package mvn test ``` --- ## License Apache License 2.0