add Gis feature class on send and receive (#195)
* send GisFeature * remove display val from child geometries * receive GisFeature * fix * ensure units are strings * fix failing test
This commit is contained in:
Родитель
8463c82260
Коммит
ad34e3bbe6
|
@ -0,0 +1,13 @@
|
|||
from typing import List, Optional
|
||||
|
||||
from specklepy.objects.base import Base
|
||||
|
||||
|
||||
class GisFeature(
|
||||
Base, speckle_type="Objects.GIS.GisFeature", detachable={"displayValue"}
|
||||
):
|
||||
"""GIS Feature"""
|
||||
|
||||
geometry: Optional[List[Base]] = None
|
||||
attributes: Base
|
||||
displayValue: Optional[List[Base]] = None
|
|
@ -9,6 +9,7 @@ import hashlib
|
|||
|
||||
import scipy as sp
|
||||
from plugin_utils.helpers import findOrCreatePath, get_scale_factor_to_meter
|
||||
from speckle.converter.features.GisFeature import GisFeature
|
||||
from speckle.converter.geometry import transform
|
||||
from speckle.converter.geometry.conversions import (
|
||||
convertToNative,
|
||||
|
@ -79,15 +80,18 @@ def featureToSpeckle(
|
|||
iterations = 0
|
||||
try:
|
||||
geom = None
|
||||
new_geom = None
|
||||
|
||||
if geomType == "None":
|
||||
geom = GisNonGeometryElement()
|
||||
geom = GisNonGeometryElement() # redundant, delete in refactor
|
||||
new_geom = GisFeature()
|
||||
new_report = {"obj_type": geom.speckle_type, "errors": ""}
|
||||
else:
|
||||
# Try to extract geometry
|
||||
skipped_msg = f"'{geomType}' feature skipped due to invalid geometry"
|
||||
try:
|
||||
geom, iterations = convertToSpeckle(f, selectedLayer, dataStorage)
|
||||
|
||||
if geom is not None and geom != "None":
|
||||
if not isinstance(geom.geometry, List):
|
||||
logToUser(
|
||||
|
@ -97,6 +101,16 @@ def featureToSpeckle(
|
|||
)
|
||||
return None
|
||||
|
||||
# geom is GisPointElement, GisLineElement, GisPolygonElement
|
||||
new_geom = GisFeature()
|
||||
new_geom.geometry = []
|
||||
for g in geom.geometry:
|
||||
obj = g
|
||||
if isinstance(g, GisPolygonGeometry):
|
||||
new_geom.displayValue = []
|
||||
obj = GisPolygonGeometry(boundary=g.boundary, voids=g.voids)
|
||||
new_geom.geometry.append(obj)
|
||||
|
||||
all_errors = ""
|
||||
for g in geom.geometry:
|
||||
if g is None or g == "None":
|
||||
|
@ -114,6 +128,7 @@ def featureToSpeckle(
|
|||
func=inspect.stack()[0][3],
|
||||
)
|
||||
elif iterations is not None and iterations > 0:
|
||||
new_geom.displayValue.extend(g.displayValue)
|
||||
all_errors += (
|
||||
"Polygon display mesh is simplified" + ", "
|
||||
)
|
||||
|
@ -122,6 +137,8 @@ def featureToSpeckle(
|
|||
level=1,
|
||||
func=inspect.stack()[0][3],
|
||||
)
|
||||
else:
|
||||
new_geom.displayValue.extend(g.displayValue)
|
||||
|
||||
if len(geom.geometry) == 0:
|
||||
all_errors = "No geometry converted"
|
||||
|
@ -129,7 +146,7 @@ def featureToSpeckle(
|
|||
{"obj_type": geom.speckle_type, "errors": all_errors}
|
||||
)
|
||||
|
||||
else: # geom is None
|
||||
else: # geom is None, should not happen, but we should pass the object with attributes anyway
|
||||
new_report = {"obj_type": "", "errors": skipped_msg}
|
||||
logToUser(skipped_msg, level=2, func=inspect.stack()[0][3])
|
||||
geom = GisNonGeometryElement()
|
||||
|
@ -162,11 +179,12 @@ def featureToSpeckle(
|
|||
|
||||
# if geom is not None and geom!="None":
|
||||
geom.attributes = attributes
|
||||
new_geom.attributes = attributes
|
||||
|
||||
dataStorage.latestActionFeaturesReport[
|
||||
len(dataStorage.latestActionFeaturesReport) - 1
|
||||
].update(new_report)
|
||||
return geom
|
||||
return new_geom
|
||||
|
||||
except Exception as e:
|
||||
new_report.update({"errors": e})
|
||||
|
@ -174,7 +192,7 @@ def featureToSpeckle(
|
|||
len(dataStorage.latestActionFeaturesReport) - 1
|
||||
].update(new_report)
|
||||
logToUser(e, level=2, func=inspect.stack()[0][3])
|
||||
return geom
|
||||
return new_geom
|
||||
|
||||
|
||||
def rasterFeatureToSpeckle(
|
||||
|
@ -987,7 +1005,9 @@ def featureToNative(feature: Base, fields: "QgsFields", dataStorage):
|
|||
try:
|
||||
qgsGeom = None
|
||||
|
||||
if isinstance(feature, GisNonGeometryElement):
|
||||
if isinstance(feature, GisNonGeometryElement) or (
|
||||
isinstance(feature, GisFeature) and feature.geometry is None
|
||||
):
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
|
@ -1006,7 +1026,10 @@ def featureToNative(feature: Base, fields: "QgsFields", dataStorage):
|
|||
qgsGeom = convertToNative(speckle_geom, dataStorage)
|
||||
|
||||
elif isinstance(speckle_geom, list):
|
||||
if len(speckle_geom) == 1:
|
||||
# add condition for new GisFeature class
|
||||
if isinstance(feature, GisFeature) and isinstance(speckle_geom[0], GisPolygonGeometry) and speckle_geom[0].boundary is None:
|
||||
qgsGeom = convertToNativeMulti(feature.displayValue, dataStorage)
|
||||
elif len(speckle_geom) == 1:
|
||||
qgsGeom = convertToNative(speckle_geom[0], dataStorage)
|
||||
elif len(speckle_geom) > 1:
|
||||
qgsGeom = convertToNativeMulti(speckle_geom, dataStorage)
|
||||
|
|
|
@ -237,9 +237,7 @@ def convertToSpeckle(
|
|||
v[1] for v in enumerate(poly.exteriorRing().vertices())
|
||||
]
|
||||
except:
|
||||
boundaryPts = [
|
||||
v[1] for v in enumerate(poly.vertices())
|
||||
]
|
||||
boundaryPts = [v[1] for v in enumerate(poly.vertices())]
|
||||
if height is not None:
|
||||
if isFlat(boundaryPts) is False:
|
||||
logToUser(
|
||||
|
@ -445,6 +443,9 @@ def convertToNativeMulti(
|
|||
return multiPolylineToNative(items, dataStorage)
|
||||
# elif isinstance(first, Arc) or isinstance(first, Polycurve) or isinstance(first, Ellipse) or isinstance(first, Circle) or isinstance(first, Curve):
|
||||
# return [convertToNative(it, dataStorage) for it in items]
|
||||
elif isinstance(first, Mesh):
|
||||
converted: QgsMultiPolygon = meshToNative(items, dataStorage)
|
||||
return converted
|
||||
elif isinstance(first, Base):
|
||||
try:
|
||||
displayVals = []
|
||||
|
@ -453,7 +454,7 @@ def convertToNativeMulti(
|
|||
displayVals.extend(it.displayValue)
|
||||
except:
|
||||
displayVals.extend(it["@displayValue"])
|
||||
if isinstance(first, GisPolygonGeometry):
|
||||
if isinstance(first, GisPolygonGeometry) or isinstance(first, Mesh):
|
||||
if first.boundary is None:
|
||||
converted: QgsMultiPolygon = meshToNative(
|
||||
displayVals, dataStorage
|
||||
|
|
|
@ -496,7 +496,8 @@ class SpeckleQGIS:
|
|||
units = str(QgsUnitTypes.encodeUnit(projectCRS.mapUnits()))
|
||||
self.dataStorage.latestActionUnits = units
|
||||
try:
|
||||
units = get_units_from_string(units)
|
||||
units_class = get_units_from_string(units)
|
||||
units = units_class.value
|
||||
except SpeckleInvalidUnitException:
|
||||
units = "none"
|
||||
self.dataStorage.currentUnits = units
|
||||
|
|
|
@ -116,8 +116,11 @@ def test_validateBranch(stream):
|
|||
assert isinstance(result, Branch)
|
||||
|
||||
|
||||
def test_validateBranch_no_commits(stream_fe1):
|
||||
branch_name = "main"
|
||||
def test_validateBranch_no_commits():
|
||||
sample_wrapper = StreamWrapper("https://latest.speckle.dev/streams/7117052f4e")
|
||||
sample_wrapper.get_client()
|
||||
stream_fe1 = sample_wrapper._client.stream.get(id=sample_wrapper.stream_id)
|
||||
branch_name = "empty_branch"
|
||||
result = validateBranch(stream_fe1, branch_name, checkCommits=True, dockwidget=None)
|
||||
assert result is None
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче