Разработка собственных драйверов источников данных на примере растрового формата BMP
Драйверы представляют собой часть менеджера ресурсов, отвечающую за работу с файлами определённых форматов.
Данная страница содержит:
формат-local.so
. Например: bmp-local.so
. $GIS_ROOT/sbin/drivers
. EXTRA_LIBVPATH += $(INSTALL_ROOT_nto)/$(CPUVARDIR)/opt/gis/libLIBS += drv_common
EXTRA_INCVPATH += $(INSTALL_ROOT_nto)/$(CPUVARDIR)/opt/gis/include
На данный момент протестировано добавление пользовательского драйвера только для растровых форматов, т.к. для них не требуется собственный конвертер (используется единый растровый). |
#include <gis/gis_time.h>#include <gis/gishelper.h>#include <gis/gis_driver.h>#include <gis/gis_databuffer.h>#include <gis/gis_core_cfg_parser.h>
#define DRIVER_GCM_EXTENSION ".local."GIS_GCM_FILE_EXTENSION/** Obligatory driver dependent defines*/#define DRIVER_ID GIS_CORE_DRIVERS_USER_R_LOCAL#define DRIVER_CFG_SECTION "bmp-local"#define DRIVER_PREFIX "[BMP_local_driver] "
Наименование сущности | Описание |
---|---|
.connect | Подключиться к серверу. |
.get_connection_state | Получение статуса соединения с сервером. |
.get_info | Получить путь до папки, содержащей кэш карт. |
.reset_cache | Очистить источники и перекэшировать данные. |
.synchronize_cache | Синхронизировать папки источника и внутреннего формата GCM. (Добавить недостающие карты и удалить те, источников которых не обнаружено.) |
.update_map_cache | Перегенерировать карту во внутренний формат. |
gis_driver_interface_t driver_functions ={.connect = bmp_local_connect,.get_connection_state = bmp_local_get_connection_state,.get_info = bmp_local_get_info,.reset_cache = bmp_local_reset_file_cache,.synchronize_cache = bmp_local_synchronize_file_cache,.update_cache = bmp_local_update_file_cache};
Наименование сущности | Описание |
---|---|
.id | Числовой идентификатор драйвера. |
.prefix | Префикс драйвера для вывода отладочной информации. |
.initialized | Флаг проверки инициализации драйвера. |
.state | Флаг проверки установки соединения с ядром. |
.acronym | Акроним драйвера. |
.mapstyle_dirname | Имя директории хранения классификаторов/картостилей. |
.origin_maps_dirname | Имя директории в каталоге $(GIS_CORE_MAP_CACHE) где хранятся исходные файлы карт. |
.origin_extension | Расширение оригинального файла карты. |
.alt_origin_extensions | Альтернативные расширения оригинального файла карты (если есть). |
.secondary_extensions | Возможные расширения, если карта состоит из нескольких файлов. |
.driver_gcm_suffix | Расширение файла после конвертации во внутренний формат. |
gis_driver_ctx_t driver_ctx ={.id = DRIVER_ID,.prefix = DRIVER_PREFIX,.mapstyle_dirname = NULL,.initialized = false,.state = NO_CONNECT,/* Conversion function is used as callback */.convert_map = bmp_local_convert_map};
Для заполнения других полей структуры gis_driver_ctx_t следует добавить требуемые записи в конфигурационном файле ($(GIS_CONFIG_DIRECTORY)/gis-core.conf )
См. ниже функция заполнения контекста из конфигурационного файла. |
int bmp_local_convert_map( gis_core_map_information_t *map_info );int bmp_local_connect( void );int bmp_local_reset_file_cache( gis_core_user_data_t *udata );int bmp_local_synchronize_file_cache( gis_core_user_data_t *udata );int bmp_local_update_file_cache( int32_t map_id , gis_core_user_data_t *udata );int bmp_local_get_info( gis_core_driver_info_t *info );gis_core_connection_state_t bmp_local_get_connection_state( void );
bmp-local.so
).
gis_driver_interface_t
.
static int get_driver_config_variables(){/*Mandatory params*/int mandatory_error_flag = 0;if ( gis_common_driver_get_mandatory_driver_param_from_cfg( &driver_ctx.acronym,DRIVER_CFG_SECTION,DRIVER_CFG_ACRONYM,DRIVER_PREFIX ) != EOK ){mandatory_error_flag++;}if ( gis_common_driver_get_mandatory_driver_param_from_cfg( &driver_ctx.origin_extension,DRIVER_CFG_SECTION,DRIVER_CFG_FMT_EXTENSION,DRIVER_PREFIX ) != EOK ){mandatory_error_flag++;}/* extension + local.gcm */char *suffix = calloc( strlen( driver_ctx.origin_extension ) + strlen( DRIVER_GCM_EXTENSION ) + 1, sizeof( char ) );if ( !suffix ){gis_helper_debug_write( GIS_DEBUG_LEVEL_ERROR, DRIVER_PREFIX,"Memory allocation error [%s()]", __FUNCTION__ );return ENOMEM;}strcpy( suffix, driver_ctx.origin_extension );driver_ctx.driver_gcm_suffix = strcat( suffix, DRIVER_GCM_EXTENSION );/* ____________________ */if ( gis_common_driver_get_mandatory_driver_param_from_cfg( &driver_ctx.origin_maps_dirname,DRIVER_CFG_SECTION,DRIVER_CFG_MAP_FOLDER,DRIVER_PREFIX ) != EOK ){mandatory_error_flag++;}if ( gis_common_driver_get_mandatory_driver_param_from_cfg( &driver_ctx.converter_path,DRIVER_CFG_SECTION,DRIVER_CFG_CONVERTER_PATH,DRIVER_PREFIX ) != EOK ){mandatory_error_flag++;}if ( mandatory_error_flag ){gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_ERROR, DRIVER_PREFIX,"Failed reading mandatory parameters from config [%s()]", __FUNCTION__ );return EINVAL;}return EOK;}
enum driver_opts{DRIVER_OPT_SYNC = 0,DRIVER_OPT_END};static const char *driver_opts_keys[] ={[DRIVER_OPT_SYNC] = "sync",[DRIVER_OPT_END] = NULL};static bool sync_initial_source = false;static bool sync_initial_source_is_hard = false;gis_driver_interface_t *bmp_local_init( char *options ){int config_return_res = get_driver_config_variables();if ( config_return_res != 0 ){gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_ERROR, DRIVER_PREFIX,"Failed to get config variables (RESULT=%d) [%s()]", config_return_res, __FUNCTION__ );return NULL;}char *value;while ( *options != '\0')switch ( getsubopt( &options, ( char *const *__restrict )driver_opts_keys, &value ) ){case DRIVER_OPT_SYNC:sync_initial_source = true;if ( value == NULL ){gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_INFO, DRIVER_PREFIX, "Source synchronization is enabled [%s()]", __FUNCTION__ );}else{if ( !strcmp( value, "hard" ) ){sync_initial_source_is_hard = true;gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_INFO, DRIVER_PREFIX, "Source hard synchronization is enabled [%s()]", __FUNCTION__ );}else{gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_INFO, DRIVER_PREFIX, "Source synchronization is enabled [%s()]", __FUNCTION__ );}}break;default:gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_INFO, DRIVER_PREFIX, "Unknown option '%s' [%s()]", value, __FUNCTION__ );break;}if ( gis_common_driver_check_folders( &driver_ctx ) != EOK )return NULL;driver_ctx.initialized = true;if ( sync_initial_source ){if ( sync_initial_source_is_hard ){gis_common_driver_reset_gcm_database( driver_ctx.id );if ( bmp_local_reset_file_cache() != EOK )return NULL;}else{if ( bmp_local_synchronize_file_cache() != EOK )return NULL;}}return &driver_functions;}
int bmp_local_convert_map( gis_core_map_information_t *map_info ){gis_timer_t timer;int res = 0;const char *directory = gis_helper_env_get_maps_cache_directory();const char *gis_root = gis_helper_env_get_gis_root_directory();char converter_path[GIS_MAX_PATH_LENGTH];char map_filepath[GIS_MAX_PATH_LENGTH];char gcm_filepath[GIS_MAX_PATH_LENGTH];char orig_basename[GIS_MAX_PATH_LENGTH];gis_common_driver_get_basename_without_extension( map_info->src_fname, &orig_basename );gis_helper_timer_start( &timer );// Fill <gcm_fname> field as outputsprintf( map_info->gcm_fname, "%s.%s", orig_basename, driver_ctx.driver_gcm_suffix );sprintf( map_filepath, "%s/%s/%s", directory, driver_ctx.origin_maps_dirname, map_info->src_fname );sprintf( gcm_filepath, "%s/%s/%s", directory, GIS_CACHE_SUBDIR_GCM, map_info->gcm_fname );sprintf( converter_path, "%s/%s", gis_root, driver_ctx.converter_path );gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_INFO, DRIVER_PREFIX, "Loading map '%s' to cache [%s()]", map_filepath, __FUNCTION__ );res = spawnl( P_WAIT, converter_path, converter_path,"-m", map_filepath,"-o", gcm_filepath,NULL );if ( res != 0 ) {gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_ERROR, DRIVER_PREFIX, "Executing error: %d [%s()]", WEXITSTATUS( res ), __FUNCTION__ );return ( EFAULT );}gis_helper_timer_stop( &timer );gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_INFO, DRIVER_PREFIX, "bmp map conversion time: %f sec [%s()]", gis_helper_timer_get_result_sec( &timer ), __FUNCTION__ );return EOK;}
int bmp_local_connect( void ){if ( !driver_ctx.initialized )return ENXIO; // - Not initializedif ( driver_ctx.state == CONNECTED )return EALREADY;driver_ctx.state = CONNECTED;return EOK;}
gis_core_connection_state_t bmp_local_get_connection_state( void ){return driver_ctx.state;}
int bmp_local_get_info( gis_core_driver_info_t *info ){const char *directory = gis_helper_env_get_maps_cache_directory();sprintf( info->orig_fpath, "%s/%s", directory, driver_ctx.origin_maps_dirname );return EOK;}
int bmp_local_reset_file_cache( void ){bmp_local_synchronize_file_cache();gis_helper_debug_write_lvl( GIS_DEBUG_LEVEL_INFO, DRIVER_PREFIX, "File cache database reset [%s()]", __FUNCTION__ );return EOK;}
int bmp_local_synchronize_file_cache( void ){return gis_common_driver_sync_cache( &driver_ctx, 0 );}
int bmp_local_update_file_cache( int32_t map_id ){if ( driver_ctx.state != CONNECTED )return ECONNREFUSED;return gis_common_driver_update_cache( &driver_ctx, map_id );}
Предыдущий раздел: Руководство разработчика