Skip to content

fix UIComponent ViewPoint cal error when geometry coordinates carry z… #2134

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

Merged
merged 2 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/geometry/Geometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -1557,7 +1557,7 @@ function getGeometryCoordinatesAlts(geometry, layerAlt, enableAltitude) {
coordinatesHasAlt(coordinates, tempAlts);
if (tempAlts.length) {
const alts = getCoordinatesAlts(coordinates, layerAlt, enableAltitude);
if (geometry.getShell) {
if (geometry.getShell && Array.isArray(alts[0])) {
return alts[0][0];
}
return alts;
Expand Down
4 changes: 4 additions & 0 deletions src/ui/UIComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,10 @@ class UIComponent extends Eventable(Class) {
altitude = coordinates.z;
} else if (this._owner && this._owner.getAltitude) {
altitude = this._owner.getAltitude() || 0;
//altitude is array from linestring ,polygon etc when coordinates carry z value [[x,y,z],[x,y,z],....];
if (!isNumber(altitude)) {
altitude = 0;
}
}
const alt = this._meterToPoint(this._coordinate, altitude);
return this.getMap().coordToViewPoint(this._coordinate, undefined, alt)
Expand Down
91 changes: 76 additions & 15 deletions test/ui/InfoWindowSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ describe('UI.InfoWindow', function () {
});

it('infowindow not repeat fire show event when geometry symbol change', function (done) {
var marker1 = new maptalks.Marker(map.getCenter(),{
symbol:{
var marker1 = new maptalks.Marker(map.getCenter(), {
symbol: {
'markerType': 'ellipse',
'markerWidth': 40,
'markerHeight': 40,
Expand All @@ -93,8 +93,8 @@ describe('UI.InfoWindow', function () {
content: 'hello maptalks'
});

var marker2 = new maptalks.Marker(map.getCenter().add(0.001,0),{
symbol:{
var marker2 = new maptalks.Marker(map.getCenter().add(0.001, 0), {
symbol: {
'markerType': 'ellipse',
'markerWidth': 40,
'markerHeight': 40,
Expand All @@ -106,29 +106,90 @@ describe('UI.InfoWindow', function () {
title: 'hello maptalks',
content: 'hello maptalks'
});
[marker1, marker2].forEach(function(marker) {
marker.getInfoWindow().on('showstart', function(e) {
[marker1, marker2].forEach(function (marker) {
marker.getInfoWindow().on('showstart', function (e) {
var ownver = e.target.getOwner();
if (!ownver._orignalSymbol) {
ownver._orignalSymbol = ownver.getSymbol();
}
//The show event should not be triggered,otherwise error:Maximum call stack size exceeded
//The show event should not be triggered,otherwise error:Maximum call stack size exceeded
e.target.getOwner().setSymbol();
})
marker.getInfoWindow().on('hide',function(e) {
marker.getInfoWindow().on('hide', function (e) {
var ownver = e.target.getOwner();
//The show event should not be triggered,otherwise error:Maximum call stack size exceeded
//The show event should not be triggered,otherwise error:Maximum call stack size exceeded
ownver.setSymbol(ownver._orignalSymbol);
})
});
//fire show events
marker1.openInfoWindow();
setTimeout(function(){
marker2.openInfoWindow();
setTimeout(function(){
done();
},100)
},100)
setTimeout(function () {
marker2.openInfoWindow();
setTimeout(function () {
done();
}, 100)
}, 100)

});
it('#2133 infowindow when owner coordinates carry z value', function (done) {
const pointSymbol = {
markerType: 'ellipse',
markerWidth: 20,
markerHeight: 20
};
const lineSymbol = {
lineColor: 'black',
lineWidth: 4
};

const fillSymbol = {
polygonFill: "black",
polygonOpacity: 1
};
map.setCenter([0, 0]);
map.setZoom(12);
//geometry coordinates carry z value
const lefttop = [-0.01, 0.01, 1], righttop = [0.01, 0.01, 1], rightbottom = [0.01, -0.01, 1], leftbottom = [-0.01, -0.01, 1];
const point = new maptalks.Marker(lefttop, { symbol: pointSymbol });
const multipoint = new maptalks.MultiPoint([lefttop, lefttop], { symbol: pointSymbol });
const line = new maptalks.LineString([lefttop, righttop], { symbol: lineSymbol });
const multiline = new maptalks.MultiLineString([[lefttop, righttop], [lefttop, righttop]], { symbol: lineSymbol });
const polygon = new maptalks.Polygon([[lefttop, righttop, rightbottom, leftbottom]], { symbol: fillSymbol });
const multipolygon = new maptalks.MultiPolygon([[[lefttop, righttop, rightbottom, leftbottom]], [[lefttop, righttop, rightbottom, leftbottom]]], { symbol: fillSymbol });
const rectange = new maptalks.Rectangle(lefttop, 2000, 1000, { symbol: fillSymbol });
const ellispe = new maptalks.Ellipse(lefttop, 2000, 1000, { symbol: fillSymbol });
const sector = new maptalks.Sector(lefttop, 1000, 0, 90, { symbol: fillSymbol });
const circle = new maptalks.Circle(lefttop, 1000, { symbol: fillSymbol });
const geos = [point, multipoint, line, multiline, polygon, multipolygon, circle, rectange, ellispe, sector];
geos.forEach(geo => {
geo.setInfoWindow({
animationDuration: 0,
title: 'hello maptalks',
content: 'hello maptalks'
});
});
let idx = 0;

function test() {
if (idx < geos.length) {
layer.clear();
const geo = geos[idx];
geo.addTo(layer);
setTimeout(() => {
const center = geo.getCenter();
center.z = undefined;
geo.openInfoWindow(center);
setTimeout(function () {
expect(geo.getInfoWindow().__uiDOM.style.display).not.to.be.eql('none');
idx++;
test();
}, 50);
}, 40);
} else {
done();
}
}

test();
});
});