diff --git a/modules/extension/xsd/xsd-gml2/src/main/java/org/geotools/gml2/bindings/GML2ParsingUtils.java b/modules/extension/xsd/xsd-gml2/src/main/java/org/geotools/gml2/bindings/GML2ParsingUtils.java index 5877949ae09..b531ea16137 100644 --- a/modules/extension/xsd/xsd-gml2/src/main/java/org/geotools/gml2/bindings/GML2ParsingUtils.java +++ b/modules/extension/xsd/xsd-gml2/src/main/java/org/geotools/gml2/bindings/GML2ParsingUtils.java @@ -117,8 +117,14 @@ public static SimpleFeature parseFeature(ElementInstance instance, Node node, Ob } if (sfType == null) { + // let's use the CRS from the node (only if it's available) on the feature type + CoordinateReferenceSystem crs = null; + if (node.hasChild("boundedBy") && node.getChild("boundedBy").hasChild("Box")) { + crs = crs(node.getChild("boundedBy").getChild("Box")); + } + //build from element declaration - sfType = GML2ParsingUtils.featureType(decl, bwFactory); + sfType = GML2ParsingUtils.featureType(decl, bwFactory, crs); ftCache.put(sfType); } } else { @@ -174,6 +180,9 @@ public static SimpleFeatureType featureType(Node node) ftBuilder.setName(node.getComponent().getName()); ftBuilder.setNamespaceURI(node.getComponent().getNamespace()); ftBuilder.setCRS(null); //JD: set explicitly to null to avoid warning + + CoordinateReferenceSystem crs = null; + //mandatory gml attributes if (!node.hasChild("description")) { ftBuilder.add("description", String.class); @@ -185,6 +194,10 @@ public static SimpleFeatureType featureType(Node node) if (!node.hasChild("boundedBy")) { ftBuilder.add("boundedBy", ReferencedEnvelope.class); + } else { + if (node.getChild("boundedBy").hasChild("Box")) { + crs = crs(node.getChild("boundedBy").getChild("Box")); + } } //application schema defined attributes @@ -193,6 +206,11 @@ public static SimpleFeatureType featureType(Node node) String name = child.getComponent().getName(); Object valu = child.getValue(); + // if the next property is of type geometry, let's set its CRS + if (Geometry.class.isAssignableFrom(valu.getClass()) && crs != null) { + ftBuilder.crs(crs); + } + ftBuilder.add(name, (valu != null) ? valu.getClass() : Object.class); } @@ -202,13 +220,32 @@ public static SimpleFeatureType featureType(Node node) /** * Turns a xml type definition into a geotools feature type. * - * @param type - * The xml schema tupe. + * @param element + * The element declaration. + * @param bwFactory + * The binding walker factory. * * @return The corresponding geotools feature type. */ public static SimpleFeatureType featureType(XSDElementDeclaration element, BindingWalkerFactory bwFactory) throws Exception { + return featureType(element, bwFactory, null); + } + + /** + * Turns a xml type definition into a geotools feature type. + * + * @param element + * The element declaration. + * @param bwFactory + * The binding walker factory. + * @param crs + * The coordinate reference system to use on this feature type. + * + * @return The corresponding geotools feature type. + */ + public static SimpleFeatureType featureType(XSDElementDeclaration element, + BindingWalkerFactory bwFactory, CoordinateReferenceSystem crs) throws Exception { SimpleFeatureTypeBuilder ftBuilder = new SimpleFeatureTypeBuilder(); ftBuilder.setName(element.getName()); ftBuilder.setNamespaceURI(element.getTargetNamespace()); @@ -261,6 +298,11 @@ public void visit(Binding binding) { max = 1; } + // if the next property is of type geometry, let's set its CRS + if (Geometry.class.isAssignableFrom(theClass) && crs != null) { + ftBuilder.crs(crs); + } + // create the type ftBuilder.minOccurs(min).maxOccurs(max).add(property.getName(), theClass); @@ -412,6 +454,14 @@ else if (MultiPolygon.class.isAssignableFrom(clazz)) { if (crs != null) { gc.setUserData(crs); + + // since we're setting the CRS on the UserData object, might as well set the SRID for the geom + // collection + try { + gc.setSRID(CRS.lookupEpsgCode(crs, true)); + } catch (FactoryException e) { + // as long as the provided CRS is valid, this block will be unreachable + } } return gc;