Страницы

Добро пожаловать

< Выберите раздел для просмотра

среда, 31 августа 2016 г.

Python в ArcGIS. Комментирование и документирование строк. 24

     Важная часть написание кода это создание комментариев и строк документации.
    Создание комментариев осуществляется с помощью символа #, весь текст на строке после данного символа игнорируется интерпретатором: 

"""
# Calculate average mean
list_1 = [10, 20, 30]
print sum(list_1)*len(list_1)**-1
"""

    Создание строк документации сильно выручает, когда возвращаешься к давно созданному, когда передаёшь скрипт коллеге, когда просят создать описание для программ и др. Документирование выглядит следующим образом:

"""
# -*- coding:utf-8 -*-
def none_list(n):
    """
    n - any int number, n have to be > 0
    Возвращает список длиной n, в котором все элементам присвоено None.
>>> none_list(3)
[None, None, None]
>>> [none_list(n) for n in range(4)]
[[], [None], [None, None], [None, None, None]]
    >>> none_list(-1)
    Traceback (most recent call last):
      ...
    ValueError: n must be >= 0
    >>> none_list(5.3)
    Traceback (most recent call last):
      ...
    ValueError: n must be exact integer
"""
    if not n >= 0:
        raise ValueError("n must be >= 0")
    if isinstance(n, int):
        result = [None for i in range(n)]
    else:
        raise ValueError("n must be integer")
    return result
"""
    В интерпретаторе выглядит следующим образом:


    Обратите внимание на подсказку при использовании функции, всплывает пояснение насчёт параметров функции.
    Также в любой момент можно вызвать и ознакомиться со строками документации для некоторой функции/класс/модуля:


вторник, 30 августа 2016 г.

Python в ArcGIS. Создание простого инструмента-скрипта в ArcGIS Python Toolbox. 23

    Чтобы добавить в скрипт в Python Toolbox необходимо:

1. Нажмите правой кнопкой мыши на определённый Python Toolbox в ArcCatalog выберите "Edit".

2. Всё содержимое заменяется на следующий код:

"""
import arcpy


class Toolbox(object):
    def __init__(self):
        """Define the toolbox (the name of the toolbox is the name of the
        .pyt file)."""
        self.label = "Toolbox_2"
        self.alias = ""

        # List of tool classes associated with this toolbox
        self.tools = [Script1]

class Script1(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "Script1"
        self.description = ""
        self.canRunInBackground = False

    def getParameterInfo(self):
        """Define parameter definitions"""
        param0 = arcpy.Parameter(
            displayName= u"Параметер 1".encode('cp1251'),
            name="parameter_1",
            datatype="String",
            parameterType="Required",
            direction="Input")
        param1 = arcpy.Parameter(
            displayName=u"Параметер 2".encode('cp1251'),
            name="parameter_2",
            datatype="String",
            parameterType="Required",
            direction="Input")
        parameters = [param0, param1]
        return parameters

    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        return True

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""
        return

    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each tool
        parameter.  This method is called after internal validation."""
        return

    def execute(self, parameters, messages):
        """The source code of the tool."""
        arcpy.AddMessage("Number of %s is %s" % (parameters[0].valueAsText, parameters[1].valueAsText)))
        return
"""

3. В коде создаётся класс с название "Script1". В функции "getParameterInfo" настраиваются параметры, что их 2, что тип данных необходим "String", какие подписи использовать при вызове окошка инструмента и пр. Функции "isLicensed", "updateParameters", "updateMessages"  - без изменений. В "execute" помещается код, который должен непосредственно выполняться при приёме указанных параметров.





Python в ArcGIS. Создание простого инструмента-скрипта в ArcGIS ToolBox. 22

    Чтобы добавить скрипт в ArcGIS Toolbox необходимо:
1. Нажмите правой кнопкой мыши на определённый Toolbox в ArcCatalog выберите "Add script".


2. Заполните поля, выберите настройки, нажмите далее.
3. Выберите необходимый файл скрипта. В качестве примера я использую файл .py следующего содержания:

"""
from sys import argv
from arcpy import AddMessage

parameter_1 = argv[1]
parameter_2 = argv[2]

