I've just tried the following with the KML Samples file Google provide and all works fine:
private ArrayList<SimpleFeature> features;
public ParseKML(String path) throws XMLStreamException, IOException, SAXException {
source = new File(path);
InputStream fis = new FileInputStream(source);
PullParser parser = new PullParser(new KMLConfiguration(), fis, KML.Placemark);
SimpleFeature f = null;
features = new ArrayList<SimpleFeature>();
while ((f = (SimpleFeature) parser.parse()) != null) {
features.add(f);
}
}
private SimpleFeatureCollection getFeatures() {
return DataUtilities.collection(features);
}
To read various file formats for rendering
GeoTools uses a DataStoreFinder mechanism that allows you to call it with a Map
of keys & parameters and then it searches all the available DataStoreFactories
to see which one can process those parameters. For your file based stores all you need to do is:
HashMap<String, Object> params = processParams(conv, parameters);
params.put("url",DataUtilities.fileToURL(f));
try {
DataStore ds = DataStoreFinder.getDataStore(params);
if (ds == null) {
//handle error
}
//read featureCollection
GeoTools takes care of the file endings etc and you can render the FeatureCollection
without the need to write and reparse a shapefile.
To Convert one file format to another
GeoTools makes this a relatively simple task - all you need is an input data store (and DataStoreFinder
will save you looking at file names) and an output DataStore
of the type you require and some code like:
Query query = new Query(inputName.getLocalPart(), filter);
SimpleFeatureCollection inFeatures = input.getFeatureSource(inputName).getFeatures(query);
Transaction transaction = new DefaultTransaction("create");
SimpleFeatureType schema = inFeatures.getSchema();
SimpleFeatureType outSchema = retypeForFormat(schema, output.getClass());
output.createSchema(outSchema);
SimpleFeatureSource featureSource = output.getFeatureSource(outputName);
if (featureSource instanceof SimpleFeatureStore) {
SimpleFeatureCollection collection;
if (outSchema != schema) {
List<SimpleFeature> feats = new ArrayList<SimpleFeature>();
FeatureIterator<SimpleFeature> features2 = inFeatures.features();
while (features2.hasNext()) {
SimpleFeature f = features2.next();
SimpleFeature reType = DataUtilities.reType(outSchema, f, true);
reType.setAttribute(outSchema.getGeometryDescriptor().getName(),
f.getAttribute(schema.getGeometryDescriptor().getName()));
feats.add(reType);
}
features2.close();
collection = new ListFeatureCollection(outSchema, feats);
} else {
collection = inFeatures;
}
SimpleFeatureStore outStore = (SimpleFeatureStore) featureSource;
outStore.setTransaction(transaction);
try {
List<FeatureId> ids = outStore.addFeatures(collection);
if (verbose) {
System.out.println("copied " + ids.size() + " features");
}
transaction.commit();
} catch (Exception problem) {
problem.printStackTrace();
transaction.rollback();
} finally {
transaction.close();
}
output.dispose();
return true;
}
There is a page in the manual which explains how DataStores work in greater detail. You may also benefit from working through the Feature tutorial.
But I suspect that rather than writing your own WMS you would be better off downloading and installing GeoServer which takes care of all of these issues for you.
Best Answer
No, it is very much possible to access any node in a KML file provided you don't miss out on the JAXB hierarchy: You may try something like below: