Browse Source

支持导入工程

master
Cmen 3 years ago
parent
commit
ead9ac685e
  1. 3
      src/map/editors/BaseOverlayEditor.ts
  2. 18
      src/map/editors/CircleEditor.ts
  3. 16
      src/map/editors/PolygonEditor.ts
  4. 9
      src/map/editors/PolylineEditor.ts
  5. 29
      src/map/editors/RectangleEditor.ts
  6. 54
      src/map/index.ts
  7. 17
      src/store/GlobalController.ts
  8. 6
      src/store/reducers/index.ts

3
src/map/editors/BaseOverlayEditor.ts

@ -1,4 +1,5 @@
import { OverlayTypes } from "@types"; import { OverlayTypes } from "@types";
import { IOverlay } from "../../store/type";
export abstract class BaseOverlayEditor<T extends AMap.BaseEditor> { export abstract class BaseOverlayEditor<T extends AMap.BaseEditor> {
map: AMap.Map; map: AMap.Map;
@ -28,5 +29,7 @@ export abstract class BaseOverlayEditor<T extends AMap.BaseEditor> {
this.editor.open(); this.editor.open();
} }
abstract build(overlay: IOverlay): AMap.MapOverlay;
abstract getType(): OverlayTypes; abstract getType(): OverlayTypes;
} }

18
src/map/editors/CircleEditor.ts

@ -1,11 +1,23 @@
import { OverlayTypes } from "@types"; import { OverlayTypes } from "@types";
import { IOverlay } from "@store";
import { BaseOverlayEditor } from "./BaseOverlayEditor"; import { BaseOverlayEditor } from "./BaseOverlayEditor";
export class CircleEditor extends BaseOverlayEditor<AMap.CircleEditor> { export class CircleEditor extends BaseOverlayEditor<AMap.CircleEditor> {
getType(): OverlayTypes {
return OverlayTypes.Circle;
}
initEditor(map: AMap.Map) { initEditor(map: AMap.Map) {
return new AMap.CircleEditor(this.map); return new AMap.CircleEditor(this.map);
} }
build(circle: IOverlay): AMap.MapOverlay {
const { lngLat, radius } = circle;
const [lng, lat] = lngLat!;
const circleOverlay = new AMap.Circle({
center: new AMap.LngLat(lng, lat),
radius: radius!,
});
return circleOverlay;
}
getType(): OverlayTypes {
return OverlayTypes.Circle;
}
} }

16
src/map/editors/PolygonEditor.ts

@ -1,11 +1,21 @@
import { OverlayTypes } from "@types"; import { OverlayTypes } from "@types";
import { IOverlay } from "../../store/type";
import { BaseOverlayEditor } from "./BaseOverlayEditor"; import { BaseOverlayEditor } from "./BaseOverlayEditor";
export class PolygonEditor extends BaseOverlayEditor<AMap.PolygonEditor> { export class PolygonEditor extends BaseOverlayEditor<AMap.PolygonEditor> {
getType(): OverlayTypes {
return OverlayTypes.Polygon;
}
initEditor(map: AMap.Map) { initEditor(map: AMap.Map) {
return new AMap.PolygonEditor(map); return new AMap.PolygonEditor(map);
} }
build(polygon: IOverlay): AMap.MapOverlay {
const { path } = polygon;
const polygonOverlay = new AMap.Polygon({
path: (path || []).map(([lng, lat]) => new AMap.LngLat(lng, lat)),
});
return polygonOverlay;
}
getType(): OverlayTypes {
return OverlayTypes.Polygon;
}
} }

9
src/map/editors/PolylineEditor.ts

