private float getArea(Point2DInteger area) {
    float longitude1 = 1.0f * area.getX() / elementsPerDegree;
    float latitude1 = 90 - 1.0f * area.getY() / elementsPerDegree;
    float longitude2 = 1.0f * (area.getX() + 1) / elementsPerDegree;
    float latitude2 = 90 - 1.0f * (area.getY() + 1) / elementsPerDegree;

    Point3DDouble dist11 = conv.positionDeg(latitude1, longitude1, 0);
    Point3DDouble dist12 = conv.positionDeg(latitude1, longitude2, 0);
    Point3DDouble dist21 = conv.positionDeg(latitude2, longitude1, 0);
    double distX = dist11.distance(dist12);
    double distY = dist11.distance(dist21);
    return (float) (distX * distY);
  }
 private void loop() {
   float max = 0;
   int counter = 0;
   while (nodes.size() != 0) {
     Point2DInteger n = nodes.peek();
     ArrayList<Point2DInteger> children = FlowDirectionUtils.getUpstreamNodes(n, flowDirection);
     if (children.size() == 0) {
       flowAccumulation.set(n.getX(), n.getY(), 0);
       nodes.pop();
     } else {
       float sum = 0;
       boolean hasUndefined = false;
       for (Point2DInteger p : children) {
         float acc = flowAccumulation.get(p.getX(), p.getY());
         if (Float.isNaN(acc)) {
           hasUndefined = true;
           nodes.add(p);
         } else {
           sum += acc;
           sum += getArea(p);
         }
       }
       if (!hasUndefined) {
         max = Math.max(max, sum);
         flowAccumulation.set(n.getX(), n.getY(), sum);
         nodes.pop();
       }
     }
     counter++;
     if ((counter & 0xffff) == 0xffff) {
       System.out.println("FlowAcc " + counter + " " + max);
     }
   }
   System.out.println("Done");
 }