6 votos

Código para abrir el navegador web bloquea ArcMap cuando ejecuta desde un complemento de Python

He creado un ArcMap Python agregar-en el uso de ArcGIS 10.1 para abrir una página web después de hacer clic en el mapa. Abre la página pero luego se bloquea el ArcGIS.

import arcpy
import pythonaddins
import webbrowser
class ToolClass2(object):
    """Implementation for TEST_addin.tool (Tool)"""
    def __init__(self):
        self.enabled = True
        self.cursor=3
    def onMouseDownMap(self, x, y, button, shift):

    mxd=arcpy.mapping.MapDocument("current")
    df = arcpy.mapping.ListDataFrames(mxd)[0]
    pt=arcpy.PointGeometry(arcpy.Point(x,y))
    pythonaddins.MessageBox("Long" + " " + str(x) + '\n'+ "Lat"+ " " + str(y), 'Coordinates', 0)
    path = 'http://pol.pictometry.com/en-us/php/default.php?lat=' +str(x) +'&lon=' + str(y)+'&v=p&o=n&type=or&level=n'
    webbrowser.open(path)
    pass

5voto

auramo Puntos 161

@BMac del código también se bloquea mi ArcMap 10.1 instalación de SP1.

Este código funciona correctamente, sin embargo:

import arcpy
import pythonaddins
import webbrowser
from threading import Thread

def OpenBrowserURL():
    url = 'http://www.google.com'
    webbrowser.open(url,new=2)

