diff --git a/src/map/index.ts b/src/map/index.ts index 2d1ffc9..0b18da2 100644 --- a/src/map/index.ts +++ b/src/map/index.ts @@ -134,7 +134,8 @@ export class MapEditor extends Emitter { const evt: any = { id, type }; if (type === OverlayTypes.Circle) { const circle = target as AMap.Circle; - evt.lngLat = circle.getCenter(); + const { lng, lat } = circle.getCenter(); + evt.lngLat = [lng, lat]; evt.radius = circle.getRadius(); } else { evt.path = getOverlayPaths(target, type); diff --git a/src/store/GlobalController.ts b/src/store/GlobalController.ts index fc4e265..a32112f 100644 --- a/src/store/GlobalController.ts +++ b/src/store/GlobalController.ts @@ -3,6 +3,7 @@ import { registerHotkey } from "@utils"; import { getGeoJSON } from "./utils/getGeoJSON"; import { OverlayTypes } from "../types/enum"; import { EditorAction } from "./actions"; +import { downloadJSON } from "../utils/download"; interface IGlobalController { saveGeoJSON: () => void; saveProject: () => void; @@ -33,7 +34,7 @@ export class GlobelController implements IGlobalController { saveGeoJSON() { const geojson = getGeoJSON(this.mapState); - console.log(geojson); + downloadJSON(geojson, "fine.geojson"); } saveProject() { diff --git a/src/store/utils/getGeoJSON.ts b/src/store/utils/getGeoJSON.ts index 5740958..1a70bff 100644 --- a/src/store/utils/getGeoJSON.ts +++ b/src/store/utils/getGeoJSON.ts @@ -1,5 +1,8 @@ +import { OverlayTypes } from "../../types/enum"; import { IMapState } from "../type"; +const EarthRadius = 6378137; + export function getGeoJSON(state: IMapState): GeoJSON.FeatureCollection { // const features: GeoJSON.Feature[] = []; @@ -11,10 +14,60 @@ export function getGeoJSON(state: IMapState): GeoJSON.FeatureCollection { features.push({ type: "Feature", geometry: { - type: "MultiPolygon", - coordinates: [[path]], + 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, + }, + }); + }); + + polylines.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!; + + const path = getCirclePath(center, radius); + + features.push({ + type: "Feature", + geometry: { + type: "Polygon", + coordinates: [path], + }, + properties: { + fineType: OverlayTypes.Circle, + center, + radius, }, - properties: {}, }); }); @@ -23,3 +76,31 @@ export function getGeoJSON(state: IMapState): GeoJSON.FeatureCollection { features, }; } +// 计算圆形overlay的path +function getCirclePath(center: GeoJSON.Position, radius: number) { + const path: GeoJSON.Position[] = []; + + let i = 0, + total = 20, + angle = 0; + while (i < total) { + angle = (i / total) * Math.PI * 2; + path.push(getLngLatWithDistance(center, radius, angle)); + i++; + } + return path; +} + +// todo: 转换并不是很准确, 需要好好研究一下. +function getLngLatWithDistance( + center: GeoJSON.Position, + distance: number, + direction: number +) { + distance /= EarthRadius; + const [lng, lat] = center; + return [ + lng + distance * Math.cos(direction), + lat + distance * Math.sin(direction), + ]; +} diff --git a/src/utils/download.ts b/src/utils/download.ts new file mode 100644 index 0000000..f95836b --- /dev/null +++ b/src/utils/download.ts @@ -0,0 +1,11 @@ +export function downloadJSON(json: any, fileName: string) { + download(JSON.stringify(json), fileName); +} + +export function download(content: string, fileName: string) { + const a = document.createElement("a"); + const blob = new Blob([content], { type: "text/json" }); + a.href = URL.createObjectURL(blob); + a.download = fileName; + a.click(); +}