For ShapeFileFeatureLayer, I think we have no way to implement this up to now, while in MsSqlFeatureLayer or PostgreFeatureLayer, we probablly can achive this by using the event ExecutingSqlStatement.
For the ShapeFileFeatureLayer, I think the SpatialQuery should be very fast based on RTree used, so what I suggest is first to the SpatialQuery and then do the SqlQuery based on the SpatialQuery result.
For the PostgreFeatureLayer, the QueryTools.GetFeaturesIntersecting() only do spatial query, how to make it to do sql query at the same time? For example the returned collection of Features are sorted by column1, column2...
To achieve this, we have to change the sqlstatement in the following event: ((PostgreSqlFeatureSource)(postgreLayer.FeatureSource)).ExecutingSqlStatement += new EventHandler<ExecutingSqlStatementPostgreSqlFeatureSourceEventArgs>(DisplayShapeMap_ExecutingSqlStatement);
void DisplayShapeMap_ExecutingSqlStatement(object sender, ExecutingSqlStatementPostgreSqlFeatureSourceEventArgs e) { if (e.ExcutingSqlStatementType == ExecutingSqlStatementType.GetFeaturesInsideBoundingBoxEx) { e.SqlStatement = e.SqlStatement.Remove(e.SqlStatement.Length - 1) + " ORDER BY COLUMN1 DESC;"; } }
I checked the SqlStatement in the ExecutingSqlStatement event, the geometry column is retrieved twice,
The geometry column is called "ais_geom", See the statement below:
Query1=select "aispolylines_id","startdate","enddate",AsBinary("ais_geom") as "ais_geom",AsBinary("ais_geom") as "ais_geom" from "tracksview" where GeomFromWKB(:geometry,4326) && "ais_geom";
Just want to know what are the ExcutingSqlStatementType for the twice events? That maybe be reasonably because we did not cache its filed , we will retrieve it everytime we need it.
The ExecutingSqlStatementType is GetFeaturesInsideBoundingBoxEx. You overlooked my question, I did not say the event fired twice, I said the geometry column was retrieved twice in the same query.
I tested with our very simple sample, it works fine, it will only regrieve the geometry column once, could you explain what special operation for you case?
select AsBinary("shape") as "shape",recid from "usstates" where GeomFromWKB(:geometry,4326) && "shape" ORDER BY COLUMN1 DESC;
I did not test it, but it sounds related to an issue that I discovered. When there are multiple tables/views present in the database having the same name, the union of the column names of all the tables/views with the same name will be retrieved, and eventually duplicated multiple times. It could be that also the geometry column will be retrieved twice, or even more often. The issue was solved, and the API now includes an extra overload when constucting the PostgreSqlFeatureLayer, one that includes the schema name. Note that also the spatial reference ID will not be read from the geometry_columns table anymore. You have to look it up yourself. This may look annoying, but in fact, it is a powerful ‘feature’, as it enables you to use temporary views, work with stored procedures and maybe even temporary tables, without listing them in the geometry_columns table.
Thanks for your sharing, your words reminds me about the schema supporting a couple of weeks ago, yes, that absolutely an awesome feature. Rose, just have a try on this feature.
Unfortunately, Rose is right. I ran into the same issue, while checking out something else. It doesn’t really hurt, but potentially slows down table-lookups, as all the geographic information has to be put through twice. In my case it revealed something else which is a little bit sad: when requesting single values for a certain column using the querytools, you have to retrieve all columns, or maybe you should assemble the collection of columns that you want to retrieve manually, which is a cumbersome process, way to difficult. Choosing which columns to retrieve should be based on a simple collection of strings. In my case, I would probably write all SQL from sratch myself, when retrieving specific single pieces of information (single value lookup, or single rows), which is not too hard. Something like this:
'Build the query string (contains a local function to get the map X and Y coordinates with a little less code) 'Also insert the columnname and the SRID. As you can see, it’s not even neccessary to retrieve the geometry data or keyvalues! Dim sSQL As String sSQL = String.Format("select {0} from nl.vw_adm_gem_2008 " & _ “where GeomFromText(‘POINT({1} {2})’,{3}) && the_geom;”, _ Chr(34) & “GEMNM” & Chr(34), CType(Me.GetGeoPt(e.X, e.Y).X, Int32), CType(Me.GetGeoPt(e.X, e.Y).Y, Int32), 28992)
'finally perform a ExecuteScalar. TextBox1.AppendText(postcode.QueryTools.ExecuteScalar(sSQL))
This is really fast for single value lookups, for entire rows you’ll need ExecuteQuery. Maybe I’ll even get around it completely, and use only the featureid and get all tabledata in another way. As a matter of fact, it would be better to use prepared statements and paramaters instead of putting together the SQL this way (mainly because of protection against SQL-injection), but if your applications manages it well, this can be safe too.
As said before, retrieving too many columns, or even twice, does not hurt, but when many people are using the same database, or when working with large tables, it could become important that MapSuite optimizes it queries.
So, this is definitely a point for improvements in upcoming releases.
I tested with our very simple sample, it works fine, it will only regrieve the geometry column once, could you explain what special operation for you case?
select AsBinary("shape") as "shape",recid from "usstates" where GeomFromWKB(:geometry,4326) && "shape" ORDER BY COLUMN1 DESC;
Any more questions just feel free to let me know.
Thanks.
Yale
Yale:
I was distracted to another project in the past few day.
I did not use any special operation, there is only one Public schema in my database, first I created a view, then created the PostgreSQL feature layer on this view. I can see there is only one geometry colum in the view.