From 0c01879431f22299d0c04a6ca1d54f07612822f1 Mon Sep 17 00:00:00 2001 From: RoXoM Date: Sat, 14 Oct 2023 21:57:12 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=A0=E5=85=A5=E7=9A=84=20coods=20?= =?UTF-8?q?=E6=98=AF=20line=20=E6=A0=BC=E5=BC=8F=E6=97=B6=E4=B9=9F?= =?UTF-8?q?=E4=BC=9A=E5=88=A0=E9=99=A4=E6=9C=80=E5=90=8E=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coordsOfGeoJSON2AMapPolygonPath.test.ts | 27 ++++++ src/helpers/__tests__/geoJSONHelper.test.ts | 84 +++++++++++++++++-- .../coordsOfGeoJSON2AMapPolygonPath.ts | 8 +- src/helpers/geoJSONHelper.ts | 18 +++- 4 files changed, 126 insertions(+), 11 deletions(-) create mode 100644 src/helpers/__tests__/coordsOfGeoJSON2AMapPolygonPath.test.ts diff --git a/src/helpers/__tests__/coordsOfGeoJSON2AMapPolygonPath.test.ts b/src/helpers/__tests__/coordsOfGeoJSON2AMapPolygonPath.test.ts new file mode 100644 index 0000000..f9ac43a --- /dev/null +++ b/src/helpers/__tests__/coordsOfGeoJSON2AMapPolygonPath.test.ts @@ -0,0 +1,27 @@ +import coordsOfGeoJSON2AMapPolygonPath from '../coordsOfGeoJSON2AMapPolygonPath'; + +describe('coordsOfGeoJSON2AMapPolygonPath', () => { + test('should remove the last position point when it is a ring', () => { + const input: GeoJSON.Position[] = [[1, 2], [3, 4], [5, 6], [1, 2]]; + const output: GeoJSON.Position[] = [[1, 2], [3, 4], [5, 6]]; + expect(coordsOfGeoJSON2AMapPolygonPath(input)).toEqual(output); + }); + + test('should not remove the last position point when it is not a ring line', () => { + const input: GeoJSON.Position[] = [[1, 2], [3, 4], [5, 6]]; + const output: GeoJSON.Position[] = [[1, 2], [3, 4], [5, 6]]; + expect(coordsOfGeoJSON2AMapPolygonPath(input)).toEqual(output); + }); + + test('should convert GeoJSON.Polygon coordinates', () => { + const input: GeoJSON.Polygon['coordinates'] = [[[1, 2], [3, 4], [5, 6], [1, 2]]]; + const output: GeoJSON.Polygon['coordinates'] = [[[1, 2], [3, 4], [5, 6]]]; + expect(coordsOfGeoJSON2AMapPolygonPath(input)).toEqual(output); + }); + + test('should convert GeoJSON.MultiPolygon coordinates', () => { + const input: GeoJSON.MultiPolygon['coordinates'] = [[[[1, 2], [3, 4], [5, 6], [1, 2]]]]; + const output: GeoJSON.MultiPolygon['coordinates'] = [[[[1, 2], [3, 4], [5, 6]]]]; + expect(coordsOfGeoJSON2AMapPolygonPath(input)).toEqual(output); + }); +}); diff --git a/src/helpers/__tests__/geoJSONHelper.test.ts b/src/helpers/__tests__/geoJSONHelper.test.ts index b82b3ac..9f71106 100644 --- a/src/helpers/__tests__/geoJSONHelper.test.ts +++ b/src/helpers/__tests__/geoJSONHelper.test.ts @@ -1,4 +1,9 @@ -import { isPosition, isLineCoords } from '../geoJSONHelper'; +import { + isPosition, + isLineCoords, + isSamePosition, + isRingLineCoords, +} from '../geoJSONHelper'; describe('isPosition', () => { test('should return true for valid position', () => { @@ -20,18 +25,81 @@ describe('isPosition', () => { describe('isLineCoords', () => { test('should return true for valid line coordinates', () => { - const validLineCoords: GeoJSON.Position[] = [[1, 2], [3, 4], [5, 6]]; + const validLineCoords1: GeoJSON.Position[] = [[1, 2], [3, 4]]; + const validLineCoords2: GeoJSON.Position[] = [[1, 2], [3, 4], [5, 6]]; - const result = isLineCoords(validLineCoords); - - expect(result).toBe(true); + expect(isLineCoords(validLineCoords1)).toBe(true); + expect(isLineCoords(validLineCoords2)).toBe(true); }); test('should return false for invalid line coordinates', () => { - const invalidLineCoords = [[1, 2], [3, '4'], [5, 6]]; + const invalidLineCoords1 = [[1, 2], [3, '4'], [5, 6]]; + const invalidLineCoords2 = [[0, 0]]; + + expect(isLineCoords(invalidLineCoords1)).toBe(false); + expect(isLineCoords(invalidLineCoords2)).toBe(false); + }); +}); - const result = isLineCoords(invalidLineCoords); +describe('isSamePosition', () => { + it('should return true if the positions are equal', () => { + const positionA: GeoJSON.Position = [0, 0]; - expect(result).toBe(false); + expect(isSamePosition(positionA, positionA)).toBe(true); + }); + + it('should return true if the positions are equivalent', () => { + const positionA: GeoJSON.Position = [0, 0]; + const positionB: GeoJSON.Position = [0, 0]; + + expect(isSamePosition(positionA, positionB)).toBe(true); + }); + + it('should throw an error if the positions are invalid', () => { + const positionA: GeoJSON.Position = [0, 0]; + const positionB: GeoJSON.Position = [null, '0'] as any; + + expect(() => isSamePosition(positionA, positionB)).toThrow('invalid position'); + expect(() => isSamePosition(positionB, positionA)).toThrow('invalid position'); + }); +}); + +describe('isRingLineCoords', () => { + it('should return false if coords are not line coordinates', () => { + const coords = [ + [0, 0], + [1, 1], + [2, 2], + ]; + expect(isRingLineCoords(coords)).toBe(false); + }); + + it('should return false if coords length is less than 4', () => { + const coords = [ + [0, 0], + [1, 1], + [2, 2], + ]; + expect(isRingLineCoords(coords)).toBe(false); + }); + + it('should return false if first and last positions are not the same', () => { + const coords = [ + [0, 0], + [1, 1], + [2, 2], + [3, 3], + ]; + expect(isRingLineCoords(coords)).toBe(false); + }); + + it('should return true if coords are line coordinates, length is greater than 3, and first and last positions are the same', () => { + const coords = [ + [0, 0], + [1, 1], + [2, 2], + [0, 0], + ]; + expect(isRingLineCoords(coords)).toBe(true); }); }); diff --git a/src/helpers/coordsOfGeoJSON2AMapPolygonPath.ts b/src/helpers/coordsOfGeoJSON2AMapPolygonPath.ts index 29340e3..413e3fc 100644 --- a/src/helpers/coordsOfGeoJSON2AMapPolygonPath.ts +++ b/src/helpers/coordsOfGeoJSON2AMapPolygonPath.ts @@ -1,4 +1,4 @@ -import { isLineCoords } from './geoJSONHelper'; +import { isLineCoords, isRingLineCoords } from './geoJSONHelper'; const coordsOfGeoJSONRingLine2AMapPolygonPath = (coords: GeoJSON.Position[]): typeof coords => { const len = coords.length; @@ -12,8 +12,12 @@ const coordsOfGeoJSONRingLine2AMapPolygonPath = (coords: GeoJSON.Position[]): ty const coordsOfGeoJSON2AMapPolygonPath = ( coords: GeoJSON.Position[] | GeoJSON.Polygon['coordinates'] | GeoJSON.MultiPolygon['coordinates'], ): typeof coords => { + if (isRingLineCoords(coords as GeoJSON.Position[])) { + return coordsOfGeoJSONRingLine2AMapPolygonPath(coords as GeoJSON.Position[]); + } + if (isLineCoords(coords)) { - return coordsOfGeoJSONRingLine2AMapPolygonPath(coords); + return coords; } // trick way diff --git a/src/helpers/geoJSONHelper.ts b/src/helpers/geoJSONHelper.ts index 3ba54be..b4e6d52 100644 --- a/src/helpers/geoJSONHelper.ts +++ b/src/helpers/geoJSONHelper.ts @@ -7,4 +7,20 @@ export const isPosition = (pos: any): pos is GeoJSON.Position => ( export const isLineCoords = ( line: any, -): line is GeoJSON.Position[] => Array.isArray(line) && line.every(isPosition); +): line is GeoJSON.Position[] => Array.isArray(line) && line.length >= 2 && line.every(isPosition); + +export const isSamePosition = (positionA: GeoJSON.Position, positionB: GeoJSON.Position) => { + if (!isPosition(positionA) || !isPosition(positionB)) { + throw Error('invalid position'); + } + + return positionA === positionB || positionA.toString() === positionB.toString(); +}; + +export const isRingLineCoords = (coords: GeoJSON.Position[]) => { + if (!isLineCoords(coords)) return false; + const coordsLen = coords.length; + const firstPosition = coords[0]; + const lastPosition = coords[coordsLen - 1]; + return coordsLen > 3 && isSamePosition(firstPosition, lastPosition); +};