Skip to content

Commit

Permalink
2.20_Attribute types and geometry types aligned with arcgis_to_DEV (#205
Browse files Browse the repository at this point in the history
)

* adjust field types and geometry types to be synced with DUI3 ArcGIS
* add displayVal to polylines and points
* support old geometry types and field types
* receive new GIS classes without .geometry
  • Loading branch information
KatKatKateryna authored Oct 22, 2024
1 parent f480441 commit bdc1398
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 46 deletions.
26 changes: 12 additions & 14 deletions speckle/converter/features/feature_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,13 @@ def featureToSpeckle(
# geom is GisPointElement, GisLineElement, GisPolygonElement
new_geom = GisFeature()
new_geom.geometry = []
new_geom.displayValue = []
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)
new_geom.geometry.append(obj)
else:
new_geom.geometry.append(g)

all_errors = ""
for g in geom.geometry:
Expand Down Expand Up @@ -139,6 +140,9 @@ def featureToSpeckle(
else:
new_geom.displayValue.extend(g.displayValue)

else: # Points and Lines
new_geom.displayValue.append(g)

if len(geom.geometry) == 0:
all_errors = "No geometry converted"
new_report.update(
Expand All @@ -148,7 +152,8 @@ def featureToSpeckle(
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()
# geom = GisNonGeometryElement()
new_geom = GisNonGeometryElement()
except Exception as error:
new_report = {
"obj_type": "",
Expand Down Expand Up @@ -177,7 +182,7 @@ def featureToSpeckle(
attributes[corrected] = f_val

# if geom is not None and geom!="None":
geom.attributes = attributes
# geom.attributes = attributes
new_geom.attributes = attributes

dataStorage.latestActionFeaturesReport[
Expand Down Expand Up @@ -1350,16 +1355,9 @@ def featureToNative(feature: Base, fields: "QgsFields", dataStorage):
pass
else:
try:
speckle_geom = (
feature.geometry
) # for QGIS / ArcGIS Layer type from 2.14
speckle_geom = feature.geometry
except:
try:
speckle_geom = feature[
"geometry"
] # for QGIS / ArcGIS Layer type before 2.14
except:
speckle_geom = feature # for created in other software
speckle_geom = feature.displayValue

if not isinstance(speckle_geom, list):
qgsGeom = convertToNative(speckle_geom, dataStorage)
Expand Down
68 changes: 68 additions & 0 deletions speckle/converter/layers/GISAttributeFieldType.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from enum import Enum


class GISAttributeFieldType(str, Enum):
"""GIS VectorLayer geometry types"""

GUID_TYPE = "Guid"
OID = "Oid"
STRING_TYPE = "String"
FLOAT_TYPE = "Float"
INTEGER_TYPE = "Integer"
BIGINTEGER = "BigInteger"
SMALLINTEGER = "SmallInteger"
DOUBLE_TYPE = "Double"
DATETIME = "DateTime"
DATEONLY = "DateOnly"
TIMEONLY = "TimeOnly"
TIMESTAMPOFFSET = "TimeStampOffset"
BOOL = "Bool"

@staticmethod
def assign_speckle_field_type(type_index: int) -> "GISAttributeFieldType":
"""Assign Speckle representation of the Field type."""
val_dict = {
1: GISAttributeFieldType.BOOL,
2: GISAttributeFieldType.INTEGER_TYPE,
6: GISAttributeFieldType.DOUBLE_TYPE,
10: GISAttributeFieldType.STRING_TYPE,
14: GISAttributeFieldType.DATEONLY,
15: GISAttributeFieldType.TIMEONLY,
16: GISAttributeFieldType.DATETIME,
}
result: GISAttributeFieldType = val_dict.get(
type_index, GISAttributeFieldType.STRING_TYPE
)
return result

@staticmethod
def get_native_field_type_from_speckle(field_type: str) -> int:
"""Get native Field type (not currently used)."""

val_dict = {
GISAttributeFieldType.BOOL: 1,
GISAttributeFieldType.STRING_TYPE: 10,
GISAttributeFieldType.GUID_TYPE: 10,
GISAttributeFieldType.OID: 10,
GISAttributeFieldType.TIMESTAMPOFFSET: 10,
GISAttributeFieldType.FLOAT_TYPE: 6,
GISAttributeFieldType.DOUBLE_TYPE: 6,
GISAttributeFieldType.INTEGER_TYPE: 2,
GISAttributeFieldType.BIGINTEGER: 2,
GISAttributeFieldType.SMALLINTEGER: 2,
GISAttributeFieldType.DATETIME: 16,
GISAttributeFieldType.DATEONLY: 14,
GISAttributeFieldType.TIMEONLY: 15,
}

try:
speckle_field_type = GISAttributeFieldType(field_type)
result: int = val_dict.get(speckle_field_type, 10)
except:
# for older commits
try:
result: int = val_dict.get(int(field_type), 10)
except:
pass

return result
80 changes: 80 additions & 0 deletions speckle/converter/layers/GISLayerGeometryType.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from enum import Enum
from typing import Optional


class GISLayerGeometryType(str, Enum):
"""GIS VectorLayer geometry types"""

NONE = "None"
POINT = "Point"
POLYLINE = "Polyline"
POLYGON = "Polygon"
POLYGON3D = "Polygon3d"
MULTIPATCH = "Multipatch"
POINTCLOUD = "Pointcloud"

@staticmethod
def assign_speckle_layer_geometry_type(
native_geom_type: int,
) -> "GISLayerGeometryType":
"""Get Speckle representation of the Layer Geometry Type."""

type_index: int = native_geom_type % 1000 # e.g.3004->7, 4002->4
val_dict = {
1: GISLayerGeometryType.POINT,
2: GISLayerGeometryType.POLYLINE,
3: GISLayerGeometryType.POLYGON,
4: GISLayerGeometryType.POINT,
5: GISLayerGeometryType.POLYLINE,
6: GISLayerGeometryType.POLYGON,
7: "GeometryCollection",
8: GISLayerGeometryType.POLYLINE,
9: GISLayerGeometryType.POLYLINE,
10: GISLayerGeometryType.POLYGON,
11: GISLayerGeometryType.POLYLINE,
12: "MultiSurface",
17: "Triangle",
}
result: GISLayerGeometryType = val_dict.get(
type_index, GISLayerGeometryType.NONE
)

# write 3d polygons as a separate type
# geometry types of 1,2,3 etc (<1000) have 2 dimensions, rest: 3
if native_geom_type > 1000 and result == GISLayerGeometryType.POLYGON:
result = GISLayerGeometryType.POLYGON3D

return result

@staticmethod
def get_native_layer_geometry_type_from_speckle(
geom_type: str,
) -> Optional[str]:
"""Get native Layer Geometry Type."""

val_dict = {
GISLayerGeometryType.NONE: "None",
GISLayerGeometryType.POINT: "MultiPointZ",
GISLayerGeometryType.POLYLINE: "MultiLineStringZ",
GISLayerGeometryType.POLYGON: "MultiPolygon",
GISLayerGeometryType.POLYGON3D: "MultiPolygonZ",
GISLayerGeometryType.MULTIPATCH: "MultiPolygonZ",
# GISLayerGeometryType.POINTCLOUD: ,
}

try:
speckle_geom_type = GISLayerGeometryType(geom_type)
result: Optional[str] = val_dict.get(speckle_geom_type)
except:
# for older commits
if "point" in geom_type.lower():
result = "MultiPointZ"
elif "line" in geom_type.lower():
result = "MultiLineStringZ"
elif (
"polygon" in geom_type.lower()
or "multipatch" in geom_type.lower()
):
result = "MultiPolygonZ"

return result
67 changes: 40 additions & 27 deletions speckle/converter/layers/layer_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import inspect
import hashlib
import math
from typing import List, Tuple, Union
from typing import List, Optional, Tuple, Union
from specklepy.objects import Base
from specklepy.objects.geometry import (
Mesh,
Expand All @@ -29,6 +29,8 @@
jsonFromList,
removeSpecialCharacters,
)
from speckle.converter.layers.GISAttributeFieldType import GISAttributeFieldType
from speckle.converter.layers.GISLayerGeometryType import GISLayerGeometryType

# from qgis._core import Qgis, QgsVectorLayer, QgsWkbTypes
try:
Expand Down Expand Up @@ -336,7 +338,9 @@ def layerToSpeckle(
if attribute_type == att_type[0]:
attribute_type = att_type[1]
"""
attributes[corrected] = attribute_type
attributes[corrected] = GISAttributeFieldType.assign_speckle_field_type(
attribute_type
)

extrusionApplied = isAppliedLayerTransformByKeywords(
selectedLayer, ["extrude", "polygon"], [], plugin.dataStorage
Expand All @@ -346,7 +350,9 @@ def layerToSpeckle(
if not layerName.endswith("_as_Mesh"):
layerName += "_as_Mesh"

geomType = getLayerGeomType(selectedLayer)
geomType = GISLayerGeometryType.assign_speckle_layer_geometry_type(
selectedLayer.wkbType()
) # getLayerGeomType(selectedLayer)
features = selectedLayer.getFeatures()

elevationLayer = getElevationLayer(plugin.dataStorage)
Expand Down Expand Up @@ -943,19 +949,34 @@ def geometryLayerToNative(
# print(geom_meshes)

if len(geom_meshes) > 0:
geomType: str = str(
GISLayerGeometryType.get_native_layer_geometry_type_from_speckle(
GISLayerGeometryType.POLYGON3D
)
)
bimVectorLayerToNative(
geom_meshes, layerName, val_id, "Mesh", streamBranch, plugin, matrix
geom_meshes, layerName, val_id, geomType, streamBranch, plugin, matrix
)
if len(geom_points) > 0:
geomType: str = str(
GISLayerGeometryType.get_native_layer_geometry_type_from_speckle(
GISLayerGeometryType.POINT
)
)
cadVectorLayerToNative(
geom_points, layerName, val_id, "Points", streamBranch, plugin, matrix
geom_points, layerName, val_id, geomType, streamBranch, plugin, matrix
)
if len(geom_polylines) > 0:
geomType: str = str(
GISLayerGeometryType.get_native_layer_geometry_type_from_speckle(
GISLayerGeometryType.POLYLINE
)
)
cadVectorLayerToNative(
geom_polylines,
layerName,
val_id,
"Polylines",
geomType,
streamBranch,
plugin,
matrix,
Expand All @@ -975,7 +996,7 @@ def bimVectorLayerToNative(
geomType: str,
streamBranch: str,
plugin,
matrix: list = None,
matrix: Optional[list] = None,
):
# print("02_________BIM vector layer to native_____")
try:
Expand All @@ -991,8 +1012,10 @@ def bimVectorLayerToNative(
# layerName = layerName + "_" + geomType
# print(layerName)

r"""
if "mesh" in geomType.lower():
geomType = "MultiPolygonZ"
"""

newFields = getLayerAttributes(geomList)
# print("___________Layer fields_____________")
Expand Down Expand Up @@ -1037,11 +1060,11 @@ def addBimMainThread(obj: Tuple):
project: QgsProject = dataStorage.project

geom_print = geomType
if "MultiPolygonZ" in geom_print:
if "multipolygon" in geom_print.lower():
geom_print = "Mesh"
elif "LineStringZ" in geom_print:
elif "linestring" in geom_print.lower():
geom_print = "Polyline"
elif "PointZ" in geom_print:
elif "point" in geom_print.lower():
geom_print = "Point"

shortName = layerName.split(SYMBOL)[len(layerName.split(SYMBOL)) - 1][:50]
Expand Down Expand Up @@ -1306,11 +1329,12 @@ def cadVectorLayerToNative(
newName = (
f'{streamBranch.split("_")[len(streamBranch.split("_"))-1]}/{layerName}'
)

r"""
if geomType == "Points":
geomType = "PointZ"
elif geomType == "Polylines":
geomType = "LineStringZ"
"""

newFields = getLayerAttributes(geomList)
# print(newFields.toList())
Expand Down Expand Up @@ -1354,11 +1378,11 @@ def addCadMainThread(obj: Tuple):
dataStorage.matrix = matrix

geom_print = geomType
if "MultiPolygonZ" in geom_print:
if "multipolygon" in geom_print.lower():
geom_print = "Mesh"
elif "LineStringZ" in geom_print:
elif "linestring" in geom_print.lower():
geom_print = "Polyline"
elif "PointZ" in geom_print:
elif "point" in geom_print.lower():
geom_print = "Point"

shortName = layerName.split(SYMBOL)[len(layerName.split(SYMBOL)) - 1][:50]
Expand Down Expand Up @@ -1573,20 +1597,9 @@ def vectorLayerToNative(
newName = layerName # f'{streamBranch.split("_")[len(streamBranch.split("_"))-1]}_{layerName}'
# print(newName)

# particularly if the layer comes from ArcGIS
geomType = (
geomType = GISLayerGeometryType.get_native_layer_geometry_type_from_speckle(
layer.geomType
) # for ArcGIS: Polygon, Point, Polyline, Multipoint, MultiPatch
if geomType == "Point":
geomType = "Point"
elif geomType == "Polygon":
geomType = "MultiPolygon"
elif geomType == "Polyline":
geomType = "MultiLineString"
elif geomType.lower() == "multipoint":
geomType = "MultiPoint"
elif geomType == "MultiPatch":
geomType = "Polygon"
)

fets = []
# print("before newFields")
Expand Down
Loading

0 comments on commit bdc1398

Please sign in to comment.