geoportal-data-mapper/src/main/java/org/gcube/application/geoportaldatamapper/exporter/gis/BBOXConverter.java

233 lines
6.0 KiB
Java

package org.gcube.application.geoportaldatamapper.exporter.gis;
import java.util.Arrays;
import java.util.List;
import org.gcube.spatial.data.geoutility.shared.BBOX;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class BBOXConverter.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Dec 18, 2023
*/
public class BBOXConverter {
Integer[] size = new Integer[2];
Double[] bbox = new Double[4];
public static final double EQUATOR = 40075016.68557849;
private static Logger LOG = LoggerFactory.getLogger(BBOXConverter.class);
/**
* The Class BBOXPixel.
*
* @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it
*
* Dec 18, 2023
*/
public static class BBOXPixel {
public double x;
public double y;
public double w;
public double h;
/**
* Instantiates a new BBOX pixel.
*
* @param x the x
* @param y the y
* @param w the w
* @param h the h
*/
public BBOXPixel(double x, double y, double w, double h) {
super();
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
/**
* To string.
*
* @return the string
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("BBOXPixel [x=");
builder.append(x);
builder.append(", y=");
builder.append(y);
builder.append(", w=");
builder.append(w);
builder.append(", h=");
builder.append(h);
builder.append("]");
return builder.toString();
}
}
/**
* Convert to pixel.
*
* @param size the size
* @param bbox the bbox
* @return the BBOX converter. BBOX pixel
*/
public static BBOXConverter.BBOXPixel convertToPixel(Integer[] size, Double[] bbox) {
double dw = 1. / size[0];
double dh = 1. / size[1];
double x = (bbox[0] + bbox[1]) / 2.0;
double y = (bbox[2] + bbox[3]) / 2.0;
double w = bbox[1] - bbox[0];
double h = bbox[3] - bbox[2];
x = x * dw;
w = w * dw;
y = y * dh;
h = h * dh;
return new BBOXPixel(x, y, w, h);
}
/**
* Convert to coordinate.
*
* @param bboxP the bbox P
* @param size the size
* @return the bbox
*/
public static BBOX convertToCoordinate(BBOXPixel bboxP, Integer[] size) {
double h = bboxP.h;
double l = bboxP.x;
double t = bboxP.y;
double w = bboxP.w;
Integer img_w = size[0];
Integer img_h = size[1];
double x1 = l / img_w;
double y1 = t / img_h;
double x2 = (l + w) / img_w;
double y2 = (t + h) / img_h;
return new BBOX(x1, y1, x2, y2, "");
}
/**
* Bbox with offset.
*
* @param wmsVersion the wms version
* @param bbox the bbox
* @param bboxOffset the bbox offset
* @return the string
*/
public static String bboxWithOffset(String wmsVersion, String bbox, double bboxOffset) {
BBOX.COORDINATE_FORMAT bboxFormat = wmsVersion.contains("1.3") ? BBOX.COORDINATE_FORMAT.YX
: BBOX.COORDINATE_FORMAT.XY;
BBOX theBBOX = new BBOX(bbox, bboxFormat);
// double lowerXR = theBBOX.getLowerLeftX() - (theBBOX.getLowerLeftX()*bboxOffset/100);
// double lowerYR = theBBOX.getLowerLeftY() - (theBBOX.getLowerLeftY()*bboxOffset/100);
// double upperXR = theBBOX.getUpperRightX() + (theBBOX.getUpperRightX()*bboxOffset/100);
// double upperYR = theBBOX.getUpperRightY() + (theBBOX.getUpperRightY()*bboxOffset/100);
double lowerXR = theBBOX.getLowerLeftX() - bboxOffset;
double lowerYR = theBBOX.getLowerLeftY() - bboxOffset;
double upperXR = theBBOX.getUpperRightX() + bboxOffset;
double upperYR = theBBOX.getUpperRightY() + bboxOffset;
return BBOX.toBBOXString(new BBOX(lowerXR, lowerYR, upperXR, upperYR, ""), bboxFormat);
}
/**
* To BBOX.
*
* @param wmsVersion the wms version
* @param bbox the bbox
* @return the bbox
*/
public static BBOX toBBOX(String wmsVersion, String bbox) {
BBOX.COORDINATE_FORMAT bboxFormat = wmsVersion.contains("1.3") ? BBOX.COORDINATE_FORMAT.YX
: BBOX.COORDINATE_FORMAT.XY;
return new BBOX(bbox, bboxFormat);
}
/**
* Converts spherical web mercator to tile pixel X/Y at zoom level 0 for 256x256
* tile size and inverts y coordinates.
*
* @param bbox the bbox
* @return {L.point} point with tile pixel x and y coordinates.
*/
public static List<Double> mercatorToPixels(List<Double> bbox) {
double pixelX1 = (bbox.get(0) + (EQUATOR / 2.0)) / (EQUATOR / 256.0);
double pixelY1 = ((bbox.get(1) - (EQUATOR / 2.0)) / (EQUATOR / -256.0));
double pixelX2 = (bbox.get(2) + (EQUATOR / 2.0)) / (EQUATOR / 256.0);
double pixelY2 = ((bbox.get(3) - (EQUATOR / 2.0)) / (EQUATOR / -256.0));
return Arrays.asList(pixelX1, pixelY1, pixelX2, pixelY2);
}
/**
* Bbox offset.
*
* @param cMin the c min
* @param cMax the c max
* @return the double
*/
public static Double bboxOffset(String cMin, String cMax) {
String bboxOffsetString = "0.";
int startIndex = cMax.indexOf(".")+1;
int lenght = cMax.length();
if (startIndex < lenght) {
for (int i = startIndex; i < lenght; i++) {
if (cMin.charAt(i) == cMax.charAt(i)) {
bboxOffsetString += "0";
} else {
bboxOffsetString += "1";
break;
}
}
}else {
bboxOffsetString = "0.0"; //no offset
}
return Double.parseDouble(bboxOffsetString);
}
/**
* Best BBOX offset.
*
* @param wmsVersion the wms version
* @param source_bbox the source bbox
* @return the double
*/
public static Double bestBBOXOffset(String wmsVersion, String source_bbox) {
BBOX theBBOX = BBOXConverter.toBBOX(wmsVersion, source_bbox);
String xMin = new Double(theBBOX.getLowerLeftX()).toString();
String xMax = new Double(theBBOX.getUpperRightX()).toString();
Double offsetWidth = bboxOffset(xMin, xMax);
//System.out.println("offsetWidth: " + offsetWidth);
LOG.debug("offset width: "+offsetWidth);
String yMin = new Double(theBBOX.getLowerLeftY()).toString();
String yMax = new Double(theBBOX.getUpperRightY()).toString();
Double offsetHeight = bboxOffset(yMax, yMin);
//System.out.println("offsetHeight: " + offsetHeight);
LOG.debug("offset width: "+offsetHeight);
return offsetWidth < offsetHeight ? offsetWidth : offsetHeight;
}
}