ArcGIS Desktop

  • ArcGIS Pro
  • ArcMap

  • My Profile
  • Справка
  • Sign Out
ArcGIS Desktop

ArcGIS Online

Картографическая платформа вашей организации

ArcGIS Desktop

Полноценная профессиональная ГИС

ArcGIS Enterprise

ГИС предприятия

ArcGIS Developers

Инструменты для встраивания приложений с местоположениями

ArcGIS Solutions

Бесплатные шаблоны карт и приложений для отрасли

ArcGIS Marketplace

Получение приложения и данных для вашей организации.

  • Документация
  • Поддержка
Esri
  • Войти
user
  • Мой профиль
  • Выход

ArcMap

  • На главную
  • Начало работы
  • Карта
  • Анализ
  • Управление данными
  • Инструменты
  • Дополнительные модули

Вызов DLL из инструмента-скрипта

  • принцип работы
  • Подробности

Новое в Python версии 2.5 это – ctypes, библиотека внешний функций. Она обеспечивает C-совместимые типы данных и позволяет вызывать функции с помощью динамически-подключаемых библиотек (DLL) или других общих библиотек. Используя модуль ctypes в Python, в инструменте-скрипте геообработки можно использовать код ArcObjects, написанный в C++ .

Применяя ctypes в Python, вы можете с легкостью изменять параметры и типы инструмента-скрипта без перекомпиляции кода C++. Модуль ctypes поддерживает любую C- функцию с основными типами данных, например char, int, float и double , а также structs and pointers.

Возможность вызова DLL из скрипта Python дает множество преимуществ. Вы можете использовать с выгодой для себя тонко настроенные классы ArcObjects в ваших заданиях по геообработке, ваша интеллектуальная собственность будут защищена, и это намного проще сделать, чем пользоваться интерфейсами IGPFunction2 и IGPFunctionFactory. Вы создаете ваш объект в Python и вызываете метод выполнения (execute), передавая необходимые параметры из скрипта при помощи структуры геокодирования.

принцип работы

Необходимо выполнить следующие действия:

Создание проекта C++ Win32 в Visual Studio 2008, поддерживающего экспорт простой функции с прототипом:

int GpExecutetool(char* parameter1, char* parameter2)

Не забудьте включить в проект директорию ArcGIS\com\directory и импортировать файлы ArcObjects.olb.

Создайте инструмент-скрипт в пользовательском наборе инструментов, где производится проверка этих двух параметров и их переотправка в скрипт.

Ваш скрипт Python сделает следующее:

  • Импорт arcpy и ctypes.
  • Получит параметры от инструмента-скрипта
  • Импортирует DLL в память.
  • Наведите курсор на функцию в DLL.
  • Укажите необходимые типы аргументов функций, экспортированных из DLLs, установив атрибут argtypes и обратный тип.
  • Передайте параметры в C++ code в DLL.

Подробности

Проект C++ project (именуемый для данного примера GPToolAsSimpleDLL) является простым проектом Win32, который добавляет в класс пространственных объектов поле AREA и вычисляет его значение.

Файл заголовка

#ifdef GPTOOLASSIMPLEDLL_EXPORTS
#define GPTOOLASSIMPLEDLL_API extern "C"__declspec(dllexport)
#else
#define GPTOOLASSIMPLEDLL_API extern "C"__declspec(dllimport)
#endif
GPTOOLASSIMPLEDLL_API int GPexecutetool(char*, char*);

Файл – источник GPToolAsSimpleDLL открывает указанный класс полигональных объектов и устанавливает указанное поле в область (area) каждого полигонального объекта. Каждая функция геообработки, которую вы пишете, может быть реализована простой точкой входа функции С (C function), все в одном и том же DLL, вместе с компаньонами инструмента-скрипта, чтобы каждая функция была видна в ArcToolbox.

