예제 #1
0
        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();
        }
예제 #2
0
 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;
     }
 }
예제 #3
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();
            }
        }
예제 #4
0
        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();
            }
        }