public void SpecificGeometryTypesTest() { var prop = new GeometricPropertyDefinition("Foo", "Bar"); Assert.AreEqual("Foo", prop.Name); Assert.AreEqual("Bar", prop.Description); Assert.AreEqual(0, prop.SpecificGeometryTypes.Length); Assert.True(String.IsNullOrEmpty(prop.SpatialContextAssociation)); prop.GeometricTypes = FeatureGeometricType.Curve | FeatureGeometricType.Point; var types = new List <SpecificGeometryType>(prop.SpecificGeometryTypes); Assert.GreaterOrEqual(types.IndexOf(SpecificGeometryType.LineString), 0); Assert.GreaterOrEqual(types.IndexOf(SpecificGeometryType.CurveString), 0); Assert.GreaterOrEqual(types.IndexOf(SpecificGeometryType.MultiCurveString), 0); Assert.GreaterOrEqual(types.IndexOf(SpecificGeometryType.MultiLineString), 0); Assert.GreaterOrEqual(types.IndexOf(SpecificGeometryType.Point), 0); Assert.GreaterOrEqual(types.IndexOf(SpecificGeometryType.MultiPoint), 0); prop.GeometricTypes = FeatureGeometricType.Point; types = new List <SpecificGeometryType>(prop.SpecificGeometryTypes); Assert.Less(types.IndexOf(SpecificGeometryType.LineString), 0); Assert.Less(types.IndexOf(SpecificGeometryType.CurveString), 0); Assert.Less(types.IndexOf(SpecificGeometryType.MultiCurveString), 0); Assert.Less(types.IndexOf(SpecificGeometryType.MultiLineString), 0); Assert.GreaterOrEqual(types.IndexOf(SpecificGeometryType.Point), 0); Assert.GreaterOrEqual(types.IndexOf(SpecificGeometryType.MultiPoint), 0); }
/// <summary> /// Adds the geometric property. /// </summary> /// <param name="geomDef">The geom def.</param> public void AddGeometricProperty(GeometricPropertyDefinition geomDef) { if (geomDef.ReadOnly) { return; } DataGridViewRow row = new DataGridViewRow(); DataGridViewTextBoxCell nameCell = new DataGridViewTextBoxCell(); nameCell.Value = geomDef.Name; nameCell.Tag = geomDef; DataGridViewCell valueCell = new DataGridViewTextBoxCell(); valueCell.ToolTipText = "Enter the FGF or WKB geometry text"; DataGridViewCheckBoxCell ecell = new DataGridViewCheckBoxCell(false); ecell.Value = true; DataGridViewCheckBoxCell ncell = new DataGridViewCheckBoxCell(false); ncell.Value = false; row.Cells.Add(ecell); row.Cells.Add(ncell); row.Cells.Add(nameCell); row.Cells.Add(valueCell); nameCell.ReadOnly = true; grdProperties.Rows.Add(row); }
/// <summary> /// Adds the geometric property. /// </summary> /// <param name="geomDef">The geom def.</param> /// <param name="value">The update value</param> /// <param name="szClassHierarchy">The class name hierarchy.</param> public void AddGeometricProperty(GeometricPropertyDefinition geomDef, string value, String szClassHierarchy) { if (geomDef.ReadOnly) { return; } DataGridViewRow row = new DataGridViewRow(); DataGridViewTextBoxCell nameCell = new DataGridViewTextBoxCell(); if (!String.IsNullOrEmpty(szClassHierarchy)) { nameCell.Value = szClassHierarchy + "."; } nameCell.Value += geomDef.Name; nameCell.Tag = geomDef; DataGridViewCell valueCell = new DataGridViewTextBoxCell(); valueCell.ToolTipText = "Enter the FGF or WKB geometry text"; valueCell.Value = value; row.Cells.Add(nameCell); row.Cells.Add(valueCell); nameCell.ReadOnly = true; grdProperties.Rows.Add(row); }
public void TestCloneProperty() { DataPropertyDefinition dp = new DataPropertyDefinition("Foo", "Bar"); dp.DataType = DataType.DataType_String; dp.DefaultValue = "Whatever"; dp.IsAutoGenerated = false; dp.Length = 45; dp.Nullable = true; dp.ReadOnly = false; PropertyValueConstraintList list = new PropertyValueConstraintList(); list.ConstraintList.Add(new StringValue("A")); list.ConstraintList.Add(new StringValue("B")); list.ConstraintList.Add(new StringValue("C")); dp.ValueConstraint = list; DataPropertyDefinition dp2 = FdoSchemaUtil.CloneProperty(dp) as DataPropertyDefinition; AssertHelper.EqualProperty(dp, dp2); GeometricPropertyDefinition gp = new GeometricPropertyDefinition("Sna", "Fu"); gp.GeometryTypes = (int)(GeometryType.GeometryType_LineString | GeometryType.GeometryType_MultiLineString | GeometryType.GeometryType_Polygon); gp.HasElevation = true; gp.HasMeasure = false; gp.ReadOnly = false; gp.SpatialContextAssociation = "LL84"; GeometricPropertyDefinition gp2 = FdoSchemaUtil.CloneProperty(gp) as GeometricPropertyDefinition; AssertHelper.EqualProperty(gp, gp2); }
public static GeometricPropertyDefinition get_geo_property(string i) { //this will return a geometry property type //geometry property GeometricPropertyDefinition geom = new GeometricPropertyDefinition(); switch (i) { //geometry property - point case "point": GeometricPropertyDefinition geo_point = new GeometricPropertyDefinition("Geometry", "The geometry of the object"); geo_point.GeometryTypes = MgGeometryType.Point; geom = geo_point; break; //geometry property - curve case "curve": GeometricPropertyDefinition geo_curve = new GeometricPropertyDefinition("Geometry", "The geometry of the object"); geo_curve.GeometryTypes = 2; geom = geo_curve; break; //geometry property - surface case "surface": GeometricPropertyDefinition geo_surface = new GeometricPropertyDefinition("Geometry", "The geometry of the object"); geo_surface.GeometryTypes = 4; geom = geo_surface; break; } return(geom); }
/// <summary> /// Executes the operation /// </summary> /// <param name="rows"></param> /// <returns></returns> public override IEnumerable <FdoRow> Execute(IEnumerable <FdoRow> rows) { using (FdoFeatureService service = _conn.CreateFeatureService()) { using (FdoFeatureReader reader = service.SelectFeatures(this.Query)) { ClassDefinition cd = reader.GetClassDefinition(); foreach (PropertyDefinition pd in cd.Properties) { if (pd.PropertyType == PropertyType.PropertyType_RasterProperty) { ignoreProperties.Add(pd.Name); } else if (pd.PropertyType == PropertyType.PropertyType_DataProperty) { DataPropertyDefinition dp = pd as DataPropertyDefinition; if (dp.IsAutoGenerated || dp.ReadOnly) { ignoreProperties.Add(pd.Name); } } else if (pd.PropertyType == PropertyType.PropertyType_GeometricProperty) { GeometricPropertyDefinition gp = pd as GeometricPropertyDefinition; if (gp.ReadOnly) { ignoreProperties.Add(gp.Name); } } } while (reader.ReadNext()) { FdoRow row = null; try { row = CreateRowFromReader(reader); } catch (Exception ex) { if (row != null) { RaiseFailedFeatureProcessed(row, ex); } else { RaiseFailedReadFeature(ex.Message, ex); } } if (row != null) { yield return(row); } } } } }
public void GeometricPropertyDefinitionTest() { var prop = new GeometricPropertyDefinition("Foo", "Bar"); Assert.AreEqual("Foo", prop.Name); Assert.AreEqual("Bar", prop.Description); Assert.AreEqual(0, prop.SpecificGeometryTypes.Length); Assert.True(String.IsNullOrEmpty(prop.SpatialContextAssociation)); }
internal FdoFeatureReader(IFeatureReader reader) : base(reader) { _internalFactory = new FgfGeometryFactory(); _classDefinition = reader.GetClassDefinition(); _ptypes = new Dictionary <string, FdoPropertyType>(); _associations = new Dictionary <string, string>(); _ordinals = new Dictionary <string, int>(); _types = new Type[_classDefinition.Properties.Count]; _names = new string[_classDefinition.Properties.Count]; List <string> geoms = new List <string>(); for (int i = 0; i < _names.Length; i++) { PropertyDefinition pd = _classDefinition.Properties[i]; _names[i] = pd.Name; string name = _names[i]; _ordinals.Add(_names[i], i); DataPropertyDefinition dp = pd as DataPropertyDefinition; GeometricPropertyDefinition gp = pd as GeometricPropertyDefinition; if (dp != null) { _types[i] = ExpressUtility.GetClrTypeFromFdoDataType(dp.DataType); _ptypes[name] = ValueConverter.FromDataType(dp.DataType); } else if (gp != null) { _types[i] = typeof(byte[]); geoms.Add(gp.Name); _ptypes[name] = FdoPropertyType.Geometry; _associations[name] = gp.SpatialContextAssociation; } else if (pd.PropertyType == PropertyType.PropertyType_ObjectProperty) { _ptypes[name] = FdoPropertyType.Object; } else if (pd.PropertyType == PropertyType.PropertyType_RasterProperty) { _ptypes[name] = FdoPropertyType.Raster; _types[i] = typeof(IRaster); } else if (pd.PropertyType == PropertyType.PropertyType_AssociationProperty) { _ptypes[name] = FdoPropertyType.Association; } } _geometryNames = geoms.ToArray(); if (_classDefinition is FeatureClass && (_classDefinition as FeatureClass).GeometryProperty != null) { _defaultGeometryName = (_classDefinition as FeatureClass).GeometryProperty.Name; } else if (geoms.Count > 0) { _defaultGeometryName = geoms[0]; } }
/// <summary> /// Creates a <see cref="ClassDefinition"/> from this instance /// </summary> /// <param name="createAutoGeneratedId">If true, will add an auto-generated id property to this class definition</param> /// <returns>The class definition</returns> public ClassDefinition CreateClassDefinition(bool createAutoGeneratedId) { ClassDefinition cd = null; if (!string.IsNullOrEmpty(this.GeometryColumn)) { FeatureClass fc = new FeatureClass(this.TableName, string.Empty); GeometricPropertyDefinition gp = new GeometricPropertyDefinition(this.GeometryColumn, string.Empty); fc.Properties.Add(gp); fc.GeometryProperty = gp; cd = fc; } else { cd = new Class(this.TableName, string.Empty); } if (createAutoGeneratedId) { int num = 1; string name = "AutoID"; string genName = name + num; string theName = string.Empty; if (this.Columns[name] != null) { while (this.Columns[genName] != null) { genName = name + (num++); } theName = genName; } else { theName = name; } DataPropertyDefinition id = new DataPropertyDefinition(theName, string.Empty); id.IsAutoGenerated = true; id.DataType = DataType.DataType_Int32; cd.Properties.Add(id); cd.IdentityProperties.Add(id); } //Now process columns foreach (DataColumn dc in this.Columns) { if (dc.ColumnName != this.GeometryColumn) { DataPropertyDefinition dp = ExpressUtility.GetDataPropertyForColumn(dc); cd.Properties.Add(dp); } } return(cd); }
/// <summary> /// Set the current element's content from the current XML node /// </summary> /// <param name="node"></param> /// <param name="mgr"></param> public void ReadXml(System.Xml.XmlNode node, System.Xml.XmlNamespaceManager mgr) { if (!node.Name.Equals("complexType")) //NOXLATE { throw new Exception(string.Format(Strings.ErrorBadDocumentExpectedElement, "complexType")); } var sn = node.ParentNode.Attributes["name"]; //NOXLATE this.SchemaName = sn.Value; var cn = node.Attributes["name"]; //NOXLATE this.ClassName = Utility.DecodeFDOName(cn.Value.Substring(0, cn.Value.Length - "Type".Length)); //NOXLATE var cls = this.Parent.GetClass(this.SchemaName, this.ClassName); if (!string.IsNullOrEmpty(cls.DefaultGeometryPropertyName)) { GeometricPropertyDefinition geom = (GeometricPropertyDefinition)cls.FindProperty(cls.DefaultGeometryPropertyName); this.SpatialContextName = geom.SpatialContextAssociation; } var table = node["Table"]; //NOXLATE var el = table.NextSibling; //foreach (System.Xml.XmlNode el in table.ChildNodes) while (el != null) { var colName = el.Attributes["name"]; //NOXLATE if (colName.Value == cls.DefaultGeometryPropertyName) { var x = el.Attributes["xColumnName"]; //NOXLATE var y = el.Attributes["yColumnName"]; //NOXLATE var z = el.Attributes["zColumnName"]; //NOXLATE if (x != null) { this.XColumn = x.Value; } if (y != null) { this.YColumn = y.Value; } if (z != null) { this.ZColumn = z.Value; } } el = el.NextSibling; } }
private static ContextMenuStrip BuildSelectedPropertyContextMenu(ClassDefinition cd, EventHandler mapHandler, EventHandler removeMappingHandler, EventHandler autoCreateHandler) { ContextMenuStrip ctxSelectedProperty = new ContextMenuStrip(); ctxSelectedProperty.Items.Add("Remove Mapping", ResourceService.GetBitmap("cross"), removeMappingHandler); ctxSelectedProperty.Items.Add(new ToolStripSeparator()); ctxSelectedProperty.Items.Add("Map to property of same name (create if necessary)", null, autoCreateHandler); ctxSelectedProperty.Items.Add(new ToolStripSeparator()); SortedList <string, ToolStripMenuItem> items = new SortedList <string, ToolStripMenuItem>(); if (cd != null) { foreach (PropertyDefinition p in cd.Properties) { if (p.PropertyType == PropertyType.PropertyType_DataProperty || p.PropertyType == PropertyType.PropertyType_GeometricProperty) { DataPropertyDefinition d = p as DataPropertyDefinition; GeometricPropertyDefinition g = p as GeometricPropertyDefinition; string name = p.Name; string text = "Map to property: " + name; Image icon = null; if (d != null) { if (d.IsAutoGenerated || d.ReadOnly) { continue; } icon = ResourceService.GetBitmap("table"); } else if (g != null) { if (g.ReadOnly) { continue; } icon = ResourceService.GetBitmap("shape_handles"); } ToolStripMenuItem itm1 = new ToolStripMenuItem(text, icon, mapHandler); itm1.Tag = name; items.Add(name, itm1); } } } foreach (ToolStripMenuItem item in items.Values) { ctxSelectedProperty.Items.Add(item); } return(ctxSelectedProperty); }
public void TestSchemaCannotBeApplied() { FeatureSchema schema = new FeatureSchema("Default", ""); FeatureClass fc = new FeatureClass("Class1", ""); DataPropertyDefinition id = new DataPropertyDefinition("ID", ""); id.DataType = DataType.DataType_Int32; id.IsAutoGenerated = true; fc.Properties.Add(id); fc.IdentityProperties.Add(id); //Unsupported property in SHP DataPropertyDefinition d1 = new DataPropertyDefinition("Unsupported", ""); d1.DataType = DataType.DataType_Int64; d1.Nullable = true; fc.Properties.Add(d1); GeometricPropertyDefinition geom = new GeometricPropertyDefinition("Geometry", ""); geom.GeometryTypes = (int)GeometryType.GeometryType_Point; fc.Properties.Add(geom); schema.Classes.Add(fc); /* * IConnection conn = FeatureAccessManager.GetConnectionManager().CreateConnection("OSGeo.SHP"); * conn.ConnectionString = "DefaultFileLocation=" + AppGateway.RunningApplication.AppPath; * using (conn) * { * conn.Open(); * using (FeatureService service = new FeatureService(conn)) * { * IncompatibleSchema incSchema = null; * bool result = service.CanApplySchema(schema, out incSchema); * Assert.IsNotNull(incSchema); * Assert.IsFalse(result); * * foreach (IncompatibleClass incClass in incSchema.Classes) * { * foreach (IncompatibleProperty incProp in incClass.Properties) * { * Assert.AreEqual(incProp.Reasons.Count, incProp.ReasonCodes.Count); * } * } * } * conn.Close(); * }*/ }
private static GeometricPropertyDefinition ConvertGeometricProperty(MgGeometricPropertyDefinition mgGeom) { var gp = new GeometricPropertyDefinition(mgGeom.Name, mgGeom.Description); gp.GeometricTypes = (FeatureGeometricType)mgGeom.GeometryTypes; gp.HasElevation = mgGeom.HasElevation; gp.HasMeasure = mgGeom.HasMeasure; gp.IsReadOnly = mgGeom.ReadOnly; gp.SpatialContextAssociation = mgGeom.SpatialContextAssociation; return(gp); }
internal void AssignGeometricProperty(string name) { var cls = _fc; if (cls.Properties.Contains(name)) { var p = cls.Properties[name]; if (p.PropertyType == PropertyType.PropertyType_GeometricProperty) { var g = (GeometricPropertyDefinition)p; this.GeometryProperty = g; } } }
public void GeometryTypesToStringTest() { var prop = new GeometricPropertyDefinition("Foo", "Bar"); Assert.AreEqual("Foo", prop.Name); Assert.AreEqual("Bar", prop.Description); Assert.AreEqual(0, prop.SpecificGeometryTypes.Length); Assert.True(String.IsNullOrEmpty(prop.SpatialContextAssociation)); prop.GeometricTypes = FeatureGeometricType.Curve | FeatureGeometricType.Solid; var types = new List <string>(prop.GeometryTypesToString().Split(' ')); Assert.GreaterOrEqual(types.IndexOf("curve"), 0); Assert.GreaterOrEqual(types.IndexOf("solid"), 0); Assert.Less(types.IndexOf("point"), 0); Assert.Less(types.IndexOf("surface"), 0); }
public void GetIndividualGeometricTypesTest() { var prop = new GeometricPropertyDefinition("Foo", "Bar"); Assert.AreEqual("Foo", prop.Name); Assert.AreEqual("Bar", prop.Description); Assert.AreEqual(0, prop.SpecificGeometryTypes.Length); Assert.True(String.IsNullOrEmpty(prop.SpatialContextAssociation)); prop.GeometricTypes = FeatureGeometricType.Curve | FeatureGeometricType.Solid; var types = new List <FeatureGeometricType>(prop.GetIndividualGeometricTypes()); Assert.GreaterOrEqual(types.IndexOf(FeatureGeometricType.Curve), 0); Assert.GreaterOrEqual(types.IndexOf(FeatureGeometricType.Solid), 0); Assert.Less(types.IndexOf(FeatureGeometricType.Point), 0); Assert.Less(types.IndexOf(FeatureGeometricType.Surface), 0); }
public static int SetDefaultSpatialContextAssociation(FeatureSchema fs, string name) { int modified = 0; foreach (ClassDefinition cls in fs.Classes) { foreach (PropertyDefinition prop in cls.Properties) { if (prop.PropertyType == PropertyType.PropertyType_GeometricProperty) { GeometricPropertyDefinition geom = (GeometricPropertyDefinition)prop; if (!geom.SpatialContextAssociation.Equals(name)) { geom.SpatialContextAssociation = name; modified++; } } } } return(modified); }
private void chkGeometry_CheckedChanged(object sender, EventArgs e) { if (!chkGeometry.Checked) { if (_item != null) { //Remove existing geometry property if defined if (!string.IsNullOrEmpty(_item.Class.DefaultGeometryPropertyName)) { var prop = _item.Class.FindProperty(_item.Class.DefaultGeometryPropertyName); if (prop != null) { _item.Class.RemoveProperty(prop); } _item.Class.DefaultGeometryPropertyName = null; } } txtSpatialContext.Text = txtX.Text = txtY.Text = txtZ.Text = string.Empty; } else { if (_item != null) { //Set logical geometry property var prop = new GeometricPropertyDefinition("Geometry", ""); //NOXLATE prop.GeometricTypes = FeatureGeometricType.Point; prop.HasElevation = true; prop.HasMeasure = true; _item.Class.AddProperty(prop); _item.Class.DefaultGeometryPropertyName = prop.Name; if (_scNames.Length > 0) { txtSpatialContext.Text = _scNames[0]; } } } }
/// <summary> /// Initializes this instance /// </summary> /// <param name="pipelineExecuter"></param> public override void PrepareForExecution(IPipelineExecuter pipelineExecuter) { //Omit read-only properties using (FdoFeatureService service = _conn.CreateFeatureService()) { ClassDefinition c = service.GetClassByName(this.ClassName); foreach (PropertyDefinition p in c.Properties) { string name = p.Name; if (p.PropertyType != PropertyType.PropertyType_DataProperty && p.PropertyType != PropertyType.PropertyType_GeometricProperty) { _unWritableProperties.Add(name); } else { if (p.PropertyType == PropertyType.PropertyType_GeometricProperty) { GeometricPropertyDefinition g = p as GeometricPropertyDefinition; if (g.ReadOnly) { _unWritableProperties.Add(name); } } else { DataPropertyDefinition d = p as DataPropertyDefinition; if (d.ReadOnly) //|| d.IsAutoGenerated) { _unWritableProperties.Add(name); } } } } c.Dispose(); } base.PrepareForExecution(pipelineExecuter); }
public void TestSchemaCanBeApplied() { FeatureSchema schema = new FeatureSchema("Default", ""); FeatureClass fc = new FeatureClass("Class1", ""); DataPropertyDefinition id = new DataPropertyDefinition("ID", ""); id.DataType = DataType.DataType_Int32; id.IsAutoGenerated = true; fc.Properties.Add(id); fc.IdentityProperties.Add(id); GeometricPropertyDefinition geom = new GeometricPropertyDefinition("Geometry", ""); geom.GeometryTypes = (int)GeometryType.GeometryType_Point; fc.Properties.Add(geom); schema.Classes.Add(fc); /* * IConnection conn = FeatureAccessManager.GetConnectionManager().CreateConnection("OSGeo.SHP"); * conn.ConnectionString = "DefaultFileLocation=" + AppGateway.RunningApplication.AppPath; * using (conn) * { * conn.Open(); * using (FeatureService service = new FeatureService(conn)) * { * IncompatibleSchema incSchema = null; * bool result = service.CanApplySchema(schema, out incSchema); * Assert.IsNull(incSchema); * Assert.IsTrue(result); * } * conn.Close(); * }*/ }
/// <summary> /// Adds the geometric property. /// </summary> /// <param name="geomDef">The geom def.</param> public void AddGeometricProperty(GeometricPropertyDefinition geomDef) { if (geomDef.ReadOnly) return; DataGridViewRow row = new DataGridViewRow(); DataGridViewTextBoxCell nameCell = new DataGridViewTextBoxCell(); nameCell.Value = geomDef.Name; nameCell.Tag = geomDef; DataGridViewCell valueCell = new DataGridViewTextBoxCell(); valueCell.ToolTipText = "Enter the FGF or WKB geometry text"; DataGridViewCheckBoxCell ecell = new DataGridViewCheckBoxCell(false); ecell.Value = true; DataGridViewCheckBoxCell ncell = new DataGridViewCheckBoxCell(false); ncell.Value = false; row.Cells.Add(ecell); row.Cells.Add(ncell); row.Cells.Add(nameCell); row.Cells.Add(valueCell); nameCell.ReadOnly = true; grdProperties.Rows.Add(row); }
public void TestCloneClass() { ClassDefinition c1 = new FeatureClass("Test", "Test Feature Class"); DataPropertyDefinition id = new DataPropertyDefinition("ID", ""); DataPropertyDefinition name = new DataPropertyDefinition("Name", ""); id.DataType = DataType.DataType_Int32; id.IsAutoGenerated = true; id.ReadOnly = true; id.Nullable = false; name.DataType = DataType.DataType_String; name.Length = 255; name.Nullable = true; GeometricPropertyDefinition geom = new GeometricPropertyDefinition("Geometry", ""); geom.GeometryTypes = (int)GeometryType.GeometryType_Polygon; geom.ReadOnly = false; c1.Properties.Add(id); c1.Properties.Add(name); c1.Properties.Add(geom); c1.IdentityProperties.Add(id); ((FeatureClass)c1).GeometryProperty = geom; ClassDefinition cd = FdoSchemaUtil.CloneClass(c1); Assert.IsNotNull(cd); FeatureClass fc = cd as FeatureClass; Assert.IsNotNull(fc); Assert.AreEqual(cd.Name, c1.Name); Assert.AreEqual(cd.ClassType, c1.ClassType); Assert.IsNotNull(fc.GeometryProperty); Assert.IsNotNull(((FeatureClass)c1).GeometryProperty); Assert.AreEqual(fc.GeometryProperty.Name, ((FeatureClass)c1).GeometryProperty.Name); Assert.AreEqual(cd.Description, c1.Description); Assert.AreEqual(cd.Properties.Count, c1.Properties.Count); Assert.AreEqual(cd.IdentityProperties.Count, c1.IdentityProperties.Count); c1.Dispose(); c1 = new Class("TestClass", "Test Class"); id = new DataPropertyDefinition("ID", ""); name = new DataPropertyDefinition("Name", ""); id.DataType = DataType.DataType_Int32; id.IsAutoGenerated = true; id.ReadOnly = true; id.Nullable = false; name.DataType = DataType.DataType_String; name.Length = 255; name.Nullable = true; cd = FdoSchemaUtil.CloneClass(c1); Assert.IsNotNull(cd); Assert.AreEqual(cd.Name, c1.Name); Assert.AreEqual(cd.Description, c1.Description); Assert.AreEqual(cd.Properties.Count, c1.Properties.Count); Assert.AreEqual(cd.IdentityProperties.Count, c1.IdentityProperties.Count); }
internal void AddProperty(PropertyType type) { TreeNode node = _view.schemaTree.SelectedNode; if (node.Level == LEVEL_CLASS) { if (type == PropertyType.PropertyType_AssociationProperty || type == PropertyType.PropertyType_ObjectProperty) { var sn = node.Parent; if (sn.Nodes.Count == 1) //The selected class is the only one { MessageService.ShowError("No other class definitions exist in the current schema"); return; } } string schema = node.Parent.Name; string clsName = node.Name; string prefix = "Property"; switch (type) { case PropertyType.PropertyType_AssociationProperty: prefix = "AssociationProperty"; break; case PropertyType.PropertyType_DataProperty: prefix = "DataProperty"; break; case PropertyType.PropertyType_GeometricProperty: prefix = "GeometricProperty"; break; case PropertyType.PropertyType_ObjectProperty: prefix = "ObjectProperty"; break; case PropertyType.PropertyType_RasterProperty: prefix = "RasterProperty"; break; } string name = _context.GenerateName(prefix); while (_context.PropertyNameExists(schema, clsName, name)) { name = _context.GenerateName(prefix); } PropertyDefinition pd = null; switch (type) { case PropertyType.PropertyType_AssociationProperty: pd = new AssociationPropertyDefinition(name, ""); break; case PropertyType.PropertyType_DataProperty: var dp = new DataPropertyDefinition(name, ""); if (dp.DataType == DataType.DataType_String) { dp.Length = 255; } pd = dp; break; case PropertyType.PropertyType_GeometricProperty: pd = new GeometricPropertyDefinition(name, ""); break; case PropertyType.PropertyType_ObjectProperty: pd = new ObjectPropertyDefinition(name, ""); break; case PropertyType.PropertyType_RasterProperty: break; } if (pd != null) { _context.AddProperty(schema, clsName, pd); } } }
internal static PropertyDefinition CreatePropertyFromExpressionType(string exprText, ClassDefinition clsDef, FunctionDefinitionCollection functionDefs, string defaultSpatialContextName) { string name = string.Empty; using (var expr = Expression.Parse(exprText)) { var et = expr.GetType(); if (typeof(ComputedIdentifier).IsAssignableFrom(et)) { var subExpr = ((ComputedIdentifier)expr).Expression; return CreatePropertyFromExpressionType(subExpr.ToString(), clsDef, functionDefs, defaultSpatialContextName); } else if (typeof(Identifier).IsAssignableFrom(et)) { var id = (Identifier)expr; return CloneProperty(clsDef.Properties[id.Name]); } else if (typeof(Function).IsAssignableFrom(et)) { var func = (Function)expr; if (functionDefs != null) { var fidx = functionDefs.IndexOf(func.Name); if (fidx >= 0) { var funcDef = functionDefs[fidx]; switch (funcDef.ReturnPropertyType) { case PropertyType.PropertyType_DataProperty: { var dp = new DataPropertyDefinition(name, ""); dp.DataType = funcDef.ReturnType; dp.Nullable = true; if (dp.DataType == DataType.DataType_String) dp.Length = 255; return dp; } break; case PropertyType.PropertyType_GeometricProperty: { var geom = new GeometricPropertyDefinition(name, ""); geom.SpatialContextAssociation = defaultSpatialContextName; geom.GeometryTypes = (int)GeometricType.GeometricType_All; return geom; } break; } } } } else if (typeof(BinaryExpression).IsAssignableFrom(et)) { var dp = new DataPropertyDefinition(name, ""); dp.DataType = DataType.DataType_Boolean; dp.Nullable = true; return dp; } else if (typeof(DataValue).IsAssignableFrom(et)) { var dv = (DataValue)expr; var dp = new DataPropertyDefinition(name, ""); dp.DataType = dv.DataType; if (dp.DataType == DataType.DataType_String) dp.Length = 255; dp.Nullable = true; return dp; } else if (typeof(GeometryValue).IsAssignableFrom(et)) { var geom = new GeometricPropertyDefinition(name, ""); geom.GeometryTypes = (int)GeometricType.GeometricType_All; return geom; } } return null; }
void RunExport(string fileName) { CadastralMapModel mapModel = CadastralMapModel.Current; using (ICreateDataStore cmd = m_Connection.CreateCommand(CommandType.CommandType_CreateDataStore) as ICreateDataStore) { try { cmd.DataStoreProperties.SetProperty("File", fileName); cmd.Execute(); } catch (OSGeo.FDO.Common.Exception ex) { Console.WriteLine(ex.Message); } } // The connection after the created is ConnectionState_Closed, so open it! m_Connection.ConnectionInfo.ConnectionProperties.SetProperty("File", fileName); m_Connection.Open(); // Define coordinate system using (ICreateSpatialContext cmd = m_Connection.CreateCommand(CommandType.CommandType_CreateSpatialContext) as ICreateSpatialContext) { ISpatialSystem ss = mapModel.SpatialSystem; cmd.CoordinateSystem = ss.Name; // CSMap key name cmd.ExtentType = SpatialContextExtentType.SpatialContextExtentType_Static; IWindow mapExtent = mapModel.Extent; IDirectPosition minxy = m_Factory.CreatePositionXY(mapExtent.Min.X, mapExtent.Min.Y); IDirectPosition maxxy = m_Factory.CreatePositionXY(mapExtent.Max.X, mapExtent.Max.Y); IEnvelope extent = m_Factory.CreateEnvelope(minxy, maxxy); IGeometry gx = m_Factory.CreateGeometry(extent); cmd.Extent = m_Factory.GetFgf(gx); cmd.XYTolerance = 0.000001; // resolution? cmd.CoordinateSystemWkt = EditingController.Current.GetCoordinateSystemText(); cmd.Execute(); } // Define feature schema FeatureSchema fs = new FeatureSchema("Steve", "This is a test"); FeatureClass fc = new FeatureClass("FC", "Test feature class"); fs.Classes.Add(fc); GeometricPropertyDefinition gp = new GeometricPropertyDefinition("Geometry", "Polygon property"); // When you stick more than one geometric type into the output, you can't // convert to SHP (not with FDO Toolbox anyway). //gp.GeometryTypes = (int)GeometricType.GeometricType_Surface; gp.GeometryTypes = (int)GeometricType.GeometricType_All; fc.Properties.Add(gp); fc.GeometryProperty = gp; // c.f. FdoToolbox ExpressUtility DataPropertyDefinition dp = new DataPropertyDefinition("ID", "Test ID"); dp.DataType = DataType.DataType_Int32; dp.Nullable = false; dp.ReadOnly = true; dp.IsAutoGenerated = true; fc.Properties.Add(dp); // Feature class requires an identity column for the insert fc.IdentityProperties.Add(dp); using (IApplySchema cmd = m_Connection.CreateCommand(CommandType.CommandType_ApplySchema) as IApplySchema) { cmd.FeatureSchema = fs; cmd.Execute(); } mapModel.Index.QueryWindow(null, SpatialType.Polygon | SpatialType.Point, ExportFeature); m_Connection.Flush(); m_Connection.Close(); }
internal void AddProperty(PropertyType type) { TreeNode node = _view.schemaTree.SelectedNode; if (node.Level == LEVEL_CLASS) { if (type == PropertyType.PropertyType_AssociationProperty || type == PropertyType.PropertyType_ObjectProperty) { var sn = node.Parent; if (sn.Nodes.Count == 1) //The selected class is the only one { MessageService.ShowError("No other class definitions exist in the current schema"); return; } } string schema = node.Parent.Name; string clsName = node.Name; string prefix = "Property"; switch (type) { case PropertyType.PropertyType_AssociationProperty: prefix = "AssociationProperty"; break; case PropertyType.PropertyType_DataProperty: prefix = "DataProperty"; break; case PropertyType.PropertyType_GeometricProperty: prefix = "GeometricProperty"; break; case PropertyType.PropertyType_ObjectProperty: prefix = "ObjectProperty"; break; case PropertyType.PropertyType_RasterProperty: prefix = "RasterProperty"; break; } string name = _context.GenerateName(prefix); while (_context.PropertyNameExists(schema, clsName, name)) { name = _context.GenerateName(prefix); } PropertyDefinition pd = null; switch (type) { case PropertyType.PropertyType_AssociationProperty: pd = new AssociationPropertyDefinition(name, ""); break; case PropertyType.PropertyType_DataProperty: var dp = new DataPropertyDefinition(name, ""); if (dp.DataType == DataType.DataType_String) dp.Length = 255; pd = dp; break; case PropertyType.PropertyType_GeometricProperty: pd = new GeometricPropertyDefinition(name, ""); break; case PropertyType.PropertyType_ObjectProperty: pd = new ObjectPropertyDefinition(name, ""); break; case PropertyType.PropertyType_RasterProperty: break; } if (pd != null) _context.AddProperty(schema, clsName, pd); } }
private void WriteGeometricProperty(GeometricPropertyDefinition geom) { Console.WriteLine("\tHas Elevation: {0}\n\tHas Measure: {1}\n\tRead-Only: {2}", geom.HasElevation, geom.HasMeasure, geom.ReadOnly); Console.WriteLine("\tGeometry Types: \n\t\t- {0}", GetGeometryTypes(geom.GeometryTypes)); Console.WriteLine("\tSpatial Context Association: {0}", geom.SpatialContextAssociation); }
private void AddSpatialContextsToCreate(bool targetSupportsMultipleSpatialContexts, List <SpatialContextInfo> targetSpatialContexts, List <SpatialContextInfo> sourceSpatialContexts, List <SpatialContextInfo> createScs, GeometricPropertyDefinition geom) { if (targetSupportsMultipleSpatialContexts) { // NOTE: // // There's a defect in the PostgreSQL provider regarding spatial context creation. // - WKT is disregarded // - Extents are disregarded when creating // // What this means is that when the PostgreSQL provider is the target connection, multiple // copies of the same spatial context will be created because the WKT comparison check will fail // because of the above point. if (!string.IsNullOrEmpty(geom.SpatialContextAssociation)) { //See if the source spatial context has a matching target (by name) SpatialContextInfo matchingTargetSc = FindMatchingSpatialContextByName(targetSpatialContexts, geom.SpatialContextAssociation); if (matchingTargetSc == null) { //The source spatial context name doesn't exist in target //We are free to create a copy of the source one as target supports multiple SCs SpatialContextInfo sourceSc = FindMatchingSpatialContextByName(sourceSpatialContexts, geom.SpatialContextAssociation); if (sourceSc != null) { Info("Adding source spatial context (" + sourceSc.Name + ") to list to be copied to target"); var sc = sourceSc.Clone(); //Add to list of ones to create createScs.Add(sc); //So that subsequent travels along this code path take into account //spatial context we will create as well targetSpatialContexts.Add(sc); } else { /* UNCOMMON CODE PATH. WE'RE WORKING WITH SOME MESSED UP DATA IF WE GET HERE */ //We have a source geom property with an invalid spatial context association reference //So which SC should we assign? SpatialContextInfo sc = null; if (targetSpatialContexts.Count > 0) { //Try first active SC on target sc = FindFirstActiveSpatialContext(targetSpatialContexts); //Otherwise first one on target if (sc == null) { sc = targetSpatialContexts[0]; } if (sc != null) { //Update reference only. No need to create geom.SpatialContextAssociation = sc.Name; return; } } if (sourceSpatialContexts.Count > 0) { //Try first active SC on source sc = FindFirstActiveSpatialContext(sourceSpatialContexts); //Otherwise first one on target if (sc == null) { sc = sourceSpatialContexts[0]; } //Still nothing???? if (sc == null) { throw new Exception("Could not find a suitable replacement spatial context for geometry property" + geom.Name); } sc = sc.Clone(); // string prefix = "SC" + geom.Name; string name = prefix; while (SpatialContextExistsByName(targetSpatialContexts, name)) { _counter++; name = prefix + _counter; } sc.Name = name; //Add to list of ones to create createScs.Add(sc); //So that subsequent travels along this code path take into account //spatial context we will create as well targetSpatialContexts.Add(sc); //Update reference to point to this sc we will create geom.SpatialContextAssociation = sc.Name; } } } else //There is a matching target spatial context of the same name { //Compare target spatial context with source spatial context SpatialContextInfo sourceSc = FindMatchingSpatialContextByName(sourceSpatialContexts, geom.SpatialContextAssociation); if (sourceSc != null) { //Compare WKTs if (!sourceSc.CoordinateSystemWkt.Equals(matchingTargetSc.CoordinateSystemWkt)) { //WKTs do not match. Create a clone of the source but with a different name var sc = sourceSc.Clone(); // string prefix = "SC" + geom.SpatialContextAssociation; string name = prefix; while (SpatialContextExistsByName(targetSpatialContexts, name)) { _counter++; name = prefix + _counter; } sc.Name = name; //Add to list of ones to create createScs.Add(sc); //So that subsequent travels along this code path take into account //spatial context we will create as well targetSpatialContexts.Add(sc); //Update reference to point to this sc we will create geom.SpatialContextAssociation = sc.Name; } //Otherwise matches both in name and WKT. Nothing needs to be done } else //No source spatial context to compare with { /* UNCOMMON CODE PATH. WE'RE WORKING WITH SOME MESSED UP DATA IF WE GET HERE */ //We have a source geom property with an invalid spatial context association reference //So which SC should we assign? geom.SpatialContextAssociation = matchingTargetSc.Name; } } } else { /* UNCOMMON CODE PATH. WE'RE WORKING WITH SOME MESSED UP DATA IF WE GET HERE */ //No spatial context association found on the cloned geometry property we created //Which SC should we assign? SpatialContextInfo sc = null; if (targetSpatialContexts.Count > 0) { //Try first active SC on target sc = FindFirstActiveSpatialContext(targetSpatialContexts); //Otherwise first one on target if (sc == null) { sc = targetSpatialContexts[0]; } //Still nothing???? if (sc != null) { //Update reference only. No need to create geom.SpatialContextAssociation = sc.Name; return; } } if (sourceSpatialContexts.Count > 0) { //Try first active SC on source sc = FindFirstActiveSpatialContext(sourceSpatialContexts); //Otherwise first one on target if (sc == null) { sc = sourceSpatialContexts[0]; } //Still nothing???? if (sc == null) { throw new Exception("Could not find a suitable replacement spatial context for geometry property" + geom.Name); } sc = sc.Clone(); // string prefix = "SC" + geom.Name; string name = prefix; int scc = 0; while (SpatialContextExistsByName(targetSpatialContexts, name)) { _counter++; name = prefix + scc; } sc.Name = name; //Add to list of ones to create createScs.Add(sc); //So that subsequent travels along this code path take into account //spatial context we will create as well targetSpatialContexts.Add(sc); //Update reference to point to this sc we will create geom.SpatialContextAssociation = sc.Name; } } } else //Only supports one spatial context { System.Diagnostics.Debug.Assert(targetSpatialContexts.Count <= 1); if (targetSpatialContexts.Count == 1) { //Coerce to the target spatial context. We can't do anything else geom.SpatialContextAssociation = targetSpatialContexts[0].Name; } else { //We can create one, but only one! SpatialContextInfo sourceSc = FindMatchingSpatialContextByName(sourceSpatialContexts, geom.SpatialContextAssociation); if (sourceSc != null) { //You're it! var sc = sourceSc.Clone(); createScs.Add(sc); geom.SpatialContextAssociation = sc.Name; } else { /* UNCOMMON CODE PATH. WE'RE WORKING WITH SOME MESSED UP DATA IF WE GET HERE */ //No spatial contexts on target and the source reference points to //nowhere! Now what? if (sourceSpatialContexts.Count == 0) { throw new Exception("Could not find source spatial context with name " + geom.SpatialContextAssociation + " and target has no spatial context"); } //Try first active source spatial context sourceSc = FindFirstActiveSpatialContext(sourceSpatialContexts); //Last resort. First known source spatial context if (sourceSc == null) { sourceSc = sourceSpatialContexts[0]; } var sc = sourceSc.Clone(); createScs.Add(sc); geom.SpatialContextAssociation = sc.Name; } } } }
public void TestSchemaCanBeApplied() { FeatureSchema schema = new FeatureSchema("Default", ""); FeatureClass fc = new FeatureClass("Class1", ""); DataPropertyDefinition id = new DataPropertyDefinition("ID", ""); id.DataType = DataType.DataType_Int32; id.IsAutoGenerated = true; fc.Properties.Add(id); fc.IdentityProperties.Add(id); GeometricPropertyDefinition geom = new GeometricPropertyDefinition("Geometry", ""); geom.GeometryTypes = (int)GeometryType.GeometryType_Point; fc.Properties.Add(geom); schema.Classes.Add(fc); /* IConnection conn = FeatureAccessManager.GetConnectionManager().CreateConnection("OSGeo.SHP"); conn.ConnectionString = "DefaultFileLocation=" + AppGateway.RunningApplication.AppPath; using (conn) { conn.Open(); using (FeatureService service = new FeatureService(conn)) { IncompatibleSchema incSchema = null; bool result = service.CanApplySchema(schema, out incSchema); Assert.IsNull(incSchema); Assert.IsTrue(result); } conn.Close(); }*/ }
/// <summary> /// Adds the geometric property. /// </summary> /// <param name="geomDef">The geom def.</param> /// <param name="value">The update value</param> public void AddGeometricProperty(GeometricPropertyDefinition geomDef, string value) { AddGeometricProperty(geomDef, value, null); }
/// <summary> /// Creates a <see cref="ClassDefinition"/> from this instance /// </summary> /// <param name="createAutoGeneratedId">If true, will add an auto-generated id property to this class definition</param> /// <returns>The class definition</returns> public ClassDefinition CreateClassDefinition(bool createAutoGeneratedId) { ClassDefinition cd = null; if (!string.IsNullOrEmpty(this.GeometryColumn)) { FeatureClass fc = new FeatureClass(this.TableName, string.Empty); GeometricPropertyDefinition gp = new GeometricPropertyDefinition(this.GeometryColumn, string.Empty); fc.Properties.Add(gp); fc.GeometryProperty = gp; cd = fc; } else { cd = new Class(this.TableName, string.Empty); } if (createAutoGeneratedId) { int num = 1; string name = "AutoID"; string genName = name + num; string theName = string.Empty; if (this.Columns[name] != null) { while (this.Columns[genName] != null) { genName = name + (num++); } theName = genName; } else { theName = name; } DataPropertyDefinition id = new DataPropertyDefinition(theName, string.Empty); id.IsAutoGenerated = true; id.DataType = DataType.DataType_Int32; cd.Properties.Add(id); cd.IdentityProperties.Add(id); } //Now process columns foreach (DataColumn dc in this.Columns) { if (dc.ColumnName != this.GeometryColumn) { DataPropertyDefinition dp = ExpressUtility.GetDataPropertyForColumn(dc); cd.Properties.Add(dp); } } return cd; }
/// <summary> /// Adds the geometric property. /// </summary> /// <param name="geomDef">The geom def.</param> /// <param name="szClassHierarchy">The class name hierarchy.</param> public void AddGeometricProperty(GeometricPropertyDefinition geomDef, String szClassHierarchy) { if (geomDef.ReadOnly) return; DataGridViewRow row = new DataGridViewRow(); DataGridViewTextBoxCell nameCell = new DataGridViewTextBoxCell(); if (!String.IsNullOrEmpty(szClassHierarchy)) nameCell.Value = szClassHierarchy + ":"; nameCell.Value += geomDef.Name; nameCell.Tag = geomDef; DataGridViewCell valueCell = new DataGridViewTextBoxCell(); valueCell.ToolTipText = "Enter the FGF or WKB geometry text"; row.Cells.Add(nameCell); row.Cells.Add(valueCell); nameCell.ReadOnly = true; grdProperties.Rows.Add(row); }
private void AddSpatialContextsToCreate(bool targetSupportsMultipleSpatialContexts, List<SpatialContextInfo> targetSpatialContexts, List<SpatialContextInfo> sourceSpatialContexts, List<SpatialContextInfo> createScs, GeometricPropertyDefinition geom) { if (targetSupportsMultipleSpatialContexts) { // NOTE: // // There's a defect in the PostgreSQL provider regarding spatial context creation. // - WKT is disregarded // - Extents are disregarded when creating // // What this means is that when the PostgreSQL provider is the target connection, multiple // copies of the same spatial context will be created because the WKT comparison check will fail // because of the above point. if (!string.IsNullOrEmpty(geom.SpatialContextAssociation)) { //See if the source spatial context has a matching target (by name) SpatialContextInfo matchingTargetSc = FindMatchingSpatialContextByName(targetSpatialContexts, geom.SpatialContextAssociation); if (matchingTargetSc == null) { //The source spatial context name doesn't exist in target //We are free to create a copy of the source one as target supports multiple SCs SpatialContextInfo sourceSc = FindMatchingSpatialContextByName(sourceSpatialContexts, geom.SpatialContextAssociation); if (sourceSc != null) { Info("Adding source spatial context (" + sourceSc.Name + ") to list to be copied to target"); var sc = sourceSc.Clone(); //Add to list of ones to create createScs.Add(sc); //So that subsequent travels along this code path take into account //spatial context we will create as well targetSpatialContexts.Add(sc); } else { /* UNCOMMON CODE PATH. WE'RE WORKING WITH SOME MESSED UP DATA IF WE GET HERE */ //We have a source geom property with an invalid spatial context association reference //So which SC should we assign? SpatialContextInfo sc = null; if (targetSpatialContexts.Count > 0) { //Try first active SC on target sc = FindFirstActiveSpatialContext(targetSpatialContexts); //Otherwise first one on target if (sc == null) sc = targetSpatialContexts[0]; if (sc != null) { //Update reference only. No need to create geom.SpatialContextAssociation = sc.Name; return; } } if (sourceSpatialContexts.Count > 0) { //Try first active SC on source sc = FindFirstActiveSpatialContext(sourceSpatialContexts); //Otherwise first one on target if (sc == null) sc = sourceSpatialContexts[0]; //Still nothing???? if (sc == null) throw new Exception("Could not find a suitable replacement spatial context for geometry property" + geom.Name); sc = sc.Clone(); // string prefix = "SC" + geom.Name; string name = prefix; while (SpatialContextExistsByName(targetSpatialContexts, name)) { _counter++; name = prefix + _counter; } sc.Name = name; //Add to list of ones to create createScs.Add(sc); //So that subsequent travels along this code path take into account //spatial context we will create as well targetSpatialContexts.Add(sc); //Update reference to point to this sc we will create geom.SpatialContextAssociation = sc.Name; } } } else //There is a matching target spatial context of the same name { //Compare target spatial context with source spatial context SpatialContextInfo sourceSc = FindMatchingSpatialContextByName(sourceSpatialContexts, geom.SpatialContextAssociation); if (sourceSc != null) { //Compare WKTs if (!sourceSc.CoordinateSystemWkt.Equals(matchingTargetSc.CoordinateSystemWkt)) { //WKTs do not match. Create a clone of the source but with a different name var sc = sourceSc.Clone(); // string prefix = "SC" + geom.SpatialContextAssociation; string name = prefix; while (SpatialContextExistsByName(targetSpatialContexts, name)) { _counter++; name = prefix + _counter; } sc.Name = name; //Add to list of ones to create createScs.Add(sc); //So that subsequent travels along this code path take into account //spatial context we will create as well targetSpatialContexts.Add(sc); //Update reference to point to this sc we will create geom.SpatialContextAssociation = sc.Name; } //Otherwise matches both in name and WKT. Nothing needs to be done } else //No source spatial context to compare with { /* UNCOMMON CODE PATH. WE'RE WORKING WITH SOME MESSED UP DATA IF WE GET HERE */ //We have a source geom property with an invalid spatial context association reference //So which SC should we assign? geom.SpatialContextAssociation = matchingTargetSc.Name; } } } else { /* UNCOMMON CODE PATH. WE'RE WORKING WITH SOME MESSED UP DATA IF WE GET HERE */ //No spatial context association found on the cloned geometry property we created //Which SC should we assign? SpatialContextInfo sc = null; if (targetSpatialContexts.Count > 0) { //Try first active SC on target sc = FindFirstActiveSpatialContext(targetSpatialContexts); //Otherwise first one on target if (sc == null) sc = targetSpatialContexts[0]; //Still nothing???? if (sc != null) { //Update reference only. No need to create geom.SpatialContextAssociation = sc.Name; return; } } if (sourceSpatialContexts.Count > 0) { //Try first active SC on source sc = FindFirstActiveSpatialContext(sourceSpatialContexts); //Otherwise first one on target if (sc == null) sc = sourceSpatialContexts[0]; //Still nothing???? if (sc == null) throw new Exception("Could not find a suitable replacement spatial context for geometry property" + geom.Name); sc = sc.Clone(); // string prefix = "SC" + geom.Name; string name = prefix; int scc = 0; while (SpatialContextExistsByName(targetSpatialContexts, name)) { _counter++; name = prefix + scc; } sc.Name = name; //Add to list of ones to create createScs.Add(sc); //So that subsequent travels along this code path take into account //spatial context we will create as well targetSpatialContexts.Add(sc); //Update reference to point to this sc we will create geom.SpatialContextAssociation = sc.Name; } } } else //Only supports one spatial context { System.Diagnostics.Debug.Assert(targetSpatialContexts.Count <= 1); if (targetSpatialContexts.Count == 1) { //Coerce to the target spatial context. We can't do anything else geom.SpatialContextAssociation = targetSpatialContexts[0].Name; } else { //We can create one, but only one! SpatialContextInfo sourceSc = FindMatchingSpatialContextByName(sourceSpatialContexts, geom.SpatialContextAssociation); if (sourceSc != null) { //You're it! var sc = sourceSc.Clone(); createScs.Add(sc); geom.SpatialContextAssociation = sc.Name; } else { /* UNCOMMON CODE PATH. WE'RE WORKING WITH SOME MESSED UP DATA IF WE GET HERE */ //No spatial contexts on target and the source reference points to //nowhere! Now what? if (sourceSpatialContexts.Count == 0) throw new Exception("Could not find source spatial context with name " + geom.SpatialContextAssociation + " and target has no spatial context"); //Try first active source spatial context sourceSc = FindFirstActiveSpatialContext(sourceSpatialContexts); //Last resort. First known source spatial context if (sourceSc == null) sourceSc = sourceSpatialContexts[0]; var sc = sourceSc.Clone(); createScs.Add(sc); geom.SpatialContextAssociation = sc.Name; } } } }
/// <summary> /// Adds the geometric property. /// </summary> /// <param name="geomDef">The geom def.</param> public void AddGeometricProperty(GeometricPropertyDefinition geomDef) { AddGeometricProperty(geomDef, null); }
internal static PropertyDefinition CreatePropertyFromExpressionType(string exprText, ClassDefinition clsDef, FunctionDefinitionCollection functionDefs, string defaultSpatialContextName) { string name = string.Empty; using (var expr = Expression.Parse(exprText)) { var et = expr.GetType(); if (typeof(ComputedIdentifier).IsAssignableFrom(et)) { var subExpr = ((ComputedIdentifier)expr).Expression; return(CreatePropertyFromExpressionType(subExpr.ToString(), clsDef, functionDefs, defaultSpatialContextName)); } else if (typeof(Identifier).IsAssignableFrom(et)) { var id = (Identifier)expr; return(CloneProperty(clsDef.Properties[id.Name])); } else if (typeof(Function).IsAssignableFrom(et)) { var func = (Function)expr; if (functionDefs != null) { var fidx = functionDefs.IndexOf(func.Name); if (fidx >= 0) { var funcDef = functionDefs[fidx]; switch (funcDef.ReturnPropertyType) { case PropertyType.PropertyType_DataProperty: { var dp = new DataPropertyDefinition(name, ""); dp.DataType = funcDef.ReturnType; dp.Nullable = true; if (dp.DataType == DataType.DataType_String) { dp.Length = 255; } return(dp); } break; case PropertyType.PropertyType_GeometricProperty: { var geom = new GeometricPropertyDefinition(name, ""); geom.SpatialContextAssociation = defaultSpatialContextName; geom.GeometryTypes = (int)GeometricType.GeometricType_All; return(geom); } break; } } } } else if (typeof(BinaryExpression).IsAssignableFrom(et)) { var dp = new DataPropertyDefinition(name, ""); dp.DataType = DataType.DataType_Boolean; dp.Nullable = true; return(dp); } else if (typeof(DataValue).IsAssignableFrom(et)) { var dv = (DataValue)expr; var dp = new DataPropertyDefinition(name, ""); dp.DataType = dv.DataType; if (dp.DataType == DataType.DataType_String) { dp.Length = 255; } dp.Nullable = true; return(dp); } else if (typeof(GeometryValue).IsAssignableFrom(et)) { var geom = new GeometricPropertyDefinition(name, ""); geom.GeometryTypes = (int)GeometricType.GeometricType_All; return(geom); } } return(null); }
/// <summary> /// Clones a given property definition /// </summary> /// <param name="pd"></param> /// <returns></returns> public static PropertyDefinition CloneProperty(PropertyDefinition pd) { PropertyDefinition propDef = null; switch (pd.PropertyType) { case PropertyType.PropertyType_DataProperty: { DataPropertyDefinition srcData = pd as DataPropertyDefinition; DataPropertyDefinition dataDef = new DataPropertyDefinition(srcData.Name, srcData.Description); dataDef.DataType = srcData.DataType; dataDef.DefaultValue = srcData.DefaultValue; dataDef.IsAutoGenerated = srcData.IsAutoGenerated; dataDef.IsSystem = srcData.IsSystem; dataDef.Length = srcData.Length; dataDef.Nullable = srcData.Nullable; dataDef.Precision = srcData.Precision; dataDef.ReadOnly = srcData.ReadOnly; //Copy constraints if (srcData.ValueConstraint != null) { if (srcData.ValueConstraint.ConstraintType == PropertyValueConstraintType.PropertyValueConstraintType_Range) { PropertyValueConstraintRange range = (PropertyValueConstraintRange)srcData.ValueConstraint; PropertyValueConstraintRange constraint = new PropertyValueConstraintRange(range.MinValue, range.MaxValue); constraint.MaxInclusive = range.MaxInclusive; constraint.MinInclusive = range.MinInclusive; dataDef.ValueConstraint = constraint; } else if (srcData.ValueConstraint.ConstraintType == PropertyValueConstraintType.PropertyValueConstraintType_List) { PropertyValueConstraintList list = (PropertyValueConstraintList)srcData.ValueConstraint; PropertyValueConstraintList constraint = new PropertyValueConstraintList(); foreach (DataValue dval in list.ConstraintList) { constraint.ConstraintList.Add(dval); } dataDef.ValueConstraint = constraint; } } CopyPropertyAttributes(srcData, dataDef); propDef = dataDef; } break; case PropertyType.PropertyType_GeometricProperty: { GeometricPropertyDefinition srcData = pd as GeometricPropertyDefinition; GeometricPropertyDefinition geomDef = new GeometricPropertyDefinition(srcData.Name, srcData.Description); geomDef.GeometryTypes = srcData.GeometryTypes; geomDef.HasElevation = srcData.HasElevation; geomDef.HasMeasure = srcData.HasMeasure; geomDef.IsSystem = srcData.IsSystem; geomDef.ReadOnly = srcData.ReadOnly; geomDef.SpatialContextAssociation = srcData.SpatialContextAssociation; CopyPropertyAttributes(srcData, geomDef); propDef = geomDef; } break; case PropertyType.PropertyType_RasterProperty: { RasterPropertyDefinition srcData = pd as RasterPropertyDefinition; RasterPropertyDefinition rastDef = new RasterPropertyDefinition(srcData.Name, srcData.Description); if (srcData.DefaultDataModel != null) { rastDef.DefaultDataModel = new OSGeo.FDO.Raster.RasterDataModel(); rastDef.DefaultDataModel.BitsPerPixel = srcData.DefaultDataModel.BitsPerPixel; rastDef.DefaultDataModel.DataModelType = srcData.DefaultDataModel.DataModelType; rastDef.DefaultDataModel.DataType = srcData.DefaultDataModel.DataType; rastDef.DefaultDataModel.Organization = srcData.DefaultDataModel.Organization; rastDef.DefaultDataModel.TileSizeX = srcData.DefaultDataModel.TileSizeX; rastDef.DefaultDataModel.TileSizeY = srcData.DefaultDataModel.TileSizeY; } rastDef.DefaultImageXSize = srcData.DefaultImageXSize; rastDef.DefaultImageYSize = srcData.DefaultImageYSize; rastDef.IsSystem = srcData.IsSystem; rastDef.Nullable = srcData.Nullable; rastDef.ReadOnly = srcData.ReadOnly; rastDef.SpatialContextAssociation = srcData.SpatialContextAssociation; CopyPropertyAttributes(srcData, rastDef); propDef = rastDef; } break; case PropertyType.PropertyType_AssociationProperty: throw new UnsupportedException(Res.GetString("ERR_UNSUPPORTED_CLONE_ASSOCIATION")); case PropertyType.PropertyType_ObjectProperty: throw new UnsupportedException(Res.GetString("ERR_UNSUPPORTED_CLONE_OBJECT")); } return propDef; }
public override void Bind(IEditorService service) { try { _init = true; _edsvc = service; _edsvc.RegisterCustomNotifier(this); var res = service.GetEditedResource() as ILayerDefinition; Debug.Assert(res != null); _vl = res.SubLayer as IVectorLayerDefinition; Debug.Assert(_vl != null); txtFeatureClass.Text = _vl.FeatureName; txtGeometry.Text = _vl.Geometry; ResetErrorState(); if (string.IsNullOrEmpty(txtFeatureClass.Text) || string.IsNullOrEmpty(txtGeometry.Text)) { TryFillUIFromNewFeatureSource(_vl.ResourceId); if (!_edsvc.CurrentConnection.ResourceService.ResourceExists(_vl.ResourceId)) { errorProvider.SetError(txtFeatureSource, Strings.LayerEditorFeatureSourceNotFound); MessageBox.Show(Strings.LayerEditorHasErrors); } } else { bool bShowErrorMessage = false; txtFeatureSource.Text = _vl.ResourceId; string featureClass = txtFeatureClass.Text; string geometry = txtGeometry.Text; BusyWaitDialog.Run(null, () => { var errors = new List <string>(); if (!_edsvc.CurrentConnection.ResourceService.ResourceExists(_vl.ResourceId)) { errors.Add(Strings.LayerEditorFeatureSourceNotFound); } if (!string.IsNullOrEmpty(featureClass)) { ClassDefinition clsDef = null; try { clsDef = _edsvc.CurrentConnection.FeatureService.GetClassDefinition(_vl.ResourceId, featureClass); } catch { errors.Add(Strings.LayerEditorFeatureClassNotFound); //These property mappings will probably be bunk if this is the case, so clear them _vl.ClearPropertyMappings(); } if (clsDef != null) { GeometricPropertyDefinition geom = clsDef.FindProperty(geometry) as GeometricPropertyDefinition; if (geom == null) { errors.Add(Strings.LayerEditorGeometryNotFound); } } else { //This is probably true errors.Add(Strings.LayerEditorGeometryNotFound); } } return(errors); }, (result, ex) => { if (ex != null) { ErrorDialog.Show(ex); } else { var list = (List <string>)result; foreach (var err in list) { if (err == Strings.LayerEditorGeometryNotFound) { errorProvider.SetError(txtGeometry, err); bShowErrorMessage = true; } else if (err == Strings.LayerEditorFeatureSourceNotFound) { errorProvider.SetError(txtFeatureSource, err); //Don't show error message here if this is the only error as the user //will get a repair feature source prompt down the road } else if (err == Strings.LayerEditorFeatureClassNotFound) { errorProvider.SetError(txtFeatureClass, err); bShowErrorMessage = true; } } if (bShowErrorMessage) { MessageBox.Show(Strings.LayerEditorHasErrors); } } }); } txtFilter.Text = _vl.Filter; //Loose bind this one because 2.4 changes this behaviour making it //unsuitable for databinding via TextBoxBinder txtHyperlink.Text = _vl.Url; txtTooltip.Text = _vl.ToolTip; //This is not the root object so no change listeners have been subscribed _vl.PropertyChanged += WeakEventHandler.Wrap <PropertyChangedEventHandler>(OnVectorLayerPropertyChanged, (eh) => _vl.PropertyChanged -= eh); } finally { _init = false; } }
/// <summary> /// Creates a FDO bulk copy task. The target file will be created as part of /// this method call. If the target path is a directory, it is assumed that /// SHP files are to be created and copied to. /// </summary> /// <param name="sourceFile">The path to the source file.</param> /// <param name="targetPath"> /// The path to the target file/directory. If it is a directory, it is assumed /// that SHP files are to be created and copied to. /// </param> /// <param name="copySpatialContexts">If true, will also copy spatial contexts</param> /// <param name="fixIncompatibleSchema">If true, will try to fix the source schema to make it compatible with the target connection. If false, an exception will be thrown</param> /// <param name="flattenGeometries">If true, will strip all Z and M coordinates from all geometries that are copied</param> /// <returns></returns> public static FdoBulkCopy CreateBulkCopy(string sourceFile, string targetPath, bool copySpatialContexts, bool fixIncompatibleSchema, bool flattenGeometries) { FdoBulkCopyOptions options = null; FdoConnection source = null; FdoConnection target = null; try { //Is a directory. Implies a SHP connection if (IsShp(targetPath)) { //SHP doesn't actually support CreateDataStore. We use the following technique: // - Connect to base directory // - Clone source schema and apply to SHP connection. // - A SHP file and related files are created for each feature class. string shpdir = Directory.Exists(targetPath) ? targetPath : Path.GetDirectoryName(targetPath); source = CreateFlatFileConnection(sourceFile); target = new FdoConnection("OSGeo.SHP", "DefaultFileLocation=" + shpdir); source.Open(); //Verify source has only classes with single geometry storage and only one geometry using (FdoFeatureService svc = source.CreateFeatureService()) { using (FeatureSchemaCollection schemas = svc.DescribeSchema()) { foreach (FeatureSchema sch in schemas) { foreach (ClassDefinition cd in sch.Classes) { int geomProps = 0; foreach (PropertyDefinition pd in cd.Properties) { if (pd.PropertyType == PropertyType.PropertyType_GeometricProperty) { GeometricPropertyDefinition gp = pd as GeometricPropertyDefinition; GeometricType[] types = FdoGeometryUtil.GetGeometricTypes(gp.GeometryTypes); if (types.Length != 1 || (types.Length == 1 && types[0] == GeometricType.GeometricType_All)) { throw new FdoETLException(string.Format("Source file cannot be copied to a SHP file. {0}:{1}.{2} has more than one geometry storage type", sch.Name, cd.Name, pd.Name)); } geomProps++; } } if (geomProps > 1) { throw new FdoETLException("Source file cannot be copied to a SHP file. One or more feature classes have more than one geometry property"); } } } } } } else { if (!CreateFlatFileDataSource(targetPath)) { throw new FdoException("Unable to create data source on: " + targetPath); } source = CreateFlatFileConnection(sourceFile); target = CreateFlatFileConnection(targetPath); } //Source and target connections may have been opened before this point if (source.State == FdoConnectionState.Closed) { source.Open(); } if (target.State == FdoConnectionState.Closed) { target.Open(); } string srcName = "SOURCE"; string dstName = "TARGET"; Dictionary <string, FdoConnection> connections = new Dictionary <string, FdoConnection>(); connections.Add(srcName, source); connections.Add(dstName, target); options = new FdoBulkCopyOptions(connections, true); if (copySpatialContexts) { CopyAllSpatialContexts(source, target, true); } using (FdoFeatureService srcService = source.CreateFeatureService()) using (FdoFeatureService destService = target.CreateFeatureService()) { FeatureSchemaCollection schemas = srcService.DescribeSchema(); //Assume single-schema FeatureSchema fs = schemas[0]; //Clone and apply to target FeatureSchema targetSchema = FdoSchemaUtil.CloneSchema(fs); IncompatibleSchema incSchema; string sourceSchemaName = fs.Name; string targetSchemaName = string.Empty; bool canApply = destService.CanApplySchema(targetSchema, out incSchema); if (canApply) { destService.ApplySchema(targetSchema); targetSchemaName = targetSchema.Name; } else { if (fixIncompatibleSchema) { FeatureSchema fixedSchema = destService.AlterSchema(targetSchema, incSchema); destService.ApplySchema(fixedSchema); targetSchemaName = fixedSchema.Name; } else { throw new Exception(incSchema.ToString()); } } //Copy all classes foreach (ClassDefinition cd in fs.Classes) { FdoClassCopyOptions copt = new FdoClassCopyOptions(srcName, dstName, sourceSchemaName, cd.Name, targetSchemaName, cd.Name); copt.Name = "Copy source to target [" + cd.Name + "]"; copt.FlattenGeometries = flattenGeometries; options.AddClassCopyOption(copt); //Flick on batch support if we can if (destService.SupportsBatchInsertion()) { copt.BatchSize = 300; //Madness? THIS IS SPARTA! } } } } catch (Exception) { if (source != null) { source.Dispose(); } if (target != null) { target.Dispose(); } throw; } return(new FdoBulkCopy(options)); }
public void TestSchemaCannotBeApplied() { FeatureSchema schema = new FeatureSchema("Default", ""); FeatureClass fc = new FeatureClass("Class1", ""); DataPropertyDefinition id = new DataPropertyDefinition("ID", ""); id.DataType = DataType.DataType_Int32; id.IsAutoGenerated = true; fc.Properties.Add(id); fc.IdentityProperties.Add(id); //Unsupported property in SHP DataPropertyDefinition d1 = new DataPropertyDefinition("Unsupported", ""); d1.DataType = DataType.DataType_Int64; d1.Nullable = true; fc.Properties.Add(d1); GeometricPropertyDefinition geom = new GeometricPropertyDefinition("Geometry", ""); geom.GeometryTypes = (int)GeometryType.GeometryType_Point; fc.Properties.Add(geom); schema.Classes.Add(fc); /* IConnection conn = FeatureAccessManager.GetConnectionManager().CreateConnection("OSGeo.SHP"); conn.ConnectionString = "DefaultFileLocation=" + AppGateway.RunningApplication.AppPath; using (conn) { conn.Open(); using (FeatureService service = new FeatureService(conn)) { IncompatibleSchema incSchema = null; bool result = service.CanApplySchema(schema, out incSchema); Assert.IsNotNull(incSchema); Assert.IsFalse(result); foreach (IncompatibleClass incClass in incSchema.Classes) { foreach (IncompatibleProperty incProp in incClass.Properties) { Assert.AreEqual(incProp.Reasons.Count, incProp.ReasonCodes.Count); } } } conn.Close(); }*/ }
private void Prepare(PropertyValueCollection propVals) { propVals.Clear(); currentValues.Clear(); // I do not trust the long-term stability of the PropertyValueCollection // // So what we do is load it up once with LiteralValue references and manipulate these // outside of the collection (via a cached dictionary). We cache everything from the wrapper API // that can be cached in the managed world so that we only have minimal contact with it // Omit read-only properties using (FdoFeatureService service = _conn.CreateFeatureService()) { ClassDefinition c = service.GetClassByName(this.ClassName); foreach (PropertyDefinition p in c.Properties) { string name = p.Name; PropertyValue pv = new PropertyValue(name, null); if (p.PropertyType == PropertyType.PropertyType_DataProperty) { DataPropertyDefinition d = p as DataPropertyDefinition; if (!d.ReadOnly && !d.IsAutoGenerated) { DataValue dv = null; switch (d.DataType) { case DataType.DataType_BLOB: dv = new BLOBValue(); break; case DataType.DataType_Boolean: dv = new BooleanValue(); break; case DataType.DataType_Byte: dv = new ByteValue(); break; case DataType.DataType_CLOB: dv = new CLOBValue(); break; case DataType.DataType_DateTime: dv = new DateTimeValue(); break; case DataType.DataType_Decimal: dv = new DecimalValue(); break; case DataType.DataType_Double: dv = new DoubleValue(); break; case DataType.DataType_Int16: dv = new Int16Value(); break; case DataType.DataType_Int32: dv = new Int32Value(); break; case DataType.DataType_Int64: dv = new Int64Value(); break; case DataType.DataType_Single: dv = new SingleValue(); break; case DataType.DataType_String: dv = new StringValue(); break; } if (dv != null) { pv.Value = dv; propVals.Add(pv); } } } else if (p.PropertyType == PropertyType.PropertyType_GeometricProperty) { GeometricPropertyDefinition g = p as GeometricPropertyDefinition; if (!g.ReadOnly) { GeometryValue gv = new GeometryValue(); pv.Value = gv; propVals.Add(pv); } } } c.Dispose(); } //Load property values into temp dictionary foreach (PropertyValue p in propVals) { currentValues[p.Name.Name] = p.Value as LiteralValue; } if (propertySnapshot == null) { propertySnapshot = new List <string>(); foreach (PropertyValue p in propVals) { propertySnapshot.Add(p.Name.Name); } } }
/// <summary> /// Clones a given property definition /// </summary> /// <param name="pd"></param> /// <returns></returns> public static PropertyDefinition CloneProperty(PropertyDefinition pd) { PropertyDefinition propDef = null; switch (pd.PropertyType) { case PropertyType.PropertyType_DataProperty: { DataPropertyDefinition srcData = pd as DataPropertyDefinition; DataPropertyDefinition dataDef = new DataPropertyDefinition(srcData.Name, srcData.Description); dataDef.DataType = srcData.DataType; dataDef.DefaultValue = srcData.DefaultValue; dataDef.IsAutoGenerated = srcData.IsAutoGenerated; dataDef.IsSystem = srcData.IsSystem; dataDef.Length = srcData.Length; dataDef.Nullable = srcData.Nullable; dataDef.Precision = srcData.Precision; dataDef.ReadOnly = srcData.ReadOnly; //Copy constraints if (srcData.ValueConstraint != null) { if (srcData.ValueConstraint.ConstraintType == PropertyValueConstraintType.PropertyValueConstraintType_Range) { PropertyValueConstraintRange range = (PropertyValueConstraintRange)srcData.ValueConstraint; PropertyValueConstraintRange constraint = new PropertyValueConstraintRange(range.MinValue, range.MaxValue); constraint.MaxInclusive = range.MaxInclusive; constraint.MinInclusive = range.MinInclusive; dataDef.ValueConstraint = constraint; } else if (srcData.ValueConstraint.ConstraintType == PropertyValueConstraintType.PropertyValueConstraintType_List) { PropertyValueConstraintList list = (PropertyValueConstraintList)srcData.ValueConstraint; PropertyValueConstraintList constraint = new PropertyValueConstraintList(); foreach (DataValue dval in list.ConstraintList) { constraint.ConstraintList.Add(dval); } dataDef.ValueConstraint = constraint; } } CopyPropertyAttributes(srcData, dataDef); propDef = dataDef; } break; case PropertyType.PropertyType_GeometricProperty: { GeometricPropertyDefinition srcData = pd as GeometricPropertyDefinition; GeometricPropertyDefinition geomDef = new GeometricPropertyDefinition(srcData.Name, srcData.Description); geomDef.GeometryTypes = srcData.GeometryTypes; geomDef.HasElevation = srcData.HasElevation; geomDef.HasMeasure = srcData.HasMeasure; geomDef.IsSystem = srcData.IsSystem; geomDef.ReadOnly = srcData.ReadOnly; geomDef.SpatialContextAssociation = srcData.SpatialContextAssociation; CopyPropertyAttributes(srcData, geomDef); propDef = geomDef; } break; case PropertyType.PropertyType_RasterProperty: { RasterPropertyDefinition srcData = pd as RasterPropertyDefinition; RasterPropertyDefinition rastDef = new RasterPropertyDefinition(srcData.Name, srcData.Description); if (srcData.DefaultDataModel != null) { rastDef.DefaultDataModel = new OSGeo.FDO.Raster.RasterDataModel(); rastDef.DefaultDataModel.BitsPerPixel = srcData.DefaultDataModel.BitsPerPixel; rastDef.DefaultDataModel.DataModelType = srcData.DefaultDataModel.DataModelType; rastDef.DefaultDataModel.DataType = srcData.DefaultDataModel.DataType; rastDef.DefaultDataModel.Organization = srcData.DefaultDataModel.Organization; rastDef.DefaultDataModel.TileSizeX = srcData.DefaultDataModel.TileSizeX; rastDef.DefaultDataModel.TileSizeY = srcData.DefaultDataModel.TileSizeY; } rastDef.DefaultImageXSize = srcData.DefaultImageXSize; rastDef.DefaultImageYSize = srcData.DefaultImageYSize; rastDef.IsSystem = srcData.IsSystem; rastDef.Nullable = srcData.Nullable; rastDef.ReadOnly = srcData.ReadOnly; rastDef.SpatialContextAssociation = srcData.SpatialContextAssociation; CopyPropertyAttributes(srcData, rastDef); propDef = rastDef; } break; case PropertyType.PropertyType_AssociationProperty: throw new UnsupportedException(Res.GetString("ERR_UNSUPPORTED_CLONE_ASSOCIATION")); case PropertyType.PropertyType_ObjectProperty: throw new UnsupportedException(Res.GetString("ERR_UNSUPPORTED_CLONE_OBJECT")); } return(propDef); }