/alaspatial/src/main/java/org/ala/spatial/analysis/layers/GetValuesOccurrencesThread.java

http://alageospatialportal.googlecode.com/ · Java · 123 lines · 67 code · 6 blank · 50 comment · 21 complexity · 8dbb4d33b45cf37f027846e6f3da6558 MD5 · raw file

  1. /**
  2. * ************************************************************************
  3. * Copyright (C) 2010 Atlas of Living Australia All Rights Reserved.
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with the
  7. * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  11. * the specific language governing rights and limitations under the License.
  12. * *************************************************************************
  13. */
  14. package org.ala.spatial.analysis.layers;
  15. import java.util.BitSet;
  16. import java.util.concurrent.CountDownLatch;
  17. import java.util.concurrent.LinkedBlockingQueue;
  18. /**
  19. * Thread operating to calculate occurrence density, with a moving average,
  20. * grid values from a list of parts.
  21. * @author Adam
  22. */
  23. class GetValuesOccurrencesThread extends Thread {
  24. /**
  25. * List of parts that need a calculation, shared with other threads.
  26. */
  27. LinkedBlockingQueue<Integer> parts;
  28. /**
  29. * Countdown for finished parts.
  30. */
  31. CountDownLatch cdl;
  32. /**
  33. * Size of this part.
  34. */
  35. int partSize;
  36. /**
  37. * Source rows data.
  38. */
  39. int[][] cRows;
  40. /**
  41. * Output array.
  42. */
  43. float[] values;
  44. /**
  45. * If world wrapping applies.
  46. */
  47. boolean worldwrap;
  48. /**
  49. * dimensions of output grid.
  50. */
  51. int height, width;
  52. /**
  53. * current offset for the moving average. It is (moving average - 1) / 2.
  54. */
  55. int offset;
  56. /**
  57. * current row.
  58. */
  59. int currentRow;
  60. /**
  61. * active row.
  62. */
  63. int row;
  64. public GetValuesOccurrencesThread(LinkedBlockingQueue<Integer> parts) {
  65. this.parts = parts;
  66. }
  67. public void set(CountDownLatch cdl, int partSize, int[][] cRows,
  68. float[] values, boolean worldwrap,
  69. int height, int width, int offset, int currentRow, int row) {
  70. this.cdl = cdl;
  71. this.partSize = partSize;
  72. this.cRows = cRows;
  73. this.values = values;
  74. this.worldwrap = worldwrap;
  75. this.height = height;
  76. this.width = width;
  77. this.offset = offset;
  78. this.currentRow = currentRow;
  79. this.row = row;
  80. }
  81. @Override
  82. public void run() {
  83. try {
  84. while (true) {
  85. int n = parts.take();
  86. int len = Math.min((n + 1) * partSize, width);
  87. for (int i = n * partSize; i < len; i++) {
  88. int thisCell = 0;
  89. int cellcount = 0;
  90. // apply moving average.
  91. for (int j = i - offset; j <= i + offset; j++) {
  92. for (int k = currentRow - offset; k <= currentRow + offset; k++) {
  93. if (j >= 0 && j < width && k >= 0 && k < height) {
  94. cellcount++;
  95. thisCell += cRows[k - row][j];
  96. } else if (worldwrap && j < 0 && k >= 0 && k < height) {
  97. cellcount++;
  98. thisCell += cRows[k - row][j + width];
  99. } else if (worldwrap && j >= width && k >= 0 && k < height) {
  100. cellcount++;
  101. thisCell += cRows[k - row][j - width];
  102. }
  103. }
  104. }
  105. if (cellcount == 0) {
  106. values[i] = 0;
  107. } else {
  108. values[i] = thisCell / (float) cellcount;
  109. }
  110. }
  111. cdl.countDown();
  112. }
  113. } catch (InterruptedException e) {
  114. //expected when done.
  115. }
  116. }
  117. }