Mercurial > postarc > postarc
comparison Postarc/Postarc/Catalog/FeatureClassExporter.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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1aca3d413885 |
---|---|
1 /* | |
2 * Postarc | |
3 * | |
4 * Author: | |
5 * Christian Lins <christian.lins@intevation.de> | |
6 * | |
7 * Copyright: | |
8 * Copyright (C) 2012 Intevation GmbH <http://www.intevation.de/> | |
9 * | |
10 * This program is free software: you can redistribute it and/or modify | |
11 * it under the terms of the GNU Lesser General Public License as published by | |
12 * the Free Software Foundation, either version 3 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU Lesser General Public License | |
21 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
22 */ | |
23 | |
24 using System; | |
25 using System.Collections.Generic; | |
26 using System.Linq; | |
27 using System.Text; | |
28 using ESRI.ArcGIS.Geodatabase; | |
29 using ESRI.ArcGIS.Geometry; | |
30 using Npgsql; | |
31 | |
32 namespace Postarc.Catalog | |
33 { | |
34 public class FeatureClassExporter | |
35 { | |
36 protected IFeatureClass featureClass; | |
37 | |
38 public FeatureClassExporter(IFeatureClass featClass) | |
39 { | |
40 this.featureClass = featClass; | |
41 } | |
42 | |
43 protected string CreateTableDefinition(IFields fields, string tableName) | |
44 { | |
45 StringBuilder buf = new StringBuilder(); | |
46 buf.Append("CREATE TABLE "); | |
47 buf.Append(tableName); | |
48 buf.Append(" ( "); | |
49 | |
50 bool hasOID = false; | |
51 for (int n = 0; n < fields.FieldCount; n++) | |
52 { | |
53 IField field = fields.get_Field(n); | |
54 string fieldType = GetSQLType(field.Type); | |
55 if (fieldType != null) | |
56 { | |
57 if (field.Name.Equals(Postarc.Feature.FeatureCursor.ARCGIS_OID_COLUMN, StringComparison.InvariantCultureIgnoreCase)) | |
58 { | |
59 hasOID = true; | |
60 buf.Append(Postarc.Feature.FeatureCursor.POSTARC_OID_COLUMN); | |
61 } | |
62 else | |
63 { | |
64 buf.Append(field.Name); | |
65 } | |
66 buf.Append(" "); | |
67 buf.Append(fieldType); | |
68 buf.Append(","); | |
69 } | |
70 | |
71 if (!hasOID && n == fields.FieldCount - 1) | |
72 { | |
73 buf.Append(Postarc.Feature.FeatureCursor.POSTARC_OID_COLUMN); | |
74 buf.Append(" BIGSERIAL NOT NULL,"); | |
75 } | |
76 } | |
77 | |
78 buf.Append("PRIMARY KEY("); | |
79 buf.Append(Postarc.Feature.FeatureCursor.POSTARC_OID_COLUMN); | |
80 buf.Append(")"); | |
81 buf.Append(" )"); | |
82 return buf.ToString(); | |
83 } | |
84 | |
85 protected string CreateGeoColumnDef(string tableName) | |
86 { | |
87 StringBuilder buf = new StringBuilder(); | |
88 | |
89 buf.Append("SELECT AddGeometryColumn('public', '"); | |
90 buf.Append(tableName); | |
91 buf.Append("', '"); | |
92 buf.Append(Postarc.Feature.FeatureCursor.POSTARC_SHAPE_COLUMN); | |
93 buf.Append("', -1, 'POINT', 2)"); | |
94 | |
95 return buf.ToString(); | |
96 } | |
97 | |
98 protected string GetSQLType(esriFieldType type) | |
99 { | |
100 switch (type) | |
101 { | |
102 case esriFieldType.esriFieldTypeInteger: | |
103 return "INT"; | |
104 // case esriFieldType.esriFieldTypeString: | |
105 // return "TEXT"; | |
106 } | |
107 return null; | |
108 } | |
109 | |
110 protected string CreateInsertStatement(string tableName, object[] row) | |
111 { | |
112 StringBuilder buf = new StringBuilder(); | |
113 buf.Append("INSERT INTO "); | |
114 buf.Append(tableName); | |
115 buf.Append("("); | |
116 | |
117 List<string> fields = new List<string>(); | |
118 for (int n = 0; n < featureClass.Fields.FieldCount; n++) | |
119 { | |
120 IField field = featureClass.Fields.get_Field(n); | |
121 string fieldType = GetSQLType(field.Type); | |
122 | |
123 if (fieldType != null) | |
124 { | |
125 fields.Add(field.Name); | |
126 } | |
127 else if (field.Type == esriFieldType.esriFieldTypeGeometry) | |
128 { | |
129 fields.Add(Postarc.Feature.FeatureCursor.POSTARC_SHAPE_COLUMN); | |
130 } | |
131 } | |
132 | |
133 for (int n = 0; n < fields.Count; n++) | |
134 { | |
135 buf.Append(fields[n]); | |
136 if (n < fields.Count - 1) | |
137 buf.Append(","); | |
138 } | |
139 | |
140 buf.Append(") VALUES ("); | |
141 | |
142 List<string> values = new List<string>(); | |
143 for (int n = 0; n < row.Length; n++) | |
144 { | |
145 esriFieldType fieldType = featureClass.Fields.get_Field(n).Type; | |
146 | |
147 if (GetSQLType(fieldType) != null || fieldType == esriFieldType.esriFieldTypeGeometry) | |
148 { | |
149 values.Add("'" + row[n] + "'"); | |
150 } | |
151 } | |
152 | |
153 for (int n = 0; n < values.Count; n++) | |
154 { | |
155 buf.Append(values[n]); | |
156 if (n < values.Count - 1) | |
157 buf.Append(","); | |
158 } | |
159 | |
160 buf.Append(")"); | |
161 return buf.ToString(); | |
162 } | |
163 | |
164 protected void CreateTable(PostGISConnection conn, string tableName) | |
165 { | |
166 NpgsqlConnection npgsqlConn = conn.Open(); | |
167 string sql; | |
168 NpgsqlCommand cmd; | |
169 | |
170 sql = CreateTableDefinition(featureClass.Fields, tableName); | |
171 cmd = new NpgsqlCommand(sql, npgsqlConn); | |
172 cmd.ExecuteNonQuery(); | |
173 | |
174 sql = CreateGeoColumnDef(tableName); | |
175 cmd = new NpgsqlCommand(sql, npgsqlConn); | |
176 cmd.ExecuteNonQuery(); | |
177 } | |
178 | |
179 protected object[] CreateRow(IFeature feature) | |
180 { | |
181 object[] row = new object[feature.Fields.FieldCount]; | |
182 for (int n = 0; n < row.Length; n++) | |
183 { | |
184 row[n] = feature.get_Value(n); | |
185 if (row[n] is IGeometry) | |
186 { | |
187 Postarc.Feature.Point point = new Postarc.Feature.Point(row[n] as IPoint); | |
188 row[n] = point.GetWKT(); | |
189 } | |
190 else if (feature.Fields.get_Field(n).Type == esriFieldType.esriFieldTypeString) | |
191 { | |
192 row[n] = EscapeString(row[n] as string); | |
193 } | |
194 } | |
195 return row; | |
196 } | |
197 | |
198 protected string EscapeString(string str) | |
199 { | |
200 str = str.Replace("'", "\'"); | |
201 return str; | |
202 } | |
203 | |
204 protected int WriteRow(string tableName, NpgsqlConnection conn, object[] row) | |
205 { | |
206 string sql = CreateInsertStatement(tableName, row); | |
207 NpgsqlCommand cmd = new NpgsqlCommand(sql, conn); | |
208 return cmd.ExecuteNonQuery(); | |
209 } | |
210 | |
211 public int ExportFeatureClass(IQueryFilter filter, PostGISConnection conn, string tableName) | |
212 { | |
213 // FIXME: Enclose in transaction | |
214 CreateTable(conn, tableName); | |
215 | |
216 NpgsqlConnection npgsqlConn = conn.Open(); | |
217 int numExported = 0; | |
218 | |
219 IFeatureCursor cursor = this.featureClass.Search(filter, true); | |
220 IFeature ifeature; | |
221 while ((ifeature = cursor.NextFeature()) != null) | |
222 { | |
223 object[] row = CreateRow(ifeature); | |
224 WriteRow(tableName, npgsqlConn, row); | |
225 numExported++; | |
226 } | |
227 | |
228 npgsqlConn.Close(); | |
229 return numExported; | |
230 } | |
231 } | |
232 } |