feat:提交
This commit is contained in:
490
tests/dev1/dataHandle/common/base/Dxf.ts
Normal file
490
tests/dev1/dataHandle/common/base/Dxf.ts
Normal file
@@ -0,0 +1,490 @@
|
||||
export class DxfWritor
|
||||
{
|
||||
layers: WeakSet<Layer>
|
||||
activeLayer: Layer
|
||||
lineTypes: WeakSet<LineType>
|
||||
offX = 0
|
||||
offY = 0 // 基点
|
||||
constructor()
|
||||
{
|
||||
this.layers = new WeakSet()
|
||||
this.activeLayer = null
|
||||
this.lineTypes = new WeakSet()
|
||||
|
||||
for (let i = 0; i < DrawingType.LINE_TYPES.length; ++i)
|
||||
{
|
||||
this.addLineType(
|
||||
DrawingType.LINE_TYPES[i].name,
|
||||
DrawingType.LINE_TYPES[i].description,
|
||||
DrawingType.LINE_TYPES[i].elements,
|
||||
)
|
||||
}
|
||||
|
||||
for (let i = 0; i < DrawingType.LAYERS.length; ++i)
|
||||
{
|
||||
this.addLayer(
|
||||
DrawingType.LAYERS[i].name,
|
||||
DrawingType.LAYERS[i].colorNumber,
|
||||
DrawingType.LAYERS[i].lineTypeName,
|
||||
)
|
||||
}
|
||||
|
||||
this.setActiveLayer('0')
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {string} description
|
||||
* @param {Array} elements - if elem > 0 it is a line, if elem < 0 it is gap, if elem == 0.0 it is a
|
||||
*/
|
||||
addLineType(name, description, elements)
|
||||
{
|
||||
this.lineTypes[name] = new LineType(name, description, elements)
|
||||
return this
|
||||
}
|
||||
|
||||
addLayer(name, colorNumber, lineTypeName)
|
||||
{
|
||||
this.layers[name] = new Layer(name, colorNumber, lineTypeName)
|
||||
return this
|
||||
}
|
||||
|
||||
/** 设置当前图层 白=0, 红=1, 黄=2, 绿=3,CYAN=4,BLUE=5,MAGENTA=6 */
|
||||
setActiveLayer(name)
|
||||
{
|
||||
this.activeLayer = this.layers[name]
|
||||
return this
|
||||
}
|
||||
|
||||
setOffset(x1, y1)
|
||||
{
|
||||
this.offX = x1
|
||||
this.offY = y1
|
||||
}
|
||||
|
||||
clear()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
drawLine(x1, y1, x2, y2)
|
||||
{
|
||||
this.activeLayer.addShape(new Line(x1 + this.offX, y1 + this.offY, x2 + this.offX, y2 + this.offY))
|
||||
return this
|
||||
}
|
||||
|
||||
drawRect(x1, y1, w, h)
|
||||
{
|
||||
x1 = x1 + this.offX
|
||||
y1 = y1 + this.offY
|
||||
this.activeLayer.addShape(new Line(x1, y1, x1 + w, y1))
|
||||
this.activeLayer.addShape(new Line(x1 + w, y1, x1 + w, y1 + h))
|
||||
this.activeLayer.addShape(new Line(x1 + w, y1 + h, x1, y1 + h))
|
||||
this.activeLayer.addShape(new Line(x1, y1 + h, x1, y1))
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x1 - Center x
|
||||
* @param {number} y1 - Center y
|
||||
* @param {number} r - radius
|
||||
* @param {number} startAngle - degree
|
||||
* @param {number} endAngle - degree
|
||||
*/
|
||||
drawArc(x1, y1, r, startAngle, endAngle)
|
||||
{
|
||||
this.activeLayer.addShape(new Arc(x1 + this.offX, y1 + this.offY, r, startAngle, endAngle))
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x1 - Center x
|
||||
* @param {number} y1 - Center y
|
||||
* @param {number} r - radius
|
||||
*/
|
||||
drawCircle(x1, y1, r)
|
||||
{
|
||||
this.activeLayer.addShape(new Circle(x1 + this.offX, y1 + this.offY, r))
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x1 - x
|
||||
* @param {number} y1 - y
|
||||
* @param {number} height - Text height
|
||||
* @param {number} rotation - Text rotation
|
||||
* @param {string} value - the string itself
|
||||
*/
|
||||
drawText(x1, y1, height, rotation, value)
|
||||
{
|
||||
this.activeLayer.addShape(new Text(x1 + this.offX, y1 + this.offY, height, rotation, value))
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array} points - Array of points like [ [x1, y1,r], [x2, y2,r]... ]
|
||||
*/
|
||||
drawPolyline(points, isClose = false)
|
||||
{
|
||||
for (const p of points)
|
||||
{
|
||||
p.x += this.offX
|
||||
p.y += this.offY
|
||||
}
|
||||
this.activeLayer.addShape(new Polyline(points, isClose))
|
||||
return this
|
||||
}
|
||||
|
||||
_getDxfLtypeTable()
|
||||
{
|
||||
let s = '0\nTABLE\n' // start table
|
||||
s += '2\nLTYPE\n' // name table as LTYPE table
|
||||
|
||||
for (let lineTypeName in this.lineTypes)
|
||||
{
|
||||
s += this.lineTypes[lineTypeName].toDxfString()
|
||||
}
|
||||
|
||||
s += '0\nENDTAB\n' // end table
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
_getDxfLayerTable()
|
||||
{
|
||||
let s = '0\nTABLE\n' // start table
|
||||
s += '2\nLAYER\n' // name table as LAYER table
|
||||
|
||||
for (let layerName in this.layers)
|
||||
{
|
||||
s += this.layers[layerName].toDxfString()
|
||||
}
|
||||
|
||||
s += '0\nENDTAB\n'
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
toDxfString()
|
||||
{
|
||||
let s = ''
|
||||
|
||||
// start section
|
||||
s += '0\nSECTION\n'
|
||||
// name section as TABLES section
|
||||
s += '2\nTABLES\n'
|
||||
|
||||
s += this._getDxfLtypeTable()
|
||||
s += this._getDxfLayerTable()
|
||||
|
||||
// end section
|
||||
s += '0\nENDSEC\n'
|
||||
|
||||
// ENTITES section
|
||||
s += '0\nSECTION\n'
|
||||
s += '2\nENTITIES\n'
|
||||
|
||||
for (let layerName in this.layers)
|
||||
{
|
||||
let layer = this.layers[layerName]
|
||||
s += layer.shapesToDxf()
|
||||
// let shapes = layer.getShapes();
|
||||
}
|
||||
|
||||
s += '0\nENDSEC\n'
|
||||
|
||||
// close file
|
||||
s += '0\nEOF'
|
||||
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
namespace DrawingType
|
||||
{
|
||||
// AutoCAD Color Index (ACI)
|
||||
// http://sub-atomic.com/~moses/acadcolors.html
|
||||
export const ACI = {
|
||||
LAYER: 0,
|
||||
RED: 1,
|
||||
YELLOW: 2,
|
||||
GREEN: 3,
|
||||
CYAN: 4,
|
||||
BLUE: 5,
|
||||
MAGENTA: 6,
|
||||
WHITE: 7,
|
||||
}
|
||||
export const LINE_TYPES = [
|
||||
{ name: 'CONTINUOUS', description: '______', elements: [] },
|
||||
{ name: 'DASHED', description: '_ _ _ ', elements: [5.0, -5.0] },
|
||||
{ name: 'DOTTED', description: '. . . ', elements: [0.0, -5.0] },
|
||||
]
|
||||
export const LAYERS = [
|
||||
{ name: '0', colorNumber: ACI.WHITE, lineTypeName: 'CONTINUOUS' },
|
||||
{ name: '1', colorNumber: ACI.RED, lineTypeName: 'CONTINUOUS' },
|
||||
{ name: '2', colorNumber: ACI.YELLOW, lineTypeName: 'CONTINUOUS' },
|
||||
{ name: '3', colorNumber: ACI.GREEN, lineTypeName: 'CONTINUOUS' },
|
||||
{ name: '4', colorNumber: ACI.CYAN, lineTypeName: 'CONTINUOUS' },
|
||||
{ name: '5', colorNumber: ACI.BLUE, lineTypeName: 'CONTINUOUS' },
|
||||
{ name: '6', colorNumber: ACI.MAGENTA, lineTypeName: 'CONTINUOUS' },
|
||||
]
|
||||
}
|
||||
|
||||
export class LineType
|
||||
{
|
||||
name: string
|
||||
description: string
|
||||
elements: any[]
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {string} description
|
||||
* @param {Array} elements - if elem > 0 it is a line, if elem < 0 it is gap, if elem == 0.0 it is a
|
||||
*/
|
||||
constructor(name, description, elements)
|
||||
{
|
||||
this.name = name
|
||||
this.description = description
|
||||
this.elements = elements
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://www.autodesk.com/techpubs/autocad/acadr14/dxf/ltype_al_u05_c.htm
|
||||
*/
|
||||
toDxfString()
|
||||
{
|
||||
let s = '0\nLTYPE\n'
|
||||
s += '72\n65\n'
|
||||
s += '70\n64\n'
|
||||
s += `2\n${this.name}\n`
|
||||
s += `3\n${this.description}\n`
|
||||
s += `73\n${this.elements.length}\n`
|
||||
s += `40\n${this.getElementsSum()}\n`
|
||||
|
||||
for (let i = 0; i < this.elements.length; ++i)
|
||||
{
|
||||
s += `49\n${this.elements[i]}\n`
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
getElementsSum()
|
||||
{
|
||||
let sum = 0
|
||||
for (let i = 0; i < this.elements.length; ++i)
|
||||
{
|
||||
sum += Math.abs(this.elements[i])
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
}
|
||||
|
||||
export class Layer
|
||||
{
|
||||
name: string
|
||||
colorNumber: string
|
||||
lineTypeName: string
|
||||
shapes: any[]
|
||||
constructor(name, colorNumber, lineTypeName)
|
||||
{
|
||||
this.name = name
|
||||
this.colorNumber = colorNumber
|
||||
this.lineTypeName = lineTypeName
|
||||
this.shapes = []
|
||||
}
|
||||
|
||||
toDxfString()
|
||||
{
|
||||
let s = '0\nLAYER\n'
|
||||
s += '70\n64\n'
|
||||
s += `2\n${this.name}\n`
|
||||
s += `62\n${this.colorNumber}\n`
|
||||
s += `6\n${this.lineTypeName}\n`
|
||||
return s
|
||||
}
|
||||
|
||||
addShape(shape)
|
||||
{
|
||||
this.shapes.push(shape)
|
||||
shape.layer = this
|
||||
}
|
||||
|
||||
getShapes()
|
||||
{
|
||||
return this.shapes
|
||||
}
|
||||
|
||||
shapesToDxf()
|
||||
{
|
||||
let s = ''
|
||||
for (let i = 0; i < this.shapes.length; ++i)
|
||||
{
|
||||
s += this.shapes[i].toDxfString()
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
export class Arc
|
||||
{
|
||||
x1: number
|
||||
y1: number
|
||||
r: number
|
||||
startAngle: number
|
||||
endAngle: number
|
||||
layer: Layer
|
||||
/**
|
||||
* @param {number} x1 - Center x
|
||||
* @param {number} y1 - Center y
|
||||
* @param {number} r - radius
|
||||
* @param {number} startAngle - degree
|
||||
* @param {number} endAngle - degree
|
||||
*/
|
||||
constructor(x1, y1, r, startAngle, endAngle)
|
||||
{
|
||||
this.x1 = x1
|
||||
this.y1 = y1
|
||||
this.r = r
|
||||
this.startAngle = startAngle
|
||||
this.endAngle = endAngle
|
||||
}
|
||||
|
||||
toDxfString()
|
||||
{
|
||||
// https://www.autodesk.com/techpubs/autocad/acadr14/dxf/line_al_u05_c.htm
|
||||
let s = `0\nARC\n`
|
||||
s += `8\n${this.layer.name}\n`
|
||||
s += `10\n${this.x1}\n20\n${this.y1}\n30\n0\n`
|
||||
s += `40\n${this.r}\n50\n${this.startAngle}\n51\n${this.endAngle}\n`
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
export class Circle
|
||||
{
|
||||
x1: number
|
||||
y1: number
|
||||
r: number
|
||||
layer: Layer
|
||||
/**
|
||||
* @param {number} x1 - Center x
|
||||
* @param {number} y1 - Center y
|
||||
* @param {number} r - radius
|
||||
*/
|
||||
constructor(x1, y1, r)
|
||||
{
|
||||
this.x1 = x1
|
||||
this.y1 = y1
|
||||
this.r = r
|
||||
}
|
||||
|
||||
toDxfString()
|
||||
{
|
||||
// https://www.autodesk.com/techpubs/autocad/acadr14/dxf/circle_al_u05_c.htm
|
||||
let s = `0\nCIRCLE\n`
|
||||
s += `8\n${this.layer.name}\n`
|
||||
s += `10\n${this.x1}\n20\n${this.y1}\n30\n0\n`
|
||||
s += `40\n${this.r}\n`
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
export class Line
|
||||
{
|
||||
x1: number
|
||||
y1: number
|
||||
x2: number
|
||||
y2: number
|
||||
layer: Layer
|
||||
constructor(x1: number, y1: number, x2: number, y2: number)
|
||||
{
|
||||
this.x1 = x1
|
||||
this.y1 = y1
|
||||
this.x2 = x2
|
||||
this.y2 = y2
|
||||
}
|
||||
|
||||
toDxfString()
|
||||
{
|
||||
// https://www.autodesk.com/techpubs/autocad/acadr14/dxf/line_al_u05_c.htm
|
||||
let s = `0\nLINE\n`
|
||||
s += `8\n${this.layer.name}\n`
|
||||
s += `10\n${this.x1}\n20\n${this.y1}\n30\n0\n`
|
||||
s += `11\n${this.x2}\n21\n${this.y2}\n31\n0\n`
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
export class Polyline
|
||||
{
|
||||
points: any[]
|
||||
isClose = false
|
||||
layer: Layer
|
||||
/**
|
||||
* @param {Array} points - Array of points like [ [x1, y1,r], [x2, y2,r]... ]
|
||||
*/
|
||||
constructor(points, isClose)
|
||||
{
|
||||
this.points = points
|
||||
this.isClose = isClose
|
||||
}
|
||||
|
||||
toDxfString()
|
||||
{
|
||||
// https://www.autodesk.com/techpubs/autocad/acad2000/dxf/polyline_dxf_06.htm
|
||||
// https://www.autodesk.com/techpubs/autocad/acad2000/dxf/vertex_dxf_06.htm
|
||||
let s = `0\nPOLYLINE\n`
|
||||
s += `8\n${this.layer.name}\n`
|
||||
s += `66\n1\n70\n${this.isClose ? 1 : 0}\n`
|
||||
|
||||
for (let i = 0; i < this.points.length; ++i)
|
||||
{
|
||||
s += `0\nVERTEX\n`
|
||||
s += `8\n${this.layer.name}\n`
|
||||
s += `70\n0\n`
|
||||
s += `10\n${this.points[i].x}\n20\n${this.points[i].y}\n42\n${this.points[i].r}\n`
|
||||
}
|
||||
|
||||
s += `0\nSEQEND\n`
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
export class Text
|
||||
{
|
||||
x1: number
|
||||
y1: number
|
||||
height: number
|
||||
rotation: number
|
||||
value: string
|
||||
layer: Layer
|
||||
/**
|
||||
* @param {number} x1 - x
|
||||
* @param {number} y1 - y
|
||||
* @param {number} height - Text height
|
||||
* @param {number} rotation - Text rotation
|
||||
* @param {string} value - the string itself
|
||||
*/
|
||||
constructor(x1, y1, height, rotation, value)
|
||||
{
|
||||
this.x1 = x1
|
||||
this.y1 = y1
|
||||
this.height = height
|
||||
this.rotation = rotation
|
||||
this.value = value
|
||||
}
|
||||
|
||||
toDxfString()
|
||||
{
|
||||
// https://www.autodesk.com/techpubs/autocad/acadr14/dxf/text_al_u05_c.htm
|
||||
let s = `0\nTEXT\n`
|
||||
s += `8\n${this.layer.name}\n`
|
||||
s += `1\n${this.value}\n`
|
||||
s += `10\n${this.x1}\n20\n${this.y1}\n30\n0\n`
|
||||
s += `40\n${this.height}\n50\n${this.rotation}\n`
|
||||
return s
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user