SpacEyes3D Plugin Tutorial

Using the component in a Web page

This section documents the inclusion of the component inside a web page. The SpacEyes3D plugin is accessible through two technologies :

In addition to the component itself, SPACEYES provides in the SDK a cross-browser javascript library providing a simple and homogeneous way to create and to pilot the component.

Including the component in the web page

SPACEYES provides with the SDK a set of javascript files containing class definitions and useful functions to help to integrate the plugin into a web page. The use of these libraries smooths considerably all cross-browser compatibility issues.

The documentation of this library is available here.

To load the SpacEyes3D Plugin, you need to :

  1. Load the Javascript Library,
  2. Create a DIV element to hold the plugin,
  3. Create an instance of the plugin.

Loading the Javascript library

Place the following tags in the head section of your html page (you will have to replace path_to_the_lib with something reflecting your configuration) :

    <script src="path_to_the_lib/prototype.js" type="text/javascript"></script>
    <script src="path_to_the_lib/sp3dViewer.js" type="text/javascript"></script>

Note that the library makes use of the well known Prototype javascript framework.

Creating a container

The SpacEyes3D plugin is created inside a DIV element. Add a DIV element to the body section of your web page :

<div id="container"></div>

Note that the specified id ("container" in this example) will be used in the next step.

Creating the plugin

Now, the creation of the 3D component is as simple as :

var oViewer ;
function createViewer() {
   oViewer = new Sp3dViewer( "container", "Sp3dPlugin", 600, 300 ) ;
}

...

<body scroll="no" onLoad="createViewer();" >

...

You can note that in this example the creation function is called using the onLoad event of the body element.

Calling plugin methods

All the methods described here can be used directly on the created instance of the Sp3dViewer class. In addition, all the methods described here can be used with the object returned by the plugin() function of the Sp3dViewer class. For example, you can load a project using SceneLoadProject :

function createViewer() {
   oViewer = new Sp3dViewer( "container", "Sp3dPlugin", 600, 300 ) ;
   if( oViewer.loaded() )
      oViewer.plugin().SceneLoadProject( "http://www.yoursite.com/project.spv" ) ;
   else
      alert( "Viewer creation failed !") ;
}

In addition, the Sp3dViewer class provides a wrapper method for each function of the plugin returning a JSON string. The wrapper function converts the JSON string into a javascript object.

For example, the function SceneGetIntersectionAtWinPos of the plugin is wrapped by the function sceneGetIntersectionAtWinPos of the Sp3dViewer class. This makes possible to write something like :

function getWorldCoordinatesString( iWinX, iWinY ) {
   var oIntersection = oViewer.sceneGetIntersectionAtWinPos( iWinX, iWinY, 'terrain' ) ;
   if( oIntersection != null )
      return 'X:' + oIntersection.x + ' Y:' + oIntersection.y + ' Z:' + oIntersection.z ;
   else
      return 'Not on terrain' ;
}

Catching events

The plugin emits events. The application can listen to these events using the AddEventHandler method provided by the Sp3dViewer class.

The following example shows how to suscribe to the SceneMouseMovedEvent :

oViewer.addEventHandler(
   'SceneMouseMovedEvent', 
   function( iX, iY, iState ) {
      $('coords').innerHTML = getWorldCoordinatesString( iX, iY ) ; 
   }
) ;

Catching events

The SDK package contains many examples in the web folder of the examples directory.

Using the component in a classical Desktop application

The component is registered as an Active X Component. It can be included in any compatible Active X container. In the next subsections we will provide examples of use of the plugin with Microsoft Visual Studio (Express edition) in the following languages : C#, managed C++ and Basic.

To add the component to the Visual Studio toolbox

  1. Open the tab of the toolbox to which you want to add the components.
  2. Right-click the toolbox and select Choose Items.
  3. Select the COM Components tab.
  4. Search for the control named 'Sp3dViewer Class' and select the check box in front of the component.
  5. Click the OK button to accept the changes and see the components added to the toolbox.
The component can now be used from the toolbox like any other Forms component.

Creating the component

Whatever the language used, the creation of the control is automatically handled by the designer when the control is dragged into the Form from the toolbox.

Anyway, we will take a look at the generated code :

C#

   // The object is declared in the Form class header
   private Axnpsp3dviewerLib.AxSp3dViewer wSp3dViewer;
   
   ...
   // In the InitializeComponent method the object is created
   this.wSp3dViewer = new Axnpsp3dviewerLib.AxSp3dViewer();
   ...
   // Properties defined from the design window or defined from the properties window are applied
   ((System.ComponentModel.ISupportInitialize)(this.wSp3dViewer)).BeginInit(); 
   ... 
   this.wSp3dViewer.Enabled = true; 
   this.wSp3dViewer.Location = new System.Drawing.Point(8, 40); 
   this.wSp3dViewer.Name = "wSp3dViewer"; 
   this.wSp3dViewer.OcxState = ((System.Windows.Forms.AxHost.State)
        (resources.GetObject("wSp3dViewer.OcxState"))); 
   this.wSp3dViewer.Size = new System.Drawing.Size(824, 456); 
   ... 
   // The control is added to the main Form
   this.Controls.Add(this.wSp3dViewer);
   ...
   // The end of initialization is signaled to the object
   ((System.ComponentModel.ISupportInitialize)(this.wSp3dViewer)).EndInit();