class OpenWebBrowserButtonClass(object):
    """Implementation for WebBrowserAddIn.openWebBrowserButton (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        t = Thread(target=OpenBrowserURL)
        t.start()
        t.join()

Puedo llamar a la misma función de un nuevo hilo. Add-in de Python clases probablemente se ejecutan en el subproceso de interfaz de usuario por defecto y tal vez hay alguna condición de carrera o de otro problema que causa el ArcMap se bloquea, pero si llama desde otro hilo funciona.

Actualización: acabo de ver un Equipo de ArcGIS Python post en el blog sobre esto:

os.startfile y webbrowser.open son dos funciones muy útiles en la Biblioteca de Python. Sin embargo, debido a algunos conflictos en la forma de Windows las bibliotecas de esperar a ser llamado, que puede provocar una caída del sistema cuando se le llama dentro de ArcGIS for Desktop en un complemento o secuencia de comandos de secuencia de comandos de geoprocesamiento de la herramienta (ver la sección de Observaciones en este MSDN página de referencia).

import functools
import os
import threading
import webbrowser

# A decorator that will run its wrapped function in a new thread
def run_in_other_thread(function):
    # functool.wraps will copy over the docstring and some other metadata
    # from the original function
    @functools.wraps(function)
    def fn_(*args, **kwargs):
        thread = threading.Thread(target=function, args=args, kwargs=kwargs)
        thread.start()
        thread.join()
    return fn_

# Our new wrapped versions of os.startfile and webbrowser.open
startfile = run_in_other_thread(os.startfile)
openbrowser = run_in_other_thread(webbrowser.open)

Las funciones locales startfile y openbrowser estará disponible, que tienen los mismos parámetros que los de la versión en la biblioteca estándar pero se ejecute en otro hilo y por lo tanto funcionan como se esperaba.

Algo relacionado con: Estrellarse ArcGIS 10.1 Add-ins con Multiprocesamiento

2voto

Ross Puntos 826

Abrí la ArcMap ventana de python y era capaz de ejecutar el código siguiente con éxito:

import webbrowser
url = 'http://www.google.com'
webbrowser.open(url,new=2)

Sin embargo, termino con el mismo problema cuando se ejecuta como un add-in de python. Cierra/se bloquea ArcMap y se abre el navegador. Podría ser un error en el complemento en el módulo o necesitamos cambiar el nombre de nuestro botón de "Abrir el navegador y bloqueo de ArcMap". Suena como que usted puede ser que necesite para llamar ESRI support para informar de un posible error.

Muestra add-in de Python que se bloquea ArcMap:

import arcpy
import pythonaddins
import webbrowser

def OpenBrowserURL():
    url = 'http://www.google.com'
    webbrowser.open(url,new=2)

class OpenMetadata(object):
    """Implementation for TestAddins_addin.button1 (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        OpenBrowserURL()

1voto

Mike Hofer Puntos 101

Sólo corrí a través de este tema. Fui capaz de estabilizar la situación con el recurso de blah238, pero pareció encontrar el éxito con el uso de módulo subproceso de Python. Este es mi código:

#--THIS IS THE CALLING SCRIPT--

class OpenURL(object):
    """Implementation for OpenURL_addin.button (Button)"""
    def __init__(self):
        self.enabled = True
        self.checked = False
    def onClick(self):
        url = "http://mywebsite.com"
        import subprocess

        #Set up the subprocess components
        python_path = r"C:\Python27\ArcGIS10.1\python.exe"
        python_script = r"C:\ArcGIS_AddIns\PythonAddIns\Tools\GIS_Locate\Install\OpenWebBrowser.py"

        #Now call the script and pass in the necessary variables
        subprocess.call([python_path, python_script, url]) 

#--THIS IS THE MODULE (OpenWebBrowser.py) THAT THE SUBPROCESS CALLS--
import sys
import webbrowser

url = sys.argv[1]
webbrowser.open(url,new=2)

0voto

Narendra Mantri Puntos 11

Todo aquí es una implementación que sólo conseguí trabajo. La mayoría de esto fue tomando el código de otros posts y tratando de hacer más dinámica la herramienta. Ojala le sirve a alguien en el futuro que está intentando hacer lo mismo.

import arcpy, pythonaddins, json, webbrowser, threading
#   Written by : Ken Carrier
#   Date       : 03/12/2015
#
#   Pictometry Connect python add-in tool. Will convert map click to current
#   spatial reference coordinates to WGS_84 coordinates. Then opens Pictometry
#   Connect in default web browser in a thread separate from ArcMap.

class PictometryConnectTool(object):
    """Implementation for Pictometry_addin.tool (Tool)"""
    def __init__(self):
        self.enabled = True
        self.shape = "NONE" # Can set to "Line", "Circle" or "Rectangle" for interactive shape drawing and to activate the onLine/Polygon/Circle event sinks.
        self.cursor=3

    def onMouseDownMap(self, x, y, button, shift):
        # Get reference to current map document.
        mxd=arcpy.mapping.MapDocument("current")
        # Get reference to active dataframe.
        df = arcpy.mapping.ListDataFrames(mxd)[0]
        # Get spatial reference from dataframe.
        sr_df = df.spatialReference.PCSCode
        # Set spatial reference object for current spatial reference.
        sr_sp = arcpy.SpatialReference(sr_df)
        # Set spatial reference object for Pictometry WKID: 4326.
        sr_wgs = arcpy.SpatialReference(4326)
        # Get point geometry object from mouse click
        pt=arcpy.PointGeometry(arcpy.Point(x,y),sr_sp)
        # Reproject X&Y coordinates from map click to WKID: 4326.
        prj_pt = pt.projectAs(sr_wgs)
        # Read the returned objects JSON string
        data = json.loads(prj_pt.JSON)
        # Parse JSON get reprojected X coordinate.
        wgsX = data["x"]
        # Parse JSON get reprojected Y coordinate.
        wgsY = data["y"]
        # Print output to python window in ArcMap.
        print "X:" + str(wgsX) + " Y:" + str(wgsY)
        # Structure url string and pass X&Y parameters to string.
        url = 'https://pol.pictometry.com/en-us/app/default.php?lat={0}&lon={1}&v=p&o=s&type=ob&level=n'.format(str(wgsY),str(wgsX))
        # ArcMap and python add-ins are sensitive to threading.
        # Therefore to open a separate process it needs to be opened
        # in it's own thread so it does not interfere with ArcMap.
        # The code below will open the url in a new tab in a separate thread.
        threading.Thread(target=webbrowser.open, args=(url,0)).start()

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