diff --git a/src/store/actions/index.ts b/src/store/actions/index.ts index dc4b56b..f2f8cc4 100644 --- a/src/store/actions/index.ts +++ b/src/store/actions/index.ts @@ -1,7 +1,7 @@ import { IMapEditor } from "@map"; import { Action } from "redux"; import { Modal } from "antd"; -import { registerHotkey, downloadJSON } from "@utils"; +import { registerHotkey, downloadJSON, openUpload } from "@utils"; import { getGeoJSON } from "../utils"; import { OverlayTypes, EventTypes } from "@types"; @@ -49,16 +49,7 @@ export class EditorAction { } setInterval(() => { - const { mapOptions } = this; - sessionStorage.setItem( - "fine-geojson", - JSON.stringify({ - ...mapOptions, - center: this.mapEditor?.getCenter(), - zoom: this.mapEditor?.getZoom(), - }) - ); - console.log("saved!"); + this.saveTemp(); }, 10000); } // ---------- public methods ------------- @@ -92,11 +83,6 @@ export class EditorAction { }); } - saveGeoJSON() { - const geojson = getGeoJSON(this.mapOptions); - downloadJSON(geojson, "fine.geojson"); - } - selectOverlay(id: string) { const { selectedIds } = this.store.getState(); if (selectedIds.indexOf(id) >= 0) { @@ -108,12 +94,24 @@ export class EditorAction { } } + saveGeoJSON() { + const geojson = getGeoJSON(this.mapOptions); + downloadJSON(geojson, "fine.geojson"); + } + saveProject() { - // + const mapOptions = this._getMapOptions(); + downloadJSON(mapOptions, "fine.fjd"); } + saveTemp() { - // + sessionStorage.setItem( + "fine-geojson", + JSON.stringify(this._getMapOptions()) + ); + console.log("saved!"); } + clearOverlays() { Modal.confirm({ title: "确定移除所有覆盖物吗?", @@ -124,16 +122,30 @@ export class EditorAction { }); } openGeoJSON() { - // + openUpload({ + accept: ".geojson", + onReady: (content) => { + this._openGeoJSON(JSON.parse(content)); + }, + }); } openProject() { - // + openUpload({ + accept: ".fjd", + onReady: (content) => { + this._openProject(JSON.parse(content)); + }, + }); } showCommand() { // } + private _openGeoJSON(geojson: GeoJSON.FeatureCollection) { + console.log(geojson); + } + private _openProject(options: IMapOptions) { this.mapEditor?.importProject(options); this.dispatch( @@ -144,8 +156,20 @@ export class EditorAction { ); } + private _getMapOptions(): IMapOptions { + const { mapOptions } = this; + return { + ...mapOptions, + center: this.mapEditor?.getCenter(), + zoom: this.mapEditor?.getZoom(), + }; + } + private _bindActions() { this.saveGeoJSON = this.saveGeoJSON.bind(this); + this.saveProject = this.saveProject.bind(this); + this.openGeoJSON = this.openGeoJSON.bind(this); + this.openProject = this.openProject.bind(this); this.createRectangle = this.createRectangle.bind(this); this.createPolygon = this.createPolygon.bind(this); this.createPolyline = this.createPolyline.bind(this); diff --git a/src/store/utils/getGeoJSON.ts b/src/store/utils/getGeoJSON.ts index 36c4597..096bbe1 100644 --- a/src/store/utils/getGeoJSON.ts +++ b/src/store/utils/getGeoJSON.ts @@ -6,70 +6,78 @@ const EarthRadius = 6378137; export function getGeoJSON(state: IMapOptions): GeoJSON.FeatureCollection { // const features: GeoJSON.Feature[] = []; - const { rectangles, polygons, polylines, circles } = state; + const { overlays } = state; - rectangles.forEach((rect) => { - const path = rect.path!; + overlays + .filter((overlay) => overlay.type === OverlayTypes.Rectangle) + .forEach((rect) => { + const path = rect.path!; - features.push({ - type: "Feature", - geometry: { - type: "Polygon", - coordinates: [path], - }, - properties: { - fineType: OverlayTypes.Rectangle, - }, + features.push({ + type: "Feature", + geometry: { + type: "Polygon", + coordinates: [path], + }, + properties: { + fineType: OverlayTypes.Rectangle, + }, + }); }); - }); - polygons.forEach((polygon) => { - const path = polygon.path!; - features.push({ - type: "Feature", - geometry: { - type: "Polygon", - coordinates: [path], - }, - properties: { - fineType: OverlayTypes.Polygon, - }, + overlays + .filter((overlay) => overlay.type === OverlayTypes.Polygon) + .forEach((polygon) => { + const path = polygon.path!; + features.push({ + type: "Feature", + geometry: { + type: "Polygon", + coordinates: [path], + }, + properties: { + fineType: OverlayTypes.Polygon, + }, + }); }); - }); - polylines.forEach((polyline) => { - const path = polyline.path!; - features.push({ - type: "Feature", - geometry: { - type: "LineString", - coordinates: path, - }, - properties: { - fineType: OverlayTypes.Polyline, - }, + overlays + .filter((overlay) => overlay.type === OverlayTypes.Polyline) + .forEach((polyline) => { + const path = polyline.path!; + features.push({ + type: "Feature", + geometry: { + type: "LineString", + coordinates: path, + }, + properties: { + fineType: OverlayTypes.Polyline, + }, + }); }); - }); - circles.forEach((circle) => { - const center = circle.lngLat!; - const radius = circle.radius!; + overlays + .filter((overlay) => overlay.type === OverlayTypes.Circle) + .forEach((circle) => { + const center = circle.lngLat!; + const radius = circle.radius!; - const path = getCirclePath(center, radius); + const path = getCirclePath(center, radius); - features.push({ - type: "Feature", - geometry: { - type: "Polygon", - coordinates: [path], - }, - properties: { - fineType: OverlayTypes.Circle, - center, - radius, - }, + features.push({ + type: "Feature", + geometry: { + type: "Polygon", + coordinates: [path], + }, + properties: { + fineType: OverlayTypes.Circle, + center, + radius, + }, + }); }); - }); return { type: "FeatureCollection", diff --git a/src/utils/index.ts b/src/utils/index.ts index 3f29989..fa7e156 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -3,6 +3,7 @@ import { OverlayTypes } from "@types"; export * from "./hotkeys"; export * from "./download"; +export * from "./upload"; export function getUID() { return uid(12); diff --git a/src/utils/upload.ts b/src/utils/upload.ts new file mode 100644 index 0000000..ac10136 --- /dev/null +++ b/src/utils/upload.ts @@ -0,0 +1,23 @@ +const fileInput: HTMLInputElement = document.createElement("input"); +fileInput.type = "file"; + +type UploadProps = { + accept: string; + onReady: (content: string) => void; +}; + +export function openUpload(props: UploadProps) { + fileInput.accept = props.accept; + fileInput.onchange = () => { + const { files } = fileInput; + if (files == null) return; + const reader = new FileReader(); + reader.onload = function (e) { + const content = e.target?.result?.toString()!; + props.onReady(content); + }; + reader.readAsText(files[0]); + }; + fileInput.files = null; + fileInput.click(); +}