Using FalconView™ Map Rendering in another Application
In most instances, users want to leverage all of the capibilities of FalconView™ including the map handling, overlays, and editors. This leads to a solution that uses ILayer and ILayerEditor to add a new feature on top of the FalconView™ Application. Other times there is an existing application that has some very specific functionality that simply wants to improve the map rendering functionality. The Map Rendering Engine, allows a third party to use the component that FalconView™ uses to render its backgrounds (CADRG, CIB, DTED etc...) to draw the backgrounds in a third-party application.
The FalconView™ rendering engine is a new set of components used in FalconView™ 4.0 to draw the background maps. The engine is also used in JMPS 1.2.2 and 1.2.3 and can be used by other applications to render the MapTypes supported by FalconView.
The Engine draws the requested map into any Windows Device Context (DC). It also provides methods to project from device coordinates (X,Y) to Geo locations (lat/lon).
The Map Rendering Engine depends on the FalconView™ Coverage Database which is managed through the FalconView™ (or JMPS) Map Data Manager. Because of this, any application using the Map Rendering Engine will need a copy of the FalconView Application to manage the map data. Alternativly, the 3rd party application will need to duplicat the functionality of the Map Data Manager for generating coverage, copying map data and adding or deleting Map Data paths.
The central method on IMapRenderingEngine is
MapStatusCodeEnum? DrawMap? (int hDC , Bool display_wait_cursor , Int map_drawn_from_scratch , String pbstrOutOfSyncDSs , String pbstrOfflineDSs )
Which is called to render the map to the screen.
The MapRenderingEngine retrieves coverage data and a path to the files containing the maps from the MapDataServer. The MapDataServer is shared between FalconView and JMPS.
The rendering engine uses a ISettableMapProj to define what will be or what has been drawn.
Heis is a list of the MAPENGINELib enumerations
Code Sample
The C# RenderEngineCodeSample creates a .NET forms application which draws the map to the screen and interacts with the user via arrow keys and the the page up/down keys.
-- ChrisBailey - 24 May 2005
Q)
This seems like it can be a very useful tool. The C# example is very helpful, but I'm interested in working with the Map Rendering engine in C++. I noticed that the interfaces that are needed are defined in MapRenderingEngine.idl, but I am unable to locate that file in the SDK or on this web site. Can anyone point me to the location of this file? Thanks!
A)
All the type libraries you need are imbedded in the DLLs themselves. To include MapRenderingEngine support in your C++ program, add the line:
#import "C:\pfps\MapDataServer\MapRenderingEngine.dll" no_namespace, named_guids
Then, to create an instance of the rendering engine:
IMapRenderingEnginePtr smpRenderingEngine(uuidof(MapRenderingEngine));
-- Thomas Moore - 27 Mar 2006
Q)
Is it correct to assume that there is no interface to load\draw threat and route data from a file? So if I wanted this functionality, which I do, I would have to write my own code to draw the icons, routes, ...etc and place them in my window is this correct?
-- Judie Stanley - 12 Apr 2006
A)
Correct the map rendering engine only draws the backgrounds (not any overlays) so you would need to do this yourself.
-- Chris Bailey - 18 Apr 2006
Q) Looking at the MapEngineTest? example, how would I change the rotation and zoom values? Do I need to call SetMapType? each time my heading and/or zoom value changes? Or is there a call similar to ChangeCenter? I can use?
-- John Allen - 26 Jul 2006
A) You can call SetMapType? each time and pass in a mask stating that only the rotation / zoom was changed.
Q) What is the purpose of the functions ChangeToBest?, ChangeToClosestScale?, ChangeToLargestScale?, and ChangeToSmallestScale??
-- John Allen - 26 Jul 2006
A)
ChangeToBest - First calls ChangeToClosestScale and if no data is available will change to a Blank map.
ChangeToClosestScale - Find the closest available scale to the given scale. FalconView uses this in the Go To dialog for instance.
ChangeToLargestScale - Change to the largest available map in the given category. Would be the same as calling ScaleIn until it failed.
ChangeToSmallestScale - Change to the smallest available map in the given category. Would be the same as calling ScaleOut until it failed. For example, the smallest map in the Raster category is Tiros WORLD.
Q)
What are the allowed values for map_source in SetMapType I can't find a list anywhere, and the only one that works for me is "TIROS". I would like to use a CADRG type map.
-- Sara Siegal - 20 Sep 2006
A)
You can get a complete list of map types by using the map handlers and the map series rowset objects. Following is an example in C++:
#import "MapDataServer.dll" no_namespace, named_guids
SomeMethod()
{
try
{
IMapHandlersRowsetPtr smpMapHandlersRowset(__uuidof(MapHandlersRowset));
IMapSeriesRowsetPtr smpMapSeriesRowset(__uuidof(MapSeriesRowset));
HRESULT hr = smpMapHandlersRowset->SelectAll();
while (hr == S_OK)
{
smpMapSeriesRowset->Initialize(smpMapHandlersRowset->m_MapHandlerName);
HRESULT hrSeries = smpMapSeriesRowset->SelectAll();
while (hrSeries == S_OK)
{
// In SetMapType map_source corresponds to m_ProductName
_bstr_t bstrProductName = smpMapSeriesRowset->m_ProductName;
double dScale = smpMapSeriesRowset->m_Scale;
MapScaleUnitsEnum eScaleUnits = static_cast<MapScaleUnitsEnum>(smpMapSeriesRowset->m_ScaleUnits);
_bstr_t bstrSeries = smpMapSeriesRowset->m_SeriesName;
hrSeries = smpMapSeriesRowset->MoveNext();
}
hr = smpMapHandlersRowset->MoveNext();
}
}
catch(_com_error &e)
{
// handle errors here
}
}
That is the basic idea to get you started. There are some additional subtleties such as not all map handlers have a renderer (e.g., RDTED). To check to see if a map handler supports rendering you can query the map handler for the IMapRender interface. Also, a quicker way to retrieve map types that have data available on the system, rather than enumerating through all map types, is to use the region rowset object (also defined in the MapDataServer).
Q)
I am looking to use the MapRenderingEngine and would like to render georeferenced MIL2525 symbols onto it. What is the best way to do this? What COM interfaces/libraries should I be looking to use? I want this to run without an instance of Falconview... meaning only using MapRenderingEngine and some additional COM components.
-- Oleg Bisker - 05 Dec 2006
A) You can do this with just the MapRenderingEngine. In the Init method you will need to pass in an !IMapRenderingEngineCallback interface that you've implemented to allow you to have a chance to render your symbols to the map.
Q)
Is there a way to get get access to the SkyView engine in the same way that I can the MapEngine? so that it can be implemented into an application?
-- Daniel Anderson - 04 Feb 2007
A) No. However, you can automate SkyView (camera position, adding objects, etc...) via the automation interfaces.
Q) What are the valid values for SetBrightness and SetContrast Every value I have tried passing in has had no effect.
A) The valid values for SetBrightness are between [-1.0, 1.0]. The valid values for SetContrast are [-1.0, 1.0] for the contrast and [0, 255] for the midval.
-- Nick La Due - 05 Feb 2007
Q) When displaying maps with the mapengine is there a way to change the name of the JMPS server that the engine is looking for? I want to modify the data in the tables but I don't want to break the installation of FalconView on the machine so I thought I could have two databases, one named JMPS_SQL_SERVER for FV and one named something else that mine would connect to.
-- Daniel Anderson - 15 Feb 2007
A) Change the value of SQLServerName? in the registry key HKEY_LOCAL_MACHINE\SOFTWARE\MissionPlanning.
Q) That sounds like it would change where both the engine AND FalconView are looking. Is there any way to have FV pointing one place and a mapengine application pointing somewhere else. As a last resort I could change the registry entry when my app starts up before mapengine initializes and then switch it back to .\JMPS_SQL_SERVER so that if FalconView is started up it looks at the JMPS one, but how often does MapEngine check the registry entry? If it's only when mapEngine initializes and then it stores the name internally I'm fine, but if it reads it while the program is running it's going to get confused.
A) Changing the registry key would change the database name used by both the engine and FalconView (which uses the engine). The map data server will read the registry key periodically - whenever creating a new connection to the DB - not just a single time at startup.
Q) Is there a way to remotely control the SkyView NG application (load maps, add object, move the camera...) without starting up fvw.exe?
-- Daniel Anderson - 26 Feb 2007
A) Currently, there is a coupling between SkyView NG and FalconView. This is because SkyView retrieves maps from FalconView's IMap interface. There is no way to control SkyView without starting up fvw.exe.
Q) I'm using Visual Studio and calling into the MapRenderingEngine in my application. My application often crashes with the debugger pointing to ISettableMapProj::geo_to_surface_dbl and claiming there is an access violation. I'm calling it like:
double x0 = 0, y0 = 0, lat, lon; int res; // lat lon are initialized somewhere here myProjP->geo_to_surface_dbl(lat, lon, &x0, &y0, &res);
I don't really get why there would be an access violation since I've declared all the variables. I do call this function many times, very fast, from a couple of threads. Are there any issues with thread safety or speed in the MapRenderingEngine? Thanks!
-- Sara Siegal - 29 Mar 2007
A) Make sure you add a try/catch block and examine the Description. Also, check the FalconView error log.
try
{
...
myProjP->geo_to_surface_dbl(...)
...
}
catch(_com_error &e)
{
char '''pErrorMsg = (char ''')e.Description();
// log the error
}
Also, make sure you marshall the ISettableMapProj to your other thread properly.
Q) Could you explain that last comment a bit more? Do I need to do anything besides pass a pointer?
-- Sara Siegal - 30 Mar 2007
Q) Additionally, when I try the above code, I don't catch the exception. When I add another catch block I do:
try
{
myProjP->surface_to_geo_dbl(...);
}
catch(_com_error &e)
{
char '''pErrorMsg = (char ''')e.Description();
// log the error
}
catch(...)
{
// log the error
}
I always end up in the second block. Thanks! -- Sara Siegal - 02 Apr 2007
A) If you are getting into a catch(...) block then something is wrong with your code (not a COM exception). Also, you can't just pass a COM pointer to a thread. You need to marshall it (see CoMarshalInterThreadInterfaceInStream and CoUnmarshalInterface in MSDN). Did you check the FalconView error log? Is myProjP non-NULL?
You are here: FVDev > MapRenderingEngine
