christian@0: /* christian@0: * Postarc christian@0: * christian@0: * Author: christian@0: * Christian Lins christian@0: * christian@0: * Copyright: christian@0: * Copyright (C) 2012 Intevation GmbH christian@0: * christian@0: * This program is free software: you can redistribute it and/or modify christian@0: * it under the terms of the GNU Lesser General Public License as published by christian@0: * the Free Software Foundation, either version 3 of the License, or christian@0: * (at your option) any later version. christian@0: * christian@0: * This program is distributed in the hope that it will be useful, christian@0: * but WITHOUT ANY WARRANTY; without even the implied warranty of christian@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the christian@0: * GNU General Public License for more details. christian@0: * christian@0: * You should have received a copy of the GNU Lesser General Public License christian@0: * along with this program. If not, see . christian@0: */ christian@0: christian@0: using System; christian@0: using System.Collections.Generic; christian@0: using System.Linq; christian@0: using ESRI.ArcGIS.Geodatabase; christian@0: using System.Text; christian@0: using Npgsql; christian@0: using System.Diagnostics; christian@0: christian@0: namespace Postarc.Feature christian@0: { christian@0: static class StringExtension christian@0: { christian@0: public static string Replace(this string str, string oldValue, string newValue, StringComparison comparison) christian@0: { christian@0: StringBuilder sb = new StringBuilder(); christian@0: christian@0: int previousIndex = 0; christian@0: int index = str.IndexOf(oldValue, comparison); christian@0: while (index != -1) christian@0: { christian@0: sb.Append(str.Substring(previousIndex, index - previousIndex)); christian@0: sb.Append(newValue); christian@0: index += oldValue.Length; christian@0: christian@0: previousIndex = index; christian@0: index = str.IndexOf(oldValue, index, comparison); christian@0: } christian@0: sb.Append(str.Substring(previousIndex)); christian@0: christian@0: return sb.ToString(); christian@0: } christian@0: } christian@0: christian@0: class FeatureCursor : IFeatureCursor, ICursor christian@0: { christian@0: /// christian@0: /// Currently Postarc requires an Postarc_ID column in the PostGIS table christian@0: /// which is mapped to ArcGIS' OID. christian@0: /// christian@0: public const string POSTARC_OID_COLUMN = "oid"; christian@0: public const string POSTARC_SHAPE_COLUMN = "shape"; christian@0: public const string ARCGIS_OID_COLUMN = "oid"; christian@0: christian@0: protected PostGISConnection connection; christian@0: protected NpgsqlConnection npgsqlConnection; christian@0: protected FeatureClass featureClass; christian@0: protected IFields fields; christian@0: protected NpgsqlDataReader reader; christian@0: christian@0: private int oidIdx = -1; christian@0: christian@0: public FeatureCursor(FeatureClass featClass, PostGISConnection conn, IQueryFilter filter) christian@0: { christian@0: this.featureClass = featClass; christian@0: this.connection = conn; christian@0: christian@0: // If a QueryFilter is given, we must adapt our SQL query christian@0: string subFields = AllFields(); christian@0: string whereClause = ""; christian@0: if (filter != null) christian@0: { christian@0: /*if (!filter.SubFields.Equals("*")) christian@0: { christian@0: subFields = filter.SubFields; christian@0: if (!subFields.Contains(POSTARC_OID_COLUMN) && !subFields.Equals("*")) christian@0: { christian@0: subFields = subFields + "," + POSTARC_OID_COLUMN; christian@0: } christian@0: }*/ christian@0: christian@0: whereClause = filter.WhereClause; christian@0: if(whereClause != null && !whereClause.Equals("")) christian@0: { christian@0: whereClause = " WHERE " + whereClause; christian@0: } christian@0: } christian@0: christian@0: subFields = subFields.Replace( christian@0: POSTARC_SHAPE_COLUMN, christian@0: "ST_AsText(" + POSTARC_SHAPE_COLUMN + ") AS " + POSTARC_SHAPE_COLUMN); christian@0: christian@0: this.npgsqlConnection = conn.Open(); christian@0: NpgsqlCommand cmd = new NpgsqlCommand( christian@0: "SELECT " + subFields + " FROM " + featClass.TableName + whereClause + " ORDER BY " + POSTARC_OID_COLUMN, christian@0: npgsqlConnection); christian@0: this.reader = cmd.ExecuteReader(); christian@0: christian@0: // Build the fields christian@0: IFieldsEdit fieldsEdit = new FieldsClass(); christian@0: for (int n = 0; n < reader.FieldCount; n++) christian@0: { christian@0: string fieldName = reader.GetName(n); christian@0: if (fieldName.Equals(POSTARC_OID_COLUMN, StringComparison.OrdinalIgnoreCase)) christian@0: { christian@0: fieldName = ARCGIS_OID_COLUMN; christian@0: oidIdx = n; christian@0: } christian@0: int fidx = featClass.FindField(fieldName); christian@0: IField field = featClass.Fields.get_Field(fidx); christian@0: fieldsEdit.AddField(field); christian@0: } christian@0: this.fields = fieldsEdit as IFields; christian@0: } christian@0: christian@0: protected string AllFields() christian@0: { christian@0: StringBuilder buf = new StringBuilder(); christian@0: christian@0: for (int n = 0; n < featureClass.Fields.FieldCount; n++) christian@0: { christian@0: buf.Append(featureClass.Fields.get_Field(n).Name); christian@0: if (n < featureClass.Fields.FieldCount - 1) christian@0: { christian@0: buf.Append(","); christian@0: } christian@0: } christian@0: christian@0: return buf.ToString(); christian@0: } christian@0: christian@0: public void DeleteFeature() christian@0: { christian@0: // Not implemented christian@0: } christian@0: christian@0: public IFields Fields christian@0: { christian@0: get christian@0: { christian@0: return this.fields; christian@0: } christian@0: } christian@0: christian@0: public int FindField(string name) christian@0: { christian@0: return this.Fields.FindField(name); christian@0: } christian@0: christian@0: public void Flush() christian@0: { christian@0: // TODO: Not implemented christian@0: } christian@0: christian@0: public object InsertFeature(IFeatureBuffer buffer) christian@0: { christian@0: Debug.WriteLine("FeatureCursor::InsertFeature(): FIXME"); christian@0: return null; // TODO: Not implemented christian@0: } christian@0: christian@0: public IFeature NextFeature() christian@0: { christian@0: if (this.reader.Read()) christian@0: { christian@0: Feature feature = new Feature(featureClass, Fields, oidIdx, this.reader); christian@0: return feature; christian@0: } christian@0: this.reader.Close(); // We've reached the last feature christian@0: return null; christian@0: } christian@0: christian@0: public void UpdateFeature(IFeature Object) christian@0: { christian@0: // TODO: Not implemented christian@0: Debug.WriteLine("FeatureCursor::UpdateFeature(): FIXME"); christian@0: } christian@0: christian@0: public void DeleteRow() christian@0: { christian@0: // TODO: Not implemented christian@0: Debug.WriteLine("FeatureCursor::DeleteRow(): FIXME"); christian@0: } christian@0: christian@0: public object InsertRow(IRowBuffer buffer) christian@0: { christian@0: // TODO: Not implemented christian@0: Debug.WriteLine("FeatureCursor::InsertRow(): FIXME"); christian@0: return null; christian@0: } christian@0: christian@0: public IRow NextRow() christian@0: { christian@0: return NextFeature(); christian@0: } christian@0: christian@0: public void UpdateRow(IRow Row) christian@0: { christian@0: // TODO: Not implemented christian@0: Debug.WriteLine("FeatureCursor::UpdateRow(): FIXME"); christian@0: } christian@0: } christian@0: }