google-earth.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. "use strict";
  2. // Copyright 2012 United States Government, as represented by the Secretary of Defense, Under
  3. // Secretary of Defense (Personnel & Readiness).
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed under the License
  11. // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
  12. // or implied. See the License for the specific language governing permissions and limitations under
  13. // the License.
  14. /// @module vwf/view/googleEarth
  15. /// @requires vwf/view
  16. define( [ "module", "vwf/view", "jquery" ], function( module, view, jQuery ) {
  17. var myOptions = undefined;
  18. return view.load( module, {
  19. // == Module Definition ====================================================================
  20. initialize: function() {
  21. if ( !this.state ) {
  22. this.state = {};
  23. }
  24. if ( !this.state.scenes ) {
  25. this.state.scenes = {};
  26. }
  27. if ( !this.state.nodes ) {
  28. this.state.nodes = {};
  29. }
  30. this.height = 600;
  31. this.width = 800;
  32. if ( window ) {
  33. if ( window.innerHeight ) this.height = window.innerHeight - 20;
  34. if ( window.innerWidth ) this.width = window.innerWidth - 20;
  35. this.window = window;
  36. }
  37. this.controlClient = "NONE";
  38. },
  39. createdNode: function( nodeID, childID, childExtendsID, childImplementsIDs,
  40. childSource, childType, childIndex, childName, callback /* ( ready ) */ ) {
  41. if ( childExtendsID === undefined )
  42. return;
  43. this.logger.infox( "createdNode", nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName );
  44. var node = {
  45. parentID: nodeID,
  46. ID: childID,
  47. extendsID: childExtendsID,
  48. implementsIDs: childImplementsIDs,
  49. source: childSource,
  50. type: childType,
  51. name: childName,
  52. loadComplete: callback,
  53. };
  54. var win;
  55. switch ( childExtendsID.toLowerCase() ) {
  56. case "http://vwf.example.com/googleearth.vwf":
  57. this.state.scenes[ childID ] = node;
  58. var outerDiv = jQuery('body').append(
  59. "<div id='map3d' style='border: 1px solid silver; width: " + this.width + "px; height: " + this.height + "px;'></div>"
  60. );
  61. window.onresize = function( event ) { console.info( "WINDOW: onresize" ); }
  62. break;
  63. case "http://vwf.example.com/node3.vwf":
  64. this.state.nodes[ childID ] = node;
  65. var view = this;
  66. if ( childName == "earth" ) {
  67. var interval;
  68. var view = this;
  69. win = this.window;
  70. var gg = google;
  71. interval = win.setInterval( function() {
  72. if ( gg.earth ) {
  73. node.earth = gg.earth;
  74. gg.earth.createInstance( "map3d", function(instance) {
  75. gg.earth.geInstance = instance;
  76. node.earthInst = instance;
  77. node.earthInst.getWindow().setVisibility(true);
  78. // add a navigation control
  79. node.earthInst.getNavigationControl().setVisibility(node.earthInst.VISIBILITY_AUTO);
  80. // add some layers
  81. node.earthInst.getLayerRoot().enableLayerById(node.earthInst.LAYER_BORDERS, true);
  82. node.earthInst.getLayerRoot().enableLayerById(node.earthInst.LAYER_BUILDINGS, true);
  83. node.earthInst.getLayerRoot().enableLayerById(node.earthInst.LAYER_ROADS, true);
  84. node.earthInst.getLayerRoot().enableLayerById(node.earthInst.LAYER_TERRAIN, true);
  85. node.earthInst.getLayerRoot().enableLayerById(node.earthInst.LAYER_TREES, true);
  86. node.earthInst.getOptions().setFlyToSpeed( node.earthInst.SPEED_TELEPORT );
  87. myOptions = node.earthInst.getOptions();
  88. myOptions.setMouseNavigationEnabled(false);
  89. var la = node.earthInst.getView().copyAsLookAt(node.earthInst.ALTITUDE_RELATIVE_TO_GROUND);
  90. la.setRange( 100000 );
  91. la.setLatitude( 38.9 );
  92. la.setLongitude( -77 );
  93. node.earthInst.getView().setAbstractView(la);
  94. if(view.kernel.find("", "//lookAt").length > 0) {
  95. view.kernel.execute(view.kernel.find("", "//lookAt")[0], "this.cameraData = this.cameraData");
  96. }
  97. view.control = false;
  98. gg.earth.addEventListener( node.earthInst.getWindow(), 'mousedown', function() {
  99. view.controlClient = view.kernel.moniker();
  100. view.kernel.setProperty( vwf_view.kernel.prototype(vwf_view.kernel.find("","/")), "controlClient", view.kernel.moniker() );
  101. });
  102. // gg.earth.addEventListener( node.earthInst.getWindow(), 'mousemove', function() {
  103. // //view.pointerDown = false;
  104. // });
  105. // gg.earth.addEventListener( node.earthInst.getWindow(), 'mouseup', function() {
  106. // //view.pointerDown = false;
  107. // });
  108. // view changed event listener
  109. gg.earth.addEventListener( node.earthInst.getView(), 'viewchange', function() {
  110. if ( view.controlClient == view.kernel.moniker() ) {
  111. broadcastCameraData.call( view );
  112. }
  113. });
  114. // view changed END event listener
  115. gg.earth.addEventListener( node.earthInst.getView(), 'viewchangeend', function() {
  116. if ( view.controlClient == view.kernel.moniker() ) {
  117. broadcastCameraData.call( view );
  118. }
  119. });
  120. view.kernel.callMethod( nodeID, "loaded", [] );
  121. }, function(errorCode) {
  122. this.logger.info( "google earth load error: " + errorCode );
  123. }, {
  124. // https://developers.google.com/earth/documentation/#sidedatabase
  125. // https://developers.google.com/earth/documentation/reference/google_earth_namespace#a70288485024d8129dd1c290fb2e5553b
  126. // Alternate database server:
  127. // database: "http://khmdb.google.com/?db=moon",
  128. // If required by the server:
  129. // username: "",
  130. // password: "",
  131. } );
  132. win.clearInterval( interval );
  133. }
  134. }, 1000 );
  135. }
  136. break;
  137. }
  138. },
  139. //deletedNode: function (nodeID) {
  140. //},
  141. createdProperty: function (nodeID, propertyName, propertyValue) {
  142. return this.initializedProperty(nodeID, propertyName, propertyValue);
  143. },
  144. initializedProperty: function (nodeID, propertyName, propertyValue) {
  145. switch (propertyName) {
  146. case "controlClient":
  147. if ( propertyValue == vwf_view.kernel.moniker() ) {
  148. enableMouseControl.call( vwf_view );
  149. }
  150. else {
  151. disableMouseControl.call( vwf_view );
  152. }
  153. break;
  154. }
  155. },
  156. satProperty: function( nodeID, propertyName, propertyValue ) {
  157. var value = undefined;
  158. var obj, earth, ge;
  159. for(var node in this.state.nodes) {
  160. if(this.state.nodes[node].name == "earth") {
  161. earth = this.state.nodes[node];
  162. }
  163. }
  164. if ( propertyValue && earth ) {
  165. //this.logger.infox( "satProperty", nodeID, propertyName, propertyValue );
  166. if ( propertyName == "controlClient" ) {
  167. if ( propertyValue != vwf_view.kernel.moniker() ) {
  168. disableMouseControl.call( vwf_view );
  169. }
  170. else {
  171. enableMouseControl.call( vwf_view );
  172. }
  173. this.controlClient = propertyValue;
  174. value = propertyValue;
  175. } else if ( this.kernel.client() != this.kernel.moniker() ) {
  176. if(vwf_view.kernel.test("", "/camera", nodeID) || vwf_view.kernel.test("", "/lookAt", nodeID)) {
  177. if ( earth && earth.earthInst ) {
  178. ge = earth.earthInst;
  179. if ( vwf_view.kernel.test("", "/lookAt", nodeID) ) {
  180. obj = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
  181. } else {
  182. obj = ge.getView().copyAsCamera(ge.ALTITUDE_RELATIVE_TO_GROUND);
  183. }
  184. switch ( propertyName ) {
  185. case "longitude":
  186. obj.setLongitude( propertyValue );
  187. ge.getView().setAbstractView(obj);
  188. value = propertyValue;
  189. break;
  190. case "latitude":
  191. obj.setLatitude( propertyValue );
  192. ge.getView().setAbstractView(obj);
  193. value = propertyValue;
  194. break;
  195. case "altitude":
  196. obj.setAltitude( propertyValue );
  197. ge.getView().setAbstractView(obj);
  198. value = propertyValue;
  199. break;
  200. case "altitudeMode":
  201. obj.setAltitudeMode( propertyValue );
  202. ge.getView().setAbstractView(obj);
  203. value = propertyValue;
  204. break;
  205. case "heading":
  206. obj.setHeading( propertyValue );
  207. ge.getView().setAbstractView(obj);
  208. value = propertyValue;
  209. break;
  210. case "tilt":
  211. obj.setTilt( propertyValue );
  212. ge.getView().setAbstractView(obj);
  213. value = propertyValue;
  214. break;
  215. case "range":
  216. obj.setRange( propertyValue );
  217. ge.getView().setAbstractView(obj);
  218. value = propertyValue;
  219. break;
  220. case "cameraData":
  221. obj.setLongitude( propertyValue[0] );
  222. obj.setLatitude( propertyValue[1] );
  223. obj.setAltitude( propertyValue[2] );
  224. obj.setAltitudeMode( propertyValue[3] );
  225. obj.setHeading( propertyValue[4] );
  226. obj.setTilt( propertyValue[5] );
  227. obj.setRange( propertyValue[6] );
  228. ge.getView().setAbstractView( obj );
  229. value = propertyValue;
  230. break;
  231. }
  232. }
  233. }
  234. }
  235. }
  236. return value;
  237. },
  238. gotProperty: function (nodeID, propertyName, propertyValue) {
  239. var value = undefined;
  240. var obj, earth, ge;
  241. var cameraNode, lookAtNode;
  242. for(var node in this.state.nodes) {
  243. if(this.state.nodes[node].name == "camera") {
  244. cameraNode = this.state.nodes[node];
  245. }
  246. else if(this.state.nodes[node].name == "lookAt") {
  247. lookAtNode = this.state.nodes[node];
  248. }
  249. }
  250. if((cameraNode && cameraNode.ID == nodeID) || (lookAtNode && lookAtNode.ID == nodeID)) {
  251. earth = this.state.nodes[ this.kernel.find("", "//earth")[0] ];
  252. if ( earth && earth.earthInst ) {
  253. ge = earth.earthInst;
  254. if ( lookAtNode && lookAtNode.ID == nodeID ) {
  255. obj = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
  256. } else {
  257. obj = ge.getView().copyAsCamera(ge.ALTITUDE_RELATIVE_TO_GROUND);
  258. }
  259. switch ( propertyName ) {
  260. case "longitude":
  261. value = obj.getLongitude();
  262. break;
  263. case "latitude":
  264. value = obj.getLatitude();
  265. break;
  266. case "altitude":
  267. value = obj.getAltitude();
  268. break;
  269. case "altitudeMode":
  270. value = obj.getAltitudeMode();
  271. break;
  272. case "heading":
  273. value = obj.getHeading();
  274. break;
  275. case "tilt":
  276. value = obj.getTilt();
  277. break;
  278. case "range":
  279. if ( obj.getRange )
  280. value = obj.getRange();
  281. break;
  282. case "cameraData":
  283. value = [ obj.getLongitude(), obj.getLatitude(), obj.getAltitude(),
  284. obj.getAltitudeMode(), obj.getHeading(), obj.getTilt(),
  285. obj.getRange ? obj.getRange() : undefined ];
  286. break;
  287. }
  288. }
  289. }
  290. else {
  291. switch ( propertyName ) {
  292. case "controlClient":
  293. value = this.controlClient;
  294. break;
  295. }
  296. }
  297. propertyValue = value;
  298. return value;
  299. },
  300. } );
  301. function disableMouseControl() {
  302. if ( myOptions != undefined ) {
  303. myOptions.setMouseNavigationEnabled(false);
  304. }
  305. }
  306. function enableMouseControl() {
  307. if ( myOptions != undefined ) {
  308. myOptions.setMouseNavigationEnabled(true);
  309. }
  310. }
  311. function broadcastCameraData() {
  312. var node, ge;
  313. if ( this.kernel.find("", "//earth").length > 0 ) {
  314. node = this.state.nodes[ this.kernel.find("", "//earth")[0] ];
  315. ge = node.earthInst;
  316. if ( ge ) {
  317. var la = ge.getView().copyAsLookAt( ge.ALTITUDE_RELATIVE_TO_GROUND );
  318. var cameraData = [ la.getLongitude(), la.getLatitude(), la.getAltitude(),
  319. la.getAltitudeMode(), la.getHeading(), la.getTilt(), la.getRange() ];
  320. this.kernel.setProperty( this.kernel.find("", "//lookAt")[0], "cameraData", cameraData );
  321. }
  322. }
  323. }
  324. } );