C++

   // The object is declared in the Form class header
   private: Axnpsp3dviewerLib::AxSp3dViewer^  wSp3dViewer;
   
   ...
   // In the InitializeComponent method the object is created
   this->wSp3dViewer = (gcnew Axnpsp3dviewerLib::AxSp3dViewer());
   ...
   // Properties defined from the design window or defined from the properties window are applied
   (cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->wSp3dViewer))->BeginInit();
   ... 
   this->wSp3dViewer->Anchor = static_cast<System::Windows::Forms::AnchorStyles>( 
                                  System::Windows::Forms::AnchorStyles::Top  
                                | System::Windows::Forms::AnchorStyles::Bottom  
                                | System::Windows::Forms::AnchorStyles::Left  
                                | System::Windows::Forms::AnchorStyles::Right) ; 
   this->wSp3dViewer->Enabled = true; 
   this->wSp3dViewer->Location = System::Drawing::Point(0, 31); 
   this->wSp3dViewer->Name = L"wSp3dViewer"; 
   this->wSp3dViewer->OcxState = (cli::safe_cast<System::Windows::Forms::AxHost::State^  > 
                                 (resources->GetObject(L"wSp3dViewer.OcxState"))); 
   this->wSp3dViewer->Size = System::Drawing::Size(759, 499); 

   this->wSp3dViewer->TabIndex = 0; 
   ...
   // The end of initialization is signaled to the object
   (cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->wSp3dViewer))->EndInit(); 

Basic

   ' The object is declared at the bootom of the Form class
   Friend WithEvents wSp3dViewer As Axnpsp3dviewerLib.AxSp3dViewer
   
   ...
   ' In the InitializeComponent method the object is created
   Me.wSp3dViewer = New Axnpsp3dviewerLib.AxSp3dViewer

   ' Properties defined from the design window or defined from the properties window are applied

   ... 

    CType(Me.wSp3dViewer, System.ComponentModel.ISupportInitialize).BeginInit()

        Me.wSp3dViewer.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or 
                    System.Windows.Forms.AnchorStyles.Bottom) _
                    Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.wSp3dViewer.Enabled = True
        Me.wSp3dViewer.Location = New System.Drawing.Point(12, 28)
        Me.wSp3dViewer.Name = "wSp3dViewer"
        Me.wSp3dViewer.OcxState = CType(resources.GetObject("wSp3dViewer.OcxState"), 
                                        System.Windows.Forms.AxHost.State)
        Me.wSp3dViewer.Size = New System.Drawing.Size(697, 409)
        Me.wSp3dViewer.TabIndex = 0

   ' The viewer is added to the main form
        Me.Controls.Add(Me.wSp3dViewer)
   ...
   ' The end of initialization is signaled to the object
     CType(Me.wSp3dViewer, System.ComponentModel.ISupportInitialize).EndInit()

Calling methods

All the plugin methods described in the plugin documentation can be called directly with the created plugin instance. Note that for methods returning JSON string (representing an object or an array), the plugin provides in the Utility module some functions allowing to easily manipulate it. For both objects and arrays the principle is the same:
  1. Parse the JSON string and keep a compiled form of it on the plugin side. This is done with JsonArraySetupAccess or JsonObjectSetupAccess.
  2. Extract members values or items values from the compiled form using JsonArrayGetItemAsXxx functions or JsonObjectGetMemberAsXxx functions.
  3. Clean up the compiled form when no more access has to de done with JsonArrayReleaseAccess or JsonObjectReleaseAccess.

C#

Here is a simple example where the application fetches the cartographic extent of the GIS Layer called 'BUILDINGS' using the SceneGetExtent function. The resulting JSON object is exploited using the JsonObjectXxx family functions.

   string sJsonExtent = wSp3dViewer.GisLayerGetExtent( "BUILDINGS" ) ;
   int iExtentId = wSp3dViewer.JsonObjectSetupAccess( sJsonExtent ) ;
   double dXMin, dXMax, dYMin, dYMax ;
   dXMin = wSp3dViewer.JsonObjectGetMemberAsFloat( iExtentId, "xmin" ) ;
   dXMax = wSp3dViewer.JsonObjectGetMemberAsFloat( iExtentId, "xmax" ) ;
   dYMin = wSp3dViewer.JsonObjectGetMemberAsFloat( iExtentId, "ymin" ) ;
   dYMax = wSp3dViewer.JsonObjectGetMemberAsFloat( iExtentId, "ymax" ) ;
   wSp3dViewer.JsonObjectReleaseAccess( iExtentId ) ;

C++

The following code snippet load a project :

   this->wSp3dViewer->SceneLoadProject( sProjetUri );   

Basic

The following code snippet pops up the project selector dialog :

   wSp3dViewer.UiDisplayLocalProjectSelector()

Catching events

C#

