@vesium/plot 1.0.1-beta.51 → 1.0.1-beta.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,7 +1,9 @@
1
- import { CallbackPositionProperty, CallbackProperty, Cartesian3, Cartographic, ClassificationType, Color, ConstantPositionProperty, ConstantProperty, CoplanarPolygonGeometry, CustomDataSource, Ellipsoid, Entity, Event, HorizontalOrigin, JulianDate, PerInstanceColorAppearance, PolygonGeometry, PolygonHierarchy, PrimitiveCollection, Rectangle, ScreenSpaceEventType, TimeInterval, VertexFormat, VerticalOrigin, createGuid, sampleTerrainMostDetailed } from "cesium";
2
- import { arrayDiff, assertError, canvasCoordToCartesian, isFunction, pickHitGraphic, toCartesian3, toCartographic, useCesiumEventListener, useDataSource, useEntityScope, useGraphicEvent, usePrimitive, usePrimitiveScope, useScreenSpaceEventHandler, useViewer } from "vesium";
1
+ import { CallbackPositionProperty, CallbackProperty, Cartesian3, Cartographic, ClassificationType, Color, ConstantPositionProperty, ConstantProperty, CoplanarPolygonGeometry, CustomDataSource, Ellipsoid, Entity, Event, HorizontalOrigin, JulianDate, LabelGraphics, PerInstanceColorAppearance, PolygonGeometry, PolygonHierarchy, PolylineGraphics, PrimitiveCollection, Rectangle, ScreenSpaceEventType, TimeInterval, VertexFormat, VerticalOrigin, createGuid, sampleTerrainMostDetailed } from "cesium";
2
+ import { arrayDiff, assertError, canvasCoordToCartesian, isFunction, pickHitGraphic, toCartesian3, toCartographic, toCoord, toProperty, toPropertyValue, useCesiumEventListener, useDataSource, useEntityScope, useGraphicEvent, usePrimitive, usePrimitiveScope, useScreenSpaceEventHandler, useViewer } from "vesium";
3
3
  import { assert, onKeyStroke, promiseTimeout, watchArray } from "@vueuse/core";
4
4
  import { computed, nextTick, ref, shallowReactive, shallowRef, toValue, watch, watchEffect } from "vue";
5
+ import * as turf$1 from "@turf/turf";
6
+ import * as turf from "@turf/turf";
5
7
 
6
8
  //#region usePlot/PlotScheme.ts
