Source Code Cross Referenced for ReprojectingFilterVisitor.java in  » GIS » GeoServer » org » geoserver » feature » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoServer » org.geoserver.feature 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002:         * This code is licensed under the GPL 2.0 license, availible at the root
003:         * application directory.
004:         */
005:        package org.geoserver.feature;
006:
007:        import org.geotools.feature.AttributeType;
008:        import org.geotools.feature.FeatureType;
009:        import org.geotools.feature.GeometryAttributeType;
010:        import org.geotools.filter.visitor.DuplicatingFilterVisitor;
011:        import org.geotools.geometry.jts.JTS;
012:        import org.geotools.geometry.jts.ReferencedEnvelope;
013:        import org.geotools.referencing.CRS;
014:        import org.opengis.filter.BinaryComparisonOperator;
015:        import org.opengis.filter.FilterFactory2;
016:        import org.opengis.filter.PropertyIsEqualTo;
017:        import org.opengis.filter.PropertyIsNotEqualTo;
018:        import org.opengis.filter.expression.Expression;
019:        import org.opengis.filter.expression.Literal;
020:        import org.opengis.filter.expression.PropertyName;
021:        import org.opengis.filter.spatial.BBOX;
022:        import org.opengis.filter.spatial.Beyond;
023:        import org.opengis.filter.spatial.BinarySpatialOperator;
024:        import org.opengis.filter.spatial.Contains;
025:        import org.opengis.filter.spatial.Crosses;
026:        import org.opengis.filter.spatial.DWithin;
027:        import org.opengis.filter.spatial.Disjoint;
028:        import org.opengis.filter.spatial.Equals;
029:        import org.opengis.filter.spatial.Intersects;
030:        import org.opengis.filter.spatial.Overlaps;
031:        import org.opengis.filter.spatial.Touches;
032:        import org.opengis.filter.spatial.Within;
033:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
034:
035:        import com.vividsolutions.jts.geom.Geometry;
036:
037:        /**
038:         * Returns a clone of the provided filter where all geometries and bboxes have
039:         * been reprojected to the CRS of the associated attributes. The working
040:         * assumption is that the filters specified are strictly compliant with the OGC
041:         * spec, so the first item is always a {@link PropertyName}, and the second
042:         * always a {@link Literal}
043:         * 
044:         * @author Andrea Aime - The Open Planning Project
045:         * 
046:         */
047:        public class ReprojectingFilterVisitor extends DuplicatingFilterVisitor {
048:            FeatureType featureType;
049:
050:            public ReprojectingFilterVisitor(FilterFactory2 factory,
051:                    FeatureType featureType) {
052:                super (factory);
053:                this .featureType = featureType;
054:            }
055:
056:            /**
057:             * Returns the CRS associated to a property in the feature type. May be null
058:             * if the property is not geometric, or if the CRS is not set
059:             * 
060:             * @param propertyName
061:             * @return
062:             */
063:            private CoordinateReferenceSystem findPropertyCRS(
064:                    PropertyName propertyName) {
065:                AttributeType at = (AttributeType) propertyName
066:                        .evaluate(featureType);
067:                if (at instanceof  GeometryAttributeType) {
068:                    GeometryAttributeType gat = (GeometryAttributeType) at;
069:                    return gat.getCoordinateSystem();
070:                } else {
071:                    return null;
072:                }
073:            }
074:
075:            public Object visit(BBOX filter, Object extraData) {
076:                // if no srs is specified we can't transform anyways
077:                String srs = filter.getSRS();
078:                if (srs == null || "".equals(srs.trim()))
079:                    return super .visit(filter, extraData);
080:
081:                try {
082:                    // grab the original envelope data
083:                    double minx = filter.getMinX();
084:                    double miny = filter.getMinY();
085:                    double maxx = filter.getMaxX();
086:                    double maxy = filter.getMaxY();
087:                    CoordinateReferenceSystem crs = CRS.decode(srs);
088:
089:                    // grab the property data
090:                    String propertyName = filter.getPropertyName();
091:                    CoordinateReferenceSystem targetCrs = findPropertyCRS(factory
092:                            .property(propertyName));
093:
094:                    // if there is a mismatch, reproject and replace
095:                    if (crs != null && targetCrs != null
096:                            && !CRS.equalsIgnoreMetadata(crs, targetCrs)) {
097:                        ReferencedEnvelope envelope = new ReferencedEnvelope(
098:                                minx, maxx, miny, maxy, crs);
099:                        envelope = envelope.transform(targetCrs, true);
100:                        minx = envelope.getMinX();
101:                        miny = envelope.getMinY();
102:                        maxx = envelope.getMaxX();
103:                        maxy = envelope.getMaxY();
104:                        srs = targetCrs.getIdentifiers().iterator().next()
105:                                .toString();
106:                    }
107:
108:                    return getFactory(extraData).bbox(propertyName, minx, miny,
109:                            maxx, maxy, srs);
110:                } catch (Exception e) {
111:                    throw new RuntimeException("Could not decode srs '" + srs
112:                            + "'", e);
113:                }
114:
115:            }
116:
117:            public Object visit(PropertyIsEqualTo filter, Object extraData) {
118:                return new BinaryComparisonTransformer() {
119:
120:                    Object cloneFilter(BinaryComparisonOperator filter,
121:                            Object extraData) {
122:                        return ReprojectingFilterVisitor.super .visit(
123:                                (PropertyIsEqualTo) filter, extraData);
124:                    }
125:
126:                    Object cloneFilter(BinaryComparisonOperator bso,
127:                            Object extraData, Expression ex1, Expression ex2) {
128:                        return factory.equal(ex1, ex2, bso.isMatchingCase());
129:                    }
130:                }.transform(filter, extraData);
131:            }
132:
133:            public Object visit(PropertyIsNotEqualTo filter, Object extraData) {
134:                return new BinaryComparisonTransformer() {
135:
136:                    Object cloneFilter(BinaryComparisonOperator filter,
137:                            Object extraData) {
138:                        return ReprojectingFilterVisitor.super .visit(
139:                                (PropertyIsNotEqualTo) filter, extraData);
140:                    }
141:
142:                    Object cloneFilter(BinaryComparisonOperator bso,
143:                            Object extraData, Expression ex1, Expression ex2) {
144:                        return factory.notEqual(ex1, ex2, bso.isMatchingCase());
145:                    }
146:                }.transform(filter, extraData);
147:            }
148:
149:            public Object visit(Beyond filter, Object extraData) {
150:                return new GeometryFilterTransformer() {
151:
152:                    Object cloneFilter(BinarySpatialOperator filter,
153:                            Object extraData) {
154:                        return ReprojectingFilterVisitor.super .visit(
155:                                (Beyond) filter, extraData);
156:                    }
157:
158:                    Object cloneFilter(BinarySpatialOperator bso,
159:                            Object extraData, Expression ex1, Expression ex2) {
160:                        Beyond filter = (Beyond) bso;
161:                        return factory.beyond(ex1, ex2, filter.getDistance(),
162:                                filter.getDistanceUnits());
163:                    }
164:                }.transform(filter, extraData);
165:            }
166:
167:            public Object visit(Contains filter, Object extraData) {
168:                return new GeometryFilterTransformer() {
169:
170:                    Object cloneFilter(BinarySpatialOperator filter,
171:                            Object extraData) {
172:                        return ReprojectingFilterVisitor.super .visit(
173:                                (Contains) filter, extraData);
174:                    }
175:
176:                    Object cloneFilter(BinarySpatialOperator bso,
177:                            Object extraData, Expression ex1, Expression ex2) {
178:                        return factory.contains(ex1, ex2);
179:                    }
180:                }.transform(filter, extraData);
181:            }
182:
183:            public Object visit(Crosses filter, Object extraData) {
184:                return new GeometryFilterTransformer() {
185:
186:                    Object cloneFilter(BinarySpatialOperator filter,
187:                            Object extraData) {
188:                        return ReprojectingFilterVisitor.super .visit(
189:                                (Crosses) filter, extraData);
190:                    }
191:
192:                    Object cloneFilter(BinarySpatialOperator bso,
193:                            Object extraData, Expression ex1, Expression ex2) {
194:                        return factory.crosses(ex1, ex2);
195:                    }
196:                }.transform(filter, extraData);
197:            }
198:
199:            public Object visit(Disjoint filter, Object extraData) {
200:                return new GeometryFilterTransformer() {
201:
202:                    Object cloneFilter(BinarySpatialOperator filter,
203:                            Object extraData) {
204:                        return ReprojectingFilterVisitor.super .visit(
205:                                (Disjoint) filter, extraData);
206:                    }
207:
208:                    Object cloneFilter(BinarySpatialOperator bso,
209:                            Object extraData, Expression ex1, Expression ex2) {
210:                        return factory.disjoint(ex1, ex2);
211:                    }
212:                }.transform(filter, extraData);
213:            }
214:
215:            public Object visit(DWithin filter, Object extraData) {
216:                return new GeometryFilterTransformer() {
217:
218:                    Object cloneFilter(BinarySpatialOperator filter,
219:                            Object extraData) {
220:                        return ReprojectingFilterVisitor.super .visit(
221:                                (DWithin) filter, extraData);
222:                    }
223:
224:                    Object cloneFilter(BinarySpatialOperator bso,
225:                            Object extraData, Expression ex1, Expression ex2) {
226:                        DWithin filter = (DWithin) bso;
227:                        return factory.dwithin(ex1, ex2, filter.getDistance(),
228:                                filter.getDistanceUnits());
229:                    }
230:                }.transform(filter, extraData);
231:            }
232:
233:            public Object visit(Intersects filter, Object extraData) {
234:                return new GeometryFilterTransformer() {
235:
236:                    Object cloneFilter(BinarySpatialOperator filter,
237:                            Object extraData) {
238:                        return ReprojectingFilterVisitor.super .visit(
239:                                (Intersects) filter, extraData);
240:                    }
241:
242:                    Object cloneFilter(BinarySpatialOperator bso,
243:                            Object extraData, Expression ex1, Expression ex2) {
244:                        return factory.intersects(ex1, ex2);
245:                    }
246:                }.transform(filter, extraData);
247:            }
248:
249:            public Object visit(Overlaps filter, Object extraData) {
250:                return new GeometryFilterTransformer() {
251:
252:                    Object cloneFilter(BinarySpatialOperator filter,
253:                            Object extraData) {
254:                        return ReprojectingFilterVisitor.super .visit(
255:                                (Overlaps) filter, extraData);
256:                    }
257:
258:                    Object cloneFilter(BinarySpatialOperator bso,
259:                            Object extraData, Expression ex1, Expression ex2) {
260:                        return factory.overlaps(ex1, ex2);
261:                    }
262:                }.transform(filter, extraData);
263:            }
264:
265:            public Object visit(Touches filter, Object extraData) {
266:                return new GeometryFilterTransformer() {
267:
268:                    Object cloneFilter(BinarySpatialOperator filter,
269:                            Object extraData) {
270:                        return ReprojectingFilterVisitor.super .visit(
271:                                (Touches) filter, extraData);
272:                    }
273:
274:                    Object cloneFilter(BinarySpatialOperator bso,
275:                            Object extraData, Expression ex1, Expression ex2) {
276:                        return factory.touches(ex1, ex2);
277:                    }
278:                }.transform(filter, extraData);
279:            }
280:
281:            public Object visit(Within filter, Object extraData) {
282:                return new GeometryFilterTransformer() {
283:
284:                    Object cloneFilter(BinarySpatialOperator filter,
285:                            Object extraData) {
286:                        return ReprojectingFilterVisitor.super .visit(
287:                                (Within) filter, extraData);
288:                    }
289:
290:                    Object cloneFilter(BinarySpatialOperator bso,
291:                            Object extraData, Expression ex1, Expression ex2) {
292:                        return factory.within(ex1, ex2);
293:                    }
294:                }.transform(filter, extraData);
295:            }
296:
297:            public Object visit(Equals filter, Object extraData) {
298:                return new GeometryFilterTransformer() {
299:
300:                    Object cloneFilter(BinarySpatialOperator filter,
301:                            Object extraData) {
302:                        return ReprojectingFilterVisitor.super .visit(
303:                                (Equals) filter, extraData);
304:                    }
305:
306:                    Object cloneFilter(BinarySpatialOperator bso,
307:                            Object extraData, Expression ex1, Expression ex2) {
308:                        return factory.equal(ex1, ex2);
309:                    }
310:                }.transform(filter, extraData);
311:            }
312:
313:            /**
314:             * Factors out most of the logic needed to reproject a geometry filter, leaving subclasses
315:             * only the need to call the appropriate methods to create the new binary spatial filter
316:             * @author Andrea Aime - The Open Plannig Project
317:             *
318:             */
319:            private abstract class GeometryFilterTransformer {
320:                Object transform(BinarySpatialOperator filter, Object extraData) {
321:                    // check working assumptions, first expression is a property
322:                    if (!(filter.getExpression1() instanceof  PropertyName))
323:                        throw new IllegalArgumentException(
324:                                "Binary geometry filter, but first expression "
325:                                        + "is not a property name? (it's a "
326:                                        + filter.getExpression1().getClass()
327:                                        + ")");
328:                    CoordinateReferenceSystem propertyCrs = findPropertyCRS((PropertyName) filter
329:                            .getExpression1());
330:
331:                    if (propertyCrs == null)
332:                        return cloneFilter(filter, extraData);
333:
334:                    // second expression is a geometry literal
335:                    if (!(filter.getExpression2() instanceof  Literal))
336:                        throw new IllegalArgumentException(
337:                                "Binary geometry filter, but second expression "
338:                                        + "is not a literal? (it's a "
339:                                        + filter.getExpression1().getClass()
340:                                        + ")");
341:                    Object value = ((Literal) filter.getExpression2())
342:                            .getValue();
343:                    if (!(value instanceof  Geometry))
344:                        throw new IllegalArgumentException(
345:                                "Binary geometry filter, but second expression "
346:                                        + "is not a geometry literal? (it's a "
347:                                        + value.getClass() + ")");
348:                    Geometry geom = (Geometry) value;
349:
350:                    // does it make sense to proceed?
351:                    if (geom.getUserData() == null
352:                            || !(geom.getUserData() instanceof  CoordinateReferenceSystem))
353:                        return cloneFilter(filter, extraData);
354:
355:                    try {
356:                        // reproject
357:                        CoordinateReferenceSystem geomCRS = (CoordinateReferenceSystem) geom
358:                                .getUserData();
359:                        Geometry transformed = JTS.transform(geom, CRS
360:                                .findMathTransform(geomCRS, propertyCrs, true));
361:                        transformed.setUserData(propertyCrs);
362:
363:                        // clone
364:                        Expression ex1 = (Expression) filter.getExpression1()
365:                                .accept(ReprojectingFilterVisitor.this ,
366:                                        extraData);
367:                        Expression ex2 = factory.literal(transformed);
368:                        return cloneFilter(filter, extraData, ex1, ex2);
369:                    } catch (Exception e) {
370:                        throw new RuntimeException(
371:                                "Could not reproject geometry filter " + filter,
372:                                e);
373:                    }
374:                }
375:
376:                /**
377:                 * Straight cloning using cascaded visit
378:                 * 
379:                 * @param filter
380:                 * @param extraData
381:                 * @return
382:                 */
383:                abstract Object cloneFilter(BinarySpatialOperator filter,
384:                        Object extraData);
385:
386:                /**
387:                 * Clone with the provided parameters as first and second expressions
388:                 * 
389:                 * @param filter
390:                 * @param extraData
391:                 * @param ex1
392:                 * @param ex2
393:                 * @return
394:                 */
395:                abstract Object cloneFilter(BinarySpatialOperator filter,
396:                        Object extraData, Expression ex1, Expression ex2);
397:            }
398:
399:            /**
400:             * Factors out most of the logic needed to reproject a binary comparison filter, leaving subclasses
401:             * only the need to call the appropriate methods to create the new binary spatial filter
402:             * @author Andrea Aime - The Open Plannig Project
403:             *
404:             */
405:            private abstract class BinaryComparisonTransformer {
406:                Object transform(BinaryComparisonOperator filter,
407:                        Object extraData) {
408:                    // check working assumptions, first expression is a property
409:                    if (!(filter.getExpression1() instanceof  PropertyName))
410:                        throw new IllegalArgumentException(
411:                                "Binary geometry filter, but first expression "
412:                                        + "is not a property name? (it's a "
413:                                        + filter.getExpression1().getClass()
414:                                        + ")");
415:                    CoordinateReferenceSystem propertyCrs = findPropertyCRS((PropertyName) filter
416:                            .getExpression1());
417:
418:                    // we have to reproject only if the property is geometric and is compared against
419:                    // a geometric literal
420:                    if (!(propertyCrs != null
421:                            && (filter.getExpression2() instanceof  Literal) && ((Literal) filter
422:                            .getExpression2()).getValue() instanceof  Geometry))
423:                        return cloneFilter(filter, extraData);
424:
425:                    // extract the geometry
426:                    Object value = ((Literal) filter.getExpression2())
427:                            .getValue();
428:                    Geometry geom = (Geometry) value;
429:
430:                    // does it make sense to proceed?
431:                    if (geom.getUserData() == null
432:                            || !(geom.getUserData() instanceof  CoordinateReferenceSystem))
433:                        return cloneFilter(filter, extraData);
434:
435:                    try {
436:                        // reproject
437:                        CoordinateReferenceSystem geomCRS = (CoordinateReferenceSystem) geom
438:                                .getUserData();
439:                        Geometry transformed = JTS.transform(geom, CRS
440:                                .findMathTransform(geomCRS, propertyCrs, true));
441:                        transformed.setUserData(propertyCrs);
442:
443:                        // clone
444:                        Expression ex1 = (Expression) filter.getExpression1()
445:                                .accept(ReprojectingFilterVisitor.this ,
446:                                        extraData);
447:                        Expression ex2 = factory.literal(transformed);
448:                        return cloneFilter(filter, extraData, ex1, ex2);
449:                    } catch (Exception e) {
450:                        throw new RuntimeException(
451:                                "Could not reproject geometry filter " + filter,
452:                                e);
453:                    }
454:                }
455:
456:                /**
457:                 * Straight cloning using cascaded visit
458:                 * 
459:                 * @param filter
460:                 * @param extraData
461:                 * @return
462:                 */
463:                abstract Object cloneFilter(BinaryComparisonOperator filter,
464:                        Object extraData);
465:
466:                /**
467:                 * Clone with the provided parameters as first and second expressions
468:                 * 
469:                 * @param filter
470:                 * @param extraData
471:                 * @param ex1
472:                 * @param ex2
473:                 * @return
474:                 */
475:                abstract Object cloneFilter(BinaryComparisonOperator filter,
476:                        Object extraData, Expression ex1, Expression ex2);
477:
478:            }
479:
480:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.