geomoose / gm3

GeoMoose 3 Development. Please submit pull requests to the 'main' branch.
https://www.geomoose.org
MIT License
60 stars 60 forks source link

Search Returns No Results if LAYER projection is not listed first in 'ows_srs' and 'wfs_srs' #346

Open tchaddad opened 5 years ago

tchaddad commented 5 years ago

Search works fine as shown in the demo workshop examples, but the trick is that the projection of the layers being searched happens to be listed first in the common_metadata INCLUDE file under the 'ows_srs' and 'wfs_srs' lines.

However if a user tries adding a search for local data, and happens to add their projection elsewhere in the order of 'ows_srs' and 'wfs_srs', search will always return no results, as if the bbox is just looking in the wrong place in space.

This behavior is a little hard for users to figure out because the lines in question are in the INCLUDE file.

Ideally, the projection would not have to be listed first, but if this is something we cannot control (maybe it's a Mapserver WFS thing?), then we should at least update the GeoMoose workshop docs to specify the situation.

See this thread: https://lists.osgeo.org/pipermail/geomoose-users/2019-January/006530.html

klassenjs commented 5 years ago

This seems particularly odd since GeoMoose is not passing in a spatial filter at all to the query:

<?xml version="1.0"?>
<GetFeature xmlns="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" service="WFS" version="1.1.0" outputFormat="text/xml; subtype=gml/2.1.2" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
  <Query typeName="ms:somelayer" srsName="EPSG:4326">
    <Filter xmlns="http://www.opengis.net/ogc">
      <PropertyIsLike wildCard="%" singleChar="_" escapeChar="\" matchCase="false">
        <PropertyName>somefield</PropertyName>
        <Literal>%somevalue%</Literal>
      </PropertyIsLike>
    </Filter>
  </Query>
</GetFeature>

I have even tested with <Literal>%</Literal> which should return all records. Thus, I expect there is an implicit spatial filter being applied by MapServer somewhere, and by @tchaddad's observation this filter somehow depends on the order of the ows_srs projections.

klassenjs commented 5 years ago

Also, if the layer's projection has to be "first" this precludes searching multiple layers where the source projection differs between the layers.

tchaddad commented 5 years ago

Yeah, agree on both points. Searching for a value in a field isn’t spatial, so projections shouldn’t be a factor, and yet...

Were you able to duplicate?

christian4423 commented 5 years ago

I had to make a mapserver-wfs layer as my query layer. In MapServer, I created a new .MAP file for the query layer. I was unable to make a map source that was able to return images and xml. This was my reasoning for having two .MAP files.

<map-source name="parcel_data" type="mapserver">
    <file>parcels/parcel_data_post.map</file>
    <layer name="parcel_data" status="on">
        <template name="identify"><![CDATA[]]></template>
    </layer>
    <param name="EPSG" value="4326"/>
    <param name="FORMAT" value="image/png"/>
</map-source>
<map-source name="parcel_data_wfs"  type="mapserver-wfs">
    <file>parcels/parcel_data_wfs.map</file>
    <param name="typename" value="ms:parcels"/>
    <layer name="parcels" status="OFF">
        <template name="search"><![CDATA[]]></template>         
    </layer>
    <param name="EPSG" value="4326"/>
    <param name="FORMAT" value="text/xml"/>
</map-source>

FYI: My templates are empty because I connected to the geomoose redux store and I get my results from there to render the data in ReactJS. This allows me to maintain a connection to the geomoose app. Click events in the template need the geomoose app to be global. If you are not using react, a template from the example will do just fine

In my init method in my MapComponent, I reference the query layer instead of the display layer:

this.props.app.registerService('search', SearchService, {
    fields: [
        { type: 'text', label: 'Parcel Number', name: 'parcelnum' },
        { type: 'text', label: 'Owner Last Name', name: 'last_name' },
        { type: 'text', label: 'House Number', name: 'prop_num' },
        { type: 'text', label: 'Street Name', name: 'prop_stree' },
    ],
    searchLayers: ['parcel_data_wfs/parcels']
});

REFERENCE: https://mapserver.org/ogc/wfs_server.html

tchaddad commented 5 years ago

@christian4423 I think you can have 2 map sources pointed to the same map file returning different sorts of content. The demo has an example of doing that.

But I can't tell if what you've posted is related to the original issue topic, because you would need to post the portion of the parcel_data_wfs.map that shows the layer projection block, and also the lines that show the values listed in 'ows_srs' and 'wfs_srs' lines.

That's where the behavior of no results was coming from.

christian4423 commented 5 years ago

@tchaddad ah, I must have misread the issue. Sorry about that!

theduckylittle commented 5 years ago

Is this issue closeable or do we need some follow up documentaiton?

klassenjs commented 5 years ago

It is either a mapserver bug or a gm3-demo-data bug.
At a minimum it needs docs.

klassenjs commented 5 years ago

Basically, an implicit spatial filter is being added by MapServer that is wrong if there is a projection mismatch between the layer and wfs request. This sounds like a real issue to me given that it basically precludes having source data in a different projection than GeoMoose.

Just don't know why it is doing that yet.

theduckylittle commented 5 years ago

I believe it's a part of the mapserver logic. It's doing a "bounding box" search on the entire data's extent. So there's weird-o logic in the MapServer WFS filters.

tchaddad commented 5 years ago

If that's the case then the logic on the Mapserver side is assuming that the first projection listed in the wfs_srs / ows_srs is the projection of the data, which is not a great assumption.

AFAIK those lists are just supposed to be what the server can respond with. A server might have data in various native projections, so there is no way that the first projection in the list can be assumed to be the projection of everything.

klassenjs commented 5 years ago

Which is why I think it is a MapServer bug or a bug in how we setup gm3-demo-data (we might be making a bad assumption in the includes, or we might need to supply map/layer projections all over, or something else).

tchaddad commented 5 years ago

I think some documentation is sufficient. Probably no need to change the demo, unless perhaps to not use the INCLUDE on the parcels layer map file.

Use of includes is great, it's just in this specific case it is something easy for the user to overlook when they are trying to track down the source of a problem.

klassenjs commented 5 years ago

Documentation yes, but this is something that should get figured out... at least as far as what is actually causing it.

tchaddad commented 5 years ago

I'll set up a Mapserver-only test to confirm it's on that side.

brentfraser commented 1 year ago

TBD: Test on PR #787