Question

I'm visualizing UTM/WGS84 coordinates in three.js. My problem is that the granularity of the trajectories are very fine grained, meaning that I can't see any differences in the movement behaviour. I'm looking for a clean way to plot a Space-Time-Cube (X and Y is space, Z is time) but I can't figure out how to project the trajectory data into the scene that I can actually see the location changes (I normalized the data which kinda worked but I would rather prefer a more fancy method). I'm loading the trajectory info from a CSV which is stored in the variable data. I have 1500 of these tuples, with LAT, LON (EPSG 4326) and ascending seconds. As you can see the movement is very fine grained (I have movement data from an object moving over a size of approx. four football fields)

12.4309352,48.4640973,0
12.4301431,48.4655268,15
12.4288555,48.4658138,30
12.4266812,48.4653488,45
12.4245049,48.4648678,60
12.4228305,48.4639438,75
12.4217859,48.4625038,90
... ... ...

Here is my code so far with comments:

var data = $.csv.toArrays(csv);

var renderer,
scene,
camera,
controls

//using terrainSize was an experiment, it didn't change much

var terrainSize = 60;

if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
renderer = new THREE.WebGLRenderer({ antialias: true });
document.body.appendChild( renderer.domElement );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColorHex( 0xeeeeee, 1.0 );

scene = new THREE.Scene();

var material = new THREE.LineBasicMaterial({
  color: 0xff00cc,
  fog: true
});

var geometry = new THREE.Geometry();

var x = []
var y = []
var z = []

var count = 0;
for(var row in data) {
   count += parseInt(data[row][2]); 
   x.push(parseFloat(data[row][0]));
   y.push(parseFloat(data[row][1]));
   z.push(parseFloat(count));
}


//I normalize the seconds that everything is visible on the map

z_stretch = stretch_array(z,10,1)

function stretch_array(my_stretched_array, given_stretch, multiplier) {
   ratio = Math.max.apply(this, my_stretched_array) / given_stretch,
   l = my_stretched_array.length;

   for ( i = 0; i < l; i++ ) {
      my_stretched_array[i] =  my_stretched_array[i] / ratio;
   }                

   for ( i = 0; i < my_stretched_array.length; i++) {
      my_stretched_array[i] = multiplier * my_stretched_array[i];
   }
   return my_stretched_array;
}


//I zip the data back together

var data_stretched = []

for ( i = 0; i < data.length; i++ ) {
   data_stretched.push([x[i], y[i], z_stretch[i]]);
} 


//I tried using d3.js but I couldn't figure out how to stretch the data accordingly

var projection = d3.geo.transverseMercator()
   .translate([terrainSize / 2, terrainSize / 2])
   .scale(10)  
   .center([12.4309352,48.4640973]);    

//Looping through the data, translating it and adding each tuple to the geometry

for (var row in data_stretched) {
   var x = data_stretched[row][0]
   var y = data_stretched[row][2]
   var z = data_stretched[row][2]

   coord = translate(projection([y, x]));

   geometry.vertices.push(new THREE.Vector3(parseFloat(coord[0]), parseFloat(z),     parseFloat(coord[1])));
}


// Another experiment

function translate(point) {
   return [point[0] - (terrainSize / 2), (terrainSize / 2) - point[1]];
}

// Plotting the line

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

// camera and control settings..

var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, -terrainSize / 2, terrainSize / 2);

controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 0.2;
controls.panSpeed = 0.8;

controls.noZoom = false;
controls.noPan = false;

controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;

animate();

function animate() {
   requestAnimationFrame( animate );
   controls.update();
   renderer.render( scene, camera );
}

Result

And this is how I want it to look like (I just stretched the values for this one, which is kinda ugly..)

enter image description here

Was it helpful?

Solution

Solved, I had to scale the coordinates.

var projection = d3.geo.transverseMercator()
.translate([window.innerWidth, window.innerHeight])
.scale(30000000);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top