From b4d9ece671d220d87ea7b9116bd4e2b2f0163706 Mon Sep 17 00:00:00 2001 From: Cmen <1176967590@qq.com> Date: Sat, 12 Mar 2022 10:26:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=A0=87=E8=AE=B0=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/images/marker.png | Bin 0 -> 4459 bytes src/editor/Catalog/index.tsx | 11 +++- src/editor/Plot/Tools/index.tsx | 1 + src/icon.less | 2 +- src/index.less | 5 ++ src/map/MapEditor.ts | 103 +++++++++++++++++++++----------- src/map/type.ts | 1 + src/store/actions/index.ts | 1 + src/store/constants.ts | 1 + src/store/reducers/map/index.ts | 2 +- src/types/amap.d.ts | 4 ++ 11 files changed, 93 insertions(+), 38 deletions(-) create mode 100644 public/images/marker.png diff --git a/public/images/marker.png b/public/images/marker.png new file mode 100644 index 0000000000000000000000000000000000000000..cbe943497a917eb6ac259bab45dccbc4264399e4 GIT binary patch literal 4459 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 { const rectangles: IOverlay[] = [], polygons: IOverlay[] = [], polylines: IOverlay[] = [], - circles: IOverlay[] = []; + circles: IOverlay[] = [], + points: IOverlay[] = []; overlays.forEach((overlay) => { switch (overlay.type) { @@ -53,6 +54,9 @@ const Catalog = () => { case OverlayTypes.Polyline: polylines.push(overlay); break; + case OverlayTypes.Point: + points.push(overlay); + break; default: circles.push(overlay); } @@ -60,7 +64,7 @@ const Catalog = () => { return ( @@ -75,6 +79,9 @@ const Catalog = () => { + + + ); }; diff --git a/src/editor/Plot/Tools/index.tsx b/src/editor/Plot/Tools/index.tsx index 32b5d50..7be9531 100644 --- a/src/editor/Plot/Tools/index.tsx +++ b/src/editor/Plot/Tools/index.tsx @@ -67,6 +67,7 @@ const Tools = () => { +
diff --git a/src/icon.less b/src/icon.less index 18982d4..48600db 100644 --- a/src/icon.less +++ b/src/icon.less @@ -63,7 +63,7 @@ .icon-setting:after { content: "\e78e"; } -.icon-location:after { +.icon-point:after { content: "\e793"; } .icon-rectangle:after { diff --git a/src/index.less b/src/index.less index bd521eb..9deea43 100644 --- a/src/index.less +++ b/src/index.less @@ -9,3 +9,8 @@ body { #app { height: 100%; } +.amap-icon img, +.amap-marker-content img{ + width: 25px; + height: 34px; +} diff --git a/src/map/MapEditor.ts b/src/map/MapEditor.ts index c014d3e..035b7bf 100644 --- a/src/map/MapEditor.ts +++ b/src/map/MapEditor.ts @@ -157,23 +157,21 @@ export class MapEditor extends Emitter implements IMapEditor { createOverlay(type: OverlayTypes) { this.finishEditOverlay(); - this.currentOverlayEditor = this.getEditorByType(type!); - this.currentOverlayEditor?.create(); - this.editorStatus = "creating"; + if (type === OverlayTypes.Point) { + this._createMarker(); + } else { + this.currentOverlayEditor = this.getEditorByType(type!); + this.currentOverlayEditor?.create(); + this.editorStatus = "creating"; + } } selectOverlays(ids?: string[]) { this.finishEditOverlay(); - this.selectedIds?.forEach((id) => { - const { target, type } = this.overlayMap[id]; - target.setOptions(getOverlayOptions(type)); - }); + this.selectedIds?.forEach((id) => this._updateOverlayProps(id)); if (ids == null) return; this.selectedIds = ids; - ids.forEach((id) => { - const { target } = this.overlayMap[id]; - target.setOptions(SelectedOptions); - }); + ids.forEach((id) => this._updateOverlayProps(id, true)); } deleteOverlays() { @@ -199,9 +197,7 @@ export class MapEditor extends Emitter implements IMapEditor { let id = getUID(); if (isCreatingOverlay) { this._addOverlay(id, { type, target }); - target.setOptions( - type === OverlayTypes.Polyline ? PolylineOptions : PolygonOptions - ); + this._updateOverlayProps(id); } else { id = this.selectedIds[0]; } @@ -237,17 +233,61 @@ export class MapEditor extends Emitter implements IMapEditor { this.placeSearch?.search(item.name); } + editSelectedOverlay() { + if (this.selectedIds.length !== 1) return; + const [id] = this.selectedIds; + const { target, type } = this.overlayMap[id]; + this.currentOverlayEditor = this.getEditorByType(type); + this.currentOverlayEditor?.edit(target); + this.editorStatus = "editing"; + } + + getOverlay(id: string) { + return this.overlayMap[id]; + } + + _createMarker() { + const id = getUID(); + const marker = this._buildMarker(this.getCenter()); + this._addOverlay(id, { type: OverlayTypes.Point, target: marker }); + this._updateOverlay(id); + } + + _buildMarker(position: number[]) { + const marker = new AMap.Marker({ + icon: "/images/marker.png", + position: position as [number, number], + anchor: "bottom-center", + offset: new AMap.Pixel(-13, -30), + }); + marker.setMap(this.map); + this.map.add(marker); + return marker; + } + + _updateOverlayProps(id: string, selected = false) { + const { type, target } = this.getOverlay(id); + if (type === OverlayTypes.Point) { + target.setOptions({ draggable: selected }); + } else { + target.setOptions(selected ? SelectedOptions : getOverlayOptions(type)); + } + } + _buildFromOverlay(overlay: IOverlay) { const { type, id } = overlay; - const editor = this.overlayEditors.find( - (editor) => editor.getType() === type - )!; - const target = editor.build(overlay); + let target: AMap.MapOverlay; + if (type === OverlayTypes.Point) { + target = this._buildMarker(overlay.lngLat!); + } else { + const editor = this.overlayEditors.find( + (editor) => editor.getType() === type + )!; + target = editor.build(overlay); + this.map.add(target); + } this._addOverlay(id, { type, target }); - target.setOptions( - type === OverlayTypes.Polyline ? PolylineOptions : PolygonOptions - ); - this.map.add(target); + this._updateOverlayProps(id); if (overlay.backgroundImage) { this.updateOverlayBackground(id, overlay.backgroundImage); } @@ -257,7 +297,11 @@ export class MapEditor extends Emitter implements IMapEditor { if (this.overlayMap[id] == null) return; const { type, target } = this.overlayMap[id]; const evt: any = { id, type }; - if (type === OverlayTypes.Circle) { + if (type === OverlayTypes.Point) { + const marker = target as AMap.Marker; + const { lng, lat } = marker.getPosition()!; + evt.lngLat = [lng, lat]; + } else if (type === OverlayTypes.Circle) { const circle = target as AMap.Circle; const { lng, lat } = circle.getCenter(); evt.lngLat = [lng, lat]; @@ -269,21 +313,12 @@ export class MapEditor extends Emitter implements IMapEditor { this.updateOverlayBackground(id); } - editSelectedOverlay() { - if (this.selectedIds.length !== 1) return; - const [id] = this.selectedIds; - const { target, type } = this.overlayMap[id]; - this.currentOverlayEditor = this.getEditorByType(type); - this.currentOverlayEditor?.edit(target); - this.editorStatus = "editing"; - } - - onOverlayDragEnd(id: string) { + _onOverlayDragEnd(id: string) { this._updateOverlay(id); } _addOverlay(id: string, overlay: OverlayTemp) { this.overlayMap[id] = overlay; - overlay.target.on("dragend", () => this.onOverlayDragEnd(id)); + overlay.target.on("dragend", () => this._onOverlayDragEnd(id)); } } diff --git a/src/map/type.ts b/src/map/type.ts index 5f56046..0857fb5 100644 --- a/src/map/type.ts +++ b/src/map/type.ts @@ -46,4 +46,5 @@ export enum OverlayTypes { Polygon = "polygon", Polyline = "polyline", Circle = "circle", + Point = "point", } diff --git a/src/store/actions/index.ts b/src/store/actions/index.ts index f7c0253..001c9f3 100644 --- a/src/store/actions/index.ts +++ b/src/store/actions/index.ts @@ -52,6 +52,7 @@ export class EditorAction { // 创建覆盖物结束 this.mapEditor.on(EventTypes.FinishEditOverlay, (overlay: IOverlay) => { this.dispatch(StoreAction.finishEditOverlay(overlay)); + this.selectOverlay(overlay.id); }); } diff --git a/src/store/constants.ts b/src/store/constants.ts index 7a6665f..abe378b 100644 --- a/src/store/constants.ts +++ b/src/store/constants.ts @@ -5,4 +5,5 @@ export const OverlayNamePrefixs: Record = { [OverlayTypes.Polygon]: "多边形", [OverlayTypes.Polyline]: "多段线", [OverlayTypes.Circle]: "圆形", + [OverlayTypes.Point]: "标记点", }; diff --git a/src/store/reducers/map/index.ts b/src/store/reducers/map/index.ts index bccb846..4b282cd 100644 --- a/src/store/reducers/map/index.ts +++ b/src/store/reducers/map/index.ts @@ -31,7 +31,6 @@ export function finishEditOverlay(state = initState, payload: any) { const overlay = payload as IOverlay; const { type, id } = overlay; // todo: uniqueName. - overlay.name = OverlayNamePrefixs[type] + overlay.id; const { overlays } = draft.map; const existed = overlays.find((overlay) => overlay.id === id); if (existed) { @@ -40,6 +39,7 @@ export function finishEditOverlay(state = initState, payload: any) { ...overlay, }; } else { + overlay.name = OverlayNamePrefixs[type] + overlay.id; const isRoad = type === OverlayTypes.Polyline; if (isRoad) { overlay.category = OverlayCategory.Road; diff --git a/src/types/amap.d.ts b/src/types/amap.d.ts index e09c15b..e60d5bf 100644 --- a/src/types/amap.d.ts +++ b/src/types/amap.d.ts @@ -7,10 +7,14 @@ declare global { interface IBaseEditor { // new (map: AMap.Map): any; } + interface Marker { + setOptions(options: { [name: string]: any }): void; + } type MapOverlay = | AMap.Rectangle | AMap.Polygon | AMap.Polyline + | AMap.Marker | AMap.Circle; class BaseEditor implements IBaseEditor { constructor(map: AMap.Map);