Skip to content

Commit

Permalink
tile creator tile sizes when tile width and/or height are null
Browse files Browse the repository at this point in the history
  • Loading branch information
bosborn committed Dec 15, 2021
1 parent 14973f2 commit c435a79
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Adheres to [Semantic Versioning](http://semver.org/).

* UrlTileGenerator HTTP Method and Header field values support
* FeatureTiles FeatureIndexManager and FeatureIndexResults support
* TileCreator improved tile sizes when tile width and/or height are not specified
* Bounding Box world bounds shortcuts for WGS84 and Web Mercator

## [6.1.1](https://github.com/ngageoint/geopackage-java/releases/tag/6.1.1) (11-10-2021)
Expand Down
118 changes: 97 additions & 21 deletions src/main/java/mil/nga/geopackage/tiles/TileCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -406,38 +406,31 @@ private GeoPackageTile getTile(BoundingBox requestBoundingBox,

if (tileResults.getCount() > 0) {

BoundingBox requestProjectedBoundingBox = requestBoundingBox
.transform(transformRequestToTiles);

// Determine the requested tile dimensions, or use the
// dimensions of a single tile matrix tile
int requestedTileWidth = width != null ? width
: (int) tileMatrix.getTileWidth();
int requestedTileHeight = height != null ? height
: (int) tileMatrix.getTileHeight();
// Determine the tile dimensions
int[] tileDimensions = tileDimensions(
requestBoundingBox, tilesBoundingBox,
tileMatrix);
int requestedTileWidth = tileDimensions[0];
int requestedTileHeight = tileDimensions[1];

// Determine the size of the tile to initially draw
int tileWidth = requestedTileWidth;
int tileHeight = requestedTileHeight;
if (!sameUnit) {
tileWidth = (int) Math
.round((requestProjectedBoundingBox
.getMaxLongitude()
- requestProjectedBoundingBox
.getMinLongitude())
/ tileMatrix.getPixelXSize());
tileWidth = (int) Math.round((tilesBoundingBox
.getMaxLongitude()
- tilesBoundingBox.getMinLongitude())
/ tileMatrix.getPixelXSize());
tileHeight = (int) Math
.round((requestProjectedBoundingBox
.getMaxLatitude()
- requestProjectedBoundingBox
.getMinLatitude())
.round((tilesBoundingBox.getMaxLatitude()
- tilesBoundingBox.getMinLatitude())
/ tileMatrix.getPixelYSize());
}

// Draw the resulting bitmap with the matching tiles
GeoPackageTile geoPackageTile = drawTile(tileMatrix,
tileResults, requestProjectedBoundingBox,
tileWidth, tileHeight);
tileResults, tilesBoundingBox, tileWidth,
tileHeight);

// Create the tile
if (geoPackageTile != null) {
Expand Down Expand Up @@ -469,6 +462,89 @@ private GeoPackageTile getTile(BoundingBox requestBoundingBox,
return tile;
}

/**
* Determine the tile dimensions. Specified width and/or height values are
* used. When only one of width or height is specified, other is determined
* as a request ratio. When neither width or height is specified, determine
* from the tile matrix as a request ratio.
*
* @param requestBoundingBox
* request bounding box
* @param tilesBoundingBox
* tiles bounding box
* @param tileMatrix
* tile matrix
* @return tile dimensions array of size 2 [width, height]
*/
private int[] tileDimensions(BoundingBox requestBoundingBox,
BoundingBox tilesBoundingBox, TileMatrix tileMatrix) {

// Determine the tile dimensions
int requestedTileWidth;
int requestedTileHeight;
if (width != null && height != null) {

// Requested dimensions
requestedTileWidth = width;
requestedTileHeight = height;

} else if (width == null && height == null) {

// Determine dimensions from a single tile matrix
// tile as a ratio to the requested bounds
double requestLonRange = requestBoundingBox.getLongitudeRange();
double requestLatRange = requestBoundingBox.getLatitudeRange();
double pixelXSize = tileMatrix.getPixelXSize();
double pixelYSize = tileMatrix.getPixelYSize();
if (requestProjection.isUnit(tilesProjection.getUnit())) {
// Same unit, use the pixel x and y size
requestedTileWidth = (int) Math
.round(requestLonRange / pixelXSize);
requestedTileHeight = (int) Math
.round(requestLatRange / pixelYSize);
} else {
// Use the max tile pixel length and adjust to
// the sides to the requested bounds ratio
double maxLength = Math.max(
tilesBoundingBox.getLongitudeRange() / pixelXSize,
tilesBoundingBox.getLatitudeRange() / pixelYSize);
if (requestLonRange < requestLatRange) {
requestedTileWidth = (int) Math.round(
maxLength * (requestLonRange / requestLatRange));
requestedTileHeight = (int) Math.round(maxLength);
} else if (requestLatRange < requestLonRange) {
requestedTileWidth = (int) Math.round(maxLength);
requestedTileHeight = (int) Math.round(
maxLength * (requestLatRange / requestLonRange));
} else {
requestedTileWidth = (int) Math.round(maxLength);
requestedTileHeight = requestedTileWidth;
}
}

} else if (width == null) {

// Requested height, determine width as a ratio from
// the requested bounds
requestedTileHeight = height;
requestedTileWidth = (int) Math
.round(height * (requestBoundingBox.getLongitudeRange()
/ requestBoundingBox.getLatitudeRange()));

} else {

// Requested width, determine height as a ratio from
// the requested bounds
requestedTileWidth = width;
requestedTileHeight = (int) Math
.round(width * (requestBoundingBox.getLatitudeRange()
/ requestBoundingBox.getLongitudeRange()));

}

return new int[] { requestedTileWidth, requestedTileHeight };
}

/**
* Draw the tile from the tile results
*
Expand Down

0 comments on commit c435a79

Please sign in to comment.