ThinkGeo.com    |     Documentation    |     Premium Support

PostgreSQLFeatureLayer question

Hi,


I loaded a subset data in my postgreSQLFeatureLayer, is this subset data downloaded to the local PC?  When I do  postgreSQLFeatureLayer.QueryTools.GetFeaturesIntersecting(), I notice it still retrieves the data from the database server. Is this efficient?


Thanks


Rose



Rose,




Thanks for your post.


 
The subset data has been downloaded to the local PC after executing GetFeaturesByIds(),  and the data has been stored in a Feature collection. That of course will retrieve data from the Postgre Server.
 
I would like to know what you did after you have got the features collection. Did you add them to another postgreSqlFeatureLayer?  If so it will retrieve data from database server again when you execute postgreSQLFeatureLayer.QueryTools.GetFeaturesIntersecting().
 
Can you just put the subset data into an InMemoryFeatureLayer? The code can be like this:

PostgreSqlFeatureLayer postgreLayer = new PostgreSqlFeatureLayer(connectString, "rail", "oid");
            postgreLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.Railway1;
            postgreLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            Collection<string> ids = new Collection<string>();
            for (int i = 0; i < 2000; i++)
            {
                ids.Add(i.ToString());
            }

            postgreLayer.Open();
            Collection<Feature> features = postgreLayer.QueryTools.GetFeaturesByIds(ids, ReturningColumnsType.AllColumns);
            postgreLayer.Close();

            InMemoryFeatureLayer tempLayer = new InMemoryFeatureLayer();
            tempLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.Railway1;
            tempLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

            foreach (Feature feature in features)
            {
                tempLayer.InternalFeatures.Add(feature);
            }

            tempLayer.Open();
            RectangleShape extent = new RectangleShape(-180, 90, 180, -90);
            extent.ScaleDown(80);
            tempLayer.QueryTools.GetFeaturesIntersecting(extent, ReturningColumnsType.AllColumns);
            tempLayer.Close();

Any questions please let me know.
 
Thanks,
 
Yale

Yale:


I did not use the GetFeaturesByIDs first, I called the postgreSqlFeatureLayer.QueryTools.GetFeaturesIntersecting directly on the PostgreSQLFeatureLayer, this is a spatial query as demonstrated in the Sample code. I just wanted to  let the user draw a circle then do a radius search, why I have fo use the GetFeaturesByIDs() first, confused!


Rose



Rose,


I think we misunderstood your first post attempts. 



In our sample pasted, we just try to simulate the progress “loaded the subset of data from PostgreServer” and then we do a spatial query from the subset of data (so we did not connect and query from PostgreServer again), that is what we understood and try to show you. 



Any all, now I think you try to do is do a SpatialQuery in the event of winformsMap1.TrackOverlay.TrackEnded event, is that right? 



Can you send us some codes to show what you attempted you to do about this post if the problem still exists? 



Thanks for your reply. 



Yale 

 



Yale:


Yes, I wanted to to do a spatial query  in the event of windormsMap1.TrackOverlay.TrackEnded event, following is my code snippet. I noticed the program still retrieves the data from the database server. As I said in this post:


gis.thinkgeo.com/Support/Dis....aspx#8922


When I created the postgreSQLFeature layer, I passed in the query string to select  all the columns from the database,but the program only retrieved the 3 of them. So when I do a spatial query in the windformsMap1.TrackOverlay.TrackEnded event, the program retrieves all columns data from the database again.


My questions is, why not retrieve all the columns data when the postgreSqlFeature layer is displayed?


 



        If CType(mnuBar.Items(VESSELRADIUSSEARCH_CMD_ID), ToolStripButton).Checked = True And Map1.TrackOverlay.TrackMode = TrackMode.Circle Then
            Dim feature1 As Feature

            If Map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count = 0 Then
                Exit Sub
            Else
                feature1 = Map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Item(Map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count - 1)
                If feature1.GetWellKnownType <> WellKnownType.Polygon Then
                    Exit Sub
                End If
            End If
            Try
                Map1.TrackOverlay.Lock.EnterWriteLock()
                Map1.TrackOverlay.TrackShapeLayer.InternalFeatures.RemoveAt(Map1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count - 1)
                Dim selectedFeatures As Collection(Of Feature)
                Dim postgreLyr As FeatureLayer = Map1.FindFeatureLayer("VesselPointsLayer")

                If postgreLyr Is Nothing Then
                    MsgBox("Vessel data is not available.")
                    Exit Sub
                End If
                postgreLyr.Open()
                selectedFeatures = postgreLyr.QueryTools.GetFeaturesIntersecting(feature1, vesselReturningColumns)
                postgreLyr.Close()


                If selectedFeatures.Count > 0 Then
                    Me.DataGridView1.DataSource = MapEngine.LoadDataTable(selectedFeatures, vesselReturningColumns)
                    UpdateInfoWindowForVessel()
                Else
                    Me.DataGridView1.DataSource = Nothing
                End If
            Catch ex As Exception
                swLog.WriteLine("TrackEndedEventHandler VesselRadiusSearch exception=" & ex.Message & " Time=" & Now.ToShortTimeString)
                swLog.Flush()
            Finally
                Map1.TrackOverlay.Lock.ExitWriteLock()
                Map1.Refresh()
            End Try
End IF


Rose, 


Normally, we will only get the data needed , in this way, it will save some time.
 
You have two ways to retrieve all the columns data when the postgreSqlFeatureLayer is displayed.
 
One way is override the GetRequiredColumnNamesCore function of PointStyle, so the code in your RotatePointStyle should be like this:
 

protected override Collection<string> GetRequiredColumnNamesCore()
    {
        Collection<string> columns = new Collection<string>();
        columns.Add("Angle");
        columns.Add("VehicleImage");
        columns.Add("VehicleImage");
 
        //Add all the column name to the collection here
        return columns;
    }

 
The other way is set the DefaultTextStyle of your postgreSqlFeatureLayer like this:

postgreLayer.Open();
Collection<FeatureSourceColumn> columns = postgreLayer.QueryTools.GetColumns();
foreach(FeatureSourceColumn column in columns)
{
postgreLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle.RequiredColumnNames.Add(column.ColumnName);
}
postgreLayer.Close();

         Any more questions just let me know,


Thanks.
 
Yale