Mercurial > postarc > postarc
diff Postarc/Postarc/Feature/Feature.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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Postarc/Postarc/Feature/Feature.cs Fri Oct 05 23:55:06 2012 +0200 @@ -0,0 +1,285 @@ +/* + * 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 Npgsql; +using ESRI.ArcGIS.Geometry; +using System.Diagnostics; + +namespace Postarc.Feature +{ + public class Feature : IFeature, IFeatureBuffer, IRow, IRowBuffer + { + protected FeatureClass featureClass; + protected IFields fields; + protected object[] row; + protected IWKTGeometry shape = new Point(); + + private int oidIdx = -1; + + /// <summary> + /// Constructs a Feature from an existing row in a database table. + /// </summary> + /// <param name="featureClass"></param> + /// <param name="reader"></param> + /// <param name="oidIdx"></param> + /// <param name="fields"></param> + public Feature(FeatureClass featureClass, IFields fields, int oidIdx, + NpgsqlDataReader reader) : this(featureClass, fields, oidIdx) + { + this.row = new object[fields.FieldCount]; + reader.GetValues(this.row); + LoadShapeFromRow(); + } + + protected Feature(FeatureClass featureClass, IFields fields, int oidIdx) + { + this.featureClass = featureClass; + this.fields = fields; + this.oidIdx = oidIdx; + } + + protected int ShapeFieldIndex + { + get + { + return this.fields.FindField(featureClass.ShapeFieldName); + } + } + + /// <summary> + /// Creates a new feature which is not yet written to a backend. + /// </summary> + /// <param name="featureClass"></param> + /// <param name="fields"></param> + /// <param name="oidIdx"></param> + /// <param name="row"></param> + public Feature(FeatureClass featureClass, IFields fields, int oidIdx, + object[] row) : this(featureClass, fields, oidIdx) + { + this.row = row; + LoadShapeFromRow(); + } + + protected void LoadShapeFromRow() + { + this.shape = new Point(); + int shpIdx = ShapeFieldIndex; + if (shpIdx >= 0 && row[ShapeFieldIndex] != null) + { + this.shape.SetWKT(row[ShapeFieldIndex] as string); + } + } + + public IObjectClass Class + { + get { throw new NotImplementedException(); } + } + + public void Delete() + { + // TODO: Not implemented + } + + public IEnvelope Extent + { + get + { + return this.Shape.Envelope; + } + } + + public esriFeatureType FeatureType + { + get + { + return this.featureClass.FeatureType; + } + } + + public IFields Fields + { + get + { + return this.fields; + } + } + + public bool HasOID + { + get + { + return oidIdx >= 0; + } + } + + public int OID + { + get + { + if (oidIdx >= 0) + { + int oid = Convert.ToInt32(this.row[oidIdx]); + return oid; + } + else + { + return -1; + } + } + } + + public IGeometry Shape + { + get + { + return this.shape as IGeometry; + } + set + { + this.shape = value as IWKTGeometry; + } + } + + public IGeometry ShapeCopy + { + get { throw new NotImplementedException(); } + } + + /// <summary> + /// Writes the row to the backend. From IRow interface. + /// </summary> + public void Store() + { + StringBuilder sql = new StringBuilder(); + NpgsqlConnection conn = featureClass.PostGISConnection.Open(); + NpgsqlCommand cmd; + + if (OID > 0) + { // Update existing row + sql.Append("UPDATE "); + sql.Append(featureClass.TableName); + sql.Append(" SET "); + for (int n = 0; n < this.row.Length; n++) + { + if (n != this.oidIdx) + { + sql.Append(Fields.get_Field(n).Name); + sql.Append(" = '"); + if (n == featureClass.ShapeFieldIndex) + sql.Append(shape.GetWKT()); + else + sql.Append(this.row[n]); + sql.Append("',"); + } + } + sql.Replace(',',' ', sql.Length - 1, 1); + sql.Append(" WHERE "); + sql.Append(FeatureCursor.POSTARC_OID_COLUMN); + sql.Append(" = "); + sql.Append(OID); + } + else + { // Create new row + sql.Append("INSERT INTO "); + sql.Append(featureClass.TableName); + sql.Append(" ("); + for (int n = 0; n < this.row.Length; n++) + { + if (n == this.oidIdx) + sql.Append(FeatureCursor.POSTARC_OID_COLUMN); + else + sql.Append(Fields.get_Field(n).Name); + + if (n != Fields.FieldCount - 1) + sql.Append(","); + } + sql.Append(" ) SELECT "); + for (int n = 0; n < this.row.Length; n++) + { + if (n == this.oidIdx) + { + sql.Append("Max("); + sql.Append(FeatureCursor.POSTARC_OID_COLUMN); + sql.Append(") + 1"); + } + else + { + sql.Append("'"); + if (n == featureClass.ShapeFieldIndex) + { + sql.Append(shape.GetWKT()); + } + else + { + sql.Append(this.row[n]); + } + sql.Append("'"); + } + if (n != Fields.FieldCount - 1) + sql.Append(","); + } + sql.Append(" FROM "); + sql.Append(featureClass.TableName); + } + + cmd = new NpgsqlCommand(sql.ToString(), conn); + int updatedRows = cmd.ExecuteNonQuery(); + conn.Close(); + Debug.WriteLine("Feature::Store: " + updatedRows + " rows affected"); + } + + public ITable Table + { + get + { + return this.featureClass; + } + } + + public object get_Value(int index) + { + Debug.WriteLine("Feature::get_Value(" + index + "): " + + (row[index] != null ? row[index].GetType() + " " + row[index].ToString() : "")); + + if (index == featureClass.ShapeFieldIndex) + { + return this.Shape; + } + else + { + return this.row[index]; + } + } + + public void set_Value(int index, object value) + { + Debug.WriteLine("Feature::set_Value(" + index + ", " + value + ")"); + this.row[index] = value; + } + } +}