Java tutorial
//package com.java2s; public class Main { public static double[] leftRightLongitude(double[] array) { double[] ret = null; /* Normal min max*/ double[] mm = minMax(array); double left = mm[0]; double right = mm[1]; /* Shortcut if everything is either positive OR negative (no crossings) */ if ((left >= 0 & right >= 0) || (left < 0 & right < 0)) { ret = mm; } else { /* Find out where the data is located */ int[] counts = lonQuadrantCounts(array); double[] pmm = minMaxSigned(array, true); double[] nmm = minMaxSigned(array, false); int one = counts[0]; int two = counts[1]; int three = counts[2]; int four = counts[3]; if ((one > 0 & two > 0 & three > 0 & four > 0)) { /* Data in all quadrants - difficult to determine starting point */ if ((two > one) & (three > four)) { /* Data starts in 1 and goes to 4 - CROSSES DATELINE */ left = pmm[0]; right = nmm[1]; } else if ((two < one) & (three < four)) { /* Data starts in 3 and goes to 2 - NORMAL - do nothing */ } else if ((four < one) & (four < two) & (four < three)) { /* Data starts in 4 and goes to 3 or 4 - CROSSES DATELINE */ left = nmm[1]; right = findNextLower(array, left); } else { /* When in doubt - whole globe...*/ left = -180; right = 180; } } else if (two > 0 & three > 0) { /* Data in at least 2 & 3 - CROSSES DATELINE */ left = pmm[0]; right = nmm[1]; } ret = new double[] { left, right }; } return ret; } /** * Determines the minimum and maximum values in the <tt>array</tt>. Calls {@link #minMax(double[], double)} with <tt>Double.NaN</tt> as * the <tt>noDataValue</tt>. * * @param array * @return a <tt>double[]</tt> where [0]==minimum and [1]==maximum * @see #minMax(double[], double) */ public static double[] minMax(double[] array) { return minMax(array, Double.NaN); } /** * Determines the minimum and maximum values in the <tt>array</tt>, ignoring any instances of <tt>noDataValue</tt>. * * @param array * @param noDataValue * @return a <tt>double[]</tt> where [0]==minimum and [1]==maximum */ public static double[] minMax(double[] array, double noDataValue) { double[] ret = null; double min = Double.POSITIVE_INFINITY, max = Double.NEGATIVE_INFINITY; double val; for (int i = 0; i < array.length; i++) { val = array[i]; if (val != noDataValue) { min = (val < min) ? val : min; max = (val > max) ? val : max; } } if (!Double.isInfinite(min) & !Double.isInfinite(max)) { ret = new double[] { min, max }; } return ret; } /** * Determines the minimum and maximum values in the two dimensional array <tt>multi</tt>. Calls {@link #minMax(double[], double)} with * <tt>Double.NaN</tt> as the <tt>noDataValue</tt>. * * @param multi * @return a <tt>double[]</tt> where [0]==minimum and [1]==maximum * @see #minMax(double[][], double) */ public static double[] minMax(double[][] multi) { return minMax(multi, Double.NaN); } /** * Determines the minimum and maximum values in the two dimensional array <tt>multi</tt>, ignoring any instances of <tt>noDataValue</tt> * . * * @param multi * @param noDataValue * @return a <tt>double[]</tt> where [0]==minimum and [1]==maximum */ public static double[] minMax(double[][] multi, double noDataValue) { double[] ret = null; double min = Double.POSITIVE_INFINITY, max = Double.NEGATIVE_INFINITY; double val; for (int i = 0; i < multi.length; i++) { for (int j = 0; j < multi[i].length; j++) { val = multi[i][j]; if (val != noDataValue) { min = (val < min) ? val : min; max = (val > max) ? val : max; } } } if (!Double.isInfinite(min) & !Double.isInfinite(max)) { ret = new double[] { min, max }; } return ret; } /** * Determines the minimum and maximum values in the <tt>array</tt>. Calls {@link #minMax(float[], float)} with <tt>Float.NaN</tt> as the * <tt>noDataValue</tt>. * * @param array * @return a <tt>float[]</tt> where [0]==minimum and [1]==maximum * @see #minMax(float[], float) */ public static float[] minMax(float[] array) { return minMax(array, Float.NaN); } /** * Determines the minimum and maximum values in the <tt>array</tt>, ignoring any instances of <tt>noDataValue</tt>. * * @param array * @param noDataValue * @return a <tt>float[]</tt> where [0]==minimum and [1]==maximum */ public static float[] minMax(float[] array, float noDataValue) { float[] ret = null; float min = Float.POSITIVE_INFINITY, max = Float.NEGATIVE_INFINITY; float val; for (int i = 0; i < array.length; i++) { val = array[i]; if (val != noDataValue) { min = (val < min) ? val : min; max = (val > max) ? val : max; } } if (!Float.isInfinite(min) & !Float.isInfinite(max)) { ret = new float[] { min, max }; } return ret; } /** * Determines the minimum and maximum values in the two dimensional array <tt>multi</tt>. Calls {@link #minMax(float[], float)} with * <tt>Float.NaN</tt> as the <tt>noDataValue</tt>. * * @param multi * @return a <tt>float[]</tt> where [0]==minimum and [1]==maximum * @see #minMax(float[][], float) */ public static float[] minMax(float[][] multi) { return minMax(multi, Float.NaN); } /** * Determines the minimum and maximum values in the two dimensional array <tt>multi</tt>, ignoring any instances of <tt>noDataValue</tt> * . * * @param multi * @param noDataValue * @return a <tt>float[]</tt> where [0]==minimum and [1]==maximum */ public static float[] minMax(float[][] multi, float noDataValue) { float[] ret = null; float min = Float.POSITIVE_INFINITY, max = Float.NEGATIVE_INFINITY; float val; for (int i = 0; i < multi.length; i++) { for (int j = 0; j < multi[i].length; j++) { val = multi[i][j]; if (val != noDataValue) { min = (val < min) ? val : min; max = (val > max) ? val : max; } } } if (!Float.isInfinite(min) & !Float.isInfinite(max)) { ret = new float[] { min, max }; } return ret; } public static int[] lonQuadrantCounts(double[] array) { int one = 0, two = 0, three = 0, four = 0; for (int i = 0; i < array.length; i++) { switch (lonQuadrant(array[i])) { case 1: one++; break; case 2: two++; break; case 3: three++; break; case 4: four++; break; } } return new int[] { one, two, three, four }; } /** * Get the minimum and maximum values of an array restricting the values to either positive or negative. If <tt>positive</tt> is true, * only positive numbers will be addressed. If <tt>positive</tt> is false, only negative numbers will be addressed. * * @param array * the array to process * @param positive * If true, negative numbers are ignored. If false, positive numbers are ignored. * @return a <tt>double[]</tt> where [0]==minimum and [1]==maximum */ public static double[] minMaxSigned(double[] array, boolean positive) { double min, max; double val; if (positive) { min = Double.POSITIVE_INFINITY; max = 0; for (int i = 0; i < array.length; i++) { val = array[i]; if (val >= 0) { min = (val < min) ? val : min; max = (val > max) ? val : max; } } } else { min = 0; max = Double.NEGATIVE_INFINITY; for (int i = 0; i < array.length; i++) { val = array[i]; if (val <= 0) { min = (val < min) ? val : min; max = (val > max) ? val : max; } } } return new double[] { min, max }; } public static double findNextLower(double[] array, double val) { double ret = array[0], nv, d, delta = Double.POSITIVE_INFINITY; val = Math.abs(val); for (int i = 0; i < array.length; i++) { nv = array[i]; if (nv < val) { d = Math.abs(nv) - val; if (d > 0d && d < delta) { delta = d; ret = nv; } } } return ret; } public static int lonQuadrant(double lon) { int ret = 1; if (lon >= 0 & lon < 90) { ret = 1; } else if (lon >= 90 & lon <= 180) { ret = 2; } else if (lon > -180 & lon <= -90) { ret = 3; } else if (lon > -90 & lon < 0) { ret = 4; } return ret; } }