Skip to content

Commit

Permalink
Merge pull request #1128 from geoadmin/fix-pb-732-profile-track-parti…
Browse files Browse the repository at this point in the history
…ally-outside-bounds

PB-732: fix open profile track partially outside bounds
  • Loading branch information
sommerfe authored Nov 18, 2024
2 parents ab8c068 + a842ce2 commit e57a443
Show file tree
Hide file tree
Showing 9 changed files with 243 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/api/profile/profile.api.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import proj4 from 'proj4'
import ElevationProfile from '@/api/profile/ElevationProfile.class'
import ElevationProfileSegment from '@/api/profile/ElevationProfileSegment.class'
import { getServiceAltiBaseUrl } from '@/config/baseUrl.config'
import OutOfBoundsError from '@/modules/menu/components/advancedTools/ImportFile/parser/errors/OutOfBoundsError.error'
import { LV95 } from '@/utils/coordinates/coordinateSystems'
import { removeZValues, unwrapGeometryCoordinates } from '@/utils/coordinates/coordinateUtils.js'
import log from '@/utils/logging'
Expand Down Expand Up @@ -198,6 +199,7 @@ export default async (profileCoordinates, projection) => {
proj4(projection.epsg, LV95.epsg, coordinate)
)
}

let coordinateChunks = splitIfTooManyPoints(
LV95.bounds.splitIfOutOfBounds(coordinatesInLV95)
)
Expand All @@ -209,6 +211,13 @@ export default async (profileCoordinates, projection) => {
'could_not_generate_profile'
)
}
if (coordinateChunks.some((chunk) => !chunk.isWithinBounds)) {
log.error('Some chunks are out of bounds, no profile data could be fetched')
throw new OutOfBoundsError(
'Some parts are out of bounds, no profile data could be fetched',
'parts_out_of_bounds'
)
}
let lastCoordinate = null
let lastDist = 0
const requestsForChunks = coordinateChunks.map((chunk) =>
Expand Down
1 change: 1 addition & 0 deletions src/modules/i18n/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@
"parse_failed": "Parsing-Fehler",
"parse_succeeded": "Laden erfolgreich",
"parsing_file": "Laden...",
"parts_out_of_bounds": "Einige Teile sind nicht im zulässigen Bereich, es konnten keine Profildaten abgerufen werden.",
"paste_url": "URL einfügen",
"permalink": "Permalink",
"plz": "PLZ",
Expand Down
1 change: 1 addition & 0 deletions src/modules/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@
"parse_failed": "Parsing error!",
"parse_succeeded": "Loading OK!",
"parsing_file": "Loading file...",
"parts_out_of_bounds": "Some parts are out of bounds, no profile data could be fetched.",
"paste_url": "Paste URL",
"permalink": "Permalink",
"plz": "ZIP",
Expand Down
1 change: 1 addition & 0 deletions src/modules/i18n/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@
"parse_failed": "Erreur de parsing!",
"parse_succeeded": "Chargement OK!",
"parsing_file": "Chargement du fichier...",
"parts_out_of_bounds": "Certaines parties sont hors limites, aucune donnée de profil n'a pu être récupérée.",
"paste_url": "Coller URL",
"permalink": "Permalien",
"plz": "NPA",
Expand Down
1 change: 1 addition & 0 deletions src/modules/i18n/locales/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@
"parse_failed": "Errore di parsing!",
"parse_succeeded": "Caricamento OK!",
"parsing_file": "Caricamento del file...",
"parts_out_of_bounds": "Alcune parti sono fuori dai limiti, non è stato possibile recuperare i dati del profilo.",
"paste_url": "Incolla URL",
"permalink": "Permalink",
"plz": "NPA",
Expand Down
1 change: 1 addition & 0 deletions src/modules/i18n/locales/rm.json
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@
"parsing_file": "La datoteca vegn chargiada",
"paste_url": "Encollar l'URL",
"permalink": "Permalink",
"parts_out_of_bounds": "Tschertas parts n'èn betg limitadas, naginas datas dal profil na pon vegnir registradas.",
"plz": "NP",
"popup_blocked": "Il browser na permetta betg d'avrir ina nova fanestra (pop-up). Adattai p.pl. ils parameters da segirezza da Voss computer.",
"position": "Posiziun",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/** Coordinates or extent out of bounds error */
export default class OutOfBoundsError extends Error {
constructor(message) {
constructor(message, messageKey) {
super(message)
this.name = 'OutOfBoundsError'
this.messageKey = messageKey
}
}
178 changes: 178 additions & 0 deletions tests/cypress/fixtures/import-tool/external-gpx-file-out-of-bounds.gpx
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?>
<gpx creator="StravaGPX" version="1.1" xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<metadata>
<name>4-Kitzbühel</name>
<author>
<name>Marcel Wyss &gt; wyss-training.ch</name>
<link href="https://www.strava.com/athletes/2714266"/>
</author>
<copyright author="OpenStreetMap contributors">
<year>2020</year>
<license>https://www.openstreetmap.org/copyright</license>
</copyright>
<link href="https://www.strava.com/routes/3230981029618534522"/>
</metadata>
<trk>
<name>4-Kitzbühel</name>
<link href="https://www.strava.com/routes/3230981029618534522"/>
<type>cycling</type>
<trkseg>
<trkpt lat="47.277480000000004" lon="11.400970000000001">
<ele>574.1200000000001</ele>
</trkpt>
<trkpt lat="47.27790000189449" lon="11.40164499450179">
<ele>574.1800000000001</ele>
</trkpt>
<trkpt lat="47.27832" lon="11.402320000000001">
<ele>574.0600000000001</ele>
</trkpt>
<trkpt lat="47.27832" lon="11.402310000000002">
<ele>574.0600000000001</ele>
</trkpt>
<trkpt lat="47.27863000102672" lon="11.402814996906823">
<ele>574.1</ele>
</trkpt>
<trkpt lat="47.278940000000006" lon="11.40332">
<ele>574.2400000000001</ele>
</trkpt>
<trkpt lat="47.279270000000004" lon="11.40409">
<ele>574.57</ele>
</trkpt>
<trkpt lat="47.27938" lon="11.404240000000001">
<ele>574.58</ele>
</trkpt>
<trkpt lat="47.279590000000006" lon="11.40441">
<ele>575.3900000000001</ele>
</trkpt>
<trkpt lat="47.279740000000004" lon="11.404480000000001">
<ele>575.3900000000001</ele>
</trkpt>
<trkpt lat="47.280235000660355" lon="11.404824996871628">
<ele>575.61</ele>
</trkpt>
<trkpt lat="47.280730000000005" lon="11.405170000000002">
<ele>575.62</ele>
</trkpt>
<trkpt lat="47.280860000000004" lon="11.40526">
<ele>575.49</ele>
</trkpt>
<trkpt lat="47.280840000000005" lon="11.405380000000001">
<ele>575.04</ele>
</trkpt>
<trkpt lat="47.28088" lon="11.40557">
<ele>574.85</ele>
</trkpt>
<trkpt lat="47.28097" lon="11.405790000000001">
<ele>574.5</ele>
</trkpt>
<trkpt lat="47.281060000000004" lon="11.40586">
<ele>574.38</ele>
</trkpt>
<trkpt lat="47.28117" lon="11.40634">
<ele>573.43</ele>
</trkpt>
<trkpt lat="47.281200000000005" lon="11.406640000000001">
<ele>573.23</ele>
</trkpt>
<trkpt lat="47.281180000000006" lon="11.407000000000002">
<ele>572.8000000000001</ele>
</trkpt>
<trkpt lat="47.28107000000001" lon="11.40756">
<ele>572.43</ele>
</trkpt>
<trkpt lat="47.280950000000004" lon="11.40793">
<ele>572.3600000000001</ele>
</trkpt>
<trkpt lat="47.280770000000004" lon="11.408700000000001">
<ele>572.2400000000001</ele>
</trkpt>
<trkpt lat="47.280680000000004" lon="11.408830000000002">
<ele>572.21</ele>
</trkpt>
<trkpt lat="47.28051000261443" lon="11.409605002481078">
<ele>572.1</ele>
</trkpt>
<trkpt lat="47.28034" lon="11.410380000000002">
<ele>572.1</ele>
</trkpt>
<trkpt lat="47.280110021205466" lon="11.41148401919535">
<ele>572.1400000000001</ele>
</trkpt>
<trkpt lat="47.27988003180817" lon="11.412588028792667">
<ele>571.8199999999999</ele>
</trkpt>
<trkpt lat="47.279650031808266" lon="11.413692028791665">
<ele>571.79</ele>
</trkpt>
<trkpt lat="47.27942002120593" lon="11.414796019192066">
<ele>571.6300000000001</ele>
</trkpt>
<trkpt lat="47.27919000000001" lon="11.4159">
<ele>571.69</ele>
</trkpt>
<trkpt lat="47.27922" lon="11.415980000000001">
<ele>571.69</ele>
</trkpt>
<trkpt lat="47.27906" lon="11.416780000000001">
<ele>571.47</ele>
</trkpt>
<trkpt lat="47.27881001089974" lon="11.417900010639354">
<ele>571.6800000000001</ele>
</trkpt>
<trkpt lat="47.27856001088729" lon="11.419020010694933">
<ele>571.4800000000001</ele>
</trkpt>
<trkpt lat="47.278310000000005" lon="11.420140000000002">
<ele>570.89</ele>
</trkpt>
<trkpt lat="47.27807000000001" lon="11.421360000000002">
<ele>570.4200000000001</ele>
</trkpt>
<trkpt lat="47.27792" lon="11.42196">
<ele>570.2600000000001</ele>
</trkpt>
<trkpt lat="47.277680000000004" lon="11.42276">
<ele>570.25</ele>
</trkpt>
<trkpt lat="47.277296018250794" lon="11.423784029705716">
<ele>570.0200000000001</ele>
</trkpt>
<trkpt lat="47.27691202737953" lon="11.42480804454892">
<ele>569.79</ele>
</trkpt>
<trkpt lat="47.276528027386476" lon="11.425832044529677">
<ele>569.76</ele>
</trkpt>
<trkpt lat="47.27614401827187" lon="11.426856029648052">
<ele>569.85</ele>
</trkpt>
<trkpt lat="47.275760000000005" lon="11.427880000000002">
<ele>569.7500000000001</ele>
</trkpt>
<trkpt lat="47.27554000214517" lon="11.428580002866095">
<ele>569.76</ele>
</trkpt>
<trkpt lat="47.27532" lon="11.42928">
<ele>569.5400000000001</ele>
</trkpt>
<trkpt lat="47.274950000000004" lon="11.430330000000001">
<ele>569.2400000000001</ele>
</trkpt>
<trkpt lat="47.274840000000005" lon="11.430570000000001">
<ele>569.21</ele>
</trkpt>
<trkpt lat="47.27474" lon="11.43082">
<ele>569.1800000000001</ele>
</trkpt>
<trkpt lat="47.27434500107853" lon="11.430309996125045">
<ele>570.16</ele>
</trkpt>
<trkpt lat="47.273950000000006" lon="11.4298">
<ele>569.08</ele>
</trkpt>
<trkpt lat="47.27411000000001" lon="11.429390000000001">
<ele>569.0200000000001</ele>
</trkpt>
</trkseg>
</trk>
</gpx>
49 changes: 49 additions & 0 deletions tests/cypress/tests-e2e/importToolFile.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -780,5 +780,54 @@ describe('The Import File Tool', () => {
cy.get('[data-cy="profile-segment-button-0"]').should('be.visible')
cy.get('[data-cy="profile-segment-button-1"]').should('be.visible')
cy.get('[data-cy="profile-segment-button-2"]').should('be.visible')

// Import file partially out of bounds
cy.log('Test import file partially out of bounds')
const gpxOutOfBoundsFileName = 'external-gpx-file-out-of-bounds.gpx'
const gpxOutOfBoundsFileFixture = `import-tool/${gpxOutOfBoundsFileName}`

cy.reload()
cy.waitMapIsReady()
cy.wait(['@headGpxNoCORS', '@proxyfiedGpxNoCORS'])
cy.openMenuIfMobile()
cy.get(
`[data-cy^="button-remove-layer-GPX|${validMultiSegmentOnlineUrl}-"]:visible`
).click()
cy.readStoreValue('state.layers.activeLayers').should('be.empty')
cy.get('[data-cy="menu-tray-tool-section"]:visible').click()
cy.get('[data-cy="menu-advanced-tools-import-file"]:visible').click()

// the menu should be automatically closed on opening import tool box
cy.get('[data-cy="menu-tray"]').should('not.be.visible')
cy.get('[data-cy="import-file-content"]').should('be.visible')
cy.get('[data-cy="import-file-online-content"]').should('be.visible')

const validOutOfBoundsOnlineUrl = 'https://example.com/valid-out-of-bounds-gpx-file.gpx'
createHeadAndGetIntercepts(
validOutOfBoundsOnlineUrl,
'GpxFile',
{
fixture: gpxOutOfBoundsFileFixture,
},
{
statusCode: 200,
headers: { 'Content-Type': 'application/gpx+xml' },
}
)
cy.openMenuIfMobile()
cy.get('[data-cy="text-input"]:visible').type(validOutOfBoundsOnlineUrl)
cy.get('[data-cy="import-file-load-button"]:visible').click()

cy.closeMenuIfMobile()

cy.get('[data-cy="window-close"]').click()
cy.get('[data-cy="ol-map"]').click(150, 250)

cy.log('Check that the error is displayed in the profile popup')
cy.get('[data-cy="show-profile"]').click()
cy.get('[data-cy="profile-popup-content"]').should('be.visible')
cy.get('[data-cy="profile-error-message"]').contains(
'Some parts are out of bounds, no profile data could be fetched'
)
})
})

0 comments on commit e57a443

Please sign in to comment.