Skip to content

Commit

Permalink
[GEOS-9014] Fixes layer iteration when generating kml files for download
Browse files Browse the repository at this point in the history
Factor out Sequence interface, replace with Iterator and fix GeneratorIterator

Starting test, rename layerIterator

Fixed and working layergroup kml test

Refactor kml.sequence package and classes, rename kml.iterator

comment out print line
  • Loading branch information
johngschulz committed Nov 21, 2018
1 parent 6b9dff2 commit e0d69e1
Show file tree
Hide file tree
Showing 15 changed files with 200 additions and 97 deletions.
Expand Up @@ -24,8 +24,8 @@
import org.geoserver.kml.KMLMapOutputFormat; import org.geoserver.kml.KMLMapOutputFormat;
import org.geoserver.kml.KmlEncodingContext; import org.geoserver.kml.KmlEncodingContext;
import org.geoserver.kml.decorator.KmlDecoratorFactory.KmlDecorator; import org.geoserver.kml.decorator.KmlDecoratorFactory.KmlDecorator;
import org.geoserver.kml.sequence.SequenceList; import org.geoserver.kml.iterator.IteratorList;
import org.geoserver.kml.sequence.WFSFeatureSequenceFactory; import org.geoserver.kml.iterator.WFSFeatureIteratorFactory;
import org.geoserver.platform.ServiceException; import org.geoserver.platform.ServiceException;
import org.geoserver.wfs.WFSInfo; import org.geoserver.wfs.WFSInfo;
import org.geotools.data.collection.ListFeatureCollection; import org.geotools.data.collection.ListFeatureCollection;
Expand Down Expand Up @@ -197,7 +197,7 @@ public void encode(Object obj, OutputStream os) throws Exception {
// create the streaming features // create the streaming features
context.setCurrentFeatureCollection(fc); context.setCurrentFeatureCollection(fc);
List<Feature> features = List<Feature> features =
new SequenceList<Feature>(new WFSFeatureSequenceFactory(context)); new IteratorList<Feature>(new WFSFeatureIteratorFactory(context));
context.addFeatures(folder, features); context.addFeatures(folder, features);
} }


Expand Down
Expand Up @@ -19,7 +19,7 @@
import org.geoserver.config.ServiceInfo; import org.geoserver.config.ServiceInfo;
import org.geoserver.kml.decorator.KmlDecoratorFactory; import org.geoserver.kml.decorator.KmlDecoratorFactory;
import org.geoserver.kml.decorator.KmlDecoratorFactory.KmlDecorator; import org.geoserver.kml.decorator.KmlDecoratorFactory.KmlDecorator;
import org.geoserver.kml.sequence.CompositeList; import org.geoserver.kml.iterator.CompositeList;
import org.geoserver.kml.utils.LookAtOptions; import org.geoserver.kml.utils.LookAtOptions;
import org.geoserver.ows.util.KvpUtils; import org.geoserver.ows.util.KvpUtils;
import org.geoserver.platform.GeoServerExtensions; import org.geoserver.platform.GeoServerExtensions;
Expand Down
Expand Up @@ -17,8 +17,8 @@
import org.geoserver.config.GeoServer; import org.geoserver.config.GeoServer;
import org.geoserver.config.ServiceInfo; import org.geoserver.config.ServiceInfo;
import org.geoserver.kml.decorator.KmlDecoratorFactory.KmlDecorator; import org.geoserver.kml.decorator.KmlDecoratorFactory.KmlDecorator;
import org.geoserver.kml.sequence.SequenceList; import org.geoserver.kml.iterator.IteratorList;
import org.geoserver.kml.sequence.WFSFeatureSequenceFactory; import org.geoserver.kml.iterator.WFSFeatureIteratorFactory;
import org.geoserver.platform.Operation; import org.geoserver.platform.Operation;
import org.geoserver.platform.ServiceException; import org.geoserver.platform.ServiceException;
import org.geoserver.wfs.WFSGetFeatureOutputFormat; import org.geoserver.wfs.WFSGetFeatureOutputFormat;
Expand Down Expand Up @@ -105,7 +105,7 @@ protected void write(
// create the streaming features // create the streaming features
context.setCurrentFeatureCollection(fc); context.setCurrentFeatureCollection(fc);
List<Feature> features = List<Feature> features =
new SequenceList<Feature>(new WFSFeatureSequenceFactory(context)); new IteratorList<Feature>(new WFSFeatureIteratorFactory(context));
context.addFeatures(folder, features); context.addFeatures(folder, features);
} }


