1 votos

Forma Arcpy de acceder a las clases de características subyacentes contenidas en un mapa web

Estoy construyendo un script arcpy autónomo, y necesito conectarme a las clases de características específicas dentro de un mapa web publicado, consultar/copiar desde esas clases de características, luego después de algún procesamiento actualizar esas clases de características específicas con datos nuevos o modificados.

Tengo un valor GUID para el mapa web específico con el que necesito interactuar (este es mi único punto de entrada a las clases de características subyacentes), pero necesito poder encontrar las conexiones de la base de datos a la base de datos y las clases de características que componen el mapa web. El mapa web se construyó a partir de 3 capas de características web publicadas/servicios de características, cada una conteniendo 1-muchas clases de características, y en última instancia necesito obtener la conexión de base de datos a una característica de punto y una característica de línea específicas, ejecutar mi script (que hace copias de esas clases de características y luego ejecuta los pasos de geoprocesamiento de arcpy-near_analysis, snap, SplitLineAtPoint, AddGeometryAttributes) y luego necesito actualizar/añadir características de nuevo a las respectivas bases de datos y clases de características.

Mi script de consulta/geoprocesamiento ya funciona con conexiones de base de datos codificadas, pero ahora necesito recorrer los distintos GUID que tengo para diferentes mapas web y conectarme dinámicamente a conexiones de base de datos variables dentro del mapa web (para las que tengo un ID GUID).

He encontrado documentación que muestra cómo acceder a los mapas web:

from arcgis.gis import GIS
gis = GIS()
web_map = gis.content.get('<GUID value>')#where GUID value is the GUID I have in a list

y, a continuación, acceder a las capas de características web que componen el mapa web:

web_map_layers = webMap(web_map)
layers = web_map_layers.layers

pero imprimir eso sólo parece darme una lista de diccionarios, no algo que pueda asignar a una variable y tratar como una clase de característica real dentro de una base de datos o incluso temporalmente en la memoria.

1voto

thecommexokid Puntos 126

Finalmente fui capaz de conseguir que esto funcione, tomando el WebMap guid ID suministrado, y:

  1. averiguar el Feature Service de la característica que quería copiar
  2. llegar al punto final REST de ese servicio de características
  3. copiar ese conjunto de características en una clase de características.

Esto me permitió ejecutar mis herramientas de geoprocesamiento e informar de mis hallazgos. Lo único que me queda por averiguar es cómo enviar mis actualizaciones/añadidos a las clases de características subyacentes en los servicios de características...

Aquí está el código que funcionó para mí (con algunos datos / código redactado / cambiado):

import arcpy
from arcpy import env
import timeit
import uuid
from arcgis.gis import GIS
from arcgis import features
from arcgis.mapping import WebMap
from collections import OrderedDict
import json
import urllib
import http.client

start_time = timeit.default_timer()

#Constant values
SURVEY_DB_WORKSPACE = r'C:\Users\survey_gdb.sde'
#survey table server instance and owner prefix values
SURVEY_DB_INSTANCE_AND_OWNER = 'mydb.dbo.'
GEO_PROC_WORKSPACE = r"C:\Users\geo_proc_gdb.sde"
#geo-proc server instance and owner prefix values
GEO_PROC_DB_INSTANCE_AND_OWNER = 'mydb_gdb.DBO.'
#rest services credentials
USERNAME = 'user'
PASSWORD = 'password'
PORTAL_URL = 'https://mywebsite/portal'
SERVERNAME = "mywebsite"
PORT = ''#if using web adaptor, leave empty (modify tokenURL)
TOKEN_URL = "https://mywebsite/server/admin/generateToken"