@ -1,4 +1,5 @@
import { OverlayTypes } from "@types"; import { OverlayTypes } from "@types";
import { IOverlay } from "@store";
import { BaseOverlayEditor } from "./BaseOverlayEditor"; import { BaseOverlayEditor } from "./BaseOverlayEditor";
export class PolylineEditor extends BaseOverlayEditor<AMap.PolylineEditor> { export class PolylineEditor extends BaseOverlayEditor<AMap.PolylineEditor> {
@ -6,6 +7,14 @@ export class PolylineEditor extends BaseOverlayEditor<AMap.PolylineEditor> {
return new AMap.PolylineEditor(this.map); return new AMap.PolylineEditor(this.map);
} }
build(polyline: IOverlay): AMap.MapOverlay {
const { path } = polyline;
const polylineOverlay = new AMap.Polyline({
path: (path || []).map(([lng, lat]) => new AMap.LngLat(lng, lat)),
});
return polylineOverlay;
}
getType(): OverlayTypes { getType(): OverlayTypes {
return OverlayTypes.Polyline; return OverlayTypes.Polyline;
} }

29
src/map/editors/RectangleEditor.ts

@ -1,4 +1,5 @@
import { OverlayTypes } from "@types"; import { OverlayTypes } from "@types";
import { IOverlay } from "../../store/type";
import { BaseOverlayEditor } from "./BaseOverlayEditor"; import { BaseOverlayEditor } from "./BaseOverlayEditor";
export class RectangleEditor extends BaseOverlayEditor<AMap.RectangleEditor> { export class RectangleEditor extends BaseOverlayEditor<AMap.RectangleEditor> {
@ -20,6 +21,34 @@ export class RectangleEditor extends BaseOverlayEditor<AMap.RectangleEditor> {
return target; return target;
} }
build(rect: IOverlay): AMap.MapOverlay {
const { path } = rect;
let west = 180,
east = -180,
north = -90,
south = 90;
path?.forEach((position) => {
const [lng, lat] = position;
west = Math.min(lng, west);
east = Math.max(lng, east);
north = Math.max(lat, north);
south = Math.min(lat, south);
});
const bounds = new AMap.Bounds(
new AMap.LngLat(west, south),
new AMap.LngLat(east, north)
);
console.log(bounds);
const rectOverlay = new AMap.Rectangle({
bounds,
fillOpacity: 0.1,
bubble: true,
cursor: "pointer",
strokeColor: "#f00",
});
return rectOverlay;
}
getType(): OverlayTypes { getType(): OverlayTypes {
return OverlayTypes.Rectangle; return OverlayTypes.Rectangle;
} }

54
src/map/index.ts

@ -1,7 +1,7 @@
import Emitter from "@finevis/emitter"; import Emitter from "@finevis/emitter";
import "@amap/amap-jsapi-types"; import "@amap/amap-jsapi-types";
import { IMapState } from "@store"; import { IMapState, IOverlay } from "@store";
import { getOverlayPaths, getUID } from "@utils"; import { getOverlayPaths, getUID } from "@utils";
import { import {
@ -84,6 +84,10 @@ export class MapEditor extends Emitter {
break; break;
case Command.DeleteOverlays: case Command.DeleteOverlays:
this._deleteOverlays(); this._deleteOverlays();
break;
case Command.OpenProject:
this.importOverlays(mapState);
break;
} }
} }
@ -103,13 +107,54 @@ export class MapEditor extends Emitter {
); );
} }
importOverlays() { importOverlays(mapState: IMapState) {
// this.clearOverlays();
const { rectangles, polygons, polylines, circles } = mapState;
const rectangleEditor = this.getEditorByType(OverlayTypes.Rectangle);
const polygonEditor = this.getEditorByType(OverlayTypes.Polygon);
const polylineEditor = this.getEditorByType(OverlayTypes.Polyline);
const circleEditor = this.getEditorByType(OverlayTypes.Circle);
const addOverlay = (
id: string,
target: AMap.MapOverlay,
type: OverlayTypes
) => {
this.overlayMap[id] = {
type,
target,
};
this.map.add(target);
};
rectangles.forEach((rect) =>
addOverlay(rect.id, rectangleEditor!.build(rect), OverlayTypes.Rectangle)
);
polygons.forEach((polygon) =>
addOverlay(
polygon.id,
polygonEditor!.build(polygon),
OverlayTypes.Polygon
)
);
polylines.forEach((polyline) =>
addOverlay(
polyline.id,
polylineEditor!.build(polyline),
OverlayTypes.Polyline
)
);
circles.forEach((circle) =>
addOverlay(circle.id, circleEditor!.build(circle), OverlayTypes.Circle)
);
} }
// 清空所有覆盖物 // 清空所有覆盖物
clearOverlays() { clearOverlays() {
// for (let id in this.overlayMap) {
this.map.remove(this.overlayMap[id].target);
}
this.overlayMap = {};
} }
_createOverlay(mapState: IMapState) { _createOverlay(mapState: IMapState) {
@ -133,6 +178,7 @@ export class MapEditor extends Emitter {
this._selectedIds.forEach((id) => { this._selectedIds.forEach((id) => {
const { target } = this.overlayMap[id]; const { target } = this.overlayMap[id];
this.map.remove(target); this.map.remove(target);
delete this.overlayMap[id];
}); });
} }

17
src/store/GlobalController.ts

@ -23,29 +23,32 @@ interface IGlobalController {
// 全局控制器, 用以复用一些快捷方法. // 全局控制器, 用以复用一些快捷方法.
export class GlobelController implements IGlobalController { export class GlobelController implements IGlobalController {
_store: IStore; store: IStore;
constructor(store: IStore) { constructor(store: IStore) {
this._store = store; this.store = store;
this._bindOperations(); this._bindOperations();
this._registerHotkeys(); this._registerHotkeys();
const cached = sessionStorage.getItem("fine-geojson"); const cached = sessionStorage.getItem("fine-geojson");
if (cached != null) { if (cached != null) {
setTimeout(() => {
this._replaceState(JSON.parse(cached)); this._replaceState(JSON.parse(cached));
}, 3000);
} }
setInterval(() => { setInterval(() => {
sessionStorage.setItem( sessionStorage.setItem(
"fine-geojson", "fine-geojson",
JSON.stringify(this._store.getState()) JSON.stringify(this.store.getState())
); );
console.log("updated!"); console.log("updated!");
}, 10000); }, 10000);
} }
get mapState() { get mapState() {
return this._store.getState().map; return this.store.getState().map;
} }
saveGeoJSON() { saveGeoJSON() {
@ -85,7 +88,7 @@ export class GlobelController implements IGlobalController {
} }
createOverlay(type: OverlayTypes) { createOverlay(type: OverlayTypes) {
this._store.dispatch(EditorAction.createOverlay(type)); this.store.dispatch(EditorAction.createOverlay(type));
} }
deleteOverlays() { deleteOverlays() {
@ -94,13 +97,13 @@ export class GlobelController implements IGlobalController {
Modal.confirm({ Modal.confirm({
title: "确定删除覆盖物吗?", title: "确定删除覆盖物吗?",
onOk: () => { onOk: () => {
this._store.dispatch(EditorAction.deleteOverlays()); this.store.dispatch(EditorAction.deleteOverlays());
}, },
}); });
} }
private _replaceState(state: IEditorState) { private _replaceState(state: IEditorState) {
this._store.dispatch(EditorAction.replaceState(state)); this.store.dispatch(EditorAction.replaceState(state));
} }
private _bindOperations() { private _bindOperations() {

6
src/store/reducers/index.ts

@ -1,3 +1,4 @@
import produce from "immer";
import { IEditorState } from "../type"; import { IEditorState } from "../type";
import { initState } from "../initState"; import { initState } from "../initState";
import { ActionTypes } from "../actions"; import { ActionTypes } from "../actions";
@ -7,6 +8,7 @@ import {
selectOverlay, selectOverlay,
deleteOverlays, deleteOverlays,
} from "./map"; } from "./map";
import { Command } from "@types";
export type Action = { export type Action = {
type: ActionTypes; type: ActionTypes;
@ -24,7 +26,9 @@ const actionReducers: Record<ActionTypes, ActionReducer> = {
}; };
function replaceState(state = initState, payload: IEditorState) { function replaceState(state = initState, payload: IEditorState) {
return payload; return produce(payload, (draft) => {
draft.map.command = Command.OpenProject;
});
} }
export function reducer(state = initState, action: Action) { export function reducer(state = initState, action: Action) {

Loading…
Cancel
Save