ui and sending working
This commit is contained in:
@@ -5,8 +5,8 @@ import json
|
||||
import os
|
||||
|
||||
try:
|
||||
from speckle.converter.layers.CRS import CRS
|
||||
from speckle.converter.layers.Layer import Layer, VectorLayer, RasterLayer
|
||||
from speckle.speckle.converter.layers.CRS import CRS
|
||||
from speckle.speckle.converter.layers.Layer import Layer, VectorLayer, RasterLayer
|
||||
except:
|
||||
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.CRS import CRS
|
||||
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.Layer import Layer, VectorLayer, RasterLayer
|
||||
@@ -73,7 +73,7 @@ for k, grp in enumerate(sym.renderer.groups):
|
||||
|
||||
|
||||
|
||||
from speckle.converter.layers.symbology import get_polygon_simpleRenderer
|
||||
from speckle.speckle.converter.layers.symbology import get_polygon_simpleRenderer
|
||||
from arcpy._mp import ArcGISProject
|
||||
|
||||
aprx = ArcGISProject('CURRENT')
|
||||
|
||||
@@ -10,38 +10,42 @@ from subprocess_call import subprocess_call
|
||||
|
||||
import sys
|
||||
|
||||
ENV_NEW_NAME = "arcgispro-py3-speckle"
|
||||
|
||||
def setup():
|
||||
pythonExec = get_python_path() # import numpy; import os; print(os.path.abspath(numpy.__file__))
|
||||
return pythonExec # None if not successful
|
||||
|
||||
def get_python_path(): # create a full copy of default env
|
||||
#print("Get Python path")
|
||||
# or: import site; site.getsitepackages()[0]
|
||||
# import specklepy; import os; print(os.path.abspath(specklepy.__file__)) ##currentPythonExec = sysconfig.get_paths()['data'] + r"\python.exe"
|
||||
|
||||
def get_default_python():
|
||||
pythonExec = os.environ["ProgramFiles"] + r'\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe' #(r"%PROGRAMFILES%\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe") #os.path.dirname(sys.executable) + "\\python.exe" # default python.exe
|
||||
#print(pythonExec)
|
||||
if not os.path.exists(pythonExec):
|
||||
pythonExec = os.getenv('APPDATA').replace("Roaming", "Local") + r'\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe'
|
||||
if not os.path.exists(pythonExec): return None
|
||||
return pythonExec
|
||||
|
||||
def get_python_path(): # create a full copy of default env
|
||||
#print("Get Python path")
|
||||
# or: import site; site.getsitepackages()[0]
|
||||
# import specklepy; import os; print(os.path.abspath(specklepy.__file__)) ##currentPythonExec = sysconfig.get_paths()['data'] + r"\python.exe"
|
||||
def_exec = get_default_python()
|
||||
#print(os.getenv('APPDATA') + r'\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe')
|
||||
|
||||
if sys.platform == "win32":
|
||||
env_new_name = "arcgispro-py3-speckle"
|
||||
newExec = clone_env(pythonExec, env_new_name) # only if doesn't exist yet
|
||||
newExec = clone_env(def_exec) # only if doesn't exist yet
|
||||
if not os.path.exists(newExec): return None
|
||||
|
||||
activate_env(env_new_name)
|
||||
activate_env()
|
||||
return newExec
|
||||
else: return None
|
||||
|
||||
def clone_env(pythonExec_old: str, env_new_name: str):
|
||||
def clone_env(pythonExec_old: str):
|
||||
install_folder = os.getenv('APPDATA').replace("\\Roaming","") + r"\Local\ESRI\conda\envs" #r"%LOCALAPPDATA%\ESRI\conda\envs"
|
||||
if not os.path.exists(install_folder): os.makedirs(install_folder)
|
||||
|
||||
default_env = pythonExec_old.replace("Pro\\bin\\Python\\envs\\arcgispro-py3\\python.exe","Pro\\bin\\Python\\envs\\arcgispro-py3") # + "\\" + 'arcgispro-py3'
|
||||
conda_exe = pythonExec_old.replace("Pro\\bin\\Python\\envs\\arcgispro-py3\\python.exe","Pro\\bin\\Python\\Scripts\\conda.exe") #%PROGRAMFILES%\ArcGIS\Pro\bin\Python\Scripts\conda.exe #base: %PROGRAMDATA%\Anaconda3\condabin\conda.bat
|
||||
new_env = install_folder + "\\" + env_new_name # %LOCALAPPDATA%\ESRI\conda\envs\...
|
||||
new_env = install_folder + "\\" + ENV_NEW_NAME # %LOCALAPPDATA%\ESRI\conda\envs\...
|
||||
|
||||
if os.path.exists(conda_exe) and os.path.exists(default_env) and os.path.exists(new_env) and not os.path.exists(new_env + "\\python.exe"):
|
||||
# conda environment invalid: delete it's folder
|
||||
@@ -60,9 +64,9 @@ def clone_env(pythonExec_old: str, env_new_name: str):
|
||||
print(new_env + "\\python.exe")
|
||||
return new_env + "\\python.exe"
|
||||
|
||||
def activate_env(env_new_name: str):
|
||||
def activate_env():
|
||||
# using Popen, because process does not return result; subprocess.run will hang indefinitely
|
||||
variable = subprocess.Popen((f'proswap {env_new_name}'),stdout = subprocess.PIPE,stderr = subprocess.PIPE,text = True,shell = True)
|
||||
variable = subprocess.Popen((f'proswap {ENV_NEW_NAME}'),stdout = subprocess.PIPE,stderr = subprocess.PIPE,text = True,shell = True)
|
||||
# activate new env : https://support.esri.com/en/technical-article/000024206
|
||||
|
||||
|
||||
@@ -152,10 +156,16 @@ def installDependencies(pythonExec: str, pkgName: str, pkgVersion: str):
|
||||
return True
|
||||
|
||||
pythonPath = setup()
|
||||
print(pythonPath)
|
||||
if pythonPath is not None:
|
||||
|
||||
#def_exec = get_default_python()
|
||||
#conda_exe = def_exec.replace("Pro\\bin\\Python\\envs\\arcgispro-py3\\python.exe","Pro\\bin\\Python\\Scripts\\conda.exe") #%PROGRAMFILES%\ArcGIS\Pro\bin\Python\Scripts\conda.exe #base: %PROGRAMDATA%\Anaconda3\condabin\conda.bat
|
||||
#subprocess_call([conda_exe, 'proup','-n', ENV_NEW_NAME])
|
||||
|
||||
clearToolbox(pythonPath)
|
||||
installToolbox(pythonPath)
|
||||
installDependencies(pythonPath, "specklepy", "2.9.0" )
|
||||
installDependencies(pythonPath, "specklepy", "2.17.12" )
|
||||
installDependencies(pythonPath, "panda3d", "1.10.11" )
|
||||
installDependencies(pythonPath, "PyQt5", "5.15.9" )
|
||||
|
||||
|
||||
@@ -1,77 +1,2 @@
|
||||
<?xml version="1.0"?>
|
||||
<metadata xml:lang="en"><Esri><CreaDate>20220718</CreaDate><CreaTime>13500100</CreaTime><ArcGISFormat>1.0</ArcGISFormat><SyncOnce>TRUE</SyncOnce><ModDate>20230912</ModDate><ModTime>150318</ModTime><scaleRange><minScale>150000000</minScale><maxScale>5000</maxScale></scaleRange><ArcGISProfile>ItemDescription</ArcGISProfile></Esri><toolbox name="Speckle" alias="speckle_toolbox_"><arcToolboxHelpPath>c:\program files\arcgis\pro\Resources\Help\gp</arcToolboxHelpPath><toolsets/></toolbox><dataIdInfo><idCitation><resTitle>Speckle</resTitle></idCitation><idPurp>Speckle connector for ArcGIS</idPurp><searchKeys><keyword>speckle3d</keyword></searchKeys></dataIdInfo><distInfo><distributor><distorFormat><formatName>ArcToolbox Toolbox</formatName></distorFormat></distributor></distInfo><mdHrLv><ScopeCd value="005"></ScopeCd></mdHrLv><Binary><Thumbnail><Data EsriPropertyType="PictureX">/9j/4AAQSkZJRgABAQEAYABgAAD/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRyUkdC
|
||||
IFhZWiAHzgACAAkABgAxAABhY3NwTVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA9tYAAQAA
|
||||
AADTLUhQICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFj
|
||||
cHJ0AAABUAAAADNkZXNjAAABhAAAAGx3dHB0AAAB8AAAABRia3B0AAACBAAAABRyWFlaAAACGAAA
|
||||
ABRnWFlaAAACLAAAABRiWFlaAAACQAAAABRkbW5kAAACVAAAAHBkbWRkAAACxAAAAIh2dWVkAAAD
|
||||
TAAAAIZ2aWV3AAAD1AAAACRsdW1pAAAD+AAAABRtZWFzAAAEDAAAACR0ZWNoAAAEMAAAAAxyVFJD
|
||||
AAAEPAAACAxnVFJDAAAEPAAACAxiVFJDAAAEPAAACAx0ZXh0AAAAAENvcHlyaWdodCAoYykgMTk5
|
||||
OCBIZXdsZXR0LVBhY2thcmQgQ29tcGFueQAAZGVzYwAAAAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEA
|
||||
AAAAAAAAAAAAABJzUkdCIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAWFlaIAAAAAAAAPNRAAEAAAABFsxYWVogAAAAAAAAAAAAAAAA
|
||||
AAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAA
|
||||
AA+EAAC2z2Rlc2MAAAAAAAAAFklFQyBodHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAFklFQyBo
|
||||
dHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAABkZXNjAAAAAAAAAC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAt
|
||||
IHNSR0IAAAAAAAAAAAAAAC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAt
|
||||
IHNSR0IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAAAAAAAAAsUmVmZXJlbmNlIFZpZXdpbmcg
|
||||
Q29uZGl0aW9uIGluIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENv
|
||||
bmRpdGlvbiBpbiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZpZXcAAAAA
|
||||
ABOk/gAUXy4AEM8UAAPtzAAEEwsAA1yeAAAAAVhZWiAAAAAAAEwJVgBQAAAAVx/nbWVhcwAAAAAA
|
||||
AAABAAAAAAAAAAAAAAAAAAAAAAAAAo8AAAACc2lnIAAAAABDUlQgY3VydgAAAAAAAAQAAAAABQAK
|
||||
AA8AFAAZAB4AIwAoAC0AMgA3ADsAQABFAEoATwBUAFkAXgBjAGgAbQByAHcAfACBAIYAiwCQAJUA
|
||||
mgCfAKQAqQCuALIAtwC8AMEAxgDLANAA1QDbAOAA5QDrAPAA9gD7AQEBBwENARMBGQEfASUBKwEy
|
||||
ATgBPgFFAUwBUgFZAWABZwFuAXUBfAGDAYsBkgGaAaEBqQGxAbkBwQHJAdEB2QHhAekB8gH6AgMC
|
||||
DAIUAh0CJgIvAjgCQQJLAlQCXQJnAnECegKEAo4CmAKiAqwCtgLBAssC1QLgAusC9QMAAwsDFgMh
|
||||
Ay0DOANDA08DWgNmA3IDfgOKA5YDogOuA7oDxwPTA+AD7AP5BAYEEwQgBC0EOwRIBFUEYwRxBH4E
|
||||
jASaBKgEtgTEBNME4QTwBP4FDQUcBSsFOgVJBVgFZwV3BYYFlgWmBbUFxQXVBeUF9gYGBhYGJwY3
|
||||
BkgGWQZqBnsGjAadBq8GwAbRBuMG9QcHBxkHKwc9B08HYQd0B4YHmQesB78H0gflB/gICwgfCDII
|
||||
RghaCG4IggiWCKoIvgjSCOcI+wkQCSUJOglPCWQJeQmPCaQJugnPCeUJ+woRCicKPQpUCmoKgQqY
|
||||
Cq4KxQrcCvMLCwsiCzkLUQtpC4ALmAuwC8gL4Qv5DBIMKgxDDFwMdQyODKcMwAzZDPMNDQ0mDUAN
|
||||
Wg10DY4NqQ3DDd4N+A4TDi4OSQ5kDn8Omw62DtIO7g8JDyUPQQ9eD3oPlg+zD88P7BAJECYQQxBh
|
||||
EH4QmxC5ENcQ9RETETERTxFtEYwRqhHJEegSBxImEkUSZBKEEqMSwxLjEwMTIxNDE2MTgxOkE8UT
|
||||
5RQGFCcUSRRqFIsUrRTOFPAVEhU0FVYVeBWbFb0V4BYDFiYWSRZsFo8WshbWFvoXHRdBF2UXiReu
|
||||
F9IX9xgbGEAYZRiKGK8Y1Rj6GSAZRRlrGZEZtxndGgQaKhpRGncanhrFGuwbFBs7G2MbihuyG9oc
|
||||
AhwqHFIcexyjHMwc9R0eHUcdcB2ZHcMd7B4WHkAeah6UHr4e6R8THz4faR+UH78f6iAVIEEgbCCY
|
||||
IMQg8CEcIUghdSGhIc4h+yInIlUigiKvIt0jCiM4I2YjlCPCI/AkHyRNJHwkqyTaJQklOCVoJZcl
|
||||
xyX3JicmVyaHJrcm6CcYJ0kneierJ9woDSg/KHEooijUKQYpOClrKZ0p0CoCKjUqaCqbKs8rAis2
|
||||
K2krnSvRLAUsOSxuLKIs1y0MLUEtdi2rLeEuFi5MLoIuty7uLyQvWi+RL8cv/jA1MGwwpDDbMRIx
|
||||
SjGCMbox8jIqMmMymzLUMw0zRjN/M7gz8TQrNGU0njTYNRM1TTWHNcI1/TY3NnI2rjbpNyQ3YDec
|
||||
N9c4FDhQOIw4yDkFOUI5fzm8Ofk6Njp0OrI67zstO2s7qjvoPCc8ZTykPOM9Ij1hPaE94D4gPmA+
|
||||
oD7gPyE/YT+iP+JAI0BkQKZA50EpQWpBrEHuQjBCckK1QvdDOkN9Q8BEA0RHRIpEzkUSRVVFmkXe
|
||||
RiJGZ0arRvBHNUd7R8BIBUhLSJFI10kdSWNJqUnwSjdKfUrESwxLU0uaS+JMKkxyTLpNAk1KTZNN
|
||||
3E4lTm5Ot08AT0lPk0/dUCdQcVC7UQZRUFGbUeZSMVJ8UsdTE1NfU6pT9lRCVI9U21UoVXVVwlYP
|
||||
VlxWqVb3V0RXklfgWC9YfVjLWRpZaVm4WgdaVlqmWvVbRVuVW+VcNVyGXNZdJ114XcleGl5sXr1f
|
||||
D19hX7NgBWBXYKpg/GFPYaJh9WJJYpxi8GNDY5dj62RAZJRk6WU9ZZJl52Y9ZpJm6Gc9Z5Nn6Wg/
|
||||
aJZo7GlDaZpp8WpIap9q92tPa6dr/2xXbK9tCG1gbbluEm5rbsRvHm94b9FwK3CGcOBxOnGVcfBy
|
||||
S3KmcwFzXXO4dBR0cHTMdSh1hXXhdj52m3b4d1Z3s3gReG54zHkqeYl553pGeqV7BHtje8J8IXyB
|
||||
fOF9QX2hfgF+Yn7CfyN/hH/lgEeAqIEKgWuBzYIwgpKC9INXg7qEHYSAhOOFR4Wrhg6GcobXhzuH
|
||||
n4gEiGmIzokziZmJ/opkisqLMIuWi/yMY4zKjTGNmI3/jmaOzo82j56QBpBukNaRP5GokhGSepLj
|
||||
k02TtpQglIqU9JVflcmWNJaflwqXdZfgmEyYuJkkmZCZ/JpomtWbQpuvnByciZz3nWSd0p5Anq6f
|
||||
HZ+Ln/qgaaDYoUehtqImopajBqN2o+akVqTHpTilqaYapoum/adup+CoUqjEqTepqaocqo+rAqt1
|
||||
q+msXKzQrUStuK4trqGvFq+LsACwdbDqsWCx1rJLssKzOLOutCW0nLUTtYq2AbZ5tvC3aLfguFm4
|
||||
0blKucK6O7q1uy67p7whvJu9Fb2Pvgq+hL7/v3q/9cBwwOzBZ8Hjwl/C28NYw9TEUcTOxUvFyMZG
|
||||
xsPHQce/yD3IvMk6ybnKOMq3yzbLtsw1zLXNNc21zjbOts83z7jQOdC60TzRvtI/0sHTRNPG1EnU
|
||||
y9VO1dHWVdbY11zX4Nhk2OjZbNnx2nba+9uA3AXcit0Q3ZbeHN6i3ynfr+A24L3hROHM4lPi2+Nj
|
||||
4+vkc+T85YTmDeaW5x/nqegy6LzpRunQ6lvq5etw6/vshu0R7ZzuKO6070DvzPBY8OXxcvH/8ozz
|
||||
GfOn9DT0wvVQ9d72bfb794r4Gfio+Tj5x/pX+uf7d/wH/Jj9Kf26/kv+3P9t////2wBDAAMCAgMC
|
||||
AgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIU
|
||||
FRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU
|
||||
FBQUFBQUFBQUFBQUFBT/wAARCAAgACADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAEC
|
||||
AwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0Kx
|
||||
wRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1
|
||||
dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ
|
||||
2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QA
|
||||
tREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYk
|
||||
NOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaH
|
||||
iImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq
|
||||
8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9Kfif8SNJ+EngjUPFeui4OlWLwrObWMPIolmSINtJGQDI
|
||||
Ccc4BwCcA8rbftG+F7y3iuLe31CeCVBJHLGkTK6kZDAiTBBHeuZ/bq/5NW8b/wDbj/6XW9fmzpP/
|
||||
ACC7P/rin/oIr9T4V4XwueYKVetJqSk18rRfl3Z8NxLnlfJfZypK/MfpTq37XHhmxvpbeFLVhGdj
|
||||
C71KKGRWHDKUG7GD716V8OfihoHxP0l7vRr+2uZ4Nq3drDOsj27HOA209Dg4bvg9CCB+S1fZf/BO
|
||||
v/moH/cP/wDbmvX4j4OwOV5XUxlBvmhy/O8ktfvvofO5DxVjMxzKGFrJcs7/ACsm/wBD1H9ur/k1
|
||||
bxv/ANuP/pdb1+bOk/8AILs/+uKf+giv2Y1DT7XVrC5sb62hvLK5iaGe2uIxJHLGwIZGU8MpBIIP
|
||||
BBrw/Rf2JPhRpLXQk0e81GGWTdDDdahMFtU7RxmNlJUDAy5ZuOWNeTwlxVg8jwlShioybcuZctne
|
||||
6Stq1ta+/wDwfoOKMjxOcqlHDNK173dvyTPzhr7L/wCCdf8AzUD/ALh//tzXsv8Awx58If8AoUf/
|
||||
ACpXn/x6uz+HXwd8IfCf+0P+EV0j+yv7Q8v7T/pM03mbN2z/AFjtjG9umOtepxDxpl+bZZVwVCE1
|
||||
KXLa6jbSSfST7djwMi4Sx2WZjSxdacHGN72bvrFrrFd+5//Z</Data></Thumbnail></Binary><mdDateSt Sync="TRUE">20220725</mdDateSt></metadata>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata xml:lang="en"><Esri><CreaDate>20231206</CreaDate><CreaTime>23391500</CreaTime><ArcGISFormat>1.0</ArcGISFormat><SyncOnce>TRUE</SyncOnce><ModDate>20231206</ModDate><ModTime>233915</ModTime></Esri><toolbox name="Speckle" alias="speckle_toolbox_"><arcToolboxHelpPath>c:\program files\arcgis\pro\Resources\Help\gp</arcToolboxHelpPath><toolsets/></toolbox><dataIdInfo><idCitation><resTitle>Speckle</resTitle></idCitation></dataIdInfo><distInfo><distributor><distorFormat><formatName>ArcToolbox Toolbox</formatName></distorFormat></distributor></distInfo></metadata>
|
||||
|
||||
@@ -33,13 +33,14 @@ try:
|
||||
from speckle.speckle.converter.layers.Layer import (Layer, VectorLayer, RasterLayer)
|
||||
from speckle.speckle.converter.layers import convertSelectedLayers, getLayers
|
||||
from speckle.speckle.converter.layers.utils import findAndClearLayerGroup
|
||||
from speckle.speckle.ui.validation import tryGetStream, validateBranch, validateCommit, validateStream, validateTransport
|
||||
from speckle.speckle.ui.validation import tryGetStream, tryGetClient, validateBranch, validateCommit, validateStream, validateTransport
|
||||
from speckle.speckle.ui.add_stream_modal import AddStreamModalDialog
|
||||
from speckle.speckle.ui.create_stream import CreateStreamModalDialog
|
||||
from speckle.speckle.ui.create_branch import CreateBranchModalDialog
|
||||
from speckle.speckle.ui.speckle_qgis_dialog import SpeckleGISDialog
|
||||
from speckle.speckle.ui.logger import logToUser, logToUserWithAction
|
||||
from speckle.speckle.plugin_utils.helpers import removeSpecialCharacters, getAppName
|
||||
from speckle.specklepy_qt_ui.qt_ui.DataStorage import DataStorage
|
||||
|
||||
except:
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.plugin_utils.object_utils import callback, traverseObject
|
||||
@@ -47,13 +48,14 @@ except:
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.converter.layers import convertSelectedLayers, getLayers
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.converter.layers.emptyLayerTemplates import createGroupLayer
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.converter.layers.utils import findAndClearLayerGroup
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.validation import tryGetStream, validateBranch, validateCommit, validateStream, validateTransport
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.validation import tryGetStream, tryGetClient, validateBranch, validateCommit, validateStream, validateTransport
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.add_stream_modal import AddStreamModalDialog
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.create_stream import CreateStreamModalDialog
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.create_branch import CreateBranchModalDialog
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.speckle_qgis_dialog import SpeckleGISDialog
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.logger import logToUser, logToUserWithAction
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.plugin_utils.helpers import removeSpecialCharacters, getAppName
|
||||
from speckle_toolbox.esri.toolboxes.speckle.specklepy_qt_ui.qt_ui.DataStorage import DataStorage
|
||||
|
||||
# Import the code for the dialog
|
||||
|
||||
@@ -138,6 +140,7 @@ class SpeckleGIS:
|
||||
|
||||
version: str
|
||||
gis_version: str
|
||||
dataStorage: DataStorage
|
||||
dockwidget: Optional[SpeckleGISDialog]
|
||||
add_stream_modal: AddStreamModalDialog
|
||||
create_stream_modal: CreateStreamModalDialog
|
||||
@@ -168,6 +171,7 @@ class SpeckleGIS:
|
||||
|
||||
self.gis_version = full_version
|
||||
# Save reference to the QGIS interface
|
||||
self.dataStorage = None
|
||||
self.dockwidget = None
|
||||
#self.iface = None
|
||||
self.gis_project = ArcGISProject('CURRENT') #QgsProject.instance()
|
||||
@@ -385,9 +389,13 @@ class SpeckleGIS:
|
||||
streamWrapper = self.active_stream[0]
|
||||
streamName = self.active_stream[1].name
|
||||
streamId = streamWrapper.stream_id
|
||||
client = streamWrapper.get_client()
|
||||
|
||||
# client = streamWrapper.get_client()
|
||||
client, stream = tryGetClient(
|
||||
streamWrapper, self.dataStorage, False, self.dockwidget
|
||||
)
|
||||
|
||||
stream = validateStream(streamWrapper)
|
||||
stream = validateStream(stream, self.dockwidget)
|
||||
if stream == None: return
|
||||
|
||||
branchName = str(self.dockwidget.streamBranchDropdown.currentText())
|
||||
@@ -472,14 +480,19 @@ class SpeckleGIS:
|
||||
# Get the stream wrapper
|
||||
streamWrapper = self.active_stream[0]
|
||||
streamId = streamWrapper.stream_id
|
||||
client = streamWrapper.get_client()
|
||||
#client = streamWrapper.get_client()
|
||||
|
||||
client, stream = tryGetClient(
|
||||
streamWrapper, self.dataStorage, False, self.dockwidget
|
||||
)
|
||||
# Ensure the stream actually exists
|
||||
print("ON RECEIVE 2")
|
||||
except Exception as e:
|
||||
logToUser(str(e), level=2, func = inspect.stack()[0][3], plugin = self.dockwidget)
|
||||
return
|
||||
try:
|
||||
stream = validateStream(streamWrapper)
|
||||
|
||||
stream = validateStream(stream, self.dockwidget)
|
||||
if stream == None: return
|
||||
|
||||
branchName = str(self.dockwidget.streamBranchDropdown.currentText())
|
||||
@@ -559,9 +572,12 @@ class SpeckleGIS:
|
||||
try:
|
||||
from speckle.ui.project_vars import get_project_streams, get_survey_point, get_project_layer_selection
|
||||
except:
|
||||
from speckle_toolbox.esri.toolboxes.speckle.ui.project_vars import get_project_streams, get_survey_point, get_project_layer_selection
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.project_vars import get_project_streams, get_survey_point, get_project_layer_selection
|
||||
|
||||
self.is_setup = self.check_for_accounts()
|
||||
self.dataStorage = DataStorage()
|
||||
self.dataStorage.plugin_version = self.version
|
||||
|
||||
self.is_setup = self.dataStorage.check_for_accounts()
|
||||
if self.dockwidget is not None:
|
||||
self.active_stream = None
|
||||
get_project_streams(self)
|
||||
@@ -593,11 +609,11 @@ class SpeckleGIS:
|
||||
"""Run method that performs all the real work"""
|
||||
print("run plugin")
|
||||
try:
|
||||
from speckle.ui.speckle_qgis_dialog import SpeckleGISDialog
|
||||
from speckle.ui.project_vars import get_project_streams, get_survey_point, get_project_layer_selection
|
||||
from speckle.speckle.ui.speckle_qgis_dialog import SpeckleGISDialog
|
||||
from speckle.speckle.ui.project_vars import get_project_streams, get_survey_point, get_project_layer_selection
|
||||
except:
|
||||
from speckle_toolbox.esri.toolboxes.speckle.ui.speckle_qgis_dialog import SpeckleGISDialog
|
||||
from speckle_toolbox.esri.toolboxes.speckle.ui.project_vars import get_project_streams, get_survey_point, get_project_layer_selection
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.speckle_qgis_dialog import SpeckleGISDialog
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.project_vars import get_project_streams, get_survey_point, get_project_layer_selection
|
||||
try:
|
||||
# Create the dialog with elements (after translation) and keep reference
|
||||
# Only create GUI ONCE in callback, so that it will only load when the plugin is started
|
||||
@@ -606,6 +622,11 @@ class SpeckleGIS:
|
||||
if self.pluginIsActive:
|
||||
self.reloadUI()
|
||||
else:
|
||||
|
||||
self.dataStorage = DataStorage()
|
||||
self.dataStorage.plugin_version = self.version
|
||||
self.is_setup = self.dataStorage.check_for_accounts()
|
||||
|
||||
self.pluginIsActive = True
|
||||
if self.dockwidget is None:
|
||||
self.dockwidget = SpeckleGISDialog()
|
||||
@@ -639,7 +660,7 @@ class SpeckleGIS:
|
||||
try:
|
||||
from speckle.ui.project_vars import set_survey_point
|
||||
except:
|
||||
from speckle_toolbox.esri.toolboxes.speckle.ui.project_vars import set_survey_point
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.project_vars import set_survey_point
|
||||
set_survey_point(self)
|
||||
|
||||
def onStreamCreateClicked(self):
|
||||
@@ -693,7 +714,7 @@ class SpeckleGIS:
|
||||
if isinstance(br_id, GraphQLException):
|
||||
logToUser(br_id.message, level=2, func = inspect.stack()[0][3])
|
||||
|
||||
self.active_stream = (sw, tryGetStream(sw))
|
||||
self.active_stream = (sw, tryGetStream(sw, self.dataStorage))
|
||||
self.current_streams[0] = self.active_stream
|
||||
|
||||
self.dockwidget.populateActiveStreamBranchDropdown(self)
|
||||
@@ -706,14 +727,14 @@ class SpeckleGIS:
|
||||
|
||||
def handleStreamAdd(self, sw: StreamWrapper):
|
||||
try:
|
||||
from speckle.ui.project_vars import set_project_streams
|
||||
from speckle.speckle.ui.project_vars import set_project_streams
|
||||
except:
|
||||
from speckle_toolbox.esri.toolboxes.speckle.ui.project_vars import set_project_streams
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.project_vars import set_project_streams
|
||||
|
||||
streamExists = 0
|
||||
index = 0
|
||||
try:
|
||||
stream = tryGetStream(sw)
|
||||
stream = tryGetStream(sw, self.dataStorage)
|
||||
|
||||
for st in self.current_streams:
|
||||
if isinstance(stream, Stream) and st[0].stream_id == stream.id:
|
||||
|
||||
@@ -33,50 +33,51 @@ except:
|
||||
|
||||
FIELDS = ["project_streams","project_layer_selection", "lat_lon"]
|
||||
|
||||
def get_project_streams(self: SpeckleGIS, content: str = None):
|
||||
def get_project_streams(plugin: SpeckleGIS, content: str = None):
|
||||
try:
|
||||
print("get proj streams")
|
||||
|
||||
print("GET proj streams")
|
||||
project = self.gis_project
|
||||
project = plugin.gis_project
|
||||
table = findOrCreateSpeckleTable(project)
|
||||
if table is None: return
|
||||
logToUser(table, level=0, func = inspect.stack()[0][3])
|
||||
|
||||
rows = arcpy.da.SearchCursor(table, "project_streams")
|
||||
saved_streams = []
|
||||
for x in rows:
|
||||
logToUser(x, level=0, func = inspect.stack()[0][3])
|
||||
saved_streams.append(x[0])
|
||||
|
||||
temp = []
|
||||
######### need to check whether saved streams are available (account reachable)
|
||||
if len(saved_streams) > 0:
|
||||
for url in saved_streams:
|
||||
if url=="": continue
|
||||
try:
|
||||
sw = StreamWrapper(url)
|
||||
try:
|
||||
stream = tryGetStream(sw)
|
||||
stream = tryGetStream(sw, plugin.dataStorage)
|
||||
except SpeckleException as e:
|
||||
logToUser(e.message, level=2, func = inspect.stack()[0][3])
|
||||
stream = None
|
||||
#strId = stream.id # will cause exception if invalid
|
||||
temp.append((sw, stream))
|
||||
except SpeckleException as e:
|
||||
logToUser(e.message, 2)
|
||||
logToUser(e.message, level=2, func = inspect.stack()[0][3])
|
||||
#except GraphQLException as e:
|
||||
# logger.logToUser(e.message, Qgis.Warning)
|
||||
self.current_streams = temp
|
||||
plugin.current_streams = temp
|
||||
except Exception as e:
|
||||
logToUser(str(e), level=2, func = inspect.stack()[0][3])
|
||||
|
||||
def set_project_streams(self: SpeckleGIS):
|
||||
def set_project_streams(plugin: SpeckleGIS):
|
||||
try:
|
||||
print("SET proj streams")
|
||||
project = self.gis_project
|
||||
project = plugin.gis_project
|
||||
table = findOrCreateSpeckleTable(project)
|
||||
print("SET proj streams 2")
|
||||
|
||||
value = [stream[0].stream_url for stream in self.current_streams] #",".join()
|
||||
value = [stream[0].stream_url for stream in plugin.current_streams] #",".join()
|
||||
print(value)
|
||||
logToUser(value, level=0, func = inspect.stack()[0][3])
|
||||
|
||||
if table is not None:
|
||||
proj_layers = []
|
||||
@@ -106,10 +107,10 @@ def set_project_streams(self: SpeckleGIS):
|
||||
except Exception as e:
|
||||
logToUser(str(e), level=2, func = inspect.stack()[0][3])
|
||||
|
||||
def get_project_layer_selection(self: SpeckleGIS):
|
||||
def get_project_layer_selection(plugin: SpeckleGIS):
|
||||
try:
|
||||
print("GET project layer selection from the table")
|
||||
project = self.gis_project
|
||||
project = plugin.gis_project
|
||||
table = findOrCreateSpeckleTable(project)
|
||||
if table is None: return
|
||||
|
||||
@@ -134,7 +135,7 @@ def get_project_layer_selection(self: SpeckleGIS):
|
||||
break
|
||||
if found == 0:
|
||||
logToUser(f'Saved layer not found: "{layerPath}"', level=1, func = inspect.stack()[0][3])
|
||||
self.current_layers = temp
|
||||
plugin.current_layers = temp
|
||||
except Exception as e:
|
||||
logToUser(str(e), level=2, func = inspect.stack()[0][3])
|
||||
|
||||
@@ -287,12 +288,12 @@ def findOrCreateSpeckleTable(project: ArcGISProject) -> Union[str, None]:
|
||||
arcpy.management.AddField(table, "lat_lon", "TEXT")
|
||||
|
||||
cursor = arcpy.da.InsertCursor(table, FIELDS )
|
||||
cursor.insertRow(["",""])
|
||||
cursor.insertRow(["","",""])
|
||||
del cursor
|
||||
|
||||
except Exception as e:
|
||||
logToUser("Error creating a table: " + str(e), level=1, func = inspect.stack()[0][3])
|
||||
return None
|
||||
raise e
|
||||
else:
|
||||
#print("table already exists")
|
||||
# make sure fileds exist
|
||||
@@ -354,266 +355,3 @@ def findOrCreateRow(table:str, fields: List[str]):
|
||||
|
||||
except Exception as e:
|
||||
logToUser(str(e), level=2, func = inspect.stack()[0][3])
|
||||
|
||||
r'''
|
||||
class speckleInputsClass:
|
||||
#def __init__(self):
|
||||
print("CREATING speckle inputs first time________")
|
||||
instances = []
|
||||
accounts: List[Account] = get_local_accounts()
|
||||
account = None
|
||||
streams_default: Optional[List[Stream]] = None
|
||||
|
||||
project = None
|
||||
active_map = None
|
||||
saved_streams: List[Optional[Tuple[StreamWrapper, Stream]]] = []
|
||||
stream_file_path: str = ""
|
||||
all_layers: List[arcLayer] = []
|
||||
clients: List[SpeckleClient] = []
|
||||
|
||||
for acc in accounts:
|
||||
if acc.isDefault: account = acc
|
||||
new_client = SpeckleClient(
|
||||
acc.serverInfo.url,
|
||||
acc.serverInfo.url.startswith("https")
|
||||
)
|
||||
new_client.authenticate_with_token(token=acc.token)
|
||||
clients.append(new_client)
|
||||
|
||||
speckle_client = None
|
||||
if account:
|
||||
speckle_client = SpeckleClient(
|
||||
account.serverInfo.url,
|
||||
account.serverInfo.url.startswith("https")
|
||||
)
|
||||
speckle_client.authenticate_with_token(token=account.token)
|
||||
streams_default = speckle_client.stream.search("")
|
||||
|
||||
def __init__(self) -> None:
|
||||
print("___start speckle inputs________")
|
||||
self.all_layers = []
|
||||
try:
|
||||
aprx = ArcGISProject('CURRENT')
|
||||
self.project = aprx
|
||||
# following will fail if no project found
|
||||
self.active_map = aprx.activeMap
|
||||
|
||||
if self.active_map is not None and isinstance(self.active_map, Map): # if project loaded
|
||||
for layer in self.active_map.listLayers():
|
||||
try: geomType = arcpy.Describe(layer.dataSource).shapeType.lower()
|
||||
except: geomType = '' #print(arcpy.Describe(layer.dataSource)) #and arcpy.Describe(layer.dataSource).shapeType.lower() != "multipatch")
|
||||
if (layer.isFeatureLayer and geomType != "multipatch") or layer.isRasterLayer: self.all_layers.append(layer) #type: 'arcpy._mp.Layer'
|
||||
self.stream_file_path: str = aprx.filePath.replace("aprx","gdb") + "\\speckle_streams.txt"
|
||||
|
||||
if os.path.exists(self.stream_file_path):
|
||||
try:
|
||||
f = open(self.stream_file_path, "r")
|
||||
content = f.read()
|
||||
self.saved_streams = self.getProjectStreams(content)
|
||||
f.close()
|
||||
except: pass
|
||||
|
||||
elif len(self.stream_file_path) >10:
|
||||
f = open(self.stream_file_path, "x")
|
||||
f.close()
|
||||
f = open(self.stream_file_path, "w")
|
||||
content = ""
|
||||
f.write(content)
|
||||
f.close()
|
||||
except: self.project = None; print("Project not found")
|
||||
self.instances.append(self)
|
||||
|
||||
def getProjectStreams(self, content: str = None):
|
||||
print("get proj streams")
|
||||
if not content:
|
||||
content = self.stream_file_path
|
||||
try:
|
||||
f = open(self.stream_file_path, "r")
|
||||
content = f.read()
|
||||
f.close()
|
||||
except: pass
|
||||
|
||||
######### need to check whether saved streams are available (account reachable)
|
||||
if content:
|
||||
streamsTuples = []
|
||||
for i, url in enumerate(content.split(",")):
|
||||
|
||||
streamExists = 0
|
||||
index = 0
|
||||
try:
|
||||
#print(url)
|
||||
sw = StreamWrapper(url)
|
||||
stream = self.tryGetStream(sw)
|
||||
|
||||
for st in streamsTuples:
|
||||
if isinstance(stream, Stream) and st[0].stream_id == stream.id:
|
||||
streamExists = 1;
|
||||
break
|
||||
index += 1
|
||||
if streamExists == 1: del streamsTuples[index]
|
||||
streamsTuples.insert(0,(sw, stream))
|
||||
|
||||
except SpeckleException as e:
|
||||
arcpy.AddMessage(str(e.args))
|
||||
return streamsTuples
|
||||
else: return []
|
||||
|
||||
def tryGetStream (self,sw: StreamWrapper) -> Stream:
|
||||
if isinstance(sw, StreamWrapper):
|
||||
steamId = sw.stream_id
|
||||
try: steamId = sw.stream_id.split("/streams/")[1].split("/")[0]
|
||||
except: pass
|
||||
|
||||
client = sw.get_client()
|
||||
stream = client.stream.get(id = steamId, branch_limit = 100, commit_limit = 100)
|
||||
if isinstance(stream, GraphQLException):
|
||||
raise SpeckleException(stream.errors[0]['message'])
|
||||
return stream
|
||||
else:
|
||||
raise SpeckleException('Invalid StreamWrapper provided')
|
||||
|
||||
class toolboxInputsClass:
|
||||
|
||||
print("CREATING UI inputs first time________")
|
||||
instances = []
|
||||
lat: float = 0.0
|
||||
lon: float = 0.0
|
||||
active_stream: Optional[Stream] = None
|
||||
active_stream_wrapper: Optional[StreamWrapper] = None
|
||||
active_branch: Optional[Branch] = None
|
||||
active_commit = None
|
||||
selected_layers: List[Any] = []
|
||||
messageSpeckle: str = ""
|
||||
action: int = 1 #send
|
||||
project = None
|
||||
stream_file_path: str = ""
|
||||
# Get the target item's Metadata object
|
||||
|
||||
def __init__(self) -> None:
|
||||
print("___start UI inputs________")
|
||||
try:
|
||||
aprx = ArcGISProject('CURRENT')
|
||||
project = aprx
|
||||
self.stream_file_path: str = aprx.filePath.replace("aprx","gdb") + "\\speckle_streams.txt"
|
||||
if os.path.exists(self.stream_file_path):
|
||||
try:
|
||||
f = open(self.stream_file_path, "r")
|
||||
content = f.read()
|
||||
self.lat, self.lon = self.get_survey_point(content)
|
||||
f.close()
|
||||
except: pass
|
||||
except: print("Project not found")
|
||||
try:
|
||||
aprx = ArcGISProject('CURRENT')
|
||||
self.project = aprx
|
||||
except: self.project = None; print("Project not found"); arcpy.AddWarning("Project not found")
|
||||
self.instances.append(self)
|
||||
|
||||
def setProjectStreams(self, wr: StreamWrapper, add = True):
|
||||
# ERROR 032659 Error queueing metrics request:
|
||||
print("SET proj streams")
|
||||
|
||||
if os.path.exists(self.stream_file_path) and ".gdb\\speckle_streams.txt" in self.stream_file_path:
|
||||
|
||||
new_content = ""
|
||||
|
||||
f = open(self.stream_file_path, "r")
|
||||
existing_content = f.read()
|
||||
f.close()
|
||||
|
||||
f = open(self.stream_file_path, "w")
|
||||
if str(wr.stream_url) in existing_content:
|
||||
new_content = existing_content.replace(str(wr.stream_url) + "," , "")
|
||||
else:
|
||||
new_content = existing_content
|
||||
|
||||
if add == True: new_content += str(wr.stream_url) + "," # add stream
|
||||
else: pass # remove stream
|
||||
|
||||
f.write(new_content)
|
||||
f.close()
|
||||
elif ".gdb\\speckle_streams.txt" in self.stream_file_path:
|
||||
f = open(self.stream_file_path, "x")
|
||||
f.close()
|
||||
f = open(self.stream_file_path, "w")
|
||||
f.write(str(wr.stream_url) + ",")
|
||||
f.close()
|
||||
|
||||
def get_survey_point(self, content = None) -> Tuple[float]:
|
||||
# get from saved project
|
||||
print("get survey point")
|
||||
x = y = 0
|
||||
if not content:
|
||||
content = None
|
||||
if os.path.exists(self.stream_file_path) and ".gdb\\speckle_streams.txt" in self.stream_file_path:
|
||||
try:
|
||||
f = open(self.stream_file_path, "r")
|
||||
content = f.read()
|
||||
f.close()
|
||||
except: pass
|
||||
if content:
|
||||
for i, coords in enumerate(content.split(",")):
|
||||
if "speckle_sr_origin_" in coords:
|
||||
try:
|
||||
x, y = [float(c) for c in coords.replace("speckle_sr_origin_","").split(";")]
|
||||
except: pass
|
||||
return (x, y)
|
||||
|
||||
def set_survey_point(self, coords: List[float]):
|
||||
# from widget (2 strings) to local vars + update SR of the map
|
||||
print("SET survey point")
|
||||
|
||||
if len(coords) == 2:
|
||||
pt = "speckle_sr_origin_" + str(coords[0]) + ";" + str(coords[1])
|
||||
if os.path.exists(self.stream_file_path) and ".gdb\\speckle_streams.txt" in self.stream_file_path:
|
||||
|
||||
new_content = ""
|
||||
f = open(self.stream_file_path, "r")
|
||||
existing_content = f.read()
|
||||
f.close()
|
||||
|
||||
f = open(self.stream_file_path, "w")
|
||||
if pt in existing_content:
|
||||
new_content = existing_content.replace( pt , "")
|
||||
else:
|
||||
new_content = existing_content
|
||||
|
||||
new_content += pt + "," # add point
|
||||
f.write(new_content)
|
||||
f.close()
|
||||
elif ".gdb\\speckle_streams.txt" in self.stream_file_path:
|
||||
f = open(self.stream_file_path, "x")
|
||||
f.close()
|
||||
f = open(self.stream_file_path, "w")
|
||||
f.write(pt + ",")
|
||||
f.close()
|
||||
|
||||
# save to project; crearte SR
|
||||
self.lat, self.lon = coords[0], coords[1]
|
||||
newCrsString = "+proj=tmerc +ellps=WGS84 +datum=WGS84 +units=m +no_defs +lon_0=" + str(self.lon) + " lat_0=" + str(self.lat) + " +x_0=0 +y_0=0 +k_0=1"
|
||||
newCrs = osr.SpatialReference()
|
||||
newCrs.ImportFromProj4(newCrsString)
|
||||
newCrs.MorphToESRI() # converts the WKT to an ESRI-compatible format
|
||||
|
||||
|
||||
validate = True if len(newCrs.ExportToWkt())>10 else False
|
||||
|
||||
if validate:
|
||||
newProjSR = arcpy.SpatialReference()
|
||||
newProjSR.loadFromString(newCrs.ExportToWkt())
|
||||
|
||||
#source = osr.SpatialReference()
|
||||
#source.ImportFromWkt(self.project.activeMap.spatialReference.exportToString())
|
||||
#transform = osr.CoordinateTransformation(source, newCrs)
|
||||
|
||||
self.project.activeMap.spatialReference = newProjSR
|
||||
arcpy.AddMessage("Custom project CRS successfully applied")
|
||||
else:
|
||||
arcpy.AddWarning("Custom CRS could not be created")
|
||||
|
||||
else:
|
||||
arcpy.AddWarning("Custom CRS could not be created: not enough coordinates provided")
|
||||
|
||||
return True
|
||||
'''
|
||||
|
||||
@@ -429,9 +429,9 @@ class SpeckleGISDialog(QMainWindow):
|
||||
print("populate layer dropdown / clicked save selection")
|
||||
if not self: return
|
||||
try:
|
||||
from speckle.ui.project_vars import set_project_layer_selection
|
||||
from speckle.speckle.ui.project_vars import set_project_layer_selection
|
||||
except:
|
||||
from speckle_toolbox.esri.toolboxes.speckle.ui.project_vars import set_project_layer_selection
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.project_vars import set_project_layer_selection
|
||||
|
||||
try:
|
||||
self.layersWidget.clear()
|
||||
@@ -531,9 +531,9 @@ class SpeckleGISDialog(QMainWindow):
|
||||
def populateProjectStreams(self, plugin):
|
||||
|
||||
try:
|
||||
from speckle.ui.project_vars import set_project_streams
|
||||
from speckle.speckle.ui.project_vars import set_project_streams
|
||||
except:
|
||||
from speckle_toolbox.esri.toolboxes.speckle.ui.project_vars import set_project_streams
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.project_vars import set_project_streams
|
||||
|
||||
try:
|
||||
if not self: return
|
||||
|
||||
@@ -13,30 +13,101 @@ try:
|
||||
from speckle.speckle.ui.logger import logToUser
|
||||
except:
|
||||
from speckle_toolbox.esri.toolboxes.speckle.speckle.ui.logger import logToUser
|
||||
|
||||
def tryGetStream (sw: StreamWrapper) -> Union[Stream, None]:
|
||||
try:
|
||||
client = sw.get_client()
|
||||
stream = client.stream.get(id = sw.stream_id, branch_limit = 100, commit_limit = 100)
|
||||
if isinstance(stream, GraphQLException):
|
||||
raise SpeckleException(stream.errors[0]['message'])
|
||||
return stream
|
||||
except Exception as e:
|
||||
logToUser(str(e), level=2, func = inspect.stack()[0][3])
|
||||
return None
|
||||
|
||||
def validateStream(streamWrapper: StreamWrapper) -> Union[Stream, None]:
|
||||
def tryGetStream(
|
||||
sw: StreamWrapper, dataStorage, write=False, dockwidget=None
|
||||
) -> Union[Stream, None]:
|
||||
try:
|
||||
# print("tryGetStream")
|
||||
client, stream = tryGetClient(sw, dataStorage, write, dockwidget)
|
||||
return stream
|
||||
except Exception as e:
|
||||
logToUser(e, level=2, func=inspect.stack()[0][3], plugin=dockwidget)
|
||||
return None
|
||||
|
||||
|
||||
def tryGetClient(sw: StreamWrapper, dataStorage, write=False, dockwidget=None):
|
||||
# only streams with write access
|
||||
try:
|
||||
client = None
|
||||
savedRole = None
|
||||
savedStreamId = None
|
||||
for acc in dataStorage.accounts:
|
||||
# only check accounts on selected server
|
||||
if acc.serverInfo.url in sw.server_url:
|
||||
client = SpeckleClient(
|
||||
acc.serverInfo.url, acc.serverInfo.url.startswith("https")
|
||||
)
|
||||
try:
|
||||
client.authenticate_with_account(acc)
|
||||
if client.account.token is not None:
|
||||
break
|
||||
except SpeckleException as ex:
|
||||
if "already connected" in ex.message:
|
||||
logToUser(
|
||||
"Dependencies versioning error.\nClick here for details.",
|
||||
url="dependencies_error",
|
||||
level=2,
|
||||
plugin=dockwidget,
|
||||
)
|
||||
return
|
||||
else:
|
||||
raise ex
|
||||
|
||||
# if token still not found
|
||||
if client is None or client.account.token is None:
|
||||
for acc in dataStorage.accounts:
|
||||
client = sw.get_client()
|
||||
if client is not None:
|
||||
break
|
||||
|
||||
if client is not None:
|
||||
stream = client.stream.get(
|
||||
id=sw.stream_id, branch_limit=100, commit_limit=100
|
||||
)
|
||||
if isinstance(stream, Stream):
|
||||
# print(stream.role)
|
||||
if write == False:
|
||||
# try get stream, only read access needed
|
||||
# print("only read access needed")
|
||||
return client, stream
|
||||
else:
|
||||
# check write access
|
||||
# print("write access needed")
|
||||
if stream.role is None or (
|
||||
isinstance(stream.role, str) and "reviewer" in stream.role
|
||||
):
|
||||
savedRole = stream.role
|
||||
savedStreamId = stream.id
|
||||
else:
|
||||
return client, stream
|
||||
|
||||
if savedRole is not None and savedStreamId is not None:
|
||||
logToUser(
|
||||
f"You don't have write access to the stream '{savedStreamId}'. You role is '{savedRole}'",
|
||||
level=2,
|
||||
func=inspect.stack()[0][3],
|
||||
plugin=dockwidget,
|
||||
)
|
||||
|
||||
return None, None
|
||||
except Exception as e:
|
||||
logToUser(e, level=2, func=inspect.stack()[0][3], plugin=dockwidget)
|
||||
return None, None
|
||||
|
||||
|
||||
def validateStream(stream: Stream, dockwidget) -> Union[Stream, None]:
|
||||
try:
|
||||
stream = tryGetStream(streamWrapper)
|
||||
if isinstance(stream, SpeckleException): return None
|
||||
if isinstance(stream, SpeckleException):
|
||||
return None
|
||||
|
||||
if stream.branches is None:
|
||||
logToUser("Stream has no branches", level=2, func = inspect.stack()[0][3])
|
||||
logToUser("Stream has no branches", level=1, plugin=dockwidget)
|
||||
return None
|
||||
return stream
|
||||
except Exception as e:
|
||||
logToUser(str(e), level=2, func = inspect.stack()[0][3])
|
||||
return None
|
||||
logToUser(e, level=2, plugin=dockwidget)
|
||||
return
|
||||
|
||||
|
||||
def validateBranch(stream: Stream, branchName: str, checkCommits: bool) -> Union[Branch, None]:
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
|
||||
from typing import Dict, List
|
||||
|
||||
from numpy import double
|
||||
from import UpdateSavedStreams
|
||||
from import UpdateSelectedStream
|
||||
|
||||
from specklepy_qt_ui.qt_ui.ConnectorBindings import ConnectorBindings
|
||||
from specklepy_qt_ui.qt_ui.Models.StreamState import StreamState
|
||||
|
||||
class QGISBindings(ConnectorBindings):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def UpdateSavedStreams(self, streams: List[StreamState]):
|
||||
UpdateSavedStreams(streams)
|
||||
|
||||
def UpdateSelectedStream(self):
|
||||
UpdateSelectedStream()
|
||||
|
||||
def Open3DView(self, viewCoordinates: List[double], viewName: str = ""):
|
||||
'''Opens a 3D view in the host application
|
||||
viewCoordinates: First three values are the camera position, second three the target.
|
||||
viewName: Id or Name of the view'''
|
||||
return
|
||||
|
||||
def GetHostAppNameVersion(self)-> str:
|
||||
'''Gets the current host application name with version.'''
|
||||
return
|
||||
|
||||
def GetHostAppName(self) -> str:
|
||||
'''Gets the current host application name.'''
|
||||
return
|
||||
|
||||
def GetFileName(self) -> str:
|
||||
'''Gets the current opened/focused file's name.
|
||||
Make sure to check regarding unsaved/temporary files.'''
|
||||
return
|
||||
|
||||
def GetDocumentId(self) -> str:
|
||||
'''Gets the current opened/focused file's id.
|
||||
Generate one in here if the host app does not provide one.'''
|
||||
return
|
||||
|
||||
def GetDocumentLocation(self) -> str:
|
||||
'''Gets the current opened/focused file's locations.
|
||||
Make sure to check regarding unsaved/temporary files.'''
|
||||
return
|
||||
|
||||
def ResetDocument(self):
|
||||
'''Clears the document state of selections and previews'''
|
||||
return
|
||||
|
||||
def GetActiveViewName(self) -> str:
|
||||
'''Gets the current opened/focused file's view, if applicable.'''
|
||||
return
|
||||
|
||||
def GetStreamsInFile(self) -> List[StreamState]:
|
||||
'''Returns the serialised clients present in the current open host file.'''
|
||||
return
|
||||
|
||||
def WriteStreamsToFile(self, streams: List[StreamState]):
|
||||
'''Writes serialised clients to the current open host file.'''
|
||||
return
|
||||
|
||||
def AddNewStream(self, state: StreamState):
|
||||
'''Adds a new client and persists the info to the host file'''
|
||||
return
|
||||
|
||||
def PersistAndUpdateStreamInFile(self, state: StreamState):
|
||||
'''Persists the stream info to the host file; if maintaining a local in memory copy, make sure to update it too.'''
|
||||
return
|
||||
|
||||
def SendStream(self, state: StreamState, progress: ProgressViewModel) -> str:
|
||||
'''Pushes a client's stream'''
|
||||
return
|
||||
|
||||
def PreviewSend(self, state: StreamState, progress: ProgressViewModel):
|
||||
'''Previews a send operation'''
|
||||
|
||||
def ReceiveStream(self, state: StreamState, progress: ProgressViewModel) -> StreamState:
|
||||
'''Receives stream data from the server'''
|
||||
|
||||
def PreviewReceive(self, state: StreamState, progress: ProgressViewModel) -> StreamState:
|
||||
'''Previews a receive operation'''
|
||||
|
||||
def GetSelectedObjects(self) -> List[str]:
|
||||
'''Adds the current selection to the provided client.'''
|
||||
|
||||
def GetObjectsInView(self) -> List[str]:
|
||||
'''Gets a list of objects in the currently active view'''
|
||||
|
||||
def SelectClientObjects(self, objs: List[str], deselect: bool = False):
|
||||
'''clients should be able to select/preview/hover one way or another their associated objects'''
|
||||
|
||||
def GetSelectionFilters(self) -> List[ISelectionFilter]:
|
||||
'''Should return a list of filters that the application supports.'''
|
||||
|
||||
def GetReceiveModes(self) -> List[ReceiveMode]:
|
||||
'''Should return a list of receive modes that the application supports.'''
|
||||
|
||||
def GetCustomStreamMenuItems(self) -> List[MenuItem]:
|
||||
'''Return a list of custom menu items for stream cards.'''
|
||||
|
||||
def GetSettings(self) -> List[ISetting]:
|
||||
return
|
||||
|
||||
def ImportFamilyCommand(self, Mapping: Dict[str, List[MappingValue]] ) -> Dict[str, List[MappingValue]] :
|
||||
'''Imports family symbols in Revit'''
|
||||
return
|
||||
@@ -0,0 +1,104 @@
|
||||
import threading
|
||||
from specklepy_qt_ui.qt_ui.dockwidget_main import SpeckleQGISDialog as SpeckleQGISDialog_UI
|
||||
import specklepy_qt_ui.qt_ui
|
||||
|
||||
from speckle.ui_widgets.widget_transforms import MappingSendDialogQGIS
|
||||
|
||||
from PyQt5 import QtWidgets, uic
|
||||
import os
|
||||
import inspect
|
||||
from specklepy.logging.exceptions import (SpeckleException, GraphQLException)
|
||||
from specklepy.logging import metrics
|
||||
|
||||
|
||||
from PyQt5 import QtWidgets, uic
|
||||
from PyQt5.QtWidgets import QCheckBox, QListWidgetItem, QHBoxLayout, QWidget
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
|
||||
|
||||
from specklepy_qt_ui.qt_ui.widget_transforms import MappingSendDialog
|
||||
from specklepy_qt_ui.qt_ui.LogWidget import LogWidget
|
||||
from specklepy_qt_ui.qt_ui.utils.logger import logToUser
|
||||
from specklepy_qt_ui.qt_ui.DataStorage import DataStorage
|
||||
|
||||
FORM_CLASS, _ = uic.loadUiType(
|
||||
os.path.join(os.path.dirname(specklepy_qt_ui.qt_ui.__file__), os.path.join("ui", "dockwidget_main.ui") )
|
||||
)
|
||||
|
||||
class SpeckleQGISDialog(SpeckleQGISDialog_UI, FORM_CLASS):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
"""Constructor."""
|
||||
super(SpeckleQGISDialog_UI, self).__init__(parent)
|
||||
|
||||
self.setupUi(self)
|
||||
self.runAllSetup()
|
||||
|
||||
def createMappingDialog(self):
|
||||
|
||||
if self.mappingSendDialog is None:
|
||||
self.mappingSendDialog = MappingSendDialogQGIS(None)
|
||||
self.mappingSendDialog.dataStorage = self.dataStorage
|
||||
|
||||
self.mappingSendDialog.runSetup()
|
||||
|
||||
def completeStreamSection(self, plugin):
|
||||
try:
|
||||
self.streams_remove_button.clicked.connect( lambda: self.onStreamRemoveButtonClicked(plugin) )
|
||||
self.streamList.currentIndexChanged.connect( lambda: self.onActiveStreamChanged(plugin) )
|
||||
self.streamBranchDropdown.currentIndexChanged.connect( lambda: self.populateActiveCommitDropdown(plugin) )
|
||||
return
|
||||
except Exception as e:
|
||||
logToUser(e, level = 2, func = inspect.stack()[0][3], plugin=self)
|
||||
return
|
||||
|
||||
def onStreamRemoveButtonClicked(self, plugin):
|
||||
try:
|
||||
from speckle.utils.project_vars import set_project_streams
|
||||
if not self: return
|
||||
index = self.streamList.currentIndex()
|
||||
if len(plugin.current_streams) > 0: plugin.current_streams.pop(index)
|
||||
plugin.active_stream = None
|
||||
self.streamBranchDropdown.clear()
|
||||
self.commitDropdown.clear()
|
||||
#self.streamIdField.setText("")
|
||||
|
||||
set_project_streams(plugin)
|
||||
self.populateProjectStreams(plugin)
|
||||
except Exception as e:
|
||||
logToUser(e, level = 2, func = inspect.stack()[0][3], plugin=self)
|
||||
return
|
||||
|
||||
def populateProjectStreams(self, plugin):
|
||||
try:
|
||||
from speckle.utils.project_vars import set_project_streams
|
||||
if not self: return
|
||||
self.streamList.clear()
|
||||
for stream in plugin.current_streams:
|
||||
self.streamList.addItems(
|
||||
[f"Stream not accessible - {stream[0].stream_id}" if stream[1] is None or isinstance(stream[1], SpeckleException) else f"{stream[1].name}, {stream[1].id} | {stream[0].stream_url.split('/streams')[0].split('/projects')[0]}"]
|
||||
)
|
||||
if len(plugin.current_streams)==0: self.streamList.addItems([""])
|
||||
self.streamList.addItems(["Create New Stream"])
|
||||
set_project_streams(plugin)
|
||||
index = self.streamList.currentIndex()
|
||||
if index == -1: self.streams_remove_button.setEnabled(False)
|
||||
else: self.streams_remove_button.setEnabled(True)
|
||||
|
||||
if len(plugin.current_streams)>0: plugin.active_stream = plugin.current_streams[0]
|
||||
except Exception as e:
|
||||
logToUser(e, level = 2, func = inspect.stack()[0][3], plugin=self)
|
||||
return
|
||||
|
||||
def cancelOperations(self):
|
||||
#print("____cancelOperations______")
|
||||
for t in threading.enumerate():
|
||||
#print(t.name)
|
||||
if 'speckle_' in t.name:
|
||||
#print(f"thread to kill: {t}")
|
||||
t.kill()
|
||||
t.join()
|
||||
# not printed if same thread
|
||||
#print("Remaining threads: ")
|
||||
#print(threading.enumerate())
|
||||
|
||||
@@ -0,0 +1,404 @@
|
||||
import inspect
|
||||
import os
|
||||
from typing import Any, List, Tuple, Union
|
||||
from speckle.converter.layers import getAllLayers
|
||||
from speckle.converter.layers.utils import getElevationLayer, getLayerGeomType
|
||||
from specklepy_qt_ui.qt_ui.widget_transforms import MappingSendDialog
|
||||
from specklepy_qt_ui.qt_ui.utils.logger import displayUserMsg
|
||||
from specklepy_qt_ui.qt_ui.DataStorage import DataStorage
|
||||
|
||||
from speckle.utils.panel_logging import logToUser
|
||||
|
||||
from qgis.core import QgsVectorLayer, QgsRasterLayer, QgsIconUtils
|
||||
|
||||
from PyQt5 import QtWidgets, uic, QtCore
|
||||
from PyQt5.QtWidgets import QListWidgetItem
|
||||
|
||||
from specklepy.logging import metrics
|
||||
from osgeo import gdal
|
||||
import webbrowser
|
||||
import specklepy_qt_ui.qt_ui
|
||||
|
||||
FORM_CLASS, _ = uic.loadUiType(
|
||||
os.path.join(
|
||||
os.path.join(
|
||||
os.path.dirname(specklepy_qt_ui.qt_ui.__file__), "ui", "transforms.ui"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class MappingSendDialogQGIS(MappingSendDialog, FORM_CLASS):
|
||||
def __init__(self, parent=None):
|
||||
super(MappingSendDialog, self).__init__(parent, QtCore.Qt.WindowStaysOnTopHint)
|
||||
self.setupUi(self)
|
||||
self.runAllSetup()
|
||||
|
||||
def runSetup(self):
|
||||
self.attr_label.setEnabled(False)
|
||||
self.attrDropdown.setEnabled(False)
|
||||
self.dialog_button.setText("Apply")
|
||||
|
||||
self.populateTransforms()
|
||||
self.populateLayersByTransform()
|
||||
self.populateSavedTransforms(self.dataStorage)
|
||||
self.populateSavedElevationLayer(self.dataStorage)
|
||||
|
||||
# self.elevationLayerDropdown.currentIndexChanged.connect(self.saveElevationLayer)
|
||||
|
||||
def populateSavedTransforms(
|
||||
self, dataStorage
|
||||
): # , savedTransforms: Union[List, None] = None, getLayer: Union[str, None] = None, getTransform: Union[str, None] = None):
|
||||
if dataStorage is not None:
|
||||
self.dataStorage = dataStorage # making sure lists are synced
|
||||
self.transformationsList.clear()
|
||||
vals = self.dataStorage.savedTransforms
|
||||
all_l_names = [l.name() for l in self.dataStorage.all_layers]
|
||||
|
||||
for item in vals:
|
||||
layer_name = item.split(" -> ")[0].split(" ('")[0]
|
||||
transform_name = item.split(" -> ")[1]
|
||||
|
||||
layer = None
|
||||
for l in self.dataStorage.all_layers:
|
||||
if layer_name == l.name():
|
||||
layer = l
|
||||
if layer is None:
|
||||
logToUser(
|
||||
f"Layer '{layer_name}' not found in the project.\nTransformation is removed.",
|
||||
level=2,
|
||||
)
|
||||
self.dataStorage.savedTransforms.remove(item)
|
||||
else:
|
||||
if transform_name not in self.dataStorage.transformsCatalog:
|
||||
displayUserMsg(
|
||||
f"Saved transformation '{transform_name}' is not valid.\nTransformation is removed.",
|
||||
level=1,
|
||||
)
|
||||
self.dataStorage.savedTransforms.remove(item)
|
||||
elif all_l_names.count(layer.name()) > 1:
|
||||
displayUserMsg(
|
||||
f"Layer name '{layer.name()}' is used for more than 1 layer in the project.\nTransformation is removed.",
|
||||
level=1,
|
||||
)
|
||||
self.dataStorage.savedTransforms.remove(item)
|
||||
else:
|
||||
listItem = QListWidgetItem(item)
|
||||
icon = QgsIconUtils().iconForLayer(layer)
|
||||
listItem.setIcon(icon)
|
||||
|
||||
self.transformationsList.addItem(listItem)
|
||||
|
||||
def onAddTransform(self):
|
||||
from speckle.utils.project_vars import set_transformations
|
||||
|
||||
root = self.dataStorage.project.layerTreeRoot()
|
||||
self.dataStorage.all_layers = getAllLayers(root)
|
||||
|
||||
if (
|
||||
len(self.layerDropdown.currentText()) > 1
|
||||
and len(self.transformDropdown.currentText()) > 1
|
||||
):
|
||||
listItem = (
|
||||
str(self.layerDropdown.currentText())
|
||||
+ " -> "
|
||||
+ str(self.transformDropdown.currentText())
|
||||
)
|
||||
layer_name = listItem.split(" -> ")[0].split(" ('")[0]
|
||||
transform_name = listItem.split(" -> ")[1].lower()
|
||||
|
||||
exists = 0
|
||||
for record in self.dataStorage.savedTransforms:
|
||||
current_layer_name = record.split(" -> ")[0].split(" ('")[0]
|
||||
current_transf_name = record.split(" -> ")[1].lower()
|
||||
if layer_name == current_layer_name: # in layers
|
||||
exists += 1
|
||||
displayUserMsg(
|
||||
"Selected layer already has a transformation applied", level=1
|
||||
)
|
||||
break
|
||||
|
||||
if exists == 0:
|
||||
layer = None
|
||||
for l in self.dataStorage.all_layers:
|
||||
if layer_name == l.name():
|
||||
layer = l
|
||||
if layer is not None:
|
||||
if (
|
||||
"attribute" in transform_name
|
||||
and self.attrDropdown.currentText() != ""
|
||||
):
|
||||
listItem = (
|
||||
str(self.layerDropdown.currentText())
|
||||
+ " ('"
|
||||
+ str(self.attrDropdown.currentText())
|
||||
+ "') -> "
|
||||
+ str(self.transformDropdown.currentText())
|
||||
)
|
||||
|
||||
self.dataStorage.savedTransforms.append(listItem)
|
||||
self.populateSavedTransforms(self.dataStorage)
|
||||
|
||||
try:
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
self.dataStorage.active_account,
|
||||
{
|
||||
"name": "Transformation on Send Add",
|
||||
"Transformation": listItem.split(" -> ")[1],
|
||||
"connector_version": str(
|
||||
self.dataStorage.plugin_version
|
||||
),
|
||||
},
|
||||
)
|
||||
except Exception as e:
|
||||
logToUser(e, level=2, func=inspect.stack()[0][3])
|
||||
|
||||
set_transformations(self.dataStorage)
|
||||
|
||||
def onRemoveTransform(self):
|
||||
from speckle.utils.project_vars import set_transformations
|
||||
|
||||
if self.transformationsList.currentItem() is not None:
|
||||
listItem = self.transformationsList.currentItem().text()
|
||||
# print(listItem)
|
||||
|
||||
if listItem in self.dataStorage.savedTransforms:
|
||||
self.dataStorage.savedTransforms.remove(listItem)
|
||||
|
||||
try:
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
self.dataStorage.active_account,
|
||||
{
|
||||
"name": "Transformation on Send Remove",
|
||||
"Transformation": listItem.split(" -> ")[1],
|
||||
"connector_version": str(self.dataStorage.plugin_version),
|
||||
},
|
||||
)
|
||||
except Exception as e:
|
||||
logToUser(e, level=2, func=inspect.stack()[0][3])
|
||||
|
||||
self.populateSavedTransforms(self.dataStorage)
|
||||
set_transformations(self.dataStorage)
|
||||
|
||||
def onOkClicked(self):
|
||||
try:
|
||||
self.saveElevationLayer()
|
||||
self.close()
|
||||
except Exception as e:
|
||||
logToUser(e, level=2, func=inspect.stack()[0][3])
|
||||
return
|
||||
|
||||
def populateLayers(self):
|
||||
try:
|
||||
self.layerDropdown.clear()
|
||||
root = self.dataStorage.project.layerTreeRoot()
|
||||
self.dataStorage.all_layers = getAllLayers(root)
|
||||
for i, layer in enumerate(self.dataStorage.all_layers):
|
||||
listItem = layer.name()
|
||||
self.layerDropdown.addItem(listItem)
|
||||
icon = QgsIconUtils().iconForLayer(layer)
|
||||
self.layerDropdown.setItemIcon(i, icon)
|
||||
|
||||
except Exception as e:
|
||||
logToUser(e, level=2, func=inspect.stack()[0][3])
|
||||
return
|
||||
|
||||
def populateLayersByTransform(self):
|
||||
try:
|
||||
self.layerDropdown.clear()
|
||||
root = self.dataStorage.project.layerTreeRoot()
|
||||
self.dataStorage.all_layers = getAllLayers(root)
|
||||
|
||||
transform = str(self.transformDropdown.currentText())
|
||||
layers_dropdown = []
|
||||
|
||||
for i, layer in enumerate(self.dataStorage.all_layers):
|
||||
listItem = None
|
||||
if "extrude" in transform.lower():
|
||||
if isinstance(layer, QgsVectorLayer):
|
||||
geom_type = getLayerGeomType(layer)
|
||||
if "polygon" in geom_type.lower():
|
||||
listItem = layer.name()
|
||||
|
||||
elif "elevation" in transform.lower():
|
||||
if isinstance(layer, QgsRasterLayer):
|
||||
# avoiding tiling layers
|
||||
ds = gdal.Open(layer.source(), gdal.GA_ReadOnly)
|
||||
if ds is None:
|
||||
continue
|
||||
|
||||
# for satellites
|
||||
if "texture" in transform.lower():
|
||||
listItem = layer.name()
|
||||
# for elevation to mesh
|
||||
elif "mesh" in transform.lower():
|
||||
try:
|
||||
if layer.bandCount() == 1:
|
||||
listItem = layer.name()
|
||||
except:
|
||||
pass
|
||||
|
||||
if listItem is not None:
|
||||
layers_dropdown.append(listItem)
|
||||
self.layerDropdown.addItem(listItem)
|
||||
icon = QgsIconUtils().iconForLayer(layer)
|
||||
self.layerDropdown.setItemIcon(len(layers_dropdown) - 1, icon)
|
||||
|
||||
except Exception as e:
|
||||
logToUser(e, level=2, func=inspect.stack()[0][3])
|
||||
return
|
||||
|
||||
def populateAttributesByLayer(self):
|
||||
try:
|
||||
self.attrDropdown.clear()
|
||||
root = self.dataStorage.project.layerTreeRoot()
|
||||
self.dataStorage.all_layers = getAllLayers(root)
|
||||
|
||||
layer_name = str(self.layerDropdown.currentText())
|
||||
transform_name = self.transformDropdown.currentText()
|
||||
layerForAttributes = None
|
||||
for i, layer in enumerate(self.dataStorage.all_layers):
|
||||
if layer_name == layer.name():
|
||||
if isinstance(layer, QgsVectorLayer):
|
||||
geom_type = getLayerGeomType(layer)
|
||||
if "polygon" in geom_type.lower():
|
||||
layerForAttributes = layer
|
||||
break
|
||||
|
||||
if layerForAttributes is not None and "attribute" in transform_name:
|
||||
self.attr_label.setEnabled(True)
|
||||
self.attrDropdown.setEnabled(True)
|
||||
|
||||
if "ignore" not in transform_name:
|
||||
self.attrDropdown.addItem("Random height")
|
||||
|
||||
for field in layerForAttributes.fields():
|
||||
field_type = field.type()
|
||||
if field_type in [2, 6, 10]:
|
||||
self.attrDropdown.addItem(str(field.name()))
|
||||
else:
|
||||
self.attr_label.setEnabled(False)
|
||||
self.attrDropdown.setEnabled(False)
|
||||
|
||||
except Exception as e:
|
||||
logToUser(e, level=2, func=inspect.stack()[0][3])
|
||||
return
|
||||
|
||||
def populateTransforms(self):
|
||||
try:
|
||||
self.transformDropdown.clear()
|
||||
for item in self.dataStorage.transformsCatalog:
|
||||
self.transformDropdown.addItem(item)
|
||||
except Exception as e:
|
||||
logToUser(e, level=2, func=inspect.stack()[0][3])
|
||||
return
|
||||
|
||||
def populateSavedElevationLayer(
|
||||
self, dataStorage
|
||||
): # , savedTransforms: Union[List, None] = None, getLayer: Union[str, None] = None, getTransform: Union[str, None] = None):
|
||||
try:
|
||||
if dataStorage is not None:
|
||||
self.dataStorage = dataStorage # making sure lists are synced
|
||||
elevationLayer = getElevationLayer(self.dataStorage)
|
||||
|
||||
self.elevationLayerDropdown.clear()
|
||||
root = self.dataStorage.project.layerTreeRoot()
|
||||
self.dataStorage.all_layers = getAllLayers(root)
|
||||
|
||||
self.elevationLayerDropdown.addItem("")
|
||||
|
||||
setAsindex = 0
|
||||
countRaster = 1
|
||||
for i, layer in enumerate(self.dataStorage.all_layers):
|
||||
if isinstance(layer, QgsRasterLayer):
|
||||
# avoiding tiling layers
|
||||
ds = gdal.Open(layer.source(), gdal.GA_ReadOnly)
|
||||
if ds is None:
|
||||
continue
|
||||
elif layer.bandCount() != 1:
|
||||
continue
|
||||
|
||||
listItem = layer.name()
|
||||
self.elevationLayerDropdown.addItem(listItem)
|
||||
icon = QgsIconUtils().iconForLayer(layer)
|
||||
self.elevationLayerDropdown.setItemIcon(countRaster, icon)
|
||||
|
||||
if elevationLayer is not None:
|
||||
if listItem == elevationLayer.name():
|
||||
setAsindex = countRaster
|
||||
countRaster += 1
|
||||
self.elevationLayerDropdown.setCurrentIndex(setAsindex)
|
||||
|
||||
except Exception as e:
|
||||
logToUser(e, level=2, func=inspect.stack()[0][3])
|
||||
return
|
||||
|
||||
def saveElevationLayer(self):
|
||||
# print("saveElevationLayer")
|
||||
from speckle.utils.project_vars import set_elevationLayer
|
||||
|
||||
root = self.dataStorage.project.layerTreeRoot()
|
||||
layer = None
|
||||
|
||||
if self.dataStorage is None:
|
||||
return
|
||||
|
||||
layerName = str(self.elevationLayerDropdown.currentText())
|
||||
try:
|
||||
if self.dataStorage.elevationLayer.name() == layerName:
|
||||
return
|
||||
except:
|
||||
pass
|
||||
|
||||
if len(layerName) < 1:
|
||||
layer = None
|
||||
else:
|
||||
self.dataStorage.all_layers = getAllLayers(root)
|
||||
all_l_names = [l.name() for l in self.dataStorage.all_layers]
|
||||
# print(all_l_names)
|
||||
|
||||
for l in self.dataStorage.all_layers:
|
||||
if layerName == l.name():
|
||||
layer = l
|
||||
try:
|
||||
# print(layerName)
|
||||
if all_l_names.count(layer.name()) > 1:
|
||||
displayUserMsg(
|
||||
f"Layer name '{layer.name()}' is used for more than 1 layer in the project",
|
||||
level=1,
|
||||
)
|
||||
layer = None
|
||||
break
|
||||
else:
|
||||
self.dataStorage.elevationLayer = layer
|
||||
set_elevationLayer(self.dataStorage)
|
||||
logToUser(
|
||||
f"Elevation layer '{layerName}' successfully set",
|
||||
level=0,
|
||||
)
|
||||
break
|
||||
except:
|
||||
displayUserMsg(
|
||||
f"Layer '{layer.name()}' is not found in the project",
|
||||
level=1,
|
||||
)
|
||||
layer = None
|
||||
break
|
||||
|
||||
try:
|
||||
metrics.track(
|
||||
"Connector Action",
|
||||
self.dataStorage.active_account,
|
||||
{
|
||||
"name": "Add transformation on Send",
|
||||
"Transformation": "Set Layer as Elevation",
|
||||
"connector_version": str(self.dataStorage.plugin_version),
|
||||
},
|
||||
)
|
||||
except Exception as e:
|
||||
logToUser(e, level=2, func=inspect.stack()[0][3])
|
||||
|
||||
def onMoreInfo(self):
|
||||
webbrowser.open("https://speckle.guide/user/qgis.html#transformations")
|
||||
Reference in New Issue
Block a user