/* Copyright 2013 The jeo project. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.jeo.tile;
import java.util.List;
import io.jeo.geom.Bounds;
import io.jeo.proj.Proj;
import org.osgeo.proj4j.CoordinateReferenceSystem;
/**
* Builder for {@link TilePyramid} objects.
* <p>
* Example usage:
* <pre>
* TilePyramid schema = TilePyramid.build().bounds(-180,-90,180,90).crs("EPSG:4326")
* .tileSize(256, 256).grid(2,1).grid().grid(2, 8, 4).pyramid();
* </pre>
* </p>
* @author Justin Deoliveira, OpenGeo
*
*/
public class TilePyramidBuilder {
TilePyramid tp;
/**
* Creates a new builder.
*/
public TilePyramidBuilder() {
tp = new TilePyramid();
}
/**
* Sets bounds of the pyramid.
*/
public TilePyramidBuilder bounds(double minx, double miny, double maxx, double maxy) {
return bounds(new Bounds(minx, maxx, miny, maxy));
}
/**
* Sets bounds of the pyramid.
*/
public TilePyramidBuilder bounds(Bounds bounds) {
tp.bounds(bounds);
return this;
}
/**
* Sets crs of the pyramid.
*/
public TilePyramidBuilder crs(String srs) {
return crs(Proj.crs(srs));
}
/**
* Sets crs of the pyramid.
*/
public TilePyramidBuilder crs(CoordinateReferenceSystem crs) {
tp.crs(crs);
return this;
}
/**
* Sets the tile dimensions for the pyramid.
*/
public TilePyramidBuilder tileSize(int width, int height) {
tp.tileWidth(width);
tp.tileHeight(height);
return this;
}
/**
* Sets the origin of the tile coordinate system.
*/
public TilePyramidBuilder origin(TilePyramid.Origin origin) {
tp.origin(origin);
return this;
}
/**
* Creates a new level in the pyramid.
*
* @param z The zoom level of the grid level.
* @param width The number of horizontal tiles in the level.
* @param height The number of vertical tiles in the level.
*
*/
public TilePyramidBuilder grid(int z, int width, int height) {
double xres = tp.bounds().getWidth() / ((double)width) / ((double)tp.tileWidth());
double yres = tp.bounds().getHeight() / ((double)height) / ((double)tp.tileHeight());
tp.grids().add(new TileGrid(z, width, height, xres, yres));
return this;
}
/**
* Creates a new level in the pyramid automatically determining the zoom level.
* <p>
* If no grids have been previously added the z level is set to 0. Otherwise the z level is
* the previously added z level + 1.
* </p>
* @param width The number of horizontal tiles in the level.
* @param height The number of vertical tiles in the level.
*/
public TilePyramidBuilder grid(int width, int height) {
int z;
List<TileGrid> grids = tp.grids();
if (grids.isEmpty()) {
z = 0;
}
else {
TileGrid last = grids.get(grids.size()-1);
z = last.z()+1;
}
return grid(z, width, height);
}
/**
* Creates a new level in the pyramid automatically determining the zoom level and grid
* dimensions.
* <p>
* If not grids have been previously added to the pyramid the z level is set to 0 and grid
* dimensions inferred from the pyramid bounds. Otherwise the grid z level is the previous
* z value + 1, and the grid dimensions are the previous dimensions * 2.
* </p>
*/
public TilePyramidBuilder grid() {
List<TileGrid> grids = tp.grids();
if (grids.isEmpty()) {
Bounds bounds = tp.bounds();
if (bounds != null) {
if (bounds.getWidth() > bounds.getHeight()) {
return grid(0, (int)(bounds.getWidth()/bounds.getHeight()), 1);
}
else {
return grid(0, 1, (int)(bounds.getHeight()/bounds.getWidth()));
}
}
else {
grid(0, 2, 1);
}
}
else {
TileGrid last = grids.get(grids.size()-1);
return grid(last.z()+1, last.width()*2, last.height()*2);
}
return this;
}
/**
* Adds a number of levels to the pyramid.
* <p>
* This method is equivalent to calling {@link #grid()} <tt>n</tt> times.
* </p>
* @param n The number of levels to add to the pyramid. * @return
*/
public TilePyramidBuilder grids(int n) {
for (int i = 0; i < n; i++) grid();
return this;
}
/**
* Returns the built pyramid.
*/
public TilePyramid pyramid() {
return tp;
}
}