понедельник, 5 октября 2009 г.

Динамическое создание сервиса карты (ArcGIS)

Во время работы над последним проектом возникла необходимость динамического создания сервиса карты, его публикации и удаления.



Суть задачи:
Есть шаблонный mxd-документ, в котором присутствуют какие-то слои (а может он вообще пустой). Пользователь выбрал фичекласс (где выбрал и как - значения не имеет. В нашем проекте информация о фичеклассах хранилась в кастомном репозитории. По хранящейся там информации мы могли подключиться к СДЕ и "вытянуть" выбранный фичекласс) и захотел просмотреть его на Flex карте (Карты Flex работают с REST сервисами ArcGIS) с настройками и слоями, имеющимися в шаблонном документе.
Решение:
Для решения задачи было принято решение динамически создавать сервис и подсовывать карте линк на новый сервис. Почему создавать динамически? Ответ очевиден: приложение многопользовательское. Одновременно несколько клиентов могут запросить отрисовку различных фичеклассов, значит каждому необходимо сгенерировать свое изображение, а это значит свой сервис.
Каждый сервис карты базируется на каком-либо mxd-документе, который и отображается (или к которому осуществляется доступ через REST). Значит для каждого выбранного фичекласса нам был необходим отдельный документ, который также создавался динамически на основании шаблонного документа.
Создание сервиса карты заключается в создании новой конфигурации сервера. Конфигурация содержит такие настройки, как имя сервиса, описание, количество одновременных подключений, тип сервиса, тип запуска и т.д. (http://edndoc.esri.com/arcobjects/9.1/ComponentHelp/esriServer/IServerObjectConfiguration.htm).
В нашем случае было необходимо создать сервис карты типа MapServer с автоматическим запуском.

Собрав все вышесказанное, мы получили приведенный ниже код:

// коннектимся к Гису
ESRI.ArcGIS.Server.IGISServerConnection gisconnection =
new ESRI.ArcGIS.Server.GISServerConnectionClass();

gisconnection.Connect("server");
 

// получаем SOM
ESRI.ArcGIS.Server.IServerObjectManager som = gisconnection.ServerObjectManager;
 

// создаем контекст
IServerContext servContext = som.CreateServerContext(String.Empty, String.Empty);
 

// создаем документ
IMapDocument doc = (IMapDocument)servContext.CreateObject("esriCarto.MapDocument");
 
// открываем существующий документ
doc.Open(@"c:\Work\Test\MapServerTest\Untitled.mxd", String.Empty);
 

// подключение к воркспейсу к воркспейсу
IWorkspace ws = null;

//
// код создания свойств подключения к воркспейсу (IPropertySet) 
// и подключения
//


// выбираем фичекласс
IFeatureClass fc = ((IFeatureWorkspace)ws).OpenFeatureClass("db.user.FeatureClass");

// берем карту
IMap map = doc.get_Map(0);

// создаем новый слой на основе полученного фичекласса
IFeatureLayer layer = (IFeatureLayer)servContext.CreateObject("esriCarto.FeatureLayer");
layer.FeatureClass = fc;
layer.Name = "Layer";
layer.Visible = true;

// добавляем слой на карту и обновляем изображение
map.AddLayer(layer);
map.RecalcFullExtent();
doc.ActiveView.Refresh();

// новое имя дока
string newDocName = @"c:\Work\Test\MapServerTest\" + Guid.NewGuid().ToString() + ".mxd";

// сохраняем новый док (полученный из шаблонного с добавлением слоя)
doc.SaveAs(newDocName, false, true);

// получаем админа
IServerObjectAdmin admin = gisconnection.ServerObjectAdmin;

// создаем новую конфигурацию для нового сервиса


IServerObjectConfiguration configuration = admin.CreateConfiguration();

//
// Description - описание
// IsPooled - с пулом или без
// Name - имя
// MaxInstances - максимальное количство подключений

// IsolationLevel - уровень изоляции создаваемых в контексте
// объектов
// MinInstances - минимальное количество подключений
// StartupType - тип запуска
//

configuration.Description = "New created configuration";
configuration.IsPooled = false;
configuration.Name = "Service1";
configuration.TypeName = "MapServer";
configuration.MaxInstances = 10;
configuration.IsolationLevel = esriServerIsolationLevel.esriServerIsolationHigh;
configuration.MinInstances = 1;
configuration.StartupType = esriStartupType.esriSTAutomatic;
 

// конфигурим свойства
if (configuration.Properties == null)
configuration.Properties = (IPropertySet)servContext.CreateObject("esriSystem.PropertySet");

configuration.Properties.SetProperty("FilePath", newDocName);

// конфигурим доп. свойства
// эти 2 свойства необходимы для подключения к сервису 

// через веб приложения (например, флексовые карты)
configuration.RecycleProperties.SetProperty("WebEnabled", "true");
configuration.RecycleProperties.SetProperty("WebCapabilities", "Map,Query,Data");

// добавляем новую конфигурацию сервиса
admin.AddConfiguration(configuration);
// запускаем конфигурацию
admin.StartConfiguration(configuration.Name, configuration.TypeName);



Для удаления сервиса используем метод админа DeleteConfiguration(...):
admin.DeleteConfiguration(configuration.Name, configuration.TypeName);

Комментариев нет:

Отправить комментарий