Skip to content

Commit

Permalink
Extend support of rotation from visualVariables (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
vuilleumierc authored and GeoSander committed Mar 29, 2023
1 parent 0bcb194 commit 81f0d96
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 25 deletions.
38 changes: 34 additions & 4 deletions bridgestyle/arcgis/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

def convertExpression(expression, engine, tolowercase):
if engine == "Arcade":
expression = expression.replace("$feature.","")
expression = convertArcadeExpression(expression)
if tolowercase:
expression = expression.lower()
if "+" in expression or "&" in expression:
Expand All @@ -16,7 +16,7 @@ def convertExpression(expression, engine, tolowercase):
for token in tokens:
if "[" in token:
addends.append(
["PropertyName", token.replace("[", "").replace("]", "").strip()]
["PropertyName", processPropertyName(token)]
)
else:
literal = token.replace('"', "")
Expand All @@ -26,7 +26,7 @@ def convertExpression(expression, engine, tolowercase):
allOps = ["Concatenate", attr, allOps]
expression = allOps
else:
expression = ["PropertyName", expression.replace("[", "").replace("]", "")]
expression = ["PropertyName", processPropertyName(expression)]
return expression


Expand All @@ -36,6 +36,14 @@ def replaceSpecialLiteral(literal):
return literal


def processPropertyName(token):
return token.replace("[", "").replace("]", "").strip()


def convertArcadeExpression(expression):
return expression.replace("$feature.", "")


def stringToParameter(s, tolowercase):
s = s.strip()
if "'" in s or '"' in s:
Expand All @@ -56,7 +64,8 @@ def convertWhereClause(clause, tolowercase):
if " AND " in clause:
expression = ["And"]
subexpressions = [s.strip() for s in clause.split(" AND ")]
expression.extend([convertWhereClause(s, tolowercase) for s in subexpressions])
expression.extend([convertWhereClause(s, tolowercase)
for s in subexpressions])
return expression
if "=" in clause:
tokens = [t.strip() for t in clause.split("=")]
Expand Down Expand Up @@ -106,3 +115,24 @@ def convertWhereClause(clause, tolowercase):
return accum

return clause


def processRotationExpression(expression, rotationType, tolowercase):
if "$feature" in expression:
field = convertArcadeExpression(expression)
else:
field = processPropertyName(expression)
propertyNameExpression = ["PropertyName",
field.lower() if tolowercase else field]
if rotationType == "Arithmetic":
return [
"Mul",
propertyNameExpression,
-1,
]
elif rotationType == "Geographic":
return [
"Sub",
propertyNameExpression,
90,
]
43 changes: 22 additions & 21 deletions bridgestyle/arcgis/togeostyler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
import uuid
from typing import Union

import typing

from .constants import ESRI_SYMBOLS_FONT, POLYGON_FILL_RESIZE_FACTOR, OFFSET_FACTOR, pt_to_px
from .expressions import convertExpression, convertWhereClause
from .expressions import convertExpression, convertWhereClause, processRotationExpression
from .wkt_geometries import to_wkt


Expand All @@ -28,6 +27,7 @@ def convert(arcgis, options=None):
def processLayer(layer, options=None):
# layer is a dictionary with the ArcGIS Pro Json style
options = options or {}
tolowercase = options.get("tolowercase", False)
geostyler = {"name": layer["name"]}
if layer["type"] == "CIMFeatureLayer":
renderer = layer["renderer"]
Expand Down Expand Up @@ -63,9 +63,14 @@ def processLayer(layer, options=None):
if layer.get("labelVisibility", False):
for labelClass in layer.get("labelClasses", []):
rules.append(
processLabelClass(labelClass, options.get("tolowercase", False))
processLabelClass(labelClass, tolowercase)
)

rotation = _getSymbolRotationFromVisualVariables(renderer, tolowercase)
if rotation:
for rule in rules:
[symbolizer.update({"rotate": rotation}) for symbolizer in rule["symbolizers"]]

geostyler["rules"] = rules
elif layer["type"] == "CIMRasterLayer":
_warnings.append('CIMRasterLayer are not supported yet.')
Expand All @@ -80,7 +85,7 @@ def processClassBreaksRenderer(renderer, options):
field = renderer["field"]
lastbound = None
tolowercase = options.get("tolowercase", False)
rotation = _getGraduatedSymbolRotation(renderer, tolowercase) if renderer.get("classBreakType") == "GraduatedSymbol" else None
rotation = _getSymbolRotationFromVisualVariables(renderer, tolowercase)
for classbreak in renderer.get("breaks", []):
symbolizers = processSymbolReference(classbreak["symbol"], options)
upperbound = classbreak.get("upperBound", 0)
Expand Down Expand Up @@ -653,23 +658,19 @@ def processSymbolLayer(layer, symboltype, options):
return None


def _getGraduatedSymbolRotation(renderer, tolowercase):
visualVariables = renderer.get("visualVariables", [])
for visualVariable in visualVariables:
if visualVariable.get("visualVariableInfoZ",{}).get("visualVariableInfoType") == "Expression":
return _processArcadeRotationExpression(
visualVariable.get("visualVariableInfoZ",{}).get("valueExpressionInfo",{}).get("expression"),
tolowercase
)


def _processArcadeRotationExpression(expression, tolowercase):
field = expression.replace("$feature.","")
return [
"Sub",
["PropertyName", field.lower() if tolowercase else field],
90,
]
def _getSymbolRotationFromVisualVariables(renderer, tolowercase):
for visualVariable in renderer.get("visualVariables", []):
if visualVariable["type"] == "CIMRotationVisualVariable":
expression = \
visualVariable["visualVariableInfoZ"].get("valueExpressionInfo", {}).get("expression") or \
visualVariable["visualVariableInfoZ"].get("expression")
rotationType = visualVariable["rotationTypeZ"]
return processRotationExpression(
expression,
rotationType,
tolowercase
)
return None


def _orientedMarkerAtEndOfLine(markerPlacement):
Expand Down

0 comments on commit 81f0d96

Please sign in to comment.