Expand Down
Expand Up @@ -11,9 +11,9 @@
import java.util.List; import java.util.List;
import org.geoserver.kml.KmlEncodingContext; import org.geoserver.kml.KmlEncodingContext;
import org.geoserver.kml.decorator.KmlDecoratorFactory.KmlDecorator; import org.geoserver.kml.decorator.KmlDecoratorFactory.KmlDecorator;
import org.geoserver.kml.sequence.PlainFolderSequenceFactory; import org.geoserver.kml.iterator.IteratorFactory;
import org.geoserver.kml.sequence.SequenceFactory; import org.geoserver.kml.iterator.IteratorList;
import org.geoserver.kml.sequence.SequenceList; import org.geoserver.kml.iterator.PlainFolderIteratorFactory;
import org.geoserver.platform.ServiceException; import org.geoserver.platform.ServiceException;


/** /**
Expand Down Expand Up @@ -49,8 +49,8 @@ public Kml buildKMLDocument(KmlEncodingContext context) {


// create a generator that will generate a folder and feature dumps/ground overlays for each // create a generator that will generate a folder and feature dumps/ground overlays for each
// layer // layer
SequenceFactory<Feature> generatorFactory = new PlainFolderSequenceFactory(context); IteratorFactory<Feature> generatorFactory = new PlainFolderIteratorFactory(context);
SequenceList<Feature> folders = new SequenceList<Feature>(generatorFactory); IteratorList<Feature> folders = new IteratorList<Feature>(generatorFactory);
context.addFeatures(document, folders); context.addFeatures(document, folders);


return kml; return kml;
Expand Down
Expand Up @@ -3,10 +3,11 @@
* This code is licensed under the GPL 2.0 license, available at the root * This code is licensed under the GPL 2.0 license, available at the root
* application directory. * application directory.
*/ */
package org.geoserver.kml.sequence; package org.geoserver.kml.iterator;


import de.micromata.opengis.kml.v_2_2_0.Feature; import de.micromata.opengis.kml.v_2_2_0.Feature;
import de.micromata.opengis.kml.v_2_2_0.Folder; import de.micromata.opengis.kml.v_2_2_0.Folder;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.geoserver.kml.KmlEncodingContext; import org.geoserver.kml.KmlEncodingContext;
import org.geoserver.kml.decorator.KmlDecoratorFactory.KmlDecorator; import org.geoserver.kml.decorator.KmlDecoratorFactory.KmlDecorator;
Expand All @@ -19,35 +20,32 @@
import org.geotools.map.Layer; import org.geotools.map.Layer;


