From ceaca12caabfd6d753bd4e8133460bbb2e61ff3a Mon Sep 17 00:00:00 2001 From: KatKatKateryna Date: Tue, 13 Feb 2024 16:40:54 +0000 Subject: [PATCH] fixed reprojecting geometry on send --- .../speckle/converter/geometry/conversions.py | 8 +- .../speckle/converter/geometry/polyline.py | 17 +- .../speckle/speckle/converter/layers/utils.py | 157 ++++++++++-------- 3 files changed, 100 insertions(+), 82 deletions(-) diff --git a/speckle_toolbox/esri/toolboxes/speckle/speckle/converter/geometry/conversions.py b/speckle_toolbox/esri/toolboxes/speckle/speckle/converter/geometry/conversions.py index d2bc9a3..a668e9c 100644 --- a/speckle_toolbox/esri/toolboxes/speckle/speckle/converter/geometry/conversions.py +++ b/speckle_toolbox/esri/toolboxes/speckle/speckle/converter/geometry/conversions.py @@ -107,7 +107,7 @@ def convertToSpeckle( f_shape = apply_reproject(feature, x_form, dataStorage).getPart() if f_shape is None: return None - result = [pointToSpeckle(feature.getPart(), feature, layer, dataStorage)] + result = [pointToSpeckle(f_shape, feature, layer, dataStorage)] for r in result: r.units = units @@ -123,7 +123,7 @@ def convertToSpeckle( return None result = [ pointToSpeckle(pt, feature, layer, dataStorage) - for pt in feature.getPart() + for pt in f_shape ] for r in result: r.units = units @@ -172,7 +172,7 @@ def convertToSpeckle( f_shape = apply_reproject(feature, x_form, dataStorage).getPart() result = [ polygonToSpeckle(geom, feature, index, layer, dataStorage, x_form) - for geom in feature.getPart() + for geom in f_shape ] for r in result: @@ -198,7 +198,7 @@ def convertToSpeckle( f_shape = apply_reproject(feature, x_form, dataStorage).getPart() if f_shape is None: return None - result = [polygonToSpeckleMesh(feature, index, layer, False, dataStorage)] + result = [polygonToSpeckleMesh(f_shape, index, layer, False, dataStorage)] for r in result: if r is None: continue diff --git a/speckle_toolbox/esri/toolboxes/speckle/speckle/converter/geometry/polyline.py b/speckle_toolbox/esri/toolboxes/speckle/speckle/converter/geometry/polyline.py index 155ab23..6b52a0d 100644 --- a/speckle_toolbox/esri/toolboxes/speckle/speckle/converter/geometry/polyline.py +++ b/speckle_toolbox/esri/toolboxes/speckle/speckle/converter/geometry/polyline.py @@ -97,17 +97,18 @@ def anyLineToSpeckle(geom, feature, layer, dataStorage, x_form=None): # geometry SHAPE@ tokens: https://pro.arcgis.com/en/pro-app/latest/arcpy/get-started/reading-geometries.htm # print(geom.JSON) new_geom = geom.densify("GEODESIC", 0.1) - if x_form is not None: - f_shape = apply_reproject(feature, x_form, dataStorage).getPart() - #f_shape = findTransformation(new_geom, *xform_vars) - if f_shape is None: - return None else: new_geom = geom except: # no curves new_geom = geom - #print(new_geom) # describe geometry object + if x_form is not None: + new_geom = apply_reproject(new_geom, x_form, dataStorage).getPart() + # f_shape = findTransformation(new_geom, *xform_vars) + if new_geom is None: + return None + + # print(new_geom) # describe geometry object for p in new_geom: print(p) # array for pt in p: @@ -165,8 +166,8 @@ def polylineFromVerticesToSpeckle( """Converts a Polyline to Speckle""" polyline = Polyline(units="m") try: - #print("__polylineFromVerticesToSpeckle") - #print(vertices) + # print("__polylineFromVerticesToSpeckle") + # print(vertices) if isinstance(vertices, list): if len(vertices) > 0 and isinstance(vertices[0], Point): specklePts = vertices diff --git a/speckle_toolbox/esri/toolboxes/speckle/speckle/converter/layers/utils.py b/speckle_toolbox/esri/toolboxes/speckle/speckle/converter/layers/utils.py index 5ce9602..a411dd5 100644 --- a/speckle_toolbox/esri/toolboxes/speckle/speckle/converter/layers/utils.py +++ b/speckle_toolbox/esri/toolboxes/speckle/speckle/converter/layers/utils.py @@ -1,5 +1,6 @@ import copy from datetime import datetime +import random from typing import Dict, Any, List, Tuple, Union import json import hashlib @@ -527,91 +528,100 @@ def findTransformation( layer_sr: arcpy.SpatialReference, projectCRS: arcpy.SpatialReference, selectedLayer: arcLayer, -) -> tuple: +) -> Tuple: # apply transformation if needed try: - # print(f_shape) + print("___findTransformation___") + tr0 = tr1 = tr2 = tr_custom = None if ( - layer_sr.name != projectCRS.name - or len(layer_sr.name) < 2 - or len(projectCRS.name) < 2 + geomType != "Point" + and geomType != "Polyline" + and geomType != "Polygon" + and geomType != "Multipoint" + and geomType != "MultiPatch" ): - tr0 = tr1 = tr2 = tr_custom = None - midSr = arcpy.SpatialReference("WGS 1984") # GCS_WGS_1984 - # print(layer_sr) try: - transformations = arcpy.ListTransformations(layer_sr, projectCRS) - # print(transformations) - customTransformName = "layer_sr.name" + "_To_" + projectCRS.name - if len(transformations) == 0: - try: - tr1 = arcpy.ListTransformations(layer_sr, midSr)[0] - tr2 = arcpy.ListTransformations(midSr, projectCRS)[0] - except: - # customGeoTransfm = "GEOGTRAN[METHOD['Geocentric_Translation'],PARAMETER['X_Axis_Translation',''],PARAMETER['Y_Axis_Translation',''],PARAMETER['Z_Axis_Translation','']]" - # CreateCustomGeoTransformation(customTransformName, layer_sr, projectCRS) - tr_custom = customTransformName - else: - # print("else") - # choose equation based instead of file-based/grid-based method, - # to be consistent with QGIS: https://desktop.arcgis.com/en/arcmap/latest/map/projections/choosing-an-appropriate-transformation.htm - selecterTr = {} - for tr in transformations: - if "NTv2" not in tr and "NADCON" not in tr: - set1 = set( - layer_sr.name.split("_") + projectCRS.name.split("_") - ) - set2 = set(tr.split("_")) - diff = len(set(set1).symmetric_difference(set2)) - selecterTr.update({tr: diff}) - selecterTr = dict( - sorted(selecterTr.items(), key=lambda item: item[1]) - ) - tr0 = list(selecterTr.keys())[0] - # print(tr0) - - if ( - geomType != "Point" - and geomType != "Polyline" - and geomType != "Polygon" - and geomType != "Multipoint" - and geomType != "MultiPatch" - ): - try: - logToUser( - "Unsupported or invalid geometry in layer " - + selectedLayer.name, - level=2, - func=inspect.stack()[0][3], - ) - except: - logToUser( - "Unsupported or invalid geometry", - level=2, - func=inspect.stack()[0][3], - ) - try: - print(layer_sr, tr0, tr1, tr2) - except: - pass - return layer_sr, tr0, tr1, tr2 - - except: logToUser( - f"Spatial Transformation not found for layer {selectedLayer.name}", + "Unsupported or invalid geometry in layer " + selectedLayer.name, level=2, func=inspect.stack()[0][3], ) - return None, None, None, None + except: + logToUser( + "Unsupported or invalid geometry", + level=2, + func=inspect.stack()[0][3], + ) + return layer_sr, None, None, None, None + + if layer_sr.name == projectCRS.name: + return layer_sr, None, None, None, None + + # get list of transforms and find similar one + transformations = arcpy.ListTransformations(layer_sr, projectCRS) + + customTransformName = ( + hashlib.md5(layer_sr.exportToString().encode("utf-8")).hexdigest() + + "_To_" + + hashlib.md5(projectCRS.exportToString().encode("utf-8")).hexdigest() + ) + print(customTransformName) + for tr in transformations: + print(tr) + if tr == customTransformName: + tr0 = tr + print("found") + return layer_sr, tr0, tr1, tr2, tr_custom + + if tr0 is None: # if no valid transforms found + try: # try find intermediate transforms + midSr = arcpy.SpatialReference("WGS 1984") # GCS_WGS_1984 + tr1 = arcpy.ListTransformations(layer_sr, midSr)[0] + tr2 = arcpy.ListTransformations(midSr, projectCRS)[0] + except Exception as e: # create custom transform in nothing else works + print(e) + layer_sr = arcpy.SpatialReference(text=layer_sr.exportToString()) + projectCRS = arcpy.SpatialReference(text=projectCRS.exportToString()) + customGeoTransfm = "GEOGTRAN[METHOD['Geocentric_Translation'],PARAMETER['X_Axis_Translation',''],PARAMETER['Y_Axis_Translation',''],PARAMETER['Z_Axis_Translation','']]" + arcpy.management.CreateCustomGeoTransformation( + customTransformName, layer_sr, projectCRS, customGeoTransfm + ) + tr_custom = customTransformName + print(tr_custom) + return layer_sr, tr0, tr1, tr2, tr_custom + r""" + else: + print("else") + # choose equation based instead of file-based/grid-based method, + # to be consistent with QGIS: https://desktop.arcgis.com/en/arcmap/latest/map/projections/choosing-an-appropriate-transformation.htm + selecterTr = {} + for tr in transformations: + if "NTv2" not in tr and "NADCON" not in tr: + set1 = set( + layer_sr.name.split("_") + projectCRS.name.split("_") + ) + set2 = set(tr.split("_")) + diff = len(set(set1).symmetric_difference(set2)) + selecterTr.update({tr: diff}) + selecterTr = dict( + sorted(selecterTr.items(), key=lambda item: item[1]) + ) + tr0 = list(selecterTr.keys())[0] + # print(tr0) + """ except Exception as e: - logToUser(str(e), level=2, func=inspect.stack()[0][3]) - return None, None, None, None + logToUser( + f"Spatial Transformation not found for layer {selectedLayer.name}: {e}", + level=2, + func=inspect.stack()[0][3], + ) + return layer_sr, None, None, None, None def apply_reproject(f_shape, transforms: Tuple, dataStorage): try: - layer_sr, tr0, tr1, tr2 = transforms + layer_sr, tr0, tr1, tr2, tr_custom = transforms projectCRS = dataStorage.project.activeMap.spatialReference # reproject geometry using chosen transformstion(s) if tr0 is not None: @@ -622,7 +632,14 @@ def apply_reproject(f_shape, transforms: Tuple, dataStorage): ptgeo1 = f_shape.projectAs(midSr, tr1) ptgeo2 = ptgeo1.projectAs(projectCRS, tr2) f_shape = ptgeo2 + r""" + elif tr_custom is not None: + print(tr_custom) + ptgeo1 = f_shape.projectAs(projectCRS, tr_custom) + f_shape = ptgeo1 + """ else: + projectCRS = arcpy.SpatialReference(text=projectCRS.exportToString()) ptgeo1 = f_shape.projectAs(projectCRS) f_shape = ptgeo1 except Exception as e: