-
Notifications
You must be signed in to change notification settings - Fork 15
PB-101 : zoom on GPX extent on file added #626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
import AbstractLayer from '@/api/layers/AbstractLayer.class' | ||
import ExternalGroupOfLayers from '@/api/layers/ExternalGroupOfLayers.class' | ||
import LayerTypes from '@/api/layers/LayerTypes.enum' | ||
import { getKmlExtent, getKmlExtentForProjection, parseKmlName } from '@/utils/kmlUtils' | ||
import { getExtentForProjection } from '@/utils/extentUtils.js' | ||
import { getKmlExtent, parseKmlName } from '@/utils/kmlUtils' | ||
import { ActiveLayerConfig } from '@/utils/layerUtils' | ||
import log from '@/utils/logging' | ||
|
||
|
@@ -465,7 +466,7 @@ const actions = { | |
if (!extent) { | ||
updatedLayer.errorKey = 'kml_gpx_file_empty' | ||
updatedLayer.hasError = true | ||
} else if (!getKmlExtentForProjection(rootState.position.projection, extent)) { | ||
} else if (!getExtentForProjection(rootState.position.projection, extent)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've just seen that in your previous PR for GPX support it seems that you don't support GPX after a reload as the GPX data will not be set (no store subscriber to get the GPX data from url). This means that you would need to add that support and also need a similar logic in the layer store as here and have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's something I wanted to do in another PR |
||
updatedLayer.errorKey = 'kml_gpx_file_out_of_bounds' | ||
updatedLayer.hasError = true | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { expect } from 'chai' | ||
import proj4 from 'proj4' | ||
import { describe, it } from 'vitest' | ||
|
||
import { LV95, WGS84 } from '@/utils/coordinates/coordinateSystems' | ||
import { getExtentForProjection } from '@/utils/extentUtils' | ||
|
||
describe('Test extent utils', () => { | ||
pakb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
describe('reproject and cut extent within projection bounds', () => { | ||
it('handles well wrong inputs and returns null', () => { | ||
expect(getExtentForProjection()).to.be.null | ||
expect(getExtentForProjection(null, null)).to.be.null | ||
expect(getExtentForProjection(0, 0)).to.be.null | ||
expect(getExtentForProjection({}, [])).to.be.null | ||
expect(getExtentForProjection(LV95, [1, 2, 3])).to.be.null | ||
}) | ||
it('reproject extent of a single coordinate inside the bounds of the projection', () => { | ||
const singleCoordinate = [8.2, 47.5] | ||
const singleCoordinateInLV95 = proj4(WGS84.epsg, LV95.epsg, singleCoordinate).map( | ||
LV95.roundCoordinateValue | ||
) | ||
const extent = [singleCoordinate, singleCoordinate].flat() | ||
expect(getExtentForProjection(LV95, extent)).to.deep.equal([ | ||
singleCoordinateInLV95, | ||
singleCoordinateInLV95, | ||
]) | ||
}) | ||
it('returns null if a single coordinate outside of bounds is given', () => { | ||
const singleCoordinateOutOfLV95Bounds = [8.2, 40] | ||
const extent = [singleCoordinateOutOfLV95Bounds, singleCoordinateOutOfLV95Bounds].flat() | ||
expect(getExtentForProjection(LV95, extent)).to.be.null | ||
}) | ||
it('returns null if the extent given is completely outside of the projection bounds', () => { | ||
const extent = [-5.0, -20.0, -25.0, -45.0] | ||
expect(getExtentForProjection(LV95, extent)).to.be.null | ||
}) | ||
it('reproject and cut an extent that is greater than LV95 extent on all sides', () => { | ||
const projectedExtent = getExtentForProjection(LV95, [-2.4, 35, 21.3, 51.7]) | ||
expect(projectedExtent).to.deep.equal([LV95.bounds.bottomLeft, LV95.bounds.topRight]) | ||
}) | ||
it('only gives back the portion of an extent that is within LV95 bounds', () => { | ||
const singleCoordinateInsideLV95 = [7.54, 48.12] | ||
const singleCoordinateInLV95 = proj4( | ||
WGS84.epsg, | ||
LV95.epsg, | ||
singleCoordinateInsideLV95 | ||
).map(LV95.roundCoordinateValue) | ||
const overlappingExtent = [0, 0, ...singleCoordinateInsideLV95] | ||
expect(getExtentForProjection(LV95, overlappingExtent)).to.deep.equal([ | ||
LV95.bounds.bottomLeft, | ||
singleCoordinateInLV95, | ||
]) | ||
}) | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { expect } from 'chai' | ||
import { describe, it } from 'vitest' | ||
|
||
import { LV95 } from '@/utils/coordinates/coordinateSystems.js' | ||
import { parseGpx } from '@/utils/gpxUtils.js' | ||
|
||
describe('Test GPX utils', () => { | ||
describe('parseGpx', () => { | ||
it('handles correctly invalid inputs', () => { | ||
expect(parseGpx()).to.be.null | ||
expect(parseGpx(null, null)).to.be.null | ||
expect(parseGpx(0, LV95)).to.be.null | ||
expect(parseGpx([], LV95)).to.be.null | ||
expect(parseGpx({}, LV95)).to.be.null | ||
expect(parseGpx('', LV95)).to.be.null | ||
}) | ||
// further testing isn't really necessary as it's using out-of-the-box OL functions | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { getIntersection as getExtentIntersection, isEmpty as isExtentEmpty } from 'ol/extent' | ||
|
||
import CoordinateSystem from '@/utils/coordinates/CoordinateSystem.class.js' | ||
import { WGS84 } from '@/utils/coordinates/coordinateSystems' | ||
import { normalizeExtent, projExtent } from '@/utils/coordinates/coordinateUtils' | ||
import log from '@/utils/logging' | ||
|
||
/** | ||
* Get a flattened extent for the projection bounds. | ||
* | ||
* @param {CoordinateSystem} projection Projection in which to get the extent | ||
* @param {[number, number, number, number]} extent Extent in WGS84 such as `[minx, miny, maxx, | ||
* maxy]` | ||
* @returns {null | [[number, number], [number, number]]} Return null if the extent is out of | ||
* projection bounds or the intersection between the extent and projection bounds. The return | ||
* extent is re-projected to the projection. The output format will be `[[minx, miny], [maxx, | ||
* maxy]]`. | ||
*/ | ||
export function getExtentForProjection(projection, extent) { | ||
if (!(projection instanceof CoordinateSystem) || extent?.length !== 4) { | ||
return null | ||
} | ||
const projectionBounds = projection.getBoundsAs(WGS84).flatten | ||
let intersectExtent = getExtentIntersection(projectionBounds, extent) | ||
log.debug( | ||
`Get extent for projection ${projection.epsg}`, | ||
`extent=${extent}`, | ||
`projectionBounds=${projectionBounds}`, | ||
`intersectExtent=${intersectExtent}` | ||
) | ||
if (!isExtentEmpty(intersectExtent)) { | ||
return normalizeExtent(projExtent(WGS84, projection, intersectExtent)) | ||
} | ||
return null | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You also need to handle this error here
web-mapviewer/src/modules/menu/components/advancedTools/ImportFile/ImportFileLocalTab.vue
Line 79 in d9e436d