GPTOOLASSIMPLEDLL_API int GPexecutetool(char* featureclassPath, char* fieldname)
{
    // Convert char*s to bstring
    _bstr_t catalogPath;
    catalogPath = featureclasspath;
    _bstr_t newfieldname;
    newfieldname = fieldname;
    // Coinitialize GP utilities class
    IGPUtilitiesPtr ipUtil(CLSID_GPUtilities);
    // Feature class holder
    IFeatureClassPtr ipFeatureclass(0);
    HRESULT hr;
    // Try to fetch feature class from catalog path
    if (FAILED(hr = ipUtil->OpenFeatureClassFromString(catalogPath, &ipFeatureclass)))
    {
        return -1;
    }
    // Index position of the specified field
   	long fieldIndex;
   	ipFeatureclass->FindField(newfieldname, &fieldIndex);
    // Set up query filter and feature cursor
   	IQueryFilterPtr ipFilter(CLSID_QueryFilter);
   	IFeatureCursorPtr ipCursor;
   	IFeaturePtr ipRow;
   	IGeometryPtr ipShape;
    // Open search cursor on feature class
   	ipFeatureclass->Search(ipFilter, VARIANT_FALSE, &ipCursor);
    // Iterate
    esriGeometryType gt;
    for (ipCursor->NextFeature(&ipRow);
       		ipRow != NULL;
         ipCursor->NextFeature(&ipRow))
    {
         // Get row's associated geometry
		       ipRow->get_Shape(&ipShape);
		       // Ensure we've got a polygon
		       ipShape->get_GeometryType(&gt);
		       if (gt != esriGeometryPolygon)
			          return -2;
		       // Get area
		       IAreaPtr ipArea(ipShape);
         double area;
		       ipArea->get_Area(&area);
		       // Pop double into a variant
         VARIANT value;
		       value.vt = VT_R8;
		       value.dblVal = area;
		       // Set double variant onto target field
		       ipRow->put_Value(fieldIndex, value);
	       	// Save
	       	ipRow->Store();
    }
    return S_OK;
}

Скрипт Python действует как брокер, принимая два параметра от инструмента-скрипта в текстовом виде и пересылая их в функцию DLL какchar*, разделенные нулем строки. До вызова функции в DLL данный скрипт использует также инструмент геообработки Добавить поле. Это может сделать ваш рабочий процесс более сложным, требующим реализации вашей персональной функциональности в C++ в сочетании с выполнением общих задач в Python.

import arcpy
import ctypes
# Get the parameters from the script tool dialog
#
shp = arcpy.GetParameterAsText(0)
fieldName = arcpy.GetParameterAsText(1)
# See if the field already exists in the feature class.
#   If not, add it.
if len(arcpy.ListFields(shp, fieldName)) == 0:
    arcpy.AddField_management(shp, fieldName, "DOUBLE")
# Import DLL into memory and get a pointer to the function
#   Note: be sure the DLL is in your Python search path 
#
dll = ctypes.cdll.GPToolAsSimpleDLL
perform_function = dll.GPExecutetool
# Tell ctypes the function accepts two char* arguments
#
perform_function.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
# Tell ctypes the function return type
#
perform_function.restype = ctypes.c_int
# Call the function in the DLL
#
retval = perform_function(shp, fieldName)
# Check the return value.  If a 0 returned, success!
#
if retval == 0:
    arcpy.AddMessage("Success")
elif retval == 1:
    arcpy.AddError("Unable to open " + shp)
elif retval == 2:
    arcpy.AddError("Not a polygon feature class")

ArcGIS Desktop

  • На главную
  • Документация
  • Поддержка

ArcGIS

  • ArcGIS Online
  • ArcGIS Desktop
  • ArcGIS Enterprise
  • ArcGIS
  • ArcGIS Developer
  • ArcGIS Solutions
  • ArcGIS Marketplace

Об Esri

  • О нас
  • Карьера
  • Блог Esri
  • Конференция пользователей
  • Саммит разработчиков
Esri
Расскажите нам, что вы думаете.
Copyright © 2021 Esri. | Конфиденциальность | Правовая информация