使用google earth的api在html上顯示地圖,精美的模組讓人更有飛行的真實感,並可使用經緯度來改變地圖位置,下面經緯度為倫敦
turnLeft = false;
turnRight = false;
tiltUp = false;
tiltDown = false;
moveForward = false;
moveBackward = false;
strafeLeft = false;
strafeRight = false;
altitudeUp = false;
altitudeDown = false;
INITIAL_CAMERA_ALTITUDE = 1.7; // Roughly 6 feet tall
cameraAltitude = INITIAL_CAMERA_ALTITUDE;
//----------------------------------------------------------------------------
// Utility Functions
//----------------------------------------------------------------------------
// Keep an angle in [-180,180]
function fixAngle(a) {
while (a < -180) {
a += 360;
}
while (a > 180) {
a -= 360;
}
return a;
}
//----------------------------------------------------------------------------
// Input Handlers
//----------------------------------------------------------------------------
function keyDown(event) {
if (!event) {
event = window.event;
}
if (event.keyCode == 33) { // Altitude Up
altitudeUp = true;
event.returnValue = false;
} else if (event.keyCode == 34) { // Altitude Down
altitudeDown = true;
event.returnValue = false;
} else if (event.keyCode == 37) { // Turn Left.
turnLeft = true;
event.returnValue = false;
} else if (event.keyCode == 39) { // Turn Right.
turnRight = true;
event.returnValue = false;
} else if (event.keyCode == 38) { // Tilt Up.
tiltUp = true;
event.returnValue = false;
} else if (event.keyCode == 40) { // Tilt Down.
tiltDown = true;
event.returnValue = false;
} else if (event.keyCode == 65 ||
event.keyCode == 97) { // Strafe Left.
strafeLeft = true;
event.returnValue = false;
} else if (event.keyCode == 68 ||
event.keyCode == 100) { // Strafe Right.
strafeRight = true;
event.returnValue = false;
} else if (event.keyCode == 87 ||
event.keyCode == 119) { // Move Forward.
moveForward = true;
event.returnValue = false;
} else if (event.keyCode == 83 ||
event.keyCode == 115) { // Move Forward.
moveBackward = true;
} else {
return true;
}
return false;
}
function keyUp(event) {
if (!event) {
event = window.event;
}
if (event.keyCode == 33) { // Altitude Up
altitudeUp = false;
event.returnValue = false;
} else if (event.keyCode == 34) { // Altitude Down
altitudeDown = false;
event.returnValue = false;
} else if (event.keyCode == 37) { // Left.
turnLeft = false;
event.returnValue = false;
} else if (event.keyCode == 39) { // Right.
turnRight = false;
event.returnValue = false;
} else if (event.keyCode == 38) { // Up.
tiltUp = false;
event.returnValue = false;
} else if (event.keyCode == 40) { // Down.
tiltDown = false;
event.returnValue = false;
} else if (event.keyCode == 65 ||
event.keyCode == 97) { // Strafe Left.
strafeLeft = false;
event.returnValue = false;
} else if (event.keyCode == 68 ||
event.keyCode == 100) { // Strafe Right.
strafeRight = false;
event.returnValue = false;
} else if (event.keyCode == 87 ||
event.keyCode == 119) { // Move Forward.
moveForward = false;
event.returnValue = false;
} else if (event.keyCode == 83 ||
event.keyCode == 115) { // Move Forward.
moveBackward = false;
}
return false;
}
//----------------------------------------------------------------------------
// JSObject - FirstPersonCamera
//----------------------------------------------------------------------------
function FirstPersonCam() {
var me = this;
// The anchor point is where the camera is situated at. We store
// the current position in lat, lon, altitude and in cartesian
// coordinates.
me.localAnchorLla = [51.506008, -0.075445, 0];
me.localAnchorCartesian = V3.latLonAltToCartesian(me.localAnchorLla);
// Heading, tilt angle is relative to local frame
me.headingAngle = 0;
me.tiltAngle = 0;
// Initialize the time
me.lastMillis = (new Date()).getTime();
// Used for bounce.
me.distanceTraveled = 0;
// prevent mouse navigation in the plugin
ge.getOptions().setMouseNavigationEnabled(false);
// Updates should be called on frameend to help keep objects in sync.
// GE does not propogate changes caused by KML objects until an
// end of frame.
google.earth.addEventListener(ge, "frameend",
function() { me.update(); });
}
FirstPersonCam.prototype.updateOrientation = function(dt) {
var me = this;
// Based on dt and input press, update turn angle.
if (turnLeft || turnRight) {
var turnSpeed = 60.0; // radians/sec
if (turnLeft)
turnSpeed *= -1.0;
me.headingAngle += turnSpeed * dt * Math.PI / 180.0;
}
if (tiltUp || tiltDown) {
var tiltSpeed = 60.0; // radians/sec
if (tiltDown)
tiltSpeed *= -1.0;
me.tiltAngle = me.tiltAngle + tiltSpeed * dt * Math.PI / 180.0;
// Clamp
var tiltMax = 50.0 * Math.PI / 180.0;
var tiltMin = -90.0 * Math.PI / 180.0;
if (me.tiltAngle > tiltMax)
me.tiltAngle = tiltMax;
if (me.tiltAngle < tiltMin)
me.tiltAngle = tiltMin;
}
}
FirstPersonCam.prototype.updatePosition = function(dt) {
var me = this;
// Convert local lat/lon to a global matrix. The up vector is
// vector = position - center of earth. And the right vector is a vector
// pointing eastwards and the facing vector is pointing towards north.
var localToGlobalFrame = M33.makeLocalToGlobalFrame(me.localAnchorLla);
// Move in heading direction by rotating the facing vector around
// the up vector, in the angle specified by the heading angle.
// Strafing is similar, except it's aligned towards the right vec.
var headingVec = V3.rotate(localToGlobalFrame[1], localToGlobalFrame[2],
-me.headingAngle);
var rightVec = V3.rotate(localToGlobalFrame[0], localToGlobalFrame[2],
-me.headingAngle);
// Calculate strafe/forwards
var strafe = 0;
if (strafeLeft || strafeRight) {
var strafeVelocity = 30;
if (strafeLeft)
strafeVelocity *= -1;
strafe = strafeVelocity * dt;
}
var forward = 0;
if (moveForward || moveBackward) {
var forwardVelocity = 100;
if (moveBackward)
forwardVelocity *= -1;
forward = forwardVelocity * dt;
}
if (altitudeUp) {
cameraAltitude += 1.0;
} else if (altitudeDown) {
cameraAltitude -= 1.0;
}
cameraAltitude = Math.max(0, cameraAltitude);
me.distanceTraveled += forward;
// Add the change in position due to forward velocity and strafe velocity
me.localAnchorCartesian = V3.add(me.localAnchorCartesian,
V3.scale(rightVec, strafe));
me.localAnchorCartesian = V3.add(me.localAnchorCartesian,
V3.scale(headingVec, forward));
// Convert cartesian to Lat Lon Altitude for camera setup later on.
me.localAnchorLla = V3.cartesianToLatLonAlt(me.localAnchorCartesian);
}
FirstPersonCam.prototype.updateCamera = function() {
var me = this;
var lla = me.localAnchorLla;
lla[2] = ge.getGlobe().getGroundAltitude(lla[0], lla[1]);
// Will put in a bit of a stride if the camera is at or below 1.7 meters
var bounce = 0;
if (cameraAltitude <= INITIAL_CAMERA_ALTITUDE /* 1.7 */) {
bounce = 1.5 * Math.abs(Math.sin(4 * me.distanceTraveled *
Math.PI / 180));
}
// Update camera position. Note that tilt at 0 is facing directly downwards.
// We add 90 such that 90 degrees is facing forwards.
var la = ge.createLookAt('');
la.set(me.localAnchorLla[0], me.localAnchorLla[1],
cameraAltitude + bounce,
ge.ALTITUDE_RELATIVE_TO_SEA_FLOOR,
fixAngle(me.headingAngle * 180 / Math.PI), /* heading */
me.tiltAngle * 180 / Math.PI + 90, /* tilt */
0 /* altitude is constant */
);
ge.getView().setAbstractView(la);
};
FirstPersonCam.prototype.update = function() {
var me = this;
ge.getWindow().blur();
// Update delta time (dt in seconds)
var now = (new Date()).getTime();
var dt = (now - me.lastMillis) / 1000.0;
if (dt > 0.25) {
dt = 0.25;
}
me.lastMillis = now;
// Update orientation and then position of camera based
// on user input
me.updateOrientation(dt);
me.updatePosition(dt);
// Update camera
me.updateCamera();
};
沒有留言:
張貼留言