Beruflich Dokumente
Kultur Dokumente
ArcGIS
Introducción
En este capítulo, trataremos algunos temas que son de una naturaleza más
avanzada. Específicamente, usted aprenderá cómo acceder a la REST API de
ArcGIS utilizando el módulo de solicitudes de Python. Al hacerlo usted aprenderá
cómo obtener acceso a los datos y servicios publicados por ArcGIS Server y ArcGIS
Online. El módulo de solicitudes de Python incluye funciones que permiten que su
script pueda enviar peticiones a una URL endpoint y recibir respuestas en varios
formatos, incluyendo el popular formato JSON. Hacia el final del capítulo, tendremos
también más de un par de ArcP y varios temas, incluido el uso de los objetos
FieldMappings FieldMap y combinar conjuntos de datos y trabajando también con
ValueTables para situaciones en las que una herramienta tiene la capacidad de
aceptar múltiples entradas.
Introducción a ArcGIS REST API
Antes de adentrarnos demasiado en la codificación, usted necesita entender
algunos conceptos básicos de la REST API de ArcGIS. Usted necesita conocer
específicamente cómo construir una URL e interpretar la respuesta que se devuelve.
Preparándose
Todos los recursos y operaciones de la REST API de ArcGIS están expuestos a
través de una jerarquía de puntos finales, que analizaremos a medida que
avanzamos en el curso de este libro. Por ahora, vamos a examinar los pasos
específicos que debe comprender para poder presentar una solicitud a la API a
través de Python. En estas instrucciones aprenderá a usar el directorio de servicios
de ArcGIS SERVER para construir las solicitudes URL.
Cómo hacerlo...
Vamos a usar una instancia del servidor ArcGIS públicamente disponible para
aprender a utilizar las herramientas proporcionadas por el Directorio de Servicios
para construir una petición de URL:
http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/
Demographics/ESRI_Census_USA/MapServer.
Observe que esto sigue el patrón visto aquí:
http://<host>/<site>/rest/services/<folder>/<serviceName>/<serv
iceType>
4. Hacer clic en los diferentes enlace, observe cómo cambia el URL en la barra de
direcciones. Esta URL es muy importante porque le proporciona el contenido que
será presentado a través de una solicitud de Python:
solicitudes para ArcGIS REST API. Este es un paso muy importante. La sintaxis de
la solicitud incluye la ruta al recurso junto con un nombre de operación seguida por
una lista de parámetros. El nombre de operación indica el tipo de operación que se
realiza contra el recurso. Por ejemplo, puede que desee exportar un mapa a un
archivo de imagen.
siguiente URL:
http://<resource-url>/<operation>?<parameter1=value1>&<paramete
r2=value2>
7. Los servicios del directorio contiene cuadros de diálogo que puede utilizar para
generar valores de parámetro. Usted puede encontrar enlaces a estos cuadros de
diálogo en la parte inferior de la página Servicios. En el explorador, vaya a
http://sampleserver1.arcgisonline.com/
ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/1
12. En un próximo paso, podrás aprovechar esta misma URL, enviar la solicitud, y
procesar los resultados usando Python.
¿Cómo funciona?
Los servicios de directorio de una instancia del servidor ArcGIS proporcionan una
variedad de herramientas que puede utilizar para generar solicitudes de URL y
examinar las respuestas esas peticiones de producir. En este procedimiento,
aprendió a utilizar la tarea de consulta para construir una consulta de atributos. Al
hacerlo, ha aprendido cómo se construye una petición de URL.
Hay una serie de módulos de Python que puede utilizar para hacer el resto de
solicitudes. ¡Realmente, hay demasiadas! Los módulos incluyen urllib2, httplib2,
pycurl, solicitudes y peticiones. Definitivamente es el mejor del grupo en mi opinión.
Es limpia y fácil de usar para repetir la interacción con RESTful APIs. Una vez que
haya hecho la solicitud, se podrá analizar la respuesta de JSON con el módulo json
Python. En este procedimiento aprenderá a hacerlo.
Preparándose
Las solicitudes Python módulo puede ser utilizado para enviar las peticiones a un
recurso del servidor ArcGIS y procesar la respuesta devuelta. Siga estos pasos para
aprender los pasos básicos involucrados en la presentación de solicitudes y el
procesamiento de la respuesta mediante el módulo de solicitudes:
Cómo hacerlo...
Antes de comenzar, asegúrese de haber descargado e instalado el módulo de
solicitudes, utilizando el pip. Si aún no lo ha hecho, me han proporcionado las
siguientes instrucciones para instalar tanto el PIP y el módulo de solicitudes:
Este ejercicio y todas los ejercicios de este capítulo se utilizan el módulo de requests de
Python. Si usted no tiene ya este módulo instalado en tu equipo, tendrás que hacerlo en
este momento. Las solicitudes módulo se instala mediante pip, se necesita instalarlo en
su equipo antes de que el módulo de solicitudes este instalado. Las versiones posteriores
de Python 2.7.9 incluyendo (en la serie python2) y Python 3.4 incluyen pip por defecto,
por lo que puede tenerlo ya. Para poner a prueba para ver si ya pip tiene instalado, puede
introducir lo siguiente desde un indicador de DOS:PIP instalar solicitudes.
3. Crear una nueva variable que contiene una dirección URL a una lista de servicios
ofrecidos por ArcGIS Online. Esta dirección URL contiene un formato de salida de
pjson, un formato JSON contenida en un amplio formato para facilitar la legibilidad.
r = requests.get(agisurl)
import requests
import json
agisurl = "http://server.arcgisonline.com/arcgis/rest/ services?f=pjson"
r = requests.get(agisurl)
print(r.text)
6. Guardar script
10. Guardar y ejecutar el script para ver la salida. Las cargas() método ha
convertido la salida json en un diccionario de Python:
{u'folders': [u'Canvas', u'Demographics', u'Elevation', u'Ocean', u'Reference',
u'Specialty', u'Utilities'], u'services': [{u'type': u'MapServer', u'name':
u'ESRI_Imagery_World_2D'}, {u'type': u'MapServer', u'name':
u'ESRI_StreetMap_World_2D'}, {u'type': u'GlobeServer', u'name':
u'I3_Imagery_Prime_World'}, {u'type':
u'GlobeServer', u'name': u'NASA_CloudCover_World'}, {u'type':
u'MapServer', u'name': u'NatGeo_World_Map'},
{u'type': u'MapServer', u'name': u'NGS_Topo_US_2D'},
{u'type': u'MapServer', u'name': u'Ocean_Basemap'},
{u'type': u'MapServer', u'name': u'USA_Topo_Maps'},
{u'type': u'MapServer', u'name': u'World_Imagery'},
{u'type': u'MapServer', u'name': u'World_Physical_Map'},
{u'type': u'MapServer', u'name': u'World_Shaded_Relief'},
{u'type': u'MapServer', u'name': u'World_Street_Map'},
{u'type': u'MapServer', u'name': u'World_Terrain_Base'},
{u'type': u'MapServer', u'name': u'World_Topo_Map'}], u'currentVersion': 10.2}
Cómo funciona…
En esta procedimiento sencillo, aprendió a utilizar el módulo Python requests
para enviar una solicitud a una instancia del servidor ArcGIS mediante el método
quests.get (), y, a continuación, procesar la respuesta del servidor. El método
json.loads () se utilizó para convertir la respuesta a un diccionario de Python para
agilizar el procesamiento de objetos. La respuesta contiene datos básicos acerca
de la instancia del servidor ArcGIS, incluyendo carpetas, servicios y versiones.
Veremos ejemplos más complejos en los próximos procedimientos.
Un mapa de recursos de servicio contiene los conjuntos de datos que pueden incluir
tablas o capas. Contiene información básica acerca de un servicio, incluyendo
características capas, tablas y descripciones de servicios. En este procedimiento
aprenderá a devolver información de capa de un mapa de servicio, usando Python
y ArcGIS REST API.
Preparándose
Para obtener información sobre una capa de un mapa específico servicio, deberá
hacer referencia al número de índice que está asociado con la capa. Cuando
examine la página de directorio de servicios para un servicio, encontrará una lista
de las capas que forman parte del mapa servicio junto con números de índice para
cada capa. Los números de los índices se usan en lugar del nombre de la capa
cuando soliciten información acerca de una capa. Como hemos hecho en el pasado
con pocos procedimientos, usaremos el módulo Python requests para realizar la
solicitud y procesar la respuesta.
Cómo hacerlo...
Siga estos pasos para saber cómo obtener información sobre una capa de un
servicio de mapa:
3. Crear la siguiente variable agisurl. Esto servirá como la base de la URL que hace
referencia a una capa específica en el ESRI_CENSUS mapa de servicio de
EE.UU. Aquí, nos estamos refiriendo a una capa con un número de índice igual
a 1. Además, incluyen un formato de salida de pjson
y Python
El ArcGIS REST API tiene un amplio conjunto de operaciones que puede utilizar al
solicitar información de una instancia del servidor de ArcGIS. Por ejemplo, puede
exportar los mapas, capas, consulta geocodificar direcciones, y mucho más. En este
procedimiento naprenderá a exportar un mapa a partir de un mapa de imagen
pública.
Preparándose
La operación de exportación puede ser utilizada para crear la imagen de un mapa
de un mapa de servicio. La respuesta a esta solicitud incluye la URL de la imagen,
la anchura, la altura, el alcance y la escala. En esta receta, podrá utilizar la operación
de exportación para exportar un mapa como un archivo de imagen.
Cómo hacerlo...
1. En el entorno de desarrollo de Python, crear un nuevo script, guardar como:
C:\ArcpyBook\Ch12\ExportMapToImage.py.
2. Importe los modulos requests y json
import requests
import json
3. Crear una nueva variable llamada agisurl, asigne la dirección URL y la operación
de exportación, tal y como se muestra aquí:
import requests
import json
agisurl = http://sampleserver1.arcgisonline.com/ArcGIS/rest/
services/Specialty/ESRI_StateCityHighway_USA/MapServer/export
4. Crear un nuevo objeto de diccionario que contendrá los pares clave / valor
que ayudan a definir la cadena de consulta. Estos son los parámetros que se
pasarán a la operación de exportación:
import requests
import json
agisurl = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/
services/Specialty/ESRI_StateCityHighway_USA/MapServer/export"
payload = { 'bbox':'-115.8,30.4, 85.5,50.5',
'size':'800,600',
'imageSR': '102004',
'format':'gif',
'transparent':'false',
'f': 'pjson'}
9. Copiar y pegar la dirección URL del archivo .gif que se generó en la barra de
direcciones del navegador y, a continuación, haga clic en volver en su teclado
para ver el archivo:
Cómo funciona…
La operación de exportación en el ArcGIS API REST puede utilizarse para exportar
un archivo de imagen de un servicio de mapa. Si examina
http://sampleserver1.arcgisonline.com/ArcGIS/rest/
servicios/Especialidades/ESRI_StateCityHighway_EE.UU/MapServer/export, que
hemos utilizado para generar la imagen del mapa en este procedimiento, verá el
término exportar al final de la URL. Esto es lo que desencadena la ejecución de la
operación de exportación. Además, se anexa un cuadro delimitador (mapa),
tamaño, punto de referencia espacial para la imagen y el formato a través de la
variable de carga útil. La solicitud se envía al servidor a través del método
requests.get () que acepta tanto la variable de URL y la carga útil
Consultar un servicio de mapa con ArcGIS
Cómo hacerlo...
1. En IDLE o en otro entorno de desarrollo de Python, crear un nuevo script de
python llamado QueryMapService.py y guárdelo en la carpeta
C:\carpeta\ArcpyBook Ch12.
2. En el explorador, vaya a http://resources.arcgis.com/en/help/ arcgis-rest-
api/index.html#//02r3000000p1000000. . Esta es la página del REST API para la
operación de consulta contra una capa de un mapa de servicio. A medida que
se desplaza hacia abajo en la página de ayuda, usted debería ver los mismos
parámetros que se generaron utilizando el cuadro de diálogo, tales como
geometry, geometryType, spatialRel inSR, where, y otros.
3. En tu script importa los modulos requests y json
import requests
import json
4. Crear la siguiente variable agisurl. Esto servirá como la base de la URL que hace
referencia a la operación de consulta en el grupo de capas census block
(identificado por un identificador de 1 en la URL) en el servicio de mapas
ESRI_Census_USA:
import requests
import json
agisurl = http://sampleserver1.arcgisonline.com/ArcGIS/rest/services
/Demographics/ESRI_Census_USA/MapServer/1/query
5. Ahora, cree un objeto de diccionario de Python, como se muestra en el siguiente
código. Vamos a dejar de lado algunos de los parámetros que no están definidas
o utilizado en el cuadro de diálogo. Sólo estamos creando un atributo consulta
en esta instancia a fin de que todos los parámetros de geometría pueden ser
eliminados.
import requests
import json
agisurl = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/
services/Demographics/ESRI_Census_USA/MapServer/1/query"
payload = { 'where':'STATE_FIPS = \'48\' and CNTY_FIPS =
\'021\'','returnCountOnly':'false',
'returnIdsOnly': 'false', 'returnGeometry':'false',
'outFields':'POP2000,POP2007,BLKGRP',
'f': 'pjson'}
6. El método requests.get () puede aceptar un objeto de diccionario Python como
el segundo parámetro. Este diccionario define el conjunto de pares clave / valor
que ayudan a definir la cadena de consulta. Añadir el método requests.get ()
import requests
import json
agisurl = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/
services/Demographics/ESRI_Census_USA/MapServer/1/query"
payload = { 'where':'STATE_FIPS = \'48\' and CNTY_FIPS =
\'021\'','returnCountOnly':'false', \
'returnIdsOnly': 'false', 'returnGeometry':'false', \
'outFields':'POP2000,POP2007,BLKGRP', \
'f': 'pjson'}
r = requests.get(agisurl, params=payload)
7. Incluir una instrucción print para imprimir la respuesta que se devuelve.
r = requests.get(agisurl, params=payload)
#print(r.text)
decoded = json.loads(r.text)
10. El diccionario de objetos Python devuelto por los json.loads () contendrá el
contenido del objeto JSON. A continuación, puede eliminar de los elementos de
datos individuales fuera del diccionario. En este caso, queremos sacar los
atributos de cada una de las característica que se devuelve (BLKGRP, POP
POP2007 y2000). Podemos hacerlo utilizando el siguiente código, que tendrás
que añadir a su script:
r = requests.get(agisurl, params=payload)
#print(r.text)
decoded = json.loads(r.text)
for rslt in decoded['features']:
print("Block Group: " + str(rslt['attributes']['BLKGRP']))
print("Population 2000: " + str(rslt['attributes']['POP2000']))
print("Population 2007: " + str(rslt['attributes']['POP2007']))
Cómo funciona…
La operación de consulta en el resto de ArcGIS API se puede utilizar para realizar
consultas espaciales y atributo contra una capa de un servicio de mapas en ArcGIS
Server. Se utilizó el método requests.get () para realizar una consulta de atributos
contra la capa del census block groups. Hemos incluido varios parámetros,
incluyendo una cláusula where que devolverá sólo los registros en los que el
ST_código FIPS es 48 y el código FIPS Cnty_021 (el condado de Bexar, Texas). El
objeto Response se convirtió entonces a un diccionario de Python y hemos incluido
un bucle for para iterar a través de todos los registros devueltos e imprimir el bloque
nombre de grupo, y de la población para los años 2000 y 2007.
Preparándose
La operación find de REST API de ArcGIS puede ser usado para encontrar las
coordenadas geográficas de una sola dirección. Como lo hemos hecho en los
últimos procedimientos, vamos a utilizar el módulo requests de Python para hacer
el proceso de solicitud y la respuesta.
Cómo hacerlo...
1. En IDLE o en otro entorno de desarrollo de Python, crear un nuevo script de
python llamado GeocodeAddress.py y guárdelo en la carpeta
C:\carpeta\ArcpyBook Ch12.
import requests
import json
agisurl = "http://geocode.arcgis.com/arcgis/rest/services/World/
GeocodeServer/find"
payload = { 'text': '1202 Sand Wedge, San Antonio, TX, 78258','f':'pjson'}
r = requests.get(agisurl, params=payload)
decoded = json.loads(r.text)
5. Imprimir algunos de los resultados:
import requests
import json
agisurl = "http://geocode.arcgis.com/arcgis/rest/services/World/ GeocodeServer/find"
payload = { 'text': '1202 Sand Wedge, San Antonio, TX, 78258','f':'pjson'}
r = requests.get(agisurl, params=payload)
decoded = json.loads(r.text)
Cómo funciona…
La operación de búsqueda en el ArcGIS API REST puede ser utilizada para realizar
las operaciones de geocodificación de una sola dirección. Como lo hemos hecho en
los últimos procedimientos, se utilizó el método requests.get Python () para
presentar una solicitud de operación (encontrar, en este caso) a lo largo de
parámetros que incluyen la dirección que se debe geocodificar. La respuesta que
se había devuelto incluye la latitud y la longitud de la dirección geocodificada, la
puntuación y el tipo de dirección.
Preparándose
Una operación de SIG común es combinar varios conjuntos de datos dispares en
un solo conjunto de datos de un área mayor. A menudo, los campos de las bases
de datos que se combinarán serán las mismas y no habrá ningún problema. Sin
embargo, habrá momentos en los campos de los diferentes conjuntos de datos no
coinciden. En este caso, deberá asignar la relación entre los campos en un conjunto
de datos a los campos en otro conjunto de datos.
ArcGIS Tools
FieldMap FieldMappings
(Merge)
El diagrama anterior muestra la relación entre las diversas clases que son ArcPy se
utiliza para definir la asignación de campos. Un objeto FieldMap contiene una
definición de campo y una lista de campos de entrada de una o más tablas o clases
de características que proporcionan los valores para el campo. Cada objeto que
cree FieldMap se agrega a un objeto FieldMappings, que sirve como un contenedor
para estos objetos. Por último, el objeto FieldMappings puede entonces ser enviada
como entrada a diversas herramientas de geoprocesamiento, tales como la
herramienta de combinación.
Cómo hacerlo...
En este ejercicio, aprenderá como utilizar los objetos de FieldMappings y FieldMap:
2. Importe arcpy
import arcpy
3. Establezca la variable de entorno de trabajo y una variable que apunte a la clase
de función de salida:
arcpy.env.workspace = r"c:\ArcpyBook\data"
outFeatureClass = r"c:\ArcpyBook\data\AllTracts.shp"
4. Crear un objeto FieldMappings y tres objetos FieldMap. Los objetos FieldMap
tendrá referencias a campos para un Estado Federal Information Processing
Standard (FIPS), condado de código código FIPS y una zona:
arcpy.env.workspace = r"c:\ArcyBook\data"
outFeatureClass = r"c:\ArcpyBook\data\AllTracts.shp"
fieldmappings = arcpy.FieldMappings()
fldmap_STFIPS = arcpy.FieldMap()
fldmap_COFIPS = arcpy.FieldMap()
fldmap_TRACT = arcpy.FieldMap()
5. Obtener una lista de todas las clases de características de polígono del condado
en el área de trabajo actual. Cada clase de entidad County tiene un campo
llamado STFID, que contiene el código de estado FIPS, condado código FIPS, y
un sitio para cada característica. Esta información se almacena como una larga
cadena (48491020301, por ejemplo), donde los dos primeros caracteres son el
código de estado, el tercero a quinto caracteres son el código del condado, y los
caracteres restantes son las vías. Como parte de la operación de fusión, vamos
a tirar de cada uno de los elementos individuales y guardarlos en distintos
campos:
fieldmappings = arcpy.FieldMappings()
fieldmap_STFIPS = arcpy.FieldMap ()
fieldmap_COFIPS = arcpy.FieldMap ()
fieldmap_TRACT = arcpy.FieldMap ()
#List all feature classes that start with 'County' and type Polygon
fclss = arcpy.ListFeatureClasses("County*", "Polygon")
6. Crear un objeto ValueTable para mantener las clases de entidad que se van a
fusionar. ValueTable funciona como un contenedor de objetos. Contendrá la
información de asignación para cada una de las clases de características en el
área de trabajo. Toda la información se extrae de un único campo (STFID), pero
tenemos que crear campos de entrada separadas para FieldMap
STFIPS, COFIPS y tracto:
vTab = arcpy.ValueTable()
for fc in fclss:
fieldmappings.addTable(fc)
fldmap_STFIPS.addInputField(fc, "STFID")
fldmap_COFIPS.addInputField(fc, "STFID")
fldmap_TRACT.addInputField(fc, "STFID")
vTab.addRow(fc)
# STFIPS field
for x in range(0, fldmap_STFIPS.inputFieldCount):
fldmap_STFIPS.setStartTextPosition(x, 0)
fldmap_STFIPS.setEndTextPosition(x, 1)
fld_STFIPS = fldmap_STFIPS.outputField
fld_STFIPS.name = "STFIPS"
fldmap_STFIPS.outputField = fld_STFIPS
8. Añadir contenido para el campo COFIPS. La posición de estos tres caracteres
es 2-4 de la cadena se retiró de la columna de la STFID:
# STFIPS field
for x in range(0, fldmap_STFIPS.inputFieldCount):
fldmap_STFIPS.setStartTextPosition(x, 0)
fldmap_STFIPS.setEndTextPosition(x, 1)
fld_STFIPS = fldmap_STFIPS.outputField
fld_STFIPS.name = "STFIPS"
fldmap_STFIPS.outputField = fld_STFIPS
# COFIPS field
for x in range(0, fldmap_COFIPS.inputFieldCount):
fldmap_COFIPS.setStartTextPosition(x, 2)
fldmap_COFIPS.setEndTextPosition(x, 4)
fld_COFIPS = fldmap_COFIPS.outputField
fld_COFIPS.name = "COFIPS"
fldmap_COFIPS.outputField = fld_COFIPS
arcpy.Merge_management(vTab, outFeatureClass,fieldmappings)
print("Merge completed")
import arcpy
Arcpy.env.workspace = r"c:\ArcyBook\data"
outFeatureClass = r"c:\ArcpyBook\data\AllTracts.shp"
fieldmappings = arcpy.FieldMappings()
fldmap_STFIPS = arcpy.FieldMap()
fldmap_COFIPS = arcpy.FieldMap()
fldmap_TRACT = arcpy.FieldMap()
#List all feature classes that start with 'County' and type Polygon
fclss = arcpy.ListFeatureClasses("County*", "Polygon")
vTab = arcpy.ValueTable()
for fc in fclss:
fieldmappings.addTable(fc)
fldmap_STFIPS.addInputField(fc, "STFID")
fldmap_COFIPS.addInputField(fc, "STFID")
fldmap_TRACT.addInputField(fc, "STFID")
vTab.addRow(fc)
# STFIPS field
for x in range(0, fldmap_STFIPS.inputFieldCount):
fldmap_STFIPS.setStartTextPosition(x, 0)
fldmap_STFIPS.setEndTextPosition(x, 1)
fld_STFIPS = fldmap_STFIPS.outputField
fld_STFIPS.name = "STFIPS"
fldmap_STFIPS.outputField = fld_STFIPS
# COFIPS field
for x in range(0, fldmap_COFIPS.inputFieldCount):
fldmap_COFIPS.setStartTextPosition(x, 2)
fldmap_COFIPS.setEndTextPosition(x, 4)
fld_COFIPS = fldmap_COFIPS.outputField
fld_COFIPS.name = "COFIPS"
fldmap_COFIPS.outputField = fld_COFIPS
# TRACT field
for x in range(0, fldmap_TRACT.inputFieldCount):
fldmap_TRACT.setStartTextPosition(x, 5)
fldmap_TRACT.setEndTextPosition(x, 12)
fld_TRACT = fldmap_TRACT.outputField
fld_TRACT.name = "TRACT"
fldmap_TRACT.outputField = fld_TRACT
arcpy.Merge_management(vTab, outFeatureClass,fieldmappings)
print("Merge completed")
16. En la vista de datos para el All Tracts.shapefile, hora debería ver una sola capa
de polígonos combinadas, como se ve en la captura de pantalla siguiente:
Cómo funciona…
Los objetos FieldMap y FieldMappings en el módulo ArcPy junto con la herramienta
de combinación, pueden ser utilizados para operaciones de SIG que necesitan para
combinar conjuntos de datos que tienen campos que no coinciden. El objeto field
map también puede utilizarse cuando se necesita sacar una secuencia contigua de
valores de cadena a partir de un conjunto de valores de cadena larga. En esta
receta, aprendió a utilizar el objeto FieldMap para tirar el estado, condado y la
información del censo de un solo campo. Hemos creado objetos FieldMap
individuales para mantener esta información y, luego, agregarlos a un objeto
FieldMappings que pasó luego en la herramienta de combinación para crear una
capa nueva, que contiene tres campos que contienen esta información.
Utilizando un ValueTable para proporcionar a una
herramienta de entrada
de multivalores
Preparándose
Existen tres maneras de especificar un parámetro multivalores: como una lista de
Python, una cadena con cada valor separado por un punto y coma, o un objeto
ValueTable ArcPy. En este procedimiento, vamos a echar un vistazo a cómo
especificar parámetros de entrada mutlivalue mediante ValueTable.
Cómo hacerlo...
Siga estos pasos para aprender a utilizar un ValueTable para enviar múltiples
valores a una herramienta:
import arcpy
arcpy.env.workspace = r"c:\ArcyBook\data"
vTab = arcpy.ValueTable()
4. Crear tres filas de la tabla y asignarles distancias de 5, 10 y 20:
vTab = arcpy.ValueTable()
vTab.setRow(0, "5")
vTab.setRow(1, "10")
vTab.setRow(2, "20")
5. Definir variables para las unidades de la clase de entidad de entrada, la clase de
entidad de salida, distancia, y de amortiguamiento. La variable distancia (dist) se
crea como una referencia a la ValueTable, que ya ha creado:
vTab = arcpy.ValueTable()
vTab.setRow(0, "5")
vTab.setRow(1, "10")
vTab.setRow(2, "20")
inFeature = 'Hospitals.shp'
outFeature = 'HospitalMBuff.shp'
dist = vTab
bufferUnit = "meters"
inFeature = 'Hospitals.shp'
outFeature = 'HospitalMBuff.shp'
dist = vTab
bufferUnit = "meters"
arcpy.MultipleRingBuffer_analysis(inFeature,
outFeature, dist, bufferUnit, '', 'ALL')
print("Multi-Ring Buffer Complete")
8. Guardar y ejecutar el script. Examine la salida para ver los múltiples anillos de
búfer.
Como hacerlo…
ValueTable es una sencilla tabla virtual que se puede utilizar como entrada a
herramientas que acepta varios valores. En este procedimiento, hemos creado un
objeto ValueTable, añadió tres valores, y a continuación, se pasa este objeto en la
herramienta MultipleRingBuffer. La herramienta MultipleRingBuffer utiliza esta
información para crear nuevas capas de polígono basado en el búfer ValueTable
distancias proporcionados en el objeto.
B Cinco procedimientos de
Python
Que cada programador de SIG
Debe de conocer
En este capítulo, trataremos los siguientes temas:
Introducción
En este capítulo, aprenderá a escribir scripts que realizan tareas de propósito
general con Python. Tareas, tales como lectura y escritura de archivos de texto
delimitados, envío de e-mails, interactuar con servidores FTP, crear archivos .zip,
y la lectura y escritura de archivos XML y JSON, son comunes. Cada programador
SIG debe saber cómo escribir secuencias de comandos Python que incorporar
estas funcionalidades.
Preparándose
Para utilizar la funcionalidad de procesamiento de archivos integrado de Python,
primero debe abrir el archivo. Una vez abiertos, los datos dentro del archivo se
procesa utilizando funciones proporcionadas por Python, y, finalmente, se cierra el
archivo.
Siempre recuerde que debe cerrar el archivo cuando haya terminado. Python
no significa necesariamente cerrar los archivos para usted, por lo que es
posible que usted podría quedarse sin recursos o sobrescribir alguna cosa.
Además, algunas plataformas de sistemas operativos no lo dejaran abrir el
mismo archivo al mismo tiempo para acceso de sólo lectura y fines de escritura.
Cómo hacerlo
Siga estos pasos para crear un script de Python que lee un archivo de texto
delimitado por comas:
18.102,-94.353,310.7,1.3,1.1,10/02/2007,0420,T,72
19.300,-89.925,313.6,1.1,1.0,10/02/2007,0420,T,82
19.310,-89.927,309.9,1.1,1.0,10/02/2007,0420,T,68
26.888,-101.421,307.3,2.7,1.6,10/02/2007,0425,T,53
26.879,-101.425,306.4,2.7,1.6,10/02/2007,0425,T,45
36.915,-97.132,342.4,1.0,1.0,10/02/2007,0425,T,100
f.close()
F=open('c:/ArcpyBook/data/N_America.A2007275.txt'
,'r')
for fire in f:
lstValues = fire.split(',')
latitude = float(lstValues[0])
longitude = float(lstValues[1])
confid = int(lstValues[8])
f.close()
Cómo funciona...
Python's open() crea un objeto file, que sirve como un vínculo a un archivo que
resida en su ordenador. Usted debe llamar a la función open() sobre un archivo
antes de leer o escribir datos en un archivo. El primer parámetro de la función open()
es la ruta de acceso al archivo que desea abrir. El segundo parámetro de la función
open() corresponde a un modo, que normalmente es de lectura (r), escritura (w), o
añadir (a). Un valor de r indica que le gustaría abrir el archivo para operaciones de
sólo lectura, mientras que un valor de w indica que le gustaría abrir el archivo para
operaciones de escritura. Si el archivo se abre en modo de escritura ya existe, se
sobrescribirán los datos existentes en el archivo, así que debe tener cuidado al
utilizar este modo. Append (a) el modo de abrir un archivo para operaciones de
escritura, pero, en lugar de sobrescribir todos los datos, añadir datos al final del
archivo. Así, en esta receta, hemos abierto la N_America.A2007275.txt que se
encuentra en modo de sólo lectura. Dentro del bucle for, que se utiliza para recorrer
cada uno de los valores en el archivo de texto una línea a la vez, la función split()
se utiliza para crear un objeto de lista a partir de una línea de texto que está
delimitado de alguna manera. Nuestro archivo está delimitado por comas, así que
podemos usar split(","). También puede dividir basados en otros delimitadores como
tabulaciones, espacios o cualquier otro delimitador. Este nuevo objeto de lista
creada por split() se almacena en una variable denominada lstValues. Esta variable
contiene los valores de cada uno de los incendios forestales. Esto se muestra en la
siguiente captura de pantalla. Usted notará que la latitud se encuentra en la primera
posición, longitud está situado en la segunda posición, y así sucesivamente. Las
listas se basan en cero:
Utilizando los valores de índice (que hace referencia a la latitud, la longitud y valores
de confianza), debemos crear nuevas variables llamado latitud, longitud y confid.
Por último, podemos imprimir cada uno de los valores.
Una forma más sólida de geoprocesamiento script podría escribir esta información
en una clase de función utilizando un objeto InsertCursor. Realmente lo hicimos esto
en proceso anterior en Capítulo 8, Usando el módulo de acceso a datos ArcPy con
clases de características y tablas.
Sería posible utilizar los readlines () para leer todo el contenido del archivo en una
lista de Python, que luego podría ser iterado. Cada fila del archivo de texto será de
un valor único en la lista. Dado que esta función lee todo el archivo en una lista, es
necesario utilizar este método con precaución, ya que los archivos grandes pueden
causar problemas de rendimiento significativas.
Hay más...
Similar a las instancias de lectura de archivos, existen varios métodos que puede
utilizar para escribir datos en un archivo. La función write () es probablemente el
más fácil de usar. Toma un único argumento de cadena y lo escribe en un archivo.
La writelines () puede ser usada para escribir el contenido de una estructura de la
lista a un archivo. Antes de escribir datos en un archivo de texto, tendrá que abrir el
archivo en modo escritura o anexar.
Envío de e-mails
Habrá ocasiones en que necesite enviar un e-mail desde un script de Python. Un
ejemplo de esto podría ser una alerta para la culminación exitosa o errores
incurridos en una larga operación de geoprocesamiento. Sobre éstas y otras
ocasiones, enviando un e-mail puede ser útil.
Preparándose
El envío de un e-mail a través de un script de Python requerirá que usted tenga
acceso a un servidor de correo. Este puede ser un servicio de correo electrónico
público, tales como Yahoo, Gmail o otros. También puede utilizar servidores de
correo saliente que está configurado con aplicaciones como Microsoft Outlook. En
cualquier caso, necesitará saber el nombre del host y el puerto del servidor de
correo electrónico. El modulo smtplib Python es utilizado para crear conexiones con
el servidor de correo y enviar e-mails. El módulo de correo electrónico Python
contiene una clase de mensaje que representa mensajes de correo electrónico.
Cada mensaje contiene los encabezados y un cuerpo. Esta clase no se puede
utilizar para enviar mensajes de correo electrónico, sólo se ocupa de la
representación de objetos. En este procedimiento, usted aprenderá cómo utilizar la
clase SMTP para enviar correos electrónicos que contienen un archivo adjunto a
través de su escritura. La clase de mensaje puede analizar una secuencia de
caracteres o un archivo que contiene un correo electrónico utilizando ya sea el ()
funciones message_from_file () o message_from_string. Ambos crearán un nuevo
objeto del mensaje. El cuerpo del mensaje puede ser obtenida llamando
Message.getpayload ().
Cómo hacerlo...
Siga estos pasos para crear un script que puede enviar e-mails:
4. Crear una nueva función llamada Python mail(). Esta función acepta cuatro
parámetros: Para, Asunto, texto y adjuntar. Cada uno de estos parámetros
debe explicarse por sí mismo. Crear un nuevo objeto MimeMultipart y signar la
De, Para y Asunto claves. También puede adjuntar el texto del e-mail a este
nuevo objeto usando MIMEMultipart msg.attach():
msg = MIMEMultipart()
msg['From'] = gmail_user
msg['To'] = to
msg['Subject'] = subject
msg.attach(MIMEText(text))
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders
import os
gmail_user = "<janediazlop>"
gmail_pwd = "<yesenialop>"
msg['From'] = gmail_user
msg['To'] = to
msg['Subject'] = subject
msg.attach(MIMEText(text))
Cómo funciona...
El primer parámetro que se pasa a la función mail() es la dirección de correo
electrónico que recibirá el correo electrónico. Esto puede ser cualquier dirección de
correo electrónico válida, pero usted desea proporcionar una cuenta de correo
electrónico que usted realmente puede controlar, de modo que puede asegurarse
de que su script se ejecuta correctamente. El segundo parámetro es sólo la línea
de asunto del correo electrónico. El tercer parámetro es el texto. El último parámetro
es el nombre de un archivo que se adjunta al correo electrónico. Aquí, simplemente
he definido que el bc_pop1996.csv debe estar conectado. Puede utilizar cualquier
archivo que tiene acceso, pero puede que sólo desee utilizar este archivo para
realizar pruebas. Entonces creamos un nuevo objeto MIMEMultipart dentro de la
función mail() y asignar la De, Para y Asunto claves. También puede adjuntar el
texto del e-mail a este nuevo objeto usando MIMEMultipart msg.attach(). El
bc_pop1996.csv se adjunta a un mensaje de correo electrónico usando un objeto
MIMEBase y adjunto a la dirección de e-mail usando msg.attach(parte).
En este punto, hemos examinado cómo un correo electrónico de texto básico puede
ser enviado. Sin embargo, queremos enviar un mensaje de correo electrónico más
complejo que contiene texto y un archivo adjunto. Esto requiere el uso de mensajes
MIME, que proporcionan la funcionalidad para gestionar e-mails multipart.
Mensajes MIME necesitan límites entre varias partes de un e-mail junto con
encabezados adicionales para especificar el contenido que se envía. La clase
MIMEBase es una subclase abstracta de mensaje y permite que este tipo de un
correo electrónico que se enviará. Dado que es una clase abstracta, no se puede
crear instancias reales de esta clase. En su lugar, utiliza una de las subclases, como
MimeText. El último paso de la función mail () es crear un nuevo objeto de SMTP
que hace referencia al servicio de correo de Google, pasa el nombre de usuario y
contraseña para poder conectarse a los servicios de correo, envía el correo
electrónico, y luego cierra la conexión.
Como hacerlo…
Siga estos pasos para crear un script que se conecta a un servidor FTP y descarga
un archivo:
import ftplib
import os
import socket
4. Agregue las siguientes variables que defina la URL, directorio y nombre de
archivo:
HOST = 'ftp.nifc.gov'
USER = '<your username here>'
PASSW = '<your password here>'
DIRN = '/Incident_Specific_Data/2012
HISTORIC/ROCKY_MTN/Arapaho/GIS/20120629'
FILE = '20120629_0600_Arapaho_PIO_0629_8x11_land.pdf'
5. Agregue el siguiente bloque de código para crear una conexión. Si hay un error
de conexión, se generará un mensaje. Si la conexión fue exitosa, un mensaje de
éxito será impresas:
try:
f = ftplib.FTP(HOST,USER,PASS)
except (socket.error, socket.gaierror), e:
print('ERROR: cannot reach "% s "' % HOST)
print('*** Connected to host "%s"' % HOST)
try:
f.login()
except ftplib.error_perm:
print('ERROR: cannot login')
f.quit()
print('*** Logged in ')
HOST = 'ftp.nifc.gov'
USER = '<your username here>'
PASSW = '<your password here>'
DIRN = '/Incident_Specific_Data/2012
HISTORIC/ROCKY_MTN/Arapaho/GIS/20120629'
FILE = '20120629_0600_Arapaho_PIO_0629_8x11_land.pdf'
try:
f = ftplib.FTP(HOST,USER,PASSW)
except (socket.error, socket.gaierror), e:
print('ERROR: cannot reach "%s"' % HOST)
print('*** Connected to host "%s"' % HOST)
try:
f.login()
except ftplib.error_perm:
print('ERROR: cannot login')
f.quit()
print('*** Logged in ')
try:
f.cwd(DIRN)
except ftplib.error_perm:
print('ERROR: cannot CD to "%s"' % DIRN)
f.quit()
print('*** Changed to "%s" folder' % DIRN)
try:
f.retrbinary('RETR %s' % FILE,
open(FILE, 'wb').write)
except ftplib.error_perm:
print('ERROR: cannot read file "%s"' % FILE)
os.unlink(FILE)
else:
print('*** Downloaded "%s" to CWD' % FILE)
f.quit()
Cómo funciona…
Para conectarse a un servidor FTP, necesita conocer la dirección URL. Usted
también necesita saber el directorio y nombre de archivo para el archivo que se
descargará. En este script, hemos codifica esta información, por lo que puede
centrarse en la aplicación de las funcionalidades específicas de FTP. Utilizando esta
información, a continuación, creamos una conexión con el servidor FTP del NIFC.
Esto se realiza mediante el ftplib.FTP (), que acepta una dirección URL para el host.
El módulo ftplib también incluye varios métodos para trabajar con archivos. Puede
cargar y descargar archivos en un archivo binario o texto sin formato. retrbinary()y
storbinary()métodos se utilizan para recuperar y almacenar archivos binarios,
respectivamente. archivos de texto pueden ser recuperados y almacenados usando
retrlines() y storlines().
Hay varios otros métodos en la clase ftp que usted debe conocer. La eliminación de
un archivo puede realizarse con el método delete(), al cambiar el nombre de un
archivo puede realizarse con rename(). También puede enviar comandos al servidor
FTP mediante el método sendcmd().
Preparándose
ZIP es un formato de compresión y archivo común y es implementado en Python a
través del módulo de archivo zip. La clase ZipFile se puede utilizar para crear, leer,
y escribir archivos .zip. A crear un nuevo archivo .zip, sólo tiene que proporcionar el
nombre de archivo junto con un modo tan w, lo que indica que desea escribir datos
en el archivo. En el siguiente ejemplo de código, estamos creando un .zip archivo
llamado datafile.zip. El segundo parámetro, w, indica que se creará un nuevo
archivo. Un nuevo archivo será creado o un archivo existente con el mismo nombre
se truncará en la escritura modo. Un parámetro de compresión opcional también se
puede utilizar cuando se crea el archivo. Este valor se puede establecer en
cualquiera ZIP_STORED o ZIP_DEFLATED:
zipfile.ZipFile('dataFile.zip', 'w',zipfile.ZIP_STORED)
En este ejercicio, va a utilizar Python para crear el archivo, agregar archivos y aplicar
compresión en un archivo .zip. Podrá archivar todos los archivos ubicados en la
carpeta C:\ArcpyBook\directorio de datos.
Cómo hacerlo...
Siga estos pasos para aprender a crear un script que genera un archivo .zip:
1. Abrir IDLE y crear un script llamado C: \ ArcPy libro \ Apéndice 2 \ Crear
Zipfile.py
2. Importe los módulos zipfile y sistema operativo:
import os
import zipfile
files = os.listdir("c:/ArcpyBook/data")
for f in files:
if f.endswith("shp") or f.endswith("dbf") or
f.endswith("shx"):
zfile.write("C:/ArcpyBook/data/" + f)
6. Imprimir una lista de todos los archivos que se han añadido al archivo ZIP. Puede
utilizar la función ZipFile.namelist() para crear una lista de archivos en el archivo.
for f in zfile.namelist():
print "Added %s" % f
7. Cierre el archivo .zip:
zfile.close ()
8. Toda la secuencia de comandos debe aparecer como sigue:
import os
import zipfile
#create the zip file
zfile = zipfile.ZipFile("shapefiles.zip", "w", zipfile.ZIP_STORED)
files = os.listdir("c:/ArcpyBook/data")
for f in files:
if f.endswith("shp") or f.endswith("dbf") or
f.endswith("shx"):
zfile.write("C:/ArcpyBook/data/" + f)
#list files in the archive
for f in zfile.namelist():
print("Added %s" % f)
zfile.close()
Added ArcpyBook/data/Burglaries_2009.dbf
Added ArcpyBook/data/Burglaries_2009.shp
Added ArcpyBook/data/Burglaries_2009.shx
Added ArcpyBook/data/Streams.dbf
Added ArcpyBook/data/Streams.shp
Added ArcpyBook/data/Streams.shx
11. En el Explorador de Windows, usted debería ser capaz de ver el archivo .zip de
salida, como se muestra en la siguiente captura de pantalla. Observe el tamaño del
archivo. Este archivo se creó sin compresión:
12. Ahora, vamos a crear una versión comprimida del archivo .zip para ver la
diferencia. Hacer los siguientes cambios en la línea de código que crea el archivo
.zip:
15. Ven a ver el tamaño del nuevo archivo shapefiles2.zip que acaba de crear. Nota
la disminución del tamaño del archivo debido a la compresión:
Cómo funciona…
En este procedimiento, se ha creado un nuevo archivo .zip llamado shapefiles.zip
en modo de escritura. En la primera iteración de este script, usted no comprimir el
contenido del archivo. Sin embargo, en la segunda iteración, lo hicieron mediante la
deflación de parámetro que se pasa en el constructor del objeto ZipFile. A
continuación, el script obtiene una lista de los archivos en el directorio de datos y en
bucle a través de cada uno de los archivos. Cada archivo tiene una extensión .shp
y .dbf o .shx se escribe a continuación el archivo utilizando la función write().
Finalmente, los nombres de cada uno de los archivos escritos en el archivo se
imprime en la pantalla.
<root>
<child att="value">
<subchild>.....</subchild>
</child>
</root>
Python proporciona varios módulos de programación que puede utilizar
para procesar archivos XML. El módulo que se utilice debe ser determinado
por el módulo que es adecuado para el trabajo. No trate de forzar un único
módulo para hacerlo todo. Cada módulo tiene funciones específicas que
son buenos para realizar.
En este procedimiento, usted aprenderá cómo leer datos de un archivo XML que
utilizan los nodos y atributos de los elementos que forman parte del documento.
Hay una serie de formas en que se puede acceder a los nodos dentro de un
documento XML. Quizás el
forma más fácil de hacerlo es encontrar nodos por nombre de la etiqueta y luego a
través de pie del árbol que contiene una lista de los nodos secundarios. Antes de
hacerlo, tendrá que analizar el documento XML con la minidom.parse () método.
Una vez analizado, a continuación, puede utilizar los atribuyen a childNodes
obtener una lista de todos los nodos secundarios a partir de la raíz del árbol. Por
último, se puede buscar en los nodos por los nombres de etiqueta con la función
getElementsByTagName (tag), que acepta un nombre de etiqueta como un
argumento. Esto devolverá una lista de todos los nodos secundarios que se asocian
con la etiqueta.
También puede determinar si un nodo contiene un atributo llamando hasAttribute
(name), que devolverá un valor de verdadero / falso. Una vez que haya determinado
que existe un atributo, una llamada getAttribute a (name) va a obtener el valor del
atributo.
En este ejercicio, vamos a analizar un archivo XML y extraer los valores asociados
a una determinada elemento (nodo) y el atributo. Vamos a cargar un archivo XML
que contiene los datos de incendios forestales. En este archivo, vamos a buscar la
<incendio> nodo y el atributo de dirección para cada uno de estos nodos. Las
direcciones se imprimirán.
Cómo hacerlo…
<fires>
<fire address="11389 Pajaro Way" city="San Diego"
state="CA" zip="92127" country="USA" latitude="33.037187"
longitude="-117.082299" />
<fire address="18157 Valladares Dr" city="San Diego"
state="CA" zip="92127" country="USA" latitude="33.039406"
longitude="-117.076344" />
<fire address="11691 Agreste Pl" city="San Diego"
state="CA" zip="92127" country="USA" latitude="33.036575"
longitude="-117.077702" />
<fire address="18055 Polvera Way" city="San Diego"
state="CA" zip="92128" country="USA" latitude="33.044726"
longitude="-117.057649" />
</fires>
3. Importar desde xml minidom.dom:
from xml.dom import minidom
4. Analizar el archivo XML:
xmldoc = minidom.parse("WitchFireResidenceDestroyed.xml")
childNodes = xmldoc.childNodes
eList = childNodes[0].getElementsByTagName("fire")
for e in eList:
if e.hasAttribute("address"):
print(e.getAttribute("address"))
18157 Valladares Dr
11691 Agreste Pl
18189 Chretien Ct
17837 Corazon Pl
18187 Valladares Dr
18658 Locksley St
Cómo funciona…
La propiedad ChildNodes del árbol DOM genera una lista de todos los nodos del
archivo XML. A continuación, puede tener acceso a cada uno de los nodos mediante
el método getElementsByTagName(). El paso final es recorrer cada uno de los
nodos <fire> eList contenida dentro de la variable. Para cada nodo, podemos
controlar la dirección con el atributo hasAttribute(), método y, si existe, llamamos
la getAttribute() e imprimir la dirección de la pantalla.
Habrá momentos en los que tendrás que buscar un documento XML para una
determinada cadena de texto. Esto requiere el uso de XML.parsers.expat módulo.
Necesitará definir una búsqueda clase derivada de la clase expat básico y, a
continuación, crear un objeto de esta clase. Una vez creado, puede llamar al método
parse() en el objeto Search para buscar datos. Por último, a continuación, puede
buscar los nodos por nombres de etiquetas con la función
getElementsByTagName(tag), que acepta un nombre de etiqueta como un
argumento. Esto devolverá una lista de todos los nodos secundarios que están
asociados con la etiqueta.