Transforming the Geo
THREE.js is very fleixble in allowing us to use spatial data. However, some of the extensions to THREE.js assume a scene that is of an approximate size and, sometimes, rotation. Because of this, we may need to transform the Geo to make it work with other THREE.js extensions. You may also want to transform a geo to have two Geos sit next to each other in a scene (under construction).
The Scene and Geo Coordinate Systems
Up until now, the Scene and the Geo have used the same coordinates. When we transfrom the Geo, the Scene will be using different coordinates than the Geo. This means the lights, items, and spatial data you place in the Geo will appear as expected but the Views and any other objects that are placed in the Scene will need to have their locations specified in Scene coordinates.
CanvasMap 3D sets the camera to be positioned with the "Z" axis to be up. However, many 3D examplse use "Y" as up. This can be changed in the View:
var TheView=new CM3View( ); TheView.SetSetting("CM3View","CameraUp","Y"); // rotates camera to match the 3D default scene orientation
The Hawaii With Ocean example shows one method for using different coordinate systems for the Scene and the Geo. At the start of the code, we setup variables with the reference coordinates for our spatial data and coordinates that are scaled to the Scene.
// Setup the reference coordinates of the approximate center of the data var RefX=800000; // Center of the data var RefY=2200000; var RefZ=0; var SceneRefWidth=5000000; // Dimensions of a plane we will use for the ocean var SceneRefDepth=5000000; // Specify an amount to scale the data to the scene var TheScale=.005; // change this amount to scale the entire Geo within the scene // Find the scaled approximate center of the scene in Scene coordinates // This is effectively converting the reference coordinates to scene coordinates var ScaledX=RefX*TheScale; var ScaledY=RefY*TheScale; var ScaledZ=RefZ*TheScale; // Find the scale width and depth of the scene var SceneWidth=SceneRefWidth*TheScale; var SceneDepth=SceneRefDepth*TheScale;
Then, we scale the Geo by the desired amount and shift the Geo's position to the center of the Scene:
var TheGeo=TheScene.GetGeo(); // setup the geo to be in the center of the scene by scaling it to the scene and this shifting it oto the center of the scene TheGeo.SetSetting("Item","Scale",[TheScale,TheScale,TheScale]); TheGeo.SetSetting("Item","PositionOffset",[-ScaledX,-ScaledY,-ScaledZ]);
Our data layers, lights, and other objects that are placed in the Geo can have their coordinates specified through reference coordinates but since the View is in the Scene, its position needs to be specified in Scene coordinates. This can be done by muiltplying the reference coordinates by our scaling factor. Also, remember that "Y" is now up in the Scene so our Z and Y coordinate values are reversed.
- 0 - X coordinate value
- 1 - Z coordinate value
- 2 - Y coordinate value
TheView.SetSetting("Item","PositionOffset",[0,700,1400]); // Since the view has "Y" as up the values are [X,Z,Y]
TheView.SetSetting("CM3View","LookAt",[0,0,0]); // look at the origin