Let transform function transform all dimensions it is capable of
This commit is contained in:
@@ -1,5 +1,28 @@
|
|||||||
## Upgrade notes
|
## Upgrade notes
|
||||||
|
|
||||||
|
### v6.15.0
|
||||||
|
|
||||||
|
#### Fixed coordinate dimesion handling in `ol/proj`'s `addCoordinateTransforms`
|
||||||
|
|
||||||
|
The `forward` and `inverse` functions passed to `addCooordinateTransforms` now receive a coordinate with all dimensions of the original coordinate, not just two. If you previosly had coordinates with more than two dimensions and added a transform like
|
||||||
|
```js
|
||||||
|
addCoordinateTransforms(
|
||||||
|
'EPSG:4326',
|
||||||
|
new Projection({code: 'latlong', units: 'degrees}),
|
||||||
|
function(coordinate) { return coordinate.reverse(); },
|
||||||
|
function(coordinate) { return coordinate.reverse(); }
|
||||||
|
);
|
||||||
|
```
|
||||||
|
you have to change that to
|
||||||
|
```js
|
||||||
|
addCoordinateTransforms(
|
||||||
|
'EPSG:4326',
|
||||||
|
new Projection({code: 'latlong', units: 'degrees}),
|
||||||
|
function(coordinate) { return coordinate.slice(0, 2).reverse() },
|
||||||
|
function(coordinate) { return coordinate.slice(0, 2).reverse() }
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
### v6.14.0
|
### v6.14.0
|
||||||
|
|
||||||
No special changes are required when upgrading to the 6.14.0 release.
|
No special changes are required when upgrading to the 6.14.0 release.
|
||||||
|
|||||||
+13
-12
@@ -340,11 +340,10 @@ export function createTransformFromCoordinateTransform(coordTransform) {
|
|||||||
const dimension = opt_dimension !== undefined ? opt_dimension : 2;
|
const dimension = opt_dimension !== undefined ? opt_dimension : 2;
|
||||||
const output = opt_output !== undefined ? opt_output : new Array(length);
|
const output = opt_output !== undefined ? opt_output : new Array(length);
|
||||||
for (let i = 0; i < length; i += dimension) {
|
for (let i = 0; i < length; i += dimension) {
|
||||||
const point = coordTransform([input[i], input[i + 1]]);
|
const point = coordTransform(input.slice(i, i + dimension));
|
||||||
output[i] = point[0];
|
const pointLength = point.length;
|
||||||
output[i + 1] = point[1];
|
for (let j = 0, jj = dimension; j < jj; ++j) {
|
||||||
for (let j = dimension - 1; j >= 2; --j) {
|
output[i + j] = j >= pointLength ? input[i + j] : point[j];
|
||||||
output[i + j] = input[i + j];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
@@ -368,7 +367,10 @@ export function createTransformFromCoordinateTransform(coordTransform) {
|
|||||||
* @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} inverse The inverse transform
|
* @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} inverse The inverse transform
|
||||||
* function (that is, from the destination projection to the source
|
* function (that is, from the destination projection to the source
|
||||||
* projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns
|
* projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns
|
||||||
* the transformed {@link module:ol/coordinate~Coordinate}.
|
* the transformed {@link module:ol/coordinate~Coordinate}. If the transform function can only
|
||||||
|
* transform less dimensions than the input coordinate, it is supposeed to return a coordinate
|
||||||
|
* with only the length it can transform. The other dimensions will be taken unchanged from the
|
||||||
|
* source.
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
export function addCoordinateTransforms(source, destination, forward, inverse) {
|
export function addCoordinateTransforms(source, destination, forward, inverse) {
|
||||||
@@ -706,20 +708,19 @@ export function fromUserResolution(resolution, destProjection) {
|
|||||||
*/
|
*/
|
||||||
export function createSafeCoordinateTransform(sourceProj, destProj, transform) {
|
export function createSafeCoordinateTransform(sourceProj, destProj, transform) {
|
||||||
return function (coord) {
|
return function (coord) {
|
||||||
let sourceX = coord[0];
|
|
||||||
let sourceY = coord[1];
|
|
||||||
let transformed, worldsAway;
|
let transformed, worldsAway;
|
||||||
if (sourceProj.canWrapX()) {
|
if (sourceProj.canWrapX()) {
|
||||||
const sourceExtent = sourceProj.getExtent();
|
const sourceExtent = sourceProj.getExtent();
|
||||||
const sourceExtentWidth = getWidth(sourceExtent);
|
const sourceExtentWidth = getWidth(sourceExtent);
|
||||||
|
coord = coord.slice(0);
|
||||||
worldsAway = getWorldsAway(coord, sourceProj, sourceExtentWidth);
|
worldsAway = getWorldsAway(coord, sourceProj, sourceExtentWidth);
|
||||||
if (worldsAway) {
|
if (worldsAway) {
|
||||||
// Move x to the real world
|
// Move x to the real world
|
||||||
sourceX = sourceX - worldsAway * sourceExtentWidth;
|
coord[0] = coord[0] - worldsAway * sourceExtentWidth;
|
||||||
}
|
}
|
||||||
sourceX = clamp(sourceX, sourceExtent[0], sourceExtent[2]);
|
coord[0] = clamp(coord[0], sourceExtent[0], sourceExtent[2]);
|
||||||
sourceY = clamp(sourceY, sourceExtent[1], sourceExtent[3]);
|
coord[1] = clamp(coord[1], sourceExtent[1], sourceExtent[3]);
|
||||||
transformed = transform([sourceX, sourceY]);
|
transformed = transform(coord);
|
||||||
} else {
|
} else {
|
||||||
transformed = transform(coord);
|
transformed = transform(coord);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {HALF_SIZE} from '../../../src/ol/proj/epsg3857.js';
|
|||||||
import {
|
import {
|
||||||
METERS_PER_UNIT,
|
METERS_PER_UNIT,
|
||||||
addCommon,
|
addCommon,
|
||||||
|
addCoordinateTransforms,
|
||||||
clearAllProjections,
|
clearAllProjections,
|
||||||
clearUserProjection,
|
clearUserProjection,
|
||||||
disableCoordinateWarning,
|
disableCoordinateWarning,
|
||||||
@@ -776,6 +777,26 @@ describe('ol/proj.js', function () {
|
|||||||
expect(got[2]).to.be(3);
|
expect(got[2]).to.be(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('transforms a 3d coordinate with 2-dimension transform', function () {
|
||||||
|
const latlon = new Projection({
|
||||||
|
code: 'latlon',
|
||||||
|
});
|
||||||
|
addCoordinateTransforms(
|
||||||
|
'EPSG:4326',
|
||||||
|
latlon,
|
||||||
|
function (coordinate) {
|
||||||
|
return coordinate.slice(0, 2).reverse();
|
||||||
|
},
|
||||||
|
function (coordinate) {
|
||||||
|
return coordinate.slice(0, 2).reverse();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const got = transform([-10, -20, 3], 'EPSG:4326', latlon);
|
||||||
|
expect(got).to.have.length(3);
|
||||||
|
expect(got).to.eql([-20, -10, 3]);
|
||||||
|
});
|
||||||
|
|
||||||
it('transforms a 4d coordinate', function () {
|
it('transforms a 4d coordinate', function () {
|
||||||
const got = transform([-10, -20, 3, 4], 'EPSG:4326', 'EPSG:3857');
|
const got = transform([-10, -20, 3, 4], 'EPSG:4326', 'EPSG:3857');
|
||||||
expect(got).to.have.length(4);
|
expect(got).to.have.length(4);
|
||||||
@@ -805,6 +826,47 @@ describe('ol/proj.js', function () {
|
|||||||
addCommon();
|
addCommon();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('works with 3d points and proj4 defs for 3d transforms', function () {
|
||||||
|
proj4.defs(
|
||||||
|
'geocent',
|
||||||
|
'+proj=geocent +datum=WGS84 +ellps=WGS84 +units=m +no_defs'
|
||||||
|
);
|
||||||
|
register(proj4);
|
||||||
|
|
||||||
|
const got = transform(
|
||||||
|
[5584000, 2844000, 3448000],
|
||||||
|
'geocent',
|
||||||
|
'EPSG:4326'
|
||||||
|
);
|
||||||
|
expect(got).to.have.length(3);
|
||||||
|
expect(got[0]).to.roughlyEqual(26.990304649234826, 1e-9);
|
||||||
|
expect(got[1]).to.roughlyEqual(28.965718227798618, 1e-9);
|
||||||
|
expect(got[2]).to.roughlyEqual(779337.8584198505, 1e-9);
|
||||||
|
|
||||||
|
delete proj4.defs.geocent;
|
||||||
|
clearAllProjections();
|
||||||
|
addCommon();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('works with 3d points and proj4 defs for 3d transforms with clamped extent', function () {
|
||||||
|
proj4.defs(
|
||||||
|
'geocent',
|
||||||
|
'+proj=geocent +datum=WGS84 +ellps=WGS84 +units=m +no_defs'
|
||||||
|
);
|
||||||
|
register(proj4);
|
||||||
|
|
||||||
|
const got = transform([-7.56234, 38.96618, 0], 'EPSG:4326', 'geocent');
|
||||||
|
|
||||||
|
expect(got).to.have.length(3);
|
||||||
|
expect(got[0]).to.roughlyEqual(4922499, 1);
|
||||||
|
expect(got[1]).to.roughlyEqual(-653508, 1);
|
||||||
|
expect(got[2]).to.roughlyEqual(3989398, 1);
|
||||||
|
|
||||||
|
delete proj4.defs.geocent;
|
||||||
|
clearAllProjections();
|
||||||
|
addCommon();
|
||||||
|
});
|
||||||
|
|
||||||
it('does not flip axis order', function () {
|
it('does not flip axis order', function () {
|
||||||
proj4.defs('enu', '+proj=longlat');
|
proj4.defs('enu', '+proj=longlat');
|
||||||
proj4.defs('neu', '+proj=longlat +axis=neu');
|
proj4.defs('neu', '+proj=longlat +axis=neu');
|
||||||
@@ -812,7 +874,6 @@ describe('ol/proj.js', function () {
|
|||||||
|
|
||||||
const got = transform([1, 2], 'neu', 'enu');
|
const got = transform([1, 2], 'neu', 'enu');
|
||||||
expect(got).to.eql([1, 2]);
|
expect(got).to.eql([1, 2]);
|
||||||
|
|
||||||
delete proj4.defs.enu;
|
delete proj4.defs.enu;
|
||||||
delete proj4.defs.neu;
|
delete proj4.defs.neu;
|
||||||
clearAllProjections();
|
clearAllProjections();
|
||||||
|
|||||||
Reference in New Issue
Block a user