#region Disclaimer / License // Copyright (C) 2010, Jackie Ng // http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie@gmail.com // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #endregion using System; using System.Collections.Generic; using System.Text; using GeoAPI.Geometries; #pragma warning disable 1591, 0114, 0108 namespace OSGeo.MapGuide.MaestroAPI.Expression { /// /// Expression class that implements the standard FDO expression functions. /// /// Despite the modifier. This class is for Expression Engine use only. /// public static class FdoFunctionNamespace { //TODO: Use a data type hierachy akin to FDO's LiteralValue and its descendants // // NOTE: ExpressionEngine will auto-coerce null values to DBNull.Value so when // testing for nulls, test for DBNull.Value // #region Aggregate #endregion #region Conversion public static object NullValue(object first, object second) { return first == DBNull.Value ? second : first; } public static DateTime ToDate(string str) { return DateTime.Parse(str); } public static double ToDouble(object value) { return Convert.ToDouble(value); } public static float ToFloat(object value) { return Convert.ToSingle(value); } public static int ToInt32(object value) { return Convert.ToInt32(value); } public static long ToInt64(object value) { return Convert.ToInt64(value); } public static string ToString(object value) { return Coalesce(value); } #endregion #region Date public static DateTime AddMonths(object value, object months) { return Convert.ToDateTime(value).AddMonths(Convert.ToInt32(months)); } public static DateTime CurrentDate() { return DateTime.Now; } public static DateTime Extract(object date, object fromDate) { throw new NotImplementedException(); } public static double ExtractToDouble(object date, object fromDate) { throw new NotImplementedException(); } public static int ExtractToInt(object date, object fromDate) { throw new NotImplementedException(); } #endregion #region Geometry public static double Area2D(IGeometry geom) { return geom.Area; } public static double Length2D(IGeometry geom) { return geom.Length; } public static double M(IGeometry geom) { return double.NaN; //M dimensions not supported } public static double X(IGeometry geom) { var pt = geom as IPoint; if (pt != null) return pt.X; return double.NaN; } public static double Y(IGeometry geom) { var pt = geom as IPoint; if (pt != null) return pt.Y; return double.NaN; } public static double Z(IGeometry geom) { var pt = geom as IPoint; if (pt != null) return pt.Z; return double.NaN; } #endregion #region Math public static double Abs(object value) { return Math.Abs(Convert.ToDouble(value)); } public static double Acos(object value) { return Math.Acos(Convert.ToDouble(value)); } public static double Asin(object value) { return Math.Asin(Convert.ToDouble(value)); } public static double Atan(object value) { return Math.Atan(Convert.ToDouble(value)); } public static double Atan2(object y, object x) { return Math.Atan2(Convert.ToDouble(y), Convert.ToDouble(x)); } public static double Cos(object value) { return Math.Cos(Convert.ToDouble(value)); } public static double Exp(object value) { return Math.Exp(Convert.ToDouble(value)); } public static double Ln(object value) { return Math.Log(Convert.ToDouble(value)); } public static double Log(object @base, object value) { return Math.Log(Convert.ToDouble(value), Convert.ToDouble(@base)); } public static double Mod(object value, object divisor) { return Convert.ToDouble(value) % Convert.ToDouble(divisor); } public static double Power(double value, double power) { return Math.Pow(value, power); } public static int Power(int value, int power) { return Convert.ToInt32(Math.Pow(value, power)); } public static double Remainder(object value, object divisor) { return Convert.ToDouble(value) % Convert.ToDouble(divisor); } public static double Sin(object value) { return Math.Sin(Convert.ToDouble(value)); } public static double Sqrt(object value) { return Math.Sqrt(Convert.ToDouble(value)); } public static double Tan(object value) { return Math.Tan(Convert.ToDouble(value)); } #endregion #region Numeric public static double Ceil(double value) { return Math.Ceiling(value); } public static double Floor(double value) { return Math.Floor(value); } public static double Round(double value) { return Math.Round(value); } public static double Sign(double value) { return Math.Sign(value); } public static double Trunc(double value) { return Math.Truncate(value); } #endregion #region String /// /// Returns a concatenated result of 2 string expressions /// /// /// /// public static string Concat(object a, object b) { return Coalesce(a) + Coalesce(b); } private static string Coalesce(object obj) { return (obj == null || obj == DBNull.Value) ? string.Empty : obj.ToString(); } /// /// Returns a concatentated result of 2 or more string expressions /// /// /// /// public static string Concat(object a, params object[] args) { StringBuilder sb = new StringBuilder(Coalesce(a)); foreach (var str in args) { sb.Append(Coalesce(str)); } return sb.ToString(); } /// /// Returns the position of a string within a base string /// /// /// /// public static int Instr(object str, object searchText) { return Coalesce(str).IndexOf(Coalesce(searchText)); } /// /// Determines the length of a string expression /// /// /// public static int Length(object str) { return Coalesce(str).Length; } /// /// Converts all upper case letters in the string expression to lower case /// /// /// public static string Lower(object str) { return Coalesce(str).ToLower(); } /// /// Pads a string expression as directed to the left /// /// /// public static string Lpad(object str) { throw new NotImplementedException(); } /// /// Trims a string expression to the left /// /// /// public static string Ltrim(object str) { return Coalesce(str).TrimStart(); } /// /// Pads a string expression as directed to the right /// /// /// public static string Rpad(object str) { throw new NotImplementedException(); } /// /// Trims a string expression to the right /// /// /// public static string Rtrim(object str) { return Coalesce(str).TrimEnd(); } /// /// Returns the phonetic representation of a string expression /// /// /// public static string Soundex(object str) { // +--------------------------------------------------------------------------- // | The function processes a call to the function SOUNDEX. // | NOTE: // | The implementation of the function utilizes the following algorithm: // | // | Step 1: Capitalize all letters in the word and remove all punctation // | marks and digits. // | Step 2: Retain the first letter of the word. // | Step 3: Replace any letter from the set {A, E, I, O, U, H, W, Y} with // | a 0 (zero). // | Step 4: Replace any letter from the set {B, F, P, V} with a 1. // | Replace any letter from the set {C, G, J, K, Q, S, X, Z) with // | a 2 // | Replace any letter from the set {D, T) with a 3 // | Replace any letter from the set {L) with a 4 // | Replace any letter from the set {M, N) with a 5 // | Replace any letter from the set {R) with a 6 // | Step 5: Remove all pairs of digits which occur beside each other from // | the that resulted from step 4. // | Step 6: Remove all the zeros from the string that resulted from step 5. // | Step 7: Pad the string resulting from step 6 with trailing zeros and // | return the first 4 positions (resulting in a string of the // | structure ). // +--------------------------------------------------------------------------- throw new NotImplementedException(); } /// /// Returns a substring from the provided string as defined /// /// /// /// public static string Substr(object str, object position) { return Coalesce(str).Substring(Convert.ToInt32(position)); } public static string Translate(object str, object from, object to) { // Navigate through the source string and execute the replacement. The // following rules apply: // // - any character in the from-set is replaced with the character in // the to-set at the same position. // - if the character in the from-set does not have a replacement // character in the to-set at the same position, the character is // deleted. // // NOTE: It is not possible to use the function REPLACE offered with the // class FdoStringP because this may result in incorrect results. // For example, if the call is TRANSLATE('abcd', 'ae', 'eS'), the // result should be 'ebcd', not 'Sbcd' which would be the case if // the mentioned function is used to do the job. throw new NotImplementedException(); } public static string Trim(object str) { return Coalesce(str).Trim(); } public static string Upper(object str) { return Coalesce(str).ToUpper(); } #endregion } }