final double latMid = (latMax + latMin) / 2; // idea: latitude of half area (ctry or envp?)
latExtent = latMax-latMin;
lonMin = envelope.getXMin() - .005; // -.005 to catch nearby outliers (approx. 500m)
lonMax = envelope.getXMax() + .005; // +.005 to catch nearby outliers
final double lonOneDeg = lonMin + 1; // arbitrary longitude for establishing lenOneDegBaseline
Point fromPt = new Point(lonMin, latMid),
toPt = new Point(lonOneDeg, latMid);
// geodesicDistanceOnWGS84 is an approximation as we are using a different GCS, but expect it
// to be a good approximation as we are using proportions only, not positions, with it.
final double lenOneDegBaseline = GeometryEngine.geodesicDistanceOnWGS84(fromPt, toPt);
// GeometryEngine.distance "Calculates the 2D planar distance between two geometries."
//angle// final double lenOneDegBaseline = GeometryEngine.distance(fromPt, toPt, spatialReference);
arcLon = gridSide / lenOneDegBaseline; // longitude arc of grid cell
final double latOneDeg = latMid + 1;
toPt.setXY(lonMin, latOneDeg);
final double htOneDeg = GeometryEngine.geodesicDistanceOnWGS84(fromPt, toPt);
int enough = (int)(Math.ceil(.000001 + (lonMax-lonMin)*lenOneDegBaseline/gridSide)) *
(int)(Math.ceil(.000001 + latExtent*htOneDeg/gridSide));
grid = new ArrayList<double[]>(enough);
double xlon, ylat;
// If using quadtree, could filter out cells that do not overlap country polygon
for (ylat = latMin, yCount = 0; ylat < latMax; yCount++) {
fromPt.setXY(lonMin, ylat);
toPt.setXY(lonMin+arcLon, ylat);
double xlen = GeometryEngine.geodesicDistanceOnWGS84(fromPt, toPt);
double height = cellArea/xlen; // meters
double arcLat = height / htOneDeg;
for (xlon = lonMin, xCount = 0; xlon < lonMax; xlon += arcLon, xCount++) {
double[] tmp = {xlon, ylat, xlon+arcLon, ylat+arcLat};