def main():

    #set environment to the Survey database, loop through surveys table, grab WebMap GUID
    workspace = SURVEY_DB_WORKSPACE
    arcpy.env.workspace = workspace
    arcpy.env.overwriteOutput = True

    surveys = SURVEY_DB_INSTANCE_AND_OWNER + 'Surveys'
    where_clause = "active = 1"
    fields = ['OID@', 'Name', 'Id', 'Progress']
    web_map_ids = OrderedDict()

    with arcpy.da.SearchCursor(surveys, fields) as cursor:
        for row in cursor:
            web_map_ids[row[0]] = [row[1], row[2], row[3]]

    #change environment to the geo-processing database
    workspace = GEO_PROC_WORKSPACE

    #connect to db and set point and line features
    field = 'state'
    lines_backup = GEO_PROC_DB_INSTANCE_AND_OWNER + 'lines_backup'
    points_backup = GEO_PROC_DB_INSTANCE_AND_OWNER + 'points_backup'
    tmp_lines_split = GEO_PROC_DB_INSTANCE_AND_OWNER + 'tmp_lines_split'
    lines_split = GEO_PROC_DB_INSTANCE_AND_OWNER + 'lines_split'
    arcpy.env.workspace = workspace
    arcpy.env.overwriteOutput = True

    #Define how to acquire a rest services token
    #from https://community.esri.com/thread/83654

    def getToken(username, password, serverName, serverPort):
        params = urllib.parse.urlencode({'username': USERNAME, 'password': PASSWORD,'client': 'requestip', 'f': 'json'})
        headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}

        # Connect to URL and post parameters
        httpConn = http.client.HTTPSConnection(serverName, serverPort)
        httpConn.request("POST", TOKEN_URL, params, headers)

        # Read response
        response = httpConn.getresponse()
        print(response.status)
        if (response.status != 200):
            httpConn.close()
            print("Error while fetching tokens from admin URL. Please check the URL and try again.")
            return
        else:
            data = response.read()
            httpConn.close()

        # Check that data returned is not an error object
        if not assertJsonSuccess(data): 
            return

        # Extract the token from it
        token = json.loads(data) 
        return token['token']

        ###End getToken function

# A function that checks that the input JSON object is not an error object. 
def assertJsonSuccess(data):
    obj = json.loads(data)
    if 'status' in obj and obj['status'] == "error":
        print("Error: JSON object returns an error. " + str(obj))
        return False
    else:
        return True

    ### End jsonSuccess function
    """
        This is the Main loop through WebMap values, processing and reporting back to survey, then continuing
    """
    #loop through the survey web map guids for processing-this is where the GUID values come from
    current_survey = ''
    for k,v in web_map_ids.items():
        if v[1] is None:
            continue
        current_survey = v[0]

        #get WebMap
        gis = GIS(PORTAL_URL, username=USERNAME, password=PASSWORD)
        web_map = gis.content.get(v[1])
        web_Map = WebMap(web_map)
        web_map_layers = web_Map.layers

        #extract the feature service name that contains the Point feature class
        num = 0
        for item in web_map_layers:
            for tag in item:
                if tag =='title':
                    if item[tag] == 'Point':
                        num = web_map_layers.index(item)
                    else:
                        continue
                else:
                    continue

        point_url = web_map_layers[num]['url']

        #from https://www.esri.com/arcgis-blog/products/arcgis-desktop/analytics/quick-tips-consuming-feature-services-with-geoprocessing/
        #Extract Points from feature service to feature class
        baseURL = point_url
        where = '1=1'
        fields = '*'
        token = 'getToken(USERNAME, PASSWORD, SERVERNAME, PORT)'
        query = "?where={}&outFields={}&returnGeometry=true&f=json&token={}".format(where, fields, token)
        # See http://services1.arcgis.com/help/index.html?fsQuery.html for more info on FS-Query
        fsURL = baseURL + query
        fs = arcpy.FeatureSet()
        fs.load(fsURL)

        #clean up prior to re-creating backups
        if arcpy.Exists(lines_backup):
            arcpy.Delete_management(lines_backup)
        if arcpy.Exists(points_backup):
            arcpy.Delete_management(points_backup)

        #copy Points from feature service to feature class, for geo-processing
        arcpy.CopyFeatures_management(fs, points_backup)

Una vez que pude copiar el conjunto de características del servicio de características a una clase de características, pude ejecutar el resto de mi script de geoprocesamiento. Todavía no he sido capaz de empujar actualizaciones / adiciones de nuevo a esas clases de características que subyacen a los servicios de características sin embargo. abordar que ahora ...

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X