diff --git a/public/images/marker.png b/public/images/marker.png new file mode 100644 index 0000000..cbe9434 Binary files /dev/null and b/public/images/marker.png differ diff --git a/src/editor/Catalog/index.tsx b/src/editor/Catalog/index.tsx index f0847e1..101bc2b 100644 --- a/src/editor/Catalog/index.tsx +++ b/src/editor/Catalog/index.tsx @@ -40,7 +40,8 @@ const Catalog = () => { 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);