org.datasyslab.geosparkviz.utils.RasterizationUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of geospark-viz_2.1 Show documentation
Show all versions of geospark-viz_2.1 Show documentation
Geospatial visualization extension of GeoSpark
The newest version!
/*
* FILE: RasterizationUtils
* Copyright (c) 2015 - 2019 GeoSpark Development Team
*
* 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 org.datasyslab.geosparkviz.utils;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import org.apache.log4j.Logger;
import scala.Tuple2;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
// TODO: Auto-generated Javadoc
/**
* The Class RasterizationUtils.
*/
public class RasterizationUtils
implements Serializable
{
/**
* The Constant logger.
*/
final static Logger logger = Logger.getLogger(RasterizationUtils.class);
/**
* Find one pixel coordinate.
*
* @param resolutionX the resolution X
* @param resolutionY the resolution Y
* @param datasetBoundaryOriginal the dataset boundary original
* @param spatialCoordinateOriginal the spatial coordinate original
* @param reverseSpatialCoordinate the reverse spatial coordinate
* @return the tuple 2
*/
public static Tuple2 FindOnePixelCoordinate(int resolutionX, int resolutionY, Envelope datasetBoundaryOriginal, Coordinate spatialCoordinateOriginal, boolean reverseSpatialCoordinate)
{
Coordinate spatialCoordinate;
Envelope datasetBoundary;
if (reverseSpatialCoordinate) {
spatialCoordinate = new Coordinate(spatialCoordinateOriginal.y, spatialCoordinateOriginal.x);
datasetBoundary = new Envelope(datasetBoundaryOriginal.getMinY(), datasetBoundaryOriginal.getMaxY(), datasetBoundaryOriginal.getMinX(), datasetBoundaryOriginal.getMaxX());
}
else {
spatialCoordinate = spatialCoordinateOriginal;
datasetBoundary = datasetBoundaryOriginal;
}
/*
if(spatialCoordinate.x < datasetBoundary.getMinX() || spatialCoordinate.x > datasetBoundary.getMaxX())
{
throw new Exception("[RasterizationUtils][FindOnePixelCoordinate] This spatial coordinate is out of the given boundary. Should be ignored.");
}
if(spatialCoordinate.y < datasetBoundaryOriginal.getMinY() || spatialCoordinate.y > datasetBoundaryOriginal.getMaxY())
{
throw new Exception("[RasterizationUtils][FindOnePixelCoordinate] This spatial coordinate is out of the given boundary. Should be ignored.");
}*/
Double pixelXDouble = ((spatialCoordinate.x - datasetBoundary.getMinX()) / (datasetBoundary.getMaxX() - datasetBoundary.getMinX())) * resolutionX;
Double xRemainder = (spatialCoordinate.x - datasetBoundary.getMinX()) % (datasetBoundary.getMaxX() - datasetBoundary.getMinX());
Double pixelYDouble = ((spatialCoordinate.y - datasetBoundary.getMinY()) / (datasetBoundary.getMaxY() - datasetBoundary.getMinY())) * resolutionY;
Double yRemainder = (spatialCoordinate.y - datasetBoundary.getMinY()) % (datasetBoundary.getMaxY() - datasetBoundary.getMinY());
int pixelX = pixelXDouble.intValue();
int pixelY = pixelYDouble.intValue();
if (xRemainder == 0.0 && pixelXDouble != 0.0) {
pixelX--;
}
if (pixelX >= resolutionX) {
pixelX--;
}
if (yRemainder == 0.0 && pixelYDouble != 0) {
pixelY--;
}
if (pixelY >= resolutionY) {
pixelY--;
}
return new Tuple2(pixelX, pixelY);
}
/**
* Find one pixel coordinate.
*
* @param resolutionX the resolution X
* @param resolutionY the resolution Y
* @param datasetBoundaryOriginal the dataset boundary original
* @param spatialCoordinateOriginal the spatial coordinate original
* @param reverseSpatialCoordinate the reverse spatial coordinate
* @param flipOverX the flip over X
* @param flipOverY the flip over Y
* @return the tuple 2
*/
public static Tuple2 FindOnePixelCoordinate(int resolutionX, int resolutionY, Envelope datasetBoundaryOriginal, Coordinate spatialCoordinateOriginal, boolean reverseSpatialCoordinate, boolean flipOverX, boolean flipOverY)
{
Coordinate spatialCoordinate;
Envelope datasetBoundary;
if (reverseSpatialCoordinate) {
spatialCoordinate = new Coordinate(spatialCoordinateOriginal.y, spatialCoordinateOriginal.x);
datasetBoundary = new Envelope(datasetBoundaryOriginal.getMinY(), datasetBoundaryOriginal.getMaxY(), datasetBoundaryOriginal.getMinX(), datasetBoundaryOriginal.getMaxX());
}
else {
spatialCoordinate = spatialCoordinateOriginal;
datasetBoundary = datasetBoundaryOriginal;
}
Double pixelXDouble = ((spatialCoordinate.x - datasetBoundary.getMinX()) / (datasetBoundary.getMaxX() - datasetBoundary.getMinX())) * resolutionX;
Double xRemainder = (spatialCoordinate.x - datasetBoundary.getMinX()) % (datasetBoundary.getMaxX() - datasetBoundary.getMinX());
Double pixelYDouble = ((spatialCoordinate.y - datasetBoundary.getMinY()) / (datasetBoundary.getMaxY() - datasetBoundary.getMinY())) * resolutionY;
Double yRemainder = (spatialCoordinate.y - datasetBoundary.getMinY()) / (datasetBoundary.getMaxY() - datasetBoundary.getMinY());
int pixelX = pixelXDouble.intValue();
int pixelY = pixelYDouble.intValue();
if (xRemainder == 0.0 && pixelXDouble != 0.0) {
pixelX--;
}
if (pixelX >= resolutionX) {
pixelX--;
}
if (yRemainder == 0.0 && pixelYDouble != 0) {
pixelY--;
}
if (pixelY >= resolutionY) {
pixelY--;
}
// Flip over X or Y value. For example, if the original X is 15, the X resolution is 100, the flipped X will be 100 -15 = 85.
if (flipOverX) { pixelX = resolutionX - pixelX; }
if (flipOverY) { pixelY = resolutionY - pixelY; }
return new Tuple2(pixelX, pixelY);
}
/**
* Gets the width from height.
*
* @param y the y
* @param boundary the boundary
* @return the int
*/
public static int GetWidthFromHeight(int y, Envelope boundary)
{
int x = (int) (y * (boundary.getWidth() / boundary.getHeight()));
return x;
}
/**
* Encode 2 D to 1 D id.
*
* @param resolutionX the resolution X
* @param resolutionY the resolution Y
* @param twoDimensionIdX the two dimension id X
* @param twoDimensionIdY the two dimension id Y
* @return the int
* @throws Exception the exception
*/
public static int Encode2DTo1DId(int resolutionX, int resolutionY, int twoDimensionIdX, int twoDimensionIdY)
throws Exception
{
if (twoDimensionIdX < 0 || twoDimensionIdX >= resolutionX || twoDimensionIdY < 0 || twoDimensionIdY >= resolutionY) {
throw new Exception("[RasterizationUtils][Encode2DTo1DId] This given 2 dimension coordinate is " + twoDimensionIdX + " " + twoDimensionIdY + ". This coordinate is out of the given boundary and will be dropped.");
}
/*
if((twoDimensionIdX+twoDimensionIdY*resolutionX)<0 ||(twoDimensionIdX+twoDimensionIdY*resolutionX)>(resolutionX*resolutionY-1))
{
throw new Exception("[RasterizationUtils][Encode2DTo1DId] This given 2 dimension coordinate is "+twoDimensionIdX+" "+twoDimensionIdY+". This coordinate is out of the given boundary and will be dropped.");
}
*/
return twoDimensionIdX + twoDimensionIdY * resolutionX;
}
/**
* Decode 1 D to 2 D id.
*
* @param resolutionX the resolution X
* @param resolutionY the resolution Y
* @param oneDimensionId the one dimension id
* @return the tuple 2
*/
public static Tuple2 Decode1DTo2DId(int resolutionX, int resolutionY, int oneDimensionId)
{
int twoDimensionIdX = oneDimensionId % resolutionX;
int twoDimensionIdY = oneDimensionId / resolutionX;
return new Tuple2(twoDimensionIdX, twoDimensionIdY);
}
/**
* Find pixel coordinates.
*
* @param resolutionX the resolution X
* @param resolutionY the resolution Y
* @param datasetBoundary the dataset boundary
* @param spatialObject the spatial object
* @param colorizeOption the colorize option
* @param reverseSpatialCoordinate the reverse spatial coordinate
* @return the list
*/
public static List> FindPixelCoordinates(int resolutionX, int resolutionY, Envelope datasetBoundary, Point spatialObject, ColorizeOption colorizeOption, boolean reverseSpatialCoordinate)
{
List> result = new ArrayList>();
Tuple2 pixelCoordinate = null;
try {
pixelCoordinate = FindOnePixelCoordinate(resolutionX, resolutionY, datasetBoundary, spatialObject.getCoordinate(), reverseSpatialCoordinate);
}
catch (Exception e) {
// This pixel is out of boundary. Should be ignored.
return result;
}
if (colorizeOption == ColorizeOption.EARTHOBSERVATION) {
Pixel newPixel = new Pixel(pixelCoordinate._1, pixelCoordinate._2, resolutionX, resolutionY);
result.add(new Tuple2(newPixel, spatialObject.getCoordinate().z));
}
else {
Pixel newPixel = new Pixel(pixelCoordinate._1, pixelCoordinate._2, resolutionX, resolutionY);
result.add(new Tuple2(newPixel, new Double(1.0)));
}
return result;
}
/**
* Find pixel coordinates.
*
* @param resolutionX the resolution X
* @param resolutionY the resolution Y
* @param datasetBoundary the dataset boundary
* @param coordinates the coordinates
* @param reverseSpatialCoordinate the reverse spatial coordinate
* @param flipOverX the flip over X
* @param flipOverY the flip over Y
* @return the coordinate[]
*/
public static Coordinate[] FindPixelCoordinates(int resolutionX, int resolutionY, Envelope datasetBoundary, Coordinate[] coordinates, boolean reverseSpatialCoordinate, boolean flipOverX, boolean flipOverY)
{
/*
* This function is used to rasterize vector image pixels
*/
List result = new ArrayList();
for (Coordinate coordinate : coordinates) {
Tuple2 pixelCoordinate = FindOnePixelCoordinate(resolutionX, resolutionY, datasetBoundary, coordinate, reverseSpatialCoordinate, flipOverX, flipOverY);
result.add(new Coordinate(pixelCoordinate._1(), pixelCoordinate._2()));
}
Coordinate[] arrayResult = result.toArray(new Coordinate[result.size()]);
return arrayResult;
}
/**
* Find pixel coordinates.
*
* @param resolutionX the resolution X
* @param resolutionY the resolution Y
* @param datasetBoundary the dataset boundary
* @param coordinate the coordinate
* @param reverseSpatialCoordinate the reverse spatial coordinate
* @param flipOverX the flip over X
* @param flipOverY the flip over Y
* @return the coordinate
*/
public static Coordinate FindPixelCoordinates(int resolutionX, int resolutionY, Envelope datasetBoundary, Coordinate coordinate, boolean reverseSpatialCoordinate, boolean flipOverX, boolean flipOverY)
{
/*
* This function is used to rasterize vector image pixels
*/
Tuple2 pixelCoordinate = FindOnePixelCoordinate(resolutionX, resolutionY, datasetBoundary, coordinate, reverseSpatialCoordinate, flipOverX, flipOverY);
return new Coordinate(pixelCoordinate._1(), pixelCoordinate._2());
}
/**
* Find pixel coordinates.
*
* @param resolutionX the resolution X
* @param resolutionY the resolution Y
* @param datasetBoundary the dataset boundary
* @param spatialObject the spatial object
* @param reverseSpatialCoordinate the reverse spatial coordinate
* @return the list
*/
public static List> FindPixelCoordinates(int resolutionX, int resolutionY, Envelope datasetBoundary, Polygon spatialObject, boolean reverseSpatialCoordinate)
{
List> result = new ArrayList>();
for (int i = 0; i < spatialObject.getCoordinates().length - 1; i++) {
Tuple2 pixelCoordinate1 = null;
Tuple2 pixelCoordinate2 = null;
try {
pixelCoordinate1 = FindOnePixelCoordinate(resolutionX, resolutionY, datasetBoundary, spatialObject.getCoordinates()[i], reverseSpatialCoordinate);
pixelCoordinate2 = FindOnePixelCoordinate(resolutionX, resolutionY, datasetBoundary, spatialObject.getCoordinates()[i + 1], reverseSpatialCoordinate);
}
catch (Exception e) {
// This pixel is out of boundary. Should be ignored.
continue;
}
result.addAll(FindPixelCoordinates(resolutionX, resolutionY, pixelCoordinate1, pixelCoordinate2, reverseSpatialCoordinate));
}
return result;
}
/**
* Find pixel coordinates.
*
* @param resolutionX the resolution X
* @param resolutionY the resolution Y
* @param datasetBoundary the dataset boundary
* @param spatialObject the spatial object
* @param reverseSpatialCoordinate the reverse spatial coordinate
* @param objectWeight the object weight
* @return the list
*/
public static List> FindPixelCoordinates(int resolutionX, int resolutionY, Envelope datasetBoundary, Polygon spatialObject, boolean reverseSpatialCoordinate, Double objectWeight)
{
List> result = new ArrayList>();
GeometryFactory geometryfactory = new GeometryFactory();
ArrayList coordinatesList = new ArrayList();
LinearRing linear;
for (int i = 0; i < spatialObject.getCoordinates().length; i++) {
Tuple2 pixelCoordinate = null;
pixelCoordinate = FindOnePixelCoordinate(resolutionX, resolutionY, datasetBoundary, spatialObject.getCoordinates()[i], reverseSpatialCoordinate);
coordinatesList.add(new Coordinate(pixelCoordinate._1, pixelCoordinate._2));
}
coordinatesList.add(coordinatesList.get(0));
linear = geometryfactory.createLinearRing(coordinatesList.toArray(new Coordinate[coordinatesList.size()]));
Polygon polygon = new Polygon(linear, null, geometryfactory);
int minPixelX = (int) polygon.getEnvelopeInternal().getMinX();
int maxPixelX = (int) polygon.getEnvelopeInternal().getMaxX();
int minPixelY = (int) polygon.getEnvelopeInternal().getMinY();
int maxPixelY = (int) polygon.getEnvelopeInternal().getMaxY();
for (int j = minPixelY; j <= maxPixelY; j++) {
for (int i = minPixelX; i <= maxPixelX; i++) {
if (polygon.contains(geometryfactory.createPoint(new Coordinate(i, j)))) {
try {
Pixel newPixel = new Pixel(i, j, resolutionX, resolutionY);
result.add(new Tuple2(newPixel, new Double(objectWeight)));
}
catch (Exception e) {
/*
* This spatial object is out of the given dataset boundary. It is ignored here.
*/
}
}
}
}
return result;
}
/**
* Find pixel coordinates.
*
* @param resolutionX the resolution X
* @param resolutionY the resolution Y
* @param pixelCoordinate1 the pixel coordinate 1
* @param pixelCoordinate2 the pixel coordinate 2
* @param reverseSpatialCoordinate the reverse spatial coordinate
* @return the list
*/
public static List> FindPixelCoordinates(int resolutionX, int resolutionY, Tuple2 pixelCoordinate1, Tuple2 pixelCoordinate2, boolean reverseSpatialCoordinate)
{
/*
* This function uses Bresenham's line algorithm to plot pixels touched by a given line segment.
*/
int x1 = pixelCoordinate1._1;
int y1 = pixelCoordinate1._2;
int x2 = pixelCoordinate2._1;
int y2 = pixelCoordinate2._2;
int dx = x2 - x1;
int dy = y2 - y1;
int ux = dx > 0 ? 1 : -1; // x direction
int uy = dy > 0 ? 1 : -1; // y direction
int x = x1, y = y1;
int eps = 0; //cumulative errors
dx = Math.abs(dx);
dy = Math.abs(dy);
List> result = new ArrayList>();
if (dx > dy) {
for (x = x1; x != x2; x += ux) {
try {
Pixel newPixel = new Pixel(x, y, resolutionX, resolutionY);
result.add(new Tuple2(newPixel, 1.0));
}
catch (Exception e) {
/*
* This spatial object is out of the given dataset boudanry. It is ignored here.
*/
}
eps += dy;
if ((eps << 1) >= dx) {
y += uy;
eps -= dx;
}
}
}
else {
for (y = y1; y != y2; y += uy) {
try {
Pixel newPixel = new Pixel(x, y, resolutionX, resolutionY);
result.add(new Tuple2(newPixel, 1.0));
}
catch (Exception e) {
/*
* This spatial object is out of the given dataset boudanry. It is ignored here.
*/
}
eps += dx;
if ((eps << 1) >= dy) {
x += ux;
eps -= dy;
}
}
}
return result;
}
/**
* Find pixel coordinates.
*
* @param resolutionX the resolution X
* @param resolutionY the resolution Y
* @param datasetBoundary the dataset boundary
* @param spatialObject the spatial object
* @param reverseSpatialCoordinate the reverse spatial coordinate
* @return the list
*/
public static List> FindPixelCoordinates(int resolutionX, int resolutionY, Envelope datasetBoundary, LineString spatialObject, boolean reverseSpatialCoordinate)
{
List> result = new ArrayList>();
for (int i = 0; i < spatialObject.getCoordinates().length - 1; i++) {
Tuple2 pixelCoordinate1 = null;
Tuple2 pixelCoordinate2 = null;
try {
pixelCoordinate1 = FindOnePixelCoordinate(resolutionX, resolutionY, datasetBoundary, spatialObject.getCoordinates()[i], reverseSpatialCoordinate);
pixelCoordinate2 = FindOnePixelCoordinate(resolutionX, resolutionY, datasetBoundary, spatialObject.getCoordinates()[i + 1], reverseSpatialCoordinate);
}
catch (Exception e) {
// This line segment is out of boundary, Should be ignored.
continue;
}
result.addAll(FindPixelCoordinates(resolutionX, resolutionY, pixelCoordinate1, pixelCoordinate2, reverseSpatialCoordinate));
}
return result;
}
public static String getImageTileName(int zoomLevel, int partitionOnX, int partitionOnY, int tileSerialId)
{
Tuple2 tileCoordinate = RasterizationUtils.Decode1DTo2DId(partitionOnX, partitionOnY, tileSerialId);
return zoomLevel + "-" + tileCoordinate._1() + "-" + tileCoordinate._2();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy