// This software is released into the Public Domain. See copying.txt for details.
package org.openstreetmap.osmosis.dataset.v0_6;
import java.util.Collections;
import org.openstreetmap.osmosis.core.OsmosisRuntimeException;
import org.openstreetmap.osmosis.core.container.v0_6.Dataset;
import org.openstreetmap.osmosis.core.container.v0_6.DatasetContext;
import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer;
import org.openstreetmap.osmosis.core.lifecycle.ReleasableIterator;
import org.openstreetmap.osmosis.core.task.v0_6.DatasetSinkSource;
import org.openstreetmap.osmosis.core.task.v0_6.Sink;
/**
* Provides a filter utilising a dataset to extract all entities that lie within
* a specific geographical box identified by latitude and longitude coordinates.
*
* @author Brett Henderson
*/
public class DatasetBoundingBoxFilter implements DatasetSinkSource {
private Sink sink;
private double left;
private double right;
private double top;
private double bottom;
private boolean completeWays;
private DatasetContext datasetReader;
/**
* Creates a new instance with the specified geographical coordinates. When
* filtering, nodes right on the left and bottom edges of the box will be
* included, nodes on the top and right edges will be excluded.
*
* @param left
* The longitude marking the left edge of the bounding box.
* @param right
* The longitude marking the right edge of the bounding box.
* @param top
* The latitude marking the top edge of the bounding box.
* @param bottom
* The latitude marking the bottom edge of the bounding box.
* @param completeWays
* Include all nodes for ways which have some portion inside the
* filtered area.
*/
public DatasetBoundingBoxFilter(double left, double right, double top, double bottom, boolean completeWays) {
this.left = left;
this.right = right;
this.top = top;
this.bottom = bottom;
this.completeWays = completeWays;
}
/**
* {@inheritDoc}
*/
@Override
public void setSink(Sink sink) {
this.sink = sink;
}
/**
* {@inheritDoc}
*/
@Override
public void process(Dataset dataset) {
if (datasetReader != null) {
throw new OsmosisRuntimeException("process may only be invoked once.");
}
datasetReader = dataset.createReader();
// Pass all data within the bounding box to the sink.
try (ReleasableIterator<EntityContainer> bboxData =
datasetReader.iterateBoundingBox(left, right, top, bottom, completeWays)) {
sink.initialize(Collections.<String, Object>emptyMap());
while (bboxData.hasNext()) {
sink.process(bboxData.next());
}
sink.complete();
}
}
/**
* {@inheritDoc}
*/
@Override
public void close() {
sink.close();
if (datasetReader != null) {
datasetReader.close();
}
}
}