import { ILayer, LineLayer, PointLayer, PolygonLayer, Popup, Scene } from "@antv/l7";
import {
bbox,
circle,
distance,
Feature,
FeatureCollection,
multiPoint,
multiPolygon,
MultiPolygon,
bboxPolygon,
featureCollection,
area,
} from "@turf/turf";
import HPaaSL7 from "../../../HPaaSL7";
import BaseDraw from "../BaseDraw";
import CORRender from "./IRender";
import CORRenderL7 from "./renderL7";
import CORRenderOL from "./renderOL";
import HPaaSOL from "../../../../hpaas-core/HPaaSOL";
import HPaaSDeckGL from "../../../../../modules/hpaas-core/HPaaSDeckGL";
import CORRenderDeckGL from "./renderDeckGL";
import ToolsCenter from "../../ToolsCenter";
import { PolygonFeatureType } from "../../data/PolygonStore";
export interface mouseEventType {
lnglat: {
lng: number;
lat: number;
};
feature: Feature;
}
let completePolygonCount = 0;
class CircleOrRectDraw extends BaseDraw {
private render: CORRender;
private drawingPoints: {
lng: number;
lat: number;
}[] = [];
private originPoints?: {
lng: number;
lat: number;
};
private destPoints?: {
lng: number;
lat: number;
};
private drawingPointsTotalDistance = 0;
private drawingPointsTotalArea = 0;
moveingPoint = {
lng: 0,
lat: 0,
};
isDrawing = false;
isDestPointPin = false; //
isEditing = false;
public inited = false;
draggingPoint = {
lng: 0,
lat: 0,
};
type: "circle" | "rect" = "circle";
private toolsCenter: ToolsCenter;
constructor(
toolsCenter: ToolsCenter,
options: {
type?: "circle" | "rect";
} = {}
) {
super();
options.type && (this.type = options.type);
this.toolsCenter = toolsCenter;
const hpaas = toolsCenter.hpaas;
if (hpaas.type == "L7") {
this.render = new CORRenderL7(hpaas as HPaaSL7);
} else if (hpaas.type == "OL") {
this.render = new CORRenderOL(hpaas as HPaaSOL);
} else if (hpaas.type == "DECKGL") {
this.render = new CORRenderDeckGL(hpaas as HPaaSDeckGL);
} else {
this.render = new CORRenderDeckGL(hpaas as HPaaSDeckGL);
}
if (!this.inited) {
this.inited = true;
this.render?.initLayer();
this._bindEvent();
}
}
_bindEvent() {
this.render.bindEvent({
mousemove: this._mousemoveEventHandler,
click: this._mouseclickEventHandler,
});
}
_mouseclickEventHandler = (e: mouseEventType) => {
if (this.isDrawing && e) {
// console.log(e, draggingPointModel);
const lng = e.lnglat.lng;
const lat = e.lnglat.lat;
// if (this.isDestPointPin) {
// this._drawPointsToCompletePolygon();
// } else {
if (!this.originPoints) {
this.originPoints = { lng, lat };
} else {
this.destPoints = { lng, lat };
this.isDestPointPin = true;
this._drawPointsToCompletePolygon();
}
// }
this.renderData();
// this.pointLayer.setData(this.points);
}
};
lastAddPointTime = new Date().getTime();
_mousemoveEventHandler = (e: mouseEventType) => {
if (this.isDrawing && e) {
// console.log(e, draggingPointModel);
const lng = e.lnglat.lng;
const lat = e.lnglat.lat;
if (!this.isDestPointPin) this.destPoints = { lng, lat };
if (!this.originPoints) {
this.render.popup.show(`
点击开始绘制
`, {
lng,
lat,
});
}
this.renderData();
// this.hpaas.scene.addPopup(this.popup);
// this.pointLayer.setData(this.points);
}
};
_drawPointsToCompletePolygon() {
if (this.originPoints && this.destPoints) {
const circle = this._createFeatureFromOriginAndDest();
if (circle) {
circle.id = "complete_" + completePolygonCount++;
// this.completePolygons.push(circle);
}
this.originPoints = undefined;
this.destPoints = undefined;
this.isDestPointPin = false;
this.drawingPointsTotalDistance = 0;
this.drawingPointsTotalArea = 0;
this.toolsCenter.drawLayer.addData([circle as PolygonFeatureType]);
this.emit("complete_feature", circle);
}
}
_createFeatureFromOriginAndDest() {
if (!this.originPoints || !this.destPoints) {
return;
}
if (this.type == "circle") {
const center = [this.originPoints.lng, this.originPoints.lat];
const radius = distance(
[this.originPoints.lng, this.originPoints.lat],
[this.destPoints.lng, this.destPoints.lat],
{}
);
const options = { steps: 100 };
const _circle = multiPolygon([circle(center, radius, options).geometry.coordinates]);
return _circle;
} else {
const dest = bbox(
multiPoint([
[this.originPoints.lng, this.originPoints.lat],
[this.destPoints.lng, this.destPoints.lat],
])
);
const _circle = multiPolygon([bboxPolygon(dest).geometry.coordinates]);
return _circle;
}
}
renderData() {
const polygonCollection: FeatureCollection = featureCollection([]);
const circle = this._createFeatureFromOriginAndDest();
if (circle) {
polygonCollection.features.push(circle);
if (!this.isDestPointPin && this.destPoints) {
const _area = area(circle) / 1000000;
this.render.popup.show(
`总面积:${_area.toFixed(2)}平方千米
🖱再次点击停止绘制
`,
{
lng: this.destPoints.lng,
lat: this.destPoints.lat,
}
);
} else {
this.render.popup.hide();
}
}
polygonCollection.features = polygonCollection.features.concat(this.completePolygons);
const pointData = [];
this.originPoints && pointData.push(this.originPoints);
this.destPoints && pointData.push(this.destPoints);
this.render.render(polygonCollection, pointData);
// if (allPoints.length > 2) {
// var lastPoint = allPoints[allPoints.length - 1];
// var totalDistance = 0;
// for (var i = 0; i < allPoints.length - 1; i += 2) {
// var startPoint = allPoints[i];
// var endPoint = allPoints[i + 1];
// var distance = distance(startPoint.toTurf(), endPoint.toTurf(), { units: "kilometers" });
// totalDistance += distance;
// }
// this.manager.drawEndPointToolTips
// .setText(`当前终点,总长:${totalDistance.toFixed(2)}千米`)
// .moveTo(lastPoint.lng, lastPoint.lat)
// .show();
// }
}
begin() {
this.isDrawing = true;
}
// 完成一个feature的创建
completeOneFeature() {}
end() {
this.isDrawing = false;
this._drawPointsToCompletePolygon();
this.render.popup.hide();
}
clear() {
this.isDrawing = false;
this.completePolygons = [];
this.drawingPoints = [];
this.originPoints = undefined;
this.destPoints = undefined;
this.drawingPointsTotalDistance = 0;
this.drawingPointsTotalArea = 0;
this.render.popup.hide();
this.renderData();
}
}
export default CircleOrRectDraw;