public static void aoFieldsToPostGisFields(ref string fields, Layer postGisLayer, int outSrid) { // We want to load every field so we can easily // interoperate with the rest of the framework. // However, load nulls for the fields that aren't specified. log.enterFunc("aoFieldsToPostGisFields"); bool loadAll = (fields == "*"); log.Debug("outSrid = " + outSrid.ToString()); string[] fieldArray = fields.Split(','); Hashtable fieldMap = new Hashtable(fieldArray.Length); foreach (string f in fieldArray) fieldMap.Add(f.ToLower().Trim(), true); // Use a dummy value. (Paolo: I added a Trim) string name; bool load; StringBuilder sb = new StringBuilder(); DataTable dataFields = postGisLayer.getDataFields(false); foreach (DataRow r in dataFields.Rows) { name = ((string)r["ColumnName"]).ToLower(); // Are we loading the data? // (if the field is found in the Hashtable // then the field was supplied to this // function, therefore we load its data) // We also load if we are loading all. load = (fieldMap[name] != null || loadAll); // Geometry fields are special - add the asbinary() func. // Plus, we *always* load the geometry data. // DONE: apply correct coordinate transformation here if (name == postGisLayer.geometryField) name = postGisLayer.transformGeometryFieldAsBinary(outSrid) + " as " + name; else if (!load) { sb.Append("null as "); } sb.Append(name); sb.Append(","); } sb.Remove(sb.Length - 1, 1); fields = sb.ToString(); log.leaveFunc(); }
public PostGisField(Layer postGisLayer, DataRow row, int id) { m_layer = postGisLayer; m_id = id; //m_default = column.DefaultValue; m_name = (string)row["ColumnName"]; setType((Type)row["DataType"]); m_precision = (int)row["NumericPrecision"]; m_scale = (int)row["NumericScale"]; m_nullable = (bool)row["AllowDBNull"]; m_length = (Type == esriFieldType.esriFieldTypeGeometry ? 0 : (int)row["ColumnSize"]); //esriFieldTypeGeometry: length=0 if (Type == esriFieldType.esriFieldTypeGeometry) { m_length = 0; } //esriFieldTypeDouble: SchemaTable not contains precision,scale,length if (Type == esriFieldType.esriFieldTypeDouble) { m_length = 8; m_precision = 0; m_scale = 0; } }
/// <summary> /// Generate a query for PostGIS from an IQueryFilter for a Layer /// </summary> /// <param name="query"></param> /// <param name="postGisLayer"></param> /// <param name="fields">output fields for the query</param> /// <param name="where">output where clause for the query</param> public static void aoQryToPostGisQry(IQueryFilter query, Layer postGisLayer, out string fields, out string where) { log.enterFunc("aoQryToPostGisQry"); if (log.IsDebugEnabled) log.Debug(Helper.objectToString(query) + "," + Helper.objectToString(postGisLayer)); // Todo - must use the IQueryFilter::OutputSpatialReference // to project the resulting geometries. fields = ""; where = ""; try { // Get the SQL stuff. fields = query.SubFields; // Add the spatial stuff. ISpatialFilter sQuery = query as ISpatialFilter; //Paolo: FactoryCode=0 for srid=-1 int outSrid = postGisLayer.SpatialReference.FactoryCode; if (outSrid == 0) { outSrid = -1; } //if outSrid=-1, could be that the Sr is set to Unknown, but srid is != -1 (for PostGIS layers with a srid not supported from esri, ex: 27563) if (outSrid == -1 && postGisLayer.srid > 0) { outSrid = postGisLayer.srid; } aoFieldsToPostGisFields(ref fields, postGisLayer, outSrid); StringBuilder sb = new StringBuilder(query.WhereClause); //if there is a spatial filter do the following... if (sQuery != null) { /* ISpatialReference sRef = sQuery.Geometry.SpatialReference; if (sRef != null && sRef.FactoryCode != 0) srid = sRef.FactoryCode; aoFieldsToPostGisFields(ref fields, postGisLayer, srid); */ // Debug - just create a polygon from the envelope for now. object o = System.Type.Missing; IEnvelope env = sQuery.Geometry.Envelope; IPointCollection pg = (IPointCollection)(new PolygonClass()); pg.AddPoint(env.LowerLeft, ref o, ref o); pg.AddPoint(env.LowerRight, ref o, ref o); pg.AddPoint(env.UpperRight, ref o, ref o); pg.AddPoint(env.UpperLeft, ref o, ref o); if (sb.Length > 0) sb.Append(" and "); //Paolo: for srid=-1 not doing transform sb.Append("intersects("); sb.Append("transform("); sb.Append(aoPolygonToWkt((IPolygon)pg, true, outSrid)); sb.Append("," + outSrid.ToString() + "),"); sb.Append("transform(" + postGisLayer.geometryField + "," + outSrid.ToString() + ")"); sb.Append(")=true"); } where = sb.ToString(); //System.Diagnostics.EventLog.WriteEntry("GeomHelper.aoQryToPostGisQry", where, System.Diagnostics.EventLogEntryType.Information); if (log.IsDebugEnabled) { log.Debug(fields); log.Debug(where); } } catch (Exception ex) { log.Debug("GeomHelper.aoQryToPostGisQry", ex); } finally { log.leaveFunc(); } }
internal PostGisFields(Layer postGisLayer) { log.enterFunc("ctor"); try { bool hasGIDField = false; if (log.IsDebugEnabled) log.Debug("1"); DataTable dataFields = postGisLayer.getDataFields(false); if (log.IsDebugEnabled) log.Debug("2"); m_flds = new PostGisField[dataFields.Rows.Count]; m_ids = new Hashtable(fields.Length); PostGisField pgisFld; int i = 0; foreach (DataRow r in dataFields.Rows) { pgisFld = new PostGisField(postGisLayer, r, i); m_flds[i] = pgisFld; m_ids.Add(pgisFld.Name, i); if(pgisFld.Name.ToLower()=="gid") { hasGIDField=true; } ++i; } //gid (int4 or int8) is mandatory as GDB unique OID if (hasGIDField==false) { System.Windows.Forms.MessageBox.Show("This PostGis layer will be added in ArcMap but will not correctly work for some funcitonality (selections, rendering, ...): it misses a mandatory gid (int) field as unique OID for each feature. This gid field is necessary for the Esri Geodatabase model."); } } catch (Exception e) { log.Error("", e); throw; } finally { log.leaveFunc(); } }