Source Code Cross Referenced for SLDInlineFeatureParser.java in  » GIS » GeoTools-2.4.1 » org » geotools » styling » 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 » GeoTools 2.4.1 » org.geotools.styling 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2005-2006, GeoTools Project Managment Committee (PMC)
005:         *    
006:         *    This library is free software; you can redistribute it and/or
007:         *    modify it under the terms of the GNU Lesser General Public
008:         *    License as published by the Free Software Foundation;
009:         *    version 2.1 of the License.
010:         *
011:         *    This library is distributed in the hope that it will be useful,
012:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         *    Lesser General Public License for more details.
015:         */
016:        package org.geotools.styling;
017:
018:        import java.net.URI;
019:        import java.util.ArrayList;
020:        import java.util.Hashtable;
021:
022:        import org.geotools.data.memory.MemoryDataStore;
023:        import org.geotools.feature.AttributeType;
024:        import org.geotools.feature.AttributeTypeFactory;
025:        import org.geotools.feature.Feature;
026:        import org.geotools.feature.FeatureType;
027:        import org.geotools.feature.FeatureTypeBuilder;
028:        import org.geotools.feature.FeatureTypeFactory;
029:        import org.geotools.filter.ExpressionDOMParser;
030:        import org.geotools.referencing.CRS;
031:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
032:        import org.w3c.dom.NamedNodeMap;
033:        import org.w3c.dom.Node;
034:        import org.w3c.dom.NodeList;
035:
036:        import com.vividsolutions.jts.geom.Geometry;
037:
038:        public class SLDInlineFeatureParser {
039:
040:            /** hash table that takes a epsg# to its definition**/
041:            private static Hashtable SRSLookup = new Hashtable();
042:
043:            public FeatureType featureType = null;
044:            public MemoryDataStore dataStore = null;
045:            Node rootNode = null;
046:            ArrayList features = new ArrayList();
047:            CoordinateReferenceSystem SRS = null; // default EPSG#.
048:
049:            private static int uniqueNumber = 0;
050:
051:            public SLDInlineFeatureParser(Node root) throws Exception {
052:                //handle FeatureCollection or Feature Tag
053:
054:                boolean isFeatureCollection = false;
055:
056:                if (!(isSimple(root))) //make sure this isnt too complex to parse easily.
057:                {
058:                    throw new Exception(
059:                            "couldnt parse the SLD Inline features!");//shouldnt get here
060:                }
061:                Node fc = getNode(root, "FeatureCollection");
062:                if (fc != null) {
063:                    isFeatureCollection = true;
064:                    root = fc;//decend down one level
065:                }
066:
067:                featureType = makeFeatureType(root, isFeatureCollection);
068:                if (featureType == null)
069:                    throw new Exception(
070:                            "SLD InlineFeature Parser - couldnt determine a FeatureType.  See help for whats supported.");//shouldnt get here
071:
072:                makeFeatures(root, isFeatureCollection);
073:                if (features.size() == 0)
074:                    throw new Exception(
075:                            "SLD InlineFeature Parser - didnt find any features!");
076:
077:                buildStore();
078:            }
079:
080:            /**
081:             *   1. we have a FeatureType (cf. makeFeatureType)
082:             *   2. we iterate through either the featureCollection or the _Feature set
083:             *   3.      we build a Feature for each element of the set
084:             *   4. we stick it in the features list
085:             * 
086:             *  For example:
087:             * 
088:             *    <InlineFeature>
089:             *       <Dave>
090:             *            ...
091:             *       </Dave>
092:             *       <Dave>
093:             *             ...
094:             *       </Dave>
095:             *    </InlineFeature>
096:             * 
097:             *    --- OR ----
098:             * 
099:             * <InlineFeature>
100:             *    <FeatureCollection>
101:             *       <featureMember>
102:             *          <Dave>
103:             *               ...
104:             *          </Dave>
105:             *       </featureMember>
106:             *       <featureMember>
107:             *          <Dave>
108:             *               ...
109:             *         </Dave>
110:             *       </featureMember>
111:             *    </FeatureCollection>
112:             * </InlineFeature>
113:             * 	
114:             * 
115:             * @param root will point at either "<InlineFeature>" or "<FeatureCollection>
116:             */
117:            private void makeFeatures(Node root, boolean isCollection)
118:                    throws Exception {
119:                //iterate through each of the elements inside the root		
120:
121:                NodeList children = root.getChildNodes();
122:
123:                for (int i = 0; i < children.getLength(); i++) {
124:                    Node child = children.item(i);
125:
126:                    if ((child == null)
127:                            || (child.getNodeType() != Node.ELEMENT_NODE)) {
128:                        continue;
129:                    }
130:                    String childName = child.getLocalName();
131:                    if (childName == null)
132:                        childName = child.getNodeName();
133:                    if (childName.equalsIgnoreCase("boundedBy")) //be nice and ignore this
134:                        continue;
135:
136:                    if (isCollection) {
137:                        //decend into the featureMember
138:                        child = descend(child);
139:                    }
140:                    if (child == null)
141:                        throw new Exception(
142:                                "SLD inlineFeature Parser - couldnt extract a feature from the dom.");
143:
144:                    Feature f = parseFeature(child, featureType);
145:                    features.add(f);
146:                }
147:            }
148:
149:            /**
150:             *  simple - child points to a <featureMember>, we want it to point to the element inside!
151:             * 
152:             *  in general, this will find the 1st element node inside the node.
153:             * 
154:             * @param child
155:             */
156:            private Node descend(Node root) {
157:                NodeList children = root.getChildNodes();
158:
159:                for (int i = 0; i < children.getLength(); i++) {
160:                    Node child = children.item(i);
161:
162:                    if ((child == null)
163:                            || (child.getNodeType() != Node.ELEMENT_NODE)) {
164:                        continue;
165:                    }
166:                    return child;
167:                }
168:                return null; //nothing inside
169:            }
170:
171:            /**
172:             *  Parse the feature pointed to by this node.
173:             * 
174:             *  See the makeFeatureType() function - this is very similiar except it does a little parsing.
175:             * 
176:             * 
177:             * @param feature - points to the actual feature ie. "<Person>"
178:             * @param featureType
179:             */
180:            private Feature parseFeature(Node feature, FeatureType featureType)
181:                    throws Exception {
182:                Object[] nullAtts = new Object[featureType.getAttributeCount()]; // initialized to nulls
183:                Feature f = featureType.create(nullAtts);
184:
185:                NodeList children = feature.getChildNodes();
186:                for (int i = 0; i < children.getLength(); i++) {
187:                    Node child = children.item(i);
188:                    if ((child == null)
189:                            || (child.getNodeType() != Node.ELEMENT_NODE)) {
190:                        continue;
191:                    }
192:                    String childName = child.getLocalName();
193:                    if (childName == null) {
194:                        childName = child.getNodeName();
195:                    }
196:
197:                    Object value = getValue(child);
198:                    try {
199:                        f.setAttribute(childName, value);
200:                    } catch (Exception e) {
201:                        e.printStackTrace(); // we hid this from the user
202:                    }
203:                }
204:                return f;
205:            }
206:
207:            /**
208:             *  Given a node, determine if its a geometry or a string attribute
209:             *  return the corresponding value.
210:             * @param child
211:             */
212:            private Object getValue(Node root) throws Exception {
213:                NodeList children = root.getChildNodes();
214:                StringBuffer strVal = new StringBuffer();
215:
216:                for (int i = 0; i < children.getLength(); i++) {
217:                    Node child = children.item(i);
218:                    if ((child == null)) {
219:                        continue;
220:                    }
221:                    if (child.getNodeType() == Node.TEXT_NODE) {
222:                        strVal.append(child.getNodeValue()); //might get here multiple times -- see sax spec
223:                    }
224:                    //we have a nested element!  Assume its a geometry
225:                    if (child.getNodeType() == Node.ELEMENT_NODE) {
226:                        return parseGeometry(child);
227:                    }
228:                }
229:                return strVal;
230:            }
231:
232:            /**
233:             *  <Person>
234:             *     <location>
235:             *       <gml:Point>...
236:             *       </gml:Point>
237:             *     </location>
238:             *   </Person>
239:             * 
240:             *  Decend a level and then pass it off to the geometry parser.
241:             *  
242:             * NOTE: also handles SRS information:
243:             * 
244:             * <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
245:             * 
246:             *  TODO: handle more than just epsg for CRS
247:             * 
248:             * @param root  -- points to "<gml:Point>"
249:             */
250:            private Geometry parseGeometry(Node root) throws Exception {
251:                NamedNodeMap atts = root.getAttributes();
252:                if (SRS == null) //try to avoid parsing more than once.
253:                {
254:                    Node srsName = atts.getNamedItem("srsName");
255:                    if (srsName != null) {
256:                        parseSRS(srsName.getNodeValue());
257:                    }
258:                }
259:                return ExpressionDOMParser.parseGML(root);
260:            }
261:
262:            /**
263:             * 
264:             * Checks to make sure we're not going to shoot ourselves in the foot.
265:             *    if InlineFeature has a FeatureCollection, then thats the only node
266:             *           ie. no set of FeatureCollections or FeatureCollection mixed with a set of Feature 
267:             * 
268:             *    Other stuff as we think of them.
269:             * 
270:             * @param root SLD root node -- "InlineFeature"
271:             * @return true if okay, otherwise exception
272:             */
273:            private boolean isSimple(Node root) throws Exception {
274:                // if there's a <FeatureCollection>, thats the only child
275:                // if there was a <FeatureCollection>, then descend into it
276:                // check to make sure there are only <featureMember> in it
277:
278:                int foundFeature = 0;
279:                int foundFC = 0;
280:
281:                Node fcNode = null;
282:                String featureName = null;
283:
284:                NodeList children = root.getChildNodes();
285:
286:                for (int i = 0; i < children.getLength(); i++) {
287:                    Node child = children.item(i);
288:
289:                    if ((child == null)
290:                            || (child.getNodeType() != Node.ELEMENT_NODE)) {
291:                        continue;
292:                    }
293:                    String childName = child.getLocalName();
294:                    if (childName == null)
295:                        childName = child.getNodeName();
296:
297:                    if (childName.equalsIgnoreCase("FeatureCollection")) {
298:                        (foundFC)++;
299:                        fcNode = child;
300:                    } else {
301:                        if (featureName == null)
302:                            featureName = childName;
303:                        if (!(childName.equalsIgnoreCase(featureName)))
304:                            throw new Exception(
305:                                    "SLD inline feature parser  - it appear that there is >1 feature type present.  I got a "
306:                                            + childName
307:                                            + " when I was expecting a "
308:                                            + featureName + " tag");
309:                    }
310:                }
311:                if (foundFC > 1)
312:                    throw new Exception(
313:                            "SLD - UserLayer, inline feature parser - found >1 FeatureCollection.  Not supported");
314:                if ((foundFC > 0) && (foundFeature > 0))
315:                    throw new Exception(
316:                            "SLD - UserLayer, inline feature parser - found  FeatureCollection and featureMembers.  Not supported");
317:
318:                if (foundFC == 0)
319:                    return true;
320:
321:                featureName = null;
322:
323:                //otherwise decend into the featurecollection and check to make sure it only contains features
324:                children = fcNode.getChildNodes();
325:
326:                for (int i = 0; i < children.getLength(); i++) {
327:                    Node child = children.item(i);
328:
329:                    if ((child == null)
330:                            || (child.getNodeType() != Node.ELEMENT_NODE)) {
331:                        continue;
332:                    }
333:                    String childName = child.getLocalName();
334:                    if (childName == null)
335:                        childName = child.getNodeName();
336:                    if (childName.equalsIgnoreCase("featureMember"))
337:                        foundFeature++;
338:                    else if (childName.equalsIgnoreCase("boundedBy")) {
339:                        //this is okay -- we'll be nice and ignore it.
340:                    } else if (childName.equalsIgnoreCase("FeatureCollection")) {
341:                        throw new Exception(
342:                                "SLD - UserLayer, inline feature parser - found a node of type FeatureCollection.  Expected a featureMember - dont support nested collections.");
343:
344:                    } else
345:                        throw new Exception(
346:                                "SLD - UserLayer, inline feature parser - found a node of type '"
347:                                        + child.getLocalName()
348:                                        + "' and dont understand it.  Expected a featureMember.");
349:                }
350:
351:                return true;
352:            }
353:
354:            /**
355:             * 
356:             */
357:            private void buildStore() {
358:                dataStore = new MemoryDataStore((Feature[]) features
359:                        .toArray(new Feature[features.size()]));
360:            }
361:
362:            /**
363:             *  1. get an actual Feature Node 
364:             *  2. go through each of its subtags
365:             *  3. if that subtag contains a geometry, then it an attribute of type geometry, otherwise string
366:             * 
367:             * NOTE: we set the namespace to be "http://temp.inline.feature.sld.com"
368:             * NOTE: we set the featuretype name to be whatever the enclosing tag is.  For example:
369:             * <FeatureCollection>
370:             *   <gml:featureMember>
371:             *       <tiger:point_landmark fid="point_landmark.490053">
372:             *            <tiger:wkb_geometry>
373:             *   	         <gml:Point srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
374:             *   	             <gml:coordinates decimal="." cs="," ts=" ">-73.983597,40.736308</gml:coordinates>
375:             *   	         </gml:Point>
376:             *   	      </tiger:wkb_geometry>
377:             *   	      <tiger:laname>Cabrini Medical Center</tiger:laname>
378:             *       </tiger:point_landmark>
379:             *   <gml:featureMember>
380:             * </FeatureCollection>
381:             * 
382:             *   Would have a Featuretype name of "tiger:wkb_geometry" with 2 attributes:
383:             *       wkb_geometry  -- geometry
384:             *       laname        -- string
385:             * 
386:             * @param root
387:             */
388:            private FeatureType makeFeatureType(Node root, boolean isCollection)
389:                    throws Exception {
390:                Node feature = null;
391:                //get a Feature node
392:                Node featureMember = root;
393:                if (isCollection)
394:                    featureMember = getNode(root, "featureMember");
395:
396:                //next node under featureMember what we want.  Unless its a boundedBy, in which case we dont want it.
397:                NodeList children = featureMember.getChildNodes();
398:
399:                // look for next element that's not "boundedBy"
400:                for (int i = 0; i < children.getLength(); i++) {
401:                    Node child = children.item(i);
402:                    if ((child == null)
403:                            || (child.getNodeType() != Node.ELEMENT_NODE)) {
404:                        continue;
405:                    }
406:                    String childName = child.getLocalName();
407:                    if (childName == null) {
408:                        childName = child.getNodeName();
409:                    }
410:                    if (!(childName.equalsIgnoreCase("boundedBy"))) {
411:                        feature = child;
412:                        break;
413:                    }
414:                }
415:                if (feature == null)
416:                    throw new Exception(
417:                            "couldnt find a Feature in the Inline Features!");
418:
419:                //okay, we have a feature, we now need to figure out its feature type.
420:                // method:
421:                //   step through each node, its name is a new element in the Feature
422:                //   we look for any internal tags (nesting).  There there are, we check to see if its a geometry
423:                //   otherwise the type is string. 
424:                //   simple!
425:
426:                String featureName = feature.getLocalName();
427:                if (featureName == null) {
428:                    featureName = feature.getNodeName();
429:                }
430:
431:                //DJB:I considered making each featuretype unique (thats the uniquenumber), but decided against
432:                //    it so that the standard feature type filtering stuff would work ("<FeatureTypeStyle>" 
433:                //    and <FeatureTypeConsraint>
434:                FeatureTypeBuilder build = FeatureTypeFactory
435:                        .newInstance(featureName);
436:                build.setName(featureName);
437:                build
438:                        .setNamespace(new URI(
439:                                "http://temp.inline.feature.sld.com"));
440:
441:                children = feature.getChildNodes();
442:                for (int i = 0; i < children.getLength(); i++) {
443:                    Node child = children.item(i);
444:                    if ((child == null)
445:                            || (child.getNodeType() != Node.ELEMENT_NODE)) {
446:                        continue;
447:                    }
448:                    String childName = child.getLocalName();
449:                    if (childName == null) {
450:                        childName = child.getNodeName();
451:                    }
452:                    AttributeType attType = null;
453:                    //okay, have a tag, check to see if its a geometry
454:                    if (isGeometry(child)) {
455:                        // force full geometry parsing so that we get to know the declared SRS
456:                        getValue(child);
457:                        attType = AttributeTypeFactory.newAttributeType(
458:                                childName, Geometry.class, true, 0, null, SRS);
459:                    } else {
460:                        attType = AttributeTypeFactory.newAttributeType(
461:                                childName, String.class);
462:                    }
463:                    build.addType(attType);
464:                }
465:                return build.getFeatureType();
466:            }
467:
468:            /**
469:             *  looks for a nested attribute - assumes that this is a geometry.
470:             *  TODO: be much smarter
471:             * @param child
472:             */
473:            private boolean isGeometry(Node root) {
474:                NodeList children = root.getChildNodes();
475:                for (int i = 0; i < children.getLength(); i++) {
476:                    Node child = children.item(i);
477:                    if ((child == null)
478:                            || (child.getNodeType() != Node.ELEMENT_NODE)) {
479:                        continue;
480:                    }
481:                    //we have a nested element!
482:                    return true;
483:                }
484:                return false;
485:            }
486:
487:            /**
488:             *   Give a node and the name of a child of that node, find its (string) value.
489:             *   This doesnt do anything complex.
490:             *  
491:             * @param parentNode
492:             * @param wantedChildName
493:             */
494:            public Node getNode(Node parentNode, String wantedChildName) {
495:                NodeList children = parentNode.getChildNodes();
496:
497:                for (int i = 0; i < children.getLength(); i++) {
498:                    Node child = children.item(i);
499:
500:                    if ((child == null)
501:                            || (child.getNodeType() != Node.ELEMENT_NODE)) {
502:                        continue;
503:                    }
504:                    String childName = child.getLocalName();
505:                    if (childName == null) {
506:                        childName = child.getNodeName();
507:                    }
508:                    if (childName.equalsIgnoreCase(wantedChildName)) {
509:                        return child;
510:                    }
511:                }
512:                return null;
513:            }
514:
515:            public synchronized int getUID() {
516:                return uniqueNumber++;
517:            }
518:
519:            /**
520:             *  expected input:
521:             *  "http://www.opengis.net/gml/srs/epsg.xml#4326"
522:             *   NOTE: only supports epsg#s.
523:             * @param srs
524:             */
525:            private void parseSRS(String srs) throws Exception {
526:                if (srs == null)
527:                    return;
528:                String epsgCode = srs.substring(srs.indexOf('#') + 1);
529:                int srsnum = Integer.parseInt(epsgCode);
530:                SRS = getSRS(srsnum);
531:            }
532:
533:            /**
534:             *  simple way of getting epsg #.
535:             *  We cache them so that we dont have to keep reading the DB or the epsg.properties file.
536:             *   I cannot image a system with more than a dozen CRSs in it...
537:             * 
538:             * @param epsg
539:             */
540:            private CoordinateReferenceSystem getSRS(int epsg) throws Exception {
541:                CoordinateReferenceSystem result = (CoordinateReferenceSystem) SRSLookup
542:                        .get(new Integer(epsg));
543:                if (result == null) {
544:                    //make and add to hash
545:                    result = CRS.decode("EPSG:" + epsg);
546:                    SRSLookup.put(new Integer(epsg), result);
547:                }
548:                return result;
549:            }
550:
551:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.