Skip to content
Browse files

use single aggregate feature type for import

When faced with multiple schemas in a kml file, consolidate them all
into a single feature type instead of creating one per schema. This more
closely parallels the kml parser, which now adds the attributes to the
feature type itself.
  • Loading branch information...
1 parent 2ecef9b commit 4cb81d28166c8ba2eced1aee7195df4e22e72bf8 @rmarianski rmarianski committed
View
61 importer/src/main/java/org/opengeo/data/importer/format/KMLFileFormat.java
@@ -83,9 +83,9 @@ public FeatureReader read(ImportData data, ImportItem item) throws IOException {
}
ft = ftb.buildFeatureType();
MetadataMap metadata = fti.getMetadata();
- if (metadata.containsKey("importschemaname")) {
+ if (metadata.containsKey("importschemanames")) {
Map<Object, Object> userData = ft.getUserData();
- userData.put("schemaname", metadata.get("importschemaname"));
+ userData.put("schemanames", metadata.get("importschemanames"));
}
}
return read(ft, file);
@@ -180,25 +180,28 @@ public SimpleFeatureType convertParsedFeatureType(SimpleFeatureType ft, String n
SimpleFeatureType transformedType = kmlTransform.convertFeatureType(ft);
SimpleFeatureTypeBuilder ftb = new SimpleFeatureTypeBuilder();
ftb.init(transformedType);
+ Set<String> existringAttrNames = new HashSet<String>();
+ for (AttributeDescriptor ad : ft.getAttributeDescriptors()) {
+ existringAttrNames.add(ad.getLocalName());
+ }
+ for (String attr : untypedAttributes) {
+ if (!existringAttrNames.contains(attr)) {
+ ftb.add(attr, String.class);
+ }
+ }
ftb.setName(name);
ftb.setCRS(KML_CRS);
ftb.setSRS(KML_SRS);
- for (String attr : untypedAttributes) {
- ftb.add(attr, String.class);
- }
return ftb.buildFeatureType();
}
public List<SimpleFeatureType> parseFeatureTypes(String typeName, InputStream inputStream)
throws IOException {
- // the idea here is to iterate through the file, and ask for all schema and features
- // the features can have multiple associated schemas, as well as untyped attributes
- // our strategy here is to keep track of the different schemas, and create a separate item for each unique one
- // we also aggregate all the untyped attributes, and combine that with each schema
KMLRawReader reader = new KMLRawReader(inputStream,
KMLRawReader.ReadType.SCHEMA_AND_FEATURES);
- Collection<SimpleFeatureType> schemas = new ArrayList<SimpleFeatureType>();
Set<String> untypedAttributes = new HashSet<String>();
+ List<String> schemaNames = new ArrayList<String>();
+ List<SimpleFeatureType> schemas = new ArrayList<SimpleFeatureType>();
SimpleFeatureType aggregateFeatureType = null;
for (Object object : reader) {
if (object instanceof SimpleFeature) {
@@ -213,34 +216,24 @@ public SimpleFeatureType convertParsedFeatureType(SimpleFeatureType ft, String n
untypedAttributes.addAll(untypedData.keySet());
}
} else if (object instanceof SimpleFeatureType) {
- schemas.add((SimpleFeatureType) object);
+ SimpleFeatureType schema = (SimpleFeatureType) object;
+ schemas.add(schema);
+ schemaNames.add(schema.getName().getLocalPart());
}
}
if (aggregateFeatureType == null && schemas.isEmpty()) {
throw new IllegalArgumentException("No features found");
}
- List<SimpleFeatureType> featureTypes = null;
- if (schemas.isEmpty()) {
- featureTypes = Collections.singletonList(convertParsedFeatureType(aggregateFeatureType,
- typeName, untypedAttributes));
- } else {
- featureTypes = new ArrayList<SimpleFeatureType>(schemas.size());
- for (SimpleFeatureType schema : schemas) {
- String newTypeName = typeName + "-" + schema.getName().getLocalPart();
- SimpleFeatureType combinedType = null;
- if (aggregateFeatureType == null) {
- combinedType = schema;
- } else {
- combinedType = unionFeatureTypes(schema, aggregateFeatureType);
- }
- SimpleFeatureType ft = convertParsedFeatureType(combinedType, newTypeName,
- untypedAttributes);
- Map<Object, Object> userData = ft.getUserData();
- userData.put("schemaname", schema.getName().getLocalPart());
- featureTypes.add(ft);
- }
+ SimpleFeatureType featureType = aggregateFeatureType;
+ for (SimpleFeatureType schema : schemas) {
+ featureType = unionFeatureTypes(featureType, schema);
+ }
+ featureType = convertParsedFeatureType(featureType, typeName, untypedAttributes);
+ if (!schemaNames.isEmpty()) {
+ Map<Object, Object> userData = featureType.getUserData();
+ userData.put("schemanames", schemaNames);
}
- return featureTypes;
+ return Collections.singletonList(featureType);
}
@Override
@@ -277,9 +270,9 @@ public SimpleFeatureType convertParsedFeatureType(SimpleFeatureType ft, String n
resource.getMetadata().put("recalculate-bounds", Boolean.TRUE);
Map<Object, Object> userData = featureType.getUserData();
- if (userData.containsKey("schemaname")) {
+ if (userData.containsKey("schemanames")) {
MetadataMap metadata = resource.getMetadata();
- metadata.put("importschemaname", (Serializable) userData.get("schemaname"));
+ metadata.put("importschemanames", (Serializable) userData.get("schemanames"));
}
ImportItem item = new ImportItem(layer);
View
36 importer/src/main/java/org/opengeo/data/importer/format/KMLRawReader.java
@@ -2,7 +2,10 @@
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
@@ -38,15 +41,15 @@ public KMLRawReader(InputStream inputStream, KMLRawReader.ReadType readType,
parser = new PullParser(new KMLConfiguration(), inputStream, KML.Placemark,
KML.Schema);
} else {
- parser = new PullParser(new KMLConfiguration(), inputStream, KML.Placemark,
- KML.Schema, featureTypeSchemaName(featureType));
+ parser = new PullParser(new KMLConfiguration(), inputStream, pullParserArgs(
+ featureTypeSchemaNames(featureType), KML.Placemark, KML.Schema));
}
} else if (KMLRawReader.ReadType.FEATURES.equals(readType)) {
if (featureType == null) {
parser = new PullParser(new KMLConfiguration(), inputStream, KML.Placemark);
} else {
- parser = new PullParser(new KMLConfiguration(), inputStream, KML.Placemark,
- featureTypeSchemaName(featureType));
+ parser = new PullParser(new KMLConfiguration(), inputStream, pullParserArgs(
+ featureTypeSchemaNames(featureType), KML.Placemark));
}
} else {
throw new IllegalArgumentException("Unknown parse read type: " + readType.toString());
@@ -54,15 +57,26 @@ public KMLRawReader(InputStream inputStream, KMLRawReader.ReadType readType,
next = null;
}
- private QName featureTypeSchemaName(SimpleFeatureType featureType) {
+ private Object[] pullParserArgs(List<QName> featureTypeSchemaNames, Object... args) {
+ Object[] parserArgs = new Object[featureTypeSchemaNames.size() + args.length];
+ System.arraycopy(args, 0, parserArgs, 0, args.length);
+ System.arraycopy(featureTypeSchemaNames.toArray(), 0, parserArgs, args.length,
+ featureTypeSchemaNames.size());
+ return parserArgs;
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<QName> featureTypeSchemaNames(SimpleFeatureType featureType) {
Map<Object, Object> userData = featureType.getUserData();
- String name = null;
- if (userData.containsKey("schemaname")) {
- name = (String) userData.get("schemaname");
- } else {
- name = featureType.getName().getLocalPart();
+ if (userData.containsKey("schemanames")) {
+ List<String> names = (List<String>) userData.get("schemanames");
+ List<QName> qnames = new ArrayList<QName>(names.size());
+ for (String name : names) {
+ qnames.add(new QName(name));
+ }
+ return qnames;
}
- return new QName(name);
+ return Collections.emptyList();
}
private Object read() throws IOException {
View
9 importer/src/main/java/org/opengeo/data/importer/transform/KMLPlacemarkTransform.java
@@ -68,15 +68,6 @@ public SimpleFeature convertFeature(SimpleFeature old, SimpleFeatureType targetF
}
}
}
- @SuppressWarnings("unchecked")
- Map<String, Object> typedExtendedData = (Map<String, Object>) userData.get("TypedExtendedData");
- if (typedExtendedData != null) {
- for (Entry<String, Object> entry : typedExtendedData.entrySet()) {
- if (targetFeatureType.getDescriptor(entry.getKey()) != null) {
- newFeature.setAttribute(entry.getKey(), entry.getValue());
- }
- }
- }
return newFeature;
}
View
23 importer/src/test/java/org/opengeo/data/importer/format/KMLFileFormatTest.java
@@ -115,23 +115,15 @@ public void testMultipleSchemas() throws Exception {
+ "</Placemark></kml>";
List<SimpleFeatureType> featureTypes = kmlFileFormat.parseFeatureTypes("multiple",
IOUtils.toInputStream(kmlInput));
- assertEquals("Unexpected number of feature types", 2, featureTypes.size());
- SimpleFeatureType ft1 = featureTypes.get(0);
- SimpleFeatureType ft2 = featureTypes.get(1);
+ assertEquals("Unexpected number of feature types", 1, featureTypes.size());
+ SimpleFeatureType ft = featureTypes.get(0);
- FeatureReader<SimpleFeatureType, SimpleFeature> reader1 = kmlFileFormat.read(ft1,
+ FeatureReader<SimpleFeatureType, SimpleFeature> reader = kmlFileFormat.read(ft,
IOUtils.toInputStream(kmlInput));
- SimpleFeature feature1 = reader1.next();
+ SimpleFeature feature1 = reader.next();
assertNotNull("Expecting feature", feature1);
assertEquals("Invalid ext attr foo", 42, feature1.getAttribute("foo"));
- assertNull("Invalid attribute for first schema", feature1.getAttribute("bar"));
-
- FeatureReader<SimpleFeatureType, SimpleFeature> reader2 = kmlFileFormat.read(ft2,
- IOUtils.toInputStream(kmlInput));
- SimpleFeature feature2 = reader2.next();
- assertNotNull("Expecting feature", feature2);
- assertNull("Invalid attribute for second schema", feature2.getAttribute("foo"));
- assertEquals("Invalid ext attr bar", 4.2f, (Float) feature2.getAttribute("bar"), 0.01);
+ assertEquals("Invalid ext attr bar", 4.2f, (Float) feature1.getAttribute("bar"), 0.01);
}
public void testTypedAndUntyped() throws Exception {
@@ -164,8 +156,9 @@ public void testReadCustomSchema() throws Exception {
assertEquals("Unexpected number of feature types", 1, featureTypes.size());
SimpleFeatureType featureType = featureTypes.get(0);
Map<Object, Object> userData = featureType.getUserData();
- String schemaName = (String) userData.get("schemaname");
- assertEquals("Did not find expected schema name metadata", "myschema", schemaName);
+ List<String> schemaNames = (List<String>) userData.get("schemanames");
+ assertEquals(1, schemaNames.size());
+ assertEquals("Did not find expected schema name metadata", "myschema", schemaNames.get(0));
FeatureReader<SimpleFeatureType, SimpleFeature> reader = kmlFileFormat.read(featureType,
IOUtils.toInputStream(kmlInput));
SimpleFeature feature = reader.next();

0 comments on commit 4cb81d2

Please sign in to comment.
Something went wrong with that request. Please try again.