view 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 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 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;
        }
    }
}
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)