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

18
src/map/editors/CircleEditor.ts

@ -1,11 +1,23 @@
import { OverlayTypes } from "@types";
import { IOverlay } from "@store";
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);
}
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 { IOverlay } from "../../store/type";
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);
}
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 { IOverlay } from "@store";
import { BaseOverlayEditor } from "./BaseOverlayEditor";
export class PolylineEditor extends BaseOverlayEditor<AMap.PolylineEditor> {
@ -6,6 +7,14 @@ export class PolylineEditor extends BaseOverlayEditor<AMap.PolylineEditor> {
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 {
return OverlayTypes.Polyline;
}

29
src/map/editors/RectangleEditor.ts

@ -1,4 +1,5 @@
import { OverlayTypes } from "@types";
import { IOverlay } from "../../store/type";
import { BaseOverlayEditor } from "./BaseOverlayEditor";
export class RectangleEditor extends BaseOverlayEditor<AMap.RectangleEditor> {
@ -20,6 +21,34 @@ export class RectangleEditor extends BaseOverlayEditor<AMap.RectangleEditor> {
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 {
return OverlayTypes.Rectangle;
}

54
src/map/index.ts

@ -1,7 +1,7 @@
import Emitter from "@finevis/emitter";
import "@amap/amap-jsapi-types";
import { IMapState } from "@store";
import { IMapState, IOverlay } from "@store";
import { getOverlayPaths, getUID } from "@utils";
import {
@ -84,6 +84,10 @@ export class MapEditor extends Emitter {
break;
case Command.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() {
//
for (let id in this.overlayMap) {
this.map.remove(this.overlayMap[id].target);
}
this.overlayMap = {};
}
_createOverlay(mapState: IMapState) {
@ -133,6 +178,7 @@ export class MapEditor extends Emitter {
this._selectedIds.forEach((id) => {
const { target } = this.overlayMap[id];
this.map.remove(target);
delete this.overlayMap[id];
});
}

17
src/store/GlobalController.ts

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

6
src/store/reducers/index.ts

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

Loading…
Cancel
Save