#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 System.Xml; namespace OSGeo.MapGuide.MaestroAPI.Schema { /// /// Defines the valid types of geometric storage in a geometric property /// [Flags] public enum FeatureGeometricType : int { /// /// Points /// Point = 1, /// /// Curves (lines) /// Curve = 2, /// /// Surfaces (polygons) /// Surface = 4, /// /// Solids /// Solid = 8, /// /// All types /// All = Curve | Point | Solid | Surface } /// /// Defines the valid specific geometry types for geometric storage /// public enum SpecificGeometryType { /// /// Points /// Point = 1, /// /// Line Strings /// LineString = 2, /// /// Polygons /// Polygon = 3, /// /// Multi Points /// MultiPoint = 4, /// /// Multi Line Strings /// MultiLineString = 5, /// /// Multi Polygons /// MultiPolygon = 6, /// /// Multi Geometries /// MultiGeometry = 7, /// /// Curve Strings /// CurveString = 10, /// /// Curve Polygons /// CurvePolygon = 11, /// /// Multi Curve Strings /// MultiCurveString = 12, /// /// Multi Curve Polygons /// MultiCurvePolygon = 13 } /// /// A geometric property /// public class GeometricPropertyDefinition : PropertyDefinition { private GeometricPropertyDefinition() { this.SpecificGeometryTypes = new SpecificGeometryType[0]; } /// /// Initializes a new instance of the class. /// /// The name. /// The description. public GeometricPropertyDefinition(string name, string description) : this() { this.Name = name; this.Description = description; } /// /// Gets or sets a Boolean value that indicates if this geometric property is read-only. /// public bool IsReadOnly { get; set; } /// /// Gets or sets a Boolean value that indicates if the geometry of this property includes measurement values that can be used for dynamic segmentation. /// public bool HasMeasure { get; set; } /// /// Gets or sets a Boolean value that indicates if the geometry of this property include elevation values. /// public bool HasElevation { get; set; } /// /// Gets or sets the Spatial Context name associated to this geometric property. /// public string SpatialContextAssociation { get; set; } private FeatureGeometricType _geometricTypes; /// /// Gets or sets the that can be stored in this geometric /// property. The returned value may be any combination of the values from the /// enumeration combined via a bit-wise or operation. /// public FeatureGeometricType GeometricTypes { get { return _geometricTypes; } set { _geometricTypes = value; Dictionary sgts = new Dictionary(); foreach (FeatureGeometricType fgt in Enum.GetValues(typeof(FeatureGeometricType))) { if ((_geometricTypes & fgt) > 0) { switch (fgt) { case FeatureGeometricType.Point: sgts.Add(SpecificGeometryType.Point, SpecificGeometryType.Point); sgts.Add(SpecificGeometryType.MultiPoint, SpecificGeometryType.MultiPoint); break; case FeatureGeometricType.Curve: sgts.Add(SpecificGeometryType.LineString, SpecificGeometryType.LineString); sgts.Add(SpecificGeometryType.MultiLineString, SpecificGeometryType.MultiLineString); sgts.Add(SpecificGeometryType.CurveString, SpecificGeometryType.CurveString); sgts.Add(SpecificGeometryType.MultiCurveString, SpecificGeometryType.MultiCurveString); break; case FeatureGeometricType.Surface: sgts.Add(SpecificGeometryType.Polygon, SpecificGeometryType.Polygon); sgts.Add(SpecificGeometryType.MultiPolygon, SpecificGeometryType.MultiPolygon); sgts.Add(SpecificGeometryType.CurvePolygon, SpecificGeometryType.CurvePolygon); sgts.Add(SpecificGeometryType.MultiCurvePolygon, SpecificGeometryType.MultiCurvePolygon); break; } } } _sgts = new List(sgts.Keys).ToArray(); } } private SpecificGeometryType[] _sgts; /// /// Gets or sets the specific set of geometry types that can be stored in this geometric property. The provided value is a /// list of geometry types that are supported. Usually, one specific type is supported, but there can be more than one. /// public SpecificGeometryType[] SpecificGeometryTypes { get { return _sgts; } set { _sgts = value; bool hasPoint = false; bool hasLine = false; bool hasPoly = false; for (int i = 0; i < _sgts.Length; i++) { if (_sgts[i] == SpecificGeometryType.Point || _sgts[i] == SpecificGeometryType.MultiPoint) hasPoint = true; if (_sgts[i] == SpecificGeometryType.LineString || _sgts[i] == SpecificGeometryType.MultiLineString || _sgts[i] == SpecificGeometryType.CurveString || _sgts[i] == SpecificGeometryType.MultiCurveString) hasLine = true; if (_sgts[i] == SpecificGeometryType.Polygon || _sgts[i] == SpecificGeometryType.MultiPolygon || _sgts[i] == SpecificGeometryType.CurvePolygon || _sgts[i] == SpecificGeometryType.MultiCurvePolygon) hasPoly = true; if (_sgts[i] == SpecificGeometryType.MultiGeometry) hasPoly = hasPoint = hasLine = true; } FeatureGeometricType? fgt = null; if (hasPoint) { if (fgt.HasValue) fgt = fgt.Value | FeatureGeometricType.Point; else fgt = FeatureGeometricType.Point; } if (hasLine) { if (fgt.HasValue) fgt = fgt.Value | FeatureGeometricType.Curve; else fgt = FeatureGeometricType.Curve; } if (hasPoly) { if (fgt.HasValue) fgt = fgt.Value | FeatureGeometricType.Surface; else fgt = FeatureGeometricType.Surface; } if (fgt.HasValue) _geometricTypes = fgt.Value; } } /// /// Gets the type of property definition /// public override PropertyDefinitionType Type { get { return PropertyDefinitionType.Geometry; } } /// /// Writes the current element's content /// /// /// public override void WriteXml(System.Xml.XmlDocument doc, System.Xml.XmlNode currentNode) { var en = Utility.EncodeFDOName(this.Name); var geom = doc.CreateElement("xs", "element", XmlNamespaces.XS); //NOXLATE geom.SetAttribute("name", en); //NOXLATE geom.SetAttribute("type", "gml:AbstractGeometryType"); //NOXLATE geom.SetAttribute("hasMeasure", XmlNamespaces.FDO, this.HasMeasure.ToString().ToLower()); //NOXLATE geom.SetAttribute("hasElevation", XmlNamespaces.FDO, this.HasElevation.ToString().ToLower()); //NOXLATE geom.SetAttribute("srsName", XmlNamespaces.FDO, this.SpatialContextAssociation); //NOXLATE geom.SetAttribute("geometricTypes", XmlNamespaces.FDO, GeometricTypesToString()); //NOXLATE geom.SetAttribute("geometryTypes", XmlNamespaces.FDO, GeometryTypesToString()); //NOXLATE geom.SetAttribute("geometryReadOnly", XmlNamespaces.FDO, this.IsReadOnly.ToString().ToLower()); //NOXLATE //Write description node var anno = doc.CreateElement("xs", "annotation", XmlNamespaces.XS); //NOXLATE var docN = doc.CreateElement("xs", "documentation", XmlNamespaces.XS); //NOXLATE docN.InnerText = this.Description; geom.AppendChild(anno); anno.AppendChild(docN); currentNode.AppendChild(geom); } /// /// Set the current element's content from the current XML node /// /// /// public override void ReadXml(System.Xml.XmlNode node, System.Xml.XmlNamespaceManager mgr) { var gt = Utility.GetFdoAttribute(node, "geometricTypes"); var gt2 = Utility.GetFdoAttribute(node, "geometryTypes"); var gtro = Utility.GetFdoAttribute(node, "geometryReadOnly"); var hms = Utility.GetFdoAttribute(node, "hasMeasure"); var hev = Utility.GetFdoAttribute(node, "hasElevation"); var srs = Utility.GetFdoAttribute(node, "srsName"); this.GeometricTypes = ProcessGeometricTypes(gt.Value); if (gt2 != null) this.SpecificGeometryTypes = ProcessSpecificGeometryTypes(gt2.Value); this.IsReadOnly = (gtro != null ? Convert.ToBoolean(gtro.Value) : false); this.HasElevation = (hev != null ? Convert.ToBoolean(hev.Value) : false); this.HasMeasure = (hms != null ? Convert.ToBoolean(hms.Value) : false); this.SpatialContextAssociation = (srs != null ? srs.Value : string.Empty); } /// /// Converts the current specified geometry types to a space-delimited list of types /// /// public string GeometryTypesToString() { List values = new List(); var gts = GetIndividualGeometricTypes(); foreach (var gt in gts) { values.Add(gt.ToString().ToLower()); } return string.Join(" ", values.ToArray()); } /// /// Gets an array of the individual values that /// compose the final masked value that is returned by the /// property /// /// public FeatureGeometricType[] GetIndividualGeometricTypes() { List gts = new List(); if (this.GeometricTypes == FeatureGeometricType.All) { gts.AddRange((FeatureGeometricType[])Enum.GetValues(typeof(FeatureGeometricType))); } else { foreach (FeatureGeometricType gt in Enum.GetValues(typeof(FeatureGeometricType))) { if (((int)this.GeometricTypes & (int)gt) == (int)gt) { gts.Add(gt); } } } return gts.ToArray(); } private string GeometricTypesToString() { List values = new List(); foreach (SpecificGeometryType geom in this.SpecificGeometryTypes) { values.Add(geom.ToString().ToLower()); } return string.Join(" ", values.ToArray()); } private static SpecificGeometryType[] ProcessSpecificGeometryTypes(string str) { List values = new List(); string[] tokens = str.ToLower().Split(' '); foreach (string t in tokens) { switch (t) { case "curvepolygon": values.Add(SpecificGeometryType.CurvePolygon); break; case "curvestring": values.Add(SpecificGeometryType.CurveString); break; case "linestring": values.Add(SpecificGeometryType.LineString); break; case "multicurvepolygon": values.Add(SpecificGeometryType.MultiCurvePolygon); break; case "multicurvestring": values.Add(SpecificGeometryType.MultiCurveString); break; case "multigeometry": values.Add(SpecificGeometryType.MultiGeometry); break; case "multilinestring": values.Add(SpecificGeometryType.MultiLineString); break; case "multipoint": values.Add(SpecificGeometryType.MultiPoint); break; case "multipolygon": values.Add(SpecificGeometryType.MultiPolygon); break; case "point": values.Add(SpecificGeometryType.Point); break; case "polygon": values.Add(SpecificGeometryType.Polygon); break; } } return values.ToArray(); } private static FeatureGeometricType ProcessGeometricTypes(string p) { FeatureGeometricType? gt = null; string[] tokens = p.ToLower().Split(' '); foreach (string str in tokens) { switch (str) { case "point": { if (gt.HasValue) gt = gt.Value | FeatureGeometricType.Point; else gt = FeatureGeometricType.Point; } break; case "curve": { if (gt.HasValue) gt = gt.Value | FeatureGeometricType.Curve; else gt = FeatureGeometricType.Curve; } break; case "surface": { if (gt.HasValue) gt = gt.Value | FeatureGeometricType.Surface; else gt = FeatureGeometricType.Surface; } break; case "solid": { if (gt.HasValue) gt = gt.Value | FeatureGeometricType.Solid; else gt = FeatureGeometricType.Solid; } break; } } if (gt.HasValue) return gt.Value; else throw new ArgumentException(); } /// /// Gets the expression data type /// public override OSGeo.MapGuide.ObjectModels.Common.ExpressionDataType ExpressionType { get { return OSGeo.MapGuide.ObjectModels.Common.ExpressionDataType.Geometry; } } } }