This section describes the basics on how to configure and setup VisioDevKit to run within your application. In general, the product will need to perform the following steps listed below:
To create a VisioDevKit view, you're going to need some data. Visioglobe, in almost all circumstances, will provide you with the data you need.
For information on the sample data bundle provided with the VisioDevKit sample projects, please write to contact@visioglobe.com.
VisioDevKit uses the data configuration file to "describe" what datasets are available within the provided data bundle. VisioDevKit also uses the data configuration to know more specific information related to each dataset, such as what layers are support and what binaries need to be loaded to support those layers.
The data configuration extract below shows the format of the xml descriptor file.
Within the data bundle provided with each of our samples, there is a configuration file, named "vg_config.xml". Generally, you won't need to tweak this file. However if you do, it is at your own risk and we suggest that you make a back-up file first.
For further information on loading configuration or selecting a dataset see Load Configuration or Select Dataset.
Once the dataset is ready, the next step is to create an instance of the Visioglobe Application within your application.
The instance of the application is created once the VgEAGLView has been added to the view and has been started. For example, supposing in your MainWindow.nib you have added a VgEAGLView and bound it to an IBOutlet variable called m3DView.
@interface VisioDevKitHelloWorldViewController : UIViewController { VgEAGLView* m3DView; VgApplication::VgIApplication* mVgApp; ... } @property (retain) IBOutlet VgEAGLView* m3DView; ... @end - (void)viewDidLoad { [super viewDidLoad]; // Must call startAnimation before calling getApplication [m3DView startAnimation]; mVgApp = [m3DView getApplication]; ... }
The instance of the application is created once the VgSurfaceView has been created. The VgSurfaceView can be added in layouts and will be created once the layout is loaded.
Refer Navigation Example for a more detailed sample code for Android.
// FIELDS VgSurfaceView mVgView = null; VgIApplication mVgApp; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... setContentView(R.layout.main_layout); // main_layout contains a VgSurfaceView. mVgView = ((VgSurfaceView) findViewById(R.id.VgSurfaceView)); // All interfacing with the VisioDevKit should be performed within it's own thread. mVgView.queueEvent(new Runnable() { public void run() { mVgApp = mVgView.getApplication(); ... } }); ... }
Now that we have an instance of the Visioglobe application we need to configure it. This is done via a call to loadConfiguration and passing a configuration file. The configuration file contains a set of datasets, each of them representing a coherent, packaged set of data (for example a city). See VgEngine::VgIDatabase::loadConfiguration for more information.
bool lSuccess = mVgApp->editEngine()->editDatabase()->loadConfiguration("config.xml", 123456789, "my-secret-license");
boolean lSuccess = mVgApp.editEngine().editDatabase().loadConfiguration("config.xml", 123456789, "my-secret-license");
Note : as the code is very similar between iOS and Android, only Objective-C code will be used in coming snippets.
In VisioDevKit v2.0, there is only support for a single dataset. Support for handling multiple datasets will arrive in later versions of the SDK. For the meantime, it is necessary to select the first dataset using VgEngine::VgIDatabase::selectDataset, passing 0 as a parameter.
bool lSuccess = mVgApp->editEngine()->editDatabase()->selectDataset(0);
There may be several layers within a dataset, and it's possible to hide and show each of those layers independently.
Below is a code snippet showing the first layer being set to visible.
int lFloorIndex = 0; VgEngine::VgLayerManager::LayerList& lLayers = mVgApp->editEngine()->editLayerManager()->editLayers(); if (lLayers.size() > lFloorIndex) { lLayers[pFloorIndex]->setVisible(true); }
Before developing for Android using VisioDevKit there are some things you need to know.
Firstly, the VisioDevKit doesn't run on the main UI thread. It runs on the GL thread. This point is important because it implies that anytime a VisioDevKit API is called, it must be called from within the GL Thread. This can be done by following the below technique:
public void printVersion() { setContentView(R.layout.main_layout); final VgSurfaceView lSurfaceView = (VgMySurfaceView) findViewById(R.id.VgSurfaceView); lSurfaceView.queueEvent(new Runnable() { public void run() { Log.i("VisioDevKit", "Hello from the GL thread!"); Log.i("VisioDevKit", "VisioDevKit version:" + lSurfaceView.getApplication().editEngine().editLicenseManager().getVersion()); } }); }
SUMMARY: As a rule, never call a VisioDevKit API from outside of the GL Thread. A VisioDevKit API called from any other thread will have an undefined behaviour.
On Android the interface to the VisioDevKit is via the VgSurfaceView class, which extends the GLSurfaceView. When the activity which has loaded the VgSurfaceView is paused, the GL context of that view is not preserved.
The good news is that Visioglobe take care of saving the OpenGL context for you. If the activity containing the GLSurfaceView is paused and resumed, your map, map state, textures, will all still be available. On Android the graphics resources are reset when the GLSurfaceView is initially created. This is visible, when you look within the following method VgMySurfaceView.onSurfaceCreated(GL10 pGL, EGLConfig pGLConfig).
Be warned that because the VisioDevKit is compiled using JNI, any references VisioDevKit holds to external objects (such as VgPostDrawCallback) won't be counted when it comes to garbage collection. If you don't guard a reference to an object before adding it to the VisioDevKit, it will eventually be garbage collected. This causes a dangling pointer within VisioDevKit and eventually a crash at some point when VisioDevKit tries to call it.