In this language, associating a member callback function to an event of the plugin is quite verbose but really easy. In order to connect to a specific event of the plugin the application has to add a new event handler using the += operator on the related event member of the plugin.

wSp3dViewer.SceneMousePressedEvent += 
  new Axnpsp3dviewerLib.ISp3dViewerEvents_SceneMousePressedEventEventHandler(
  this.wSp3dViewer_SceneMousePressedEvent);

The event handler itself receives two parameters: the object which has emitted the event, and an event object regrouping all the event data. For example, the plugin documentation indicates about that the SceneMousePressedEvent has the following signature :

   void SceneMousePressedEvent( int iWinX, int iWinY, int iState )

The corresponding event will contain three members (integer) named :

which can be used directly in the event handler body. You can note that event member names are prefixed with p_.

private void wSp3dViewer_SceneMousePressedEvent(
    object sender, 
    Axnpsp3dviewerLib.ISp3dViewerEvents_SceneMousePressedEventEvent tEvent)
{
  wLabelMouseInfo.Value = "M Pressed: " + tEvent.p_iWinX + "," 
                                        + tEvent.p_iWinY + "," 
                                        + tEvent.p_iState ;
}

C++

This is quite similar to the C# mecanism. In order to connect to a specific event of the plugin the application has to add a new event handler using the += operator on the related event member of the plugin.

   this->wSp3dViewer->SceneProgressEvent += gcnew 
      Axnpsp3dviewerLib::ISp3dViewerEvents_SceneProgressEventEventHandler(
          this, 
          &MainForm::wSp3dViewer_Progress);

As in c# the event handler itself receives two parameters: the object which has emitted the event, and an event object regrouping all the event data. For example, the plugin documentation indicates about that the SceneMousePressedEvent has the following signature :

   void SceneMousePressedEvent( int iWinX, int iWinY, int iState )

The corresponding event will contain three members (integer) named :

which can be used directly in the event handler body. You can note that event member names are prefixed with p_.

The following example update a label with the cartographic position of the mouse in the 3D Viewport. If the mouse is on a 3D object, a computation is done to get the height of this object.

private:System::Void 
    wSp3dViewer_MouseMoved( System::Object^ sender, 
                            Axnpsp3dviewerLib::ISp3dViewerEvents_SceneMouseMovedEventEvent^ e )
{
  System::String^ sWorldPoint = 
    wSp3dViewer->SceneGetIntersectionAtWinPos( e->p_iWinX, e->p_iWinY, "terrain" ) ;

  if( sWorldPoint == "null" ) {
     this->wlblPosition->Text = "Not over the terrain" ;
         return ;
  }

  System::String^ sBuildingPoint = 
    wSp3dViewer->SceneGetIntersectionAtWinPos( e->p_iWinX, e->p_iWinY, "all" ) ;

  int iObjectWorldId = wSp3dViewer->JsonObjectSetupAccess( sWorldPoint ) ;
  int iObjectBuildingId = wSp3dViewer->JsonObjectSetupAccess( sBuildingPoint ) ;

  double dx = wSp3dViewer->JsonObjectGetMemberAsFloat( iObjectWorldId, "x" ) ;
  double dy = wSp3dViewer->JsonObjectGetMemberAsFloat( iObjectWorldId, "y" ) ;
  double dzGround = wSp3dViewer->JsonObjectGetMemberAsFloat( iObjectWorldId, "z" ) ;
  double dzObject = wSp3dViewer->JsonObjectGetMemberAsFloat( iObjectBuildingId, "z" );

  wSp3dViewer->JsonObjectReleaseAccess( iObjectWorldId ) ;
  wSp3dViewer->JsonObjectReleaseAccess( iObjectBuildingId ) ;

  if( dzGround != dzObject ) {
         double dH = dzObject - dzGround ;
         this->wlblPosition->Text="x: "+ dx.ToString("0.0")+"  y: "+dy.ToString("0.0")+
        "  z: "+dzGrounf.ToString("0.0")+"  h: "+dH.ToString("0.0");
  }
  else 
    this->wlblPosition->Text="x: "+ dx.ToString("0.0")+"  y: "+dy.ToString("0.0")+
        "  z: "+dzGround.ToString("0.0");                       
}

Basic

The easiest way to define an event handler is the following :

  1. In the design window, select the Plugin component.
  2. In the properties window, select the Events panel.
  3. In the event list, double click the event you want to connect to.
This operations will create an empty event handler connected to the specified event. You will just have to fill in the body of this function.

For example, here is the empty event handler inserted after a double-click on the :SceneProjectLoadedEvent :

Private Sub wSp3dViewer_SceneProjectLoadedEvent(
      ByVal sender As System.Object, 
      ByVal e As Axnpsp3dviewerLib.ISp3dViewerEvents_SceneProjectLoadedEventEvent
      )Handles wSp3dViewer.SceneProjectLoadedEvent

End Sub

Note that you can also directly enter this code in the source file. The event list in the design window will be updated accordingly.


SpacEyes3D Plugin SDK Documentation - generated on Tue Nov 5 11:39:14 2013 - SPACEYES