Skip to content

Commit cdf38b9

Browse files
authored
measureLenBetween consider altitude (#2406)
* measureLenBetween consider altitude * spec
1 parent d9926d6 commit cdf38b9

File tree

5 files changed

+52
-13
lines changed

5 files changed

+52
-13
lines changed

src/geo/measurer/Identity.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,21 @@ const identity = {
1818
* @param c1
1919
* @param c2
2020
*/
21-
measureLenBetween: function (c1: Coordinate | CoordinateJson, c2: Coordinate | CoordinateJson): number {
21+
measureLenBetween: function (c1: Coordinate | CoordinateJson, c2: Coordinate | CoordinateJson, ignoreAltitude = false): number {
2222
if (!c1 || !c2) {
2323
return 0;
2424
}
2525
try {
26-
return Math.sqrt(Math.pow(c1.x - c2.x, 2) + Math.pow(c1.y - c2.y, 2));
26+
const distance = Math.sqrt(Math.pow(c1.x - c2.x, 2) + Math.pow(c1.y - c2.y, 2));
27+
if (ignoreAltitude) {
28+
return distance;
29+
}
30+
const z1 = c1.z || 0, z2 = c2.z || 0;
31+
const dz = z1 - z2;
32+
if (dz === 0) {
33+
return distance;
34+
}
35+
return Math.sqrt(distance * distance + dz * dz);
2736
} catch (err) {
2837
return 0;
2938
}
@@ -63,7 +72,7 @@ const identity = {
6372
* @param yDist
6473
* @param out
6574
*/
66-
locate : function (c: Coordinate | CoordinateJson, xDist: number, yDist: number, out?: Coordinate) {
75+
locate: function (c: Coordinate | CoordinateJson, xDist: number, yDist: number, out?: Coordinate) {
6776
out = out || new Coordinate(0, 0);
6877
out.set(c.x, c.y);
6978
return this._locate(out, xDist, yDist);

src/geo/measurer/Sphere.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class Sphere {
3232
* @param c1
3333
* @param c2
3434
*/
35-
measureLenBetween(c1: CoordsLike, c2: CoordsLike): number {
35+
measureLenBetween(c1: CoordsLike, c2: CoordsLike, ignoreAltitude = false): number {
3636
if (!c1 || !c2) {
3737
return 0;
3838
}
@@ -42,7 +42,16 @@ class Sphere {
4242
f = toRadian(c1.x) - toRadian(c2.x);
4343
b = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(e / 2), 2) + Math.cos(b) * Math.cos(d) * Math.pow(Math.sin(f / 2), 2)));
4444
b *= this.radius;
45-
return b;
45+
const distance = b;
46+
if (ignoreAltitude) {
47+
return distance;
48+
}
49+
const z1 = c1.z || 0, z2 = c2.z || 0;
50+
const dz = z1 - z2;
51+
if (dz === 0) {
52+
return distance;
53+
}
54+
return Math.sqrt(distance * distance + dz * dz);
4655
}
4756

4857
/**
@@ -159,7 +168,7 @@ class Sphere {
159168
_rotate(c: Coordinate, pivot: Coordinate, angle: number) {
160169
const initialAngle = rhumbBearing(pivot, c);
161170
const finalAngle = initialAngle - angle;
162-
const distance = this.measureLenBetween(pivot, c);
171+
const distance = this.measureLenBetween(pivot, c, true);
163172
c.x = pivot.x;
164173
c.y = pivot.y;
165174
return calculateRhumbDestination(c, distance, finalAngle, this.radius);

src/layer/ImageLayer.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { extend } from '../core/util';
1+
import { extend, isNumber } from '../core/util';
22
import { getDepthFunc } from '../core/util/gl';
33
import Browser from '../core/Browser';
44
import Point from '../geo/Point';
@@ -212,7 +212,11 @@ export class ImageLayerCanvasRenderer extends CanvasRenderer {
212212
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
213213
// @ts-ignore
214214
this._painted = true;
215-
this._drawImage(image, extent, imgData[i].opacity || 1);
215+
let opacity = imgData[i].opacity;
216+
if (!isNumber(opacity)) {
217+
opacity = 1;
218+
}
219+
this._drawImage(image, extent, opacity);
216220
}
217221
}
218222
}

test/geometry/GeometryAltitudeSpec.js

+14
Original file line numberDiff line numberDiff line change
@@ -489,4 +489,18 @@ describe('Geometry.Altitude', function () {
489489
}, 100);
490490
});
491491

492+
it('#1970 geometry measure length consider altitude ', function (done) {
493+
map.addLayer(layer);
494+
const altitude = 100;
495+
const c1 = map.getCenter();
496+
const c2 = c1.copy();
497+
c2.z = altitude;
498+
const line = new maptalks.LineString([c1, c2]).addTo(layer);
499+
setTimeout(() => {
500+
expect(line.getLength()).to.be.equal(altitude);
501+
expect(map.computeGeometryLength(line)).to.be.equal(altitude);
502+
done();
503+
}, 100);
504+
});
505+
492506
});

test/geometry/SectorSpec.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -91,22 +91,25 @@ describe('#Sector', function () {
9191
});
9292

9393
it('getShell with altitude', function () {
94-
var sector = new maptalks.Sector({ x: 0, y: 0, z: 100 }, 1000, 0, 90);
94+
const radius = 1000, altitude = 100;
95+
const len = Math.sqrt(radius * radius + altitude * altitude);
96+
var sector = new maptalks.Sector({ x: 0, y: 0, z: altitude }, radius, 0, 90);
9597
var shell = sector.getShell();
9698

9799
expect(shell).to.have.length(sector.options.numberOfShellPoints);
98100
var num = sector.options.numberOfShellPoints;
99101
expect(shell).to.have.length(num);
100-
expect(map.computeLength(shell[1], [0, 0,])).to.be.approx(sector.getRadius(), 1E-5);
102+
103+
expect(map.computeLength(shell[1], [0, 0,])).to.be.approx(len, 1E-5);
101104
expect(shell[1].x).to.be.above(0);
102105
expect(shell[1].y).to.be.eql(0);
103106

104-
expect(map.computeLength(shell[shell.length - 2], [0, 0])).to.be.approx(sector.getRadius(), 1E-5);
107+
expect(map.computeLength(shell[shell.length - 2], [0, 0])).to.be.approx(len, 1E-5);
105108
expect(shell[shell.length - 2].y).to.be.above(0);
106109
expect(shell[shell.length - 2].x).to.be.approx(0, 1E-3);
107110

108-
expect(shell[shell.length - 2].z).to.be.eql(100);
109-
expect(shell[1].z).to.be.eql(100);
111+
expect(shell[shell.length - 2].z).to.be.eql(altitude);
112+
expect(shell[1].z).to.be.eql(altitude);
110113
});
111114

112115
describe('geometry fires events', function () {

0 commit comments

Comments
 (0)