AddMessage("Number of %s is %s" % (parameter_1, parameter_2))
"""

4. Следующий шаг - установка параметров, если в вашем скрипте нет входных/выходных параметров можете завершать создание инструмента. В скрипте-примере присутствует два входных параметра*, соответственно и в инструменте должно два параметра и порядок совпадать с нумерацией в теле скрипта. Выберите входной тип данных, чаще всего используется 'String', чтобы избежать возможных несовместимостей. 


5. Завершаем создание инструмента-скрипта и запускаем его.



* В скрипте используются системные параметры, в arcpy есть свои операторы для установки входных и выходных параметров (см. GetParameter, GetParameterAsText, SetParameter, SetParameterAsText и др.).






понедельник, 29 августа 2016 г.

Python в ArcGIS. Запуск скриптов из командной строки. 21

    Создайте текстовый файл следующего содержания в некоторой директории, назовите его, допустим, "arcgis_script":

"""
from sys import argv

parameter_1 = argv[1]
parameter_2 = argv[2]

print "Number of %s is %s" % (parameter_1, parameter_2)
"""

   Сохраните его с расширением .py. Затем поднимитесь на один уровень каталога в проводнике вверх и нажмите на директории правой кнопкой мыши с зажатой клавишей Shift, в контекстном меню выберите "Открыть в командной строке".

    Далее необходимо ввести интерпретатор языка Python, который вы хотите использовать (в моём случае "C:\Python27\ArcGIS10.2\python.exe"), полный или относительный путь к файлу, который вы хотите запустить и параметры.





   

пятница, 19 августа 2016 г.

Python в ArcGIS. Приведение адресов к общему виду. 20

   Пусть поле с адресом называется 'Address'.  

    Отсечение индекса:
"""
# "625053, Тюменская область, город Тюмень, Восточный административный округ, ул. Николая Гондатти, д. 13 (МАОУ СОШ №92)"

", ".join(!Address!.split(', ')[1:])
"""

    Удаление элементов между запятыми, которые включают определённые символы, слова, например, 'административный округ':
"""
# "Тюменская область, город Тюмень, Восточный административный округ, ул. Николая Гондатти, д. 13 (МАОУ СОШ №92)"

def f(x, t=u'административный округ'):
    y =  x.split(', ')[:]
    for a in x.split(', '):
        if t in a:
            y.remove(a)
    return ", ".join(y)
f(!Address!)
"""

    Обычная замена символов, слов:

"""
!Address!.replace(u'г.', u'город')
"""

    Поиск потерянных пробелов около определённых слов:

"""
# "Тюменская область, город Тюмень, пр.Солнечный, д.24"
def f(x):
    try:
        y = x.split(u'пр.')
        if y[1][0] == u' ':
            a = x
        else:
            a = u"пр. ".join(y)
    except IndexError:
        a = x
    return a
f(!Address!)
"""

    Все буквы преобразуем в заглавные:

"""
!Address!.upper()
"""

    Удаляем лишние пробелы:

"""
# "Тюменская область, город Тюмень, ул.  Геологоразведчиков, д. 14"
u" ".join([j.replace(u' ', u'') for j in !ADDRESS!.split(u" ")])
# если пробелы не исчезают, попробуйте в аргументы оператора replace скопировать
# удаляемый символ напрямую
"""

    Локализация изменений с помощью положения в строке:

"""
# "Тюменская область, Ялутуровский район, д. Новый Кавдык, ул. Новая д.20"
# необходимо добавить запятую и пробел в обозначении дома
# но не поменять обозначение деревни
def f(x):
 a = x[:-7]
 b = x[-7:]
 c = b.replace(u' д.', u', д. ')
 return a+c

f(!Address!)
"""


Python в ArcGIS. Классификация с помощью словаря. 19

    Когда в скрипте необходимо создать переменную в зависимости от значения другой переменной обычно используют конструкции if / elif / else. На информатике подобное называют множественным ветвлением. Например:

"""
population = 437000
x = population
if  x > 5000000:
    city_id = 1
elif  x < 5000000 and x >= 3000000:
    city_id = 2
elif  x < 5000000 and x >= 3000000:
    city_id = 2
