/alaspatial/src/main/java/org/ala/spatial/analysis/layers/GetValuesOccurrencesThread.java
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 */ 14package org.ala.spatial.analysis.layers; 15 16import java.util.BitSet; 17import java.util.concurrent.CountDownLatch; 18import java.util.concurrent.LinkedBlockingQueue; 19 20/** 21 * Thread operating to calculate occurrence density, with a moving average, 22 * grid values from a list of parts. 23 * @author Adam 24 */ 25class GetValuesOccurrencesThread extends Thread { 26 27 /** 28 * List of parts that need a calculation, shared with other threads. 29 */ 30 LinkedBlockingQueue<Integer> parts; 31 /** 32 * Countdown for finished parts. 33 */ 34 CountDownLatch cdl; 35 /** 36 * Size of this part. 37 */ 38 int partSize; 39 /** 40 * Source rows data. 41 */ 42 int[][] cRows; 43 /** 44 * Output array. 45 */ 46 float[] values; 47 /** 48 * If world wrapping applies. 49 */ 50 boolean worldwrap; 51 /** 52 * dimensions of output grid. 53 */ 54 int height, width; 55 /** 56 * current offset for the moving average. It is (moving average - 1) / 2. 57 */ 58 int offset; 59 /** 60 * current row. 61 */ 62 int currentRow; 63 /** 64 * active row. 65 */ 66 int row; 67 68 public GetValuesOccurrencesThread(LinkedBlockingQueue<Integer> parts) { 69 this.parts = parts; 70 } 71 72 public void set(CountDownLatch cdl, int partSize, int[][] cRows, 73 float[] values, boolean worldwrap, 74 int height, int width, int offset, int currentRow, int row) { 75 this.cdl = cdl; 76 this.partSize = partSize; 77 this.cRows = cRows; 78 this.values = values; 79 this.worldwrap = worldwrap; 80 this.height = height; 81 this.width = width; 82 this.offset = offset; 83 this.currentRow = currentRow; 84 this.row = row; 85 } 86 87 @Override 88 public void run() { 89 try { 90 while (true) { 91 int n = parts.take(); 92 int len = Math.min((n + 1) * partSize, width); 93 for (int i = n * partSize; i < len; i++) { 94 int thisCell = 0; 95 int cellcount = 0; 96 // apply moving average. 97 for (int j = i - offset; j <= i + offset; j++) { 98 for (int k = currentRow - offset; k <= currentRow + offset; k++) { 99 if (j >= 0 && j < width && k >= 0 && k < height) { 100 cellcount++; 101 thisCell += cRows[k - row][j]; 102 } else if (worldwrap && j < 0 && k >= 0 && k < height) { 103 cellcount++; 104 thisCell += cRows[k - row][j + width]; 105 } else if (worldwrap && j >= width && k >= 0 && k < height) { 106 cellcount++; 107 thisCell += cRows[k - row][j - width]; 108 } 109 } 110 } 111 if (cellcount == 0) { 112 values[i] = 0; 113 } else { 114 values[i] = thisCell / (float) cellcount; 115 } 116 } 117 cdl.countDown(); 118 } 119 } catch (InterruptedException e) { 120 //expected when done. 121 } 122 } 123}