view Postarc/Postarc/Feature/FeatureClass.cs @ 0:1aca3d413885 tip

Initial import of Postarc
author Christian Lins <christian.lins@intevation.de>
date Fri, 05 Oct 2012 23:55:06 +0200
parents
children
line wrap: on
line source
/*
 * Postarc
 *
 * Author:
 * Christian Lins <christian.lins@intevation.de>
 *
 * Copyright:
 * Copyright (C) 2012 Intevation GmbH <http://www.intevation.de/>
 *
 * This program 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 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
using Npgsql;
using NpgsqlTypes;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Postarc.Geodatabase;

namespace Postarc.Feature
{
    [Guid("77FB1E58-69A9-4bac-AFB6-76F0F85D3B75"), ClassInterface(ClassInterfaceType.None)]
    public class FeatureClass :
        IDataset, IDatasetEdit, IDatasetEditInfo,
        IFeatureClass, 
        IGeoDataset,
        //IModelInfo,
        ISchemaLock,
        ISubtypes,
        ITable /* inherits IClass */, ITableCapabilities,
        ITopology,
        IValidation, IValidation2
    {
        private string browseName = "BrowseName";
        private string clsid = "{77FB1E58-69A9-4bac-AFB6-76F0F85D3B75}";
        private IFields fields = new FieldsClass();
        private string shapeFieldName = "shape";
        private esriGeometryType shapeType = esriGeometryType.esriGeometryPoint;

        protected PostGISConnection connection;
        protected ISpatialReference spatialReference = FeatureLayer.CreateGeographicSpatialReference();
        protected string tableName;
        protected Workspace workspace = new Workspace();

        internal PostGISConnection PostGISConnection
        {
            get
            {
                return this.connection;
            }
        }

        /// <summary>
        /// Name of the PostGIS table behind this FeatureClass.
        /// </summary>
        internal string TableName
        {
            get
            {
                return this.tableName;
            }
        }

        public FeatureClass(esriGeometryType shapeType)
        {
            this.shapeType = shapeType;

            IFieldEdit field = new FieldClass();
            field.Name_2 = "OID";
            field.Type_2 = esriFieldType.esriFieldTypeOID;
            AddField(field);

            field = new FieldClass();
            field.Name_2 = ShapeFieldName;
            field.Type_2 = esriFieldType.esriFieldTypeGeometry;
            AddField(field as IField);

            field = new FieldClass();
            field.Name_2 = "test";
            field.Type_2 = esriFieldType.esriFieldTypeInteger;
            //    AddField(field as IField);
        }

        public FeatureClass(PostGISConnection conn, string tableName)
        {
            this.connection = conn;
            this.tableName = tableName;

            LoadFieldDefinitionFromTable();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected internal int NextOID()
        {
            NpgsqlConnection conn = this.connection.Open();
            NpgsqlCommand cmd = new NpgsqlCommand(
                "SELECT Max(" + FeatureCursor.POSTARC_OID_COLUMN + ") FROM " + tableName, conn);
            int maxOID = Convert.ToInt32(cmd.ExecuteScalar());
            conn.Close();
            return maxOID + 1;
        }

        protected internal void LoadFieldDefinitionFromTable()
        {
            NpgsqlConnection conn = this.connection.Open();

            NpgsqlCommand cmd = new NpgsqlCommand("SELECT * FROM " + tableName + " LIMIT 1", conn);
            NpgsqlDataReader cur = cmd.ExecuteReader();
            for (int n = 0; n < cur.FieldCount; n++)
            {
                NpgsqlDbType type = cur.GetFieldNpgsqlDbType(n);
                string name = cur.GetName(n);
                if (name.Equals(FeatureCursor.POSTARC_OID_COLUMN, StringComparison.OrdinalIgnoreCase))
                {
                    name = FeatureCursor.ARCGIS_OID_COLUMN;
                    AddField(name, type, true);
                }
                else if (name.Equals(FeatureCursor.POSTARC_SHAPE_COLUMN, StringComparison.OrdinalIgnoreCase))
                {
                    type = NpgsqlDbType.Point;
                    AddField(name, type);
                }
                else
                {
                    AddField(name, type);
                }
            }
            conn.Close();
        }

        protected void AddField(string name, NpgsqlDbType type, bool isOID = false)
        {
            esriFieldType esriType = esriFieldType.esriFieldTypeBlob;
            switch (type)
            {
                case NpgsqlDbType.Bigint:
                case NpgsqlDbType.Integer:
                    if (isOID)
                    {
                        esriType = esriFieldType.esriFieldTypeOID;
                        AddField(name, esriType, false);
                    }
                    else
                    {
                        esriType = esriFieldType.esriFieldTypeInteger;
                        AddField(name, esriType);
                    }
                    break;
                case NpgsqlDbType.Point:
                    esriType = esriFieldType.esriFieldTypeGeometry;
                    this.shapeType = esriGeometryType.esriGeometryPoint;
                    this.shapeFieldName = name;
                    AddField(name, esriType, true, true);
                    break;
                case NpgsqlDbType.Varchar:
                    esriType = esriFieldType.esriFieldTypeString;
                    AddField(name, esriType, true, false, 255);
                    break;
            }
        }

        protected void AddField(
            string name,
            esriFieldType type,
            bool editable = true,
            bool isGeometry = false,
            int length = 4)
        {
            IFieldEdit field = new FieldClass();
            field.Name_2 = name;
            field.Type_2 = type;
            field.AliasName_2 = name;
            field.Editable_2 = editable;
            if (isGeometry)
            {
                field.GeometryDef_2 = new Point() as IGeometryDef;
                Debug.Assert(field.GeometryDef != null);
            }
            field.Length_2 = length;
            AddField(field as IField);
        }

        public void AddField(IField field)
        {
            IFieldsEdit fields = this.fields as IFieldsEdit;
            fields.AddField(field);
        }

        public void AddIndex(IIndex Index)
        {

        }

        public string AliasName
        {
            get
            {
                return "AliasName";
            }
        }

        public IField AreaField
        {
            get
            {
                return null; // null is correct when ShapeType is point
            }
        }

        public UID CLSID
        {
            get
            {
                UID uid = new UID();
                uid.Value = clsid;
                return uid;
            }
        }

        /// <summary>
        /// Calls CreateFeatureBuffer()
        /// </summary>
        /// <returns></returns>
        public IFeature CreateFeature()
        {
            Debug.WriteLine("PostGISFeatureClass::CreateFeature()");
            return CreateFeatureBuffer() as IFeature;
        }

        /// <summary>
        /// Creates a new Postarc.Feature.Feature instance as IFeatureBuffer.
        /// </summary>
        /// <returns></returns>
        public IFeatureBuffer CreateFeatureBuffer()
        {
            Debug.WriteLine("PostGISFeatureClass::CreateFeatureBuffer()");
            int oidIdx = fields.FindField(FeatureCursor.ARCGIS_OID_COLUMN);
            object[] row = new object[fields.FieldCount];
            row[oidIdx] = NextOID();
            return new Feature(this, fields, oidIdx, row);
        }

        public void DeleteField(IField Field)
        {

        }

        public void DeleteIndex(IIndex Index)
        {

        }

        public ESRI.ArcGIS.esriSystem.UID EXTCLSID
        {
            get
            {
                return null;
            }
        }

        public object Extension
        {
            get
            {
                return new DummyClassExtension() as IClassExtension;
            }
        }

        public IPropertySet ExtensionProperties
        {
            get
            {
                Debug.WriteLine("PostGISFeatureClass::ExtensionProperties");
                return new PropertySetClass();
            }
        }

        public int FeatureClassID
        {
            get
            {
                return GetHashCode(); // TODO: Return unique ID for this feature class
            }
        }

        public int FeatureCount(IQueryFilter QueryFilter)
        {
            NpgsqlConnection conn = this.connection.Open();
            NpgsqlCommand cmd = new NpgsqlCommand("SELECT Count(*) FROM " + tableName, conn);
            int cnt = Convert.ToInt32(cmd.ExecuteScalar());
            conn.Close();
            return cnt;
        }

        public IFeatureDataset FeatureDataset
        {
            get
            {
                return new Postarc.Geodatabase.FeatureDataset(this);
            }
        }

        public esriFeatureType FeatureType
        {
            get
            {
                return esriFeatureType.esriFTSimple;
            }
        }

        public IFields Fields
        {
            get
            {
                return fields;
            }
        }

        public int FindField(string Name)
        {
            return this.fields.FindField(Name);
        }

        public IFeature GetFeature(int oid)
        {
            QueryFilterClass filter = new QueryFilterClass();
            filter.WhereClause = "OID in (" + oid + ")";
            IFeatureCursor cur = Search(filter, false);
            return cur.NextFeature();
        }

        public IFeatureCursor GetFeatures(object fids, bool recycling)
        {
            QueryFilterClass filter = new QueryFilterClass();
            StringBuilder buf = new StringBuilder();
            buf.Append(FeatureCursor.POSTARC_OID_COLUMN);
            buf.Append(" in (");
            int[] oids = (int[])fids;
            for (int n = 0; n < oids.Length; n++)
            {
                buf.Append(oids[n]);
                if (n != oids.Length - 1)
                    buf.Append(",");
            }
            buf.Append(")");
            filter.WhereClause = buf.ToString();

            return new FeatureCursor(this, this.connection, filter);
        }

        public bool HasOID
        {
            get
            {
                return true;
            }
        }

        public IIndexes Indexes
        {
            get
            {
                return null;
            }
        }

        public IFeatureCursor Insert(bool useBuffering)
        {
            return null;
        }

        ICursor ITable.Insert(bool useBuffering)
        {
            return null;
        }

        public IField LengthField
        {
            get
            {
                return null;
            }
        }

        public string OIDFieldName
        {
            get
            {
                return "OID";
            }
        }

        public int ObjectClassID
        {
            get
            {
                return -1;
            }
        }

        public IFeatureCursor Search(IQueryFilter filter, bool recycling)
        {
            return new FeatureCursor(this, this.connection, filter);
        }

        ICursor ITable.Search(IQueryFilter filter, bool recycling)
        {
            return Search(filter, recycling) as ICursor;
        }

        public ISelectionSet Select(
            IQueryFilter queryFilter, 
            esriSelectionType selType, 
            esriSelectionOption selOption, 
            IWorkspace selectionContainer)
        {
            Postarc.Geodatabase.SelectionSet sel = new Postarc.Geodatabase.SelectionSet(this);
            IFeatureCursor cur = Search(queryFilter, false);
            IFeature feature;
            while ((feature = cur.NextFeature()) != null)
            {
                sel.Add(feature.OID);
            }
            //return sel as ISelectionSet;
            return null;
        }

        public string ShapeFieldName
        {
            get
            {
                return this.shapeFieldName;
            }
        }

        internal int ShapeFieldIndex
        {
            get
            {
                return Fields.FindField(shapeFieldName);
            }
        }

        public esriGeometryType ShapeType
        {
            get
            {
                return this.shapeType;
            }
        }

        public IFeatureCursor Update(IQueryFilter filter, bool recycling)
        {
            return null;
        }

        ICursor ITable.Update(IQueryFilter filter, bool recycling)
        {
            return null;
        }

        public IEnumRelationshipClass get_RelationshipClasses(esriRelRole role)
        {
            Debug.WriteLine("FeatureClass::get_RelationshipClasses(): FIXME");
            return null; // TODO: ?
        }

        public string BrowseName
        {
            get
            {
                return this.browseName;
            }
            set
            {
                this.browseName = value;
            }
        }

        public bool CanCopy()
        {
            return false;
        }

        public bool CanDelete()
        {
            return false;
        }

        public bool CanRename()
        {
            return false;
        }

        public string Category
        {
            get
            {
                return "PostGIS";
            }
        }

        public IDataset Copy(string copyName, IWorkspace copyWorkspace)
        {
            return null;
        }

        public void Delete()
        {

        }

        public IName FullName
        {
            get
            {
                return new FeatureClassName();
            }
        }

        public string Name
        {
            get
            {
                return "PostGIS FeatureClass";
            }
        }

        public IPropertySet PropertySet
        {
            get
            {
                return null;
            }
        }

        public void Rename(string name)
        {
        }

        public IEnumDataset Subsets
        {
            get
            {
                return null;
            }
        }

        public esriDatasetType Type
        {
            get
            {
                return esriDatasetType.esriDTFeatureClass;
            }
        }

        /// <summary>
        /// Returns the associated Postarc.Feature.Workspace instance of this
        /// FeatureClass.
        /// </summary>
        public IWorkspace Workspace
        {
            get
            {
                return this.workspace as IWorkspace;
            }
        }

        /// <summary>
        /// From IDatasetEdit
        /// </summary>
        /// <returns></returns>
        public bool IsBeingEdited()
        {
            return this.workspace.IsBeingEdited();
        }

        public void AlterAliasName(string Name)
        {

        }

        public void AlterClassExtensionCLSID(UID ClassExtensionCLSID, IPropertySet classExtensionProperties)
        {

        }

        public void AlterDefaultValue(string FieldName, object Value)
        {

        }

        public void AlterDomain(string FieldName, IDomain Domain)
        {

        }

        public void AlterFieldAliasName(string FieldName, string AliasName)
        {

        }

        public void AlterFieldModelName(string FieldName, string ModelName)
        {

        }

        public void AlterInstanceCLSID(UID InstanceCLSID)
        {

        }

        public void AlterModelName(string Name)
        {

        }

        public int RegisterAsObjectClass(string suggestedOIDFieldName, string configKeyword)
        {
            return 0; // FIXME
        }


        public void AlterClassExtensionProperties(IPropertySet classExtensionProperties)
        {

        }

        public void AddGlobalID(string FieldName)
        {

        }

        public void DeleteGlobalID()
        {

        }

        /*        public int AllowableComponents
                {
                    get
                    {
                        return 0; // FIXME
                    }
                }

                public void Analyze(int tableComponents)
                {

                }*/

        public bool CanEdit
        {
            get
            {
                // TODO: Check for write access to PostGIS table
                return true;
            }
        }


        public bool CanRedo
        {
            get
            {
                return false;
            }
        }

        public bool CanUndo
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// IFeatureClassLoad.LoadOnlyMode: Indicates if the featureclass is in load only mode. 
        /// </summary>
        /*public bool LoadOnlyMode
        {
            get
            {
                return true; //FIXME
            }
            set
            {

            }
        }*/

        /*
        public void UpdateExtent()
        {

        }*/

        /*
        public void RemoveFeature(IFeature Feature)
        {

        }

        public void RemoveFeatures(ISet features)
        {

        }

        public void WriteFeature(IFeature Feature)
        {

        }

        public void WriteFeatures(ISet features)
        {

        }*/

        public IEnvelope Extent
        {
            get
            {
                IPoint point = new PointClass();
                point.PutCoords(0, 0);
                ITopologicalOperator topOp = point as ITopologicalOperator;
                IGeometry buf = topOp.Buffer(100);
                return buf.Envelope;
            }
        }

        public ISpatialReference SpatialReference
        {
            get
            {
                return spatialReference;
            }
        }


        /*public IGeodataXform GeodataXform
        {
            get
            {
                return null; //FIXME
            }
        }

        public IEnvelope NativeExtent
        {
            get
            {
                return null;  //FIXME
            }
        }

        public ISpatialReference NativeSpatialReference
        {
            get
            {
                return null; // FIXME
            }
        }*/

        public string ModelName
        {
            get
            {
                return "ModelName"; //FIXME
            }
            set
            {

            }
        }


        public IGeometricNetwork GeometricNetwork
        {
            get
            {
                return null; // FIXME
            }
        }

        public esriNetworkClassAncillaryRole NetworkAncillaryRole
        {
            get
            {
                return esriNetworkClassAncillaryRole.esriNCARNone;  //FIXME
            }
        }

        public int get_FieldToWeightMapping(int FieldIndex)
        {
            return 0;//FIXME
        }

        public bool CanBypassStoreMethod()
        {
            return false;
        }

        public bool CanBypassEditSession()
        {
            return false;
        }

        public void ChangeSchemaLock(esriSchemaLock schemaLock)
        {

        }

        public void GetCurrentSchemaLocks(out IEnumSchemaLockInfo schemaLockInfo)
        {
            schemaLockInfo = null; // FIXME
        }

        public void AddSubtype(int SubtypeCode, string SubtypeName)
        {

        }

        public int DefaultSubtypeCode
        {
            get
            {
                return 0; //FIXME
            }
            set
            {

            }
        }

        public void DeleteSubtype(int SubtypeCode)
        {

        }

        public bool HasSubtype
        {
            get
            {
                return false;
            }
        }

        public int SubtypeFieldIndex
        {
            get
            {
                Debug.WriteLine("FeatureClass::SubtypeFieldIndex::get");
                return 0;  //FIXME
            }
        }

        public string SubtypeFieldName
        {
            get
            {
                return "";
            }
            set
            {

            }
        }

        public IEnumSubtype Subtypes
        {
            get
            {
                Debug.WriteLine("FeatureClass::Subtypes(): FIXME");
                return null; //FIXME
            }
        }

        public object get_DefaultValue(int subtypeCode, string fieldName)
        {
            return null; // FIXME
        }

        public IDomain get_Domain(int subtypeCode, string fieldName)
        {
            Debug.WriteLine("FeatureClass::get_Domain(): FIXME " + fieldName);
            return null;  //FIXME
        }

        public string get_SubtypeName(int subtypeCode)
        {
            return ""; //FIXME
        }

        public void set_DefaultValue(int ubtypeCode, string fieldName, object value)
        {

        }

        public void set_Domain(int ubtypeCode, string fieldName, IDomain domain)
        {

        }

        public IRow CreateRow()
        {
            Debug.WriteLine("PostGISFeatureClass::CreateRow()");
            return CreateRowBuffer() as IRow;
        }

        public IRowBuffer CreateRowBuffer()
        {
            Debug.WriteLine("PostGISFeatureClass::CreateRowBuffer()");
            return CreateFeature() as IRowBuffer;
        }

        public void DeleteSearchedRows(IQueryFilter queryFilter)
        {

        }

        public IRow GetRow(int oid)
        {
            Debug.WriteLine("PostGISFeatureClass::GetRow");
            ICursor cur = GetRows(new int[] { oid }, false);
            return cur.NextRow();
        }

        public ICursor GetRows(object oids_obj, bool recycling)
        {
            Debug.WriteLine("PostGISFeatureClass::GetRows");
            return (ICursor)GetFeatures(oids_obj, recycling);
        }

        public int RowCount(IQueryFilter queryFilter)
        {
            return FeatureCount(queryFilter);
        }

        public void UpdateSearchedRows(IQueryFilter queryFilter, IRowBuffer buffer)
        {

        }

        /// <summary>
        /// From ITableCapabilities
        /// </summary>
        public bool CanSelect
        {
            get
            {
                return true;
            }
        }

        public void AddClass(IClass classToAdd, double Weight, int XYRank, int ZRank, bool EventNotificationOnValidate)
        {

        }

        public ITopologyGraph Cache
        {
            get
            {
                return null; //FIXME
            }
        }

        public double ClusterTolerance
        {
            get
            {
                return 0.0001; // FIXME
            }
        }

        public int MaximumGeneratedErrorCount
        {
            get
            {
                return 0; // FIXME
            }
        }

        public void RemoveClass(IClass classToRemove)
        {

        }

        public esriTopologyState State
        {
            get
            {
                return esriTopologyState.esriTSUnanalyzed; // FIXME
            }
        }

        public int TopologyID
        {
            get
            {
                return 0;  //FIXME
            }
        }

        public IEnvelope ValidateTopology(IEnvelope areaToValidate)
        {
            return null; //FIXME
        }

        public IPolygon get_DirtyArea(IPolygon location)
        {
            return null; //FIXME
        }

        public void AddRule(IRule Rule)
        {

        }

        public void DeleteRule(IRule Rule)
        {

        }

        public IEnumRule Rules
        {
            get
            {
                return null; // FIXME
            }
        }

        public ISelectionSet Validate(IQueryFilter Selection, IWorkspace Workspace)
        {
            return null;
        }

        public ISelectionSet ValidateSelection(ISelectionSet Selection, IWorkspace Workspace)
        {
            return null; // FIXME
        }

        public ISet ValidateSet(ISet Selection)
        {
            return null;
        }

        public IEnumRule get_RulesByField(string FieldName)
        {
            return null;
        }

        public IEnumRule get_RulesBySubtypeCode(int SubtypeCode)
        {
            return null;
        }

        public void AlterRule(IRule Rule)
        {

        }
    }
}
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)