elif  x < 3000000 and x >= 1000000:
    city_id = 3
elif  x < 1000000 and x >= 500000:
    city_id = 4
elif  x < 500000 and x >= 250000:
    city_id = 5
elif  x < 250000 and x >= 100000:
    city_id = 6
elif  x < 100000 and x >= 10000:
    city_id = 7
elif  x < 10000:
    city_id = 8
else:
    print 'error'

"""
    В случае когда входное значение может принадлежать всей шкале, без специальных исключений, удобно использовать словарь, в котором ключи будут вычисляться. Конструкция выглядит наглядней, её легче читать и править:

"""
population = 437000
x = population
city_id = {
    x > 5000000: 1,
    x < 5000000 and x >= 3000000: 2,
    x < 3000000 and x >= 1000000: 3,
    x < 1000000 and x >= 500000: 4,
    x < 500000 and x >= 250000: 5,
    x < 250000 and x >= 100000: 6,
    x < 100000 and x >= 10000: 7,
    x < 10000: 8
}[True]
"""

четверг, 18 августа 2016 г.

Python в ArcGIS. Функции и передача параметров в них. 18

    Функция с позиционными параметрами:

"""
def func_1(a, b):
    print a, b

func_1(10, 20)
"""



    Функция с произвольным количеством аргументов:

"""
def func_2(*args):
    print type(args)
    print args

func_2(10, 20, 30, 40)
func_2([10, 20, 30, 40])
func_2(*[10, 20, 30, 40])
"""


    Функция с именованными аргументами:

"""
def func_3(a=10, b=20):
    print a, b

func_3()
func_3(100, 200)
func_3(100)
func_3(a=100, b=200)
func_3(b=200)
"""


    Функция с произвольным количеством именованных аргументов:

"""
def func_4(**kwargs):
    print kwargs

func_4()
func_4(b=1, d=2)
e = {'a1': 1, 'a2': 2}
func_4(**e)
"""


   Теперь глянем на пример всего вместе:

"""
def func_5(a, b, *args, **kwargs):
    print a, b, args, kwargs

func_5(1, 2)
func_5(1, 2, 3, 4)
func_5(1, 2, 3, 4, e=5, f=6, g=7)
"""


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

"""
# AddField_management (in_table, field_name, field_type, {field_precision}, {field_scale}, {field_length}, {field_alias}, {field_is_nullable}, {field_is_required}, {field_domain})
# Инструмент имеет 3 обязательных параметра и 7 необязательных 
# про особенности параметров см. на официальном сайте ArcGIS

arcpy.AddField_management('table_1', 'name_1', 'TEXT')
arcpy.AddField_management('table_1', 'name_1', 'TEXT', '', '', '', '', '', '', '')
t = ('table_1', 'name_1', 'TEXT')
arcpy.AddField_management(*t)

arcpy.AddField_management('table_1', 'name_2', 'TEXT', field_length='255')
arcpy.AddField_management(field_name='name_2', field_length='255', field_type='TEXT', in_table='table_1')
arcpy.AddField_management('table_1', 'name_2', 'TEXT', '', '', '255', '', '', '', '')
w = ('table_1', 'name_2', 'TEXT')
arcpy.AddField_management(*w+('', '', '255'))

"""

среда, 17 августа 2016 г.

Python в ArcGIS. Универсальный курсор для добавления данных в таблицу. 17

    Чтобы добавить одну строку в данные удобно использовать следующую функцию:

"""
def func_cursor_in_table(in_table, in_fields, in_values):
    cursor_u = arcpy.da.InsertCursor(in_table=in_table, field_names=in_fields)
    cursor_u.insertRow(in_values)
    del cursor_u
"""

    В качестве параметров укажите таблицу, список полей и список значений соответствующих указанным полям.


Python в ArcGIS. Создание копий списков и словарей. 16

    Чтобы создать копию списка или словаря недостаточно присвоить равенство новой переменной, т. е.:

"""
list1 = [0, 1, 2, 3, 4, 5]
list2 = list1
dict1 = {'a': 1, 'b': 2, 'c': 3}
dict1 = dict2
"""
    Таким образом создаётся копия ссылки на один и тот же лист, словарь. Чтобы создать  полноценные копии используйте следующие конструкции:

"""
list1 = [0, 1, 2, 3, 4, 5]
list2 = list1[:]

