;
private render: PolygonRender;
private drawingPoints: {
lng: number;
lat: number;
}[] = [];
private drawingPointsTotalArea = 0;
private moveingPoint = {
lng: 0,
lat: 0,
};
private isDrawing = false;
private type: "byroad" | "line" | "quickline" = "quickline";
private lastAddPointTime = new Date().getTime();
private drivingInstance?: AMap.Driving;
// 是否自动吸附基础路段上的点
private pinToBaseUnit = true;
// 是否自动吸附到其他的区域上
private pinToOtherArea = false;
inited = false;
hpaas: IHPaaS;
public toolsCenter: ToolsCenter;
constructor(toolsCenter: ToolsCenter, options: { type?: "byroad" | "line" | "quickline" } = {}) {
super();
this.toolsCenter = toolsCenter;
this.hpaas = toolsCenter.hpaas;
if (options.type) {
this.type = options.type;
}
if (this.hpaas.type == "L7") {
this.render = new PolygonRenderL7(this);
} else {
this.render = new PolygonRenderDeckGL(this);
}
if (this.type == "byroad") {
this._initDrive();
}
if (!this.inited) {
this.inited = true;
this.render?.initLayer();
this._bindEvent();
}
}
_initDrive() {
if (window.AMap) {
this.drivingInstance = new AMap.Driving({
// map: this.hpaas.mapInstance.amapInstance,
policy: AMap.DrivingPolicy.LEAST_TIME,
});
}
}
_bindEvent() {
this.render.bindEvent({
mousemove: this._mousemoveEventHandler,
click: this._mouseclickEventHandler,
contextmenu: this.contextmenuEventHandler,
});
// this.hpaas.scene.on("mousemove", this._mousemoveEventHandler);
// this.hpaas.scene.on("click", this._mouseclickEventHandler);
// this.hpaas.scene.on("contextmenu", this.contextmenuEventHandler);
// this.bgLayer?.on("mousedown", this.polygonMouseDownHandler);
// this.hpaas.scene.on("mouseup", this.polygonMouseUpHandler);
}
contextmenuEventHandler = (e: any) => {
if (this.isDrawing) {
// this.isDrawing = false;
this._drawPointsToCompletePolygon();
this.renderData();
}
};
_mouseclickEventHandler = (e: mouseEventType) => {
if (this.isDrawing && e) {
// console.log(e, draggingPointModel);
if (this.type == "line" || this.type == "quickline") {
// 折线的时候,点击代表结束
const lng = e.lnglat.lng;
const lat = e.lnglat.lat;
this.drawingPoints.push({ lng, lat });
// if (this.drawingPoints.length > 3) {
// this._drawPointsToCompletePolygon();
// }
this.renderData();
} else if (this.type == "byroad") {
const lng = e.lnglat.lng;
const lat = e.lnglat.lat;
const lastPoint = this.drawingPoints[this.drawingPoints.length - 1];
if (lastPoint) {
this.drivingInstance &&
this.drivingInstance.search(
new AMap.LngLat(lastPoint.lng, lastPoint.lat),
new AMap.LngLat(lng, lat),
(status, result) => {
if (status == "complete") {
const res = result as AMap.Driving.SearchResultBase;
const steps = res.routes[0].steps;
let temps: AMap.LngLat[] = [];
for (let i = 0; i < steps.length; i++) {
const element = steps[i];
temps = temps.concat(element.path);
}
for (let m = 0; m < temps.length; m++) {
const p = temps[m];
this.drawingPoints.push({ lng: p.getLng(), lat: p.getLat() });
}
this.renderData();
}
}
);
} else {
const lng = e.lnglat.lng;
const lat = e.lnglat.lat;
this.drawingPoints.push({ lng, lat });
this.renderData();
}
}
// this.pointLayer.setData(this.points);
}
};
_mousemoveEventHandler = (e: mouseEventType) => {
if (this.isDrawing) {
const lng = e.lnglat.lng;
const lat = e.lnglat.lat;
if (this.type == "quickline") {
const nowTime = new Date().getTime();
if (nowTime - this.lastAddPointTime > 100 && this.drawingPoints.length > 1) {
const lastPoint = this.drawingPoints[this.drawingPoints.length - 1];
const _distance = distance([lng, lat], [lastPoint.lng, lastPoint.lat], {
units: "kilometers",
});
if (_distance > 0.001) {
console.log("add point");
this.drawingPoints.push({ lng, lat });
this.lastAddPointTime = nowTime;
}
}
}
this.renderData();
if (this.drawingPoints.length == 0) {
this.render.popup?.html(
`点击开始绘制
${
this.type == "quickline" ? "然后移动🖱自动添加点" : "点击继续添加点"
}
右击停止绘制
`
);
this.render.popup?.pos({ lng, lat });
this.render.popup?.show();
} else {
this.render.popup?.html(
`总面积:${this.drawingPointsTotalArea.toFixed(
2
)}平方千米
右击停止绘制
`
);
this.render.popup?.pos({ lng, lat });
this.render.popup?.show();
}
// this.popup && this.hpaas.scene.addPopup(this.popup);
}
};
_calcDistanceByAddPoint(lng: number, lat: number) {
const lastPoint = this.drawingPoints[this.drawingPoints.length - 1];
const _distance = distance([lng, lat], [lastPoint.lng, lastPoint.lat], {
units: "kilometers",
});
}
_drawPointsToCompletePolygon() {
if (!this.drawingPolygon) return;
this.drawingPolygon.id = "complete_" + completePolygonCount++;
const multipolygon = multiPolygon([this.drawingPolygon.geometry.coordinates]);
this.toolsCenter.drawLayer.addData([multipolygon as PolygonFeatureType]);
this.emit("complete_feature", multipolygon);
// this.completePolygons.push(multiPolygon([this.drawingPolygon.geometry.coordinates]));
this.drawingPolygon = undefined;
this.drawingFeature = undefined;
this.drawingPoints = [];
this.drawingPointsTotalArea = 0;
}
updateDrawingFeature() {
const drawPoints = Array.from(this.drawingPoints);
if (this.moveingPoint.lng) {
drawPoints.push(this.moveingPoint);
}
if (drawPoints.length == 1) {
const _point = drawPoints[0];
this.drawingFeature = point([_point.lng, _point.lat]) as Feature;
} else if (drawPoints.length == 2) {
const startPoint = drawPoints[0];
const endPoint = drawPoints[1];
this.drawingFeature = lineString([
[startPoint.lng, startPoint.lat],
[endPoint.lng, endPoint.lat],
]) as Feature;
} else if (drawPoints.length > 2) {
if (drawPoints.length > 0) {
drawPoints.push(drawPoints[0]);
}
this.drawingFeature = polygon([
drawPoints.map((p) => {
return [p.lng, p.lat];
}),
]) as Feature;
this.drawingPolygon = this.drawingFeature as Feature;
this.drawingPointsTotalArea = area(this.drawingPolygon) / 1000000;
}
}
renderData() {
this.updateDrawingFeature();
if (this.drawingFeature?.geometry.type == "Point") {
const polygonCollection = featureCollection([]);
polygonCollection.features = polygonCollection.features.concat(this.completePolygons);
this.render.render(polygonCollection, this.drawingPoints);
this.render.popup.hide();
} else if (this.drawingFeature?.geometry.type == "LineString") {
const polygonCollection = featureCollection([]);
polygonCollection.features = polygonCollection.features.concat(this.completePolygons);
this.render.render(polygonCollection, this.drawingPoints);
this.render.popup.show();
} else if (this.drawingFeature?.geometry.type == "Polygon") {
const polygonCollection = featureCollection([multiPolygon([this.drawingFeature.geometry.coordinates])]);
polygonCollection.features = polygonCollection.features.concat(this.completePolygons);
this.render.render(polygonCollection, this.drawingPoints);
this.render.popup.show();
} else {
const polygonCollection = featureCollection([]);
polygonCollection.features = polygonCollection.features.concat(this.completePolygons);
this.render.render(polygonCollection, this.drawingPoints);
this.render.popup.hide();
}
}
begin() {
this.isDrawing = true;
}
end() {
this._drawPointsToCompletePolygon();
this.isDrawing = false;
this.render.popup.hide();
}
clear() {
this.isDrawing = false;
this.completePolygons = [];
this.drawingPoints = [];
this.drawingPolygon = undefined;
this.drawingFeature = undefined;
this.drawingPointsTotalArea = 0;
this.render.popup.hide();
this.renderData();
}
}
export default PolygonDraw;