/** /**
* Base class for sequences that create one folder per layer * Base class for iterators that create one folder per layer
* *
* @author Andrea Aime - GeoSolutions * @author Andrea Aime - GeoSolutions
*/ */
public abstract class AbstractFolderSequenceFactory implements SequenceFactory<Feature> { public abstract class AbstractFolderIteratorFactory implements IteratorFactory<Feature> {


protected KmlEncodingContext context; protected KmlEncodingContext context;


protected List<KmlDecorator> decorators; protected List<KmlDecorator> decorators;


public AbstractFolderSequenceFactory(KmlEncodingContext context) { public AbstractFolderIteratorFactory(KmlEncodingContext context) {
this.context = context; this.context = context;
this.decorators = context.getDecoratorsForClass(Folder.class); this.decorators = context.getDecoratorsForClass(Folder.class);
} }


public abstract class AbstractFolderGenerator implements Sequence<Feature> { public abstract class AbstractFolderGenerator implements Iterator<Feature> {
protected int i = 0; Iterator layerIterator;

protected int size;


public AbstractFolderGenerator() { public AbstractFolderGenerator() {
this.size = context.getMapContent().layers().size(); this.layerIterator = context.getMapContent().layers().iterator();
} }


@Override @Override
public Feature next() { public Feature next() {
while (i < size) { while (hasNext()) {
List<Layer> layers = context.getMapContent().layers(); Layer layer = (Layer) layerIterator.next();
Layer layer = layers.get(i++);
context.setCurrentLayer(layer); context.setCurrentLayer(layer);


// setup the folder and let it be decorated // setup the folder and let it be decorated
Expand Down Expand Up @@ -94,6 +92,11 @@ public Feature next() {
return null; return null;
} }


@Override
public boolean hasNext() {
return layerIterator.hasNext();
}

/** /**
* Encodes the actual contents of the folder, besides the one generated by decorators * Encodes the actual contents of the folder, besides the one generated by decorators
* *
Expand Down
Expand Up @@ -3,7 +3,7 @@
* This code is licensed under the GPL 2.0 license, available at the root * This code is licensed under the GPL 2.0 license, available at the root
* application directory. * application directory.
*/ */
package org.geoserver.kml.sequence; package org.geoserver.kml.iterator;


import java.util.AbstractList; import java.util.AbstractList;
import java.util.Iterator; import java.util.Iterator;
Expand Down
Expand Up @@ -3,11 +3,12 @@
* This code is licensed under the GPL 2.0 license, available at the root * This code is licensed under the GPL 2.0 license, available at the root
* application directory. * application directory.
*/ */
package org.geoserver.kml.sequence; package org.geoserver.kml.iterator;


import de.micromata.opengis.kml.v_2_2_0.Feature; import de.micromata.opengis.kml.v_2_2_0.Feature;
import de.micromata.opengis.kml.v_2_2_0.Placemark; import de.micromata.opengis.kml.v_2_2_0.Placemark;
import java.util.EmptyStackException; import java.util.EmptyStackException;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import org.geoserver.kml.KmlEncodingContext; import org.geoserver.kml.KmlEncodingContext;
Expand All @@ -27,11 +28,11 @@
import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.simple.SimpleFeatureType;


/** /**
* Creates a sequence of Placemark objects mapping the vector contents of a layer * Creates a iterator of Placemark objects mapping the vector contents of a layer
* *
* @author Andrea Aime - GeoSolutions * @author Andrea Aime - GeoSolutions
*/ */
public class FeatureSequenceFactory implements SequenceFactory<Feature> { public class FeatureIteratorFactory implements IteratorFactory<Feature> {


static final String OUTPUT_MODE = "kmlOutputMode"; static final String OUTPUT_MODE = "kmlOutputMode";


Expand All @@ -47,7 +48,7 @@ public class FeatureSequenceFactory implements SequenceFactory<Feature> {


private boolean hasActiveRules; private boolean hasActiveRules;


public FeatureSequenceFactory(KmlEncodingContext context, FeatureLayer layer) { public FeatureIteratorFactory(KmlEncodingContext context, FeatureLayer layer) {
this.context = context; this.context = context;
this.features = context.getCurrentFeatureCollection(); this.features = context.getCurrentFeatureCollection();
WMSMapContent mapContent = context.getMapContent(); WMSMapContent mapContent = context.getMapContent();
Expand Down Expand Up @@ -88,11 +89,11 @@ private Style getSimplifiedStyle(WMSMapContent mc, Layer layer) {
} }


@Override @Override
public Sequence<Feature> newSequence() { public Iterator<Feature> newIterator() {
return new FeatureGenerator(hasActiveRules ? context.openIterator(features) : null); return new FeatureGenerator(hasActiveRules ? context.openIterator(features) : null);
} }


public class FeatureGenerator implements Sequence<Feature> { public class FeatureGenerator implements Iterator<Feature> {


private FeatureIterator fi; private FeatureIterator fi;


Expand Down Expand Up @@ -159,6 +160,11 @@ public Feature next() {
return null; return null;
} }


@Override
public boolean hasNext() {
return fi.hasNext();
}

private List<Symbolizer> getSymbolizers(Style style, SimpleFeature sf) { private List<Symbolizer> getSymbolizers(Style style, SimpleFeature sf) {
SymbolizerCollector collector = new SymbolizerCollector(sf); SymbolizerCollector collector = new SymbolizerCollector(sf);
style.accept(collector); style.accept(collector);
Expand Down
Expand Up @@ -3,15 +3,17 @@
* This code is licensed under the GPL 2.0 license, available at the root * This code is licensed under the GPL 2.0 license, available at the root
* application directory. * application directory.
*/ */
package org.geoserver.kml.sequence; package org.geoserver.kml.iterator;

import java.util.Iterator;


/** /**
* Builds a new Sequence * Builds a new Iterator
* *
* @author Andrea Aime - GeoSolutions * @author Andrea Aime - GeoSolutions
* @param <T> * @param <T>
*/ */
public interface SequenceFactory<T> { public interface IteratorFactory<T> {


Sequence<T> newSequence(); Iterator<T> newIterator();
} }
Expand Up @@ -3,7 +3,7 @@
* This code is licensed under the GPL 2.0 license, available at the root * This code is licensed under the GPL 2.0 license, available at the root
* application directory. * application directory.
*/ */
package org.geoserver.kml.sequence; package org.geoserver.kml.iterator;


import java.util.AbstractList; import java.util.AbstractList;
import java.util.Iterator; import java.util.Iterator;
Expand All @@ -15,22 +15,19 @@
* @author Andrea Aime - GeoSolutions * @author Andrea Aime - GeoSolutions
* @param <T> * @param <T>
*/ */
public class SequenceList<T> extends AbstractList<T> { public class IteratorList<T> extends AbstractList<T> {


public class GeneratorIterator implements Iterator<T> { public class GeneratorIterator implements Iterator<T> {


private Sequence<T> generator; private Iterator<T> generator;


private T item; public GeneratorIterator(Iterator<T> generator) {

public GeneratorIterator(Sequence<T> generator) {
this.generator = generator; this.generator = generator;
this.item = generator.next();
} }


@Override @Override
public boolean hasNext() { public boolean hasNext() {
return item != null; return generator.hasNext();
} }


@Override @Override
Expand All @@ -39,9 +36,7 @@ public T next() {
throw new NoSuchElementException(); throw new NoSuchElementException();
} }


T next = this.item; return generator.next();
this.item = generator.next();
return next;
} }


@Override @Override
Expand All @@ -50,15 +45,15 @@ public void remove() {
} }
} }


SequenceFactory<T> generatorFactory; IteratorFactory<T> generatorFactory;


public SequenceList(SequenceFactory<T> generatorFactory) { public IteratorList(IteratorFactory<T> generatorFactory) {
this.generatorFactory = generatorFactory; this.generatorFactory = generatorFactory;
} }


@Override @Override
public Iterator iterator() { public Iterator iterator() {
return new GeneratorIterator(generatorFactory.newSequence()); return new GeneratorIterator(generatorFactory.newIterator());
} }


@Override @Override
Expand Down
Expand Up @@ -3,7 +3,7 @@
* This code is licensed under the GPL 2.0 license, available at the root * This code is licensed under the GPL 2.0 license, available at the root
* application directory. * application directory.
*/ */
package org.geoserver.kml.sequence; package org.geoserver.kml.iterator;


import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import org.geoserver.kml.KmlEncodingContext; import org.geoserver.kml.KmlEncodingContext;
Expand Down
Expand Up @@ -3,14 +3,15 @@
* This code is licensed under the GPL 2.0 license, available at the root * This code is licensed under the GPL 2.0 license, available at the root
* application directory. * application directory.
*/ */
package org.geoserver.kml.sequence; package org.geoserver.kml.iterator;


import de.micromata.opengis.kml.v_2_2_0.Feature; import de.micromata.opengis.kml.v_2_2_0.Feature;
import de.micromata.opengis.kml.v_2_2_0.Folder; import de.micromata.opengis.kml.v_2_2_0.Folder;
import de.micromata.opengis.kml.v_2_2_0.GroundOverlay; import de.micromata.opengis.kml.v_2_2_0.GroundOverlay;
import de.micromata.opengis.kml.v_2_2_0.Icon; import de.micromata.opengis.kml.v_2_2_0.Icon;
import de.micromata.opengis.kml.v_2_2_0.LatLonBox; import de.micromata.opengis.kml.v_2_2_0.LatLonBox;
import de.micromata.opengis.kml.v_2_2_0.ViewRefreshMode; import de.micromata.opengis.kml.v_2_2_0.ViewRefreshMode;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.geoserver.kml.KmlEncodingContext; import org.geoserver.kml.KmlEncodingContext;
import org.geoserver.platform.ServiceException; import org.geoserver.platform.ServiceException;
Expand All @@ -24,32 +25,32 @@
import org.geotools.referencing.crs.DefaultGeographicCRS; import org.geotools.referencing.crs.DefaultGeographicCRS;


/** /**
* Creates a sequence of folders mapping the layers in the map content, using either kml dumps or * Creates an iterator of folders mapping the layers in the map content, using either kml dumps or
* ground overlays (the classic approach, that is) * ground overlays (the classic approach, that is)
* *
* @author Andrea Aime - GeoSolutions * @author Andrea Aime - GeoSolutions
*/ */
public class PlainFolderSequenceFactory extends AbstractFolderSequenceFactory { public class PlainFolderIteratorFactory extends AbstractFolderIteratorFactory {


public PlainFolderSequenceFactory(KmlEncodingContext context) { public PlainFolderIteratorFactory(KmlEncodingContext context) {
super(context); super(context);
} }


@Override @Override
public Sequence<Feature> newSequence() { public Iterator<Feature> newIterator() {
return new PlainFolderGenerator(); return new PlainFolderGenerator();
} }


public class PlainFolderGenerator extends AbstractFolderGenerator { public class PlainFolderGenerator extends AbstractFolderGenerator {


protected void encodeFolderContents(Layer layer, Folder folder) { protected void encodeFolderContents(Layer layer, Folder folder) {
// now encode the contents (dynamic bit, it may use the Sequence construct) // now encode the contents (dynamic bit, it may use the Iterator construct)
if (layer instanceof FeatureLayer) { if (layer instanceof FeatureLayer) {
// do we use a KML placemark dump, or a ground overlay? // do we use a KML placemark dump, or a ground overlay?
if (useVectorOutput(context)) { if (useVectorOutput(context)) {
List<Feature> features = List<Feature> features =
new SequenceList<Feature>( new IteratorList<Feature>(
new FeatureSequenceFactory(context, (FeatureLayer) layer)); new FeatureIteratorFactory(context, (FeatureLayer) layer));
context.addFeatures(folder, features); context.addFeatures(folder, features);
} else { } else {
addGroundOverlay(folder, layer); addGroundOverlay(folder, layer);
Expand Down Expand Up @@ -80,7 +81,7 @@ private void addFeatureCentroids(Layer layer, Folder folder) {
FeatureLayer centroidsLayer = FeatureLayer centroidsLayer =
new FeatureLayer(centroids, layer.getStyle(), layer.getTitle()); new FeatureLayer(centroids, layer.getStyle(), layer.getTitle());
List<Feature> features = List<Feature> features =
new SequenceList<Feature>(new FeatureSequenceFactory(context, centroidsLayer)); new IteratorList<Feature>(new FeatureIteratorFactory(context, centroidsLayer));
context.addFeatures(folder, features); context.addFeatures(folder, features);
} }


Expand Down

0 comments on commit e0d69e1

Please sign in to comment.