dict1 = {'a': 1, 'b': 2, 'c': 3}
dict2 = dict1.copy()
"""

Python в ArcGIS. Как прописать Null в поле. 15

    Чтобы заполнить поле значениями <Null> необходимо прописать служебное слово None.


вторник, 16 августа 2016 г.

Python в ArcGIS. Функция аналогичная инструменту Append на курсорах. 14

    После обработки данных во временном рабочем пространстве полученные результаты грузятся в конечную базу с помощью инструмента arcpy Append. Опытным путём было испытано, что часто данный инструмент обременяет базу дополнительной нагрузкой, поэтому чаще используется альтернативный способ добавления данных через курсоры. 

Функция добавления данных через курсоры:
"""
def cursor_append(source_table, target_table, fields):
    with arcpy.da.SearchCursor(source_table, fields) as cur_m, arcpy.da.InsertCursor(target_table, fields) as app_cur:
        for row_q in cur_m:
            app_cur.insertRow(row_q)

cursor_append('any_source_table', 'any_target_table', ["ID", "NAME", "DESCRIPTION"])
"""

Python в ArcGIS. Создание временной базы данных. 13

    Не оптимально проводить геообработку на данных из высоко-нагруженной базы. Для этой ситуации выгодно создать временную базу данных, в ней провести обработку, а потом добавить результаты в конечную базу. 
   Простой скрипт для создания временной базы:

"""
def func_scratch_base(scratchfolder):
    from arcpy.management import CreateFileGDB
    from uuid import uuid1
    name = str(uuid1()).upper()
    res = CreateFileGDB(scratchfolder, '{}.gdb'.format(name), '')
    return res[0]
"""


Python в ArcGIS. Использование объекта - результата выполненных инструментов. 12

     Каждый инструмент ArcGIS возвращает объект Result. Он имеет свой уникальный идентификатор, включает в себя входные и выходные параметры и пр. Чтобы не формировать путь к результату самому оптимально забирать данные из объекта-результата.

"""
result1 = arcpy.CreateMosaicDataset_management('any_workspace', 'any_name', 'template_fc')
print result1[0] 
u'any_workspace\\any_name'
# в противном случае пришлось бы использовать модуль os.path
"""

"""
result2 = arcpy.GetCount_management('any_fc')
print result2[0]
"""

Python в ArcGIS. Создание атрибутивных SQL-запросов для инструментов геообработки. 11

    Часто в теле скрипта приходится формировать выражения для инструментов геообработки, например следующего вида:
" OBJECTID = 1340 " к полю long, " SUBJECT = 'Республика Адыгея' " к текстовому полю,
 ну или совсем что-то составное:
" (NAME = 'Железнодорожная станция' OR NAME = 'Железнодорожный вокзал') AND (CITY = 'Инта' OR CITY = 'Ульяновск' OR CITY = 'Тында') AND ID_CODE IN (34, 37, 43, 47)".

"""
query_field_1 = "OBJECTID"
query_value_1 = 1340
expression = """ {0} = {1} """.format(query_field_1, query_value_1)
print expression
arcpy.MakeTableView(in_table="table_1", out_view="layer_1", where_clause=expression)
"""

"""
query_field_1 = "SUBJECT"
query_value_1 = u'Республика Адыгея'
expression = """ {0} = {1} """.format(query_field_1, query_value_1)
print expression
arcpy.MakeTableView(in_table="table_1", out_view="layer_1", where_clause=expression)
"""

"""
query_field_1 = "NAME"
query_value_1 = u"Железнодорожная станция"
query_value_2 = u"Железнодорожный вокзал"
query_field_2 = "CITY"
city_1 = u"Инта"
city_2 = u"Ульяновск"
city_3 = u"Тында"
query_field_3 = "ID_CODES"
codes = (34, 37, 43, 47)
expression = """ ({0} = '{1}' OR {0} = '{2}') AND ({3} = '{4}' OR {3} = '{5}' OR {3} = '{6}') AND {7} IN ({8}) """.format(query_field_1, query_value_1.encode('utf-8'), query_value_2.encode('utf-8'), query_field_2, city_1.encode('utf-8'), city_2.encode('utf-8'), city_3.encode('utf-8'), query_field_3, ",".join(map(str, codes)))
print expression
arcpy.MakeTableView(in_table="table_1", out_view="layer_1", where_clause=expression)
"""


Python в ArcGIS. Функция перевода текстовой даты вида "YYYY*MM*DD" в формат datetime. 10

    Функция имеет следующий вид (в качестве * могут быть любые символы, кроме чисел):

"""
def yyyy_mm_dd_to_datetime(x):
from datetime import date
from re import findall
date1 = map(int, findall(r'(\d*)\D+(\d*)\D+(\d*)', x)[0])
return date(date1[0], date1[1], date1[2])
"""


Python в ArcGIS. Разный импорт arcpy. 9

    Любой модуль Python может быть загружен по-разному, в зависимости от способа меняется дальнейший код.

"""
# Общий вариант:
import arcpy
arcpy.sa.Raster()

