PageRenderTime 29ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/alaspatial/src/main/java/org/ala/spatial/analysis/index/FilteringIndex.java

http://alageospatialportal.googlecode.com/
Java | 1570 lines | 897 code | 237 blank | 436 comment | 154 complexity | ea063ab2f923b344ef1edc32284f6cee MD5 | raw file
  1. package org.ala.spatial.analysis.index;
  2. //import com.vividsolutions.jts.geom.Geometry;
  3. //import com.vividsolutions.jts.geom.GeometryFactory;
  4. //import com.vividsolutions.jts.io.WKTReader;
  5. import java.io.BufferedInputStream;
  6. import java.io.BufferedOutputStream;
  7. import java.io.File;
  8. import java.io.FileInputStream;
  9. import java.io.FileOutputStream;
  10. import java.io.ObjectInputStream;
  11. import java.io.ObjectOutputStream;
  12. import java.io.RandomAccessFile;
  13. import java.nio.ByteBuffer;
  14. import java.util.ArrayList;
  15. import java.util.Comparator;
  16. import java.util.HashMap;
  17. import java.util.Map;
  18. import java.util.concurrent.LinkedBlockingQueue;
  19. import org.ala.spatial.analysis.cluster.SpatialCluster3;
  20. import org.ala.spatial.util.Grid;
  21. import org.ala.spatial.util.Layer;
  22. import org.ala.spatial.util.Layers;
  23. import org.ala.spatial.util.SimpleShapeFile;
  24. import org.ala.spatial.util.SpatialLogger;
  25. import org.ala.spatial.util.TabulationSettings;
  26. import org.ala.spatial.util.Tile;
  27. //import org.geotools.geometry.jts.JTS;
  28. //import org.geotools.geometry.jts.JTSFactoryFinder;
  29. //import org.geotools.referencing.CRS;
  30. //import org.opengis.referencing.crs.CoordinateReferenceSystem;
  31. //import org.opengis.referencing.operation.MathTransform;
  32. /**
  33. * builder for species list index.
  34. *
  35. * requires OccurrencesIndex to be up to date.
  36. *
  37. * operates on GridFiles
  38. * operates on ShapeFiles
  39. *
  40. * TODO: incremental and partial update mechanism
  41. *
  42. * @author adam
  43. *
  44. */
  45. public class FilteringIndex extends Object {
  46. /**
  47. * length of a grid record in bytes
  48. */
  49. static final int GRID_RECORD_LENGTH = 4 * 3 + 4; //3 floats + 1 int
  50. /**
  51. * length of a catagory record in bytes
  52. */
  53. static final int CATAGORY_RECORD_LENGTH = 4 * 2 + 4;//1 short + 2 floats + 1 int
  54. /**
  55. * mapping for LayerFilters copies, init since static
  56. */
  57. static Map<String, LayerFilter> map_layerfilters = new HashMap<String, LayerFilter>();
  58. /**
  59. * destination of loaded occurrences
  60. */
  61. ArrayList<String[]> occurrences;
  62. String index_path;
  63. /**
  64. * default constructor
  65. */
  66. public FilteringIndex(String directoryPath) {
  67. index_path = directoryPath;
  68. /* load settings file */
  69. TabulationSettings.load();
  70. }
  71. /**
  72. * performs update of 'indexing' for a new layer (grid or shapefile)
  73. *
  74. * @param layername name of the layer to update as String. To update
  75. * all layers use null.
  76. */
  77. public void layersUpdate(String layername) {
  78. /* placeholder for patial update mechanism */
  79. makeSPL_GRID(layername);
  80. makeSPL_CATAGORIES(layername);
  81. /* for onscreen filtering server or client side */
  82. makeAllScaledShortImages(layername);
  83. }
  84. /**
  85. * method to determine if the index is up to date
  86. *
  87. * @return true if index is up to date
  88. */
  89. public boolean isUpToDate() {
  90. /* placeholder for patial update mechanism */
  91. return true;
  92. }
  93. /**
  94. * make species list index for environmental files
  95. *
  96. * for each grid file intersect and export in points order
  97. *
  98. * uses OccurrencesIndex generated SAM_D_ files
  99. */
  100. void makeSPL_GRID(String layername) {
  101. Layer layer;
  102. int i;
  103. /* iterate for each environmental file */
  104. for (i = 0; i < TabulationSettings.environmental_data_files.length; i++) {
  105. layer = TabulationSettings.environmental_data_files[i];
  106. if (layername != null
  107. && !layername.equalsIgnoreCase(TabulationSettings.environmental_data_files[i].name)) {
  108. continue;
  109. }
  110. System.out.println("makeSPL_GRID: " + layer.display_name + " target?: " + layername);
  111. try {
  112. /* open input file for this layer's values in order of records*/
  113. RandomAccessFile sam_d_gridfile = new RandomAccessFile(
  114. index_path + "SAM_D_" + layer.name + ".dat", "r");
  115. int number_of_records = (int) (sam_d_gridfile.length() / 4); //4 bytes in float
  116. byte[] b = new byte[(number_of_records) * 4];
  117. sam_d_gridfile.read(b);
  118. ByteBuffer bb = ByteBuffer.wrap(b);
  119. sam_d_gridfile.close();
  120. /* temporary variables */
  121. double value;
  122. ArrayList<SPLGridRecord> records = new ArrayList<SPLGridRecord>(number_of_records);
  123. /* maintain original record index number
  124. * for unqiueness
  125. */
  126. int p = 0;
  127. /* load all valid values and add to records with species number and
  128. * original record index
  129. */
  130. for (i = 0; i < number_of_records; i++) {
  131. /* split up record line for extraction of:
  132. * species name (column at idx ofu.onetwoCount-1)
  133. * longitude (before last value)
  134. * latitude (last value)
  135. */
  136. value = bb.getFloat();
  137. /* do not want NaN */
  138. if (!Double.isNaN(value)) {
  139. /* put it in a map to sort later */
  140. records.add(new SPLGridRecord(value, p));
  141. }
  142. p++; //increment for next original record
  143. }
  144. /* sort records by environmental value */
  145. java.util.Collections.sort(records,
  146. new Comparator<SPLGridRecord>() {
  147. public int compare(SPLGridRecord r1, SPLGridRecord r2) {
  148. if (r2.value == r1.value) {
  149. return 0;
  150. } else if (r1.value < r2.value) {
  151. return -1;
  152. }
  153. return 1;
  154. }
  155. });
  156. /* open output file and write */
  157. RandomAccessFile outputvalues = new RandomAccessFile(
  158. index_path + "SPL_V_" + layer.name + ".dat", "rw");
  159. RandomAccessFile outputrecords = new RandomAccessFile(
  160. index_path + "SPL_R_" + layer.name + ".dat", "rw");
  161. byte[] b1 = new byte[records.size() * 4]; //for float
  162. ByteBuffer bb1 = ByteBuffer.wrap(b1);
  163. byte[] b2 = new byte[records.size() * 8]; //for int
  164. ByteBuffer bb2 = ByteBuffer.wrap(b2);
  165. for (SPLGridRecord r : records) {
  166. bb1.putFloat((float) r.value);
  167. bb2.putInt(r.record_number);
  168. }
  169. outputvalues.write(b1);
  170. outputrecords.write(b2);
  171. outputvalues.close();
  172. outputrecords.close();
  173. SpatialLogger.log("makeSPL_GRID writing done > " + layer.name);
  174. } catch (Exception e) {
  175. SpatialLogger.log("makeSPL_GRID writing", ">" + layer.name + "> " + e.toString());
  176. }
  177. }
  178. }
  179. /**
  180. * make species list index for catagorical files
  181. *
  182. * for each catagory file, split by field index value
  183. *
  184. */
  185. void makeSPL_CATAGORIES(String layername) {
  186. Layer layer;
  187. int i;
  188. /* iterate for each shape file */
  189. for (i = 0; i < TabulationSettings.geo_tables.length; i++) {
  190. if (layername != null
  191. && !layername.equalsIgnoreCase(TabulationSettings.geo_tables[i].name)) {
  192. continue;
  193. }
  194. layer = TabulationSettings.geo_tables[i];
  195. try {
  196. /* open catagorical value file */
  197. RandomAccessFile sam_i_layerfile = new RandomAccessFile(
  198. index_path
  199. + SamplingIndex.CATAGORICAL_PREFIX + layer.name
  200. + SamplingIndex.VALUE_POSTFIX, "r");
  201. int number_of_records = (int) (sam_i_layerfile.length() / 2); //2 bytes in short
  202. byte[] b = new byte[(number_of_records) * 2];
  203. sam_i_layerfile.read(b);
  204. ByteBuffer bb = ByteBuffer.wrap(b);
  205. sam_i_layerfile.close();
  206. /* temporary variables */
  207. int value;
  208. ArrayList<SPLGridRecord> records = new ArrayList<SPLGridRecord>(number_of_records);
  209. int p = 0; /* maintain original record index number
  210. * for unqiueness
  211. */
  212. /* load all valid values and add to records with species number and
  213. * original record index*/
  214. for (int j = 0; j < number_of_records; j++) {
  215. /* split up record line for extraction of:
  216. * species name (2 before last value)
  217. * longitude (before last value)
  218. * latitude (last value)
  219. */
  220. value = bb.getShort();
  221. /* put it in a map to sort later */
  222. records.add(new SPLGridRecord(value, p));
  223. p++; //maintain original record number
  224. }
  225. /* sort by catagorical value */
  226. java.util.Collections.sort(records,
  227. new Comparator<SPLGridRecord>() {
  228. public int compare(SPLGridRecord r1, SPLGridRecord r2) {
  229. if (r2.value == r1.value) {
  230. return r1.record_number - r2.record_number;
  231. } else if (r1.value < r2.value) {
  232. return -1;
  233. }
  234. return 1;
  235. }
  236. });
  237. /* open output file and write */
  238. int idxpos = 0;
  239. int startpos = 0;
  240. /* iterate across records, exporting each group of records
  241. * with the same value into a separate file with serialization
  242. *
  243. * exports as species_number and original_sorted_index (key)
  244. *
  245. * usage is whole of file
  246. */
  247. int len = records.size();
  248. for (idxpos = 0; idxpos < len; idxpos++) {
  249. if (idxpos + 1 == len || records.get(idxpos).value != records.get(idxpos + 1).value) {
  250. //output the previous group of records into a new file
  251. String filename =
  252. index_path
  253. + "SPL_" + layer.name + "_"
  254. + records.get(idxpos).value + ".dat";
  255. /* open output stream */
  256. FileOutputStream fos = new FileOutputStream(filename);
  257. BufferedOutputStream bos = new BufferedOutputStream(fos);
  258. ObjectOutputStream oos = new ObjectOutputStream(bos);
  259. /* build set */
  260. int[] set = new int[idxpos - startpos + 1];
  261. for (p = startpos; p <= idxpos; p++) {
  262. set[p - startpos] = records.get(p).record_number;
  263. }
  264. /* sort by record_number (key) */
  265. java.util.Arrays.sort(set);
  266. /* write */
  267. oos.writeObject(set);
  268. oos.close();
  269. /* preserve starting pos for end of next value */
  270. startpos = idxpos + 1;
  271. }
  272. }
  273. sam_i_layerfile.close();
  274. SpatialLogger.log("makeSPL_CATAGORIES writing done > " + layer.name);
  275. } catch (Exception e) {
  276. SpatialLogger.log("makeSPL_CATAGORIES writing", ">" + layer.name + "> " + e.toString());
  277. }
  278. }
  279. }
  280. /**
  281. * gets a default LayerFilter for a layer by layer name
  282. * @param layer name of layer
  283. * @return new default LayerFilter or null if does not exist
  284. */
  285. public static LayerFilter getLayerFilter(String layer) {
  286. /* if template already loaded copy it */
  287. LayerFilter layerfilter = map_layerfilters.get(layer);
  288. if (layerfilter == null) {
  289. layerfilter = getLayerFilter(Layers.getLayer(layer));
  290. map_layerfilters.put(layer, layerfilter);
  291. }
  292. /* if still not loaded, reutrn null */
  293. if (layerfilter == null) {
  294. SpatialLogger.info("getLayerFilter(" + layer + ")", ">layer does not exist");
  295. return null;
  296. }
  297. return layerfilter.copy();
  298. }
  299. /**
  300. * gets a default LayerFilter for a layer by layer object
  301. *
  302. * note: use getLayerFilter(String) for public function
  303. *
  304. * @param layer as Layer
  305. * @return new default LayerFilter
  306. */
  307. static private LayerFilter getLayerFilter(Layer layer) {
  308. if (layer == null) {
  309. return null;
  310. }
  311. // check that the tabulationsettings is loaded.
  312. // if not, load it.
  313. if (!TabulationSettings.loaded) {
  314. TabulationSettings.load();
  315. }
  316. /* is it continous (grid file) */
  317. File continous_file = new File(TabulationSettings.environmental_data_path
  318. + layer.name + ".gri");
  319. if (!continous_file.exists()) {
  320. continous_file = new File(TabulationSettings.environmental_data_path
  321. + layer.name + ".GRI");
  322. }
  323. if (continous_file.exists()) {
  324. /* load grid file and fill layerfilter with min/max */
  325. try {
  326. Grid grid = new Grid(TabulationSettings.environmental_data_path
  327. + layer.name);
  328. double minimum = grid.minval;
  329. double maximum = grid.maxval;
  330. return new LayerFilter(layer, null, null, minimum, maximum);
  331. } catch (Exception e) {
  332. SpatialLogger.info("getLayerFilter(" + layer + ")", ">error opening grid file");
  333. return null;
  334. }
  335. }
  336. /* otherwise, catagorical */
  337. /*
  338. * TODO: handle multiple fieldnames
  339. */
  340. String fieldname = layer.fields[0].name;
  341. int i;
  342. File catagories_file = new File(
  343. TabulationSettings.index_path
  344. + SamplingIndex.CATAGORY_LIST_PREFIX
  345. + layer.name + "_" + fieldname
  346. + SamplingIndex.CATAGORY_LIST_POSTFIX);
  347. if (catagories_file.exists()) {
  348. /* load catagories names and fill layerfilter with it */
  349. byte[] data = new byte[(int) catagories_file.length()];
  350. try {
  351. FileInputStream fis = new FileInputStream(catagories_file);
  352. fis.read(data);
  353. fis.close();
  354. /* insert (row number) as beginning of each line */
  355. String str = new String(data);
  356. data = null;
  357. String[] catagory_names = str.split("\n");
  358. int[] catagories = new int[catagory_names.length];
  359. for (i = 0; i < catagories.length; i++) {
  360. catagories[i] = i;
  361. }
  362. return new LayerFilter(layer, catagories, catagory_names, 0, 0);
  363. } catch (Exception e) {
  364. SpatialLogger.log("getLayerExtents(" + layer.name + "), catagorical",
  365. e.toString());
  366. }
  367. }
  368. return null;
  369. }
  370. /**
  371. * gets layer extents for a layer
  372. *
  373. * TODO: improve this function, move to LayerService.java
  374. *
  375. * @param layer_name layer name as String
  376. * @return formatted layer extents as String,
  377. * - min and max for grid
  378. * - list of values for shape
  379. */
  380. static public String getLayerExtents(String layer_name) {
  381. /* is it continous (grid file) */
  382. /*
  383. * TODO: handle multiple fieldnames
  384. */
  385. String fieldname = "";
  386. int i;
  387. for (i = 0; i < TabulationSettings.geo_tables.length; i++) {
  388. Layer l = TabulationSettings.geo_tables[i];
  389. if (l.name.equalsIgnoreCase(layer_name)) {
  390. fieldname = l.fields[0].name;
  391. break;
  392. }
  393. }
  394. File catagories_file = new File(
  395. TabulationSettings.index_path
  396. + SamplingIndex.CATAGORY_LIST_PREFIX
  397. + layer_name + "_" + fieldname
  398. + SamplingIndex.CATAGORY_LIST_POSTFIX);
  399. if (!catagories_file.exists()) {
  400. /* load grid file and get min/max */
  401. try {
  402. Grid grid = new Grid(TabulationSettings.environmental_data_path
  403. + layer_name);
  404. double minimum = grid.minval;
  405. double maximum = grid.maxval;
  406. return ((float) minimum) + " to " + ((float) maximum);
  407. } catch (Exception e) {
  408. /* log error */
  409. //return nothing
  410. return "";
  411. }
  412. }
  413. /* otherwise, catagorical */
  414. if (catagories_file.exists()) {
  415. /* load catagories values file and format */
  416. byte[] data = new byte[(int) catagories_file.length()];
  417. try {
  418. FileInputStream fis = new FileInputStream(catagories_file);
  419. fis.read(data);
  420. fis.close();
  421. /* insert (row number) as beginning of each line */
  422. String str = new String(data);
  423. data = null;
  424. String[] lines = str.split("\n");
  425. str = null;
  426. StringBuffer output = new StringBuffer();
  427. /*
  428. * TODO: add -1, missing
  429. */
  430. int row = 0; // 0..n indexing
  431. for (String s : lines) {
  432. if (s.length() > 0) {
  433. output.append(row + "," + s + "\r\n");
  434. row = row + 1;
  435. }
  436. }
  437. return output.toString().replace("\r\n", "<br>\r\n");
  438. } catch (Exception e) {
  439. SpatialLogger.log("getLayerExtents(" + layer_name + "), catagorical",
  440. e.toString());
  441. }
  442. }
  443. return "";
  444. }
  445. /**
  446. * gets list of SpeciesRecord (species number and record number) from
  447. * a layer filter (LayerFilter), grid/environmental/continous data source
  448. * @param filter layer filter as LayerFilter
  449. * @return records within the filtered region defined as ArrayList<RecordKey>
  450. */
  451. public int[] getGridSampleSet(LayerFilter filter) {
  452. /* grid/env filter, binary searching by seeking */
  453. double dblvalue;
  454. int[] set = null;
  455. try {
  456. /* open VALUES file to determine records positions */
  457. RandomAccessFile raf = new RandomAccessFile(
  458. index_path + "SPL_V_" + filter.layername + ".dat", "r");
  459. /* seek to first position */
  460. int length = (int) raf.length() / 4; //4 = sizeof float
  461. int recordpos = length / 2;
  462. int step = recordpos / 2;
  463. while (step > 1) {
  464. raf.seek(recordpos * 4); //4 = sizeof float
  465. dblvalue = raf.readFloat();
  466. /* determine direction */
  467. if (dblvalue > filter.minimum_value) {
  468. recordpos -= step;
  469. } else {
  470. recordpos += step;
  471. }
  472. step /= 2;
  473. }
  474. /* roll back to before the list */
  475. raf.seek(recordpos * 4); //4 = sizeof float
  476. while (recordpos > 0 && raf.readFloat() > filter.minimum_value) {
  477. recordpos--;
  478. raf.seek(recordpos * 4); //4 = sizeof float
  479. }
  480. /* roll forwards to first record */
  481. raf.seek(recordpos * 4); //4 = sizeof float
  482. while (recordpos < length && raf.readFloat() < filter.minimum_value) {
  483. recordpos++;
  484. raf.seek(recordpos * 4); //4 = sizeof float
  485. }
  486. /* seek to actual position */
  487. raf.seek(recordpos * 4); //4 = sizeof float
  488. int start_recordpos = recordpos;
  489. double over_max = filter.maximum_value + 0.000001; //TODO fix this as an actual small value
  490. /* seek to last position */
  491. length = (int) raf.length() / 4; //4 = sizeof float
  492. recordpos = length / 2;
  493. step = recordpos / 2;
  494. while (step > 1) {
  495. raf.seek(recordpos * 4); //4 = sizeof float
  496. dblvalue = raf.readFloat();
  497. /* determine direction */
  498. if (dblvalue > over_max) {
  499. recordpos -= step;
  500. } else {
  501. recordpos += step;
  502. }
  503. step /= 2;
  504. }
  505. /* roll back to before the list */
  506. raf.seek(recordpos * 4); //4 = sizeof float
  507. while (recordpos > 0 && raf.readFloat() > over_max) {
  508. recordpos--;
  509. raf.seek(recordpos * 4); //4 = sizeof float
  510. }
  511. /* roll forwards to first record */
  512. raf.seek(recordpos * 4); //4 = sizeof float
  513. while (recordpos < length && raf.readFloat() < over_max) {
  514. recordpos++;
  515. raf.seek(recordpos * 4); //4 = sizeof float
  516. }
  517. /* seek to actual position */
  518. raf.seek(recordpos * 4); //4 = sizeof float
  519. int end_recordpos = recordpos - 1;
  520. System.out.println("size: " + end_recordpos + " " + start_recordpos);
  521. raf.close(); //done with VALUES file
  522. /* open RECORDS file to get records numbers */
  523. raf = new RandomAccessFile(
  524. index_path + "SPL_R_" + filter.layername + ".dat", "r");
  525. /* read between start_recordpos and end_recordpos */
  526. raf.seek(start_recordpos * 4); //4 = sizeof int
  527. byte[] records = new byte[(end_recordpos - start_recordpos + 1) * 4]; //TODO: setup for correct use of +1 //4 = sizeof int
  528. raf.read(records);
  529. /* byte buffer */
  530. ByteBuffer bb = ByteBuffer.wrap(records);
  531. /* convert records to keys & add to system */
  532. long len = records.length / 4; //4 = sizeof int
  533. //float longitude, latitude;
  534. int record;
  535. int j;
  536. set = new int[(int) len];
  537. for (j = 0; j < len; j++) {
  538. set[j] = bb.getInt();
  539. }
  540. /* sort by key (record number) */
  541. java.util.Arrays.sort(set);
  542. raf.close();
  543. } catch (Exception e) {
  544. SpatialLogger.log("apply continous species list file",
  545. "layer:" + filter.layername
  546. + "> " + e.toString());
  547. }
  548. return set;
  549. }
  550. /**
  551. * gets list of SpeciesRecord (species number and record number) from
  552. * a layer filter (LayerFilter), catagorical/contextual/shapefile data source
  553. * @param filter layer filter as LayerFilter
  554. * @return records within the filtered region defined as ArrayList<SpeciesRecord>
  555. */
  556. public int[] getCatagorySampleSet(LayerFilter filter) {
  557. int[] set = null;
  558. /* catagory filter, iterate the whole file for each catagory */
  559. int value;
  560. int k = 0;
  561. int j;
  562. for (j = 0; j < filter.catagories.length; j++) {
  563. value = filter.catagories[j];
  564. try {
  565. String filename =
  566. index_path + "SPL_" + filter.layername + "_"
  567. + ((double) value) + ".dat";
  568. FileInputStream fos = new FileInputStream(filename);
  569. BufferedInputStream bos = new BufferedInputStream(fos);
  570. ObjectInputStream oos = new ObjectInputStream(bos);
  571. int[] newset;
  572. newset = (int[]) oos.readObject();
  573. oos.close();
  574. if (set != null) {
  575. int[] joined = new int[set.length + newset.length];
  576. System.arraycopy(set, 0, joined, 0, set.length);
  577. System.arraycopy(newset, 0, joined, set.length, newset.length);
  578. } else {
  579. set = newset;
  580. }
  581. } catch (Exception e) {
  582. SpatialLogger.log("apply catagory species list file",
  583. "layer:" + filter.layername + " cat:" + value
  584. + ": species_mask_layer len:"
  585. + " : " + k + ">" + e.toString());
  586. }
  587. }
  588. if (filter.catagories.length > 1) {
  589. java.util.Arrays.sort(set);
  590. }
  591. return set;
  592. }
  593. /**
  594. * makes indexed tiles for filtering by a region
  595. *
  596. * TODO: dynamic
  597. */
  598. public void makeAllScaledShortImages(String layername) {
  599. /* ?? default long lat & dist */
  600. double longitude_start = 112;
  601. double longitude_end = 154;
  602. double latitude_start = -44;//-44;
  603. double latitude_end = -9;
  604. int height = 840; //210 42/210
  605. int width = 1008; //252
  606. int i, j;
  607. /* get all layers */
  608. int size = 0;
  609. Layer[] all_layers = new Layer[TabulationSettings.environmental_data_files.length
  610. + TabulationSettings.geo_tables.length];
  611. j = TabulationSettings.environmental_data_files.length;
  612. for (i = 0; i < j; i++) {
  613. if (layername != null
  614. && !layername.equalsIgnoreCase(TabulationSettings.environmental_data_files[i].name)) {
  615. continue;
  616. }
  617. all_layers[size++] = TabulationSettings.environmental_data_files[i];
  618. }
  619. for (i = 0; i < TabulationSettings.geo_tables.length; i++) {
  620. if (layername != null
  621. && !layername.equalsIgnoreCase(TabulationSettings.geo_tables[i].name)) {
  622. continue;
  623. }
  624. all_layers[size++] = TabulationSettings.geo_tables[i];
  625. }
  626. /* process all layers */
  627. for (i = 0; i < size; i++) {
  628. //makeScaledShortImageFromGrid(all_layers[i], longitude_start, longitude_end, latitude_start, latitude_end, width, height);
  629. makeScaledShortImageFromGridToMetresGrid(all_layers[i], longitude_start, longitude_end, latitude_start, latitude_end, width, height);
  630. i++;
  631. }
  632. }
  633. /**
  634. * filter tile creation...
  635. *
  636. * more in docs now
  637. *
  638. * @param l layer as Layer
  639. * @param longitude_start longitude extent as double
  640. * @param longitude_end other longitude extent as double
  641. * @param latitude_start latitude extent as double
  642. * @param latitude_end other latitude extent as double
  643. * @param width width resoluion as int
  644. * @param height height resolution as in
  645. */
  646. public void makeScaledShortImageFromGrid(Layer l, double longitude_start, double longitude_end,
  647. double latitude_start, double latitude_end, int width, int height) {
  648. /* output data */
  649. Tile[] data;
  650. /* load raw */
  651. if (l.type.equals("environmental")) {
  652. data = getTileFromGrid(l.name, longitude_start, longitude_end, latitude_start, latitude_end, width, height);
  653. } else {
  654. data = getTileFromShape(l, longitude_start, longitude_end, latitude_start, latitude_end, width, height);
  655. }
  656. /* sort */
  657. java.util.Arrays.sort(data,
  658. new Comparator<Tile>() {
  659. public int compare(Tile i1, Tile i2) {
  660. if (i1.value_ < i2.value_) {
  661. return -1;
  662. } else if (i1.value_ > i2.value_) {
  663. return 1;
  664. }
  665. return 0;
  666. }
  667. });
  668. /* index, only used for non-enviornmental layers */
  669. boolean has_index = true;
  670. if (l.type.equals("environmental")) {
  671. has_index = false;
  672. }
  673. int[] index = null;
  674. if (has_index) {
  675. int i, j;
  676. int max = (int) data[data.length - 1].value_;
  677. index = new int[max + 2];
  678. int last_idx = 1;
  679. for (i = 1; i < data.length; i++) {
  680. if (data[i].value_ != data[i - 1].value_) {
  681. for (j = last_idx; j <= data[i].value_; j++) {
  682. index[j] = i;
  683. }
  684. last_idx = (int) data[i].value_ + 1;
  685. }
  686. }
  687. index[max + 1] = data.length;
  688. }
  689. /* write as object*/
  690. try {
  691. FileOutputStream fos = new FileOutputStream(
  692. TabulationSettings.index_path + "SPL_IMG_T_" + l.name + ".dat");
  693. BufferedOutputStream bos = new BufferedOutputStream(fos);
  694. ObjectOutputStream oos = new ObjectOutputStream(bos);
  695. oos.writeObject(data);
  696. oos.writeObject(new Boolean(has_index));
  697. if (has_index) {
  698. oos.writeObject(index);
  699. }
  700. oos.close();
  701. } catch (Exception e) {
  702. /* TODO: log error */
  703. }
  704. }
  705. /**
  706. * filter tile creation...
  707. *
  708. * more in docs now, meters grid from provided grid,
  709. *
  710. * TODO: better solution for projection change
  711. *
  712. * @param l layer as Layer
  713. * @param longitude_start longitude extent as double
  714. * @param longitude_end other longitude extent as double
  715. * @param latitude_start latitude extent as double
  716. * @param latitude_end other latitude extent as double
  717. * @param width width resoluion as int
  718. * @param height height resolution as in
  719. */
  720. public void makeScaledShortImageFromGridToMetresGrid(Layer l, double longitude_start, double longitude_end,
  721. double latitude_start, double latitude_end, int width, int height) {
  722. /* output data */
  723. Tile[] data;
  724. /* load raw */
  725. if (l.type.equals("environmental")) {
  726. data = getTileFromGridToMetresGrid(l.name, longitude_start, longitude_end, latitude_start, latitude_end, width, height);
  727. } else {
  728. data = getTileFromShape(l, longitude_start, longitude_end, latitude_start, latitude_end, width, height);
  729. }
  730. /* sort */
  731. java.util.Arrays.sort(data,
  732. new Comparator<Tile>() {
  733. public int compare(Tile i1, Tile i2) {
  734. if (i1.value_ < i2.value_) {
  735. return -1;
  736. } else if (i1.value_ > i2.value_) {
  737. return 1;
  738. }
  739. return 0;
  740. }
  741. });
  742. /* index, only used for non-enviornmental layers */
  743. boolean has_index = true;
  744. if (l.type.equals("environmental")) {
  745. has_index = false;
  746. }
  747. int[] index = null;
  748. if (has_index) {
  749. int i, j;
  750. int max = (int) data[data.length - 1].value_;
  751. index = new int[max + 2];
  752. int last_idx = 1;
  753. for (i = 1; i < data.length; i++) {
  754. if (data[i].value_ != data[i - 1].value_) {
  755. for (j = last_idx; j <= data[i].value_; j++) {
  756. index[j] = i;
  757. }
  758. last_idx = (int) data[i].value_ + 1;
  759. }
  760. }
  761. index[max + 1] = data.length;
  762. }
  763. /* write as object*/
  764. try {
  765. FileOutputStream fos = new FileOutputStream(
  766. TabulationSettings.index_path + "SPL_IMG_T_" + l.name + ".dat");
  767. BufferedOutputStream bos = new BufferedOutputStream(fos);
  768. ObjectOutputStream oos = new ObjectOutputStream(bos);
  769. oos.writeObject(data);
  770. oos.writeObject(new Boolean(has_index));
  771. if (has_index) {
  772. oos.writeObject(index);
  773. }
  774. oos.close();
  775. } catch (Exception e) {
  776. /* TODO: log error */
  777. }
  778. }
  779. /**
  780. * gets Tile data from a grid file onto specified extents
  781. *
  782. * @param layer_name
  783. * @param longitude_start
  784. * @param longitude_end
  785. * @param latitude_start
  786. * @param latitude_end
  787. * @param longitude_steps
  788. * @param latitude_steps
  789. * @return Tile[]
  790. */
  791. public Tile[] getTileFromGrid(String layer_name,
  792. double longitude_start, double longitude_end,
  793. double latitude_start, double latitude_end,
  794. int longitude_steps, int latitude_steps) {
  795. Grid grid = new Grid(
  796. TabulationSettings.environmental_data_path
  797. + layer_name);
  798. /* make points to interrogate */
  799. double[][] points = new double[longitude_steps * latitude_steps][2];
  800. for (int j = 0; j < latitude_steps; j++) {
  801. for (int i = 0; i < longitude_steps; i++) {
  802. points[j * longitude_steps + i][0] = longitude_start
  803. + i / (double) (longitude_steps - 1) * (longitude_end - longitude_start);
  804. points[j * longitude_steps + i][1] = latitude_end
  805. - j / (double) (latitude_steps - 1) * (latitude_end - latitude_start);
  806. }
  807. }
  808. /* get layer data */
  809. float[] values = grid.getValues2(points);
  810. if (values != null && values.length > 0) {
  811. int i;
  812. /* copy values back to byte data */
  813. int countvalues = 0;
  814. for (i = 0; i < values.length; i++) {
  815. if (!Double.isNaN(values[i])) {
  816. countvalues++;
  817. }
  818. }
  819. Tile[] data = new Tile[countvalues];
  820. int p = 0;
  821. for (i = 0; i < values.length; i++) {
  822. if (!Double.isNaN(values[i])) {
  823. data[p++] = new Tile((float) values[i], i);
  824. }
  825. }
  826. /* return data */
  827. return data;
  828. }
  829. return null;
  830. }
  831. /**
  832. * gets Tile data from a grid file onto specified extents
  833. *
  834. * @param layer_name
  835. * @param longitude_start
  836. * @param longitude_end
  837. * @param latitude_start
  838. * @param latitude_end
  839. * @param longitude_steps
  840. * @param latitude_steps
  841. * @return Tile[]
  842. */
  843. public Tile[] getTileFromGridToMetresGrid(String layer_name,
  844. double longitude_start, double longitude_end,
  845. double latitude_start, double latitude_end,
  846. int longitude_steps, int latitude_steps) {
  847. Grid grid = new Grid(
  848. TabulationSettings.environmental_data_path
  849. + layer_name);
  850. /* make points to interrogate */
  851. double[][] points = new double[longitude_steps * latitude_steps][2];
  852. //get latproj and longproj between display projection and data projection
  853. SpatialCluster3 sc = new SpatialCluster3();
  854. int[] px_boundary = new int[4];
  855. px_boundary[0] = sc.convertLngToPixel(longitude_start);
  856. px_boundary[2] = sc.convertLngToPixel(longitude_end);
  857. px_boundary[1] = sc.convertLatToPixel(latitude_start);
  858. px_boundary[3] = sc.convertLatToPixel(latitude_end);
  859. double[] latproj = new double[latitude_steps];
  860. double[] longproj = new double[longitude_steps];
  861. for (int i = 0; i < latproj.length; i++) {
  862. latproj[i] = sc.convertPixelToLat((int) (px_boundary[1] + (px_boundary[3] - px_boundary[1]) * (i / (double) (latproj.length))));
  863. }
  864. for (int i = 0; i < longproj.length; i++) {
  865. longproj[i] = sc.convertPixelToLng((int) (px_boundary[0] + (px_boundary[2] - px_boundary[0]) * (i / (double) (longproj.length))));
  866. }
  867. //add half cell for sample center
  868. double latoffset = (latproj[1] - latproj[0]) / 2.0;
  869. for (int i = 0; i < latproj.length; i++) {
  870. latproj[i] += latoffset;
  871. }
  872. double longoffset = (longproj[1] - longproj[0]) / 2.0;
  873. for (int i = 0; i < longproj.length; i++) {
  874. longproj[i] += longoffset;
  875. }
  876. for (int j = 0; j < latitude_steps; j++) {
  877. for (int i = 0; i < longitude_steps; i++) {
  878. points[j * longitude_steps + i][0] = longproj[i];
  879. points[j * longitude_steps + i][1] = latproj[latitude_steps - 1 - j];
  880. }
  881. }
  882. /* get layer data */
  883. float[] values = grid.getValues2(points);
  884. if (values != null && values.length > 0) {
  885. int i;
  886. /* copy values back to byte data */
  887. int countvalues = 0;
  888. for (i = 0; i < values.length; i++) {
  889. if (!Double.isNaN(values[i])) {
  890. countvalues++;
  891. }
  892. }
  893. Tile[] data = new Tile[countvalues];
  894. int p = 0;
  895. for (i = 0; i < values.length; i++) {
  896. if (!Double.isNaN(values[i])) {
  897. data[p++] = new Tile((float) values[i], i);
  898. }
  899. }
  900. /* return data */
  901. return data;
  902. }
  903. return null;
  904. }
  905. /**
  906. * get Tiles from shape file layer
  907. *
  908. * @param l layer as Layer
  909. * @param longitude_start
  910. * @param longitude_end
  911. * @param latitude_start
  912. * @param latitude_end
  913. * @param longitude_steps
  914. * @param latitude_steps
  915. * @return Tile []
  916. */
  917. public Tile[] getTileFromShape(Layer l,
  918. double longitude_start, double longitude_end,
  919. double latitude_start, double latitude_end,
  920. int longitude_steps, int latitude_steps) {
  921. SimpleShapeFile ssf = new SimpleShapeFile(
  922. TabulationSettings.environmental_data_path
  923. + l.name);
  924. int column_idx = ssf.getColumnIdx(l.fields[0].name);
  925. Tile[] data = ssf.getTileList(column_idx, longitude_start, latitude_start, longitude_end, latitude_end, longitude_steps, latitude_steps);
  926. return data;
  927. }
  928. void occurrencesUpdate(boolean forceUpdate) {
  929. /* threaded building, needs more ram than one at a time */
  930. int threadcount = TabulationSettings.analysis_threads;
  931. ArrayList<String> layers = new ArrayList();
  932. int i;
  933. for (i = 0; i < TabulationSettings.geo_tables.length; i++) {
  934. if (forceUpdate || !isUpToDateCatagorical(TabulationSettings.geo_tables[i].name)) {
  935. // layers.add(TabulationSettings.geo_tables[i].name);
  936. }
  937. }
  938. for (i = 0; i < TabulationSettings.environmental_data_files.length; i++) {
  939. if (forceUpdate || !isUpToDateContinous(TabulationSettings.environmental_data_files[i].name)) {
  940. layers.add(TabulationSettings.environmental_data_files[i].name);
  941. }
  942. }
  943. if(layers.size() == 0) {
  944. return;
  945. }
  946. LinkedBlockingQueue<String> lbq = new LinkedBlockingQueue(layers);
  947. FilteringIndexThread[] it = new FilteringIndexThread[threadcount];
  948. for (i = 0; i < threadcount; i++) {
  949. it[i] = new FilteringIndexThread(lbq, index_path);
  950. }
  951. System.out.println("Start FilteringIndex.build_all (" + threadcount + " threads): " + System.currentTimeMillis());
  952. //height mapping here while it is running
  953. startBuildAreaSize();
  954. //wait until all done
  955. try {
  956. boolean alive = true;
  957. while (alive) {
  958. Thread.sleep(2000);
  959. alive = false;
  960. for (i = 0; i < threadcount; i++) {
  961. if (it[i].isAlive()) {
  962. alive = true;
  963. break;
  964. }
  965. }
  966. }
  967. } catch (Exception e) {
  968. e.printStackTrace();
  969. }
  970. }
  971. //build vertical area file, for image in epsg900913
  972. // static void buildAreaSize(double longitude_start, double longitude_end,
  973. // double latitude_start, double latitude_end,
  974. // int longitude_steps, int latitude_steps,
  975. // String filename) {
  976. //
  977. // //get latproj between display projection and data projection
  978. // SpatialCluster3 sc = new SpatialCluster3();
  979. // int[] px_boundary = new int[4];
  980. // px_boundary[0] = sc.convertLngToPixel(longitude_start);
  981. // px_boundary[2] = sc.convertLngToPixel(longitude_end);
  982. // px_boundary[1] = sc.convertLatToPixel(latitude_start);
  983. // px_boundary[3] = sc.convertLatToPixel(latitude_end);
  984. //
  985. // double[] latproj = new double[latitude_steps + 1];
  986. // double[] longproj = new double[longitude_steps];
  987. // for (int i = 0; i < latproj.length; i++) {
  988. // latproj[i] = sc.convertPixelToLat((int) (px_boundary[1] + (px_boundary[3] - px_boundary[1]) * (i / (double) (latproj.length))));
  989. // }
  990. // for (int i = 0; i < longproj.length; i++) {
  991. // longproj[i] = sc.convertPixelToLng((int) (px_boundary[0] + (px_boundary[2] - px_boundary[0]) * (i / (double) (longproj.length))));
  992. // }
  993. //
  994. // //get area's
  995. // double[] areaSize = new double[latitude_steps];
  996. //
  997. // double north, south, east, west;
  998. // east = longproj[longproj.length - 2];
  999. // west = longproj[longproj.length - 1];
  1000. //
  1001. // try {
  1002. // String wkt4326 = "GEOGCS[" + "\"WGS 84\"," + " DATUM[" + " \"WGS_1984\","
  1003. // + " SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],"
  1004. // + " TOWGS84[0,0,0,0,0,0,0]," + " AUTHORITY[\"EPSG\",\"6326\"]],"
  1005. // + " PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],"
  1006. // + " UNIT[\"DMSH\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9108\"]],"
  1007. // + " AXIS[\"Lat\",NORTH]," + " AXIS[\"Long\",EAST],"
  1008. // + " AUTHORITY[\"EPSG\",\"4326\"]]";
  1009. // String wkt3577 = "PROJCS[\"GDA94 / Australian Albers\","
  1010. // + " GEOGCS[\"GDA94\","
  1011. // + " DATUM[\"Geocentric_Datum_of_Australia_1994\","
  1012. // + " SPHEROID[\"GRS 1980\",6378137,298.257222101,"
  1013. // + " AUTHORITY[\"EPSG\",\"7019\"]],"
  1014. // + " TOWGS84[0,0,0,0,0,0,0],"
  1015. // + " AUTHORITY[\"EPSG\",\"6283\"]],"
  1016. // + " PRIMEM[\"Greenwich\",0,"
  1017. // + " AUTHORITY[\"EPSG\",\"8901\"]],"
  1018. // + " UNIT[\"degree\",0.01745329251994328,"
  1019. // + " AUTHORITY[\"EPSG\",\"9122\"]],"
  1020. // + " AUTHORITY[\"EPSG\",\"4283\"]],"
  1021. // + " UNIT[\"metre\",1,"
  1022. // + " AUTHORITY[\"EPSG\",\"9001\"]],"
  1023. // + " PROJECTION[\"Albers_Conic_Equal_Area\"],"
  1024. // + " PARAMETER[\"standard_parallel_1\",-18],"
  1025. // + " PARAMETER[\"standard_parallel_2\",-36],"
  1026. // + " PARAMETER[\"false_northing\",0],"
  1027. // + " PARAMETER[\"latitude_of_center\",0],"
  1028. // + " PARAMETER[\"longitude_of_center\",132],"
  1029. // + " PARAMETER[\"false_easting\",0],"
  1030. // + " AUTHORITY[\"EPSG\",\"3577\"],"
  1031. // + " AXIS[\"Easting\",EAST],"
  1032. // + " AXIS[\"Northing\",NORTH]]";
  1033. //
  1034. // CoordinateReferenceSystem wgsCRS = CRS.parseWKT(wkt4326);
  1035. // CoordinateReferenceSystem GDA94CRS = CRS.parseWKT(wkt3577);
  1036. // MathTransform transform = CRS.findMathTransform(wgsCRS, GDA94CRS);
  1037. //
  1038. // GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
  1039. // WKTReader reader = new WKTReader(geometryFactory);
  1040. //
  1041. // for (int i = 0; i < latitude_steps; i++) {
  1042. // south = latproj[i];
  1043. // north = latproj[i + 1]; //latproj is len latitude_steps+1
  1044. //
  1045. // //backwards otherwise projection fails (?)
  1046. // String wkt = "POLYGON((" + south + " " + east
  1047. // + ", " + north + " " + east
  1048. // + ", " + north + " " + west
  1049. // + ", " + south + " " + west
  1050. // + ", " + south + " " + east + "))";
  1051. //
  1052. // Geometry geom = reader.read(wkt);
  1053. // Geometry geomT = JTS.transform(geom, transform);
  1054. //
  1055. // //images are top down, this is south to north.
  1056. // areaSize[latitude_steps - 1 - i] = geomT.getArea();
  1057. // }
  1058. // } catch (Exception ex) {
  1059. // ex.printStackTrace();
  1060. // }
  1061. //
  1062. // //export
  1063. // try {
  1064. // String fname = TabulationSettings.index_path + filename;
  1065. //
  1066. // FileOutputStream fos = new FileOutputStream(fname);
  1067. // BufferedOutputStream bos = new BufferedOutputStream(fos);
  1068. // ObjectOutputStream oos = new ObjectOutputStream(bos);
  1069. //
  1070. // oos.writeObject(areaSize);
  1071. //
  1072. // oos.close();
  1073. // } catch (Exception e) {
  1074. // e.printStackTrace();
  1075. // }
  1076. // }
  1077. static void buildAreaSizeG(double longitude_start, double longitude_end,
  1078. double latitude_start, double latitude_end,
  1079. int longitude_steps, int latitude_steps,
  1080. String filename, boolean imageSpacing) {
  1081. //get area's
  1082. double[] areaSize = new double[latitude_steps];
  1083. double [][] points = new double[4][2];
  1084. if(imageSpacing) {
  1085. //get latproj between display projection and data projection
  1086. SpatialCluster3 sc = new SpatialCluster3();
  1087. int[] px_boundary = new int[4];
  1088. px_boundary[0] = sc.convertLngToPixel(longitude_start);
  1089. px_boundary[2] = sc.convertLngToPixel(longitude_end);
  1090. px_boundary[1] = sc.convertLatToPixel(latitude_start);
  1091. px_boundary[3] = sc.convertLatToPixel(latitude_end);
  1092. double[] latproj = new double[latitude_steps + 1];
  1093. double[] longproj = new double[longitude_steps];
  1094. for (int i = 0; i < latproj.length; i++) {
  1095. latproj[i] = sc.convertPixelToLat((int) (px_boundary[1] + (px_boundary[3] - px_boundary[1]) * (i / (double) (latproj.length))));
  1096. }
  1097. for (int i = 0; i < longproj.length; i++) {
  1098. longproj[i] = sc.convertPixelToLng((int) (px_boundary[0] + (px_boundary[2] - px_boundary[0]) * (i / (double) (longproj.length))));
  1099. }
  1100. double east = longproj[longproj.length - 2];
  1101. double west = longproj[longproj.length - 1];
  1102. points[0][0] = east;
  1103. points[1][0] = west;
  1104. points[2][0] = west;
  1105. points[3][0] = east;
  1106. for (int i = 0; i < latitude_steps; i++) {
  1107. double south = latproj[i];
  1108. double north = latproj[i + 1]; //latproj is len latitude_steps+1
  1109. points[0][1] = north;
  1110. points[1][1] = north;
  1111. points[2][1] = south;
  1112. points[3][1] = south;
  1113. //images are top down, this is south to north.
  1114. areaSize[latitude_steps - 1 - i] = calculateArea(points);
  1115. }
  1116. } else {
  1117. double east = longitude_start;
  1118. double west = east + (longitude_end - longitude_start) / (double) longitude_steps;
  1119. double yrange = latitude_end - latitude_start;
  1120. points[0][0] = east;
  1121. points[1][0] = west;
  1122. points[2][0] = west;
  1123. points[3][0] = east;
  1124. for (int i = 0; i < latitude_steps; i++) {
  1125. double south = latitude_start + i / (double) latitude_steps * yrange;
  1126. double north = latitude_start + (i+1) / (double) latitude_steps * yrange;
  1127. if(i == latitude_steps - 1) {
  1128. north = latitude_end;
  1129. }
  1130. points[0][1] = north;
  1131. points[1][1] = north;
  1132. points[2][1] = south;
  1133. points[3][1] = south;
  1134. //images are top down, this is south to north.
  1135. areaSize[latitude_steps - 1 - i] = calculateArea(points);
  1136. }
  1137. }
  1138. //export
  1139. try {
  1140. String fname = TabulationSettings.index_path + filename;
  1141. FileOutputStream fos = new FileOutputStream(fname);
  1142. BufferedOutputStream bos = new BufferedOutputStream(fos);
  1143. ObjectOutputStream oos = new ObjectOutputStream(bos);
  1144. oos.writeObject(areaSize);
  1145. oos.close();
  1146. } catch (Exception e) {
  1147. e.printStackTrace();
  1148. }
  1149. }
  1150. static public double[] getImageLatitudeArea() {
  1151. String filename = TabulationSettings.index_path + "IMAGE_LATITUDE_AREA";
  1152. //create it if it does not exist
  1153. File file = new File(filename);
  1154. if (!file.exists()) {
  1155. startBuildAreaSize();
  1156. }
  1157. //import
  1158. double[] areaSize = null;
  1159. try {
  1160. FileInputStream fis = new FileInputStream(filename);
  1161. BufferedInputStream bis = new BufferedInputStream(fis);
  1162. ObjectInputStream ois = new ObjectInputStream(bis);
  1163. areaSize = (double[]) ois.readObject();
  1164. ois.close();
  1165. } catch (Exception e) {
  1166. e.printStackTrace();
  1167. }
  1168. return areaSize;
  1169. }
  1170. static void startBuildAreaSize() {
  1171. double longitude_start = 112;
  1172. double longitude_end = 154;
  1173. double latitude_start = -44;//-44;
  1174. double latitude_end = -9;
  1175. int height = 840; //210 42/210
  1176. int width = 1008; //252
  1177. buildAreaSizeG(longitude_start, longitude_end, latitude_start, latitude_end, width, height, "IMAGE_LATITUDE_AREA", true);
  1178. }
  1179. static public double[] getCommonGridLatitudeArea() {
  1180. String filename = TabulationSettings.index_path + "IMAGE_LATITUDE_AREA_COMMON_GRID";
  1181. //create it if it does not exist
  1182. File file = new File(filename);
  1183. if (!file.exists()) {
  1184. buildAreaSizeG(TabulationSettings.grd_xmin,
  1185. TabulationSettings.grd_xmax,
  1186. TabulationSettings.grd_ymin,
  1187. TabulationSettings.grd_ymax,
  1188. TabulationSettings.grd_ncols,
  1189. TabulationSettings.grd_nrows,
  1190. "IMAGE_LATITUDE_AREA_COMMON_GRID", false);
  1191. }
  1192. //import
  1193. double[] areaSize = null;
  1194. try {
  1195. FileInputStream fis = new FileInputStream(filename);
  1196. BufferedInputStream bis = new BufferedInputStream(fis);
  1197. ObjectInputStream ois = new ObjectInputStream(bis);
  1198. areaSize = (double[]) ois.readObject();
  1199. ois.close();
  1200. } catch (Exception e) {
  1201. e.printStackTrace();
  1202. }
  1203. return areaSize;
  1204. }
  1205. /**
  1206. * determine if a GRD/GRI layer's filtering index is up to date.
  1207. *
  1208. * index_path + "SAM_D_" + layer.name + ".dat"
  1209. * grid file
  1210. *
  1211. * both dated earlier than
  1212. *
  1213. * index_path + "SPL_V_" + layer.name + ".dat"
  1214. * index_path + "SPL_R_" + layer.name + ".dat"
  1215. *
  1216. * @param fileName
  1217. * @return true if up to date
  1218. */
  1219. private boolean isUpToDateContinous(String fileName) {
  1220. //is it continous (grd/gri)
  1221. File gri = new File(TabulationSettings.environmental_data_path
  1222. + fileName + ".gri");
  1223. File grd = new File(TabulationSettings.environmental_data_path
  1224. + fileName + ".grd");
  1225. //extension case alternative
  1226. if (!gri.exists()) {
  1227. gri = new File(TabulationSettings.environmental_data_path
  1228. + fileName + ".GRI");
  1229. }
  1230. if (!grd.exists()) {
  1231. grd = new File(TabulationSettings.environmental_data_path
  1232. + fileName + ".GRD");
  1233. }
  1234. File samD = new File(index_path + "SAM_D_" + fileName + ".dat");
  1235. File splV = new File(index_path + "SPL_V_" + fileName + ".dat");
  1236. File splR = new File(index_path + "SPL_R_" + fileName + ".dat");
  1237. if (gri.exists() && grd.exists() && samD.exists()
  1238. && splV.exists() && splR.exists()) {
  1239. long latestData = Math.max(Math.max(grd.lastModified(), gri.lastModified()), samD.lastModified());
  1240. return splV.lastModified() > latestData
  1241. && splR.lastModified() > latestData;
  1242. }
  1243. return false;
  1244. }
  1245. /**
  1246. * determine if a SHP/DBF layer's sampling index is up to date.
  1247. *
  1248. * index_path + "SAM_D_" + layer.name + ".dat"
  1249. * index_path + SamplingIndex.CATAGORICAL_PREFIX + layer.name + SamplingIndex.VALUE_POSTFIX
  1250. *
  1251. * both dated earlier than
  1252. *
  1253. * index_path + "SPL_V_" + layer.name + ".dat"
  1254. * index_path + "SPL_R_" + layer.name + ".dat"
  1255. *
  1256. * @param fileName
  1257. * @return true if up to date
  1258. */
  1259. private boolean isUpToDateCatagorical(String fileName) {
  1260. //is it continous (grd/gri)
  1261. File sam = new File(index_path + SamplingIndex.CATAGORICAL_PREFIX + fileName + SamplingIndex.VALUE_POSTFIX);
  1262. File spl0 = new File(index_path
  1263. + "SPL_" + fileName + "_"
  1264. + "0.0" + ".dat");
  1265. if (spl0.exists() && sam.exists()) {
  1266. return spl0.lastModified() > sam.lastModified();
  1267. }
  1268. return false;
  1269. }
  1270. //calculateArea from FilteringResultsWCController
  1271. static private double calculateArea(double [][] areaarr) {
  1272. try {
  1273. double totalarea = 0.0;
  1274. double [] d = areaarr[0];
  1275. for (int f = 1; f < areaarr.length-2; ++f) {
  1276. totalarea += Mh(d, areaarr[f], areaarr[f + 1]);
  1277. }
  1278. totalarea = Math.abs(totalarea*6378137*6378137);
  1279. //return as sq km
  1280. return totalarea / 1000.0 / 1000.0;
  1281. } catch (Exception e) {
  1282. System.out.println("Error in calculateArea");
  1283. e.printStackTrace(System.out);
  1284. }
  1285. return 0;
  1286. }
  1287. static private double Mh(double [] a, double [] b, double [] c) {
  1288. return Nh(a, b, c) * hi(a, b, c);
  1289. }
  1290. static private double Nh(double [] a, double [] b, double [] c) {
  1291. double [][] poly = {a, b, c, a};
  1292. double[] area = new double[3];
  1293. int i = 0;
  1294. double j = 0.0;
  1295. for (i=0; i < 3; ++i) {
  1296. area[i] = vd(poly[i], poly[i + 1]);
  1297. j += area[i];
  1298. }
  1299. j /= 2;
  1300. double f = Math.tan(j / 2);
  1301. for (i = 0; i < 3; ++i) {
  1302. f *= Math.tan((j - area[i]) / 2);
  1303. }
  1304. return 4 * Math.atan(Math.sqrt(Math.abs(f)));
  1305. }
  1306. static private double hi(double [] a, double [] b, double [] c) {
  1307. double [][] d = {a, b, c};
  1308. int i = 0;
  1309. double[][] bb = new double[3][3];
  1310. for (i = 0; i < 3; ++i) {
  1311. double lng = d[i][0];
  1312. double lat = d[i][1];
  1313. double y = Uc(lat);
  1314. double x = Uc(lng);
  1315. bb[i][0] = Math.cos(y) * Math.cos(x);
  1316. bb[i][1] = Math.cos(y) * Math.sin(x);
  1317. bb[i][2] = Math.sin(y);
  1318. }
  1319. return (bb[0][0] * bb[1][1] * bb[2][2] + bb[1][0] * bb[2][1] * bb[0][2] + bb[2][0] * bb[0][1] * bb[1][2] - bb[0][0] * bb[2][1] * bb[1][2] - bb[1][0] * bb[0][1] * bb[2][2] - bb[2][0] * bb[1][1] * bb[0][2] > 0) ? 1 : -1;
  1320. }
  1321. static private double vd(double [] a, double [] b) {
  1322. double lng1 = a[0];
  1323. double lat1 = a[1];
  1324. double lng2 = b[0];
  1325. double lat2 = b[1];
  1326. double c = Uc(lat1);
  1327. double d = Uc(lat2);
  1328. return 2 * Math.asin(Math.sqrt(Math.pow(Math.sin((c - d) / 2), 2) + Math.cos(c) * Math.cos(d) * Math.pow(Math.sin((Uc(lng1) - Uc(lng2)) / 2), 2)));
  1329. }
  1330. static private double Uc(double a) {
  1331. return a * (Math.PI / 180);
  1332. }
  1333. };