mirror of
https://github.com/sakitam-fdd/maptalks.plot.git
synced 2026-01-18 16:03:28 +00:00
commit
d9cb5ed3ed
@ -12,4 +12,3 @@ before_script:
|
||||
- sleep 3 # give xvfb some time to start
|
||||
script:
|
||||
- npm run build
|
||||
- npm run karma.test
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
## 0.0.2 (暂时添加所有符号类型)
|
||||
|
||||
* 添加部分点,圆,椭圆,8种箭头类型符号
|
||||
|
||||
## 0.0.1 (完善PlotDraw)
|
||||
|
||||
* 完善PlotDraw
|
||||
* 添加部分geometry构造类(Ployline,Arror,Polygon)
|
||||
* 添加部分geometry构造类(Ployline,Arror,Polygon, Flag)
|
||||
|
||||
## 0.0.0 (搭建框架)
|
||||
|
||||
|
||||
@ -70,6 +70,7 @@ module.exports = [
|
||||
{
|
||||
file: resolve(_package.unpkg),
|
||||
format: 'umd',
|
||||
sourceMap: true,
|
||||
env: 'development'
|
||||
},
|
||||
{
|
||||
|
||||
72
examples/circle.html
Normal file
72
examples/circle.html
Normal file
@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Geometry - Rectangle, Circle, Ellipse and Sector</title>
|
||||
<style type="text/css">
|
||||
html,body{margin:0px;height:100%;width:100%}
|
||||
.container{width:100%;height:100%}
|
||||
</style>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/maptalks@0.36.2/dist/maptalks.css">
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/maptalks@0.36.2/dist/maptalks.min.js"></script>
|
||||
<body>
|
||||
|
||||
<div id="map" class="container"></div>
|
||||
|
||||
<script>
|
||||
var map = new maptalks.Map('map', {
|
||||
center: [-0.113049,51.498568],
|
||||
zoom: 14,
|
||||
attribution: {
|
||||
content: '© <a href="http://osm.org">OpenStreetMap</a> contributors, © <a href="https://carto.com/">CARTO</a>'
|
||||
},
|
||||
baseLayer: new maptalks.TileLayer('base', {
|
||||
urlTemplate: 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
|
||||
subdomains: ['a','b','c','d']
|
||||
})
|
||||
});
|
||||
|
||||
var center = map.getCenter();
|
||||
|
||||
var rectangle = new maptalks.Rectangle(center.add(-0.018,0.012), 800, 700, {
|
||||
symbol: {
|
||||
lineColor: '#34495e',
|
||||
lineWidth: 2,
|
||||
polygonFill: '#34495e',
|
||||
polygonOpacity: 0.4
|
||||
}
|
||||
});
|
||||
console.log(center.add(-0.013,-0.001))
|
||||
var circle = new maptalks.Circle(center.add(0.002,0.008), 500,{
|
||||
symbol: {
|
||||
lineColor: '#34495e',
|
||||
lineWidth: 2,
|
||||
polygonFill: '#1bbc9b',
|
||||
polygonOpacity: 0.4
|
||||
}
|
||||
});
|
||||
var sector = new maptalks.Sector(center.add(-0.013,-0.001), 900, 240, 300, {
|
||||
symbol: {
|
||||
lineColor: '#34495e',
|
||||
lineWidth: 2,
|
||||
polygonFill: 'rgb(135,196,240)',
|
||||
polygonOpacity: 0.4
|
||||
}
|
||||
});
|
||||
|
||||
var ellipse = new maptalks.Ellipse(center.add(0.003,-0.005), 1000, 600, {
|
||||
symbol: {
|
||||
lineColor: '#34495e',
|
||||
lineWidth: 2,
|
||||
polygonFill: 'rgb(216,115,149)',
|
||||
polygonOpacity: 0.4
|
||||
}
|
||||
});
|
||||
|
||||
new maptalks.VectorLayer('vector')
|
||||
.addGeometry([rectangle, circle, sector, ellipse])
|
||||
.addTo(map);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -43,11 +43,10 @@
|
||||
console.log(param.geometry);
|
||||
layer.addGeometry(param.geometry);
|
||||
});
|
||||
var items = ['Polyline', 'Curve',
|
||||
var itemsLeft = ['Point', 'Polyline', 'Curve',
|
||||
'Arc', 'FreeLine', 'AttackArrow',
|
||||
'ClosedCurve', 'FreePolygon',
|
||||
'GatheringPlace', 'Lune', 'Sector', 'Polygon',
|
||||
'RectAngle'].map(function (value) {
|
||||
'GatheringPlace', 'Lune', 'Sector'].map(function (value) {
|
||||
return {
|
||||
item: value,
|
||||
click: function () {
|
||||
@ -55,11 +54,79 @@
|
||||
}
|
||||
};
|
||||
});
|
||||
var itemsCenter = ['AttackArrow', 'DoubleArrow', 'FineArrow',
|
||||
'StraightArrow', 'AssaultDirection', 'SquadCombat', 'TailedAttackArrow', 'TailedSquadCombat'].map(function (value) {
|
||||
return {
|
||||
item: value,
|
||||
click: function () {
|
||||
drawTool.setMode(value).enable();
|
||||
}
|
||||
};
|
||||
});
|
||||
var itemsRight = ['Polygon',
|
||||
'CurveFlag', 'TriangleFlag', 'RectFlag',
|
||||
'RectAngle', 'Circle', 'Ellipse'].map(function (value) {
|
||||
return {
|
||||
item: value,
|
||||
click: function () {
|
||||
drawTool.setMode(value).enable();
|
||||
}
|
||||
};
|
||||
});
|
||||
// left
|
||||
new maptalks.control.Toolbar({
|
||||
position : 'top-left',
|
||||
items: [
|
||||
{
|
||||
item: 'Shape',
|
||||
children: items
|
||||
children: itemsLeft
|
||||
},
|
||||
{
|
||||
item: 'Disable',
|
||||
click: function () {
|
||||
drawTool.disable();
|
||||
}
|
||||
},
|
||||
{
|
||||
item: 'Clear',
|
||||
click: function () {
|
||||
layer.clear();
|
||||
}
|
||||
}
|
||||
]
|
||||
}).addTo(map);
|
||||
// center
|
||||
new maptalks.control.Toolbar({
|
||||
position : {
|
||||
'top' : 20,
|
||||
'left' : 580
|
||||
},
|
||||
items: [
|
||||
{
|
||||
item: 'Shape',
|
||||
children: itemsCenter
|
||||
},
|
||||
{
|
||||
item: 'Disable',
|
||||
click: function () {
|
||||
drawTool.disable();
|
||||
}
|
||||
},
|
||||
{
|
||||
item: 'Clear',
|
||||
click: function () {
|
||||
layer.clear();
|
||||
}
|
||||
}
|
||||
]
|
||||
}).addTo(map);
|
||||
// right
|
||||
new maptalks.control.Toolbar({
|
||||
position : 'top-right',
|
||||
items: [
|
||||
{
|
||||
item: 'Shape',
|
||||
children: itemsRight
|
||||
},
|
||||
{
|
||||
item: 'Disable',
|
||||
|
||||
@ -191,7 +191,11 @@ class PlotDraw extends maptalks.MapTool {
|
||||
const registerMode = this._getRegisterMode()
|
||||
const coordinate = event['coordinate']
|
||||
if (this._geometry) {
|
||||
if (!registerMode.freehand) {
|
||||
if (this.getMode() === 'point') {
|
||||
this.endDraw(event)
|
||||
return
|
||||
}
|
||||
if (!registerMode.freehand && registerMode['limitClickCount'] > 1) {
|
||||
if (MathDistance([
|
||||
coordinate['x'], coordinate['y']], [
|
||||
this._clickCoords[this._clickCoords.length - 1]['x'],
|
||||
|
||||
97
src/geometry/Arrow/AssaultDirection.js
Normal file
97
src/geometry/Arrow/AssaultDirection.js
Normal file
@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Created by FDD on 2017/12/31.
|
||||
* @desc 粗单直箭头
|
||||
* @Inherits maptalks.Polygon
|
||||
*/
|
||||
|
||||
import * as maptalks from 'maptalks'
|
||||
import * as Constants from '../../Constants'
|
||||
import {
|
||||
getThirdPoint,
|
||||
getBaseLength
|
||||
} from '../helper/index'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
|
||||
const _options = {
|
||||
tailWidthFactor: 0.05,
|
||||
headWidthFactor: 0.15,
|
||||
neckWidthFactor: 0.1,
|
||||
headAngle: Math.PI / 4,
|
||||
neckAngle: Math.PI * 0.17741
|
||||
}
|
||||
|
||||
class AssaultDirection extends maptalks.Polygon {
|
||||
constructor (coordinates, options = {}) {
|
||||
super(options)
|
||||
this.type = 'AssaultDirection'
|
||||
this._coordinates = []
|
||||
if (coordinates) {
|
||||
this.setPoints(coordinates)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理插值
|
||||
*/
|
||||
_generate () {
|
||||
try {
|
||||
const count = this._coordinates.length
|
||||
const _points = Coordinate.toNumberArrays(this._coordinates)
|
||||
if (count < 2) return
|
||||
let [points1, points2] = [_points[0], _points[1]]
|
||||
let len = getBaseLength(_points)
|
||||
let tailWidth = len * _options.tailWidthFactor
|
||||
let neckWidth = len * _options.neckWidthFactor
|
||||
let headWidth = len * _options.headWidthFactor
|
||||
let tailLeft = getThirdPoint(points2, points1, Constants.HALF_PI, tailWidth, true)
|
||||
let tailRight = getThirdPoint(points2, points1, Constants.HALF_PI, tailWidth, false)
|
||||
let headLeft = getThirdPoint(points1, points2, _options.headAngle, headWidth, false)
|
||||
let headRight = getThirdPoint(points1, points2, _options.headAngle, headWidth, true)
|
||||
let neckLeft = getThirdPoint(points1, points2, _options.neckAngle, neckWidth, false)
|
||||
let neckRight = getThirdPoint(points1, points2, _options.neckAngle, neckWidth, true)
|
||||
let pList = [tailLeft, neckLeft, headLeft, points2, headRight, neckRight, tailRight]
|
||||
this.setCoordinates([
|
||||
Coordinate.toCoordinates(pList)
|
||||
])
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
setPoints (coordinates) {
|
||||
this._coordinates = !coordinates ? [] : coordinates
|
||||
if (this._coordinates.length >= 1) {
|
||||
this._generate()
|
||||
}
|
||||
}
|
||||
|
||||
_exportGeoJSONGeometry () {
|
||||
const coordinates = Coordinate.toNumberArrays([this.getShell()])
|
||||
return {
|
||||
'type': 'Polygon',
|
||||
'coordinates': coordinates
|
||||
}
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
const opts = maptalks.Util.extend({}, options)
|
||||
opts.geometry = false
|
||||
const feature = this.toGeoJSON(opts)
|
||||
return {
|
||||
'feature': feature,
|
||||
'coordinates': feature['coordinates'],
|
||||
'subType': 'AssaultDirection'
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON (json) {
|
||||
const feature = json['feature']
|
||||
const assaultDirection = new AssaultDirection(json['coordinates'], json['options'])
|
||||
assaultDirection.setProperties(feature['properties'])
|
||||
return assaultDirection
|
||||
}
|
||||
}
|
||||
|
||||
AssaultDirection.registerJSONType('AssaultDirection')
|
||||
|
||||
export default AssaultDirection
|
||||
@ -43,27 +43,27 @@ class AttackArrow extends maptalks.Polygon {
|
||||
if (count === 2) {
|
||||
this.setCoordinates([this._coordinates])
|
||||
} else {
|
||||
let pnts = Coordinate.toNumberArrays(this._coordinates)
|
||||
let [tailLeft, tailRight] = [pnts[0], pnts[1]]
|
||||
if (isClockWise(pnts[0], pnts[1], pnts[2])) {
|
||||
tailLeft = pnts[1]
|
||||
tailRight = pnts[0]
|
||||
let _points = Coordinate.toNumberArrays(this._coordinates)
|
||||
let [tailLeft, tailRight] = [_points[0], _points[1]]
|
||||
if (isClockWise(_points[0], _points[1], _points[2])) {
|
||||
tailLeft = _points[1]
|
||||
tailRight = _points[0]
|
||||
}
|
||||
let midTail = Mid(tailLeft, tailRight)
|
||||
let bonePnts = [midTail].concat(pnts.slice(2))
|
||||
let headPnts = this._getArrowHeadPoints(bonePnts, tailLeft, tailRight)
|
||||
let [neckLeft, neckRight] = [headPnts[0], headPnts[4]]
|
||||
let tailWidthFactor = MathDistance(tailLeft, tailRight) / getBaseLength(bonePnts)
|
||||
let bodyPnts = this._getArrowBodyPoints(bonePnts, neckLeft, neckRight, tailWidthFactor)
|
||||
let count = bodyPnts.length
|
||||
let leftPnts = [tailLeft].concat(bodyPnts.slice(0, count / 2))
|
||||
leftPnts.push(neckLeft)
|
||||
let rightPnts = [tailRight].concat(bodyPnts.slice(count / 2, count))
|
||||
rightPnts.push(neckRight)
|
||||
leftPnts = getQBSplinePoints(leftPnts)
|
||||
rightPnts = getQBSplinePoints(rightPnts)
|
||||
let bonePoints = [midTail].concat(_points.slice(2))
|
||||
let headPoints = this._getArrowHeadPoints(bonePoints, tailLeft, tailRight)
|
||||
let [neckLeft, neckRight] = [headPoints[0], headPoints[4]]
|
||||
let tailWidthFactor = MathDistance(tailLeft, tailRight) / getBaseLength(bonePoints)
|
||||
let bodyPoints = AttackArrow._getArrowBodyPoints(bonePoints, neckLeft, neckRight, tailWidthFactor)
|
||||
let count = bodyPoints.length
|
||||
let leftPoints = [tailLeft].concat(bodyPoints.slice(0, count / 2))
|
||||
leftPoints.push(neckLeft)
|
||||
let rightPoints = [tailRight].concat(bodyPoints.slice(count / 2, count))
|
||||
rightPoints.push(neckRight)
|
||||
leftPoints = getQBSplinePoints(leftPoints)
|
||||
rightPoints = getQBSplinePoints(rightPoints)
|
||||
this.setCoordinates([
|
||||
Coordinate.toCoordinates(leftPnts.concat(headPnts, rightPnts.reverse()))
|
||||
Coordinate.toCoordinates(leftPoints.concat(headPoints, rightPoints.reverse()))
|
||||
])
|
||||
}
|
||||
} catch (e) {
|
||||
@ -100,33 +100,6 @@ class AttackArrow extends maptalks.Polygon {
|
||||
return [neckLeft, headLeft, headPnt, headRight, neckRight]
|
||||
}
|
||||
|
||||
/**
|
||||
* 插值面部分数据
|
||||
* @param points
|
||||
* @param neckLeft
|
||||
* @param neckRight
|
||||
* @param tailWidthFactor
|
||||
* @returns {*|T[]|string}
|
||||
*/
|
||||
_getArrowBodyPoints (points, neckLeft, neckRight, tailWidthFactor) {
|
||||
let allLen = wholeDistance(points)
|
||||
let len = getBaseLength(points)
|
||||
let tailWidth = len * tailWidthFactor
|
||||
let neckWidth = MathDistance(neckLeft, neckRight)
|
||||
let widthDif = (tailWidth - neckWidth) / 2
|
||||
let [tempLen, leftBodyPnts, rightBodyPnts] = [0, [], []]
|
||||
for (let i = 1; i < points.length - 1; i++) {
|
||||
let angle = getAngleOfThreePoints(points[i - 1], points[i], points[i + 1]) / 2
|
||||
tempLen += MathDistance(points[i - 1], points[i])
|
||||
let w = (tailWidth / 2 - tempLen / allLen * widthDif) / Math.sin(angle)
|
||||
let left = getThirdPoint(points[i - 1], points[i], Math.PI - angle, w, true)
|
||||
let right = getThirdPoint(points[i - 1], points[i], angle, w, false)
|
||||
leftBodyPnts.push(left)
|
||||
rightBodyPnts.push(right)
|
||||
}
|
||||
return leftBodyPnts.concat(rightBodyPnts)
|
||||
}
|
||||
|
||||
setPoints (coordinates) {
|
||||
this._coordinates = !coordinates ? [] : coordinates
|
||||
if (this._coordinates.length >= 1) {
|
||||
@ -143,15 +116,46 @@ class AttackArrow extends maptalks.Polygon {
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
const opts = maptalks.Util.extend({}, options)
|
||||
opts.geometry = false
|
||||
const feature = this.toGeoJSON(opts)
|
||||
return {
|
||||
'feature': this.toGeoJSON(options),
|
||||
'feature': feature,
|
||||
'coordinates': feature['coordinates'],
|
||||
'subType': 'AttackArrow'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 插值面部分数据
|
||||
* @param points
|
||||
* @param neckLeft
|
||||
* @param neckRight
|
||||
* @param tailWidthFactor
|
||||
* @returns {*|T[]|string}
|
||||
*/
|
||||
static _getArrowBodyPoints (points, neckLeft, neckRight, tailWidthFactor) {
|
||||
let allLen = wholeDistance(points)
|
||||
let len = getBaseLength(points)
|
||||
let tailWidth = len * tailWidthFactor
|
||||
let neckWidth = MathDistance(neckLeft, neckRight)
|
||||
let widthDif = (tailWidth - neckWidth) / 2
|
||||
let [tempLen, leftBodyPoints, rightBodyPoints] = [0, [], []]
|
||||
for (let i = 1; i < points.length - 1; i++) {
|
||||
let angle = getAngleOfThreePoints(points[i - 1], points[i], points[i + 1]) / 2
|
||||
tempLen += MathDistance(points[i - 1], points[i])
|
||||
let w = (tailWidth / 2 - tempLen / allLen * widthDif) / Math.sin(angle)
|
||||
let left = getThirdPoint(points[i - 1], points[i], Math.PI - angle, w, true)
|
||||
let right = getThirdPoint(points[i - 1], points[i], angle, w, false)
|
||||
leftBodyPoints.push(left)
|
||||
rightBodyPoints.push(right)
|
||||
}
|
||||
return leftBodyPoints.concat(rightBodyPoints)
|
||||
}
|
||||
|
||||
static fromJSON (json) {
|
||||
const feature = json['feature']
|
||||
const attackArrow = new AttackArrow(json['coordinates'], json['width'], json['height'], json['options'])
|
||||
const attackArrow = new AttackArrow(json['coordinates'], json['options'])
|
||||
attackArrow.setProperties(feature['properties'])
|
||||
return attackArrow
|
||||
}
|
||||
|
||||
247
src/geometry/Arrow/DoubleArrow.js
Normal file
247
src/geometry/Arrow/DoubleArrow.js
Normal file
@ -0,0 +1,247 @@
|
||||
/**
|
||||
* Created by FDD on 2017/12/31.
|
||||
* @desc 双箭头
|
||||
* @Inherits maptalks.Polygon
|
||||
*/
|
||||
|
||||
import * as maptalks from 'maptalks'
|
||||
import * as Constants from '../../Constants'
|
||||
import {
|
||||
Mid,
|
||||
getThirdPoint,
|
||||
MathDistance,
|
||||
getBaseLength,
|
||||
wholeDistance,
|
||||
isClockWise,
|
||||
getBezierPoints,
|
||||
getAngleOfThreePoints
|
||||
} from '../helper/index'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
|
||||
const _options = {
|
||||
headHeightFactor: 0.25,
|
||||
headWidthFactor: 0.3,
|
||||
neckHeightFactor: 0.85,
|
||||
neckWidthFactor: 0.15
|
||||
}
|
||||
|
||||
class DoubleArrow extends maptalks.Polygon {
|
||||
constructor (coordinates, options = {}) {
|
||||
super(options)
|
||||
this.type = 'DoubleArrow'
|
||||
this._coordinates = []
|
||||
this.connetPoints = []
|
||||
this.symmetricalPoints = []
|
||||
if (coordinates) {
|
||||
this.setPoints(coordinates)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理插值
|
||||
*/
|
||||
_generate () {
|
||||
try {
|
||||
const count = this._coordinates.length
|
||||
const _points = Coordinate.toNumberArrays(this._coordinates)
|
||||
if (count < 2) return
|
||||
if (count === 2) {
|
||||
this.setCoordinates([this._coordinates])
|
||||
} else {
|
||||
let [pnt1, pnt2, pnt3] = [_points[0], _points[1], _points[2]]
|
||||
if (count === 3) {
|
||||
this.symmetricalPoints = DoubleArrow.getSymmetricalPoints(pnt1, pnt2, pnt3)
|
||||
this.connetPoints = Mid(pnt1, pnt2)
|
||||
} else if (count === 4) {
|
||||
this.symmetricalPoints = _points[3]
|
||||
this.connetPoints = Mid(pnt1, pnt2)
|
||||
} else {
|
||||
this.symmetricalPoints = _points[3]
|
||||
this.connetPoints = _points[4]
|
||||
}
|
||||
let [leftArrowPoints, rightArrowPoints] = [undefined, undefined]
|
||||
if (isClockWise(pnt1, pnt2, pnt3)) {
|
||||
leftArrowPoints = DoubleArrow.getArrowPoints(pnt1, this.connetPoints, this.symmetricalPoints, false)
|
||||
rightArrowPoints = DoubleArrow.getArrowPoints(this.connetPoints, pnt2, pnt3, true)
|
||||
} else {
|
||||
leftArrowPoints = DoubleArrow.getArrowPoints(pnt2, this.connetPoints, pnt3, false)
|
||||
rightArrowPoints = DoubleArrow.getArrowPoints(this.connetPoints, pnt1, this.symmetricalPoints, true)
|
||||
}
|
||||
let m = leftArrowPoints.length
|
||||
let t = (m - 5) / 2
|
||||
let llBodyPoints = leftArrowPoints.slice(0, t)
|
||||
let lArrowPoints = leftArrowPoints.slice(t, t + 5)
|
||||
let lrBodyPoints = leftArrowPoints.slice(t + 5, m)
|
||||
let rlBodyPoints = rightArrowPoints.slice(0, t)
|
||||
let rArrowPoints = rightArrowPoints.slice(t, t + 5)
|
||||
let rrBodyPoints = rightArrowPoints.slice(t + 5, m)
|
||||
rlBodyPoints = getBezierPoints(rlBodyPoints)
|
||||
let bodyPoints = getBezierPoints(rrBodyPoints.concat(llBodyPoints.slice(1)))
|
||||
lrBodyPoints = getBezierPoints(lrBodyPoints)
|
||||
let Points = rlBodyPoints.concat(rArrowPoints, bodyPoints, lArrowPoints, lrBodyPoints)
|
||||
this.setCoordinates([
|
||||
Coordinate.toCoordinates(Points)
|
||||
])
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
setPoints (coordinates) {
|
||||
this._coordinates = !coordinates ? [] : coordinates
|
||||
if (this._coordinates.length >= 1) {
|
||||
this._generate()
|
||||
}
|
||||
}
|
||||
|
||||
_exportGeoJSONGeometry () {
|
||||
const coordinates = Coordinate.toNumberArrays([this.getShell()])
|
||||
return {
|
||||
'type': 'Polygon',
|
||||
'coordinates': coordinates
|
||||
}
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
const opts = maptalks.Util.extend({}, options)
|
||||
opts.geometry = false
|
||||
const feature = this.toGeoJSON(opts)
|
||||
return {
|
||||
'feature': feature,
|
||||
'coordinates': feature['coordinates'],
|
||||
'subType': 'DoubleArrow'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 插值箭形上的点
|
||||
* @param pnt1
|
||||
* @param pnt2
|
||||
* @param pnt3
|
||||
* @param clockWise
|
||||
* @returns {*[]}
|
||||
*/
|
||||
static getArrowPoints (pnt1, pnt2, pnt3, clockWise) {
|
||||
let midPnt = Mid(pnt1, pnt2)
|
||||
let len = MathDistance(midPnt, pnt3)
|
||||
let midPnt1 = getThirdPoint(pnt3, midPnt, 0, len * 0.3, true)
|
||||
let midPnt2 = getThirdPoint(pnt3, midPnt, 0, len * 0.5, true)
|
||||
midPnt1 = getThirdPoint(midPnt, midPnt1, Constants.HALF_PI, len / 5, clockWise)
|
||||
midPnt2 = getThirdPoint(midPnt, midPnt2, Constants.HALF_PI, len / 4, clockWise)
|
||||
let points = [midPnt, midPnt1, midPnt2, pnt3]
|
||||
let arrowPnts = DoubleArrow._getArrowHeadPoints(points)
|
||||
if (arrowPnts && Array.isArray(arrowPnts) && arrowPnts.length > 0) {
|
||||
let [neckLeftPoint, neckRightPoint] = [arrowPnts[0], arrowPnts[4]]
|
||||
let tailWidthFactor = MathDistance(pnt1, pnt2) / getBaseLength(points) / 2
|
||||
let bodyPnts = DoubleArrow._getArrowBodyPoints(points, neckLeftPoint, neckRightPoint, tailWidthFactor)
|
||||
if (bodyPnts) {
|
||||
let n = bodyPnts.length
|
||||
let lPoints = bodyPnts.slice(0, n / 2)
|
||||
let rPoints = bodyPnts.slice(n / 2, n)
|
||||
lPoints.push(neckLeftPoint)
|
||||
rPoints.push(neckRightPoint)
|
||||
lPoints = lPoints.reverse()
|
||||
lPoints.push(pnt2)
|
||||
rPoints = rPoints.reverse()
|
||||
rPoints.push(pnt1)
|
||||
return (lPoints.reverse().concat(arrowPnts, rPoints))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 插值头部点
|
||||
* @param points
|
||||
* @returns {*[]}
|
||||
*/
|
||||
static _getArrowHeadPoints (points) {
|
||||
let len = getBaseLength(points)
|
||||
let headHeight = len * _options.headHeightFactor
|
||||
let headPnt = points[points.length - 1]
|
||||
let headWidth = headHeight * _options.headWidthFactor
|
||||
let neckWidth = headHeight * _options.neckWidthFactor
|
||||
let neckHeight = headHeight * _options.neckHeightFactor
|
||||
let headEndPnt = getThirdPoint(points[points.length - 2], headPnt, 0, headHeight, true)
|
||||
let neckEndPnt = getThirdPoint(points[points.length - 2], headPnt, 0, neckHeight, true)
|
||||
let headLeft = getThirdPoint(headPnt, headEndPnt, Constants.HALF_PI, headWidth, false)
|
||||
let headRight = getThirdPoint(headPnt, headEndPnt, Constants.HALF_PI, headWidth, true)
|
||||
let neckLeft = getThirdPoint(headPnt, neckEndPnt, Constants.HALF_PI, neckWidth, false)
|
||||
let neckRight = getThirdPoint(headPnt, neckEndPnt, Constants.HALF_PI, neckWidth, true)
|
||||
return [neckLeft, headLeft, headPnt, headRight, neckRight]
|
||||
}
|
||||
|
||||
/**
|
||||
* 插值面部分数据
|
||||
* @param points
|
||||
* @param neckLeft
|
||||
* @param neckRight
|
||||
* @param tailWidthFactor
|
||||
* @returns {*|T[]|string}
|
||||
*/
|
||||
static _getArrowBodyPoints (points, neckLeft, neckRight, tailWidthFactor) {
|
||||
let allLen = wholeDistance(points)
|
||||
let len = getBaseLength(points)
|
||||
let tailWidth = len * tailWidthFactor
|
||||
let neckWidth = MathDistance(neckLeft, neckRight)
|
||||
let widthDif = (tailWidth - neckWidth) / 2
|
||||
let [tempLen, leftBodyPnts, rightBodyPnts] = [0, [], []]
|
||||
for (let i = 1; i < points.length - 1; i++) {
|
||||
let angle = getAngleOfThreePoints(points[i - 1], points[i], points[i + 1]) / 2
|
||||
tempLen += MathDistance(points[i - 1], points[i])
|
||||
let w = (tailWidth / 2 - tempLen / allLen * widthDif) / Math.sin(angle)
|
||||
let left = getThirdPoint(points[i - 1], points[i], Math.PI - angle, w, true)
|
||||
let right = getThirdPoint(points[i - 1], points[i], angle, w, false)
|
||||
leftBodyPnts.push(left)
|
||||
rightBodyPnts.push(right)
|
||||
}
|
||||
return leftBodyPnts.concat(rightBodyPnts)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对称点
|
||||
* @param linePnt1
|
||||
* @param linePnt2
|
||||
* @param point
|
||||
* @returns {undefined}
|
||||
*/
|
||||
static getSymmetricalPoints (linePnt1, linePnt2, point) {
|
||||
let midPnt = Mid(linePnt1, linePnt2)
|
||||
let len = MathDistance(midPnt, point)
|
||||
let angle = getAngleOfThreePoints(linePnt1, midPnt, point)
|
||||
let [symPnt, distance1, distance2, mid] = [undefined, undefined, undefined, undefined]
|
||||
if (angle < Constants.HALF_PI) {
|
||||
distance1 = len * Math.sin(angle)
|
||||
distance2 = len * Math.cos(angle)
|
||||
mid = getThirdPoint(linePnt1, midPnt, Constants.HALF_PI, distance1, false)
|
||||
symPnt = getThirdPoint(midPnt, mid, Constants.HALF_PI, distance2, true)
|
||||
} else if (angle >= Constants.HALF_PI && angle < Math.PI) {
|
||||
distance1 = len * Math.sin(Math.PI - angle)
|
||||
distance2 = len * Math.cos(Math.PI - angle)
|
||||
mid = getThirdPoint(linePnt1, midPnt, Constants.HALF_PI, distance1, false)
|
||||
symPnt = getThirdPoint(midPnt, mid, Constants.HALF_PI, distance2, false)
|
||||
} else if (angle >= Math.PI && angle < Math.PI * 1.5) {
|
||||
distance1 = len * Math.sin(angle - Math.PI)
|
||||
distance2 = len * Math.cos(angle - Math.PI)
|
||||
mid = getThirdPoint(linePnt1, midPnt, Constants.HALF_PI, distance1, true)
|
||||
symPnt = getThirdPoint(midPnt, mid, Constants.HALF_PI, distance2, true)
|
||||
} else {
|
||||
distance1 = len * Math.sin(Math.PI * 2 - angle)
|
||||
distance2 = len * Math.cos(Math.PI * 2 - angle)
|
||||
mid = getThirdPoint(linePnt1, midPnt, Constants.HALF_PI, distance1, true)
|
||||
symPnt = getThirdPoint(midPnt, mid, Constants.HALF_PI, distance2, false)
|
||||
}
|
||||
return symPnt
|
||||
}
|
||||
|
||||
static fromJSON (json) {
|
||||
const feature = json['feature']
|
||||
const doubleArrow = new DoubleArrow(json['coordinates'], json['options'])
|
||||
doubleArrow.setProperties(feature['properties'])
|
||||
return doubleArrow
|
||||
}
|
||||
}
|
||||
|
||||
DoubleArrow.registerJSONType('DoubleArrow')
|
||||
|
||||
export default DoubleArrow
|
||||
97
src/geometry/Arrow/FineArrow.js
Normal file
97
src/geometry/Arrow/FineArrow.js
Normal file
@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Created by FDD on 2017/12/31.
|
||||
* @desc 粗单尖头箭头
|
||||
* @Inherits maptalks.Polygon
|
||||
*/
|
||||
|
||||
import * as maptalks from 'maptalks'
|
||||
import * as Constants from '../../Constants'
|
||||
import {
|
||||
getThirdPoint,
|
||||
getBaseLength
|
||||
} from '../helper/index'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
|
||||
const _options = {
|
||||
tailWidthFactor: 0.1,
|
||||
headWidthFactor: 0.25,
|
||||
neckWidthFactor: 0.2,
|
||||
headAngle: Math.PI / 8.5,
|
||||
neckAngle: Math.PI / 13
|
||||
}
|
||||
|
||||
class FineArrow extends maptalks.Polygon {
|
||||
constructor (coordinates, options = {}) {
|
||||
super(options)
|
||||
this.type = 'FineArrow'
|
||||
this._coordinates = []
|
||||
if (coordinates) {
|
||||
this.setPoints(coordinates)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理插值
|
||||
*/
|
||||
_generate () {
|
||||
try {
|
||||
const count = this._coordinates.length
|
||||
const _points = Coordinate.toNumberArrays(this._coordinates)
|
||||
if (count < 2) return
|
||||
let [points1, points2] = [_points[0], _points[1]]
|
||||
let len = getBaseLength(_points)
|
||||
let tailWidth = len * _options.tailWidthFactor
|
||||
let neckWidth = len * _options.neckWidthFactor
|
||||
let headWidth = len * _options.headWidthFactor
|
||||
let tailLeft = getThirdPoint(points2, points1, Constants.HALF_PI, tailWidth, true)
|
||||
let tailRight = getThirdPoint(points2, points1, Constants.HALF_PI, tailWidth, false)
|
||||
let headLeft = getThirdPoint(points1, points2, _options.headAngle, headWidth, false)
|
||||
let headRight = getThirdPoint(points1, points2, _options.headAngle, headWidth, true)
|
||||
let neckLeft = getThirdPoint(points1, points2, _options.neckAngle, neckWidth, false)
|
||||
let neckRight = getThirdPoint(points1, points2, _options.neckAngle, neckWidth, true)
|
||||
let pList = [tailLeft, neckLeft, headLeft, points2, headRight, neckRight, tailRight]
|
||||
this.setCoordinates([
|
||||
Coordinate.toCoordinates(pList)
|
||||
])
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
setPoints (coordinates) {
|
||||
this._coordinates = !coordinates ? [] : coordinates
|
||||
if (this._coordinates.length >= 1) {
|
||||
this._generate()
|
||||
}
|
||||
}
|
||||
|
||||
_exportGeoJSONGeometry () {
|
||||
const coordinates = Coordinate.toNumberArrays([this.getShell()])
|
||||
return {
|
||||
'type': 'Polygon',
|
||||
'coordinates': coordinates
|
||||
}
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
const opts = maptalks.Util.extend({}, options)
|
||||
opts.geometry = false
|
||||
const feature = this.toGeoJSON(opts)
|
||||
return {
|
||||
'feature': feature,
|
||||
'coordinates': feature['coordinates'],
|
||||
'subType': 'FineArrow'
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON (json) {
|
||||
const feature = json['feature']
|
||||
const fineArrow = new FineArrow(json['coordinates'], json['options'])
|
||||
fineArrow.setProperties(feature['properties'])
|
||||
return fineArrow
|
||||
}
|
||||
}
|
||||
|
||||
FineArrow.registerJSONType('FineArrow')
|
||||
|
||||
export default FineArrow
|
||||
91
src/geometry/Arrow/SquadCombat.js
Normal file
91
src/geometry/Arrow/SquadCombat.js
Normal file
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Created by FDD on 2017/12/26.
|
||||
* @desc 分队战斗行动
|
||||
* @Inherits AttackArrow
|
||||
*/
|
||||
|
||||
import AttackArrow from './AttackArrow'
|
||||
import * as maptalks from 'maptalks'
|
||||
import * as Constants from '../../Constants'
|
||||
import {
|
||||
getBaseLength,
|
||||
getThirdPoint,
|
||||
getQBSplinePoints
|
||||
} from '../helper/index'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
|
||||
class SquadCombat extends AttackArrow {
|
||||
constructor (coordinates, options = {}) {
|
||||
super(coordinates, options)
|
||||
this.type = 'SquadCombat'
|
||||
this._coordinates = []
|
||||
this.headHeightFactor = 0.18
|
||||
this.headWidthFactor = 0.3
|
||||
this.neckHeightFactor = 0.85
|
||||
this.neckWidthFactor = 0.15
|
||||
this.tailWidthFactor = 0.1
|
||||
if (coordinates) {
|
||||
this.setPoints(coordinates)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理插值
|
||||
*/
|
||||
_generate () {
|
||||
try {
|
||||
const count = this._coordinates.length
|
||||
if (count < 2) return
|
||||
if (count === 2) {
|
||||
this.setCoordinates([this._coordinates])
|
||||
} else {
|
||||
let _points = Coordinate.toNumberArrays(this._coordinates)
|
||||
let tailPoints = this.getTailPoints(_points)
|
||||
let headPoints = this._getArrowHeadPoints(_points, tailPoints[0], tailPoints[1])
|
||||
let neckLeft = headPoints[0]
|
||||
let neckRight = headPoints[4]
|
||||
let bodyPoints = AttackArrow._getArrowBodyPoints(_points, neckLeft, neckRight, this.tailWidthFactor)
|
||||
let count = bodyPoints.length
|
||||
let leftPoints = [tailPoints[0]].concat(bodyPoints.slice(0, count / 2))
|
||||
leftPoints.push(neckLeft)
|
||||
let rightPoints = [tailPoints[1]].concat(bodyPoints.slice(count / 2, count))
|
||||
rightPoints.push(neckRight)
|
||||
leftPoints = getQBSplinePoints(leftPoints)
|
||||
rightPoints = getQBSplinePoints(rightPoints)
|
||||
this.setCoordinates(Coordinate.toCoordinates([leftPoints.concat(headPoints, rightPoints.reverse())]))
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
getTailPoints (points) {
|
||||
let allLen = getBaseLength(points)
|
||||
let tailWidth = allLen * this.tailWidthFactor
|
||||
let tailLeft = getThirdPoint(points[1], points[0], Constants.HALF_PI, tailWidth, false)
|
||||
let tailRight = getThirdPoint(points[1], points[0], Constants.HALF_PI, tailWidth, true)
|
||||
return ([tailLeft, tailRight])
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
const opts = maptalks.Util.extend({}, options)
|
||||
opts.geometry = false
|
||||
const feature = this.toGeoJSON(opts)
|
||||
return {
|
||||
'feature': feature,
|
||||
'coordinates': feature['coordinates'],
|
||||
'subType': 'SquadCombat'
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON (json) {
|
||||
const feature = json['feature']
|
||||
const squadCombat = new SquadCombat(json['coordinates'], json['options'])
|
||||
squadCombat.setProperties(feature['properties'])
|
||||
return squadCombat
|
||||
}
|
||||
}
|
||||
|
||||
SquadCombat.registerJSONType('SquadCombat')
|
||||
|
||||
export default SquadCombat
|
||||
78
src/geometry/Arrow/StraightArrow.js
Normal file
78
src/geometry/Arrow/StraightArrow.js
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Created by FDD on 2017/12/31.
|
||||
* @desc 细直箭头
|
||||
* @Inherits maptalks.LineString
|
||||
*/
|
||||
|
||||
import * as maptalks from 'maptalks'
|
||||
import {
|
||||
getThirdPoint,
|
||||
MathDistance
|
||||
} from '../helper/index'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
|
||||
const _options = {
|
||||
'maxArrowLength': 3000000,
|
||||
'arrowLengthScale': 5,
|
||||
'arrowStyle': null,
|
||||
'arrowPlacement': 'vertex-last', // vertex-first, vertex-last, vertex-firstlast, point
|
||||
'clipToPaint': true
|
||||
}
|
||||
|
||||
class StraightArrow extends maptalks.LineString {
|
||||
constructor (coordinates, options = {}) {
|
||||
super(options)
|
||||
this.type = 'StraightArrow'
|
||||
this._coordinates = []
|
||||
if (coordinates) {
|
||||
this.setPoints(coordinates)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理插值
|
||||
*/
|
||||
_generate () {
|
||||
try {
|
||||
const count = this._coordinates.length
|
||||
const _points = Coordinate.toNumberArrays(this._coordinates)
|
||||
if (count < 2) return
|
||||
let [points1, points2] = [_points[0], _points[1]]
|
||||
let distance = MathDistance(points1, points2)
|
||||
let len = distance / _options.arrowLengthScale
|
||||
len = ((len > _options.maxArrowLength) ? _options.maxArrowLength : len)
|
||||
let leftPnt = getThirdPoint(points1, points2, Math.PI / 6, len, false)
|
||||
let rightPnt = getThirdPoint(points1, points2, Math.PI / 6, len, true)
|
||||
this.setCoordinates(Coordinate.toCoordinates([points1, points2, leftPnt, points2, rightPnt]))
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
setPoints (coordinates) {
|
||||
this._coordinates = !coordinates ? [] : coordinates
|
||||
if (this._coordinates.length >= 1) {
|
||||
this._generate()
|
||||
}
|
||||
}
|
||||
|
||||
_exportGeoJSONGeometry () {
|
||||
const points = this.getCoordinates()
|
||||
const coordinates = Coordinate.toNumberArrays(points)
|
||||
return {
|
||||
'type': 'LineString',
|
||||
'coordinates': coordinates
|
||||
}
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
return {
|
||||
'feature': this.toGeoJSON(options)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StraightArrow.registerJSONType('StraightArrow')
|
||||
StraightArrow.mergeOptions(_options)
|
||||
|
||||
export default StraightArrow
|
||||
98
src/geometry/Arrow/TailedAttackArrow.js
Normal file
98
src/geometry/Arrow/TailedAttackArrow.js
Normal file
@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Created by FDD on 2017/12/31.
|
||||
* @desc 进攻方向(尾)
|
||||
* @Inherits AttackArrow
|
||||
*/
|
||||
|
||||
import AttackArrow from './AttackArrow'
|
||||
import * as maptalks from 'maptalks'
|
||||
import {
|
||||
isClockWise,
|
||||
getBaseLength,
|
||||
getThirdPoint,
|
||||
getQBSplinePoints,
|
||||
MathDistance,
|
||||
Mid
|
||||
} from '../helper/index'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
|
||||
class TailedAttackArrow extends AttackArrow {
|
||||
constructor (coordinates, options = {}) {
|
||||
super(coordinates, options)
|
||||
this.type = 'TailedAttackArrow'
|
||||
this._coordinates = []
|
||||
this.headHeightFactor = 0.18
|
||||
this.headWidthFactor = 0.3
|
||||
this.neckHeightFactor = 0.85
|
||||
this.neckWidthFactor = 0.15
|
||||
this.tailWidthFactor = 0.1
|
||||
this.headTailFactor = 0.8
|
||||
this.swallowTailFactor = 1
|
||||
this.swallowTailPnt = null
|
||||
if (coordinates) {
|
||||
this.setPoints(coordinates)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理插值
|
||||
*/
|
||||
_generate () {
|
||||
try {
|
||||
const count = this._coordinates.length
|
||||
if (count < 2) return
|
||||
if (count === 2) {
|
||||
this.setCoordinates([this._coordinates])
|
||||
} else {
|
||||
let _points = Coordinate.toNumberArrays(this._coordinates)
|
||||
let [tailLeft, tailRight] = [_points[0], _points[1]]
|
||||
if (isClockWise(_points[0], _points[1], _points[2])) {
|
||||
tailLeft = _points[1]
|
||||
tailRight = _points[0]
|
||||
}
|
||||
let midTail = Mid(tailLeft, tailRight)
|
||||
let bonePoints = [midTail].concat(_points.slice(2))
|
||||
let headPoints = this._getArrowHeadPoints(bonePoints, tailLeft, tailRight)
|
||||
let [neckLeft, neckRight] = [headPoints[0], headPoints[4]]
|
||||
let tailWidth = MathDistance(tailLeft, tailRight)
|
||||
let allLen = getBaseLength(bonePoints)
|
||||
let len = allLen * this.tailWidthFactor * this.swallowTailFactor
|
||||
this.swallowTailPnt = getThirdPoint(bonePoints[1], bonePoints[0], 0, len, true)
|
||||
let factor = tailWidth / allLen
|
||||
let bodyPoints = AttackArrow._getArrowBodyPoints(bonePoints, neckLeft, neckRight, factor)
|
||||
let count = bodyPoints.length
|
||||
let leftPoints = [tailLeft].concat(bodyPoints.slice(0, count / 2))
|
||||
leftPoints.push(neckLeft)
|
||||
let rightPoints = [tailRight].concat(bodyPoints.slice(count / 2, count))
|
||||
rightPoints.push(neckRight)
|
||||
leftPoints = getQBSplinePoints(leftPoints)
|
||||
rightPoints = getQBSplinePoints(rightPoints)
|
||||
this.setCoordinates(Coordinate.toCoordinates([leftPoints.concat(headPoints, rightPoints.reverse(), [this.swallowTailPnt, leftPoints[0]])]))
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
const opts = maptalks.Util.extend({}, options)
|
||||
opts.geometry = false
|
||||
const feature = this.toGeoJSON(opts)
|
||||
return {
|
||||
'feature': feature,
|
||||
'coordinates': feature['coordinates'],
|
||||
'subType': 'TailedAttackArrow'
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON (json) {
|
||||
const feature = json['feature']
|
||||
const _geometry = new TailedAttackArrow(json['coordinates'], json['options'])
|
||||
_geometry.setProperties(feature['properties'])
|
||||
return _geometry
|
||||
}
|
||||
}
|
||||
|
||||
TailedAttackArrow.registerJSONType('TailedAttackArrow')
|
||||
|
||||
export default TailedAttackArrow
|
||||
91
src/geometry/Arrow/TailedSquadCombat.js
Normal file
91
src/geometry/Arrow/TailedSquadCombat.js
Normal file
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Created by FDD on 2017/12/31.
|
||||
* @desc 燕尾直箭头
|
||||
* @Inherits AttackArrow
|
||||
*/
|
||||
|
||||
import AttackArrow from './AttackArrow'
|
||||
import * as maptalks from 'maptalks'
|
||||
import * as Constants from '../../Constants'
|
||||
import {
|
||||
getBaseLength,
|
||||
getThirdPoint,
|
||||
getQBSplinePoints
|
||||
} from '../helper/index'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
|
||||
class TailedSquadCombat extends AttackArrow {
|
||||
constructor (coordinates, options = {}) {
|
||||
super(coordinates, options)
|
||||
this.type = 'TailedSquadCombat'
|
||||
this._coordinates = []
|
||||
this.headHeightFactor = 0.18
|
||||
this.headWidthFactor = 0.3
|
||||
this.neckHeightFactor = 0.85
|
||||
this.neckWidthFactor = 0.15
|
||||
this.tailWidthFactor = 0.1
|
||||
this.swallowTailFactor = 1
|
||||
this.swallowTailPnt = null
|
||||
if (coordinates) {
|
||||
this.setPoints(coordinates)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理插值
|
||||
*/
|
||||
_generate () {
|
||||
try {
|
||||
const count = this._coordinates.length
|
||||
const _points = Coordinate.toNumberArrays(this._coordinates)
|
||||
if (count < 2) return
|
||||
let tailPoints = this.getTailPoints(_points)
|
||||
let headPoints = this._getArrowHeadPoints(_points, tailPoints[0], tailPoints[2])
|
||||
let neckLeft = headPoints[0]
|
||||
let neckRight = headPoints[4]
|
||||
let bodyPoints = AttackArrow._getArrowBodyPoints(_points, neckLeft, neckRight, this.tailWidthFactor)
|
||||
let _count = bodyPoints.length
|
||||
let leftPoints = [tailPoints[0]].concat(bodyPoints.slice(0, _count / 2))
|
||||
leftPoints.push(neckLeft)
|
||||
let rightPoints = [tailPoints[2]].concat(bodyPoints.slice(_count / 2, _count))
|
||||
rightPoints.push(neckRight)
|
||||
leftPoints = getQBSplinePoints(leftPoints)
|
||||
rightPoints = getQBSplinePoints(rightPoints)
|
||||
this.setCoordinates(Coordinate.toCoordinates([leftPoints.concat(headPoints, rightPoints.reverse(), [tailPoints[1], leftPoints[0]])]))
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
getTailPoints (points) {
|
||||
let allLen = getBaseLength(points)
|
||||
let tailWidth = allLen * this.tailWidthFactor
|
||||
let tailLeft = getThirdPoint(points[1], points[0], Constants.HALF_PI, tailWidth, false)
|
||||
let tailRight = getThirdPoint(points[1], points[0], Constants.HALF_PI, tailWidth, true)
|
||||
let len = tailWidth * this.swallowTailFactor
|
||||
let swallowTailPnt = getThirdPoint(points[1], points[0], 0, len, true)
|
||||
return ([tailLeft, swallowTailPnt, tailRight])
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
const opts = maptalks.Util.extend({}, options)
|
||||
opts.geometry = false
|
||||
const feature = this.toGeoJSON(opts)
|
||||
return {
|
||||
'feature': feature,
|
||||
'coordinates': feature['coordinates'],
|
||||
'subType': 'TailedSquadCombat'
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON (json) {
|
||||
const feature = json['feature']
|
||||
const _geometry = new TailedSquadCombat(json['coordinates'], json['options'])
|
||||
_geometry.setProperties(feature['properties'])
|
||||
return _geometry
|
||||
}
|
||||
}
|
||||
|
||||
TailedSquadCombat.registerJSONType('TailedSquadCombat')
|
||||
|
||||
export default TailedSquadCombat
|
||||
53
src/geometry/Circle/Circle.js
Normal file
53
src/geometry/Circle/Circle.js
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Created by FDD on 2017/12/28.
|
||||
* @desc 标绘画圆算法
|
||||
* @Inherits maptalks.Circle
|
||||
*/
|
||||
|
||||
import * as maptalks from 'maptalks'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
class PlotCircle extends maptalks.Circle {
|
||||
constructor (coordinate, radius, options = {}) {
|
||||
super(null, options)
|
||||
this.type = 'Circle'
|
||||
if (coordinate) {
|
||||
this.setCoordinates(coordinate)
|
||||
}
|
||||
this._radius = radius
|
||||
}
|
||||
|
||||
_exportGeoJSONGeometry () {
|
||||
const coordinates = Coordinate.toNumberArrays([this.getShell()])
|
||||
return {
|
||||
'type': 'Polygon',
|
||||
'coordinates': coordinates
|
||||
}
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
const center = this.getCenter()
|
||||
const opts = maptalks.Util.extend({}, options)
|
||||
opts.geometry = false
|
||||
const feature = this.toGeoJSON(opts)
|
||||
feature['geometry'] = {
|
||||
'type': 'Polygon'
|
||||
}
|
||||
return {
|
||||
'feature': feature,
|
||||
'subType': 'PlotCircle',
|
||||
'coordinates': [center.x, center.y],
|
||||
'radius': this.getRadius()
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON (json) {
|
||||
const GeoJSON = json['feature']
|
||||
const feature = new PlotCircle(json['coordinates'], json['radius'], json['options'])
|
||||
feature.setProperties(GeoJSON['properties'])
|
||||
return feature
|
||||
}
|
||||
}
|
||||
|
||||
PlotCircle.registerJSONType('PlotCircle')
|
||||
|
||||
export default PlotCircle
|
||||
47
src/geometry/Circle/Ellipse.js
Normal file
47
src/geometry/Circle/Ellipse.js
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Created by FDD on 2017/12/31.
|
||||
* @desc 标绘椭圆算法
|
||||
* @Inherits maptalks.Ellipse
|
||||
*/
|
||||
|
||||
import * as maptalks from 'maptalks'
|
||||
|
||||
class PlotEllipse extends maptalks.Ellipse {
|
||||
constructor (coordinates, width, height, options = {}) {
|
||||
super(null, options)
|
||||
this.type = 'Ellipse'
|
||||
if (coordinates) {
|
||||
this.setCoordinates(coordinates)
|
||||
}
|
||||
this.width = width
|
||||
this.height = height
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
const opts = maptalks.Util.extend({}, options)
|
||||
const center = this.getCenter()
|
||||
opts.geometry = false
|
||||
const feature = this.toGeoJSON(opts)
|
||||
feature['geometry'] = {
|
||||
'type': 'Polygon'
|
||||
}
|
||||
return {
|
||||
'feature': feature,
|
||||
'subType': 'PlotEllipse',
|
||||
'coordinates': [center.x, center.y],
|
||||
'width': this.getWidth(),
|
||||
'height': this.getHeight()
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON (json) {
|
||||
const GeoJSON = json['feature']
|
||||
const feature = new PlotEllipse(json['coordinates'], json['width'], json['height'], json['options'])
|
||||
feature.setProperties(GeoJSON['properties'])
|
||||
return feature
|
||||
}
|
||||
}
|
||||
|
||||
PlotEllipse.registerJSONType('PlotEllipse')
|
||||
|
||||
export default PlotEllipse
|
||||
116
src/geometry/Flag/CurveFlag.js
Normal file
116
src/geometry/Flag/CurveFlag.js
Normal file
@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Created by FDD on 2017/12/26.
|
||||
* @desc 曲线旗标
|
||||
* @Inherits maptalks.Polygon
|
||||
*/
|
||||
|
||||
import * as maptalks from 'maptalks'
|
||||
import {
|
||||
getBezierPoints
|
||||
} from '../helper/index'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
class CurveFlag extends maptalks.Polygon {
|
||||
constructor (coordinates, options = {}) {
|
||||
super(options)
|
||||
this.type = 'CurveFlag'
|
||||
this._coordinates = []
|
||||
if (coordinates) {
|
||||
this.setPoints(coordinates)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle coordinates
|
||||
* @private
|
||||
*/
|
||||
_generate () {
|
||||
const count = this._coordinates.length
|
||||
let _points = Coordinate.toNumberArrays(this._coordinates)
|
||||
if (count < 2) return
|
||||
this.setCoordinates([
|
||||
Coordinate.toCoordinates(CurveFlag.calculatePoints(_points))
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* set point
|
||||
* @param coordinates
|
||||
*/
|
||||
setPoints (coordinates) {
|
||||
this._coordinates = !coordinates ? [] : coordinates
|
||||
if (this._coordinates.length >= 1) {
|
||||
this._generate()
|
||||
}
|
||||
}
|
||||
|
||||
_exportGeoJSONGeometry () {
|
||||
const coordinates = Coordinate.toNumberArrays([this.getShell()])
|
||||
return {
|
||||
'type': 'Polygon',
|
||||
'coordinates': coordinates
|
||||
}
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
return {
|
||||
'feature': this.toGeoJSON(options),
|
||||
'subType': 'CurveFlag'
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 插值点数据
|
||||
* @param points
|
||||
* @returns {Array}
|
||||
*/
|
||||
static calculatePoints (points) {
|
||||
let components = []
|
||||
// 至少需要两个控制点
|
||||
if (points.length > 1) {
|
||||
// 取第一个
|
||||
let startPoint = points[0]
|
||||
// 取最后一个
|
||||
let endPoint = points[points.length - 1]
|
||||
// 上曲线起始点
|
||||
let point1 = startPoint
|
||||
// 上曲线第一控制点
|
||||
let point2 = [(endPoint[0] - startPoint[0]) / 4 + startPoint[0], (endPoint[1] - startPoint[1]) / 8 + startPoint[1]]
|
||||
// 上曲线第二个点
|
||||
let point3 = [(startPoint[0] + endPoint[0]) / 2, startPoint[1]]
|
||||
// 上曲线第二控制点
|
||||
let point4 = [(endPoint[0] - startPoint[0]) * 3 / 4 + startPoint[0], -(endPoint[1] - startPoint[1]) / 8 + startPoint[1]]
|
||||
// 上曲线结束点
|
||||
let point5 = [endPoint[0], startPoint[1]]
|
||||
// 下曲线结束点
|
||||
let point6 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
|
||||
// 下曲线第二控制点
|
||||
let point7 = [(endPoint[0] - startPoint[0]) * 3 / 4 + startPoint[0], (endPoint[1] - startPoint[1]) * 3 / 8 + startPoint[1]]
|
||||
// 下曲线第二个点
|
||||
let point8 = [(startPoint[0] + endPoint[0]) / 2, (startPoint[1] + endPoint[1]) / 2]
|
||||
// 下曲线第一控制点
|
||||
let point9 = [(endPoint[0] - startPoint[0]) / 4 + startPoint[0], (endPoint[1] - startPoint[1]) * 5 / 8 + startPoint[1]]
|
||||
// 下曲线起始点
|
||||
let point10 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
|
||||
// 旗杆底部点
|
||||
let point11 = [startPoint[0], endPoint[1]]
|
||||
// 计算上曲线
|
||||
let curve1 = getBezierPoints([point1, point2, point3, point4, point5])
|
||||
// 计算下曲线
|
||||
let curve2 = getBezierPoints([point6, point7, point8, point9, point10])
|
||||
// 合并
|
||||
components = curve1.concat(curve2)
|
||||
components.push(point11)
|
||||
}
|
||||
return components
|
||||
}
|
||||
|
||||
static fromJSON (json) {
|
||||
const feature = json['feature']
|
||||
const attackArrow = new CurveFlag(json['coordinates'], json['width'], json['height'], json['options'])
|
||||
attackArrow.setProperties(feature['properties'])
|
||||
return attackArrow
|
||||
}
|
||||
}
|
||||
|
||||
CurveFlag.registerJSONType('CurveFlag')
|
||||
|
||||
export default CurveFlag
|
||||
89
src/geometry/Flag/RectFlag.js
Normal file
89
src/geometry/Flag/RectFlag.js
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Created by FDD on 2017/12/26.
|
||||
* @desc 直角旗标(使用两个控制点直接创建直角旗标)
|
||||
* @Inherits maptalks.Polygon
|
||||
*/
|
||||
|
||||
import * as maptalks from 'maptalks'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
class RectFlag extends maptalks.Polygon {
|
||||
constructor (coordinates, options = {}) {
|
||||
super(options)
|
||||
this.type = 'RectFlag'
|
||||
this._coordinates = []
|
||||
if (coordinates) {
|
||||
this.setPoints(coordinates)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle coordinates
|
||||
* @private
|
||||
*/
|
||||
_generate () {
|
||||
const count = this._coordinates.length
|
||||
let _points = Coordinate.toNumberArrays(this._coordinates)
|
||||
if (count < 2) return
|
||||
this.setCoordinates([
|
||||
Coordinate.toCoordinates(RectFlag.calculatePoints(_points))
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* set point
|
||||
* @param coordinates
|
||||
*/
|
||||
setPoints (coordinates) {
|
||||
this._coordinates = !coordinates ? [] : coordinates
|
||||
if (this._coordinates.length >= 1) {
|
||||
this._generate()
|
||||
}
|
||||
}
|
||||
|
||||
_exportGeoJSONGeometry () {
|
||||
const coordinates = Coordinate.toNumberArrays([this.getShell()])
|
||||
return {
|
||||
'type': 'Polygon',
|
||||
'coordinates': coordinates
|
||||
}
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
return {
|
||||
'feature': this.toGeoJSON(options),
|
||||
'subType': 'RectFlag'
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 插值点数据
|
||||
* @param points
|
||||
* @returns {Array}
|
||||
*/
|
||||
static calculatePoints (points) {
|
||||
let components = []
|
||||
// 至少需要两个控制点
|
||||
if (points.length > 1) {
|
||||
// 取第一个
|
||||
let startPoint = points[0]
|
||||
// 取最后一个
|
||||
let endPoint = points[points.length - 1]
|
||||
let point1 = [endPoint[0], startPoint[1]]
|
||||
let point2 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
|
||||
let point3 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
|
||||
let point4 = [startPoint[0], endPoint[1]]
|
||||
components = [startPoint, point1, point2, point3, point4]
|
||||
}
|
||||
return components
|
||||
}
|
||||
|
||||
static fromJSON (json) {
|
||||
const feature = json['feature']
|
||||
const rectFlag = new RectFlag(json['coordinates'], json['width'], json['height'], json['options'])
|
||||
rectFlag.setProperties(feature['properties'])
|
||||
return rectFlag
|
||||
}
|
||||
}
|
||||
|
||||
RectFlag.registerJSONType('RectFlag')
|
||||
|
||||
export default RectFlag
|
||||
88
src/geometry/Flag/TriangleFlag.js
Normal file
88
src/geometry/Flag/TriangleFlag.js
Normal file
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Created by FDD on 2017/12/26.
|
||||
* @desc 曲线旗标
|
||||
* @Inherits maptalks.Polygon
|
||||
*/
|
||||
|
||||
import * as maptalks from 'maptalks'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
class TriangleFlag extends maptalks.Polygon {
|
||||
constructor (coordinates, options = {}) {
|
||||
super(options)
|
||||
this.type = 'TriangleFlag'
|
||||
this._coordinates = []
|
||||
if (coordinates) {
|
||||
this.setPoints(coordinates)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle coordinates
|
||||
* @private
|
||||
*/
|
||||
_generate () {
|
||||
const count = this._coordinates.length
|
||||
let _points = Coordinate.toNumberArrays(this._coordinates)
|
||||
if (count < 2) return
|
||||
this.setCoordinates([
|
||||
Coordinate.toCoordinates(TriangleFlag.calculatePoints(_points))
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* set point
|
||||
* @param coordinates
|
||||
*/
|
||||
setPoints (coordinates) {
|
||||
this._coordinates = !coordinates ? [] : coordinates
|
||||
if (this._coordinates.length >= 1) {
|
||||
this._generate()
|
||||
}
|
||||
}
|
||||
|
||||
_exportGeoJSONGeometry () {
|
||||
const coordinates = Coordinate.toNumberArrays([this.getShell()])
|
||||
return {
|
||||
'type': 'Polygon',
|
||||
'coordinates': coordinates
|
||||
}
|
||||
}
|
||||
|
||||
_toJSON (options) {
|
||||
return {
|
||||
'feature': this.toGeoJSON(options),
|
||||
'subType': 'TriangleFlag'
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 插值点数据
|
||||
* @param points
|
||||
* @returns {Array}
|
||||
*/
|
||||
static calculatePoints (points) {
|
||||
let components = []
|
||||
// 至少需要两个控制点
|
||||
if (points.length > 1) {
|
||||
// 取第一个
|
||||
let startPoint = points[0]
|
||||
// 取最后一个
|
||||
let endPoint = points[points.length - 1]
|
||||
let point1 = [endPoint[0], (startPoint[1] + endPoint[1]) / 2]
|
||||
let point2 = [startPoint[0], (startPoint[1] + endPoint[1]) / 2]
|
||||
let point3 = [startPoint[0], endPoint[1]]
|
||||
components = [startPoint, point1, point2, point3]
|
||||
}
|
||||
return components
|
||||
}
|
||||
|
||||
static fromJSON (json) {
|
||||
const feature = json['feature']
|
||||
const triangleFlag = new TriangleFlag(json['coordinates'], json['width'], json['height'], json['options'])
|
||||
triangleFlag.setProperties(feature['properties'])
|
||||
return triangleFlag
|
||||
}
|
||||
}
|
||||
|
||||
TriangleFlag.registerJSONType('TriangleFlag')
|
||||
|
||||
export default TriangleFlag
|
||||
@ -6,25 +6,11 @@
|
||||
import * as maptalks from 'maptalks'
|
||||
const Coordinate = maptalks.Coordinate
|
||||
|
||||
maptalks.Polygon.getCoordinateFromExtent = function (extent) {
|
||||
let [minX, minY, maxX, maxY] = [extent[0], extent[1], extent[2], extent[3]]
|
||||
return [minX, minY, minX, maxY, maxX, maxY, maxX, minY, minX, minY]
|
||||
}
|
||||
|
||||
const boundingExtent = function (coordinates) {
|
||||
let extent = new maptalks.Extent()
|
||||
for (let i = 0, ii = coordinates.length; i < ii; ++i) {
|
||||
extent.add(extent, coordinates[i])
|
||||
}
|
||||
return extent
|
||||
}
|
||||
|
||||
class RectAngle extends maptalks.Polygon {
|
||||
constructor (coordinates, options = {}) {
|
||||
super(options)
|
||||
this.type = 'RectAngle'
|
||||
this._coordinates = []
|
||||
this.isFill = ((options['isFill'] === false) ? options['isFill'] : true)
|
||||
if (coordinates) {
|
||||
this.setPoints(coordinates)
|
||||
}
|
||||
@ -39,18 +25,10 @@ class RectAngle extends maptalks.Polygon {
|
||||
let _points = Coordinate.toNumberArrays(this._coordinates)
|
||||
if (count < 2) return
|
||||
if (count === 2) {
|
||||
let coordinates = []
|
||||
if (this.isFill) {
|
||||
let extent = boundingExtent(this._coordinates)
|
||||
coordinates = maptalks.Polygon.getCoordinateFromExtent(extent)
|
||||
} else {
|
||||
let start = _points[0]
|
||||
let end = _points[1]
|
||||
coordinates = [start, [start[0], end[1]], end, [end[0], start[1]], start]
|
||||
}
|
||||
this.setCoordinates([
|
||||
Coordinate.toCoordinates(coordinates)
|
||||
])
|
||||
let start = _points[0]
|
||||
let end = _points[1]
|
||||
let coordinates = [start, [start[0], end[1]], end, [end[0], start[1]], start]
|
||||
this.setCoordinates(Coordinate.toCoordinates(coordinates))
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,9 +56,9 @@ class RectAngle extends maptalks.Polygon {
|
||||
|
||||
static fromJSON (json) {
|
||||
const feature = json['feature']
|
||||
const attackArrow = new RectAngle(json['coordinates'], json['width'], json['height'], json['options'])
|
||||
attackArrow.setProperties(feature['properties'])
|
||||
return attackArrow
|
||||
const reactAngle = new RectAngle(json['coordinates'], json['options'])
|
||||
reactAngle.setProperties(feature['properties'])
|
||||
return reactAngle
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -65,6 +65,7 @@ class Arc extends maptalks.LineString {
|
||||
const coordinates = Coordinate.toNumberArrays(points)
|
||||
return {
|
||||
'type': 'LineString',
|
||||
'subType': 'Arc',
|
||||
'coordinates': coordinates
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,20 @@ import Curve from './Polyline/Curve'
|
||||
import Polyline from './Polyline/Polyline'
|
||||
import FreeLine from './Polyline/FreeLine'
|
||||
|
||||
import PlotCircle from './Circle/Circle'
|
||||
import PlotEllipse from './Circle/Ellipse'
|
||||
import AttackArrow from './Arrow/AttackArrow'
|
||||
import DoubleArrow from './Arrow/DoubleArrow'
|
||||
import FineArrow from './Arrow/FineArrow'
|
||||
import StraightArrow from './Arrow/StraightArrow'
|
||||
import AssaultDirection from './Arrow/AssaultDirection'
|
||||
import SquadCombat from './Arrow/SquadCombat'
|
||||
import TailedAttackArrow from './Arrow/TailedAttackArrow'
|
||||
import TailedSquadCombat from './Arrow/TailedSquadCombat'
|
||||
|
||||
import CurveFlag from './Flag/CurveFlag'
|
||||
import RectFlag from './Flag/RectFlag'
|
||||
import TriangleFlag from './Flag/TriangleFlag'
|
||||
|
||||
import Lune from './Polygon/Lune'
|
||||
import Sector from './Polygon/Sector'
|
||||
@ -20,7 +33,21 @@ import GatheringPlace from './Polygon/GatheringPlace'
|
||||
|
||||
import * as PlotTypes from '../core/PlotTypes'
|
||||
const Polygon = maptalks.Polygon
|
||||
const Coordinate = maptalks.Coordinate
|
||||
const RegisterModes = {}
|
||||
RegisterModes[PlotTypes.POINT] = {
|
||||
'freehand': false,
|
||||
'limitClickCount': 1,
|
||||
'action': ['click'],
|
||||
'create': function (path) {
|
||||
return new maptalks.Marker(path[0])
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return geometry
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.ARC] = {
|
||||
'freehand': false,
|
||||
'limitClickCount': 3,
|
||||
@ -83,12 +110,118 @@ RegisterModes[PlotTypes.ATTACK_ARROW] = {
|
||||
'update': function (path, geometry) {
|
||||
geometry.setPoints(path)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return geometry
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.DOUBLE_ARROW] = {
|
||||
'freehand': false,
|
||||
'limitClickCount': 4,
|
||||
'action': ['click', 'mousemove', 'dblclick'],
|
||||
'create': function (path) {
|
||||
return new DoubleArrow(path)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
geometry.setPoints(path)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return new Polygon(geometry.getCoordinates(), {
|
||||
'symbol': geometry.getSymbol()
|
||||
})
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.FINE_ARROW] = {
|
||||
'freehand': false,
|
||||
'limitClickCount': 2,
|
||||
'action': ['click', 'mousemove', 'click'],
|
||||
'create': function (path) {
|
||||
return new FineArrow(path)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
geometry.setPoints(path)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return new Polygon(geometry.getCoordinates(), {
|
||||
'symbol': geometry.getSymbol()
|
||||
})
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.ASSAULT_DIRECTION] = {
|
||||
'freehand': false,
|
||||
'limitClickCount': 2,
|
||||
'action': ['click', 'mousemove', 'click'],
|
||||
'create': function (path) {
|
||||
return new AssaultDirection(path)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
geometry.setPoints(path)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return new Polygon(geometry.getCoordinates(), {
|
||||
'symbol': geometry.getSymbol()
|
||||
})
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.SQUAD_COMBAT] = {
|
||||
'freehand': false,
|
||||
'action': ['click', 'mousemove', 'dblclick'],
|
||||
'create': function (path) {
|
||||
return new SquadCombat(path)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
geometry.setPoints(path)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return new Polygon(geometry.getCoordinates(), {
|
||||
'symbol': geometry.getSymbol()
|
||||
})
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.TAILED_ATTACK_ARROW] = {
|
||||
'freehand': false,
|
||||
'action': ['click', 'mousemove', 'dblclick'],
|
||||
'create': function (path) {
|
||||
return new TailedAttackArrow(path)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
geometry.setPoints(path)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return new Polygon(geometry.getCoordinates(), {
|
||||
'symbol': geometry.getSymbol()
|
||||
})
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.TAILED_SQUAD_COMBAT] = {
|
||||
'freehand': false,
|
||||
'limitClickCount': 2,
|
||||
'action': ['click', 'mousemove', 'dblclick'],
|
||||
'create': function (path) {
|
||||
return new TailedSquadCombat(path)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
geometry.setPoints(path)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return new Polygon(geometry.getCoordinates(), {
|
||||
'symbol': geometry.getSymbol()
|
||||
})
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.STRAIGHT_ARROW] = {
|
||||
'freehand': false,
|
||||
'limitClickCount': 2,
|
||||
'action': ['click', 'mousemove', 'click'],
|
||||
'create': function (path) {
|
||||
return new StraightArrow(path)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
geometry.setPoints(path)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return geometry
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.CLOSED_CURVE] = {
|
||||
'freehand': false,
|
||||
'action': ['click', 'mousemove', 'dblclick'],
|
||||
@ -159,7 +292,7 @@ RegisterModes[PlotTypes.RECTANGLE] = {
|
||||
return new RectAngle(path)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
geometry.setCoordinates(path)
|
||||
geometry.setPoints(path)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return new Polygon(geometry.getCoordinates(), {
|
||||
@ -198,5 +331,92 @@ RegisterModes[PlotTypes.GATHERING_PLACE] = {
|
||||
})
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.CURVEFLAG] = {
|
||||
'freehand': false,
|
||||
'limitClickCount': 2,
|
||||
'action': ['click', 'mousemove', 'click'],
|
||||
'create': function (path) {
|
||||
return new CurveFlag(path)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
geometry.setPoints(path)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return new Polygon(geometry.getCoordinates(), {
|
||||
'symbol': geometry.getSymbol()
|
||||
})
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.RECTFLAG] = {
|
||||
'freehand': false,
|
||||
'limitClickCount': 2,
|
||||
'action': ['click', 'mousemove', 'click'],
|
||||
'create': function (path) {
|
||||
return new RectFlag(path)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
geometry.setPoints(path)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return new Polygon(geometry.getCoordinates(), {
|
||||
'symbol': geometry.getSymbol()
|
||||
})
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.TRIANGLEFLAG] = {
|
||||
'freehand': false,
|
||||
'limitClickCount': 2,
|
||||
'action': ['click', 'mousemove', 'click'],
|
||||
'create': function (path) {
|
||||
return new TriangleFlag(path)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
geometry.setPoints(path)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return new Polygon(geometry.getCoordinates(), {
|
||||
'symbol': geometry.getSymbol()
|
||||
})
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.CIRCLE] = {
|
||||
'freehand': true,
|
||||
'action': ['mousedown', 'drag', 'mouseup'],
|
||||
'create': function (coordinate) {
|
||||
return new PlotCircle(coordinate[0], 0)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
const map = geometry.getMap()
|
||||
const radius = map.computeLength(geometry.getCenter(), path[path.length - 1])
|
||||
geometry.setRadius(radius)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return geometry
|
||||
}
|
||||
}
|
||||
RegisterModes[PlotTypes.ELLIPSE] = {
|
||||
'freehand': true,
|
||||
'action': ['mousedown', 'drag', 'mouseup'],
|
||||
'create': function (coordinate) {
|
||||
return new PlotEllipse(coordinate[0], 0, 0)
|
||||
},
|
||||
'update': function (path, geometry) {
|
||||
const map = geometry.getMap()
|
||||
const center = geometry.getCenter()
|
||||
const rx = map.computeLength(center, new Coordinate({
|
||||
x: path[path.length - 1].x,
|
||||
y: center.y
|
||||
}))
|
||||
const ry = map.computeLength(center, new Coordinate({
|
||||
x: center.x,
|
||||
y: path[path.length - 1].y
|
||||
}))
|
||||
geometry.setWidth(rx * 2)
|
||||
geometry.setHeight(ry * 2)
|
||||
},
|
||||
'generate': function (geometry) {
|
||||
return geometry
|
||||
}
|
||||
}
|
||||
|
||||
export default RegisterModes
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user