Mercurial > postarc > postarc
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) { } } }