# Импорт отдельного пакета инструментов
from arcpy import sa
sa.Raster()

# Импорт отдельного инструмента
from arcpy.sa import Raster
Raster()

# C переименованием:
from arcpy.sa import Raster as tool_1
tool_1()
"""

Python в ArcGIS. Функция для генерации текстового GUID. 8

    Функция выглядит следующим образом:

"""
def guid(x):
import uuid4 from uuid
# если скобки не нужны - удалите их из выражения
return '{%s}' % str(uuid4()).upper()
"""


Python в ArcGIS. Малые функции для работы с числовыми данными. 7

    Функция для перевода десятичных текстовых значений с запятой в десятичные числа:
"""
def to_dot(x):
return float(x.replace(',','.'))
"""

    Функция для округления чисел
"""
# x - число, которое необходимо округлить, y - кол-во знаков сохраняемое в дробной части
def rounding(x, y):
return round(x, y)
"""

    Функция "чтобы поделить целое на целое и получилось дробное:
"""
def segmentation(a, b):
return a*b**-1
"""


Python в ArcGIS. Функция для извлечения всех уникальных значений из поля таблицы. 6

    Функция выглядит следующим образом:

"""
def get_values_from_field(in_table, field):
    bo_list_id = []
    with arcpy.da.SearchCursor(in_table, field) as cur5:
        for row in cur5:
if row[0] not in bo_list_id:
bo_list_id.append(row[0])
    return bo_list_id
"""


Python в ArcGIS. Функция для разбора текстовой записи координат вида dd* mm' ss,sss''. 5

"""
def vavilon_to_mercator(a):
    from re import findall
    ux = a.encode('utf-8')
    urx = ux.replace(u' ', '') if u' ' in ux else ux
    try:
        first_number = int(urx[0])
    except ValueError:
        urx = urx[1:]
    urx = urx.replace(u',', '.') if u',' in ux else urx
    rx = findall(r'(\d*).(\d*).(\d*.\d*)..', urx)[0]
    roll_360 = lambda x: int(x[0])+int(x[1])*60.**-1+float(x[2])*3600**-1
    return roll_360(rx)
