All right, I got it:
String text = “Hambur*”;
FilterFactory2 filterFactory = CommonFactoryFinder.getFilterFactory2( GeoTools.getDefaultHints() );
PropertyName filterAttrProperty = filterFactory.property(“NAME”);
PropertyName filterGeomProperty = filterFactory.property(“the_geom”);
Literal literalTrue = filterFactory.literal(true);
// spatial filter
Intersects geometryIntersectsFilter = filterFactory.intersects(filterGeomProperty, filterFactory.bbox(filterGeomProperty, minX,minY, maxX,maxY,null).getExpression2());
Not geometryNotNullFilter = filterFactory.not(filterFactory.isNull(filterGeomProperty));
Filter bboxFilter = filterFactory.and(geometryNotNullFilter, geometryIntersectsFilter);
// attribute filter
Not attributeNotNullFilter = filterFactory.not(filterFactory.isNull(filterAttrProperty));
PropertyIsEqualTo equal = filterFactory.equals(literalTrue, filterFactory.function(“isLike”, filterAttrProperty, filterFactory.literal(“(?i)”+text.replace(“", "(.)”))));
Filter attributeFilter = filterFactory.and(attributeNotNullFilter, equal);
Query query = new DefaultQuery( typeName, filterFactory.and(bboxFilter, attributeFilter), new String{ geomName, attributeName } );
So that is the workaround for the behavior described in http://jira.codehaus.org/browse/GEOS-4105 Thanks Jody!
But the final question is: How should be the default behavior if null occurs in the data sets and isNull is not explicit checked in the filter. Most of the users doesn’t have any idea about the quality of the data sets they query against and so this would be a common pitfall.
in my opinion the patch from Andrea (thanks for that) looks good except the return of an empty string (“”) for
static public String geometryType(Geometry arg0)
static public String relate(Geometry arg0,Geometry arg1)
static public String strConcat(String s1,String s2)
static public String strReplace(String s1, String s2, String s3, boolean bAll)
static public String strSubstring(String s1,int beg, int end)
static public String strSubstringStart(String s1,int beg)
static public String strTrim(String s1)
Where I would expect null instead of. That would make the creation of filters easier and more readable
Frank
2010/10/4 Justin Deoliveira <jdeolive@anonymised.com>
Hi Frank,
Strange… I can’t think why the combination fo the filters would fail. The stack trace indicates that the failure is occuring due to one of the operands to the islike function being null. The literal should be no problem because internally it is converted to a string and any value can be converted to a string. So my guess would be the PropertyName. Are you sure “NAME” is the correct attribute name including case?
When i get a minute I will see if i can replicate the issue with another dataset.
-Justin
On Mon, Oct 4, 2010 at 1:28 AM, Frank Gasdorf <fgdrf@anonymised.com> wrote:
Hi Justin,
the last two days I tried to get the combination of isLike and BBOX filter running but with the configuration described before (geoserver 2.0.2 and udig 1.2) it failed always with an NPE:
at org.geotools.filter.function.StaticGeometry.isLike(StaticGeometry.java:644)
at org.geotools.filter.function.FilterFunction_isLike.evaluate(FilterFunction_isLike.java:61)
at org.geotools.filter.FilterAbstract.eval(FilterAbstract.java:96)
at org.geotools.filter.IsEqualsToImpl.evaluate(IsEqualsToImpl.java:52)
at org.geotools.filter.AndImpl.evaluate(AndImpl.java:55)
at org.geotools.data.FilteringFeatureReader.hasNext(FilteringFeatureReader.java:130)
at org.geotools.data.MaxFeatureReader.hasNext(MaxFeatureReader.java:84)
at org.geotools.data.MaxFeatureReader.hasNext(MaxFeatureReader.java:84)
at org.geotools.data.DefaultFeatureResults.getCount(DefaultFeatureResults.java:329)
at org.geotools.data.store.DataFeatureCollection.size(DataFeatureCollection.java:265)
at org.geotools.feature.collection.DecoratingFeatureCollection.size(DecoratingFeatureCollection.java:168)
at org.geotools.data.crs.ReprojectFeatureResults.size(ReprojectFeatureResults.java:120)
at org.geoserver.wfs.GetFeature.run(GetFeature.java:371)
at org.geoserver.wfs.DefaultWebFeatureService.getFeature(DefaultWebFeatureService.java:115)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.geoserver.ows.util.EMFLogger.invoke(EMFLogger.java:51)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy19.getFeature(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.geoserver.ows.Dispatcher.execute(Dispatcher.java:599)
at org.geoserver.ows.Dispatcher.handleRequestInternal(Dispatcher.java:230)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.vfny.geoserver.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:265)
at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
The getFeature Request looks like that:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:GetFeature handle=“GeoTools 2.6-3 WFS DataStore”
outputFormat=“text/xml; subtype=gml/3.1.1” resultType=“results”
service=“WFS” version=“1.1.0” xmlns:ogc=“http://www.opengis.net/ogc”
xmlns:gml=“http://www.opengis.net/gml”
xmlns:xlink=“http://www.w3.org/1999/xlink”
xmlns:ows=“http://www.opengis.net/ows” xmlns:wfs=“http://www.opengis.net/wfs”>
<wfs:Query typeName=“naturalEarth:ne-10m-populated-places”>
ogc:Filter
ogc:And
<ogc:PropertyIsEqualTo matchCase=“true”>
ogc:Literaltrue</ogc:Literal>
<ogc:Function name=“isLike”>
ogc:PropertyNameNAME</ogc:PropertyName>
ogc:Literal(?i)Hamburg(.)*</ogc:Literal>
</ogc:Function>
</ogc:PropertyIsEqualTo>
ogc:BBOX
ogc:PropertyNamethe_geom</ogc:PropertyName>
gml:Envelope
gml:lowerCorner-8.12030075187971 38.584213720391205</gml:lowerCorner>
gml:upperCorner31.57894736842104 61.02075620442082</gml:upperCorner>
</gml:Envelope>
</ogc:BBOX>
</ogc:And>
</ogc:Filter>
</wfs:Query>
</wfs:GetFeature>
Like you can see, I added a free dataset from natural-earth to the workspace as a Shapefile-Datastore. The geometry filter describes a region in Europe and the isLike Filter should return all populated places where the name starts with hamburg (case insensitive ;o))
If using the PropertyIsEqualTo Filter or the BBOX Filter as standalone request it works quite well. Only the AND Filter results into the NPE. Do you have any ideas? I’m a bit confused …
Thanks a lot and sorry for my delayed feedback.
Frank
2010/10/1 Justin Deoliveira <jdeolive@anonymised.com>
So if I understand correctly you just want to create the filter object directly and not go through xml?
The following geotools code should do the trick:
FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
PropertyIsEqualTo filter = ff.bbox(“the_geom”, -75.102613 40.212597, -72.361859 41.512517);
If you need FilterFactory2 you can safely cast to it… although usually FilterFactory itself does the trick.
Hope that answers your question.
-Justin
On Fri, Oct 1, 2010 at 6:58 AM, Frank Gasdorf <fgdrf@anonymised.com> wrote:
Hello again Justin,
Great, got it running. I also unsuccessfully tried to use FilterFactor2 to create a filter like that. What I’ve done is: Parse the xml with the following created parser object and substitute the attribute with MessageFormat.
org.geotools.xml.Configuration configuration = new org.geotools.filter.v1_1.OGCConfiguration();
Parser parser = new org.geotools.xml.Parser(configuration);
That code is quite ugly and I would like to transform it to FilterFactory2.
Second: I also combine this “isLike” filter with a spatial filter (bbox, envelope or whatever) to add gazetteer support for the LocationView in udig. But I get a lot of NullPointerExceptions if I create bbox-Filters (FilterFactory2.bbox(…) or FilterFactory2.intersect(…))
I had a look at the demo requests and got the following filter running (no NPE occured) but I have no idea how to define it with filter factory’s:
<wfs:GetFeature service=“WFS” version=“1.1.0”
xmlns:topp=“http://www.openplans.org/topp”
xmlns:wfs=“http://www.opengis.net/wfs”
xmlns:ogc=“http://www.opengis.net/ogc”
xmlns:gml=“http://www.opengis.net/gml”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=“http://www.opengis.net/wfs
http://schemas.opengis.net/wfs/1.1.0/wfs.xsd”>
<wfs:Query typeName=“naturalEarth:ne-10m-populated-places”>
wfs:PropertyNametopp:NAME</wfs:PropertyName>
ogc:Filter
ogc:BBOX
ogc:PropertyNamethe_geom</ogc:PropertyName>
<gml:Envelope srsName=“http://www.opengis.net/gml/srs/epsg.xml#4326”>
gml:lowerCorner-75.102613 40.212597</gml:lowerCorner>
gml:upperCorner-72.361859 41.512517</gml:upperCorner>
</gml:Envelope>
</ogc:BBOX>
</ogc:Filter>
</wfs:Query>
</wfs:GetFeature>
Do you have any suggestions?
Cheers
Frank
2010/10/1 Justin Deoliveira <jdeolive@anonymised.com>
Hi Frank,
Good to hear from you!
Well the regular expression is just a java regex, so anything that works with java.util.Pattern should work as an argument to the isLike function.
-Justin
On Thu, Sep 30, 2010 at 2:22 PM, Frank Gasdorf <fgdrf@anonymised.com> wrote:
Hi Justin!
Thanks a lot for the fast response and the link to the discussion! I just checked it out and it works quite well! Could you point me to the syntax documentation of the isLike function. I guess some chars in the search string are for escape, single and multi wildcard characters but I’ve no idea which one.
Thanks
Frank
2010/9/30 Justin Deoliveira <jdeolive@anonymised.com>
Hi Frank!
This has been a popular topic lately
See this recent discussion from the users list:
http://old.nabble.com/case-insensitive-LIKE-filter…-td29820164.html
-Justin
On Thu, Sep 30, 2010 at 5:07 AM, Frank Gasdorf <fgdrf@anonymised.com> wrote:
found an interesting discussion right here
http://getsatisfaction.com/opengeo/topics/cql_reference
about default upper usage of the property Expression if using LIKE filters :
What I try to do is using WFS to implement a gazetteer like search for point of interests. But the user typing the search text doesn’t know about the type of storage (upper or lower case or even Camel Style or whatever).
So is there a solution in geoserver 2.1.x to get results from a like query?
Cheers
Frank
2010/9/30 Frank Gasdorf <fgdrf@anonymised.com>
Hello everybody!
I enabled the WFS service for my local geoserver installation and tried to request features with a LIKE Filter to find features with a special name attribute. But I couldn’t create a case insensitive filter, where attribute values and the filter criteria is uppercase.
FilterFactory2 filterFactory = CommonFactoryFinder.getFilterFactory2( GeoTools.getDefaultHints() );
String attributeName = “nam”;
String text = “hamburg*”
Expression upperAttribute = filterFactory.function(“strToUpperCase”, filterFactory.property(attributeName));
Filter attributeFilter = filterFactory.like(upperAttribute, text.toUpperCase(), “*”, “?”, “\”, false);
the resulting filter looks like that:
[ strToUpperCase([nam]) is like HAMBURG* ]
But I got no results back from the geoserver 2.0.2 WFS service.
Could you give any hints to solve this problem? Any suggestions? Which filters are supported by geoserver
Thanks a lot,
Frank
PS: code snippet is used witth udig 1.2 on geotools 2.6.3
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
Geoserver-devel mailing list
Geoserver-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-devel
–
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.
–
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.
–
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.
–
Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.