Plotting and labeling

Can some-one help me with plotting lines in cesium globe and labeling it. Basically the line should be plotted from one point of the earth to another point and both the points should be labeled. The line should be in 3d nature similar to the orbits shown in the examples. And if its possible the center of the curved line should have another label. I am attaching edited pictures to give more idea on how this feature should look like.

Edited.rar (1.88 MB)

Cesium is certainly capable of putting lines and labels on a globe. It also has CatmullRomSpline and HermiteSpline that can be used to generate curves in various ways. What have you tried already?

By the way, you should consider just attaching JPG files to your email in the future, rather than putting PNGs in a RAR. The JPGs will be much smaller, and they won’t look like you’re trying to hit us all with a phishing attack. :slight_smile:

Kevin

I tried plotting using Catmullromspline, it is not giving me any errors but the line is still not being plotted could you tell me why is this

Yea i got it working :slight_smile: idid not use any visualizers then. But i need one help. I tried plotting using hermitespline, it looks like this

is there any way i can make the plotted curve look better? Something like below:

In the cesium plotted one the curve looks a bit awkward compared to this one, is there any way i can make it good like this?

It’s a little hard to tell exactly why you got the odd curve without seeing your code, but here’s some code to generate a simple curve between 2 points on the surface of the earth.

var earth = Cesium.Ellipsoid.WGS84;

// start and end points on the surface of the earth

var startPoint = earth.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-75.1642, 39.9522, 0.0));

var endPoint = earth.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-118.2428, 34.0522, 0.0));

// determine the midpoint (point will be inside the earth)

var midpointCartesian = startPoint.add(endPoint).divideByScalar(2.0);

// move the midpoint to the surface of the earth

earth.scaleToGeodeticSurface(midpointCartesian);

// add some altitude if you want (1000 km in this case)

var midpointCartographic = earth.cartesianToCartographic(midpointCartesian);

midpointCartographic.height = 1000000;

midpointCartesian = earth.cartographicToCartesian(midpointCartographic);

// create a hermite spline that goes through these three points

var hermiteSpline = new Cesium.HermiteSpline( [

{point: startPoint, time: 0.0},

{point: midpointCartesian, time: 0.5},

{point: endPoint, time: 1.0}

]);

// create a 20 point polyline that follows the spline

var polylinePoints = ;

for(var i=0; i<20; ++i) {

polylinePoints.push(hermiteSpline.evaluate(i/20));

}

var polylineCollection = new Cesium.PolylineCollection();

var polyline = polylineCollection.add();

polyline.setPositions(polylinePoints);

var primitives = widget.scene.getPrimitives();

primitives.add(polylineCollection);

can you take a look at this project?

http://callum.com/sandbox/webglex/connected_planet/

I want something like that buy in cesium. The function which you showed me is good, but aesthetically isnt the above project better? Can we do anything make the spline look better?

I have attached the project so you can take a look at it. It would be really helpful if the lines can be plotted smoothly like

webgl.zip (1.93 MB)

functions used there are :

function addData(locs) {

var index = Math.floor(Math.random() * locs.length) - 1;

var start_lat = locs[index].lat;

var start_lng = locs[index].lng;

var data_size = 1;

var start = Math.floor(Math.random() * locs.length) - 1;

if (start + data_size > locs.length) {

start = locs.length - data_size - 1;

}

var hue = Math.random();

var i;

for (i = start; i < start + data_size; i++) {

var obj = locs[i];

if (i != index) {

addTrack(25.2697, 55.3095, 28.6667, 77.2167, planetRadius, hue+.5);//delhi

addMarker(28.6667, 77.2167, planetRadius);

addTrack(25.2697, 55.3095, 35.6833, 51.4167, planetRadius, hue+.5);//terhan

addMarker(35.6833, 51.4167, planetRadius);

addTrack(25.2697, 55.3095, 51.0000, 9.0000, planetRadius, hue+.5);//germany

addMarker(51.0000, 9.0000, planetRadius);

addTrack(25.2697, 55.3095, 33.6667, 73.1667, planetRadius, hue+.5);//Islamabad

addMarker(33.6667, 73.1667, planetRadius);

addTrack(25.2697, 55.3095, 31.2000, 121.5000, planetRadius, hue+.5);//Shanghai,

addMarker(31.2000, 121.5000, planetRadius);

}

}

}

