openlayermap
Version:
openlayer Map Component for Vue 2.0
319 lines (306 loc) • 11 kB
JavaScript
import { SuperMap } from '../../SuperMap'
import { Point } from './Point'
import { Curve } from './Curve'
/**
* @class SuperMap.Geometry.LineString
* @classdesc 几何对象线串类。
* @category BaseTypes Geometry
* @param points - {Array<SuperMap.Geometry.Point>} 用来生成线串的点数组。
* @extends {SuperMap.Geometry.Curve}
*
* @example
* var points = [new SuperMap.Geometry.Point(4933.319287022352, -3337.3849141502124),
* new SuperMap.Geometry.Point(4960.9674060199022, -3349.3316322355736),
* new SuperMap.Geometry.Point(5006.0235999418364, -3358.8890067038628),
* new SuperMap.Geometry.Point(5075.3145648369318, -3378.0037556404409),
* new SuperMap.Geometry.Point(5305.19551436013, -3376.9669111768926)],
* var roadLine = new SuperMap.Geometry.LineString(points);
*/
export class LineString extends Curve {
constructor(points) {
super(points)
this.CLASS_NAME = 'SuperMap.Geometry.LineString'
}
/**
* @function SuperMap.Geometry.LineString.prototype.removeComponent
* @description 只有在线串上有三个或更多的点的时候,才会允许移除点(否则结果将会是单一的点)。
* @param point - {SuperMap.Geometry.Point} 将被删除的点。
* @returns {Boolean} 删除的点。
*/
removeComponent(point) { // eslint-disable-line no-unused-vars
var removed = this.components && (this.components.length > 2)
if (removed) {
super.removeComponent.apply(this, arguments)
}
return removed
}
/**
* @function SuperMap.Geometry.LineString.prototype.getSortedSegments
* @returns {Array} An array of segment objects. Segment objects have properties
* x1, y1, x2, and y2. The start point is represented by x1 and y1.
* The end point is represented by x2 and y2. Start and end are
* ordered so that x1 < x2.
*/
getSortedSegments() {
var numSeg = this.components.length - 1
var segments = new Array(numSeg)
var point1
var point2
for (var i = 0; i < numSeg; ++i) {
point1 = this.components[i]
point2 = this.components[i + 1]
if (point1.x < point2.x) {
segments[i] = {
x1: point1.x,
y1: point1.y,
x2: point2.x,
y2: point2.y
}
} else {
segments[i] = {
x1: point2.x,
y1: point2.y,
x2: point1.x,
y2: point1.y
}
}
}
// more efficient to define this somewhere static
function byX1(seg1, seg2) {
return seg1.x1 - seg2.x1
}
return segments.sort(byX1)
}
/**
* @function SuperMap.Geometry.LineString.prototype.getVertices
* @description 返回几何图形的所有顶点的列表。
* @param nodes - {Boolean} 对于线来说,仅仅返回作为端点的顶点,如果设为false,则返回非端点的顶点
* 如果没有设置此参数,则返回所有顶点。
* @returns {Array} 几何图形的顶点列表。
*/
getVertices(nodes) {
var vertices
if (nodes === true) {
vertices = [
this.components[0],
this.components[this.components.length - 1]
]
} else if (nodes === false) {
vertices = this.components.slice(1, this.components.length - 1)
} else {
vertices = this.components.slice()
}
return vertices
}
/**
* @function SuperMap.Geometry.LineString.calculateCircle
* @description 三点画圆弧
* @param points -{Array<SuperMap.Geometry.Point>} 传入的待计算的初始点串。
* @returns {Array<SuperMap.Geometry.Point>} 计算出相应的圆弧控制点。
* @example
* var points = [];
* points.push(new SuperMap.Geometry.Point(-50,30));
* points.push(new SuperMap.Geometry.Point(-30,50));
* points.push(new SuperMap.Geometry.Point(2,60));
*
* var circle = SuperMap.Geometry.LineString.calculateCircle(points);
*/
static calculateCircle(points) {
if (points.length < 3) {
return points
}
var centerPoint = {}
var p1 = points[0]
var p2 = points[1]
var p3 = points[2]
var R = 0
var dStep = 0
var direc = true
var dRotation = 0
var dRotationBegin = 0
var dRotationAngle = 0
var nSegmentCount = 72
var circlePoints = []
var KTan13 = (p3.y - p1.y) / (p3.x - p1.x)
var B13 = p3.y - KTan13 * p3.x
if ((((p3.x !== p1.x) && (p3.y !== p1.y)) && (p2.y === KTan13 * p2.x + B13)) ||
((p3.x === p1.x) && (p2.x === p1.x)) || ((p3.y === p1.y) && (p2.y === p1.y)) ||
((p3.x === p1.x) && (p3.y === p1.y)) || ((p3.x === p2.x) && (p3.y === p2.y)) || ((p1.x === p2.x) && (p1.y === p2.y))) {
circlePoints.push(p1)
circlePoints.push(p2)
circlePoints.push(p3)
} else {
var D = ((p2.x * p2.x + p2.y * p2.y) - (p1.x * p1.x + p1.y * p1.y)) * (2 * (p3.y - p1.y)) - ((p3.x * p3.x + p3.y * p3.y) -
(p1.x * p1.x + p1.y * p1.y)) * (2 * (p2.y - p1.y))
var E = (2 * (p2.x - p1.x)) * ((p3.x * p3.x + p3.y * p3.y) - (p1.x * p1.x + p1.y * p1.y)) -
(2 * (p3.x - p1.x)) * ((p2.x * p2.x + p2.y * p2.y) - (p1.x * p1.x + p1.y * p1.y))
var F = 4 * ((p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y))
centerPoint.x = D / F
centerPoint.y = E / F
R = Math.sqrt((p1.x - centerPoint.x) * (p1.x - centerPoint.x) + (p1.y - centerPoint.y) * (p1.y - centerPoint.y))
var dis = (p1.x - p3.x) * (p1.x - p3.x) + (p1.y - p3.y) * (p1.y - p3.y)
var cons = (2 * R * R - dis) / (2 * R * R)
cons = cons >= 1 ? 1 : cons
cons = cons <= -1 ? -1 : cons
dRotationAngle = Math.acos(cons) * 180 / Math.PI
if (p3.x === p1.x) {
dRotationAngle = ((centerPoint.x > p1.x && p2.x > p1.x) || (centerPoint.x < p1.x && p2.x < p1.x)) ? (360 - dRotationAngle) : dRotationAngle
} else {
dRotationAngle = ((centerPoint.y > (KTan13 * centerPoint.x + B13) && p2.y > (KTan13 * p2.x + B13)) ||
(centerPoint.y < (KTan13 * centerPoint.x + B13) && p2.y < (KTan13 * p2.x + B13))) ? (360 - dRotationAngle) : dRotationAngle
}
dStep = dRotationAngle / 72
if (p3.y !== p1.y) {
if (p3.x === p1.x) {
if (p3.y > p1.y) {
if (p2.x < p1.x) {
direc = false
}
} else {
if (p2.x > p1.x) {
direc = false
}
}
} else if (p3.x < p1.x) {
if (p2.y < KTan13 * p2.x + B13) {
direc = false
}
} else {
if (p2.y > KTan13 * p2.x + B13) {
direc = false
}
}
} else {
if (p3.x > p1.x) {
if (p2.y > p1.y) {
direc = false
}
} else {
if (p2.y < p1.y) {
direc = false
}
}
}
var K10 = (p1.y - centerPoint.y) / (p1.x - centerPoint.x)
var atan10 = K10 >= 0 ? Math.atan(K10) * 180 / Math.PI : Math.abs(Math.atan(K10) * 180 / Math.PI) + 90
var CY = Math.abs(centerPoint.y)
if ((p1.y === CY) && (CY === p3.y)) {
if (p1.x < p3.x) {
atan10 = atan10 + 180
}
}
var newPY = p1.y - centerPoint.y
circlePoints.push(p1)
for (var i = 1; i < nSegmentCount; i++) {
dRotation = dStep * i
dRotationBegin = atan10
if (direc) {
if (newPY >= 0) {
if (K10 >= 0) {
dRotationBegin = dRotationBegin + dRotation
} else {
dRotationBegin = (180 - (dRotationBegin - 90)) + dRotation
}
} else {
if (K10 > 0) {
dRotationBegin = (dRotationBegin - 180) + dRotation
} else {
dRotationBegin = (90 - dRotationBegin) + dRotation
}
}
} else {
if (newPY >= 0) {
if (K10 >= 0) {
dRotationBegin = dRotationBegin - dRotation
} else {
dRotationBegin = (180 - (dRotationBegin - 90)) - dRotation
}
} else {
if (K10 >= 0) {
dRotationBegin = (dRotationBegin - 180) - dRotation
} else {
dRotationBegin = (90 - dRotationBegin) - dRotation
}
}
}
dRotationBegin = dRotationBegin * Math.PI / 180
var x = centerPoint.x + R * Math.cos(dRotationBegin)
var y = centerPoint.y + R * Math.sin(dRotationBegin)
circlePoints.push(new Point(x, y))
}
circlePoints.push(p3)
}
return circlePoints
}
/**
* @function SuperMap.Geometry.LineString.createLineEPS
* @description 根据点的类型画出不同类型的曲线
* 点的类型有三种, LTypeArc, LTypeCurve, NONE
* @param points -{Array<SuperMap.Geometry.Point>} 传入的待计算的初始点串。
* @returns {Array<SuperMap.Geometry.Point>} 计算出相应的lineEPS控制点。
* @example
* var points = [];
* points.push(new SuperMap.Geometry.Point(-50,30));
* points.push(new SuperMap.Geometry.Point(-30,50,"LTypeArc"));
* points.push(new SuperMap.Geometry.Point(2,60));
* points.push(new SuperMap.Geometry.Point(8,20));
*
* var lineEPS = SuperMap.Geometry.LineString.createLineEPS(points);
*/
static createLineEPS(points) {
var list = []
var len = points.length
if (points == null || len < 2) {
return points
}
for (var i = 0; i < len;) {
var type = points[i].type
if (type === 'LTypeArc') {
var listObj = LineString.createLineArc(list, i, len, points)
list = listObj[0]
i = listObj[1]
} else {
list.push(points[i])
i++
}
}
return list
}
static createLineArc(list, i, len, points) {
if (i === 0) {
let bezierPtsObj = LineString.addPointEPS(points, i, len, 'LTypeArc')
Array.prototype.push.apply(list, bezierPtsObj[0])
i = bezierPtsObj[1] + 1
} else if (i === len - 1) {
var bezierP = [points[i - 1], points[i]]
var bezierPts = LineString.calculateCircle(bezierP)
Array.prototype.push.apply(list, bezierPts)
i++
} else {
let bezierPtsObj = LineString.addPointEPS(points, i, len, 'LTypeArc')
list.pop()
Array.prototype.push.apply(list, bezierPtsObj[0])
i = bezierPtsObj[1] + 1
}
return [list, i]
}
static addPointEPS(points, i, len, type) {
var bezierP = []
var j = i + 1
if (i === 0) {
Array.prototype.push.apply(bezierP, [points[i], points[i + 1]])
} else if (i === len - 1) {
Array.prototype.push.apply(bezierP, [points[i - 1], points[i]])
} else {
Array.prototype.push.apply(bezierP, [points[i - 1], points[i], points[i + 1]])
}
var bezierPts
if (type === 'LTypeCurve') {
bezierPts = LineString.calculatePointsFBZN(bezierP)
} else if (type === 'LTypeArc') {
bezierPts = LineString.calculateCircle(bezierP)
}
return [bezierPts, j]
}
}
SuperMap.Geometry.LineString = LineString