This extension allows you to control styles by evaluating complex expressions from FeatureSource column data and also your own custom variables. With it, you can create powerful styles that do things such as color certain features differently based on an expression. To accomplish this, We use the Flee (Fast Lightweight Expression Evaluator) package.
It is my pleasure to share the FleeStyleExtension with the community. The idea was sparked by a requirement from one of our fellow developers named John who is an active forum member. Thank you very much John for challenging us with your requirements!
What Does it Do?
This extension allows you to control styles by evaluating complex expressions from FeatureSource column data and also your own custom variables. With it, you can create powerful styles that do things such as color certain features differently based on an expression, such as in the example below:
(ToInt32(POP_CNTRY)>10000000) AND (ToChar(LANDLOCKED)='Y')
In this expression, we look to find countries with populations over 10 million that are also landlocked. Normally you would need to use a combination of nested styles or create a custom Style to achieve this effect; however, now you can leverage expressions to do these types of operations in a single style.
Extension Highlights:
1. We use the Flee (Fast Lightweight Expression Evaluator) package. This package is well known for evaluating expressions much more quickly than other native methods found in .NET and, as the name suggests, being lightweight. You can find the source and useful examples online at the links below.
Homepage:
http://www.codeplex.com/Flee
CodeProject Article (great reference):
http://www.codeproject.com/KB/recipes/Flee.aspx
The package is released under the LGPL license, so we are referencing their released assembly. Due to this limitation, we are releasing this Style as an extension so that the main MapSuiteCore assembly does not require an additional DLL dependency. It can be used in commercial applications without releasing your source, as long as the LGPL guidelines are satisfied.
2. We allow you to include your own static types to use in the expressions. You can use the FleeBooleanStyle.StaticTypes collection to add any class type that has static methods. You can then use these in your expression just by calling the static method name. This is really handy for things like System.Math, System.Convert, etc. You can also use this to encapsulate your own custom logic.
3. It is simple to add your own custom variables, not just those from column data in the FeatureSource.
4. Expressions supported:
| Element |
Description |
Example |
| +, - |
Additive |
100 + a |
| *, /, % |
Multiplicative |
100 * 2 / (3 % 2) |
| ^ |
Power |
2 ^ 16 |
| - |
Negation |
-6 + 10 |
| + |
Concatenation |
"abc" + "def" |
| <<, >> |
Shift |
0x80 >> 2 |
| =, <>, <, >, <=, >= |
Comparison |
2.5 > 100 |
| And, Or, Xor, Not |
Logical |
(1 > 10) and (true or not false) |
| And, Or, Xor, Not |
Bitwise |
100 And 44 or (not 255) |
| If |
Conditional |
If(a > 100, "greater", "less") |
| Cast |
Cast and conversion |
cast(100.25, int) |
| [] |
Array index |
1 + arr[i+1] |
| . |
Member |
varA.varB.function("a") |
| String literal |
|
"string!" |
| Char literal |
|
'c' |
| Boolean literal |
|
true AND false |
| Real literal |
Double and single |
100.25 + 100.25f |
| Integer literal |
Signed/unsigned 32/64 bit |
100 + 100U + 100L + 100LU |
| Hex literal |
|
0xFF + 0xABCDU + 0x80L + 0xC9LU |
Limitations:
Currently we have implemented a boolean-type Style so your expressions need to result in a true or false. In reviewing the Flee engine, it is possible to have the result be a string or any kind of object. We will look into this to see what other kinds of Styles can leverage this powerful feature. If you have any scenarios in mind please let us know, as we would be happy to implement them.
It is required that you use the convert methods on variables coming from column data. When we retrieve data from the underlying FeatureSource, we convert all values to strings. This is because not all possible sources of data conform to the same data types. In Flee the variables are sensitive to the type, so if you have a column value in a shape file that is a number, make sure that in your expression you convert it to a number type. If you do not do the conversion then the engine will consider it a string and it will likely throw an exception. Here is an example of what the conversion code looks like: "(ToInt32(POP_CNTRY)>10000000) AND (ToChar(LANDLOCKED)='Y')" Note how we use the ToInt32 and ToChar methods. These are the static methods on the System.Convert class.
Sample
For the sample application to run correctly, you will need to reference the MapSuiteCore.dll assembly from any of our evaluation or full Map Suite 3.x products.
Downloads:
The sample provided shows how you can do an evaluation on multiple columns of mixed types and include static libraries. We render the Countries02 shape file and highlight in yellow the countries where the LandLocked field is "T" for true and the Population field is greater than 10 million. We include two different CustomStyles collections called CustomTrueStyles and CustomFalseStyles. As you can imagine, the CustomTrueStyles will be used if the expression evaluates to true and the CustomFalseStyles if false.
Feedback
We invite you to submit feedback on this extension and let us know what you think. As this has not yet been integrated into the Map Suite family of products, we have time to tweak the API, add features and enhance this to meet your requirements.