How to add your knowledge

Schema Overrides

    When FDO connects to a datastore with an existing schema and describes the schema, it maps the native data types to FDO data types to create a default physical to logical schema mapping. You can create a schema mapping that overrides the default FDO mapping. This schema override must be applied every time that you connect to the data store. Use the provider’s Schema Override API to write a program that defines the overrides and writes them to an XML configuration file. Thereafter, before opening the connection to the provider, set the connection objects’s configuration property to point to the XML configuration file.

    The key elements to a schema override are an FDO feature schema and a mapping of column names in the existing table to property names in the FDO feature schema. The ODBC provider supports the mapping of two column names in an existing table to a 2D FDO point geometry property and optionally supports the mapping of three columns to a 3D point geometry property. In the event that the mapping includes an FDO geometry property, a spatial context definition should be provided.

    The description given here is based on sample code written to define a schema override for a table in a Microsoft Access database. The following table shows the name of the column in the Access database, which is the same as the default FDO property name, the FDO property name assigned by the schema override, a description of the contents of the column, the FDO data type assigned by the default schema mapping, and the FDO data type assigned by the schema override.

    The default schema mapping of the CITY_ID and POPULATION columns are overriden to assign them different data types than the default ones and to give them different names. A change in case counts as a change in name. The default schema mapping of the LATITUDE and LONGITUDE columns are overriden because they are combined into a single property that has a different name and a different type than the defaults. The default schema mapping of the NAME, COUNTRY, and CAPITAL columns are overriden to assign them different names than the defaults. The default schema mapping of the URL column is not overriden and retains its default type and name.

    Column Name (Default Property Name)Override Property NameColumn ContentsDefault FDO Data TypeOverride FDO Data Type
    CITY_IDIdconsecutive sequence of integers from 1 to < 1000Int16Int64
    NAMENameNamesStringString
    COUNTRYCountryNamesStringString
    CAPITALCaptial‘N’ or ‘Y’StringString
    URLNot overridennullStringNot overriden
    POPULATIONPopulationpositive integers < 17,000,000DoubleInt32
    LATITUDEGeometrypositive and negative decimalsDoubleGeometry
    LONGITUDEGeometrypositive and negative decimalsDoubleGeometry

    First a conceptual view of how to create the XML configuration file for a schema override is presented and then a code view is presented. The override includes a geometry property and so a spatial context is defined as well.

    1. Open the XML file
    2. Create a spatial context for the geometry and write it to the XML file
    3. Create the FDO feature schema and write it to the XML file
    4. Create a connection to the provider and get a reference to the connection’s physical schema mapping.
    5. Use the reference to the connection’s physical schema mapping and the Schema Override API to create the schema override whereby the logical fields in the feature schema are associated with columns in the database table
    6. Write the schema override to the XML file
    7. Close the XML file.

    C#

    The following namespaces are used.

    • OSGeo.FDO.Common..Io
    • OSGeo.FDO.Common.Xml
    • OSGeoFDO.Geometry
    • OSGeo.FDO.Schema

    Create the XML Schema Override Configuration File

    Open the XML File

    IoFileStream writeFileStream = new IoFileStream("Cities.xml", "w");
    XmlWriter writer = new XmlWriter(writeFileStream);
    

    Create a Spatial Context and Write It to the XML File

    XmlSpatialContextFlags flags = new XmlSpatialContextFlags();
    XmlSpatialContextWriter spatialContextWriter = new XmlSpatialContextWriter(writer, flags);
    DirectPositionImpl lowerLeft = new DirectPositionImpl();
    lowerLeft.X = -180.0;
    lowerLeft.Y = -90.0;
    DirectPositionImpl upperRight = new DirectPositionImpl();
    upperRight.X = 180.0;
    upperRight.Y = 90.0;
    FgfGeometryFactory geomFactory = new FgfGeometryFactory();
    IEnvelope envelope = geomFactory.CreateEnvelope(lowerLeft, upperRight);
    IGeometry geom = geomFactory.CreateGeometry(envelope);
    byte[] extent = geomFactory.GetFgf(geom);
    spatialContextWriter.CoordinateSystem = "WGS 84";
    spatialContextWriter.CoordinateSystemWkt = "GEOGCS [ \"Longitude / Latitude (WGS 84)\", DATUM [\"WGS 84\", SPHEROID [\"WGS 84\", 6378137, 298.257223563]], PRIMEM [ \"Greenwich\", 0.000000 ], UNIT \"Decimal Degree\", 0.01745329251994330]]";
    spatialContextWriter.Description = "This Coordinate System is used for GPS.";
    spatialContextWriter.ExtentType = SpatialContextExtentType.SpatialContextExtentType_Static;
    spatialContextWriter.Extent = extent;
    spatialContextWriter.Name = "WGS84";
    spatialContextWriter.XYTolerance = 0.001;
     // the next line writes the XML declaration, the opening tag for the fdo:DataStore element
    // and the gml:DerivedCRS element to the XML file
    spatialContextWriter.WriteSpatialContext();
    

    Create the Feature Schema and Write It to the XML File

    FeatureSchema schema = new FeatureSchema("World", "Logical feature schema");
    FeatureClass featClass = new FeatureClass("Cities", "This feature class contains one identity property, many data properties, and a feature geometry.");
    PropertyDefinitionCollection properties = featClass.Properties;
    DataPropertyDefinitionCollection idProperties = featClass.IdentityProperties;
    DataPropertyDefinition idProp = new DataPropertyDefinition("Id", "This is the unique id number for the city.");
    idProp.DataType = DataType.DataType_Int64;
    idProp.IsAutoGenerated = false;
    idProp.Nullable = false;
    idProp.ReadOnly = true;
    properties.Add(idProp);
    idProperties.Add(idProp);
    DataPropertyDefinition nameProp = new DataPropertyDefinition("Name", "This is the name of the City.");
    nameProp.DataType = DataType.DataType_String;
    nameProp.Length = 64;
    properties.Add(nameProp);
    DataPropertyDefinition countryProp = new DataPropertyDefinition("Country", "This is country that contains the city.");
    countryProp.DataType = DataType.DataType_String;
    countryProp.Length = 64;
    properties.Add(countryProp);
    DataPropertyDefinition populationProp = new DataPropertyDefinition("Population", "This is the population of the city.");
    populationProp.DataType = DataType.DataType_Int32;
    properties.Add(populationProp);
    DataPropertyDefinition capitalProp = new DataPropertyDefinition("Capital", "This is 'Y' or 'N' to say whether the city is the capital of the country.");
    capitalProp.DataType = DataType.DataType_String;
    capitalProp.Length = 1;
    properties.Add(capitalProp);
    GeometricPropertyDefinition featGeomProp = new GeometricPropertyDefinition("Geometry", "This is the feature geometry.");
    featGeomProp.GeometryTypes = (int)GeometricType.GeometricType_Point;
    featGeomProp.HasElevation = false;
    featGeomProp.HasMeasure = false;
    properties.Add(featGeomProp);
    featClass.GeometryProperty = featGeomProp;
    ClassCollection classes = schema.Classes;
    classes.Add(featClass);
    // the next line writes the xs:schema element to the XML file
    schema.WriteXml(writer);
    

    Create the Physical Schema Mapping and Write It to the XML File

    // set the connection to point
    // at the Microsoft Access database file
    //whose Data Source Name (DSN) has been
    // defined using the Data Sources (ODBC)
    // Windows XP administrative tool
    connection.ConnectionString = "DataSourceName=" + dataSourceName;
    // get a reference to the PhysicalSchemaMapping object contained in the connection
    PhysicalSchemaMapping connectionSchemaMapping = connection.CreateSchemaMapping();
    // use that reference to create an override physical schema mapping
    // the override definition associates columns in the columns of the Access database with property names in the FDO feature schema
    OvPhysicalSchemaMapping mapping = new OvPhysicalSchemaMapping(connectionSchemaMapping, false);
    mapping.Name = "World";
    OvClassCollection overrideClasses = mapping.Classes;
    OvClassDefinition overrrideClassDef = new OvClassDefinition("Cities");
    OvPropertyDefinitionCollection overrideProperties = overrrideClassDef.Properties;
    // associate the table in the Access database with the override class definition
    OvTable table = new OvTable("Cities");
    overrrideClassDef.Table = table;
    // associate the columns in the table in the Access database with the properties in the FDO feature schema
    OvColumn column = null;
    OvGeometricPropertyDefinition overridGeomProp = new OvGeometricPropertyDefinition("Geometry");
    overridGeomProp.GeometricColumnType = OSGeo.FDO.Providers.Rdbms.Override.OvGeometricColumnType.OvGeometricColumnType_Double;
    overridGeomProp.GeometricContentType = OSGeo.FDO.Providers.Rdbms.Override.OvGeometricContentType.OvGeometricContentType_Ordinates;
    overridGeomProp.XColumnName = "LONGITUDE";
    overridGeomProp.YColumnName = "LATITUDE";
    overrideProperties.Add(overridGeomProp);
    OvDataPropertyDefinition overrideIdProp = new OvDataPropertyDefinition("Id");
    column = new OvColumn("CITY_ID"); overrideIdProp.Column = column;
    overrideProperties.Add(overrideIdProp);
    OvDataPropertyDefinition overrideNameProp = new OvDataPropertyDefinition("Name");
    column = new OvColumn("NAME");
    overrideNameProp.Column = column;
    overrideProperties.Add(overrideNameProp);
    OvDataPropertyDefinition overrideCountryProp = new OvDataPropertyDefinition("Country");
    column = new OvColumn("COUNTRY");
    overrideCountryProp.Column = column;
    overrideProperties.Add(overrideCountryProp);
    OvDataPropertyDefinition overridePopulationProp = new OvDataPropertyDefinition("Population");
    column = new OvColumn("POPULATION");
    overridePopulationProp.Column = column;
    overrideProperties.Add(overridePopulationProp);
    OvDataPropertyDefinition overrideCapitalProp = new OvDataPropertyDefinition("Capital");
    column = new OvColumn("CAPITAL");
    overrideCapitalProp.Column = column;
    overrideProperties.Add(overrideCapitalProp);
     overrideClasses.Add(overrideClassDef);
    // write the override definition to the XML file
    XmlFlags flags = new XmlFlags();
    // the next line writes the SchemaMapping element to the XML file
    mapping.WriteXml(writer, flags);
    mapping.Dispose();
    

    Write the Closing Tag and Close the XML File

    // the next line writes the closing tag of the fdo:DataStore element to the XML file
    writer.WriteEndElement();
    writer.Close();
    writer.Dispose();
    writeFileStream.Close();
    writeFileStream.Dispose();
    

    Configure a Connection to Use the Schema Override

    The connection object contains a property whose value points to the XML configuration file.

    IConnection connection = connMgr.CreateConnection(providerName);
    IoFileStream configurationFileStream = new IoFileStream("Cities.xml", "r");
    connection.Configuration = configurationFileStream;
    connection.ConnectionString = "DataSourceName=" + dataSourceName;
    connection.Open();