Merge pull request #4 from sakitam-fdd/dev

添加部分点,圆,椭圆,8种箭头类型符号
This commit is contained in:
FDD 2018-01-02 22:26:15 +08:00 committed by GitHub
commit d9cb5ed3ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1626 additions and 84 deletions

View File

@ -12,4 +12,3 @@ before_script:
- sleep 3 # give xvfb some time to start
script:
- npm run build
- npm run karma.test

View File

@ -1,7 +1,11 @@
## 0.0.2 (暂时添加所有符号类型)
* 添加部分点椭圆8种箭头类型符号
## 0.0.1 (完善PlotDraw)
* 完善PlotDraw
* 添加部分geometry构造类PloylineArrorPolygon
* 添加部分geometry构造类PloylineArrorPolygon, Flag
## 0.0.0 (搭建框架)

View File

@ -70,6 +70,7 @@ module.exports = [
{
file: resolve(_package.unpkg),
format: 'umd',
sourceMap: true,
env: 'development'
},
{

72
examples/circle.html Normal file
View 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: '&copy; <a href="http://osm.org">OpenStreetMap</a> contributors, &copy; <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>

View File

@ -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',

View File

@ -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'],

View 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

View File

@ -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
}

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -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
}
}

View File

@ -65,6 +65,7 @@ class Arc extends maptalks.LineString {
const coordinates = Coordinate.toNumberArrays(points)
return {
'type': 'LineString',
'subType': 'Arc',
'coordinates': coordinates
}
}

View File

@ -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