// This software is released into the Public Domain. See copying.txt for details.
package org.openstreetmap.osmosis.core.bound.v0_6;
import org.openstreetmap.osmosis.core.OsmosisConstants;
import org.openstreetmap.osmosis.core.domain.v0_6.Bound;
import org.openstreetmap.osmosis.core.pipeline.common.TaskConfiguration;
import org.openstreetmap.osmosis.core.pipeline.common.TaskManager;
import org.openstreetmap.osmosis.core.pipeline.common.TaskManagerFactory;
import org.openstreetmap.osmosis.core.pipeline.v0_6.SinkSourceManager;
/**
* Task manager factory for the bound setter task.
*
* @author Igor Podolskiy
*/
public class BoundSetterFactory extends TaskManagerFactory {
private static final String ARG_LEFT = "left";
private static final String ARG_RIGHT = "right";
private static final String ARG_TOP = "top";
private static final String ARG_BOTTOM = "bottom";
private static final String ARG_X1 = "x1";
private static final String ARG_Y1 = "y1";
private static final String ARG_X2 = "x2";
private static final String ARG_Y2 = "y2";
private static final String ARG_ZOOM = "zoom";
private static final String ARG_REMOVE = "remove";
private static final String ARG_ORIGIN = "origin";
private static final double DEFAULT_LEFT = -180;
private static final double DEFAULT_RIGHT = 180;
private static final double DEFAULT_TOP = 90;
private static final double DEFAULT_BOTTOM = -90;
private static final int DEFAULT_ZOOM = 12;
private static final String DEFAULT_ORIGIN = "Osmosis/" + OsmosisConstants.VERSION;
private static final boolean DEFAULT_REMOVE = false;
private double xToLon(int zoom, int x) {
double unit = 360 / Math.pow(2, zoom);
return -180 + x * unit;
}
private double projectF(double lat) {
// Project latitude to mercator
return Math.log(Math.tan(lat) + 1 / Math.cos(lat));
}
private double projectMercToLat(double y) {
return Math.toDegrees(Math.atan(Math.sinh(y)));
}
private double yToLat(int zoom, int y) {
// Convert zoom/y to mercator
// Get maximum range of mercator coordinates
double limitY = projectF(Math.atan(Math.sinh(Math.PI)));
double limitY2 = projectF((Math.atan(Math.sinh(-Math.PI))));
double rangeY = limitY - limitY2;
double unit = 1 / Math.pow(2, zoom);
double relY = limitY - rangeY * y * unit;
// Mercator to latitude
return projectMercToLat(relY);
}
@Override
protected TaskManager createTaskManagerImpl(TaskConfiguration taskConfig) {
double left;
double right;
double top;
double bottom;
int zoom;
Bound newBound = null;
String origin = null;
boolean remove;
remove = getBooleanArgument(taskConfig, ARG_REMOVE, DEFAULT_REMOVE);
if (!remove) {
origin = getStringArgument(taskConfig, ARG_ORIGIN, DEFAULT_ORIGIN);
left = getDoubleArgument(taskConfig, ARG_LEFT, DEFAULT_LEFT);
right = getDoubleArgument(taskConfig, ARG_RIGHT, DEFAULT_RIGHT);
top = getDoubleArgument(taskConfig, ARG_TOP, DEFAULT_TOP);
bottom = getDoubleArgument(taskConfig, ARG_BOTTOM, DEFAULT_BOTTOM);
zoom = getIntegerArgument(taskConfig, ARG_ZOOM, DEFAULT_ZOOM);
if (doesArgumentExist(taskConfig, ARG_X1)) {
int x1 = getIntegerArgument(taskConfig, ARG_X1);
left = xToLon(zoom, x1);
right = xToLon(zoom, getIntegerArgument(taskConfig, ARG_X2, x1) + 1);
}
if (doesArgumentExist(taskConfig, ARG_Y1)) {
int y1 = getIntegerArgument(taskConfig, ARG_Y1);
top = yToLat(zoom, y1);
bottom = yToLat(zoom, getIntegerArgument(taskConfig, ARG_Y2, y1) + 1);
}
newBound = new Bound(right, left, top, bottom, origin);
}
return new SinkSourceManager(taskConfig.getId(),
new BoundSetter(newBound), taskConfig.getPipeArgs());
}
}