Hello,
I'm trying to create a polyline which will measure distance between two points.
I've used two examples I've seen:
1. drawing polylines on mouse click and movement:
the issue I'm having with the above is that the temp polylines are "blinking", this must be because of the line position callback property.
2.Adding a label to the polyline entity which will display the distance between two points.
for this I've used a part of the Callbackproperty sample in sandcastle:
2.a. Adding a label to the final polyline is fine but the position as I've explained above.
2.b. adding the label to the templine caused the templine to be recreated again and again.
I've taken the Midpoint function but it gives me the wrong position and therefore my label isn't displayed good.
Attached below my code:
ruler()
{
let viewer = this.viewer;
var screenSpaceEventHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
var startPoint = new Cesium.Cartographic();
var endPoint = new Cesium.Cartographic();
// Event handler for left click
screenSpaceEventHandler.setInputAction(function(click) {
// get position of click
var clickPosition = viewer.camera.pickEllipsoid(click.position);
// Event handler for mouse movement
screenSpaceEventHandler.setInputAction(function(movement) {
// get position of mouse
var mousePosition = viewer.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid, mousePosition);
// create an empty array where the coordinates of the line will be stored
var lineArray = ;
// convert mouse and click position to lon/lat coordinates and add them to the array
var cartographicMouse = Cesium.Ellipsoid.WGS84.cartesianToCartographic(mousePosition);
var cartographicClick = Cesium.Ellipsoid.WGS84.cartesianToCartographic(clickPosition);
startPoint.longitude = cartographicClick.longitude;
startPoint.latitude = cartographicClick.latitude;
endPoint.longitude = cartographicMouse.longitude;
endPoint.latitude = cartographicMouse.latitude;
var x = Cesium.Math.toDegrees(cartographicMouse.longitude);
var y = Cesium.Math.toDegrees(cartographicMouse.latitude);
lineArray.push(x);
lineArray.push(y);
x = Cesium.Math.toDegrees(cartographicClick.longitude);
y = Cesium.Math.toDegrees(cartographicClick.latitude);
lineArray.push(x);
lineArray.push(y);
// use callback property to get cartesian coordinates for the line; if there is an existing line remove it, store in varible
var linePosition = new Cesium.CallbackProperty(function(time, result) {
if (typeof tempLine !== 'undefined') {
viewer.entities.remove(tempLine);
}
return new Cesium.Cartesian3.fromDegreesArray(lineArray);
}, false);
let surfacePositions = Cesium.PolylinePipeline.generateArc({
positions: linePosition.getValue(),
});
let scratchCartesian3 = new Cesium.Cartesian3();
let surfacePositionsLength = surfacePositions.length;
let totalDistanceInMeters = 0;
for (let i = 3; i < surfacePositionsLength; i += 3) {
scratchCartesian3.x = surfacePositions[i] - surfacePositions[i - 3];
scratchCartesian3.y = surfacePositions[i + 1] - surfacePositions[i - 2];
scratchCartesian3.z = surfacePositions[i + 2] - surfacePositions[i - 1];
totalDistanceInMeters += Cesium.Cartesian3.magnitude(scratchCartesian3);
}
let totalDistanceInKm = totalDistanceInMeters * 0.001;
// draw tempLine
var startCartographic = Cesium.Cartographic.fromDegrees(startPoint.longitude, startPoint.latitude);
var endCartographic = new Cesium.Cartographic();
var geodesic = new Cesium.EllipsoidGeodesic();
var scratch = new Cesium.Cartographic();
function getMidpointT(time, result) {
// Get the end position from the polyLine's callback.
var endPoint = tempLine.polyline.positions.getValue(time, result)[1];
endCartographic = Cesium.Cartographic.fromCartesian(endPoint);
geodesic.setEndPoints(startCartographic, endCartographic);
var midpointCartographic = geodesic.interpolateUsingFraction(0.5, scratch);
return Cesium.Cartesian3.fromRadians(midpointCartographic.longitude, midpointCartographic.latitude);
}
var tempLine = viewer.entities.add({
position : new Cesium.CallbackProperty(getMidpointT, false),
polyline: {
positions: linePosition,
width: 5,
material: Cesium.Color.RED
},
label: {
text: totalDistanceInKm.toFixed(2)+' km',
show : true,
showBackground : false,
font : '14px monospace',
},
});
console.log(viewer.entities);
// Event handler for second click; draw line with position from variable linePosition
screenSpaceEventHandler.setInputAction(function(click) {
// get position of click
let clickPosition = viewer.camera.pickEllipsoid(click.position);
var startCartographic = Cesium.Cartographic.fromDegrees(startPoint.longitude, startPoint.latitude);
var endCartographic = new Cesium.Cartographic();
var geodesic = new Cesium.EllipsoidGeodesic();
var scratch = new Cesium.Cartographic();
function getMidpoint(time, result) {
// Get the end position from the polyLine's callback.
var endPoint = Line.polyline.positions.getValue(time, result)[1];
endCartographic = Cesium.Cartographic.fromCartesian(endPoint);
geodesic.setEndPoints(startCartographic, endCartographic);
var midpointCartographic = geodesic.interpolateUsingFraction(0.5, scratch);
return Cesium.Cartesian3.fromRadians(midpointCartographic.longitude, midpointCartographic.latitude);
}
var Line = viewer.entities.add({
position : new Cesium.CallbackProperty(getMidpoint, false),
polyline: {
positions: linePosition,
width: 5,
material: Cesium.Color.RED
},
label: {
text: totalDistanceInKm.toFixed(2)+' km',
show : true,
showBackground : false,
font : '14px monospace',
},
});
console.log(Line);
screenSpaceEventHandler = screenSpaceEventHandler && screenSpaceEventHandler.destroy();
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
I would very much like an assistant with the issues above.
thanks a lot,
Lior.