"""
  
    Пригодится, когда текстовые координаты имеют определённый вид, см. в примере.


   *Если функция не работает, то чаще всего связано с кодировкой входного текста.

Python в ArcGIS. Использование справочной информации об элементах модуля arcpy. 4

    При работе со средствами геообработки часто приходится использовать документацию по инструментам на официальных сайтах arcgis:
http://desktop.arcgis.com/ru/arcmap/latest/tools/main/a-quick-tour-of-geoprocessing-tool-references.htm
http://resources.arcgis.com/ru/help/main/10.2/index.html

    Использование команды help в консоли python
"""
help(arcpy.da)
help(arcpy.Geometry)
help(arcpy.Buffer_analysis)
"""
    Пример, чтобы проверить состав входных параметров инструмента.

Python в ArcGIS. Консоль Python и функция транскрипции текста. 3

    Консоль Python в ArcGIS - удобный встроенный инструмент для несложных операций.


"""
def latinizator(x):
legend = { 'а': 'a','б': 'b','в': 'v','г': 'g','д':'d','е':'e','ё':'yo', 'ж':'zh',
    'з':'z','и':'i','й':'y','к':'k','л':'l','м':'m','н':'n','о':'o','п':'p','р':'r',
    'с':'s','т':'t','у':'u','ф':'f','х':'h','ц':'ts','ч':'ch','ш':'sh','щ':'shch',
    'ъ':'y','ы':'y','ь':"'",'э':'e','ю':'yu','я':'ya','А':'A','Б':'B','В':'V','Г':'G',
    'Д':'D','Е':'E','Ё':'Yo','Ж':'Zh','З':'Z','И':'I','Й':'Y','К':'K','Л':'L','М':'M',
    'Н':'N','О':'O','П':'P','Р':'R','С':'S','Т':'T','У':'U','Ф':'F','Х':'H','Ц':'Ts',
    'Ч':'Ch','Ш':'Sh','Щ':'Shch','Ъ':'Y','Ы':'Y','Ь':"'",'Э':'E','Ю':'Yu','Я':'Ya'}
for i, j in legend.items():
x = x.replace(i, j)
return x
"""

Python в ArcGIS. Извлечение свойств геометрии объектов. 2

    Через окно "Field Calculator" есть простая возможность извлекать свойства геометрии объектов, такие как длина линий, координаты точки, площадь, экстент и др.

"""
# рассчитать площадь полигона (в поле типа Double)
!SHAPE!.area

# определние координаты X и Y для точки (в поле типа Double)
!SHAPE!.X
!SHAPE!.Y

# извлечение свойств экстента объектов
# экстремальные значения для экстента  (в поле типа Double)
!SHAPE!.extent.XMin
!SHAPE!.extent.XMax
!SHAPE!.extent.YMin
!SHAPE!.extent.XMax

# координата X для левой нижней точки экстента (в поле типа Double)
!SHAPE!.extent.lowerLeft.X

"""
   См. другие свойства геометрии объектов на официальном сайте ArcGIS https://pro.arcgis.com/ru/pro-app/arcpy/classes/extent.htm


понедельник, 15 августа 2016 г.

Размышления. Человек. 4

    Презрение или полное равнодушие к вещам, которыми не можешь обладать - иллюзия с фундаментом из тщеславия.

Размышления. Человек. 3

    Человек способный пронести ярость сквозь время - сильный человек, способный направить ярость в продуктивность - великий (Москва, 2016).

Размышления. Человек. 2

    Если мужчина при жене откровенно пялится на другую женщину, это является не только хорошим примером эволюционного механизма, известного как эффект Кулиджа, невоспитанности, но и того, что сущность человека - единство множества определений, которые не только различны, но и вступают в противоречие друг с другом (Москва, 2015).

Размышления. Человек. 1

    Слабому самцу стаи человекообразных обезьян не доставалось доступной пищи и он, испытывая голод и осознание тщетного использования зубов, добыл ядро ореха камнем, добыл ли подобным образом право спариваться? Если вы это прочитали то, вероятно, да.
    P.S. Использовать камень ему показала мать, а мужики похоже всегда путали орех и чью-то голову.

Python в ArcGIS. Использование окна "Field Calculator". 1

    Самым простым использованием Python в ArcGIS Desktop являются манипуляции с атрибутивными данными через окно "Field Calculator".

    В приведённом примере используется следующая функция:
"""
def func(x):
 if x > 0:
  a = 1
 else:
  a = 0
 return a
"""
    При выполнении в поле "INDEX", будет рассчитано значение по указанной функции, которая в качестве аргумента принимает значение из поля "X" (в той же строке).

    *Если позволяет код, есть возможность отказываться от конструкции полноценной функций и использовать краткий синтаксис (т. н. lambda-функции). 



"""
1 if !X! > 0 else 0

"""

T. И. Ойзерман Размышления. Изречения

T. И. Ойзерман Размышления. Изречения - М.: Языки славянской культуры, 2013. - 216 с.

Прекрасные мысли.

http://www.ozon.ru/context/detail/id/19725946/