Solved, I had to scale the coordinates.
var projection = d3.geo.transverseMercator()
.translate([window.innerWidth, window.innerHeight])
.scale(30000000);
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 );
}
And this is how I want it to look like (I just stretched the values for this one, which is kinda ugly..)
Solution
Solved, I had to scale the coordinates.
var projection = d3.geo.transverseMercator()
.translate([window.innerWidth, window.innerHeight])
.scale(30000000);