From 2855f7501ed49be914e73a092abf62841bfee413 Mon Sep 17 00:00:00 2001 From: Paul Schreiber Date: Tue, 21 Nov 2023 12:46:28 -0500 Subject: [PATCH 1/9] feat: add isGpxFile helper --- src/gis/gisUtils.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gis/gisUtils.js b/src/gis/gisUtils.js index cf85d59ac..55ece2eb4 100644 --- a/src/gis/gisUtils.js +++ b/src/gis/gisUtils.js @@ -21,6 +21,8 @@ import { isValidLatitude, isValidLongitude } from 'terraso-client-shared/utils'; // From: https://gis.stackexchange.com/a/303362 export const normalizeLongitude = lng => (((lng % 360) + 540) % 360) - 180; +export const isGpxFile = file => file.name.endsWith('.gpx'); + export const isKmlFile = file => file.name.endsWith('.kml') || file.name.endsWith('.kmz'); From 81cadcfafbd7e0953c82489394fc6e014fa09922 Mon Sep 17 00:00:00 2001 From: Paul Schreiber Date: Tue, 21 Nov 2023 12:46:47 -0500 Subject: [PATCH 2/9] feat: add GPX to gisService --- src/gis/gisService.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gis/gisService.js b/src/gis/gisService.js index 958a5c111..49ada3de0 100644 --- a/src/gis/gisService.js +++ b/src/gis/gisService.js @@ -18,7 +18,12 @@ import _ from 'lodash/fp'; import logger from 'terraso-client-shared/monitoring/logger'; import * as terrasoApi from 'terraso-client-shared/terrasoApi/api'; -import { isKmlFile, isShapefile, openGeoJsonFile } from 'gis/gisUtils'; +import { + isGpxFile, + isKmlFile, + isShapefile, + openGeoJsonFile, +} from 'gis/gisUtils'; const generateUrl = name => `https://nominatim.openstreetmap.org/search.php?q=${name}&format=jsonv2`; @@ -52,7 +57,7 @@ const sendFileToTerrasoApi = async file => { }; export const parseFileToGeoJSON = async file => { - return isKmlFile(file) || isShapefile(file) + return isKmlFile(file) || isShapefile(file) || isGpxFile(file) ? sendFileToTerrasoApi(file) : openGeoJsonFile(file); }; From bd1a005106304a7c4f157a1faeec9675c5da62ee Mon Sep 17 00:00:00 2001 From: Paul Schreiber Date: Tue, 21 Nov 2023 12:47:06 -0500 Subject: [PATCH 3/9] feat: add GPX to accepted fle types list --- src/config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config.ts b/src/config.ts index 5d1c6d389..be0e6a01d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -71,6 +71,7 @@ export const MAX_DESCRIPTION_LENGTH = 600; export const MAP_DATA_ACCEPTED_TYPES_NAMES = [ 'GeoJSON', + 'GPX', 'JSON', 'KML', 'KMZ', @@ -85,7 +86,7 @@ const getTypesExtensions = (types: Record) => export const MAP_DATA_ACCEPTED_TYPES = { 'application/json': ['.json', '.geojson'], - 'application/xml': ['.kml'], + 'application/xml': ['gpx', '.kml'], 'application/zip': ['.kmz', '.zip'], }; From 88cbd99cc73c3d93749b3a55f2bed474fd20e2a1 Mon Sep 17 00:00:00 2001 From: Paul Schreiber Date: Tue, 21 Nov 2023 12:47:24 -0500 Subject: [PATCH 4/9] fix: add GPX to file types in test --- .../visualization/components/VisualizationConfigForm.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sharedData/visualization/components/VisualizationConfigForm.test.js b/src/sharedData/visualization/components/VisualizationConfigForm.test.js index d25121682..e453b8ea6 100644 --- a/src/sharedData/visualization/components/VisualizationConfigForm.test.js +++ b/src/sharedData/visualization/components/VisualizationConfigForm.test.js @@ -579,6 +579,7 @@ test.each([ expectedDataEntriesFetchInput: { resourceTypes: [ 'geojson', + 'gpx', 'json', 'kml', 'kmz', From 931bfebcfd269c7cf65246d5d9bf8bd60b9c0120 Mon Sep 17 00:00:00 2001 From: Paul Schreiber Date: Tue, 21 Nov 2023 12:47:32 -0500 Subject: [PATCH 5/9] style: remove trailing whitespace --- .../VisualizationConfigForm.test.js | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sharedData/visualization/components/VisualizationConfigForm.test.js b/src/sharedData/visualization/components/VisualizationConfigForm.test.js index e453b8ea6..dcece8df6 100644 --- a/src/sharedData/visualization/components/VisualizationConfigForm.test.js +++ b/src/sharedData/visualization/components/VisualizationConfigForm.test.js @@ -50,7 +50,7 @@ const TEST_KML = ` Simple placemark - Attached to the ground. Intelligently places itself + Attached to the ground. Intelligently places itself at the height of the underlying terrain. -122.0822035425683,37.42228990140251,0 @@ -61,11 +61,11 @@ const TEST_KML = ` - -77.05788457660967,38.87253259892824,100 - -77.05465973756702,38.87291016281703,100 - -77.05315536854791,38.87053267794386,100 - -77.05552622493516,38.868757801256,100 - -77.05844056290393,38.86996206506943,100 + -77.05788457660967,38.87253259892824,100 + -77.05465973756702,38.87291016281703,100 + -77.05315536854791,38.87053267794386,100 + -77.05552622493516,38.868757801256,100 + -77.05844056290393,38.86996206506943,100 -77.05788457660967,38.87253259892824,100 @@ -73,11 +73,11 @@ const TEST_KML = ` - -77.05668055019126,38.87154239798456,100 - -77.05542625960818,38.87167890344077,100 - -77.05485125901024,38.87076535397792,100 - -77.05577677433152,38.87008686581446,100 - -77.05691162017543,38.87054446963351,100 + -77.05668055019126,38.87154239798456,100 + -77.05542625960818,38.87167890344077,100 + -77.05485125901024,38.87076535397792,100 + -77.05577677433152,38.87008686581446,100 + -77.05691162017543,38.87054446963351,100 -77.05668055019126,38.87154239798456,100 From 0f42a8ec4342693a168ea458a65877a49effa077 Mon Sep 17 00:00:00 2001 From: Paul Schreiber Date: Tue, 28 Nov 2023 14:33:52 -0500 Subject: [PATCH 6/9] fix: use correct MIME type for GPX --- src/config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config.ts b/src/config.ts index be0e6a01d..1f4d5f247 100644 --- a/src/config.ts +++ b/src/config.ts @@ -86,7 +86,8 @@ const getTypesExtensions = (types: Record) => export const MAP_DATA_ACCEPTED_TYPES = { 'application/json': ['.json', '.geojson'], - 'application/xml': ['gpx', '.kml'], + 'application/gpx': ['.gpx'], + 'application/xml': ['.kml'], 'application/zip': ['.kmz', '.zip'], }; From 769cba37110a9aefa9c1dbe8d92cf80e216ad3c6 Mon Sep 17 00:00:00 2001 From: Paul Schreiber Date: Tue, 28 Nov 2023 15:01:58 -0500 Subject: [PATCH 7/9] test: add GPX file extension to resourceTypes list --- .../visualization/components/VisualizationConfigForm.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sharedData/visualization/components/VisualizationConfigForm.test.js b/src/sharedData/visualization/components/VisualizationConfigForm.test.js index dcece8df6..ac8cd873b 100644 --- a/src/sharedData/visualization/components/VisualizationConfigForm.test.js +++ b/src/sharedData/visualization/components/VisualizationConfigForm.test.js @@ -652,6 +652,7 @@ test.each([ expectedDataEntriesFetchInput: { resourceTypes: [ 'geojson', + 'gpx', 'json', 'kml', 'kmz', From 0858ca226e0d8d1cfa17e072865892cc9529f5da Mon Sep 17 00:00:00 2001 From: Paul Schreiber Date: Tue, 28 Nov 2023 15:16:21 -0500 Subject: [PATCH 8/9] fix: remove GPX from DOCUMENT_ACCEPTED_TYPES as it's now in MAP_DATA_ACCEPTED_TYPES --- src/config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/config.ts b/src/config.ts index 1f4d5f247..28e2b8658 100644 --- a/src/config.ts +++ b/src/config.ts @@ -113,7 +113,6 @@ export const DOCUMENT_ACCEPTED_TYPES = { 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': [ '.docx', ], - 'application/xml': ['.gpx'], }; export const MEDIA_ACCEPTED_TYPES = { From 3da74872ce9ef0dcab87f916be3242ad8e610720 Mon Sep 17 00:00:00 2001 From: Paul Schreiber Date: Tue, 28 Nov 2023 15:16:32 -0500 Subject: [PATCH 9/9] test: update test strings to include GPX --- .../BoundaryStepNewBoundariesFile.test.js | 6 ++--- .../LandscapeForm/BoundaryStepUpdate.test.js | 24 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/landscape/components/LandscapeForm/BoundaryStepNewBoundariesFile.test.js b/src/landscape/components/LandscapeForm/BoundaryStepNewBoundariesFile.test.js index 3419d0eb1..5d2e565d9 100644 --- a/src/landscape/components/LandscapeForm/BoundaryStepNewBoundariesFile.test.js +++ b/src/landscape/components/LandscapeForm/BoundaryStepNewBoundariesFile.test.js @@ -189,13 +189,13 @@ test('LandscapeNew: Save from GeoJSON', async () => { await act(async () => fireEvent.click( screen.getByRole('button', { - name: 'Upload a map file. Accepted file formats: GeoJSON, JSON, KML, KMZ, ESRI Shapefile', + name: 'Upload a map file. Accepted file formats: GeoJSON, GPX, JSON, KML, KMZ, ESRI Shapefile', }) ) ); const dropzone = screen.getByRole('button', { - name: 'Select File Accepted file formats: *.geojson, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB', + name: 'Select File Accepted file formats: *.geojson, *.gpx, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB', }); const file = new File([GEOJSON_STRING], 'test.json', { @@ -219,7 +219,7 @@ test('LandscapeNew: Save from GeoJSON', async () => { await waitFor(async () => { expect( await screen.findByRole('button', { - name: 'Select File Accepted file formats: *.geojson, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB test.json 804 B', + name: 'Select File Accepted file formats: *.geojson, *.gpx, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB test.json 804 B', }) ).toBeInTheDocument(); }); diff --git a/src/landscape/components/LandscapeForm/BoundaryStepUpdate.test.js b/src/landscape/components/LandscapeForm/BoundaryStepUpdate.test.js index 97672a529..7c4bee3e0 100644 --- a/src/landscape/components/LandscapeForm/BoundaryStepUpdate.test.js +++ b/src/landscape/components/LandscapeForm/BoundaryStepUpdate.test.js @@ -90,13 +90,13 @@ const testGeoJsonParsing = (file, errorMessage) => async () => { await act(async () => fireEvent.click( screen.getByRole('button', { - name: 'Upload a map file. Accepted file formats: GeoJSON, JSON, KML, KMZ, ESRI Shapefile', + name: 'Upload a map file. Accepted file formats: GeoJSON, GPX, JSON, KML, KMZ, ESRI Shapefile', }) ) ); const dropzone = screen.getByRole('button', { - name: 'Select File Accepted file formats: *.geojson, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB', + name: 'Select File Accepted file formats: *.geojson, *.gpx, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB', }); const data = { @@ -246,13 +246,13 @@ test('LandscapeBoundaries: Select file', async () => { await act(async () => fireEvent.click( screen.getByRole('button', { - name: 'Upload a map file. Accepted file formats: GeoJSON, JSON, KML, KMZ, ESRI Shapefile', + name: 'Upload a map file. Accepted file formats: GeoJSON, GPX, JSON, KML, KMZ, ESRI Shapefile', }) ) ); const dropzone = screen.getByRole('button', { - name: 'Select File Accepted file formats: *.geojson, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB', + name: 'Select File Accepted file formats: *.geojson, *.gpx, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB', }); const file = new File([GEOJSON], 'test.json', { type: 'application/json' }); @@ -272,7 +272,7 @@ test('LandscapeBoundaries: Select file', async () => { await act(async () => fireEvent.drop(dropzone, data)); expect( await screen.findByRole('button', { - name: 'Select File Accepted file formats: *.geojson, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB test.json 804 B', + name: 'Select File Accepted file formats: *.geojson, *.gpx, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB test.json 804 B', }) ).toBeInTheDocument(); }); @@ -299,7 +299,7 @@ test('LandscapeBoundaries: Show back', async () => { await act(async () => fireEvent.click( screen.getByRole('button', { - name: 'Upload a map file. Accepted file formats: GeoJSON, JSON, KML, KMZ, ESRI Shapefile', + name: 'Upload a map file. Accepted file formats: GeoJSON, GPX, JSON, KML, KMZ, ESRI Shapefile', }) ) ); @@ -355,13 +355,13 @@ test('LandscapeBoundaries: Save GeoJSON', async () => { await act(async () => fireEvent.click( screen.getByRole('button', { - name: 'Upload a map file. Accepted file formats: GeoJSON, JSON, KML, KMZ, ESRI Shapefile', + name: 'Upload a map file. Accepted file formats: GeoJSON, GPX, JSON, KML, KMZ, ESRI Shapefile', }) ) ); const dropzone = screen.getByRole('button', { - name: 'Select File Accepted file formats: *.geojson, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB', + name: 'Select File Accepted file formats: *.geojson, *.gpx, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB', }); const file = new File([GEOJSON], 'test.json', { type: 'application/json' }); @@ -381,7 +381,7 @@ test('LandscapeBoundaries: Save GeoJSON', async () => { await act(async () => fireEvent.drop(dropzone, data)); expect( await screen.findByRole('button', { - name: 'Select File Accepted file formats: *.geojson, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB test.json 804 B', + name: 'Select File Accepted file formats: *.geojson, *.gpx, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB test.json 804 B', }) ).toBeInTheDocument(); @@ -471,13 +471,13 @@ test('LandscapeBoundaries: Save KML', async () => { await act(async () => fireEvent.click( screen.getByRole('button', { - name: 'Upload a map file. Accepted file formats: GeoJSON, JSON, KML, KMZ, ESRI Shapefile', + name: 'Upload a map file. Accepted file formats: GeoJSON, GPX, JSON, KML, KMZ, ESRI Shapefile', }) ) ); const dropzone = screen.getByRole('button', { - name: 'Select File Accepted file formats: *.geojson, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB', + name: 'Select File Accepted file formats: *.geojson, *.gpx, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB', }); const dataTransfer = { @@ -497,7 +497,7 @@ test('LandscapeBoundaries: Save KML', async () => { await waitFor(async () => { expect( screen.getByRole('button', { - name: 'Select File Accepted file formats: *.geojson, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB valid.kml 406 B', + name: 'Select File Accepted file formats: *.geojson, *.gpx, *.json, *.kml, *.kmz, *.zip Maximum file size: 10 MB valid.kml 406 B', }) ).toBeInTheDocument(); });