The MapDataServer is the object from which the FalconView MapRenderingEngine and MdsWrapper retrieve data about map coverage (what geographical areas are covered by files on a given data path).

The MapDataServer uses a SQL Server database to store information such as a list of data sources (paths), a list of MapHandlers (code that knows how to read a format), coverage rectangles for various map types, regions of coverage for various map types, etc.

The MapRenderingEngine keeps data about local data sources in a local database and can also interface to RemoteMapDataServers in order to load coverage data from a shared server.

Other components can elect to be notified whenever the database changes through MDSUtilNotifyEvents.

In FalconView 4.1 there is functionality, called the Distributed Map Data Server, which allows a user with the proper permissions to query the database on another machine to determine if there is data for a given region. To enable the sharing, you go into the Map data manager's paths dialog and push the share button, then users can attach to your machine by adding the entire machine name "\\MapServer" for example.

This streamlines the Map Data Management workload for users:

  • There is no coverage generation step when the user adds a map server like there is in earlier versions when the user add a one or more map paths on a machine.
  • Changes to the server machine appear immediately (next screen refresh) on the client machine so CSD updates can be performed even when users are attached to the server.
  • All of the shared data on the server machine is attached when the user attaches to the Server machine so the administrator can partition the data into manageable sizes paths without confusing the user with multiple paths in the FalconView paths dialog.

The Following code snipet will add a single record to the MapDataServer Database. This would be useful for instance if you program created a GeoTIff of an area and wanted to make it available immediately to the user without requiring the user to regenerate coverage on the entire path.

1. Import type library for map data server (DLL is installed to \pfps\MapDataServer directory)

#import "MapDataServer.dll" no_namespace, named_guids

2. First, you will need to determine the data source ID. This corresponds to a map path as shown in FalconView's map data manager Paths tab. The data source ID will be needed to insert a coverage record into the database

long lDataSourceId;
try
{
        IDataSourcesRowsetPtr smpDataSourcesRowset(__uuidof(DataSourcesRowset));

        hr = smpDataSourcesRowset->SelectAll(TRUE);
        while (hr == S_OK)
        {
            // _bstr_t containing data source path
            _bstr_t bstrFolderName = smpDataSourcesRowset->m_LocalFolderName;
        lDataSourceId = smpDataSourcesRowset->m_Identity;
            hr = smpDataSourcesRowset->MoveNext();
     }
}
catch(_com_error &e)
{
    char '''pErrorDescription = (char ''')e.Description(); // log this somewhere
}

3. The appropriate lMapSeriesId will have to be retrieved from an IMapSeriesRowset based on the scale and series of the map being output.

long lMapSeriesId;
try
{
   BSTR bstr_type;

   IMapSeriesRowsetPtr smpMapSeriesRowset(__uuidof(MapSeriesRowset));

   smpMapSeriesRowset->Initialize("Cadrg"); // you could also initialize with Cadrg, Dted, GeoTiff, etc...

   hr = smpMapSeriesRowset->SelectByScale(dScale, eScaleUnits, bstrSeries);
   if (hr == S_OK)
      lMapSeriesId = smpMapSeriesRowset->m_Identity;
}
catch(_com_error &e)
{
   char '''pErrorDescription = (char ''')e.Description();  // log this somewhere
   rslt = FAILURE;
}

4. Add an entry to the coverage table and update the region table for the map

try
{
   ICoverageRowsetPtr smpCoverageRowset(__uuidof(CoverageRowset));
   IRegionRowsetPtr smpRegionRowset(__uuidof(RegionRowset));


   smpCoverageRowset->Initialize("Cadrg");

   smpCoverageRowset->InsertSingleRec(lDataSourceId, lMapSeriesId, bstr_t(bstrFilename), 
                                   dLowerLeftLat, dLowerLeftLon, dUpperRightLat, dUpperRightLon,
                                    MAP_PROJECTION_EQUAL_ARC, lFileSizeBytes, _bstr_t(""));

   // update region table
   _variant_t vt = smpRegionRowset->SelectRegion("Cadrg", lDataSourceId, lMapSeriesId);
   if (vt.vt != VT_EMPTY)                // already a region in the table?
   {
        // delete the current region record from the DB 
        // -- we will insert a brand new one with the new cov recs added in
         smpRegionRowset->DeleteRegion("Cadrg", lDataSourceId, lMapSeriesId);
         smpRegionRowset->ExtCreateRegion("Cadrg", lDataSourceId, lMapSeriesId, vt);
   }
   else // create a new empty region record
      smpRegionRowset->CreateRegion("Cadrg", lDataSourceId, lMapSeriesId);

   smpRegionRowset->m_ProjectionMask = MAP_PROJECTION_EQUAL_ARC;
   smpRegionRowset->CombineRegion(dLowerLeftLat, dLowerLeftLon, dUpperRightLat, dUpperRightLon);
   smpRegionRowset->InsertRegion();
}
catch(_com_error &e)
{
   char '''pErrorDescription = (char ''')e.Description(); // log this somewhere
}

-- Main.ChrisBailey - 01 Nov 2006