7
9
  var PlotScheme = class PlotScheme {
@@ -11,9 +13,7 @@ var PlotScheme = class PlotScheme {
11
13
  this.allowManualComplete = options.allowManualComplete;
12
14
  this.definingCursor = options.definingCursor ?? "crosshair";
13
15
  this.skeletons = options.skeletons?.map((item) => item()) ?? [];
14
- this.initEntites = options.initEntites;
15
- this.initPrimitives = options.initPrimitives;
16
- this.initGroundPrimitives = options.initGroundPrimitives;
16
+ this.initRender = options.initRender;
17
17
  this.render = options.render;
18
18
  }
19
19
  /**
@@ -40,17 +40,9 @@ var PlotScheme = class PlotScheme {
40
40
  */
41
41
  skeletons;
42
42
  /**
43
- * 初始化时创建`Entity`的函数,创建后的`Entity`会作为配置项传入`render`中
44
- */
45
- initEntites;
46
- /**
47
- * 初始化时创建`Primitive`的函数,创建后的`Primitive`会作为配置项传入`render`中
48
- */
49
- initPrimitives;
50
- /**
51
43
  * 初始化时创建贴地`Primitive`的函数,创建后的`Primitive`会作为配置项传入`render`中
52
44
  */
53
- initGroundPrimitives;
45
+ initRender;
54
46
  /**
55
47
  * 当标绘数据变化时,会触发`render`回调,返回的数据会被添加到cesium中
56
48
  */
@@ -225,10 +217,13 @@ var SampledPlotProperty = class SampledPlotProperty {
225
217
  * @template D 数据类型。
226
218
  */
227
219
  getValue(time, result) {
228
- result ??= { time };
220
+ result ??= {
221
+ time,
222
+ positions: []
223
+ };
229
224
  Object.assign(result, {
230
225
  time: time?.clone(),
231
- positions: void 0,
226
+ positions: [],
232
227
  derivative: void 0
233
228
  });
234
229
  if (!time) {
@@ -344,9 +339,10 @@ var PlotFeature = class {
344
339
  this._disabled = disabled;
345
340
  this._sampled = sampled instanceof SampledPlotProperty ? sampled : new SampledPlotProperty(sampled);
346
341
  this._sampled.definitionChanged.addEventListener((property) => this._definitionChanged.raiseEvent(this, "sampled", property, property), this);
347
- this._entities = [...this._scheme.initEntites?.() ?? []];
348
- this._primitives = [...this._scheme.initPrimitives?.() ?? []];
349
- this._groundPrimitives = [...this._scheme.initGroundPrimitives?.() ?? []];
342
+ const init = this._scheme.initRender?.() ?? {};
343
+ this._entities = [...init.entities ?? []];
344
+ this._primitives = [...init.primitives ?? []];
345
+ this._groundPrimitives = [...init.groundPrimitives ?? []];
350
346
  this._skeletons = [];
351
347
  }
352
348
  /**
@@ -917,9 +913,9 @@ function control() {
917
913
  const positions = [...packable.positions ?? []];
918
914
  const cartographic = toCartographic(positions[index]);
919
915
  const r = height / 1e5;
920
- const distance = r * Math.PI / 180 / 1e3;
921
- cartographic.latitude += distance * Math.cos(newHeading);
922
- cartographic.longitude += distance * Math.sin(newHeading);
916
+ const distance$1 = r * Math.PI / 180 / 1e3;
917
+ cartographic.latitude += distance$1 * Math.cos(newHeading);
918
+ cartographic.longitude += distance$1 * Math.sin(newHeading);
923
919
  positions[index] = toCartesian3(cartographic);
924
920
  sampled.setSample({
925
921
  time: packable.time,
@@ -1182,7 +1178,7 @@ async function clampToHeightMostDetailedByTilesetOrTerrain(options) {
1182
1178
 
1183
1179
  //#endregion
1184
1180
  //#region measure/utils/triangleGrid.ts
1185
- function defaultOptions$1(original) {
1181
+ function defaultOptions$2(original) {
1186
1182
  const clampToGround = original?.clampToGround ?? false;
1187
1183
  const classificationType = original?.classificationType ?? ClassificationType.BOTH;
1188
1184
  const density = Math.floor(original?.density ?? 10);
@@ -1201,7 +1197,7 @@ function defaultOptions$1(original) {
1201
1197
  */
1202
1198
  async function triangleGrid(positions, options) {
1203
1199
  if (positions.length < 3) throw new Error("positions must >= 3");
1204
- const { density, scene, clampToGround, classificationType, terrainProvider } = defaultOptions$1(options);
1200
+ const { density, scene, clampToGround, classificationType, terrainProvider } = defaultOptions$2(options);
1205
1201
  if (density <= 0) throw new Error("options.density must > 0");
1206
1202
  const bbox = Rectangle.fromCartesianArray(positions);
1207
1203
  const vertical = bbox.north - bbox.south;
@@ -1260,7 +1256,7 @@ function triangleArea(p0, p1, p2) {
1260
1256
  const cross = Cartesian3.cross(v0, v1, v0);
1261
1257
  return Cartesian3.magnitude(cross) * .5;
1262
1258
  }
1263
- function defaultOptions(original) {
1259
+ function defaultOptions$1(original) {
1264
1260
  const clampToGround = original?.clampToGround ?? false;
1265
1261
  const classificationType = original?.classificationType ?? ClassificationType.BOTH;
1266
1262
  const density = Math.floor(original?.density ?? 10);
@@ -1278,7 +1274,7 @@ function defaultOptions(original) {
1278
1274
  */
1279
1275
  async function area(positions, options) {
1280
1276
  if (positions.length < 2) throw new Error("positions.length must >= 2");
1281
- const { density, scene, clampToGround, classificationType, terrainProvider } = defaultOptions(options);
1277
+ const { density, scene, clampToGround, classificationType, terrainProvider } = defaultOptions$1(options);
1282
1278
  if (density <= 0) throw new Error("options.density must > 0");
1283
1279
  if (!clampToGround) {
1284
1280
  const triangles$1 = tesselate(positions);
@@ -1294,24 +1290,111 @@ async function area(positions, options) {
1294
1290
  return triangles.reduce((count, current) => count += triangleArea(...current), 0);
1295
1291
  }
1296
1292
 
1293
+ //#endregion
1294
+ //#region measure/utils/lerpArray.ts
1295
+ /**
1296
+ * 在起点和终点间进行插值, 返回的数组包括起点和终点,数组长度为 count+1
1297
+ */
1298
+ async function lerpArray(options) {
1299
+ const { start, end, count, scene, clampToGround, classificationType, terrainProvider } = options;
1300
+ const result = [];
1301
+ for (let i = 0; i < count; i++) {
1302
+ const position = Cartesian3.lerp(start, end, 1 / count, new Cartesian3());
1303
+ result.push(position);
1304
+ }
1305
+ result.push(end.clone());
1306
+ if (!clampToGround) return result;
1307
+ if (!scene) throw new Error("scene is required on `clampToGround == true`.");
1308
+ const detaileds = await clampToHeightMostDetailedByTilesetOrTerrain({
1309
+ scene,
1310
+ terrainProvider,
1311
+ positions: result,
1312
+ classificationType
1313
+ });
1314
+ return detaileds;
1315
+ }
1316
+
1317
+ //#endregion
1318
+ //#region measure/utils/distance.ts
1319
+ function defaultOptions(original) {
1320
+ const clampToGround = original?.clampToGround ?? false;
1321
+ const classificationType = original?.classificationType ?? ClassificationType.BOTH;
1322
+ const density = Math.floor(original?.density ?? 50);
1323
+ return {
1324
+ scene: original?.scene,
1325
+ clampToGround,
1326
+ classificationType,
1327
+ terrainProvider: original?.terrainProvider,
1328
+ density
1329
+ };
1330
+ }
1331
+ /**
1332
+ * 计算多点位之间的距离
1333
+ * @param positions
1334
+ */
1335
+ async function distance(positions, options) {
1336
+ if (positions.length < 2) throw new Error("positions.length must >= 2");
1337
+ const _options = defaultOptions(options);
1338
+ const stages = [];
1339
+ let count = 0;
1340
+ positions.forEach((position, index) => {
1341
+ if (index !== positions.length - 1) {
1342
+ const next = positions[index + 1];
1343
+ const distance$1 = Cartesian3.distance(position, next);
1344
+ stages.push(distance$1);
1345
+ count += distance$1;
1346
+ }
1347
+ });
1348
+ if (!_options.clampToGround) return {
1349
+ stages,
1350
+ count
1351
+ };
1352
+ const density = _options.density;
1353
+ if (density <= 0) throw new Error("options.density must > 0");
1354
+ const densities = stages.map((stage) => {
1355
+ return Math.floor(stage / count * density);
1356
+ });
1357
+ const diff = density - densities.reduce((count$1, current) => count$1 += current, 0);
1358
+ if (diff) densities[densities.length - 1] += diff;
1359
+ const positionListPromises = densities.map((density$1, i) => {
1360
+ return lerpArray({
1361
+ scene: _options.scene,
1362
+ start: positions[i],
1363
+ end: positions[i + 1],
1364
+ count: density$1,
1365
+ clampToGround: true,
1366
+ classificationType: _options.classificationType,
1367
+ terrainProvider: _options.terrainProvider
1368
+ });
1369
+ });
1370
+ const detaileds = await Promise.all(positionListPromises);
1371
+ const stagePromises = detaileds.map(async (positions$1) => {
1372
+ const { count: count$1 } = await distance(positions$1);
1373
+ return count$1;
1374
+ });
1375
+ const groundStages = await Promise.all(stagePromises);
1376
+ return {
1377
+ stages: groundStages,
1378
+ count: groundStages.reduce((count$1, current) => count$1 += current, 0)
1379
+ };
1380
+ }
1381
+
1297
1382
  //#endregion
1298
1383
  //#region measure/measureArea.ts
1299
1384
  const schemeMeasureArea = new PlotScheme({
1300
- type: "measureArea",
1385
+ type: "MeasureArea",
1301
1386
  allowManualComplete: (packable) => packable.positions.length >= 3,
1302
1387
  skeletons: [control, interval],
1303
- initEntites: () => [new Entity({
1304
- label: { font: "14pt" },
1305
- polyline: { material: Color.YELLOW.withAlpha(.5) },
1306
- polygon: { material: Color.YELLOW.withAlpha(.5) }
1307
- })],
1308
- render(options) {
1309
- const { mouse, packable } = options;
1310
- const entity = options.previous.entities?.[0] ?? new Entity({
1388
+ initRender() {
1389
+ return { entities: [new Entity({
1311
1390
  label: { font: "14pt" },
1312
1391
  polyline: { material: Color.YELLOW.withAlpha(.5) },
1313
1392
  polygon: { material: Color.YELLOW.withAlpha(.5) }
1314
- });
1393
+ })] };
1394
+ },
1395
+ render(context) {
1396
+ const entity = context.previous.entities[0];
1397
+ const { mouse, packable } = context;
1315
1398
  const positions = [...packable.positions ?? []];
1316
1399
  mouse && positions.push(mouse);
1317
1400
  if (positions.length === 2) {
@@ -1343,19 +1426,67 @@ const schemeMeasureArea = new PlotScheme({
1343
1426
  });
1344
1427
 
1345
1428
  //#endregion
1346
- //#region scheme/billboard.ts
1347
- /**
1348
- * 广告牌标绘方案
1349
- */
1350
- const schemeBillboard = new PlotScheme({
1351
- type: "billboard",
1429
+ //#region measure/measureDistance.ts
1430
+ const schemeMeasureDistance = new PlotScheme({
1431
+ type: "MeasureDistance",
1432
+ allowManualComplete: (packable) => packable.positions.length >= 2,
1433
+ skeletons: [control],
1434
+ initRender() {
1435
+ return { entities: [new Entity({ polyline: {
1436
+ width: 2,
1437
+ material: Color.YELLOW.withAlpha(.5)
1438
+ } })] };
1439
+ },
1440
+ render(context) {
1441
+ const entity = context.previous.entities[0];
1442
+ const { mouse, packable, previous } = context;
1443
+ const entities = previous.entities;
1444
+ const positions = [...packable.positions ?? []];
1445
+ mouse && positions.push(mouse);
1446
+ if (positions.length < 2) return { entities };
1447
+ const pl = entities[0];
1448
+ pl.polyline ??= new PolylineGraphics();
1449
+ pl.polyline.positions = new CallbackProperty(() => positions, false);
1450
+ positions.forEach((item, index) => {
1451
+ if (!entities[index + 1]) entities[index + 1] = new Entity({
1452
+ position: item,
1453
+ label: new LabelGraphics({
1454
+ backgroundColor: Color.fromCssColorString("#fff"),
1455
+ font: "12pt sans-serif"
1456
+ })
1457
+ });
1458
+ });
1459
+ entities.splice(positions.length, entities.length - positions.length - 1);
1460
+ distance(positions).then(({ count, stages }) => {
1461
+ stages.forEach((stage, index) => {
1462
+ entities[index + 1].position = new CallbackPositionProperty(() => Cartesian3.midpoint(positions[index], positions[index + 1], new Cartesian3()), false);
1463
+ entities[index + 1].label.text = new CallbackProperty(() => `${stage.toFixed(2)} m`, false);
1464
+ });
1465
+ if (stages.length > 1) {
1466
+ entities[entities.length - 1].position = new CallbackPositionProperty(() => positions[positions.length - 1], false);
1467
+ entities[entities.length - 1].label.text = new CallbackProperty(() => `${count.toFixed(2)} m`, false);
1468
+ } else {
1469
+ entities[entities.length - 1].position = void 0;
1470
+ entities[entities.length - 1].label.text = void 0;
1471
+ }
1472
+ });
1473
+ return { entities };
1474
+ }
1475
+ });
1476
+
1477
+ //#endregion
1478
+ //#region scheme/Billboard.ts
1479
+ const PlotSchemeBillboard = new PlotScheme({
1480
+ type: "Billboard",
1352
1481
  complete: (packable) => packable.positions.length >= 1,
1353
1482
  skeletons: [moved],
1354
- initEntites: () => [new Entity({ billboard: {
1355
- image: "/favicon.svg",
1356
- width: 32,
1357
- height: 32
1358
- } })],
1483
+ initRender: () => {
1484
+ return { entities: [new Entity({ billboard: {
1485
+ image: "/favicon.svg",
1486
+ width: 32,
1487
+ height: 32
1488
+ } })] };
1489
+ },
1359
1490
  render(options) {
1360
1491
  const { mouse, packable } = options;
1361
1492
  const entity = options.previous.entities?.[0] ?? new Entity({ billboard: {} });
@@ -1366,47 +1497,130 @@ const schemeBillboard = new PlotScheme({
1366
1497
  });
1367
1498
 
1368
1499
  //#endregion
1369
- //#region scheme/label.ts
1370
- /**
1371
- * 标签文字标绘方案
1372
- */
1373
- const schemeLabel = new PlotScheme({
1374
- type: "label",
1500
+ //#region scheme/BillboardPinBuilder.ts
1501
+ const PlotSchemeBillboardPinBuilder = new PlotScheme({
1502
+ type: "BillboardPinBuilder",
1375
1503
  complete: (packable) => packable.positions.length >= 1,
1376
1504
  skeletons: [moved],
1377
- initEntites: () => [new Entity({ label: { text: "Label" } })],
1378
- render(options) {
1379
- const { mouse, packable } = options;
1380
- const entity = options.previous.entities?.[0] ?? new Entity({ label: {} });
1381
- const position = packable.positions?.[0] ?? mouse;
1505
+ initRender() {
1506
+ return { entities: [new Entity({ billboard: {} })] };
1507
+ },
1508
+ render(context) {
1509
+ const entity = context.previous.entities[0];
1510
+ const position = context.packable.positions[0] ?? context.mouse;
1382
1511
  entity.position = new CallbackPositionProperty(() => position, true);
1383
1512
  return { entities: [entity] };
1384
1513
  }
1385
1514
  });
1386
1515
 
1387
1516
  //#endregion
1388
- //#region scheme/polygon.ts
1389
- /**
1390
- * 内置的多边形标绘方案
1391
- */
1392
- const schemePolygon = new PlotScheme({
1393
- type: "polygon",
1394
- allowManualComplete: (packable) => packable.positions.length >= 3,
1517
+ //#region scheme/Cylinder.ts
1518
+ const PlotSchemeCylinder = new PlotScheme({
1519
+ type: "Cylinder",
1520
+ complete: (packable) => packable.positions.length >= 2,
1521
+ skeletons: [moved, control],
1522
+ initRender() {
1523
+ return { entities: [new Entity({ cylinder: {} })] };
1524
+ },
1525
+ render(context) {
1526
+ const entity = context.previous.entities[0];
1527
+ const positions = [...context.packable.positions];
1528
+ if (positions.length === 0) return context.previous;
1529
+ if (positions.length === 1) {
1530
+ const position = context.mouse;
1531
+ position && positions.push(position);
1532
+ }
1533
+ if (positions.length < 2) return context.previous;
1534
+ entity.position = new ConstantPositionProperty(positions[0]);
1535
+ const radius = Cartesian3.distance(positions[0], positions[1]);
1536
+ entity.cylinder.bottomRadius = new CallbackProperty(() => radius, false);
1537
+ if (context.defining || !toPropertyValue(entity.cylinder.length)) entity.cylinder.length = toProperty(radius * 2);
1538
+ return { entities: [entity] };
1539
+ }
1540
+ });
1541
+
1542
+ //#endregion
1543
+ //#region scheme/Ellipse.ts
1544
+ const PlotSchemeEllipse = new PlotScheme({
1545
+ type: "Ellipse",
1546
+ complete: (packable) => packable.positions.length >= 2,
1547
+ skeletons: [moved, control],
1548
+ initRender() {
1549
+ return { entities: [new Entity({ ellipse: {} })] };
1550
+ },
1551
+ render(context) {
1552
+ const entity = context.previous.entities[0];
1553
+ const positions = [...context.packable.positions];
1554
+ if (positions.length === 0) return context.previous;
1555
+ if (positions.length === 1) {
1556
+ const position = context.mouse;
1557
+ position && positions.push(position);
1558
+ }
1559
+ if (positions.length < 2) return context.previous;
1560
+ entity.position = new ConstantPositionProperty(positions[0]);
1561
+ const radius = Cartesian3.distance(positions[0], positions[1]);
1562
+ entity.ellipse.semiMinorAxis = new CallbackProperty(() => radius || 1, false);
1563
+ entity.ellipse.semiMajorAxis = entity.ellipse.semiMinorAxis;
1564
+ return { entities: [entity] };
1565
+ }
1566
+ });
1567
+
1568
+ //#endregion
1569
+ //#region scheme/Label.ts
1570
+ const PlotSchemeLabel = new PlotScheme({
1571
+ type: "Label",
1572
+ complete: (packable) => packable.positions.length >= 1,
1573
+ skeletons: [moved],
1574
+ initRender() {
1575
+ return { entities: [new Entity({ label: { text: "Label" } })] };
1576
+ },
1577
+ render(context) {
1578
+ const entity = context.previous.entities[0];
1579
+ const position = context.packable.positions[0] ?? context.mouse;
1580
+ entity.position = new CallbackPositionProperty(() => position, true);
1581
+ return { entities: [entity] };
1582
+ }
1583
+ });
1584
+
1585
+ //#endregion
1586
+ //#region scheme/Point.ts
1587
+ const PlotSchemePoint = new PlotScheme({
1588
+ type: "Point",
1589
+ complete: (packable) => packable.positions.length >= 1,
1590
+ skeletons: [moved],
1591
+ initRender() {
1592
+ return { entities: [new Entity({ point: {
1593
+ pixelSize: 10,
1594
+ color: Color.RED
1595
+ } })] };
1596
+ },
1597
+ render(context) {
1598
+ const entity = context.previous.entities[0];
1599
+ const position = context.packable.positions[0] ?? context.mouse;
1600
+ entity.position = new CallbackPositionProperty(() => position, true);
1601
+ return { entities: [entity] };
1602
+ }
1603
+ });
1604
+
1605
+ //#endregion
1606
+ //#region scheme/Polygon.ts
1607
+ const PlotSchemePolygon = new PlotScheme({
1608
+ type: "Polygon",
1609
+ allowManualComplete: (packable) => packable.positions.length >= 2,
1395
1610
  skeletons: [
1611
+ moved,
1396
1612
  control,
1397
- interval,
1398
- moved
1613
+ interval
1399
1614
  ],
1400
- initEntites: () => [new Entity({
1401
- polyline: { material: Color.YELLOW.withAlpha(.5) },
1402
- polygon: { material: Color.YELLOW.withAlpha(.5) }
1403
- })],
1615
+ initRender: () => {
1616
+ return { entities: [new Entity({
1617
+ polyline: {},
1618
+ polygon: {}
1619
+ })] };
1620
+ },
1404
1621
  render(options) {
1405
1622
  const { mouse, packable } = options;
1406
- const entity = options.previous.entities?.[0] ?? new Entity({
1407
- polyline: { material: Color.YELLOW.withAlpha(.5) },
1408
- polygon: { material: Color.YELLOW.withAlpha(.5) }
1409
- });
1623
+ const entity = options.previous.entities[0];
1410
1624
  const positions = [...packable.positions ?? []];
1411
1625
  mouse && positions.push(mouse);
1412
1626
  if (positions.length === 2) {
@@ -1427,55 +1641,1366 @@ const schemePolygon = new PlotScheme({
1427
1641
  });
1428
1642
 
1429
1643
  //#endregion
1430
- //#region scheme/polyline.ts
1644
+ //#region geom/helper.ts
1645
+ const FITTING_COUNT = 100;
1646
+ const HALF_PI = Math.PI / 2;
1647
+ const ZERO_TOLERANCE = 1e-4;
1648
+ const TWO_PI = Math.PI * 2;
1649
+ /**
1650
+ * 计算两个坐标之间的距离
1651
+ * @param coord1
1652
+ * @param coord2
1653
+ */
1654
+ function mathDistance(coord1, coord2) {
1655
+ return Math.hypot(coord1[0] - coord2[0], coord1[1] - coord2[1]);
1656
+ }
1657
+ /**
1658
+ * 计算点集合的总距离
1659
+ * @param points
1660
+ */
1661
+ function wholeDistance(points) {
1662
+ let distance$1 = 0;
1663
+ if (points && Array.isArray(points) && points.length > 0) points.forEach((item, index) => {
1664
+ if (index < points.length - 1) distance$1 += mathDistance(item, points[index + 1]);
1665
+ });
1666
+ return distance$1;
1667
+ }
1668
+ /**
1669
+ * 获取基础长度
1670
+ * @param points
1671
+ */
1672
+ const getBaseLength = (points) => wholeDistance(points) ** .99;
1673
+ /**
1674
+ * 求取两个坐标的中间坐标
1675
+ * @param coord1
1676
+ * @param coord2
1677
+ */
1678
+ function mid(coord1, coord2) {
1679
+ return [(coord1[0] + coord2[0]) / 2, (coord1[1] + coord2[1]) / 2];
1680
+ }
1681
+ /**
1682
+ * 通过三个点确定一个圆的中心点
1683
+ * @param coord1
1684
+ * @param coord2
1685
+ * @param coord3
1686
+ */
1687
+ function getCircleCenterOfThreeCoords(coord1, coord2, coord3) {
1688
+ const coordA = [(coord1[0] + coord2[0]) / 2, (coord1[1] + coord2[1]) / 2];
1689
+ const coordB = [coordA[0] - coord1[1] + coord2[1], coordA[1] + coord1[0] - coord2[0]];
1690
+ const coordC = [(coord1[0] + coord3[0]) / 2, (coord1[1] + coord3[1]) / 2];
1691
+ const coordD = [coordC[0] - coord1[1] + coord3[1], coordC[1] + coord1[0] - coord3[0]];
1692
+ return getIntersectCoord(coordA, coordB, coordC, coordD);
1693
+ }
1694
+ /**
1695
+ * 获取交集的点
1696
+ * @param coordA
1697
+ * @param coordB
1698
+ * @param coordC
1699
+ * @param coordD
1700
+ */
1701
+ function getIntersectCoord(coordA, coordB, coordC, coordD) {
1702
+ if (coordA[1] === coordB[1]) {
1703
+ const f$1 = (coordD[0] - coordC[0]) / (coordD[1] - coordC[1]);
1704
+ const x$1 = f$1 * (coordA[1] - coordC[1]) + coordC[0];
1705
+ const y$1 = coordA[1];
1706
+ return [x$1, y$1];
1707
+ }
1708
+ if (coordC[1] === coordD[1]) {
1709
+ const e$1 = (coordB[0] - coordA[0]) / (coordB[1] - coordA[1]);
1710
+ const x$1 = e$1 * (coordC[1] - coordA[1]) + coordA[0];
1711
+ const y$1 = coordC[1];
1712
+ return [x$1, y$1];
1713
+ }
1714
+ const e = (coordB[0] - coordA[0]) / (coordB[1] - coordA[1]);
1715
+ const f = (coordD[0] - coordC[0]) / (coordD[1] - coordC[1]);
1716
+ const y = (e * coordA[1] - coordA[0] - f * coordC[1] + coordC[0]) / (e - f);
1717
+ const x = e * y - e * coordA[1] + coordA[0];
1718
+ return [x, y];
1719
+ }
1720
+ /**
1721
+ * 获取方位角(地平经度)
1722
+ * @param startCoord
1723
+ * @param endCoord
1724
+ */
1725
+ function getAzimuth(startCoord, endCoord) {
1726
+ let azimuth = 0;
1727
+ const angle = Math.asin(Math.abs(endCoord[1] - startCoord[1]) / mathDistance(startCoord, endCoord));
1728
+ if (endCoord[1] >= startCoord[1] && endCoord[0] >= startCoord[0]) azimuth = angle + Math.PI;
1729
+ else if (endCoord[1] >= startCoord[1] && endCoord[0] < startCoord[0]) azimuth = Math.PI * 2 - angle;
1730
+ else if (endCoord[1] < startCoord[1] && endCoord[0] < startCoord[0]) azimuth = angle;
1731
+ else if (endCoord[1] < startCoord[1] && endCoord[0] >= startCoord[0]) azimuth = Math.PI - angle;
1732
+ return azimuth;
1733
+ }
1734
+ /**
1735
+ * 通过三个点获取方位角
1736
+ * @param coordA
1737
+ * @param coordB
1738
+ * @param coordC
1739
+ */
1740
+ function getAngleOfThreeCoords(coordA, coordB, coordC) {
1741
+ const angle = getAzimuth(coordB, coordA) - getAzimuth(coordB, coordC);
1742
+ return angle < 0 ? angle + Math.PI * 2 : angle;
1743
+ }
1744
+ /**
1745
+ * 判断是否是顺时针
1746
+ * @param coord1
1747
+ * @param coord2
1748
+ * @param coord3
1749
+ */
1750
+ function isClockWise(coord1, coord2, coord3) {
1751
+ return (coord3[1] - coord1[1]) * (coord2[0] - coord1[0]) > (coord2[1] - coord1[1]) * (coord3[0] - coord1[0]);
1752
+ }
1753
+ /**
1754
+ * 获取立方值
1755
+ */
1756
+ function getCubicValue(t, startCoord, coord1, coord2, endCoord) {
1757
+ t = Math.max(Math.min(t, 1), 0);
1758
+ const [tp, t2] = [1 - t, t * t];
1759
+ const t3 = t2 * t;
1760
+ const tp2 = tp * tp;
1761
+ const tp3 = tp2 * tp;
1762
+ const x = tp3 * startCoord[0] + 3 * tp2 * t * coord1[0] + 3 * tp * t2 * coord2[0] + t3 * endCoord[0];
1763
+ const y = tp3 * startCoord[1] + 3 * tp2 * t * coord1[1] + 3 * tp * t2 * coord2[1] + t3 * endCoord[1];
1764
+ return [x, y];
1765
+ }
1766
+ /**
1767
+ * 根据起止点和旋转方向求取第三个点
1768
+ * @param startCoord
1769
+ * @param endCoord
1770
+ * @param angle
1771
+ * @param distance
1772
+ * @param clockWise
1773
+ */
1774
+ function getThirdCoord(startCoord, endCoord, angle, distance$1, clockWise) {
1775
+ const azimuth = getAzimuth(startCoord, endCoord);
1776
+ const alpha = clockWise ? azimuth + angle : azimuth - angle;
1777
+ const dx = distance$1 * Math.cos(alpha);
1778
+ const dy = distance$1 * Math.sin(alpha);
1779
+ return [endCoord[0] + dx, endCoord[1] + dy];
1780
+ }
1781
+ /**
1782
+ * 插值弓形线段点
1783
+ * @param center
1784
+ * @param radius
1785
+ * @param startAngle
1786
+ * @param endAngle
1787
+ */
1788
+ function getArcCoords(center, radius, startAngle, endAngle) {
1789
+ let [x, y, coords, angleDiff] = [
1790
+ 0,
1791
+ 0,
1792
+ [],
1793
+ endAngle - startAngle
1794
+ ];
1795
+ angleDiff = angleDiff < 0 ? angleDiff + Math.PI * 2 : angleDiff;
1796
+ for (let i = 0; i <= 100; i++) {
1797
+ const angle = startAngle + angleDiff * i / 100;
1798
+ x = center[0] + radius * Math.cos(angle);
1799
+ y = center[1] + radius * Math.sin(angle);
1800
+ coords.push([x, y]);
1801
+ }
1802
+ return coords;
1803
+ }
1804
+ /**
1805
+ * getBisectorNormals
1806
+ * @param t
1807
+ * @param coord1
1808
+ * @param coord2
1809
+ * @param coord3
1810
+ */
1811
+ function getBisectorNormals(t, coord1, coord2, coord3) {
1812
+ const normal = getNormal(coord1, coord2, coord3);
1813
+ let [bisectorNormalRight, bisectorNormalLeft, dt, x, y] = [
1814
+ [0, 0],
1815
+ [0, 0],
1816
+ 0,
1817
+ 0,
1818
+ 0
1819
+ ];
1820
+ const dist = Math.hypot(normal[0], normal[1]);
1821
+ const uX = normal[0] / dist;
1822
+ const uY = normal[1] / dist;
1823
+ const d1 = mathDistance(coord1, coord2);
1824
+ const d2 = mathDistance(coord2, coord3);
1825
+ if (dist > ZERO_TOLERANCE) if (isClockWise(coord1, coord2, coord3)) {
1826
+ dt = t * d1;
1827
+ x = coord2[0] - dt * uY;
1828
+ y = coord2[1] + dt * uX;
1829
+ bisectorNormalRight = [x, y];
1830
+ dt = t * d2;
1831
+ x = coord2[0] + dt * uY;
1832
+ y = coord2[1] - dt * uX;
1833
+ bisectorNormalLeft = [x, y];
1834
+ } else {
1835
+ dt = t * d1;
1836
+ x = coord2[0] + dt * uY;
1837
+ y = coord2[1] - dt * uX;
1838
+ bisectorNormalRight = [x, y];
1839
+ dt = t * d2;
1840
+ x = coord2[0] - dt * uY;
1841
+ y = coord2[1] + dt * uX;
1842
+ bisectorNormalLeft = [x, y];
1843
+ }
1844
+ else {
1845
+ x = coord2[0] + t * (coord1[0] - coord2[0]);
1846
+ y = coord2[1] + t * (coord1[1] - coord2[1]);
1847
+ bisectorNormalRight = [x, y];
1848
+ x = coord2[0] + t * (coord3[0] - coord2[0]);
1849
+ y = coord2[1] + t * (coord3[1] - coord2[1]);
1850
+ bisectorNormalLeft = [x, y];
1851
+ }
1852
+ return [bisectorNormalRight, bisectorNormalLeft];
1853
+ }
1854
+ /**
1855
+ * 获取默认三点的内切圆
1856
+ * @param coord1
1857
+ * @param coord2
1858
+ * @param coord3
1859
+ */
1860
+ function getNormal(coord1, coord2, coord3) {
1861
+ let dX1 = coord1[0] - coord2[0];
1862
+ let dY1 = coord1[1] - coord2[1];
1863
+ const d1 = Math.hypot(dX1, dY1);
1864
+ dX1 /= d1;
1865
+ dY1 /= d1;
1866
+ let dX2 = coord3[0] - coord2[0];
1867
+ let dY2 = coord3[1] - coord2[1];
1868
+ const d2 = Math.hypot(dX2, dY2);
1869
+ dX2 /= d2;
1870
+ dY2 /= d2;
1871
+ const uX = dX1 + dX2;
1872
+ const uY = dY1 + dY2;
1873
+ return [uX, uY];
1874
+ }
1875
+ /**
1876
+ * 贝塞尔曲线
1877
+ * @param points
1878
+ */
1879
+ function getBezierCoords(points) {
1880
+ if (points.length <= 2) return points;
1881
+ const bezierCoords = [];
1882
+ const n = points.length - 1;
1883
+ for (let t = 0; t <= 1; t += .01) {
1884
+ let [x, y] = [0, 0];
1885
+ for (let index = 0; index <= n; index++) {
1886
+ const factor = getBinomialFactor(n, index);
1887
+ const a = t ** index;
1888
+ const b = (1 - t) ** (n - index);
1889
+ x += factor * a * b * points[index][0];
1890
+ y += factor * a * b * points[index][1];
1891
+ }
1892
+ bezierCoords.push([x, y]);
1893
+ }
1894
+ bezierCoords.push(points[n]);
1895
+ return bezierCoords;
1896
+ }
1897
+ /**
1898
+ * 获取阶乘数据
1899
+ * @param n
1900
+ */
1901
+ function getFactorial(n) {
1902
+ let result = 1;
1903
+ switch (true) {
1904
+ case n <= 1:
1905
+ result = 1;
1906
+ break;
1907
+ case n === 2:
1908
+ result = 2;
1909
+ break;
1910
+ case n === 3:
1911
+ result = 6;
1912
+ break;
1913
+ case n === 24:
1914
+ result = 24;
1915
+ break;
1916
+ case n === 5:
1917
+ result = 120;
1918
+ break;
1919
+ default:
1920
+ for (let i = 1; i <= n; i++) result *= i;
1921
+ break;
1922
+ }
1923
+ return result;
1924
+ }
1925
+ /**
1926
+ * 获取二项分布
1927
+ * @param n
1928
+ * @param index
1929
+ */
1930
+ function getBinomialFactor(n, index) {
1931
+ return getFactorial(n) / (getFactorial(index) * getFactorial(n - index));
1932
+ }
1933
+ /**
1934
+ * 插值线性点
1935
+ * @param points
1936
+ */
1937
+ function getQBSplineCoords(points) {
1938
+ if (points.length <= 2) return points;
1939
+ const [n, bSplineCoords] = [2, []];
1940
+ const m = points.length - n - 1;
1941
+ bSplineCoords.push(points[0]);
1942
+ for (let i = 0; i <= m; i++) for (let t = 0; t <= 1; t += .05) {
1943
+ let [x, y] = [0, 0];
1944
+ for (let k = 0; k <= n; k++) {
1945
+ const factor = getQuadricBSplineFactor(k, t);
1946
+ x += factor * points[i + k][0];
1947
+ y += factor * points[i + k][1];
1948
+ }
1949
+ bSplineCoords.push([x, y]);
1950
+ }
1951
+ bSplineCoords.push(points.at(-1));
1952
+ return bSplineCoords;
1953
+ }
1954
+ /**
1955
+ * 得到二次线性因子
1956
+ * @param k
1957
+ * @param t
1958
+ */
1959
+ function getQuadricBSplineFactor(k, t) {
1960
+ let res = 0;
1961
+ if (k === 0) res = (t - 1) ** 2 / 2;
1962
+ else if (k === 1) res = (-2 * t ** 2 + 2 * t + 1) / 2;
1963
+ else if (k === 2) res = t ** 2 / 2;
1964
+ return res;
1965
+ }
1966
+
1967
+ //#endregion
1968
+ //#region geom/arc.ts
1969
+ /**
1970
+ * 标绘画弓形算法,继承线要素相关方法和属性
1971
+ */
1972
+ function arc(coords) {
1973
+ const coordlength = coords.length;
1974
+ if (coordlength <= 2) throw new Error("coords.length must >= 3");
1975
+ else {
1976
+ let [coord1, coord2, coord3, startAngle, endAngle] = [
1977
+ coords[0],
1978
+ coords[1],
1979
+ coords[2],
1980
+ 0,
1981
+ 0
1982
+ ];
1983
+ const center = getCircleCenterOfThreeCoords(coord1, coord2, coord3);
1984
+ const radius = mathDistance(coord1, center);
1985
+ const angle1 = getAzimuth(coord1, center);
1986
+ const angle2 = getAzimuth(coord2, center);
1987
+ if (isClockWise(coord1, coord2, coord3)) {
1988
+ startAngle = angle2;
1989
+ endAngle = angle1;
1990
+ } else {
1991
+ startAngle = angle1;
1992
+ endAngle = angle2;
1993
+ }
1994
+ return getArcCoords(center, radius, startAngle, endAngle);
1995
+ }
1996
+ }
1997
+
1998
+ //#endregion
1999
+ //#region geom/arrowAttackDirection.ts
2000
+ /**
2001
+ * 尖曲箭头
2002
+ */
2003
+ function arrowAttackDirection(coords, options = {}) {
2004
+ const coordLength = coords.length;
2005
+ if (coordLength < 3) throw new Error("coords.length must >= 3");
2006
+ else {
2007
+ let [tailLeft, tailRight] = [coords[0], coords[1]];
2008
+ if (isClockWise(coords[0], coords[1], coords[2])) {
2009
+ tailLeft = coords[1];
2010
+ tailRight = coords[0];
2011
+ }
2012
+ const midTail = mid(tailLeft, tailRight);
2013
+ const boneCoords = [midTail].concat(coords.slice(2));
2014
+ const headCoords = getArrowHeadCoords(boneCoords, {
2015
+ tailLeft,
2016
+ tailRight,
2017
+ ...options
2018
+ });
2019
+ if (headCoords && headCoords.length > 4) {
2020
+ const [neckLeft, neckRight] = [headCoords[0], headCoords[4]];
2021
+ const tailWidthFactor = mathDistance(tailLeft, tailRight) / getBaseLength(boneCoords);
2022
+ const bodyCoords = getArrowBodyCoords(boneCoords, neckLeft, neckRight, tailWidthFactor);
2023
+ const coordlength = bodyCoords.length;
2024
+ let leftCoords = [tailLeft].concat(bodyCoords.slice(0, coordlength / 2));
2025
+ leftCoords.push(neckLeft);
2026
+ let rightCoords = [tailRight].concat(bodyCoords.slice(coordlength / 2, coordlength));
2027
+ rightCoords.push(neckRight);
2028
+ leftCoords = getQBSplineCoords(leftCoords);
2029
+ rightCoords = getQBSplineCoords(rightCoords);
2030
+ return leftCoords.concat(headCoords, rightCoords.reverse());
2031
+ } else return [];
2032
+ }
2033
+ }
2034
+ /**
2035
+ * 插值头部点
2036
+ */
2037
+ function getArrowHeadCoords(points, options) {
2038
+ const { tailLeft, tailRight, headHeightFactor = .18, headWidthFactor = .3, neckHeightFactor = .85, neckWidthFactor = .15, headTailFactor = .8 } = options;
2039
+ let len = getBaseLength(points);
2040
+ let headHeight = len * headHeightFactor;
2041
+ const headCoord = points.at(-1);
2042
+ len = mathDistance(headCoord, points.at(-2));
2043
+ let tailWidth = 0;
2044
+ if (tailLeft && tailRight) tailWidth = mathDistance(tailLeft, tailRight);
2045
+ if (headHeight > tailWidth * headTailFactor) headHeight = tailWidth * headTailFactor;
2046
+ const headWidth = headHeight * headWidthFactor;
2047
+ const neckWidth = headHeight * neckWidthFactor;
2048
+ headHeight = Math.min(headHeight, len);
2049
+ const neckHeight = headHeight * neckHeightFactor;
2050
+ const headEndCoord = getThirdCoord(points.at(-2), headCoord, 0, headHeight, true);
2051
+ const neckEndCoord = getThirdCoord(points.at(-2), headCoord, 0, neckHeight, true);
2052
+ const headLeft = getThirdCoord(headCoord, headEndCoord, HALF_PI, headWidth, false);
2053
+ const headRight = getThirdCoord(headCoord, headEndCoord, HALF_PI, headWidth, true);
2054
+ const neckLeft = getThirdCoord(headCoord, neckEndCoord, HALF_PI, neckWidth, false);
2055
+ const neckRight = getThirdCoord(headCoord, neckEndCoord, HALF_PI, neckWidth, true);
2056
+ return [
2057
+ neckLeft,
2058
+ headLeft,
2059
+ headCoord,
2060
+ headRight,
2061
+ neckRight
2062
+ ];
2063
+ }
2064
+ /**
2065
+ * 插值面部分数据
2066
+ * @param points
2067
+ * @param neckLeft
2068
+ * @param neckRight
2069
+ * @param tailWidthFactor
2070
+ */
2071
+ function getArrowBodyCoords(points, neckLeft, neckRight, tailWidthFactor) {
2072
+ const allLen = wholeDistance(points);
2073
+ const len = getBaseLength(points);
2074
+ const tailWidth = len * tailWidthFactor;
2075
+ const neckWidth = mathDistance(neckLeft, neckRight);
2076
+ const widthDif = (tailWidth - neckWidth) / 2;
2077
+ let tempLen = 0;
2078
+ const leftBodyCoords = [];
2079
+ const rightBodyCoords = [];
2080
+ for (let i = 1; i < points.length - 1; i++) {
2081
+ const angle = getAngleOfThreeCoords(points[i - 1], points[i], points[i + 1]) / 2;
2082
+ tempLen += mathDistance(points[i - 1], points[i]);
2083
+ const w = (tailWidth / 2 - tempLen / allLen * widthDif) / Math.sin(angle);
2084
+ const left = getThirdCoord(points[i - 1], points[i], Math.PI - angle, w, true);
2085
+ const right = getThirdCoord(points[i - 1], points[i], angle, w, false);
2086
+ leftBodyCoords.push(left);
2087
+ rightBodyCoords.push(right);
2088
+ }
2089
+ return leftBodyCoords.concat(rightBodyCoords);
2090
+ }
2091
+
2092
+ //#endregion
2093
+ //#region geom/arrowAttackDirectionTailed.ts
2094
+ /**
2095
+ * 燕尾尖曲箭头
2096
+ */
2097
+ function arrowAttackDirectionTailed(coords, options = {}) {
2098
+ const { headHeightFactor = .18, headWidthFactor = .3, neckHeightFactor = .85, neckWidthFactor = .15, tailWidthFactor = .1, swallowTailFactor = 1 } = options;
2099
+ const coordLength = coords.length;
2100
+ if (coordLength < 3) throw new Error("coords.length must >= 3");
2101
+ let [tailLeft, tailRight] = [coords[0], coords[1]];
2102
+ if (isClockWise(coords[0], coords[1], coords[2])) {
2103
+ tailLeft = coords[1];
2104
+ tailRight = coords[0];
2105
+ }
2106
+ const midTail = mid(tailLeft, tailRight);
2107
+ const boneCoords = [midTail].concat(coords.slice(2));
2108
+ const headCoords = getArrowHeadCoords(boneCoords, {
2109
+ tailLeft,
2110
+ tailRight,
2111
+ headHeightFactor,
2112
+ headWidthFactor,
2113
+ neckWidthFactor,
2114
+ neckHeightFactor
2115
+ });
2116
+ if (headCoords && headCoords.length > 4) {
2117
+ const [neckLeft, neckRight] = [headCoords[0], headCoords[4]];
2118
+ const tailWidth = mathDistance(tailLeft, tailRight);
2119
+ const allLen = getBaseLength(boneCoords);
2120
+ const len = allLen * tailWidthFactor * swallowTailFactor;
2121
+ const swallowTailCoord = getThirdCoord(boneCoords[1], boneCoords[0], 0, len, true);
2122
+ const factor = tailWidth / allLen;
2123
+ const bodyCoords = getArrowBodyCoords(boneCoords, neckLeft, neckRight, factor);
2124
+ const coordlength = bodyCoords.length;
2125
+ let leftCoords = [tailLeft].concat(bodyCoords.slice(0, coordlength / 2));
2126
+ leftCoords.push(neckLeft);
2127
+ let rightCoords = [tailRight].concat(bodyCoords.slice(coordlength / 2, coordlength));
2128
+ rightCoords.push(neckRight);
2129
+ leftCoords = getQBSplineCoords(leftCoords);
2130
+ rightCoords = getQBSplineCoords(rightCoords);
2131
+ return leftCoords.concat(headCoords, rightCoords.reverse(), [swallowTailCoord, leftCoords[0]]);
2132
+ } else return [];
2133
+ }
2134
+
2135
+ //#endregion
2136
+ //#region geom/arrowClamped.ts
1431
2137
  /**
1432
- * 内置的线段标绘方案
2138
+ * 钳击箭头 有效点位长度3,4,5
1433
2139
  */
1434
- const schemePolyline = new PlotScheme({
1435
- type: "polyline",
2140
+ function arrowClamped(coords) {
2141
+ const options = {
2142
+ headHeightFactor: .25,
2143
+ headWidthFactor: .3,
2144
+ neckHeightFactor: .85,
2145
+ neckWidthFactor: .15
2146
+ };
2147
+ if (coords.length < 3) throw new Error(`coords.length must >= 3`);
2148
+ const [coord1, coord2, coord3] = coords;
2149
+ let tempCoord4, connCoord;
2150
+ if (coords.length === 3) {
2151
+ tempCoord4 = getTempCoord4(coord1, coord2, coord3);
2152
+ connCoord = mid(coord1, coord2);
2153
+ } else if (coords.length === 4) {
2154
+ tempCoord4 = coords[3];
2155
+ connCoord = mid(coord1, coord2);
2156
+ } else {
2157
+ tempCoord4 = coords[3];
2158
+ connCoord = coords[4];
2159
+ }
2160
+ let leftArrowCoords;
2161
+ let rightArrowCoords;
2162
+ if (isClockWise(coord1, coord2, coord3)) {
2163
+ leftArrowCoords = getArrowCoords(coord1, connCoord, tempCoord4, false, options);
2164
+ rightArrowCoords = getArrowCoords(connCoord, coord2, coord3, true, options);
2165
+ } else {
2166
+ leftArrowCoords = getArrowCoords(coord2, connCoord, coord3, false, options);
2167
+ rightArrowCoords = getArrowCoords(connCoord, coord1, tempCoord4, true, options);
2168
+ }
2169
+ const m = leftArrowCoords.length;
2170
+ const t = (m - 5) / 2;
2171
+ const llBodyCoords = leftArrowCoords.slice(0, t);
2172
+ const lArrowCoords = leftArrowCoords.slice(t, t + 5);
2173
+ let lrBodyCoords = leftArrowCoords.slice(t + 5, m);
2174
+ let rlBodyCoords = rightArrowCoords.slice(0, t);
2175
+ const rArrowCoords = rightArrowCoords.slice(t, t + 5);
2176
+ const rrBodyCoords = rightArrowCoords.slice(t + 5, m);
2177
+ rlBodyCoords = getBezierCoords(rlBodyCoords);
2178
+ const bodyCoords = getBezierCoords(rrBodyCoords.concat(llBodyCoords.slice(1)));
2179
+ lrBodyCoords = getBezierCoords(lrBodyCoords);
2180
+ return rlBodyCoords.concat(rArrowCoords, bodyCoords, lArrowCoords, lrBodyCoords);
2181
+ }
2182
+ /**
2183
+ * 插值箭形上的点
2184
+ * @param coord1 - Wgs84坐标
2185
+ * @param coord2 - Wgs84坐标
2186
+ * @param coord3 - Wgs84坐标
2187
+ * @param clockWise - 是否顺时针
2188
+ */
2189
+ function getArrowCoords(coord1, coord2, coord3, clockWise, options) {
2190
+ const midCoord = mid(coord1, coord2);
2191
+ const len = mathDistance(midCoord, coord3);
2192
+ let midCoord1 = getThirdCoord(coord3, midCoord, 0, len * .3, true);
2193
+ let midCoord2 = getThirdCoord(coord3, midCoord, 0, len * .5, true);
2194
+ midCoord1 = getThirdCoord(midCoord, midCoord1, HALF_PI, len / 5, clockWise);
2195
+ midCoord2 = getThirdCoord(midCoord, midCoord2, HALF_PI, len / 4, clockWise);
2196
+ const coords = [
2197
+ midCoord,
2198
+ midCoord1,
2199
+ midCoord2,
2200
+ coord3
2201
+ ];
2202
+ const arrowCoords = getArrowHeadCoords$1(coords, options);
2203
+ if (arrowCoords && Array.isArray(arrowCoords) && arrowCoords.length > 0) {
2204
+ const [neckLeftCoord, neckRightCoord] = [arrowCoords[0], arrowCoords[4]];
2205
+ const tailWidthFactor = mathDistance(coord1, coord2) / getBaseLength(coords) / 2;
2206
+ const bodyCoords = getArrowBodyCoords$1(coords, neckLeftCoord, neckRightCoord, tailWidthFactor);
2207
+ const n = bodyCoords.length;
2208
+ let lCoords = bodyCoords.slice(0, n / 2);
2209
+ let rCoords = bodyCoords.slice(n / 2, n);
2210
+ lCoords.push(neckLeftCoord);
2211
+ rCoords.push(neckRightCoord);
2212
+ lCoords = lCoords.reverse();
2213
+ lCoords.push(coord2);
2214
+ rCoords = rCoords.reverse();
2215
+ rCoords.push(coord1);
2216
+ return lCoords.reverse().concat(arrowCoords, rCoords);
2217
+ } else throw new Error("插值出错");
2218
+ }
2219
+ /**
2220
+ * 插值头部点
2221
+ * @param coords
2222
+ */
2223
+ function getArrowHeadCoords$1(coords, options) {
2224
+ const { headHeightFactor, headWidthFactor, neckWidthFactor, neckHeightFactor } = options;
2225
+ const len = getBaseLength(coords);
2226
+ const headHeight = len * headHeightFactor;
2227
+ const headCoord = coords.at(-1);
2228
+ const headWidth = headHeight * headWidthFactor;
2229
+ const neckWidth = headHeight * neckWidthFactor;
2230
+ const neckHeight = headHeight * neckHeightFactor;
2231
+ const headEndCoord = getThirdCoord(coords.at(-2), headCoord, 0, headHeight, true);
2232
+ const neckEndCoord = getThirdCoord(coords.at(-2), headCoord, 0, neckHeight, true);
2233
+ const headLeft = getThirdCoord(headCoord, headEndCoord, HALF_PI, headWidth, false);
2234
+ const headRight = getThirdCoord(headCoord, headEndCoord, HALF_PI, headWidth, true);
2235
+ const neckLeft = getThirdCoord(headCoord, neckEndCoord, HALF_PI, neckWidth, false);
2236
+ const neckRight = getThirdCoord(headCoord, neckEndCoord, HALF_PI, neckWidth, true);
2237
+ return [
2238
+ neckLeft,
2239
+ headLeft,
2240
+ headCoord,
2241
+ headRight,
2242
+ neckRight
2243
+ ];
2244
+ }
2245
+ /**
2246
+ * 插值面部分数据
2247
+ * @param coords
2248
+ * @param neckLeft
2249
+ * @param neckRight
2250
+ * @param tailWidthFactor
2251
+ */
2252
+ function getArrowBodyCoords$1(coords, neckLeft, neckRight, tailWidthFactor) {
2253
+ const allLen = wholeDistance(coords);
2254
+ const len = getBaseLength(coords);
2255
+ const tailWidth = len * tailWidthFactor;
2256
+ const neckWidth = mathDistance(neckLeft, neckRight);
2257
+ const widthDif = (tailWidth - neckWidth) / 2;
2258
+ let tempLen = 0;
2259
+ const leftBodyCoords = [];
2260
+ const rightBodyCoords = [];
2261
+ for (let i = 1; i < coords.length - 1; i++) {
2262
+ const angle = getAngleOfThreeCoords(coords[i - 1], coords[i], coords[i + 1]) / 2;
2263
+ tempLen += mathDistance(coords[i - 1], coords[i]);
2264
+ const w = (tailWidth / 2 - tempLen / allLen * widthDif) / Math.sin(angle);
2265
+ const left = getThirdCoord(coords[i - 1], coords[i], Math.PI - angle, w, true);
2266
+ const right = getThirdCoord(coords[i - 1], coords[i], angle, w, false);
2267
+ leftBodyCoords.push(left);
2268
+ rightBodyCoords.push(right);
2269
+ }
2270
+ return leftBodyCoords.concat(rightBodyCoords);
2271
+ }
2272
+ /**
2273
+ * 获取对称点
2274
+ * @param lineCoord1
2275
+ * @param lineCoord2
2276
+ * @param coord
2277
+ */
2278
+ function getTempCoord4(lineCoord1, lineCoord2, coord) {
2279
+ const midCoord = mid(lineCoord1, lineCoord2);
2280
+ const len = mathDistance(midCoord, coord);
2281
+ const angle = getAngleOfThreeCoords(lineCoord1, midCoord, coord);
2282
+ if (angle < HALF_PI) {
2283
+ const distance1 = len * Math.sin(angle);
2284
+ const distance2 = len * Math.cos(angle);
2285
+ const mid$1 = getThirdCoord(lineCoord1, midCoord, HALF_PI, distance1, false);
2286
+ return getThirdCoord(midCoord, mid$1, HALF_PI, distance2, true);
2287
+ } else if (angle >= HALF_PI && angle < Math.PI) {
2288
+ const distance1 = len * Math.sin(Math.PI - angle);
2289
+ const distance2 = len * Math.cos(Math.PI - angle);
2290
+ const mid$1 = getThirdCoord(lineCoord1, midCoord, HALF_PI, distance1, false);
2291
+ return getThirdCoord(midCoord, mid$1, HALF_PI, distance2, false);
2292
+ } else if (angle >= Math.PI && angle < Math.PI * 1.5) {
2293
+ const distance1 = len * Math.sin(angle - Math.PI);
2294
+ const distance2 = len * Math.cos(angle - Math.PI);
2295
+ const mid$1 = getThirdCoord(lineCoord1, midCoord, HALF_PI, distance1, true);
2296
+ return getThirdCoord(midCoord, mid$1, HALF_PI, distance2, true);
2297
+ } else {
2298
+ const distance1 = len * Math.sin(Math.PI * 2 - angle);
2299
+ const distance2 = len * Math.cos(Math.PI * 2 - angle);
2300
+ const mid$1 = getThirdCoord(lineCoord1, midCoord, HALF_PI, distance1, true);
2301
+ return getThirdCoord(midCoord, mid$1, HALF_PI, distance2, false);
2302
+ }
2303
+ }
2304
+
2305
+ //#endregion
2306
+ //#region geom/arrowStraightSharp.ts
2307
+ /**
2308
+ * 尖箭头
2309
+ *
2310
+ */
2311
+ function arrowStraightSharp(coords, options = {}) {
2312
+ const { tailWidthFactor = .1, neckWidthFactor = .2, headWidthFactor = .25, headAngle = Math.PI / 8.5, neckAngle = Math.PI / 13 } = options;
2313
+ const coordlength = coords.length;
2314
+ if (coordlength < 2) throw new Error("coords.length must >= 2");
2315
+ const [coord1, coord2] = [coords[0], coords[1]];
2316
+ const len = getBaseLength(coords);
2317
+ const tailWidth = len * tailWidthFactor;
2318
+ const neckWidth = len * neckWidthFactor;
2319
+ const headWidth = len * headWidthFactor;
2320
+ const tailLeft = getThirdCoord(coord2, coord1, HALF_PI, tailWidth, true);
2321
+ const tailRight = getThirdCoord(coord2, coord1, HALF_PI, tailWidth, false);
2322
+ const headLeft = getThirdCoord(coord1, coord2, headAngle, headWidth, false);
2323
+ const headRight = getThirdCoord(coord1, coord2, headAngle, headWidth, true);
2324
+ const neckLeft = getThirdCoord(coord1, coord2, neckAngle, neckWidth, false);
2325
+ const neckRight = getThirdCoord(coord1, coord2, neckAngle, neckWidth, true);
2326
+ const pList = [
2327
+ tailLeft,
2328
+ neckLeft,
2329
+ headLeft,
2330
+ coord2,
2331
+ headRight,
2332
+ neckRight,
2333
+ tailRight
2334
+ ];
2335
+ return pList;
2336
+ }
2337
+
2338
+ //#endregion
2339
+ //#region geom/arrowStraight.ts
2340
+ /**
2341
+ * 直箭头
2342
+ */
2343
+ function arrowStraight(coords) {
2344
+ const tailWidthFactor = .05;
2345
+ const neckWidthFactor = .1;
2346
+ const headWidthFactor = .15;
2347
+ const headAngle = Math.PI / 4;
2348
+ const neckAngle = Math.PI * .17741;
2349
+ return arrowStraightSharp(coords, {
2350
+ tailWidthFactor,
2351
+ neckWidthFactor,
2352
+ headWidthFactor,
2353
+ headAngle,
2354
+ neckAngle
2355
+ });
2356
+ }
2357
+
2358
+ //#endregion
2359
+ //#region geom/arrowUnitCombatOperation.ts
2360
+ /**
2361
+ * 分队战斗行动(尖曲箭头)
2362
+ */
2363
+ function arrowUnitCombatOperation(coords, options = {}) {
2364
+ const { headHeightFactor = .18, headWidthFactor = .3, neckHeightFactor = .85, neckWidthFactor = .15, tailWidthFactor = .1 } = options;
2365
+ const coordlength = coords.length;
2366
+ if (coordlength < 2) throw new Error("coords.length must >= 2");
2367
+ else {
2368
+ const allLen = getBaseLength(coords);
2369
+ const tailWidth = allLen * tailWidthFactor;
2370
+ const tailLeft = getThirdCoord(coords[1], coords[0], HALF_PI, tailWidth, false);
2371
+ const tailRight = getThirdCoord(coords[1], coords[0], HALF_PI, tailWidth, true);
2372
+ const headCoords = getArrowHeadCoords(coords, {
2373
+ tailLeft,
2374
+ tailRight,
2375
+ headHeightFactor,
2376
+ headWidthFactor,
2377
+ neckWidthFactor,
2378
+ neckHeightFactor
2379
+ });
2380
+ if (headCoords && headCoords.length > 4) {
2381
+ const neckLeft = headCoords[0];
2382
+ const neckRight = headCoords[4];
2383
+ const bodyCoords = getArrowBodyCoords(coords, neckLeft, neckRight, tailWidthFactor);
2384
+ const coordlength$1 = bodyCoords.length;
2385
+ let leftCoords = [tailLeft].concat(bodyCoords.slice(0, coordlength$1 / 2));
2386
+ leftCoords.push(neckLeft);
2387
+ let rightCoords = [tailRight].concat(bodyCoords.slice(coordlength$1 / 2, coordlength$1));
2388
+ rightCoords.push(neckRight);
2389
+ leftCoords = getQBSplineCoords(leftCoords);
2390
+ rightCoords = getQBSplineCoords(rightCoords);
2391
+ return leftCoords.concat(headCoords, rightCoords.reverse());
2392
+ } else return [];
2393
+ }
2394
+ }
2395
+
2396
+ //#endregion
2397
+ //#region geom/arrowUnitCombatOperationTailed.ts
2398
+ /**
2399
+ * 燕尾尖箭头
2400
+ */
2401
+ function arrowUnitCombatOperationTailed(coords, options = {}) {
2402
+ const { headHeightFactor = .18, headWidthFactor = .3, neckHeightFactor = .85, neckWidthFactor = .15, tailWidthFactor = .1, swallowTailFactor = 1 } = options;
2403
+ const coordlength = coords.length;
2404
+ if (coordlength < 2) throw new Error("coords.length must >= 2");
2405
+ const allLen = getBaseLength(coords);
2406
+ const tailWidth = allLen * tailWidthFactor;
2407
+ const tailLeft = getThirdCoord(coords[1], coords[0], HALF_PI, tailWidth, false);
2408
+ const tailRight = getThirdCoord(coords[1], coords[0], HALF_PI, tailWidth, true);
2409
+ const len = tailWidth * swallowTailFactor;
2410
+ const swallowTailCoord = getThirdCoord(coords[1], coords[0], 0, len, true);
2411
+ const tailCoords = [
2412
+ tailLeft,
2413
+ swallowTailCoord,
2414
+ tailRight
2415
+ ];
2416
+ const headCoords = getArrowHeadCoords(coords, {
2417
+ tailLeft: tailCoords[0],
2418
+ tailRight: tailCoords[2],
2419
+ headHeightFactor,
2420
+ headWidthFactor,
2421
+ neckWidthFactor,
2422
+ neckHeightFactor
2423
+ });
2424
+ if (headCoords && headCoords.length > 4) {
2425
+ const neckLeft = headCoords[0];
2426
+ const neckRight = headCoords[4];
2427
+ const bodyCoords = getArrowBodyCoords(coords, neckLeft, neckRight, tailWidthFactor);
2428
+ const coordlength$1 = bodyCoords.length;
2429
+ let leftCoords = [tailCoords[0]].concat(bodyCoords.slice(0, coordlength$1 / 2));
2430
+ leftCoords.push(neckLeft);
2431
+ let rightCoords = [tailCoords[2]].concat(bodyCoords.slice(coordlength$1 / 2, coordlength$1));
2432
+ rightCoords.push(neckRight);
2433
+ leftCoords = getQBSplineCoords(leftCoords);
2434
+ rightCoords = getQBSplineCoords(rightCoords);
2435
+ return leftCoords.concat(headCoords, rightCoords.reverse(), [tailCoords[1], leftCoords[0]]);
2436
+ }
2437
+ return [];
2438
+ }
2439
+
2440
+ //#endregion
2441
+ //#region geom/assemblingPlace.ts
2442
+ /**
2443
+ * 集结地
2444
+ *
2445
+ */
2446
+ function assemblingPlace(coords) {
2447
+ if (coords.length < 3) throw new Error(`coords.length must >= 3`);
2448
+ const t = .4;
2449
+ const midCoord = mid(coords[0], coords[2]);
2450
+ coords.push(midCoord, coords[0], coords[1]);
2451
+ let normals = [];
2452
+ const pList = [];
2453
+ for (let i = 0; i < coords.length - 2; i++) {
2454
+ const coord1 = coords[i];
2455
+ const coord2 = coords[i + 1];
2456
+ const coord3 = coords[i + 2];
2457
+ const normalCoords = getBisectorNormals(t, coord1, coord2, coord3);
2458
+ normals = normals.concat(normalCoords);
2459
+ }
2460
+ const count = normals.length;
2461
+ normals = [normals[count - 1]].concat(normals.slice(0, count - 1));
2462
+ for (let i = 0; i < coords.length - 2; i++) {
2463
+ const coord1 = coords[i];
2464
+ const coord2 = coords[i + 1];
2465
+ pList.push(coord1);
2466
+ for (let t$1 = 0; t$1 <= FITTING_COUNT; t$1++) {
2467
+ const coord = getCubicValue(t$1 / FITTING_COUNT, coord1, normals[i * 2], normals[i * 2 + 1], coord2);
2468
+ pList.push(coord);
2469
+ }
2470
+ pList.push(coord2);
2471
+ }
2472
+ return pList;
2473
+ }
2474
+
2475
+ //#endregion
2476
+ //#region geom/flagCurve.ts
2477
+ /**
2478
+ * 曲线旗标
2479
+ */
2480
+ function flagCurve(coords) {
2481
+ const coordlength = coords.length;
2482
+ if (coordlength < 2) throw new Error("coords.length must >= 2");
2483
+ return calculatePonits(coords);
2484
+ }
2485
+ /**
2486
+ * 插值点数据
2487
+ * @param coords
2488
+ */
2489
+ function calculatePonits(coords) {
2490
+ let components = [];
2491
+ if (coords.length > 1) {
2492
+ const startCoord = coords[0];
2493
+ const endCoord = coords.at(-1);
2494
+ const coord1 = startCoord;
2495
+ const coord2 = [(endCoord[0] - startCoord[0]) / 4 + startCoord[0], (endCoord[1] - startCoord[1]) / 8 + startCoord[1]];
2496
+ const coord3 = [(startCoord[0] + endCoord[0]) / 2, startCoord[1]];
2497
+ const coord4 = [(endCoord[0] - startCoord[0]) * 3 / 4 + startCoord[0], -(endCoord[1] - startCoord[1]) / 8 + startCoord[1]];
2498
+ const coord5 = [endCoord[0], startCoord[1]];
2499
+ const coord6 = [endCoord[0], (startCoord[1] + endCoord[1]) / 2];
2500
+ const coord7 = [(endCoord[0] - startCoord[0]) * 3 / 4 + startCoord[0], (endCoord[1] - startCoord[1]) * 3 / 8 + startCoord[1]];
2501
+ const coord8 = [(startCoord[0] + endCoord[0]) / 2, (startCoord[1] + endCoord[1]) / 2];
2502
+ const coord9 = [(endCoord[0] - startCoord[0]) / 4 + startCoord[0], (endCoord[1] - startCoord[1]) * 5 / 8 + startCoord[1]];
2503
+ const coord10 = [startCoord[0], (startCoord[1] + endCoord[1]) / 2];
2504
+ const coord11 = [startCoord[0], endCoord[1]];
2505
+ const curve1 = getBezierCoords([
2506
+ coord1,
2507
+ coord2,
2508
+ coord3,
2509
+ coord4,
2510
+ coord5
2511
+ ]);
2512
+ const curve2 = getBezierCoords([
2513
+ coord6,
2514
+ coord7,
2515
+ coord8,
2516
+ coord9,
2517
+ coord10
2518
+ ]);
2519
+ components = curve1.concat(curve2);
2520
+ components.push(coord11);
2521
+ }
2522
+ return components;
2523
+ }
2524
+
2525
+ //#endregion
2526
+ //#region geom/flagRect.ts
2527
+ /**
2528
+ * 直角旗标(使用两个控制点直接创建直角旗标)
2529
+ */
2530
+ function flagRect(coords) {
2531
+ if (coords.length < 2) throw new Error("coords.length must >= 2");
2532
+ const [startCoord, endCoord] = coords;
2533
+ const coord1 = [endCoord[0], startCoord[1]];
2534
+ const coord2 = [endCoord[0], (startCoord[1] + endCoord[1]) / 2];
2535
+ const coord3 = [startCoord[0], (startCoord[1] + endCoord[1]) / 2];
2536
+ const coord4 = [startCoord[0], endCoord[1]];
2537
+ return [
2538
+ startCoord,
2539
+ coord1,
2540
+ coord2,
2541
+ coord3,
2542
+ coord4
2543
+ ];
2544
+ }
2545
+
2546
+ //#endregion
2547
+ //#region geom/flagTriangle.ts
2548
+ /**
2549
+ * 三角旗标(使用两个控制点直接创建三角旗标)
2550
+ */
2551
+ function flagTriangle(coords) {
2552
+ const coordlength = coords.length;
2553
+ if (coordlength < 2) throw new Error("coords.length must >= 2");
2554
+ const [startCoord, endCoord] = coords;
2555
+ const coord1 = [endCoord[0], (startCoord[1] + endCoord[1]) / 2];
2556
+ const coord2 = [startCoord[0], (startCoord[1] + endCoord[1]) / 2];
2557
+ const coord3 = [startCoord[0], endCoord[1]];
2558
+ return [
2559
+ startCoord,
2560
+ coord1,
2561
+ coord2,
2562
+ coord3
2563
+ ];
2564
+ }
2565
+
2566
+ //#endregion
2567
+ //#region scheme/PolygonArc.ts
2568
+ const PlotSchemePolygonArc = new PlotScheme({
2569
+ type: "PolygonArc",
2570
+ complete: (packable) => packable.positions.length >= 3,
2571
+ skeletons: [moved, control],
2572
+ initRender() {
2573
+ return { entities: [new Entity({ polygon: {} })] };
2574
+ },
2575
+ render(context) {
2576
+ const entity = context.previous.entities[0];
2577
+ const points = context.packable.positions;
2578
+ if (points.length < 3) context.mouse && points.push(context.mouse.clone());
2579
+ const coords = points.map((e) => toCoord(e));
2580
+ if (coords.length < 3) {
2581
+ entity.polygon.hierarchy = void 0;
2582
+ return context.previous;
2583
+ }
2584
+ const positions = arc(coords).map((item) => toCartesian3(item));
2585
+ const hierarchy = new PolygonHierarchy(positions);
2586
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
2587
+ return { entities: [entity] };
2588
+ }
2589
+ });
2590
+
2591
+ //#endregion
2592
+ //#region scheme/PolygonArrowAttackDirection.ts
2593
+ const PlotSchemePolygonArrowAttackDirection = new PlotScheme({
2594
+ type: "PolygonArrowAttackDirection",
2595
+ allowManualComplete: (packable) => packable.positions.length >= 3,
2596
+ skeletons: [
2597
+ moved,
2598
+ control,
2599
+ intervalNonclosed
2600
+ ],
2601
+ initRender() {
2602
+ return { entities: [new Entity({ polygon: {} })] };
2603
+ },
2604
+ render(context) {
2605
+ const entity = context.previous.entities[0];
2606
+ const points = context.packable.positions;
2607
+ context.mouse && points.push(context.mouse.clone());
2608
+ const coords = points.map((e) => toCoord(e));
2609
+ if (coords.length < 3) {
2610
+ entity.polygon.hierarchy = void 0;
2611
+ return context.previous;
2612
+ }
2613
+ const positions = arrowAttackDirection(coords).map((item) => toCartesian3(item));
2614
+ const hierarchy = new PolygonHierarchy(positions);
2615
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
2616
+ return { entities: [entity] };
2617
+ }
2618
+ });
2619
+
2620
+ //#endregion
2621
+ //#region scheme/PolygonArrowAttackDirectionTailed.ts
2622
+ const PlotSchemePolygonArrowAttackDirectionTailed = new PlotScheme({
2623
+ type: "PolygonArrowAttackDirectionTailed",
2624
+ allowManualComplete: (packable) => packable.positions.length >= 3,
2625
+ skeletons: [
2626
+ moved,
2627
+ control,
2628
+ intervalNonclosed
2629
+ ],
2630
+ initRender() {
2631
+ return { entities: [new Entity({ polygon: {} })] };
2632
+ },
2633
+ render(context) {
2634
+ const entity = context.previous.entities[0];
2635
+ const points = context.packable.positions;
2636
+ context.mouse && points.push(context.mouse.clone());
2637
+ const coords = points.map((e) => toCoord(e));
2638
+ if (coords.length < 3) {
2639
+ entity.polygon.hierarchy = void 0;
2640
+ return context.previous;
2641
+ }
2642
+ const positions = arrowAttackDirectionTailed(coords).map((item) => toCartesian3(item));
2643
+ const hierarchy = new PolygonHierarchy(positions);
2644
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
2645
+ return { entities: [entity] };
2646
+ }
2647
+ });
2648
+
2649
+ //#endregion
2650
+ //#region scheme/PolygonArrowClamped.ts
2651
+ const PlotSchemePolygonArrowClamped = new PlotScheme({
2652
+ type: "PolygonArrowClamped",
2653
+ complete: (packable) => packable.positions.length >= 5,
2654
+ skeletons: [moved, control],
2655
+ initRender() {
2656
+ return { entities: [new Entity({ polygon: {} })] };
2657
+ },
2658
+ render(context) {
2659
+ const entity = context.previous.entities[0];
2660
+ const points = context.packable.positions;
2661
+ if (points.length < 5) {
2662
+ const mouse = context.mouse;
2663
+ mouse && points.push(mouse.clone());
2664
+ }
2665
+ const coords = points.map((e) => toCoord(e));
2666
+ if (coords.length >= 3) {
2667
+ const positions = arrowClamped(coords);
2668
+ const hierarchy = new PolygonHierarchy(positions.map((item) => toCartesian3(item)));
2669
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
2670
+ } else entity.polygon.hierarchy = void 0;
2671
+ return { entities: [entity] };
2672
+ }
2673
+ });
2674
+
2675
+ //#endregion
2676
+ //#region scheme/PolygonArrowStraight.ts
2677
+ const PlotSchemePolygonArrowStraight = new PlotScheme({
2678
+ type: "PolygonArrowStraight",
2679
+ complete: (packable) => packable.positions.length >= 2,
2680
+ skeletons: [moved, control],
2681
+ initRender() {
2682
+ return { entities: [new Entity({ polygon: {} })] };
2683
+ },
2684
+ render(context) {
2685
+ const entity = context.previous.entities[0];
2686
+ const points = context.packable.positions;
2687
+ if (points.length < 2) {
2688
+ const mouse = context.mouse;
2689
+ mouse && points.push(mouse.clone());
2690
+ }
2691
+ const coords = points.map((e) => toCoord(e));
2692
+ if (coords.length >= 2) {
2693
+ const positions = arrowStraight(coords);
2694
+ const hierarchy = new PolygonHierarchy(positions.map((item) => toCartesian3(item)));
2695
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
2696
+ } else entity.polygon.hierarchy = void 0;
2697
+ return { entities: [entity] };
2698
+ }
2699
+ });
2700
+
2701
+ //#endregion
2702
+ //#region scheme/PolygonArrowStraightSharp.ts
2703
+ const PlotSchemePolygonArrowStraightSharp = new PlotScheme({
2704
+ type: "PolygonArrowStraightSharp",
2705
+ complete: (packable) => packable.positions.length >= 2,
2706
+ skeletons: [moved, control],
2707
+ initRender() {
2708
+ return { entities: [new Entity({ polygon: {} })] };
2709
+ },
2710
+ render(context) {
2711
+ const entity = context.previous.entities[0];
2712
+ const points = context.packable.positions;
2713
+ if (points.length < 2) {
2714
+ const mouse = context.mouse;
2715
+ mouse && points.push(mouse.clone());
2716
+ }
2717
+ const coords = points.map((e) => toCoord(e));
2718
+ if (coords.length >= 2) {
2719
+ const positions = arrowStraightSharp(coords);
2720
+ const hierarchy = new PolygonHierarchy(positions.map((item) => toCartesian3(item)));
2721
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
2722
+ } else entity.polygon.hierarchy = void 0;
2723
+ return { entities: [entity] };
2724
+ }
2725
+ });
2726
+
2727
+ //#endregion
2728
+ //#region scheme/PolygonArrowUnitCombatOperation.ts
2729
+ const PlotSchemePolygonArrowUnitCombatOperation = new PlotScheme({
2730
+ type: "PolygonArrowUnitCombatOperation",
1436
2731
  allowManualComplete: (packable) => packable.positions.length >= 2,
1437
2732
  skeletons: [
2733
+ moved,
1438
2734
  control,
1439
- intervalNonclosed,
1440
- moved
2735
+ intervalNonclosed
1441
2736
  ],
1442
- initEntites: () => [new Entity({ polyline: { width: 1 } })],
1443
- render(options) {
1444
- const { mouse, packable } = options;
1445
- const entity = options.previous.entities?.[0] ?? new Entity({ polyline: {} });
1446
- entity.polyline.positions = new CallbackProperty(() => {
1447
- const positions = [...packable.positions ?? []].concat(mouse ? [mouse] : []);
1448
- return positions.length >= 2 ? positions : [];
1449
- }, false);
2737
+ initRender() {
2738
+ return { entities: [new Entity({ polygon: {} })] };
2739
+ },
2740
+ render(context) {
2741
+ const entity = context.previous.entities[0];
2742
+ const points = context.packable.positions;
2743
+ context.mouse && points.push(context.mouse.clone());
2744
+ const coords = points.map((e) => toCoord(e));
2745
+ if (coords.length < 2) {
2746
+ entity.polygon.hierarchy = void 0;
2747
+ return context.previous;
2748
+ }
2749
+ const positions = arrowUnitCombatOperation(coords).map((item) => toCartesian3(item));
2750
+ const hierarchy = new PolygonHierarchy(positions);
2751
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
1450
2752
  return { entities: [entity] };
1451
2753
  }
1452
2754
  });
1453
2755
 
1454
2756
  //#endregion
1455
- //#region scheme/rectangle.ts
1456
- /**
1457
- * 内置的多边形标绘方案
1458
- */
1459
- const schemeRectangle = new PlotScheme({
1460
- type: "rectangle",
2757
+ //#region scheme/PolygonArrowUnitCombatOperationTailed.ts
2758
+ const PlotSchemePolygonArrowUnitCombatOperationTailed = new PlotScheme({
2759
+ type: "PolygonArrowUnitCombatOperationTailed",
2760
+ allowManualComplete: (packable) => packable.positions.length >= 2,
2761
+ skeletons: [
2762
+ moved,
2763
+ control,
2764
+ interval
2765
+ ],
2766
+ initRender() {
2767
+ return { entities: [new Entity({ polygon: {} })] };
2768
+ },
2769
+ render(context) {
2770
+ const entity = context.previous.entities[0];
2771
+ const points = context.packable.positions;
2772
+ context.mouse && points.push(context.mouse.clone());
2773
+ const coords = points.map((e) => toCoord(e));
2774
+ if (coords.length < 2) {
2775
+ entity.polygon.hierarchy = void 0;
2776
+ return context.previous;
2777
+ }
2778
+ const positions = arrowUnitCombatOperationTailed(coords).map((item) => toCartesian3(item));
2779
+ const hierarchy = new PolygonHierarchy(positions);
2780
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
2781
+ return { entities: [entity] };
2782
+ }
2783
+ });
2784
+
2785
+ //#endregion
2786
+ //#region scheme/PolygonAssemblingPlace.ts
2787
+ const PlotSchemePolygonAssemblingPlace = new PlotScheme({
2788
+ type: "PolygonAssemblingPlace",
2789
+ complete: (packable) => packable.positions.length >= 3,
2790
+ skeletons: [
2791
+ moved,
2792
+ control,
2793
+ interval
2794
+ ],
2795
+ initRender() {
2796
+ return { entities: [new Entity({ polygon: {} })] };
2797
+ },
2798
+ render(context) {
2799
+ const entity = context.previous.entities[0];
2800
+ const points = context.packable.positions;
2801
+ context.mouse && points.push(context.mouse.clone());
2802
+ const coords = points.map((e) => toCoord(e));
2803
+ if (coords.length < 2) {
2804
+ entity.polygon.hierarchy = void 0;
2805
+ return context.previous;
2806
+ }
2807
+ const positions = assemblingPlace(coords).map((item) => toCartesian3(item));
2808
+ const hierarchy = new PolygonHierarchy(positions);
2809
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
2810
+ return { entities: [entity] };
2811
+ }
2812
+ });
2813
+
2814
+ //#endregion
2815
+ //#region scheme/PolygonFlagCurve.ts
2816
+ const PlotSchemePolygonFlagCurve = new PlotScheme({
2817
+ type: "PolygonFlagCurve",
1461
2818
  complete: (packable) => packable.positions.length >= 2,
2819
+ skeletons: [moved, control],
2820
+ initRender() {
2821
+ return { entities: [new Entity({ polygon: {} })] };
2822
+ },
2823
+ render(context) {
2824
+ const entity = context.previous.entities[0];
2825
+ const points = context.packable.positions;
2826
+ context.mouse && points.push(context.mouse.clone());
2827
+ const coords = points.map((e) => toCoord(e));
2828
+ if (coords.length < 2) {
2829
+ entity.polygon.hierarchy = void 0;
2830
+ return context.previous;
2831
+ }
2832
+ const positions = flagCurve(coords).map((item) => toCartesian3(item));
2833
+ const hierarchy = new PolygonHierarchy(positions);
2834
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
2835
+ return { entities: [entity] };
2836
+ }
2837
+ });
2838
+
2839
+ //#endregion
2840
+ //#region scheme/PolygonFlagRect.ts
2841
+ const PlotSchemePolygonFlagRect = new PlotScheme({
2842
+ type: "PolygonFlagRect",
2843
+ complete: (packable) => packable.positions.length >= 2,
2844
+ skeletons: [moved, control],
2845
+ initRender() {
2846
+ return { entities: [new Entity({ polygon: {} })] };
2847
+ },
2848
+ render(context) {
2849
+ const entity = context.previous.entities[0];
2850
+ const points = context.packable.positions;
2851
+ context.mouse && points.push(context.mouse.clone());
2852
+ const coords = points.map((e) => toCoord(e));
2853
+ if (coords.length < 2) {
2854
+ entity.polygon.hierarchy = void 0;
2855
+ return context.previous;
2856
+ }
2857
+ const positions = flagRect(coords).map((item) => toCartesian3(item));
2858
+ const hierarchy = new PolygonHierarchy(positions);
2859
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
2860
+ return { entities: [entity] };
2861
+ }
2862
+ });
2863
+
2864
+ //#endregion
2865
+ //#region scheme/PolygonFlagTriangle.ts
2866
+ const PlotSchemePolygonFlagTriangle = new PlotScheme({
2867
+ type: "PolygonFlagTriangle",
2868
+ complete: (packable) => packable.positions.length >= 2,
2869
+ skeletons: [moved, control],
2870
+ initRender() {
2871
+ return { entities: [new Entity({ polygon: {} })] };
2872
+ },
2873
+ render(context) {
2874
+ const entity = context.previous.entities[0];
2875
+ const points = context.packable.positions;
2876
+ context.mouse && points.push(context.mouse.clone());
2877
+ const coords = points.map((e) => toCoord(e));
2878
+ if (coords.length < 2) {
2879
+ entity.polygon.hierarchy = void 0;
2880
+ return context.previous;
2881
+ }
2882
+ const positions = flagTriangle(coords).map((item) => toCartesian3(item));
2883
+ const hierarchy = new PolygonHierarchy(positions);
2884
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
2885
+ return { entities: [entity] };
2886
+ }
2887
+ });
2888
+
2889
+ //#endregion
2890
+ //#region scheme/PolygonSmooth.ts
2891
+ const PlotSchemePolygonSmooth = new PlotScheme({
2892
+ type: "PolygonSmooth",
2893
+ allowManualComplete: (packable) => packable.positions.length >= 3,
1462
2894
  skeletons: [
2895
+ moved,
1463
2896
  control,
1464
- interval,
1465
- moved
2897
+ intervalNonclosed
1466
2898
  ],
1467
- initEntites: () => [new Entity({ rectangle: { material: Color.YELLOW.withAlpha(.5) } })],
1468
- render(options) {
1469
- const { mouse, packable } = options;
1470
- const entity = options.previous.entities?.[0] ?? new Entity({ rectangle: { material: Color.YELLOW.withAlpha(.5) } });
1471
- const positions = [...packable.positions ?? []];
1472
- mouse && positions.push(mouse);
1473
- if (positions.length >= 2) entity.rectangle.coordinates = new CallbackProperty(() => Rectangle.fromCartesianArray(positions), false);
1474
- else entity.rectangle.coordinates = void 0;
2899
+ initRender() {
2900
+ return { entities: [new Entity({ polygon: {} })] };
2901
+ },
2902
+ render(context) {
2903
+ const entity = context.previous.entities[0];
2904
+ const positions = context.packable.positions;
2905
+ const mousePosition = context.mouse;
2906
+ mousePosition && positions.push(mousePosition.clone());
2907
+ if (positions.length <= 2) {
2908
+ entity.polygon.hierarchy = void 0;
2909
+ return context.previous;
2910
+ }
2911
+ const wgs84s = positions.map((e) => toCoord(e));
2912
+ wgs84s.push(wgs84s[0]);
2913
+ const { features } = turf$1.polygonSmooth(turf$1.polygon([wgs84s]), { iterations: 3 });
2914
+ const cartesians = features[0].geometry.coordinates[0].map((item) => toCartesian3(item)).filter((e) => !!e);
2915
+ const hierarchy = new PolygonHierarchy(cartesians);
2916
+ entity.polygon.hierarchy = new CallbackProperty(() => hierarchy, false);
2917
+ return { entities: [entity] };
2918
+ }
2919
+ });
2920
+
2921
+ //#endregion
2922
+ //#region scheme/Polyline.ts
2923
+ const PlotSchemePolyline = new PlotScheme({
2924
+ type: "Polyline",
2925
+ allowManualComplete: (packable) => packable.positions.length > 1,
2926
+ skeletons: [
2927
+ moved,
2928
+ control,
2929
+ intervalNonclosed
2930
+ ],
2931
+ initRender() {
2932
+ return { entities: [new Entity({ polyline: {
2933
+ material: Color.RED,
2934
+ width: 2
2935
+ } })] };
2936
+ },
2937
+ render(context) {
2938
+ const entity = context.previous.entities[0];
2939
+ const positions = [...context.packable.positions];
2940
+ const mouse = context.mouse;
2941
+ mouse && positions.push(mouse.clone());
2942
+ const cache = positions.length >= 2 ? positions : [];
2943
+ entity.polyline.positions = new CallbackProperty(() => cache, false);
2944
+ return { entities: [entity] };
2945
+ }
2946
+ });
2947
+
2948
+ //#endregion
2949
+ //#region scheme/PolylineCurve.ts
2950
+ const PlotSchemePolylineCurve = new PlotScheme({
2951
+ type: "PolylineCurve",
2952
+ allowManualComplete: (packable) => packable.positions.length > 1,
2953
+ skeletons: [
2954
+ moved,
2955
+ control,
2956
+ intervalNonclosed
2957
+ ],
2958
+ initRender() {
2959
+ return { entities: [new Entity({ polyline: {
2960
+ material: Color.RED,
2961
+ width: 2
2962
+ } })] };
2963
+ },
2964
+ render(context) {
2965
+ const entity = context.previous.entities[0];
2966
+ const positions = [...context.packable.positions];
2967
+ const mouse = context.mouse;
2968
+ mouse && positions.push(mouse.clone());
2969
+ if (positions.length < 2) {
2970
+ entity.polyline.positions = void 0;
2971
+ return context.previous;
2972
+ }
2973
+ const coords = positions.map((position) => toCoord(position));
2974
+ const { geometry: { coordinates } } = turf.bezierSpline(turf.lineString(coords));
2975
+ entity.polyline.positions = new CallbackProperty(() => coordinates.map(toCartesian3), false);
2976
+ return { entities: [entity] };
2977
+ }
2978
+ });
2979
+
2980
+ //#endregion
2981
+ //#region scheme/Rectangle.ts
2982
+ const PlotSchemeRectangle = new PlotScheme({
2983
+ type: "Rectangle",
2984
+ complete: (packable) => packable.positions.length >= 2,
2985
+ skeletons: [moved, control],
2986
+ initRender() {
2987
+ return { entities: [new Entity({ rectangle: {} })] };
2988
+ },
2989
+ render(context) {
2990
+ const entity = context.previous.entities[0];
2991
+ const positions = [...context.packable.positions];
2992
+ const mouse = context.mouse;
2993
+ mouse && positions.push(mouse.clone());
2994
+ if (positions.length < 2) {
2995
+ entity.rectangle.coordinates = void 0;
2996
+ return context.previous;
2997
+ }
2998
+ const coordinates = Rectangle.fromCartesianArray(positions ?? []);
2999
+ entity.rectangle.coordinates = new CallbackProperty(() => coordinates, false);
1475
3000
  return { entities: [entity] };
1476
3001
  }
1477
3002
  });
1478
3003
 
1479
3004
  //#endregion
1480
- export { PlotAction, PlotFeature, PlotScheme, PlotSkeletonEntity, SampledPlotProperty, SampledPlotStrategy, control, interval, intervalNonclosed, moved, schemeBillboard, schemeLabel, schemeMeasureArea, schemePolygon, schemePolyline, schemeRectangle, usePlot };
3005
+ export { PlotAction, PlotFeature, PlotScheme, PlotSchemeBillboard, PlotSchemeBillboardPinBuilder, PlotSchemeCylinder, PlotSchemeEllipse, PlotSchemeLabel, PlotSchemePoint, PlotSchemePolygon, PlotSchemePolygonArc, PlotSchemePolygonArrowAttackDirection, PlotSchemePolygonArrowAttackDirectionTailed, PlotSchemePolygonArrowClamped, PlotSchemePolygonArrowStraight, PlotSchemePolygonArrowStraightSharp, PlotSchemePolygonArrowUnitCombatOperation, PlotSchemePolygonArrowUnitCombatOperationTailed, PlotSchemePolygonAssemblingPlace, PlotSchemePolygonFlagCurve, PlotSchemePolygonFlagRect, PlotSchemePolygonFlagTriangle, PlotSchemePolygonSmooth, PlotSchemePolyline, PlotSchemePolylineCurve, PlotSchemeRectangle, PlotSkeletonEntity, SampledPlotProperty, SampledPlotStrategy, control, interval, intervalNonclosed, moved, schemeMeasureArea, schemeMeasureDistance, usePlot };
1481
3006
  //# sourceMappingURL=index.mjs.map