Browse Source

补齐overlayEditor

master
Cmen 3 years ago
parent
commit
495bb4da12
  1. 9
      src/editor/Catalog/index.tsx
  2. 17
      src/editor/Plot/Tools/index.tsx
  3. 6
      src/map/editors/BaseOverlayEditor.ts
  4. 11
      src/map/editors/CircleEditor.ts
  5. 11
      src/map/editors/PolygonEditor.ts
  6. 12
      src/map/editors/PolylineEditor.ts
  7. 9
      src/map/editors/RectangleEditor.ts
  8. 5
      src/map/editors/index.ts
  9. 47
      src/map/index.ts
  10. 6
      src/store/actions.ts
  11. 4
      src/store/initState.ts
  12. 25
      src/store/reducers/map/index.ts
  13. 2
      src/store/selectors.ts
  14. 8
      src/store/type.ts
  15. 7
      src/types/enum.ts
  16. 8
      src/types/index.ts

9
src/editor/Catalog/index.tsx

@ -30,7 +30,8 @@ const OverlayList = (props: OverlayListProps) => {
const Catalog = () => { const Catalog = () => {
// const callback = (key: string | string[]) => console.log(key); // const callback = (key: string | string[]) => console.log(key);
const { rectangles, polygons } = useSelector(mapStateSelector); const { rectangles, polygons, polylines, circles } =
useSelector(mapStateSelector);
return ( return (
<Collapse <Collapse
defaultActiveKey={["1"]} defaultActiveKey={["1"]}
@ -43,6 +44,12 @@ const Catalog = () => {
<Panel header="多边形" key={2}> <Panel header="多边形" key={2}>
<OverlayList overlays={polygons} /> <OverlayList overlays={polygons} />
</Panel> </Panel>
<Panel header="多段线" key={3}>
<OverlayList overlays={polylines} />
</Panel>
<Panel header="圆形" key={4}>
<OverlayList overlays={circles} />
</Panel>
</Collapse> </Collapse>
); );
}; };

17
src/editor/Plot/Tools/index.tsx

@ -1,6 +1,7 @@
import { Tooltip } from "antd"; import { Tooltip } from "antd";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import { editorAction } from "@store"; import { editorAction } from "@store";
import { OverlayTypes } from "@types";
type IconWithTipProps = { type IconWithTipProps = {
type: string; type: string;
@ -25,15 +26,25 @@ const IconWithTip = ({
const Tools = () => { const Tools = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const createOverlay = (type: string) => () => const createOverlay = (type: OverlayTypes) => () =>
dispatch(editorAction.createOverlay(type)); dispatch(editorAction.createOverlay(type));
const createRectangle = createOverlay("rect");
const createRectangle = createOverlay(OverlayTypes.Rectangle);
const createPolygon = createOverlay(OverlayTypes.Polygon);
const createPolyline = createOverlay(OverlayTypes.Polyline);
const createCircle = createOverlay(OverlayTypes.Circle);
return ( return (
<> <>
<div className="marker-tools"> <div className="marker-tools">
<IconWithTip type="rect" text="矩形工具" onClick={createRectangle} /> <IconWithTip type="rect" text="矩形工具" onClick={createRectangle} />
<IconWithTip type="circle" text="圆形工具" /> <IconWithTip type="polygon" text="多边形工具" onClick={createPolygon} />
<IconWithTip
type="polyline"
text="多段线工具"
onClick={createPolyline}
/>
<IconWithTip type="circle" text="圆形工具" onClick={createCircle} />
</div> </div>
<div className="common-tools"> <div className="common-tools">
<div className="tools-group"> <div className="tools-group">

6
src/map/editors/BaseLayerEditor.ts → src/map/editors/BaseOverlayEditor.ts

@ -1,4 +1,6 @@
export abstract class BaseLayerEditor<T extends AMap.BaseEditor> { import { OverlayTypes } from "@types";
export abstract class BaseOverlayEditor<T extends AMap.BaseEditor> {
map: AMap.Map; map: AMap.Map;
editor: T; editor: T;
constructor(map: AMap.Map) { constructor(map: AMap.Map) {
@ -19,4 +21,6 @@ export abstract class BaseLayerEditor<T extends AMap.BaseEditor> {
return target; return target;
} }
abstract getType(): OverlayTypes;
} }

11
src/map/editors/CircleEditor.ts

@ -0,0 +1,11 @@
import { OverlayTypes } from "@types";
import { BaseOverlayEditor } from "./BaseOverlayEditor";
export class CircleEditor extends BaseOverlayEditor<AMap.CircleEditor> {
getType(): OverlayTypes {
return OverlayTypes.Circle;
}
initEditor(map: AMap.Map) {
return new AMap.CircleEditor(this.map);
}
}

11
src/map/editors/PolygonEditor.ts

@ -0,0 +1,11 @@
import { OverlayTypes } from "@types";
import { BaseOverlayEditor } from "./BaseOverlayEditor";
export class PolygonEditor extends BaseOverlayEditor<AMap.PolygonEditor> {
getType(): OverlayTypes {
return OverlayTypes.Polygon;
}
initEditor(map: AMap.Map) {
return new AMap.PolygonEditor(map);
}
}

12
src/map/editors/PolylineEditor.ts

@ -0,0 +1,12 @@
import { OverlayTypes } from "@types";
import { BaseOverlayEditor } from "./BaseOverlayEditor";
export class PolylineEditor extends BaseOverlayEditor<AMap.PolylineEditor> {
initEditor(map: AMap.Map) {
return new AMap.PolylineEditor(this.map);
}
getType(): OverlayTypes {
return OverlayTypes.Polyline;
}
}

9
src/map/editors/RectangleEditor.ts

@ -1,7 +1,12 @@
import { BaseLayerEditor } from "./BaseLayerEditor"; import { OverlayTypes } from "@types";
import { BaseOverlayEditor } from "./BaseOverlayEditor";
export class RectangleEditor extends BaseLayerEditor<AMap.PolygonEditor> { export class RectangleEditor extends BaseOverlayEditor<AMap.RectangleEditor> {
initEditor(map: AMap.Map) { initEditor(map: AMap.Map) {
return new AMap.RectangleEditor(this.map); return new AMap.RectangleEditor(this.map);
} }
getType(): OverlayTypes {
return OverlayTypes.Rectangle;
}
} }

5
src/map/editors/index.ts

@ -1,2 +1,5 @@
export * from "./BaseLayerEditor"; export * from "./BaseOverlayEditor";
export * from "./RectangleEditor"; export * from "./RectangleEditor";
export * from "./PolygonEditor";
export * from "./CircleEditor";
export * from "./PolylineEditor";

47
src/map/index.ts

@ -1,19 +1,35 @@
import Emitter from "@finevis/emitter"; import Emitter from "@finevis/emitter";
import "../types"; import "@amap/amap-jsapi-types";
import { IMapState } from "@store"; import { IMapState } from "@store";
import { RectangleEditor } from "./editors"; import {
BaseOverlayEditor,
RectangleEditor,
PolygonEditor,
PolylineEditor,
CircleEditor,
} from "./editors";
import "@amap/amap-jsapi-types";
import { registerHotkey } from "../utils/hotkeys"; import { registerHotkey } from "../utils/hotkeys";
import { EventTypes } from "../types/enum"; import { EventTypes } from "../types/enum";
let uuid = 0; let uuid = 0;
const getUuid = () => ++uuid; const getUuid = () => ++uuid;
type AMapOverlayEditor =
| AMap.RectangleEditor
| AMap.PolygonEditor
| AMap.PolylineEditor
| AMap.CircleEditor;
export class MapEditor extends Emitter { export class MapEditor extends Emitter {
dom: HTMLDivElement; dom: HTMLDivElement;
private _map: AMap.Map | undefined; private _map: AMap.Map | undefined;
private rectangleEditor: RectangleEditor | undefined; private overlayEditors: BaseOverlayEditor<AMapOverlayEditor>[] = [];
private overlayMap: Record<number, AMap.MapOverlay> = {}; private overlayMap: Record<number, AMap.MapOverlay> = {};
private _currentOverlayEditor:
| BaseOverlayEditor<AMapOverlayEditor>
| undefined;
constructor(dom: HTMLDivElement) { constructor(dom: HTMLDivElement) {
super(); super();
this.dom = dom; this.dom = dom;
@ -31,6 +47,7 @@ export class MapEditor extends Emitter {
"AMap.RectangleEditor", "AMap.RectangleEditor",
"AMap.PolylineEditor", "AMap.PolylineEditor",
"AMap.PolygonEditor", "AMap.PolygonEditor",
"AMap.CircleEditor",
"AMap.PlaceSearch", "AMap.PlaceSearch",
"AMap.AutoComplete", "AMap.AutoComplete",
], ],
@ -41,21 +58,26 @@ export class MapEditor extends Emitter {
registerHotkey(" ", { callback: this.finishCreateOverlay.bind(this) }); registerHotkey(" ", { callback: this.finishCreateOverlay.bind(this) });
} }
update(state: IMapState) { update(mapState: IMapState) {
if (state.status === "createOverlay") { const { status, overlayType } = mapState;
this.rectangleEditor?.create(); if (status === "createOverlay") {
this._currentOverlayEditor = this.overlayEditors.find(
(editor) => editor.getType() === overlayType
);
this._currentOverlayEditor?.create();
} }
} }
finishCreateOverlay() { finishCreateOverlay() {
const target = this.rectangleEditor?.finish(); if (this._currentOverlayEditor == null) return;
const target = this._currentOverlayEditor.finish();
let evt: any = null; let evt: any = null;
if (target != null) { if (target != null) {
const id = getUuid(); const id = getUuid();
this.overlayMap[id] = target; this.overlayMap[id] = target;
evt = { evt = {
id, id,
type: "rectangle", type: this._currentOverlayEditor.getType(),
}; };
} }
this.emit(EventTypes.FinishCreateOverlay, evt); this.emit(EventTypes.FinishCreateOverlay, evt);
@ -63,6 +85,11 @@ export class MapEditor extends Emitter {
initEditors() { initEditors() {
const { map } = this; const { map } = this;
this.rectangleEditor = new RectangleEditor(map); this.overlayEditors = [
new RectangleEditor(map),
new PolygonEditor(map),
new PolylineEditor(map),
new CircleEditor(map),
];
} }
} }

6
src/store/actions.ts

@ -1,3 +1,5 @@
import { OverlayTypes } from "@types";
export enum ActionTypes { export enum ActionTypes {
// AddRect = "addRect", // AddRect = "addRect",
CreateOverlay = "createOverlay", CreateOverlay = "createOverlay",
@ -6,7 +8,7 @@ export enum ActionTypes {
export type CreatedOverlay = { export type CreatedOverlay = {
id: string; id: string;
type: string; type: OverlayTypes;
}; };
export class EditorAction { export class EditorAction {
// addRect() { // addRect() {
@ -14,7 +16,7 @@ export class EditorAction {
// type: ActionTypes.AddRect, // type: ActionTypes.AddRect,
// }; // };
// } // }
createOverlay(type: string) { createOverlay(type: OverlayTypes) {
return { return {
type: ActionTypes.CreateOverlay, type: ActionTypes.CreateOverlay,
payload: type, payload: type,

4
src/store/initState.ts

@ -3,8 +3,10 @@ import { IEditorState } from "./type";
export const initState: IEditorState = { export const initState: IEditorState = {
map: { map: {
status: "", status: "",
overlayType: "", overlayType: null,
polygons: [], polygons: [],
polylines: [],
circles: [],
rectangles: [], rectangles: [],
}, },
}; };

25
src/store/reducers/map/index.ts

@ -1,21 +1,38 @@
import produce from "immer"; import produce from "immer";
import { initState } from "../../initState"; import { initState } from "../../initState";
import { IOverlay } from "@store"; import { IOverlay } from "@store";
import { OverlayTypes } from "@types";
const OverlayNamePrefixs: Record<OverlayTypes, string> = {
[OverlayTypes.Rectangle]: "矩形",
[OverlayTypes.Polygon]: "多边形",
[OverlayTypes.Polyline]: "多段线",
[OverlayTypes.Circle]: "圆形",
};
export function createOverlay(state = initState, payload: any) { export function createOverlay(state = initState, payload: any) {
return produce(state, (draft) => { return produce(state, (draft) => {
draft.map.status = "createOverlay"; draft.map.status = "createOverlay";
draft.map.overlayType = payload as string; draft.map.overlayType = payload as OverlayTypes;
}); });
} }
export function finishCreateOverlay(state = initState, payload: any) { export function finishCreateOverlay(state = initState, payload: any) {
return produce(state, (draft) => { return produce(state, (draft) => {
const overlay = payload as IOverlay; const overlay = payload as IOverlay;
const { type } = overlay;
// todo: uniqueName. // todo: uniqueName.
overlay.name = "矩形" + overlay.id; overlay.name = OverlayNamePrefixs[type] + overlay.id;
draft.map.status = ""; draft.map.status = "";
draft.map.overlayType = ""; draft.map.overlayType = null;
draft.map.rectangles = state.map.rectangles.concat([overlay]); (type === OverlayTypes.Rectangle
? draft.map.rectangles
: type === OverlayTypes.Circle
? draft.map.circles
: type === OverlayTypes.Polygon
? draft.map.polygons
: draft.map.polylines
).push(overlay);
// draft.map.rectangles = state.map.rectangles.concat([overlay]);
}); });
} }

2
src/store/selectors.ts

@ -1,3 +1,3 @@
import { editorAction, IEditorState } from "@store"; import { IEditorState } from "@store";
export const mapStateSelector = (state: IEditorState) => state.map; export const mapStateSelector = (state: IEditorState) => state.map;

8
src/store/type.ts

@ -1,13 +1,17 @@
import { OverlayTypes } from "@types";
export interface IOverlay { export interface IOverlay {
id: string; id: string;
name: string; name: string;
type: string; type: OverlayTypes;
} }
export interface IMapState { export interface IMapState {
status: string; status: string;
overlayType: string; overlayType: OverlayTypes | null;
polygons: IOverlay[]; polygons: IOverlay[];
polylines: IOverlay[];
circles: IOverlay[];
rectangles: IOverlay[]; rectangles: IOverlay[];
} }

7
src/types/enum.ts

@ -1,3 +1,10 @@
export enum EventTypes { export enum EventTypes {
FinishCreateOverlay = "finishCreateOverlay", FinishCreateOverlay = "finishCreateOverlay",
} }
export enum OverlayTypes {
Rectangle = "rectangle",
Polygon = "polygon",
Polyline = "polyline",
Circle = "circle",
}

8
src/types/index.ts

@ -19,6 +19,12 @@ declare global {
class RectangleEditor extends BaseEditor { class RectangleEditor extends BaseEditor {
// //
} }
class PolylineEditor extends BaseEditor {
//
}
class CircleEditor extends BaseEditor {
//
}
} }
} }
export {}; export * from "./enum";

Loading…
Cancel
Save