22{
33 using System ;
44 using System . Collections . Generic ;
5+ using System . Diagnostics ;
56 using System . Diagnostics . CodeAnalysis ;
6- using System . Linq ;
77 using System . Text . Json ;
88 using System . Text . Json . Serialization ;
99
@@ -24,41 +24,102 @@ public class Expression
2424 internal Expression ( ) { }
2525
2626 /// <summary>
27- /// Creates an expression
27+ /// Creates an expression.
2828 /// </summary>
29- /// <param name="expressions">Expressions to include in this expression</param>
29+ /// <param name="expressions">Expressions to include in this expression. </param>
3030 public Expression ( IEnumerable < Expression > expressions ) => Expressions = expressions ;
3131
3232 /// <summary>
33- /// Creates an expression
33+ /// Creates an expression.
3434 /// </summary>
35- /// <param name="json">Json representation of the expression</param>
35+ /// <param name="json">Json representation of the expression. </param>
3636 public Expression ( JsonDocument json ) => Json = json ;
37+
38+ /// <summary>
39+ /// Converts <see cref="this"/> resulting value to number.
40+ /// <para>Wrapper around 'to-number': <see cref="https://docs.microsoft.com/en-us/azure/azure-maps/data-driven-style-expressions-web-sdk"/>.</para>
41+ /// </summary>
42+ /// <returns>An expression converting supplied expression result into number.</returns>
43+ public ExpressionOrNumber ToNumber ( )
44+ => this is ExpressionOrNumber alreadyNumber
45+ ? alreadyNumber
46+ : ( new ( new [ ] { new ExpressionOrString ( "to-number" ) , this } ) ) ;
47+
48+ private static readonly Expression s_getter = new ExpressionOrString ( "get" ) ;
49+
50+ /// <summary>
51+ /// An expression getting property value by <paramref name="propertyName"/>.
52+ /// <para>Cluster properties are supplied via <seealso cref="Data.DataSourceOptions.ClusterProperties"/>.</para>
53+ /// <para>Leaf level properties are supplied in data itself (f.e. <see cref="Feature.Properties"/>).</para>
54+ /// </summary>
55+ /// <param name="propertyName">The property name to get value.</param>
56+ /// <returns>An expression to fetch property value.</returns>
57+ public static Expression GetProperty ( string propertyName ) => new ( new [ ] { s_getter , new ExpressionOrString ( propertyName ) } ) ;
58+
59+ /// <summary>
60+ /// An expression checking if <paramref name="propertyName"/> is defined in node.
61+ /// <para>Typically used during data clustering to check if cluster node has property</para>
62+ /// <para>See <seealso cref="Data.DataSourceOptions.ClusterProperties"/>.</para>
63+ /// </summary>
64+ /// <param name="propertyName">The property name to check existance.</param>
65+ /// <returns>Expression that will evaluate into <c>true</c> if cluster has property; <c>false</c> otherwise.</returns>
66+ public static Expression HasProperty ( string propertyName ) => new ( new [ ] { new ExpressionOrString ( "has" ) , new ExpressionOrString ( propertyName ) } ) ;
67+
68+ /// <summary>
69+ /// An expression conditionally evaluating either <paramref name="ifTrue"/> or <paramref name="ifFalse"/> based on <paramref name="condition"/>.
70+ /// <para>Typically used during cluster/leaf property fetch, as cluster has only aggregated properties, while leaf level has more.</para>
71+ /// </summary>
72+ /// <param name="condition">The expression evaluating to <see cref="bool"/> (f.e. <see cref="IsCluster"/>).</param>
73+ /// <param name="ifTrue">The expression to evaluate if <paramref name="condition"/> was <c>true</c>.</param>
74+ /// <param name="ifFalse">The expression to evaluate if <paramref name="condition"/> was <c>false</c>.</param>
75+ /// <returns>An expression conditionally evaluating either expression based on <paramref name="condition"/>.</returns>
76+ public static Expression Conditional ( Expression condition , Expression ifTrue , Expression ifFalse ) => new ( new [ ] { new ExpressionOrString ( "case" ) , condition , ifTrue , ifFalse } ) ;
77+
78+ /// <summary>
79+ /// An expression checking if node is cluster, or leaf.
80+ /// <para>See <seealso cref="Data.DataSourceOptions.Cluster"/></para>
81+ /// </summary>
82+ public static readonly Expression IsCluster = HasProperty ( ClusterProperties . PointCount ) ;
83+
84+ /// <summary>
85+ /// Holds cluster-specific properties provided by clustering engine, see <seealso cref="Data.DataSourceOptions.Cluster"/>.
86+ /// <para>
87+ /// <seealso cref="https://docs.microsoft.com/en-us/azure/azure-maps/clustering-point-data-web-sdk"/>
88+ /// </para>
89+ /// </summary>
90+ private struct ClusterProperties
91+ {
92+ /// <summary>
93+ /// Point count exists only for cluster-level; leaf-level nodes do not have it.
94+ /// </summary>
95+ public static readonly string PointCount = "point_count" ;
96+ }
3797 }
3898
3999 /// <summary>
40100 /// Can be specified as the value of filter or certain layer options.
41101 /// </summary>
42102 [ JsonConverter ( typeof ( ExpressionOrNumberJsonConverter ) ) ]
43103 [ ExcludeFromCodeCoverage ]
104+ [ DebuggerDisplay ( "{" + nameof ( Value ) + "}" ) ]
44105 public sealed class ExpressionOrNumber : Expression
45106 {
46107 internal double ? Value { get ; }
47108
48109 /// <summary>
49- /// Creates an expression
110+ /// <inheritdoc cref="Expression(IEnumerable{Expression})"/>
50111 /// </summary>
51- /// <param name="expressions">Expressions to include in this expression </param>
112+ /// <param name="expressions"><inheritdoc/> </param>
52113 public ExpressionOrNumber ( IEnumerable < Expression > expressions ) : base ( expressions ) { }
53114
54115 /// <summary>
55- /// Creates an expression
116+ /// <inheritdoc cref="Expression(JsonDocument)"/>
56117 /// </summary>
57- /// <param name="json">Json representation of the expression </param>
118+ /// <param name="json"><inheritdoc/> </param>
58119 public ExpressionOrNumber ( JsonDocument json ) : base ( json ) { }
59120
60121 /// <summary>
61- /// Creates an expression
122+ /// Creates an expression.
62123 /// </summary>
63124 /// <param name="value">Value which will be used instead of the expression</param>
64125 public ExpressionOrNumber ( double ? value ) => Value = value ;
@@ -69,20 +130,21 @@ public ExpressionOrNumber(JsonDocument json) : base(json) { }
69130 /// </summary>
70131 [ JsonConverter ( typeof ( ExpressionOrStringJsonConverter ) ) ]
71132 [ ExcludeFromCodeCoverage ]
133+ [ DebuggerDisplay ( "{" + nameof ( Value ) + "}" ) ]
72134 public sealed class ExpressionOrString : Expression
73135 {
74136 internal string Value { get ; }
75137
76138 /// <summary>
77- /// Creates an expression
139+ /// <inheritdoc cref="Expression(IEnumerable{Expression})"/>
78140 /// </summary>
79- /// <param name="expressions">Expressions to include in this expression </param>
141+ /// <param name="expressions"><inheritdoc/> </param>
80142 public ExpressionOrString ( IEnumerable < Expression > expressions ) : base ( expressions ) { }
81143
82144 /// <summary>
83- /// Creates an expression
145+ /// <inheritdoc cref="Expression(JsonDocument)"/>
84146 /// </summary>
85- /// <param name="json">Json representation of the expression </param>
147+ /// <param name="json"><inheritdoc/> </param>
86148 public ExpressionOrString ( JsonDocument json ) : base ( json ) { }
87149
88150 /// <summary>
@@ -102,19 +164,19 @@ public sealed class ExpressionOrStringArray : Expression
102164 internal IEnumerable < string > Values { get ; }
103165
104166 /// <summary>
105- /// Creates an expression
167+ /// <inheritdoc cref="Expression(IEnumerable{Expression})"/>
106168 /// </summary>
107- /// <param name="expressions">Expressions to include in this expression </param>
169+ /// <param name="expressions"><inheritdoc/> </param>
108170 public ExpressionOrStringArray ( IEnumerable < Expression > expressions ) : base ( expressions ) { }
109171
110172 /// <summary>
111- /// Creates an expression
173+ /// <inheritdoc cref="Expression(JsonDocument)"/>
112174 /// </summary>
113- /// <param name="json">Json representation of the expression </param>
175+ /// <param name="json"><inheritdoc/> </param>
114176 public ExpressionOrStringArray ( JsonDocument json ) : base ( json ) { }
115177
116178 /// <summary>
117- /// Creates an expression
179+ /// Creates an expression.
118180 /// </summary>
119181 /// <param name="values">Values of the expression</param>
120182 public ExpressionOrStringArray ( IEnumerable < string > values ) => Values = values ;
0 commit comments