function addMarker(lat, lng, radius) {

var marker_mesh = new THREE.Mesh(markerGeom, markerMaterial);

var marker_position = latlngPosFromLatLng(lat, lng, radius);

marker_mesh.position.x = marker_position.x;

marker_mesh.position.y = marker_position.y;

marker_mesh.position.z = marker_position.z;

marker_mesh.name = “trackmarker”;

meshPlanet.add(marker_mesh);

}

function addTrackLine(spline, hue) {

var num_control_points = 32;

var i;

var colors = ;

var geometry = new THREE.Geometry();

var pos;

for (i = 0; i < num_control_points; i++) {

var index = i / num_control_points;

pos = spline.getPoint(index);

colors[i] = new THREE.Color(0xffffff);

colors[i].setHSV(hue, (1.0 - i / num_control_points), 1.0);

geometry.vertices.push(new THREE.Vector3(pos.x, pos.y, pos.z));

}

pos = spline.getPoint(1.0);

geometry.vertices.push(new THREE.Vector3(pos.x, pos.y, pos.z));

geometry.colors = colors;

var material = new THREE.LineBasicMaterial({

color: 0xffffff,

opacity: 1,

linewidth: 2

});

material.vertexColors = true;

var line = new THREE.Line(geometry, material);

line.name = “trackline”;

meshPlanet.add(line);

}

function addTrack(start_lat, start_lng, end_lat, end_lng, radius, hue) {

var num_control_points = 8;

var max_altitude = 500 + Math.random() * 1200;

var points = ;

var i;

for (i = 0; i < num_control_points + 1; i++) {

var arc_angle = i * 180.0 / num_control_points;

var arc_radius = radius + (Math.sin(latlngDeg2rad(arc_angle))) * max_altitude;

var latlng = latlngInterPoint(start_lat, start_lng, end_lat, end_lng, i / num_control_points);

var pos = latlngPosFromLatLng(latlng.lat, latlng.lng, arc_radius);

points.push(new THREE.Vector3(pos.x, pos.y, pos.z));

}

var spline = new THREE.SplineCurve3(points);

addTrackLine(spline, hue);

}

You can control the shape of the spline by using tangents at the end points.

// vector tangent to the surface of the earth at the start/end points

var startTangent = earth.geodeticSurfaceNormal(startPoint);

var endTangent = earth.geodeticSurfaceNormal(endPoint);

// scaling factor affects the shape of the hermite curve (end tangent should be negated for hermite splines in your case)

startTangent = startTangent.multiplyByScalar(2000000);

endTangent = endTangent.multiplyByScalar(-2000000);

// create a control points for hermite spline

var controlPoints = [

{point: startPoint, tangent: startTangent, time: 0.0},

{point: midpointCartesian, time: 0.5},

{point: endPoint, tangent: endTangent, time: 1.0}

];

Let me try this, i will get back to you if there is more doubt, Thanks a lot for responding.

Greg still the curve looks a bit weird. Is there any way to modify the curve to look better like that connected planet project? It would be really helpful if you can help me figure it out.

And one more thing, can i generate these lines dynamically? because two many variables are used to plot just a single curve between two points. Is it possible to use just a single function to plot multiple lines dynamically? and label both the starting and ending of these points?

The shape of hermite curves are completely configurable by using tangent vectors at for the control points (see HermiteSpline).

The direction and the magnitude of the tangent vectors “pull” the curve. Here’s a very crude illustration of how tangent vectors affect a hermite curve. Red dots are tangent vectors, black dots are the control points.

We don’t currently have a high level abstraction to draw a labeled curve like you described, but there’s no reason you couldn’t create a single function to create the polyline and the labels. The function would probably take the 2 endpoints and label text as input. The midpoint would be generated similar to the code posted above. Slight modifications would probably be that the midpoint altitude and tangent magnitudes would be some function of the distance between the two endpoints.

that was really helpful. by the way is there anyway to import third party functions on to cesium widget and make it work? and could you take a look at Microsoft’s Geoflow is there any alternative to that available in Cesium.?

Greg is it possible to plot graphs in cesium? like bar graph or something in street level?