Compare commits

...

63 Commits

Author SHA1 Message Date
KatKatKateryna fceeb6a9d7 remove unnecessary files 2023-02-13 21:40:35 +08:00
KatKatKateryna 8a27a3a8e2 Manual install instructions 2023-02-13 21:35:32 +08:00
KatKatKateryna 2540d05181 typo 2023-02-13 20:36:46 +08:00
KatKatKateryna 4cb57d9631 list directories 2023-02-13 20:33:32 +08:00
KatKatKateryna 007e6263a6 typo 2023-02-13 20:29:53 +08:00
KatKatKateryna 4a93b40e8e attach installer folder to workspace 2023-02-13 20:28:56 +08:00
KatKatKateryna 95c1495977 split tag version 2023-02-13 20:22:18 +08:00
KatKatKateryna fc07cbf60e add a context with github token 2023-02-13 20:15:09 +08:00
KatKatKateryna 07029675e4 remove token 2023-02-13 20:00:15 +08:00
KatKatKateryna f24ef49450 quote version 2023-02-13 19:52:44 +08:00
KatKatKateryna 52a531e040 debug 2023-02-13 19:46:40 +08:00
KatKatKateryna d3be4f0377 version syntax 2023-02-13 19:43:57 +08:00
KatKatKateryna 865964249c latest 2023-02-13 19:35:31 +08:00
KatKatKateryna 1d11e702dc go install 2023-02-13 19:33:47 +08:00
KatKatKateryna b454ac543c try another docker image 2023-02-13 19:31:47 +08:00
KatKatKateryna fcbdc9a200 remove whl step completely 2023-02-13 19:14:53 +08:00
KatKatKateryna 7cbdab0471 remove --64 2023-02-13 19:04:49 +08:00
KatKatKateryna 464bcf0f61 test another ghr installer 2023-02-13 19:03:11 +08:00
KatKatKateryna 97c8cebdb4 sudo 2023-02-13 18:58:37 +08:00
KatKatKateryna cd3a05103b add $ 2023-02-13 18:56:54 +08:00
KatKatKateryna cc11402470 remove powershell 2023-02-13 18:53:05 +08:00
KatKatKateryna ae0f15023c Update config.yml 2023-02-13 07:53:44 +08:00
KatKatKateryna 0eed167715 Merge pull request #52 from specklesystems/kate/2.12
tags fix, run on cmd
2023-02-13 07:48:44 +08:00
KatKatKateryna f60cd064f3 tags fix, run on cmd 2023-02-13 07:47:40 +08:00
KatKatKateryna b86799856e Merge pull request #51 from specklesystems/kate/2.12
Kate/2.12
2023-02-13 07:38:22 +08:00
KatKatKateryna 14e805cf99 typo 2023-02-13 07:37:19 +08:00
KatKatKateryna 6d35d13f99 ghr for adding files to release; separate job 2023-02-13 07:35:46 +08:00
KatKatKateryna 5e0ff316f0 add whl via powershell 2023-02-13 07:07:19 +08:00
KatKatKateryna b22ac2ef17 don't add whl to installer 2023-02-13 06:59:11 +08:00
KatKatKateryna da1ebb04e4 Merge branch 'main' into kate/2.12 2023-02-09 02:28:17 +08:00
KatKatKateryna 29c4fde0c5 handling access error to the account 2023-02-08 20:24:27 +08:00
KatKatKateryna e132b16878 refactoring unittests 2023-02-08 20:16:15 +08:00
KatKatKateryna 2e1dc329b3 add 2.11.3 whl 2023-02-02 16:52:02 +08:00
KatKatKateryna ee3cc81391 Merge branch 'main' into kate/2.12 2023-02-02 16:31:28 +08:00
KatKatKateryna 78063bc976 ci: add whl file to release 2023-02-02 16:24:38 +08:00
KatKatKateryna 8dcdfbbfc1 version name for metrics 2023-02-02 00:49:08 +08:00
KatKatKateryna 221a050df4 typings fix for python 3.7 2023-02-01 22:58:43 +08:00
KatKatKateryna 67480f2f70 CI: return version 2023-01-31 23:24:53 +08:00
KatKatKateryna 0a24379984 typo 2023-01-31 23:15:56 +08:00
KatKatKateryna 6437be9d25 CI signing 2023-01-31 23:15:05 +08:00
KatKatKateryna 644b64bbb3 ci contexts 2023-01-31 22:42:19 +08:00
KatKatKateryna 037469966b Merge pull request #50 from specklesystems/2.11-fix
typing fixed for older python versions
2023-01-31 21:10:53 +08:00
KatKatKateryna e8d4b8035b typing fixed for older python versions 2023-01-31 21:09:53 +08:00
KatKatKateryna 8721ae246a search limit for branches and commits increased from 10 to 100 2023-01-28 07:14:23 +08:00
KatKatKateryna 261d324ed4 folder naming (to save BIM mesh and raster bands) 2023-01-28 06:29:19 +08:00
KatKatKateryna 07fe49a1f8 Merge pull request #48 from specklesystems/kate/2.11-fixes
missing value of 'Speckle_ID' for received GIS features
2023-01-11 20:34:12 +08:00
KatKatKateryna 6f90081af7 linting 2023-01-11 20:29:40 +08:00
KatKatKateryna 67911fdb5d typo 2023-01-11 19:32:50 +08:00
KatKatKateryna a9e48db570 manual install 2.11.0; patching error fixed 2023-01-11 19:21:40 +08:00
KatKatKateryna d284c5415a missing value of 'Speckle_ID' for received GIS features 2023-01-11 19:11:20 +08:00
Alan Rynne a6ec7b4a0b ci: Added issue automation actions 2023-01-09 20:39:59 +01:00
KatKatKateryna e70debc606 Merge pull request #47 from specklesystems/ci/use-contexts
CI: Use contexts and ssh
2023-01-09 15:21:55 +08:00
Alan Rynne a651fbd732 fix(ci): Use correct fingerprint 2023-01-05 18:14:31 +01:00
Alan Rynne 7eba1ba98b ci: Changes in CI config for get-ci-tools and deploy jobs 2023-01-05 18:10:01 +01:00
KatKatKateryna 4828f5b55e extra fix for changed attribute types 2023-01-05 22:45:14 +08:00
KatKatKateryna 0a5e49fb07 SpeckleID prop for CAD geometry on receive; fixed weird bug where object properties changed type before assigning to attribute table 2023-01-05 20:38:23 +08:00
KatKatKateryna b651bfd401 Merge pull request #46 from specklesystems/kate/2.12
2.11.0-fixed
2023-01-05 17:18:39 +08:00
KatKatKateryna 52a28eae3f Merging Main with old commits 2023-01-05 17:15:29 +08:00
KatKatKateryna 50c37315f8 Merge branch 'main' into kate/2.12 2023-01-05 16:14:10 +08:00
KatKatKateryna d9706b4f5f Merge branch 'main' of https://github.com/specklesystems/speckle-arcgis 2023-01-05 16:02:03 +08:00
KatKatKateryna aad3be3962 setting app version, basic unit tests, some error-preventing fixes 2023-01-05 15:53:20 +08:00
KatKatKateryna 013e9e27d6 adjust imports for unittest 2023-01-04 18:11:51 +08:00
KatKatKateryna faadba8e73 manual install taking the latest available 2.x whl 2022-11-30 02:36:46 +08:00
33 changed files with 472 additions and 279 deletions
+57 -10
View File
@@ -23,6 +23,12 @@ jobs:
- checkout
- attach_workspace:
at: ./
- run:
name: Create Innosetup signing cert
shell: powershell.exe
command: |
echo $env:PFX_B64 > "speckle-sharp-ci-tools\SignTool\AEC Systems Ltd.txt"
certutil -decode "speckle-sharp-ci-tools\SignTool\AEC Systems Ltd.txt" "speckle-sharp-ci-tools\SignTool\AEC Systems Ltd.pfx"
- run:
name: Patch
shell: powershell.exe
@@ -36,7 +42,12 @@ jobs:
python patch_version.py $semver
python setup.py sdist bdist_wheel
Copy-Item -Path "dist\speckle_toolbox-$($ver)-py3-none-any.whl" -Destination "speckle_arcgis_installer"
speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\arcgis.iss
- run:
name: Build Installer
shell: cmd.exe
command:
| # If no tag, use 0.0.0.1 and don't make any YML (for testing only!)
speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\arcgis.iss /Sbyparam=$p
- when:
condition: << parameters.installer >>
steps:
@@ -44,14 +55,38 @@ jobs:
root: ./
paths:
- speckle-sharp-ci-tools/Installers
- speckle_arcgis_installer
publish-github-release:
docker:
- image: cimg/go:1.20.0
steps:
- attach_workspace:
at: ./
- run:
name: "Publish Release on GitHub"
command: |
set -x
go install github.com/tcnksm/ghr@v0.16.0
VERSION="${CIRCLE_TAG:-0.0.0}"
VERSION_SHORT=$(echo "${VERSION}" | cut -d- -f1)
ghr -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete "${VERSION}" "./speckle_arcgis_installer/speckle_toolbox-${VERSION_SHORT}-py3-none-any.whl"
get-ci-tools: # Clones our ci tools and persists them to the workspace
docker:
- image: cimg/base:2021.01
steps:
- run: # Could not get ssh to work, so using a personal token
- add_ssh_keys:
fingerprints:
- "77:64:03:93:c5:f3:1d:a6:fd:bd:fb:d1:05:56:ca:e9"
- run:
name: I know Github as a host
command: |
mkdir ~/.ssh
touch ~/.ssh/known_hosts
ssh-keyscan github.com >> ~/.ssh/known_hosts
- run:
name: Clone
command: git clone https://$GITHUB_TOKEN@github.com/specklesystems/speckle-sharp-ci-tools.git speckle-sharp-ci-tools
command: git clone git@github.com:specklesystems/speckle-sharp-ci-tools.git speckle-sharp-ci-tools
- persist_to_workspace:
root: ./
paths:
@@ -84,6 +119,7 @@ workflows: #happens with every PR to main
build: # build the installers, but don't persist to workspace for deployment
jobs:
- get-ci-tools:
context: github-dev-bot
filters:
branches:
only:
@@ -97,10 +133,12 @@ workflows: #happens with every PR to main
only:
- main
- /ci\/.*/
context: innosetup
deploy: # build installers and deploy
jobs:
- get-ci-tools:
context: github-dev-bot
filters:
tags:
only: /.*/
@@ -118,16 +156,25 @@ workflows: #happens with every PR to main
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
branches:
ignore: /.*/
- deploy-manager2:
slug: arcgis
os: Win
extension: exe
context: innosetup
- publish-github-release:
requires:
- get-ci-tools
- build-deploy-connector-win
filters:
tags:
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
branches:
ignore: /.*/ # For testing only! /ci\/.*/
ignore: /.*/
context: arcgis-github-release
- deploy-manager2:
slug: arcgis
os: Win
extension: exe
requires:
- build-deploy-connector-win
filters:
tags:
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
branches:
ignore: /.*/ # For testing only! /ci\/.*/
context: do-spaces-speckle-releases
+12
View File
@@ -0,0 +1,12 @@
name: Update issue Status
on:
issues:
types: [closed]
jobs:
update_issue:
uses: specklesystems/github-actions/.github/workflows/project-add-issue.yml@main
secrets: inherit
with:
issue-id: ${{ github.event.issue.node_id }}
+12
View File
@@ -0,0 +1,12 @@
name: Move new issues into Project
on:
issues:
types: [opened]
jobs:
track_issue:
uses: specklesystems/github-actions/.github/workflows/project-add-issue.yml@main
secrets: inherit
with:
issue-id: ${{ github.event.issue.node_id }}
+3 -1
View File
@@ -118,4 +118,6 @@ scratch.py
settings.json
**/.DS_Store
zip_build
.qt_for_python
.qt_for_python
*.pyt.xml
+3 -3
View File
@@ -6,7 +6,7 @@ def patch_installer(tag):
iss_file = "speckle-sharp-ci-tools/arcgis.iss"
setup_whl_file = "setup.py"
conda_file = "speckle_arcgis_installer/conda_clone_activate.py"
toolbox_install_file = "speckle_arcgis_installer/toolbox_install.py"
#toolbox_install_file = "speckle_arcgis_installer/toolbox_install.py"
toolbox_manual_install_file = "speckle_arcgis_installer/toolbox_install_manual.py"
#py_tag = get_specklepy_version()
@@ -37,7 +37,7 @@ def patch_installer(tag):
with open(fileName, "r") as file:
lines = file.readlines()
for i, line in enumerate(lines):
if "-py3-none-any.whl" in line:
if "-py3-none-any.whl" in line and '.sort' not in line:
p1 = line.split("-py3-none-any.whl")[0].split("-")[0]
p2 = f'{tag.split("-")[0]}'
p3 = line.split("-py3-none-any.whl")[1]
@@ -48,7 +48,7 @@ def patch_installer(tag):
file.close()
whlFileRename(conda_file)
whlFileRename(toolbox_install_file)
#whlFileRename(toolbox_install_file)
whlFileRename(toolbox_manual_install_file)
+3
View File
@@ -0,0 +1,3 @@
specklepy==2.9.1
panda3d==1.10.11
+2
View File
@@ -0,0 +1,2 @@
print("Hello")
@@ -4,8 +4,12 @@ import arcpy
import json
import os
from speckle.converter.layers.CRS import CRS
from speckle.converter.layers.Layer import Layer, VectorLayer, RasterLayer
try:
from speckle.converter.layers.CRS import CRS
from 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
from arcpy._mp import ArcGISProject, Map, Layer as arcLayer
from arcpy.management import (CreateFeatureclass, MakeFeatureLayer,
+3 -3
View File
@@ -1,10 +1,10 @@
### Manual installation
1. Download present "speckle_arcgis_installer" folder
2. Clone the default ArcGIS Pro conda environment and restart ArcGIS Pro
1. From the [latest release](https://github.com/specklesystems/speckle-arcgis/releases) download the whl file and the source code zip, unzip and locate the subfolder "speckle_arcgis_installer" on your machine and place whl file in it.
2. Clone the default ArcGIS Pro conda environment (or set the one you use, except the default one) and restart ArcGIS Pro
- for 2.9.0: Project-> Python-> Manage Environments-> Clone Default
- for 3.0.0: Project-> Package Manager-> Active Environment (Environment Manager)-> Clone arcgispro-py3
3. Change the path to your new environemnt Python.exe if necessary (variable "pythonPath" in "toolbox_install_manual.py")
3. Adjust the path to your new environment python executable (variable "pythonPath" in "speckle_arcgis_installer/toolbox_install_manual.py")
4. Enter the location of 'toolbox_install_manual.py' in the following command and run this command in ArcGIS Python console (View -> Python Window)
```python
+2 -1
View File
@@ -1 +1,2 @@
from speckle.speckle_arcgis import *
try: from speckle.speckle_arcgis import *
except: from speckle_toolbox.esri.toolboxes.speckle.speckle_arcgis import *
@@ -1,3 +0,0 @@
@echo off
"%PROGRAMFILES%\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\python.exe" "conda_clone_activate.py"
"%LOCALAPPDATA%\ESRI\conda\envs\arcgispro-py3-speckle\python.exe" "toolbox_install.py"
@@ -1,61 +0,0 @@
from subprocess_call import subprocess_call
import os
pythonPath = os.getenv('APPDATA').replace("\\Roaming","") + r"\Local\ESRI\conda\envs\arcgispro-py3-speckle\python.exe"
def installToolbox(newExec: str):
print("Installing Speckle Toolbox")
whl_file = os.path.join(os.path.dirname(__file__), "speckle_toolbox-2.9.4-py3-none-any.whl" )
print(whl_file)
subprocess_call([newExec, '-m','pip','install','--upgrade', '--force-reinstall', whl_file])
# to uninstall: cmd.exe "C:\\Users\\username\\AppData\\Local\\ESRI\\conda\\envs\\arcgispro-2.9.4-py3-none-any.whl
return
def installDependencies(pythonExec: str, pkgName: str, pkgVersion: str):
# install pip
print(pythonExec)
try:
import pip
except:
getPipFilePath = os.path.join(os.path.dirname(__file__), "get_pip.py") #TODO: give actual folder path
exec(open(getPipFilePath).read())
# just in case the included version is old
subprocess_call([pythonExec, "-m", "pip", "install", "--upgrade", "pip"])
# install package
try:
import importlib
importlib.import_module(pkgName)
except Exception as e:
print(f"{pkgName} not installed")
subprocess_call( [pythonExec, "-m", "pip", "install", f"{pkgName}=={pkgVersion}"])
# Check if package needs updating
try:
print(f"Attempting to update {pkgName} to {pkgVersion}")
result = subprocess_call(
[
pythonExec,
"-m",
"pip",
"install",
"--upgrade",
f"{pkgName}=={pkgVersion}",
]
)
if result == True:
print(f"{pkgName} upgraded")
return True
else:
return False
except Exception as e:
print(e)
print(e.with_traceback)
return True
installToolbox(pythonPath)
installDependencies(pythonPath, "specklepy", "2.9.0" )
installDependencies(pythonPath, "panda3d", "1.10.11" )
@@ -4,17 +4,23 @@
# for 3.0.0: Project-> Package Manager-> Active Environment (Environment Manager)-> Clone arcgispro-py3
# 2. Change the path to your new environemnt Python.exe if necessary (in variable "pythonPath" below, line 13)
# 3. Enter the location of 'toolbox_install_manual.py' in the following command and run this command in ArcGIS Python console (View -> Python Window)
# import sysconfig; import subprocess; x = sysconfig.get_paths()['data'] + r"\python.exe"; subprocess.run((x, 'C:\\Users\\myusername\\Documents\\manual_toolbox_install.py'), capture_output=True, text=True, shell=True, timeout=1000 )
# import sysconfig; import subprocess; x = sysconfig.get_paths()['data'] + r"\python.exe"; subprocess.run((x, 'C:\\Users\\myusername\\Documents\\toolbox_install_manual.py'), capture_output=True, text=True, shell=True, timeout=1000 )
# 4. Restart ArcGIS Pro
from subprocess_call import subprocess_call
import os
from os import listdir
from os.path import isfile, join
pythonPath = os.getenv('APPDATA').replace("\\Roaming","") + r"\Local\ESRI\conda\envs\arcgispro-py3-speckle\python.exe"
def installToolbox(newExec: str):
print("Installing Speckle Toolbox")
whl_file = os.path.join(os.path.dirname(__file__), "speckle_toolbox-2.9.4-py3-none-any.whl" )
mypath = os.path.dirname(__file__)
onlyfiles = [f for f in listdir(mypath) if (isfile(join(mypath, f)) and "py3-none-any.whl" in str(f))]
onlyfiles.sort(key = lambda x: int(x.replace("speckle_toolbox-","").replace("-py3-none-any.whl","").split(".")[1]) )
whl_file = onlyfiles[len(onlyfiles)-1]
#whl_file = os.path.join(os.path.dirname(__file__), "speckle_toolbox-2.11.3-py3-none-any.whl" )
subprocess_call([newExec, '-m','pip','install','--upgrade', '--force-reinstall', whl_file])
return
+2 -1
View File
@@ -1 +1,2 @@
from speckle.speckle_arcgis import *
try: from speckle.speckle_arcgis import *
except: from speckle_toolbox.esri.toolboxes.speckle.speckle_arcgis import *
@@ -5,11 +5,19 @@ from specklepy.objects.geometry import Line, Mesh, Point, Polyline, Curve, Arc,
import arcpy
from typing import Any, List, Union, Sequence
from speckle.converter.geometry.polygon import polygonToNative, polygonToSpeckle, multiPolygonToSpeckle
from speckle.converter.geometry.polyline import arcToNative, ellipseToNative, circleToNative, curveToNative, lineToNative, polycurveToNative, polylineFromVerticesToSpeckle, polylineToNative, polylineToSpeckle
from speckle.converter.geometry.point import pointToCoord, pointToNative, pointToSpeckle, multiPointToSpeckle
from speckle.converter.geometry.polyline import speckleArcCircleToPoints, specklePolycurveToPoints, multiPolylineToSpeckle
from speckle.converter.geometry.mesh import meshToNative
try:
from speckle.converter.geometry.polygon import polygonToNative, polygonToSpeckle, multiPolygonToSpeckle
from speckle.converter.geometry.polyline import arcToNative, ellipseToNative, circleToNative, curveToNative, lineToNative, polycurveToNative, polylineFromVerticesToSpeckle, polylineToNative, polylineToSpeckle
from speckle.converter.geometry.point import pointToCoord, pointToNative, pointToSpeckle, multiPointToSpeckle
from speckle.converter.geometry.polyline import speckleArcCircleToPoints, specklePolycurveToPoints, multiPolylineToSpeckle
from speckle.converter.geometry.mesh import meshToNative
except:
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry.polygon import polygonToNative, polygonToSpeckle, multiPolygonToSpeckle
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry.polyline import arcToNative, ellipseToNative, circleToNative, curveToNative, lineToNative, polycurveToNative, polylineFromVerticesToSpeckle, polylineToNative, polylineToSpeckle
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry.point import pointToCoord, pointToNative, pointToSpeckle, multiPointToSpeckle
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry.polyline import speckleArcCircleToPoints, specklePolycurveToPoints, multiPolylineToSpeckle
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry.mesh import meshToNative
import numpy as np
def convertToSpeckle(feature, index: str, layer, geomType, featureType) -> Union[Base, Sequence[Base], None]:
@@ -5,7 +5,8 @@ from specklepy.objects.geometry import Mesh
import shapefile
from shapefile import TRIANGLE_STRIP, TRIANGLE_FAN
from speckle.converter.layers.utils import get_scale_factor
try: from speckle.converter.layers.utils import get_scale_factor
except: from speckle_toolbox.esri.toolboxes.speckle.converter.layers.utils import get_scale_factor
def meshToNative(meshes: List[Mesh], path: str):
"""Converts a Speckle Mesh to MultiPatch"""
@@ -3,7 +3,8 @@ from typing import List
from specklepy.objects.geometry import Point
import arcpy
from speckle.converter.layers.utils import get_scale_factor
try: from speckle.converter.layers.utils import get_scale_factor
except: from speckle_toolbox.esri.toolboxes.speckle.converter.layers.utils import get_scale_factor
def multiPointToSpeckle(geom, feature, layer, multiType: bool):
@@ -5,19 +5,31 @@ from arcpy.arcobjects.arcobjects import SpatialReference
from specklepy.objects import Base
from specklepy.objects.geometry import Point, Arc, Circle, Polycurve, Polyline, Line
from speckle.converter.geometry.mesh import rasterToMesh
from speckle.converter.geometry.point import pointToCoord, pointToNative
from speckle.converter.geometry.polyline import (polylineFromVerticesToSpeckle,
circleToSpeckle,
speckleArcCircleToPoints,
curveToSpeckle,
specklePolycurveToPoints
)
try:
from speckle.converter.geometry.mesh import rasterToMesh
from speckle.converter.geometry.point import pointToCoord, pointToNative
from speckle.converter.layers.symbologyTemplates import featureColorfromNativeRenderer
from speckle.converter.geometry.polyline import (polylineFromVerticesToSpeckle,
circleToSpeckle,
speckleArcCircleToPoints,
curveToSpeckle,
specklePolycurveToPoints
)
except:
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry.mesh import rasterToMesh
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry.point import pointToCoord, pointToNative
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.symbologyTemplates import featureColorfromNativeRenderer
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry.polyline import (polylineFromVerticesToSpeckle,
circleToSpeckle,
speckleArcCircleToPoints,
curveToSpeckle,
specklePolycurveToPoints
)
import math
from panda3d.core import Triangulator
from speckle.converter.layers.symbologyTemplates import featureColorfromNativeRenderer
def multiPolygonToSpeckle(geom, feature, index: str, layer, multiType: bool):
@@ -8,8 +8,13 @@ from specklepy.objects.geometry import Box, Vector, Point, Line, Polyline, Curve
import arcpy
import numpy as np
from speckle.converter.geometry.point import pointToCoord, pointToSpeckle, addZtoPoint
from speckle.converter.layers.utils import get_scale_factor
try:
from speckle.converter.geometry.point import pointToCoord, pointToSpeckle, addZtoPoint
from speckle.converter.layers.utils import get_scale_factor
except:
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry.point import pointToCoord, pointToSpeckle, addZtoPoint
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.utils import get_scale_factor
def circleToSpeckle(center, point):
print("___Circle to Speckle____")
@@ -336,7 +341,7 @@ def lineFrom2pt(pt1: List[float], pt2: List[float]):
def polylineToNative(poly: Polyline, sr: arcpy.SpatialReference) -> arcpy.Polyline:
"""Converts a Speckle Polyline to QgsLineString"""
print("__ convert poly to native __")
print("__ convert polyline to native __")
if isinstance(poly, Polycurve):
poly = specklePolycurveToPoints(poly)
@@ -1,7 +1,10 @@
from typing import List, Optional
from specklepy.objects.base import Base
from speckle.converter.layers.CRS import CRS
try:
from speckle.converter.layers.CRS import CRS
except:
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.CRS import CRS
@@ -4,13 +4,29 @@ Contains all Layer related classes and methods.
import os
from typing import Any, List, Tuple, Union
from regex import D
from speckle.converter.layers.CRS import CRS
from speckle.converter.layers.Layer import Layer, VectorLayer, RasterLayer
from speckle.converter.layers.feature import featureToNative, featureToSpeckle, cadFeatureToNative, bimFeatureToNative, rasterFeatureToSpeckle
#from regex import D
try:
from speckle.converter.layers.CRS import CRS
from speckle.converter.layers.Layer import Layer, VectorLayer, RasterLayer
from speckle.converter.layers.symbologyTemplates import vectorRendererToNative, rasterRendererToNative, rendererToSpeckle
from speckle.converter.layers.feature import featureToNative, featureToSpeckle, cadFeatureToNative, bimFeatureToNative, rasterFeatureToSpeckle
from speckle.converter.geometry.mesh import rasterToMesh, meshToNative
from speckle.converter.layers.utils import findTransformation
from speckle.converter.layers.utils import getLayerAttributes, newLayerGroupAndName, validate_path
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
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.symbologyTemplates import vectorRendererToNative, rasterRendererToNative, rendererToSpeckle
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.feature import featureToNative, featureToSpeckle, cadFeatureToNative, bimFeatureToNative, rasterFeatureToSpeckle
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry.mesh import rasterToMesh, meshToNative
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.utils import findTransformation
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.utils import getLayerAttributes, newLayerGroupAndName, validate_path
from specklepy.objects import Base
from specklepy.objects.geometry import Mesh
from speckle.converter.geometry.mesh import rasterToMesh, meshToNative
import arcgisscripting
import pandas as pd
@@ -19,13 +35,8 @@ from arcpy._mp import ArcGISProject, Map, Layer as arcLayer
from arcpy.management import (CreateFeatureclass, MakeFeatureLayer,
AddFields, AlterField, DefineProjection )
from speckle.converter.layers.utils import getLayerAttributes, newLayerGroupAndName, validate_path
import numpy as np
from speckle.converter.layers.utils import findTransformation
from speckle.converter.layers.symbologyTemplates import vectorRendererToNative, rasterRendererToNative, rendererToSpeckle
def convertSelectedLayers(all_layers: List[arcLayer], selected_layers: List[str], project: ArcGISProject) -> List[Union[VectorLayer,Layer]]:
"""Converts the current selected layers to Speckle"""
print("________Convert Layers_________")
@@ -202,7 +213,7 @@ def bimVectorLayerToNative(geomList, layerName: str, geomType: str, streamBranch
active_map = project.activeMap
path = project.filePath.replace("aprx","gdb") #
path_bim = "\\".join(project.filePath.split("\\")[:-1]) + "\\Layers_Speckle\\BIM_layers_speckle\\" + streamBranch+ "\\" + layerName + "\\" #arcpy.env.workspace + "\\" #
path_bim = "\\".join(project.filePath.split("\\")[:-1]) + "\\Layers_Speckle\\BIM_layers\\" + streamBranch+ "\\" + layerName + "\\" #arcpy.env.workspace + "\\" #
print(path_bim)
if not os.path.exists(path_bim): os.makedirs(path_bim)
@@ -478,8 +489,9 @@ def cadVectorLayerToNative(geomList, layerName: str, geomType: str, streamBranch
new_feat = cadFeatureToNative(f, newFields, sr)
if new_feat != "" and new_feat != None:
fets.append(new_feat)
#print("features created")
print("features created")
print(len(fets))
print(all_keys)
if len(fets) == 0: return None
count = 0
@@ -492,14 +504,20 @@ def cadVectorLayerToNative(geomList, layerName: str, geomType: str, streamBranch
heads = [ 'Shape@', 'OBJECTID']
for key,value in feat.items():
#print(key, str(value))
if key in all_keys and key.lower() not in fields_to_ignore:
heads.append(key)
row.append(value)
rowValues.append(row)
count += 1
cur = arcpy.da.InsertCursor(str(f_class), tuple(heads) )
#print(heads)
for row in rowValues:
cur.insertRow(tuple(row))
try:
#print(row)
cur.insertRow(tuple(row))
except Exception as e:
print(e)
del cur
vl = MakeFeatureLayer(str(f_class), newName).getOutput(0)
@@ -662,7 +680,7 @@ def rasterLayerToNative(layer: RasterLayer, streamBranch: str, project: ArcGISPr
rasterHasSr = False
print(path)
path_bands = "\\".join(path.split("\\")[:-1]) + "\\Layers_Speckle\\rasters_Speckle\\" + streamBranch
path_bands = "\\".join(path.split("\\")[:-1]) + "\\Layers_Speckle\\raster_bands\\" + streamBranch
if not os.path.exists(path_bands): os.makedirs(path_bands)
try:
@@ -9,18 +9,24 @@ import arcpy
from arcpy.management import CreateCustomGeoTransformation
from arcpy._mp import ArcGISProject, Map, Layer as arcLayer
from speckle.converter.geometry._init_ import convertToSpeckle, convertToNative, convertToNativeMulti
from speckle.converter.layers.utils import (findTransformation, getVariantFromValue, traverseDict,
traverseDictByKey, hsv_to_rgb)
from speckle.converter.geometry.point import pointToSpeckle
from speckle.converter.geometry.mesh import rasterToMesh, meshToNative
try:
from speckle.converter.geometry._init_ import convertToSpeckle, convertToNative, convertToNativeMulti
from speckle.converter.layers.utils import (findTransformation, getVariantFromValue, traverseDict,
traverseDictByKey, hsv_to_rgb)
from speckle.converter.geometry.point import pointToSpeckle
from speckle.converter.geometry.mesh import rasterToMesh, meshToNative
from speckle.converter.layers.symbologyTemplates import jsonFromLayerStyle
except:
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry._init_ import convertToSpeckle, convertToNative, convertToNativeMulti
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.utils import (findTransformation, getVariantFromValue, traverseDict,
traverseDictByKey, hsv_to_rgb)
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry.point import pointToSpeckle
from speckle_toolbox.esri.toolboxes.speckle.converter.geometry.mesh import rasterToMesh, meshToNative
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.symbologyTemplates import jsonFromLayerStyle
import numpy as np
import colorsys
from speckle.converter.layers.symbologyTemplates import jsonFromLayerStyle
def featureToSpeckle(fieldnames, attr_list, index: int, f_shape, projectCRS: arcpy.SpatialReference, project: ArcGISProject, selectedLayer: arcLayer):
print("___________Feature to Speckle____________")
@@ -82,9 +88,14 @@ def featureToNative(feature: Base, fields: dict, geomType: str, sr: arcpy.Spatia
return None
for key, variant in fields.items():
try: value = feature[key]
except:
if key == 'Speckle_ID': value = feature['id']
else:
arcpy.AddWarning(f'Field {key} not found')
return None
value = feature[key]
if variant == "TEXT": value = str(feature[key])
if variant == "TEXT": value = str(value)
if variant == getVariantFromValue(value) and value != "NULL" and value != "None":
feat.update({key: value})
else:
@@ -112,7 +123,7 @@ def bimFeatureToNative(feature: Base, fields: dict, sr: arcpy.SpatialReference,
def cadFeatureToNative(feature: Base, fields: dict, sr: arcpy.SpatialReference):
#print("04_________CAD Feature To Native____________")
print("04_________CAD Feature To Native____________")
feat = {}
try: speckle_geom = feature["geometry"] # for created in QGIS Layer type
except: speckle_geom = feature # for created in other software
@@ -133,6 +144,8 @@ def cadFeatureToNative(feature: Base, fields: dict, sr: arcpy.SpatialReference):
#### setting attributes to feature
feat_updated = updateFeat(feat, fields, feature)
print(feat)
print(fields)
return feat_updated
def addFeatVariant(key, variant, value, f):
@@ -140,24 +153,31 @@ def addFeatVariant(key, variant, value, f):
feat = f
if variant == "TEXT": value = str(value)
if value != "NULL" and value != "None":
#if key == 'area': print(value); print(type(value)); print(getVariantFromValue(value))
if variant == getVariantFromValue(value) or (variant=="FLOAT" and isinstance(value, int)):
feat.update({key: value})
feat.update({key: value})
elif variant == "LONG" and isinstance(value, float): # if object has been modified
feat.update({key: int(value)})
elif variant == "FLOAT" and isinstance(value, int): # if object has been modified
feat.update({key: float(value)})
else: feat.update({key: None})
elif variant == "TEXT" or variant == "FLOAT" or variant == "LONG" or variant == "SHORT": feat.update({key: None})
return feat
def updateFeat(feat:dict, fields: dict, feature: Base) -> dict[str, Any]:
def updateFeat(feat:dict, fields: dict, feature: Base) -> Dict[str, Any]:
for key, variant in fields.items():
try:
if key == "Speckle_ID":
value = str(feature["id"])
if key != "parameters": print(value)
feat[key] = value
feat = addFeatVariant(key, variant, value, feat)
else:
try:
value = feature[key]
#if key == "area": print(feature[key]); print(type(feature[key]))
feat = addFeatVariant(key, variant, value, feat)
except:
value = None
@@ -314,8 +334,8 @@ def rasterFeatureToSpeckle(selectedLayer: arcLayer, projectCRS: arcpy.SpatialRef
else:
#RGB colorizer
root_path = "\\".join(project.filePath.split("\\")[:-1])
if not os.path.exists(root_path + '\\Layers_Speckle\\rasters_Speckle'): os.makedirs(root_path + '\\Layers_Speckle\\rasters_Speckle')
path_style = root_path + '\\Layers_Speckle\\rasters_Speckle\\' + selectedLayer.name + '_temp.lyrx'
if not os.path.exists(root_path + '\\Layers_Speckle\\raster_bands'): os.makedirs(root_path + '\\Layers_Speckle\\raster_bands')
path_style = root_path + '\\Layers_Speckle\\raster_bands\\' + selectedLayer.name + '_temp.lyrx'
symJson = jsonFromLayerStyle(selectedLayer, path_style)
# read from Json
@@ -1,16 +1,21 @@
import json
from typing import Any, List, Union
from typing import Any, List, Tuple, Union
import copy
import os
from typing import Dict
import arcpy
from arcpy._mp import ArcGISProject
from specklepy.objects import Base
from speckle.converter.layers.Layer import Layer, VectorLayer, RasterLayer
from arcpy.management import (CreateFeatureclass, MakeFeatureLayer,
AddFields, AlterField, DefineProjection )
from specklepy.objects import Base
try:
from speckle.converter.layers.Layer import Layer, VectorLayer, RasterLayer
except:
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.Layer import Layer, VectorLayer, RasterLayer
def jsonFromLayerStyle(layerArcgis, path_style):
# write updated renderer to file and get layerStyle variable
arcpy.management.SaveToLayerFile(layerArcgis, path_style, False)
@@ -30,7 +35,7 @@ def symbol_color_to_speckle(color: dict):
except: pass
return newColor
def vectorRendererToNative(project: ArcGISProject, active_map, layerGroup, layerSpeckle: Union[Layer, VectorLayer], layerArcgis, f_class, existingAttrs: List) -> Union[None, dict[str, Any]] :
def vectorRendererToNative(project: ArcGISProject, active_map, layerGroup, layerSpeckle: Union[Layer, VectorLayer], layerArcgis, f_class, existingAttrs: List) -> Union[None, Dict[str, Any]] :
print("___________APPLY VECTOR RENDERER______________")
print(layerArcgis)
print(f_class)
@@ -158,7 +163,7 @@ def vectorRendererToNative(project: ArcGISProject, active_map, layerGroup, layer
else: return None
def get_rgb_from_speckle(rgb: int) -> tuple[int, int, int]:
def get_rgb_from_speckle(rgb: int) -> Tuple[int, int, int]:
r = g = b = 0
try:
r = (rgb & 0xFF0000) >> 16
@@ -169,7 +174,7 @@ def get_rgb_from_speckle(rgb: int) -> tuple[int, int, int]:
r,g,b = check_rgb(r,g,b)
return r,g,b
def check_rgb(r:int, g:int, b:int) -> tuple[int, int, int]:
def check_rgb(r:int, g:int, b:int) -> Tuple[int, int, int]:
if not isinstance(r, int) or r<0 or r>255: r=g=b=0
if not isinstance(g, int) or g<0 or g>255: r=g=b=0
@@ -203,9 +208,9 @@ def rasterRendererToNative(project: ArcGISProject, active_map, layerGroup, laye
# multiband raster, CIMRasterRGBColorizer
# arcpy doesnt support multiband raster symbology: https://community.esri.com/t5/arcgis-api-for-python-questions/why-does-arcpy-mp-arcgis-pro-2-6-mosaic-dataset/td-p/1016312
root_path = "\\".join(project.filePath.split("\\")[:-1])
if not os.path.exists(root_path + '\\Layers_Speckle\\rasters_Speckle'): os.makedirs(root_path + '\\Layers_Speckle\\rasters_Speckle')
path_style = root_path + '\\Layers_Speckle\\rasters_Speckle\\' + newName + '_old.lyrx'
path_style2 = root_path + '\\Layers_Speckle\\rasters_Speckle\\' + newName + '_new.lyrx'
if not os.path.exists(root_path + '\\Layers_Speckle\\raster_bands'): os.makedirs(root_path + '\\Layers_Speckle\\raster_bands')
path_style = root_path + '\\Layers_Speckle\\raster_bands\\' + newName + '_old.lyrx'
path_style2 = root_path + '\\Layers_Speckle\\raster_bands\\' + newName + '_new.lyrx'
symJson = jsonFromLayerStyle(arcLayer, path_style)
if renderer['type'] == 'singlebandgray':
@@ -303,12 +308,12 @@ def rendererToSpeckle(project: ArcGISProject, active_map, arcLayer, rasterFeat:
except:
rType = "multibandcolor"
root_path = "\\".join(project.filePath.split("\\")[:-1])
if not os.path.exists(root_path + '\\Layers_Speckle\\rasters_Speckle'): os.makedirs(root_path + '\\Layers_Speckle\\rasters_Speckle')
path_style = root_path + '\\Layers_Speckle\\rasters_Speckle\\' + arcLayer.name + '_temp.lyrx'
if not os.path.exists(root_path + '\\Layers_Speckle\\raster_bands'): os.makedirs(root_path + '\\Layers_Speckle\\raster_bands')
path_style = root_path + '\\Layers_Speckle\\raster_bands\\' + arcLayer.name + '_temp.lyrx'
#path_style2 = root_path + '\\' + newName + '_new.lyrx'
symJson = jsonFromLayerStyle(arcLayer, path_style)
layerRenderer: dict[str, Any] = {}
layerRenderer: Dict[str, Any] = {}
layerRenderer['type'] = rType
print(rType)
my_raster = arcpy.Raster(arcLayer.dataSource)
@@ -391,7 +396,7 @@ def rendererToSpeckle(project: ArcGISProject, active_map, arcLayer, rasterFeat:
return layerRenderer
elif arcLayer.isFeatureLayer:
layerRenderer: dict[str, Any] = {}
layerRenderer: Dict[str, Any] = {}
sym = arcLayer.symbology
print(sym.renderer.type)
@@ -15,8 +15,7 @@ def getVariantFromValue(value: Any) -> Union[str, None]:
(str, "TEXT"), # 10
(float, "FLOAT"),
(int, "LONG"),
(bool, "SHORT")
#date: "SHORT"
(bool, "SHORT")
]
res = None
for p in pairs:
@@ -31,7 +30,7 @@ def getVariantFromValue(value: Any) -> Union[str, None]:
return res
def getLayerAttributes(featuresList: List[Base], attrsToRemove: List[str] = ATTRS_REMOVE ) -> dict[str, str]:
def getLayerAttributes(featuresList: List[Base], attrsToRemove: List[str] = ATTRS_REMOVE ) -> Dict[str, str]:
print("03________ get layer attributes")
if not isinstance(featuresList, list): features = [featuresList]
@@ -53,6 +52,7 @@ def getLayerAttributes(featuresList: List[Base], attrsToRemove: List[str] = ATTR
value = feature[name]
variant = getVariantFromValue(value)
#if name == 'area': print(value); print(variant)
if not variant: variant = None #LongLong #4
# go thought the dictionary object
@@ -83,13 +83,15 @@ def getLayerAttributes(featuresList: List[Base], attrsToRemove: List[str] = ATTR
else: #check if the field was empty previously:
oldVariant = fields[k]
# replace if new one is NOT Float (too large integers)
if oldVariant != "FLOAT" and v == "FLOAT":
#print(oldVariant, v)
if oldVariant == "LONG" and v == "FLOAT":
fields.update({k: v})
# replace if new one is NOT LongLong or IS String
if oldVariant != "TEXT" and v == "TEXT":
fields.update({k: v})
#print(fields)
# replace all empty ones wit String
all_props.append("Speckle_ID")
for name in all_props:
if name not in fields.keys():
fields.update({name: 'TEXT'})
@@ -10,15 +10,26 @@ import arcpy
from arcpy._mp import ArcGISProject, Map, Layer as arcLayer
from arcpy import metadata as md
from specklepy.api.models import Branch, Stream, Streams
from speckle.converter.layers.Layer import Layer, RasterLayer
from speckle.converter.layers._init_ import convertSelectedLayers, layerToNative, cadLayerToNative, bimLayerToNative
try:
from speckle.converter.layers.Layer import Layer, RasterLayer
from speckle.converter.layers._init_ import convertSelectedLayers, layerToNative, cadLayerToNative, bimLayerToNative
from speckle.ui.project_vars import toolboxInputsClass, speckleInputsClass
from speckle.converter.layers.emptyLayerTemplates import createGroupLayer
from speckle.converter.layers.Layer import VectorLayer
except:
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.Layer import Layer, RasterLayer
from speckle_toolbox.esri.toolboxes.speckle.converter.layers._init_ import convertSelectedLayers, layerToNative, cadLayerToNative, bimLayerToNative
from speckle_toolbox.esri.toolboxes.speckle.ui.project_vars import toolboxInputsClass, speckleInputsClass
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.emptyLayerTemplates import createGroupLayer
from speckle_toolbox.esri.toolboxes.speckle.converter.layers.Layer import VectorLayer
from arcgis.features import FeatureLayer
import os
import os.path
import sys
import specklepy
from specklepy.api.models import Branch, Stream, Streams
from specklepy.transports.server.server import ServerTransport
from specklepy.api.credentials import get_local_accounts
from specklepy.api.client import SpeckleClient
@@ -33,10 +44,6 @@ from specklepy.api.wrapper import StreamWrapper
from specklepy.objects import Base
from specklepy.logging import metrics
from speckle.ui.project_vars import toolboxInputsClass, speckleInputsClass
from speckle.converter.layers.emptyLayerTemplates import createGroupLayer
from speckle.converter.layers.Layer import VectorLayer
#'''
def traverseObject(
@@ -78,8 +85,13 @@ class Toolbox:
self.alias = "speckle_toolbox_"
# List of tool classes associated with this toolbox
self.tools = [Speckle]
metrics.set_host_app("ArcGIS")
try:
version = arcpy.GetInstallInfo()['Version']
python_version = f"python {'.'.join(map(str, sys.version_info[:2]))}"
metrics.set_host_app("ArcGIS", ', '.join([f"ArcGIS {version}", python_version]))
except:
metrics.set_host_app("ArcGIS")
# https://pro.arcgis.com/en/pro-app/2.8/arcpy/mapping/alphabeticallistofclasses.htm#except: print("something happened")
class Speckle:
@@ -115,6 +127,10 @@ class Speckle:
break
if self.toolboxInputs is None: self.toolboxInputs = toolboxInputsClass()
#print(self.speckleInputs.accounts)
if len(self.speckleInputs.accounts) == 0:
arcpy.AddError("Speckle accounts not found")
def getParameterInfo(self):
#data types: https://pro.arcgis.com/en/pro-app/2.8/arcpy/geoprocessing_and_python/defining-parameter-data-types-in-a-python-toolbox.htm
# parameter details: https://pro.arcgis.com/en/pro-app/latest/arcpy/geoprocessing_and_python/customizing-tool-behavior-in-a-python-toolbox.htm
@@ -128,7 +144,6 @@ class Speckle:
name="streamsDefalut",
datatype="GPString",
parameterType="Optional",
#category="Sending data",
direction="Input",
category=cat1
)
@@ -136,15 +151,17 @@ class Speckle:
if isinstance(self.speckleInputs.streams_default, SpeckleException):
arcpy.AddError("Speckle account not accessible")
streamsDefalut.filter.list = []
elif self.speckleInputs.streams_default is not None:
streamsDefalut.filter.list = [ (str(st.name) + " - " + str(st.id)) for st in self.speckleInputs.streams_default ]
else:
streamsDefalut.filter.list = [ (st.name + " - " + st.id) for st in self.speckleInputs.streams_default ]
streamsDefalut.filter.list = []
arcpy.AddError("Error connecting to default Speckle account")
addDefStreams = arcpy.Parameter(
displayName="Add",
name="addDefStreams",
datatype="GPBoolean",
parameterType="Optional",
#category="Sending data",
direction="Input",
category=cat1
)
@@ -211,7 +228,6 @@ class Speckle:
parameterType="Required",
direction="Input",
multiValue=False,
#category=cat2
)
savedStreams.filter.list = [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}" for i,stream in enumerate(self.speckleInputs.saved_streams)]
@@ -229,9 +245,7 @@ class Speckle:
name="branch",
datatype="GPString",
parameterType="Required",
#category="Sending data",
direction="Input",
#category=cat2
)
branch.value = ""
branch.filter.type = 'ValueList'
@@ -241,9 +255,7 @@ class Speckle:
name="commit",
datatype="GPString",
parameterType="Optional",
#category="Sending data",
direction="Input",
#category=cat2
)
commit.value = ""
commit.filter.type = 'ValueList'
@@ -255,7 +267,6 @@ class Speckle:
parameterType="Optional",
direction="Input",
multiValue=False,
#category=cat2
)
msg.value = ""
@@ -266,7 +277,6 @@ class Speckle:
parameterType="Optional",
direction="Input",
multiValue=True,
#category=cat2
)
selectedLayers.filter.list = [str(i) + "-" + l.longName for i,l in enumerate(self.speckleInputs.all_layers)] #"Polyline"
@@ -276,13 +286,10 @@ class Speckle:
name="action",
datatype="GPString",
parameterType="Required",
#category="Sending data",
direction="Input",
multiValue=False,
#category=cat2
)
action.value = "Send"
#action.filter.type = 'ValueList'
action.filter.list = ["Send", "Receive"]
refresh = arcpy.Parameter(
@@ -291,8 +298,7 @@ class Speckle:
datatype="GPBoolean",
parameterType="Optional",
direction="Input"
)
#refresh.filter.type = "ValueList"
)
refresh.value = False
parameters = [streamsDefalut, addDefStreams, streamUrl, addUrlStreams, lat, lon, setLatLon, savedStreams, removeStream, branch, commit, selectedLayers, msg, action, refresh]
@@ -310,11 +316,11 @@ class Speckle:
if par.name == "addDefStreams" and par.altered and par.value == True:
for p in parameters:
if p.name == "streamsDefalut" and p.valueAsText is not None:
# add value from streamsDefault to saved streams
selected_stream_name = p.valueAsText[:]
#print(selected_stream_name)
for stream in self.speckleInputs.streams_default:
#print(stream)
if stream.name == selected_stream_name.split(" - ")[0]:
print("_____Add from list___")
wr = StreamWrapper(f"{self.speckleInputs.account.serverInfo.url}/streams/{stream.id}?u={self.speckleInputs.account.userInfo.id}")
@@ -340,8 +346,9 @@ class Speckle:
steamId = query
try: steamId = query.split("/streams/")[1].split("/")[0]
except: pass
# quesry stream, add to saved
stream = self.speckleInputs.speckle_client.stream.get(steamId)
# query stream, add to saved
stream = self.speckleInputs.speckle_client.stream.get(id = steamId, branch_limit = 100, commit_limit = 100)
if isinstance(stream, Stream):
print("_____Add by URL___")
wr = StreamWrapper(f"{self.speckleInputs.account.serverInfo.url}/streams/{stream.id}?u={self.speckleInputs.account.userInfo.id}")
@@ -364,11 +371,9 @@ class Speckle:
for p in parameters:
if p.name == "savedStreams" and p.valueAsText is not None:
# get value from savedStreams
# get value from savedStreams
selected_stream_name = p.valueAsText[:]
#print(selected_stream_name)
for streamTup in self.speckleInputs.saved_streams:
#print(stream)
stream = streamTup[1]
if stream.name == selected_stream_name.split(" - ")[0]:
print("_____Remove stream___")
@@ -394,6 +399,7 @@ class Speckle:
lat = p.valueAsText[:].replace(",","").replace(" ","").replace(";","").replace("_","")
try: lat = float(lat)
except: lat = 0; p.value = "0.0"
if p.name == "lon" and p.valueAsText is not None:
# add value from the UI to saved lat
lon = p.valueAsText[:].replace(",","").replace(" ","").replace(";","").replace("_","")
@@ -408,7 +414,6 @@ class Speckle:
if par.name == "savedStreams" and par.altered:
# Search for the stream by name
if par.value is not None and "Stream not accessible" not in par.valueAsText[:]:
#print("SAVED STREAMS - selection")
selected_stream_name = par.valueAsText[:]
self.toolboxInputs.active_stream = None
self.toolboxInputs.active_stream_wrapper = None
@@ -444,7 +449,6 @@ class Speckle:
p.value = None
self.toolboxInputs.active_commit = None
else: par.value = None
#print(self.toolboxInputs.action)
if par.name == "branch" and par.altered: # branches
if par.value is not None:
@@ -483,23 +487,14 @@ class Speckle:
if par.value is not None:
self.toolboxInputs.selected_layers = par.values
#print("selected layers changed")
#print(self.toolboxInputs.action)
#print(self.toolboxInputs.selected_layers)
if par.name == "msg" and par.altered and par.valueAsText is not None:
self.toolboxInputs.messageSpeckle = par.valueAsText
print(self.toolboxInputs.messageSpeckle)
if par.name == "action" and par.altered:
#print("action changed")
#print(par.valueAsText)
if par.valueAsText == "Send": self.toolboxInputs.action = 1
else: self.toolboxInputs.action = 0
#print(self.toolboxInputs.action)
#print(self.toolboxInputs.selected_layers)
if par.name == "refresh" and par.altered: # refresh btn
if par.value == True:
self.refresh(parameters)
@@ -508,9 +503,6 @@ class Speckle:
self.toRefresh = False
print("____________________________parameters___________________________")
#[print(str(x.name) + " - " + str(x.valueAsText)) for x in parameters]
#[x.clearMessage() for x in parameters] # https://pro.arcgis.com/en/pro-app/latest/arcpy/geoprocessing_and_python/programming-a-toolvalidator-class.htm
#[print(x.valueAsText) for x in parameters]
return
def refresh(self, parameters: List[Any]):
@@ -538,9 +530,7 @@ class Speckle:
else:
par.filter.list = [ (st.name + " - " + st.id) for st in self.speckleInputs.streams_default ]
if par.name == "savedStreams":
#print("par.name")
saved_streams = self.speckleInputs.getProjectStreams()
#print(saved_streams)
par.filter.list = [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}" for i,stream in enumerate(saved_streams)]
if par.name == "selectedLayers": par.filter.list = [str(i) + "-" + l.longName for i,l in enumerate(self.speckleInputs.all_layers)]
@@ -577,8 +567,6 @@ class Speckle:
print("______________SEND_______________")
#if self.validateStreamBranch(parameters) == False: return
if len(self.toolboxInputs.selected_layers) == 0:
arcpy.AddError("No layers selected for sending")
return
@@ -5,13 +5,12 @@ from arcpy._mp import ArcGISProject, Map, Layer as arcLayer
from specklepy.api.models import Branch, Stream, Streams
import os.path
from specklepy.api.credentials import get_local_accounts
from specklepy.api.credentials import Account, get_local_accounts
from specklepy.api.client import SpeckleClient
from specklepy.logging.exceptions import (
GraphQLException,
SpeckleException,
)
#from specklepy.api.credentials import StreamWrapper
from specklepy.api.wrapper import StreamWrapper
from osgeo import osr
@@ -19,21 +18,19 @@ class speckleInputsClass:
#def __init__(self):
print("CREATING speckle inputs first time________")
instances = []
accounts = get_local_accounts()
accounts: List[Account] = get_local_accounts()
account = None
streams_default: None or Streams = 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 = []
clients: List[SpeckleClient] = []
for acc in accounts:
if acc.isDefault:
account = acc
#break
if acc.isDefault: account = acc
new_client = SpeckleClient(
acc.serverInfo.url,
acc.serverInfo.url.startswith("https")
@@ -56,6 +53,7 @@ class speckleInputsClass:
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
@@ -119,23 +117,22 @@ class speckleInputsClass:
else: return []
def tryGetStream (self,sw: StreamWrapper) -> Stream:
#print("Try get streams")
steamId = sw.stream_id
try: steamId = sw.stream_id.split("/streams/")[1].split("/")[0]
except: pass
client = sw.get_client()
stream = client.stream.get(steamId)
if isinstance(stream, GraphQLException):
raise SpeckleException(stream.errors[0]['message'])
return 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:
#def __init__(self):
print("CREATING UI inputs first time________")
# self.instances.append(self)
instances = []
lat: float = 0.0
lon: float = 0.0
@@ -172,10 +169,9 @@ class toolboxInputsClass:
def setProjectStreams(self, wr: StreamWrapper, add = True):
# ERROR 032659 Error queueing metrics request:
# Cannot parse into a stream wrapper class - invalid URL provided.
print("SET proj streams")
if os.path.exists(self.stream_file_path):
if os.path.exists(self.stream_file_path) and ".gdb\\speckle_streams.txt" in self.stream_file_path:
new_content = ""
@@ -194,7 +190,7 @@ class toolboxInputsClass:
f.write(new_content)
f.close()
elif len(self.stream_file_path) >10:
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")
@@ -206,71 +202,75 @@ class toolboxInputsClass:
print("get survey point")
x = y = 0
if not content:
content = self.stream_file_path
try:
f = open(self.stream_file_path, "r")
content = f.read()
f.close()
except: pass
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:
temp = []
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)
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")
pt = "speckle_sr_origin_" + str(coords[0]) + ";" + str(coords[1])
if os.path.exists(self.stream_file_path):
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()
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
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()
new_content += pt + "," # add point
f.write(new_content)
f.close()
elif len(self.stream_file_path) >10:
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")
# 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")
arcpy.AddWarning("Custom CRS could not be created: not enough coordinates provided")
return True
+104
View File
@@ -0,0 +1,104 @@
from speckle_toolbox.esri.toolboxes.speckle.speckle_arcgis import Toolbox, Speckle # The code to test
from speckle_toolbox.esri.toolboxes.speckle.ui.project_vars import speckleInputsClass, toolboxInputsClass
import arcpy
import os
from specklepy.api.wrapper import StreamWrapper
from specklepy.api.models import Branch, Stream, Streams
from specklepy.logging.exceptions import GraphQLException, SpeckleException
from specklepy.api.credentials import Account
import unittest # The test framework
# remove SetUp
# add different scenqrios for Streqm Wrapper including wrng ones
# tree of all options for input or class outcome
# use dict for types chech
# issue with untestable class init
# "mocking objects" for tests or "faking"
# get functions ut of INIT
class Test_InitializingClasses(unittest.TestCase):
def setUp(self) -> None:
self.toolbox_input = toolboxInputsClass()
self.speckle_input = speckleInputsClass()
self.toolbox = Toolbox()
self.speckleTool = Speckle()
self.test_stream = "https://speckle.xyz/streams////17b0b76d13"
def text_all_toolbox(self):
self.assertTrue(isinstance(self.toolbox.tools[0], Speckle))
def test_toolbox_inputs(self):
self.assertEqual(self.toolbox_input.lat, 0)
self.assertEqual(self.toolbox_input.lon, 0)
self.assertIsNone(self.toolbox_input.active_stream)
self.assertIsNone(self.toolbox_input.active_branch)
self.assertIsNone(self.toolbox_input.active_commit)
self.assertEqual(len(self.toolbox_input.selected_layers), 0)
self.assertEqual(self.toolbox_input.messageSpeckle, "")
self.assertEqual(self.toolbox_input.action, 1)
self.assertIsNone(self.toolbox_input.project)
self.assertEqual(self.toolbox_input.stream_file_path, "")
def test_something(self):
# Arrange
toolbox_input: toolboxInputsClass = toolboxInputsClass()
# Act
toolbox_input.setProjectStreams(StreamWrapper(self.test_stream))
# Assert
os.path.exists(self.toolbox_input.stream_file_path)
def test_toolbox_inputs_functions(self):
self.toolbox_input.setProjectStreams(StreamWrapper(self.test_stream))
if os.path.exists(self.toolbox_input.stream_file_path):
f = open(self.toolbox_input.stream_file_path, "r")
existing_content = f.read()
f.close()
self.assertTrue(isinstance(existing_content, str))
self.toolbox_input.setProjectStreams(None)
if os.path.exists(self.toolbox_input.stream_file_path):
f = open(self.toolbox_input.stream_file_path, "r")
existing_content = f.read()
f.close()
self.assertTrue(isinstance(existing_content, str))
self.assertIsInstance()
self.assertTrue( isinstance(self.toolbox_input.get_survey_point(), tuple))
self.assertTrue( isinstance(self.toolbox_input.get_survey_point()[0], float) or isinstance(self.toolbox_input.get_survey_point()[0], int))
self.assertTrue( isinstance(self.toolbox_input.get_survey_point()[1], float) or isinstance(self.toolbox_input.get_survey_point()[1], int))
self.assertTrue( self.toolbox_input.set_survey_point )
def test_speckle_inputs(self):
self.assertTrue(isinstance(self.speckle_input.accounts, list))
self.assertTrue(self.speckle_input.account is None or isinstance(self.speckle_input.account, Account))
self.assertTrue(self.speckle_input.streams_default is None or isinstance(self.speckle_input.streams_default, list))
self.assertIsNone(self.speckle_input.project)
self.assertIsNone(self.speckle_input.active_map)
self.assertEqual(self.speckle_input.stream_file_path, "")
self.assertTrue(isinstance(self.speckle_input.saved_streams, list))
self.assertTrue(isinstance(self.speckle_input.all_layers, list))
self.assertTrue(isinstance(self.speckle_input.clients, list))
def test_speckle_inputs_functions(self):
self.assertTrue(isinstance(self.speckle_input.getProjectStreams(), list))
getStreams = self.speckle_input.getProjectStreams(self.test_stream)
self.assertTrue(isinstance(getStreams[0][0], StreamWrapper) and isinstance(getStreams[0][1], Stream))
self.assertTrue(isinstance(self.speckle_input.tryGetStream(StreamWrapper(self.test_stream)), Stream))
self.assertRaises(SpeckleException, lambda: self.speckle_input.tryGetStream(None))
def test_parameters(self):
actual = len(self.speckleTool.getParameterInfo())
expected = 15
self.assertEqual(actual, expected)
if __name__ == '__main__':
unittest.main()