/webportal/src/main/java/org/ala/spatial/analysis/web/AddToolSitesBySpeciesComposer.java

http://alageospatialportal.googlecode.com/ · Java · 575 lines · 459 code · 84 blank · 32 comment · 120 complexity · 0d9d5ab4fa2105ea40cfd5a9ab664623 MD5 · raw file

  1. package org.ala.spatial.analysis.web;
  2. import au.com.bytecode.opencsv.CSVReader;
  3. import au.org.emii.portal.composer.MapComposer;
  4. import au.org.emii.portal.menu.MapLayer;
  5. import au.org.emii.portal.menu.MapLayerMetadata;
  6. import au.org.emii.portal.util.LayerUtilities;
  7. import java.io.StringReader;
  8. import java.net.URL;
  9. import java.net.URLEncoder;
  10. import java.util.ArrayList;
  11. import java.util.HashSet;
  12. import java.util.List;
  13. import org.ala.spatial.data.Facet;
  14. import org.ala.spatial.data.Query;
  15. import org.ala.spatial.util.CommonData;
  16. import org.ala.spatial.data.QueryField;
  17. import org.ala.spatial.data.QueryUtil;
  18. import org.ala.spatial.data.BiocacheQuery;
  19. import org.ala.spatial.data.UploadQuery;
  20. import org.ala.spatial.exception.NoSpeciesFoundException;
  21. import org.ala.spatial.sampling.SimpleRegion;
  22. import org.ala.spatial.sampling.SimpleShapeFile;
  23. import org.ala.spatial.util.SelectedArea;
  24. import org.ala.spatial.util.Util;
  25. import org.apache.commons.httpclient.HttpClient;
  26. import org.apache.commons.httpclient.methods.GetMethod;
  27. import org.apache.commons.httpclient.methods.PostMethod;
  28. import org.zkoss.zhtml.Filedownload;
  29. import org.zkoss.zk.ui.Executions;
  30. import org.zkoss.zk.ui.event.Event;
  31. import org.zkoss.zul.Checkbox;
  32. import org.zkoss.zul.Combobox;
  33. /**
  34. *
  35. * @author ajay
  36. */
  37. public class AddToolSitesBySpeciesComposer extends AddToolComposer {
  38. Checkbox chkOccurrenceDensity;
  39. Checkbox chkSpeciesDensity;
  40. Checkbox chkSitesBySpecies;
  41. Combobox cbMovingAverageSize;
  42. @Override
  43. public void afterCompose() {
  44. super.afterCompose();
  45. this.selectedMethod = "Points To Grid";
  46. this.totalSteps = 3;
  47. this.loadAreaLayers();
  48. this.loadSpeciesLayers(true);
  49. this.updateWindowTitle();
  50. }
  51. @Override
  52. public void onLastPanel() {
  53. System.out.println("**** On last step ****");
  54. super.onLastPanel();
  55. //this.updateName("My Prediction model for " + rgSpecies.getSelectedItem().getLabel());
  56. //this.updateName(getMapComposer().getNextAreaLayerName("Sites By Species"));
  57. }
  58. @Override
  59. public boolean onFinish() {
  60. //super.onFinish();
  61. if (!hasEstimated && !isUserLoggedIn()) {
  62. checkEstimate();
  63. return false;
  64. }
  65. Query query = getSelectedSpecies();
  66. if (query == null) {
  67. getMapComposer().showMessage("There is a problem selecting the species. Try to select the species again", this);
  68. return false;
  69. }
  70. if (searchSpeciesACComp.hasValidItemSelected()) {
  71. getMapComposer().mapSpeciesFromAutocompleteComponent(searchSpeciesACComp, getSelectedArea(), getGeospatialKosher());
  72. } else if (query != null && rgSpecies.getSelectedItem() != null && rgSpecies.getSelectedItem().getValue().equals("multiple")) {
  73. getMapComposer().mapSpecies(query, "Species assemblage", "species", 0, LayerUtilities.SPECIES, null, -1, MapComposer.DEFAULT_POINT_SIZE, MapComposer.DEFAULT_POINT_OPACITY, MapComposer.nextColour());
  74. }
  75. return runsitesbyspecies();
  76. }
  77. Query query = null;
  78. SelectedArea sa = null;
  79. private void setupData() throws Exception {
  80. if (query == null) {
  81. sa = getSelectedArea();
  82. query = QueryUtil.queryFromSelectedArea(getSelectedSpecies(), sa, false, getGeospatialKosher());
  83. }
  84. }
  85. @Override
  86. public long getEstimate() {
  87. try {
  88. setupData();
  89. String ma = "9";
  90. if (cbMovingAverageSize.getSelectedItem() == null) {
  91. String txt = cbMovingAverageSize.getValue();
  92. for (int i = 0; i < cbMovingAverageSize.getItemCount(); i++) {
  93. if (txt != null && txt.equalsIgnoreCase(cbMovingAverageSize.getItemAtIndex(i).getLabel())) {
  94. ma = (String) cbMovingAverageSize.getItemAtIndex(i).getValue();
  95. break;
  96. }
  97. }
  98. } else {
  99. ma = (String) cbMovingAverageSize.getSelectedItem().getValue();
  100. }
  101. int movingAverageSize = Integer.parseInt(ma);
  102. if (movingAverageSize % 2 == 0 || movingAverageSize <= 0 || movingAverageSize >= 16) {
  103. getMapComposer().showMessage("Moving average size " + movingAverageSize + " is not valid. Must be odd and between 1 and 15.", this);
  104. return -1;
  105. }
  106. if (!chkOccurrenceDensity.isChecked()
  107. && !chkSitesBySpecies.isChecked()
  108. && !chkSpeciesDensity.isChecked()) {
  109. getMapComposer().showMessage("Must select at least one output; Sites by species, Occurrence density or Species richness.", this);
  110. return -1;
  111. }
  112. Double gridResolution = dResolution.getValue();
  113. //SelectedArea sa = getSelectedArea();
  114. SimpleRegion sr = SimpleShapeFile.parseWKT(sa.getWkt());
  115. //query = QueryUtil.queryFromSelectedArea(getSelectedSpecies(), sa, false, getGeospatialKosher());
  116. int occurrenceCount = query.getOccurrenceCount();
  117. int boundingboxcellcount = (int) ((sr.getBoundingBox()[1][0] - sr.getBoundingBox()[0][0])
  118. * (sr.getBoundingBox()[1][1] - sr.getBoundingBox()[0][1])
  119. / (gridResolution * gridResolution));
  120. System.out.println("SitesBySpecies for " + occurrenceCount + " occurrences in up to " + boundingboxcellcount + " grid cells.");
  121. if (boundingboxcellcount > settingsSupplementary.getValueAsInt("sitesbyspecies_maxbbcells")) {
  122. //getMapComposer().showMessage("Too many potential output grid cells. Reduce by at least " + String.format("%.2f",100* (1-boundingboxcellcount / (double)settingsSupplementary.getValueAsInt("sitesbyspecies_maxbbcells"))) + "% by decreasing area or increasing resolution.", this);
  123. getMapComposer().showMessage("Too many output grid cells: Decrease area or increase grid size.", this);
  124. return -1;
  125. }
  126. if (occurrenceCount > settingsSupplementary.getValueAsInt("sitesbyspecies_maxoccurrences")) {
  127. getMapComposer().showMessage("Too many occurrences for the selected species in this area. " + occurrenceCount + " occurrences found, must be less than " + settingsSupplementary.getValueAsInt("sitesbyspecies_maxoccurrences"), this);
  128. return -1;
  129. }
  130. StringBuffer sbProcessUrl = new StringBuffer();
  131. sbProcessUrl.append(CommonData.satServer + "/ws/sitesbyspecies/estimate?");
  132. sbProcessUrl.append("speciesq=").append(URLEncoder.encode(QueryUtil.queryFromSelectedArea(query, sa, false, getGeospatialKosher()).getQ(), "UTF-8"));
  133. sbProcessUrl.append("&gridsize=" + URLEncoder.encode(String.valueOf(gridResolution), "UTF-8"));
  134. sbProcessUrl.append("&bs=" + URLEncoder.encode(((BiocacheQuery) query).getBS(), "UTF-8"));
  135. if (chkOccurrenceDensity.isChecked()) {
  136. sbProcessUrl.append("&occurrencedensity=1");
  137. }
  138. if (chkSpeciesDensity.isChecked()) {
  139. sbProcessUrl.append("&speciesdensity=1");
  140. }
  141. if (chkSitesBySpecies.isChecked()) {
  142. sbProcessUrl.append("&sitesbyspecies=1");
  143. }
  144. sbProcessUrl.append("&movingaveragesize=" + ma);
  145. String areaSqKm = "0";
  146. if (sa.getMapLayer() != null && sa.getMapLayer().getData("area") != null) {
  147. areaSqKm = (String) sa.getMapLayer().getData("area");
  148. } else {
  149. areaSqKm = String.format("%,.2f", Util.calculateArea(sa.getWkt()) / 1000000.0);
  150. }
  151. sbProcessUrl.append("&areasqkm=" + areaSqKm);
  152. HttpClient client = new HttpClient();
  153. PostMethod get = new PostMethod(sbProcessUrl.toString());
  154. String area = null;
  155. if (sa.getMapLayer() != null && sa.getMapLayer().getData("envelope") != null) {
  156. area = "ENVELOPE(" + (String) sa.getMapLayer().getData("envelope") + ")";
  157. } else {
  158. area = sa.getWkt();
  159. }
  160. if (getSelectedArea() != null) {
  161. get.addParameter("area", area);
  162. }
  163. get.addParameter("qname", query.getName());
  164. get.addRequestHeader("Accept", "text/plain");
  165. int result = client.executeMethod(get);
  166. String estimate = get.getResponseBodyAsString();
  167. return Long.valueOf(estimate);
  168. } catch (Exception e) {
  169. System.out.println("Unable to get estimates");
  170. e.printStackTrace(System.out);
  171. }
  172. return -1;
  173. }
  174. public boolean runsitesbyspecies() {
  175. try {
  176. setupData();
  177. String ma = "9";
  178. if (cbMovingAverageSize.getSelectedItem() == null) {
  179. String txt = cbMovingAverageSize.getValue();
  180. for (int i = 0; i < cbMovingAverageSize.getItemCount(); i++) {
  181. if (txt != null && txt.equalsIgnoreCase(cbMovingAverageSize.getItemAtIndex(i).getLabel())) {
  182. ma = (String) cbMovingAverageSize.getItemAtIndex(i).getValue();
  183. break;
  184. }
  185. }
  186. } else {
  187. ma = (String) cbMovingAverageSize.getSelectedItem().getValue();
  188. }
  189. int movingAverageSize = Integer.parseInt(ma);
  190. if (movingAverageSize % 2 == 0 || movingAverageSize <= 0 || movingAverageSize >= 16) {
  191. getMapComposer().showMessage("Moving average size " + movingAverageSize + " is not valid. Must be odd and between 1 and 15.", this);
  192. return false;
  193. }
  194. if (!chkOccurrenceDensity.isChecked()
  195. && !chkSitesBySpecies.isChecked()
  196. && !chkSpeciesDensity.isChecked()) {
  197. getMapComposer().showMessage("Must select at least one output; Sites by species, Occurrence density or Species richness.", this);
  198. return false;
  199. }
  200. Double gridResolution = dResolution.getValue();
  201. //SelectedArea sa = getSelectedArea();
  202. SimpleRegion sr = SimpleShapeFile.parseWKT(sa.getWkt());
  203. //Query query = QueryUtil.queryFromSelectedArea(getSelectedSpecies(), sa, false, getGeospatialKosher());
  204. int occurrenceCount = query.getOccurrenceCount();
  205. int boundingboxcellcount = (int) ((sr.getBoundingBox()[1][0] - sr.getBoundingBox()[0][0])
  206. * (sr.getBoundingBox()[1][1] - sr.getBoundingBox()[0][1])
  207. / (gridResolution * gridResolution));
  208. System.out.println("SitesBySpecies for " + occurrenceCount + " occurrences in up to " + boundingboxcellcount + " grid cells.");
  209. if (boundingboxcellcount > settingsSupplementary.getValueAsInt("sitesbyspecies_maxbbcells")) {
  210. //getMapComposer().showMessage("Too many potential output grid cells. Reduce by at least " + String.format("%.2f",100* (1-boundingboxcellcount / (double)settingsSupplementary.getValueAsInt("sitesbyspecies_maxbbcells"))) + "% by decreasing area or increasing resolution.", this);
  211. getMapComposer().showMessage("Too many output grid cells: Decrease area or increase grid size.", this);
  212. return false;
  213. }
  214. if (occurrenceCount > settingsSupplementary.getValueAsInt("sitesbyspecies_maxoccurrences")) {
  215. getMapComposer().showMessage("Too many occurrences for the selected species in this area. " + occurrenceCount + " occurrences found, must be less than " + settingsSupplementary.getValueAsInt("sitesbyspecies_maxoccurrences"), this);
  216. return false;
  217. }
  218. StringBuffer sbProcessUrl = new StringBuffer();
  219. sbProcessUrl.append(CommonData.satServer + "/ws/sitesbyspecies?");
  220. sbProcessUrl.append("speciesq=").append(URLEncoder.encode(QueryUtil.queryFromSelectedArea(query, sa, false, getGeospatialKosher()).getQ(), "UTF-8"));
  221. sbProcessUrl.append("&gridsize=" + URLEncoder.encode(String.valueOf(gridResolution), "UTF-8"));
  222. sbProcessUrl.append("&bs=" + URLEncoder.encode(((BiocacheQuery) query).getBS(), "UTF-8"));
  223. if (chkOccurrenceDensity.isChecked()) {
  224. sbProcessUrl.append("&occurrencedensity=1");
  225. }
  226. if (chkSpeciesDensity.isChecked()) {
  227. sbProcessUrl.append("&speciesdensity=1");
  228. }
  229. if (chkSitesBySpecies.isChecked()) {
  230. sbProcessUrl.append("&sitesbyspecies=1");
  231. }
  232. sbProcessUrl.append("&movingaveragesize=" + ma);
  233. String areaSqKm = "0";
  234. if (sa.getMapLayer() != null && sa.getMapLayer().getData("area") != null) {
  235. areaSqKm = (String) sa.getMapLayer().getData("area");
  236. } else {
  237. areaSqKm = String.format("%,.2f", Util.calculateArea(sa.getWkt()) / 1000000.0);
  238. }
  239. sbProcessUrl.append("&areasqkm=" + areaSqKm);
  240. HttpClient client = new HttpClient();
  241. PostMethod get = new PostMethod(sbProcessUrl.toString());
  242. String area = null;
  243. if (sa.getMapLayer() != null && sa.getMapLayer().getData("envelope") != null) {
  244. area = "ENVELOPE(" + (String) sa.getMapLayer().getData("envelope") + ")";
  245. } else {
  246. area = sa.getWkt();
  247. }
  248. if (getSelectedArea() != null) {
  249. get.addParameter("area", area);
  250. }
  251. get.addParameter("qname", query.getName());
  252. get.addRequestHeader("Accept", "text/plain");
  253. int result = client.executeMethod(get);
  254. pid = get.getResponseBodyAsString();
  255. openProgressBar();
  256. StringBuffer sbParams = new StringBuffer();
  257. this.setVisible(false);
  258. try {
  259. String extras = "";
  260. extras += "gridsize=" + String.valueOf(gridResolution);
  261. extras += "|occurrencedensity=1";
  262. extras += "|speciesdensity=1";
  263. extras += "|sitesbyspecies=1";
  264. extras += "|movingaveragesize=" + ma;
  265. if (query instanceof BiocacheQuery) {
  266. BiocacheQuery bq = (BiocacheQuery) query;
  267. extras = bq.getWS() + "|" + bq.getBS() + "|" + bq.getFullQ(false) + "|" + extras;
  268. remoteLogger.logMapAnalysis("species to grid", "Tool - Species to Grid", area, bq.getLsids(), "", pid, extras, "STARTED");
  269. } else if (query instanceof UploadQuery) {
  270. remoteLogger.logMapAnalysis("species to grid", "Tool - Species to Grid", area, ((UploadQuery) query).getQ(), "", pid, extras, "STARTED");
  271. } else {
  272. remoteLogger.logMapAnalysis("species to grid", "Tool - Species to Grid", area, "", "", pid, extras, "STARTED");
  273. }
  274. } catch (Exception e) {
  275. e.printStackTrace();
  276. }
  277. return true;
  278. } catch (Exception e) {
  279. System.out.println("SitesBySpecies error: ");
  280. e.printStackTrace(System.out);
  281. getMapComposer().showMessage("Unknown error.", this);
  282. }
  283. return false;
  284. }
  285. @Override
  286. public void loadMap(Event event) {
  287. try {
  288. if (chkOccurrenceDensity.isChecked()) {
  289. String mapurl = CommonData.geoServer + "/wms?service=WMS&version=1.1.0&request=GetMap&layers=ALA:odensity_" + pid + "&styles=odensity_" + pid + "&FORMAT=image%2Fpng";
  290. String legendurl = CommonData.geoServer
  291. + "/wms?REQUEST=GetLegendGraphic&VERSION=1.0.0&FORMAT=image/png&WIDTH=10&HEIGHT=1"
  292. + "&LAYER=ALA:odensity_" + pid
  293. + "&STYLE=odensity_" + pid;
  294. System.out.println(legendurl);
  295. // String layername = tToolName.getValue();
  296. String layername = getMapComposer().getNextAreaLayerName("Occurrence Density");
  297. getMapComposer().addWMSLayer(pid + "_odensity", layername, mapurl, (float) 0.5, null, legendurl, LayerUtilities.ODENSITY, null, null);
  298. MapLayer ml = getMapComposer().getMapLayer(pid + "_odensity");
  299. ml.setData("pid", pid + "_odensity");
  300. String infoUrl = CommonData.satServer + "/output/sitesbyspecies/" + pid + "/odensity_metadata.html";
  301. MapLayerMetadata md = ml.getMapLayerMetadata();
  302. if (md == null) {
  303. md = new MapLayerMetadata();
  304. ml.setMapLayerMetadata(md);
  305. }
  306. md.setMoreInfo(infoUrl + "\nOccurrence Density\npid:" + pid);
  307. md.setId(Long.valueOf(pid));
  308. //perform intersection on user uploaded layers so you can facet on this layer
  309. getMapComposer().addAnalysisLayerToUploadedCoordinates(pid + "_odensity", layername);
  310. }
  311. if (chkSpeciesDensity.isChecked()) {
  312. String mapurl = CommonData.geoServer + "/wms?service=WMS&version=1.1.0&request=GetMap&layers=ALA:srichness_" + pid + "&styles=srichness_" + pid + "&FORMAT=image%2Fpng";
  313. String legendurl = CommonData.geoServer
  314. + "/wms?REQUEST=GetLegendGraphic&VERSION=1.0.0&FORMAT=image/png&WIDTH=10&HEIGHT=1"
  315. + "&LAYER=ALA:srichness_" + pid
  316. + "&STYLE=srichness_" + pid;
  317. System.out.println(legendurl);
  318. // String layername = tToolName.getValue();
  319. String layername = getMapComposer().getNextAreaLayerName("Species Richness");
  320. getMapComposer().addWMSLayer(pid + "_srichness", layername, mapurl, (float) 0.5, null, legendurl, LayerUtilities.SRICHNESS, null, null);
  321. MapLayer ml = getMapComposer().getMapLayer(pid + "_srichness");
  322. ml.setData("pid", pid + "_srichness");
  323. String infoUrl = CommonData.satServer + "/output/sitesbyspecies/" + pid + "/srichness_metadata.html";
  324. MapLayerMetadata md = ml.getMapLayerMetadata();
  325. if (md == null) {
  326. md = new MapLayerMetadata();
  327. ml.setMapLayerMetadata(md);
  328. }
  329. md.setMoreInfo(infoUrl + "\nSpecies Richness\npid:" + pid);
  330. md.setId(Long.valueOf(pid));
  331. //perform intersection on user uploaded layers so you can facet on this layer
  332. getMapComposer().addAnalysisLayerToUploadedCoordinates(pid + "_srichness", layername);
  333. }
  334. // set off the download as well
  335. String fileUrl = CommonData.satServer + "/ws/download/" + pid;
  336. Filedownload.save(new URL(fileUrl).openStream(), "application/zip", "sites_by_species.zip");
  337. } catch (Exception ex) {
  338. System.out.println("Error generating download for prediction model:");
  339. ex.printStackTrace(System.out);
  340. }
  341. this.detach();
  342. }
  343. void openProgressBar() {
  344. ProgressWCController window = (ProgressWCController) Executions.createComponents("WEB-INF/zul/AnalysisProgress.zul", getMapComposer(), null);
  345. window.parent = this;
  346. window.start(pid, "Points to Grid");
  347. try {
  348. window.doModal();
  349. } catch (Exception e) {
  350. e.printStackTrace();
  351. }
  352. }
  353. String getJob(String type) {
  354. try {
  355. StringBuffer sbProcessUrl = new StringBuffer();
  356. sbProcessUrl.append(CommonData.satServer + "/ws/jobs/").append(type).append("?pid=").append(pid);
  357. System.out.println(sbProcessUrl.toString());
  358. HttpClient client = new HttpClient();
  359. GetMethod get = new GetMethod(sbProcessUrl.toString());
  360. get.addRequestHeader("Accept", "text/plain");
  361. int result = client.executeMethod(get);
  362. String slist = get.getResponseBodyAsString();
  363. System.out.println(slist);
  364. return slist;
  365. } catch (Exception e) {
  366. e.printStackTrace();
  367. }
  368. return "";
  369. }
  370. /**
  371. * get CSV of speciesName, longitude, latitude in [0] and
  372. *
  373. * @param selectedSpecies
  374. * @param area
  375. * @return
  376. */
  377. private String[] getSpeciesData(Query query) throws NoSpeciesFoundException {
  378. if (query instanceof UploadQuery) {
  379. //no sensitive records in upload
  380. ArrayList<QueryField> fields = new ArrayList<QueryField>();
  381. String lsidFieldName = query.getSpeciesIdFieldName();
  382. QueryField qf = null;
  383. if (lsidFieldName != null) {
  384. qf = new QueryField(query.getSpeciesIdFieldName());
  385. qf.setStored(true);
  386. fields.add(qf);
  387. }
  388. double[] points = query.getPoints(fields);
  389. StringBuilder sb = null;
  390. if (points != null) {
  391. sb = new StringBuilder();
  392. for (int i = 0; i < points.length; i += 2) {
  393. if (sb.length() == 0) {
  394. //header
  395. sb.append("species,longitude,latitude");
  396. }
  397. sb.append("\nspecies,").append(points[i]).append(",").append(points[i + 1]);
  398. }
  399. }
  400. String[] out = {((sb == null) ? null : sb.toString()), null};
  401. return out;
  402. } else {
  403. //identify sensitive species records
  404. List<String[]> sensitiveSpecies = null;
  405. try {
  406. String sensitiveSpeciesRaw = new BiocacheQuery(null, null, "sensitive:[* TO *]", null, false, getGeospatialKosher()).speciesList();
  407. CSVReader csv = new CSVReader(new StringReader(sensitiveSpeciesRaw));
  408. sensitiveSpecies = csv.readAll();
  409. csv.close();
  410. } catch (Exception e) {
  411. e.printStackTrace();
  412. }
  413. HashSet<String> sensitiveSpeciesFound = new HashSet<String>();
  414. HashSet<String> sensitiveLsids = new HashSet<String>();
  415. //add to 'identified' sensitive list
  416. try {
  417. CSVReader csv = new CSVReader(new StringReader(query.speciesList()));
  418. List<String[]> fullSpeciesList = csv.readAll();
  419. csv.close();
  420. for (int i = 0; i < fullSpeciesList.size(); i++) {
  421. String[] sa = fullSpeciesList.get(i);
  422. for (String[] ss : sensitiveSpecies) {
  423. if (sa != null && sa.length > 4
  424. && ss != null && ss.length > 4
  425. && sa[4].equals(ss[4])) {
  426. sensitiveSpeciesFound.add(ss[4] + "," + ss[1] + "," + ss[3]);
  427. sensitiveLsids.add(ss[4]);
  428. break;
  429. }
  430. }
  431. }
  432. } catch (Exception e) {
  433. e.printStackTrace();
  434. }
  435. //remove sensitive records that will not be LSID matched
  436. Query maxentQuery = query.newFacet(new Facet("sensitive", "[* TO *]", false), false);
  437. ArrayList<QueryField> fields = new ArrayList<QueryField>();
  438. String lsidFieldName = maxentQuery.getSpeciesIdFieldName();
  439. QueryField qf = null;
  440. if (lsidFieldName != null) {
  441. qf = new QueryField(maxentQuery.getSpeciesIdFieldName());
  442. qf.setStored(true);
  443. fields.add(qf);
  444. }
  445. double[] points = maxentQuery.getPoints(fields);
  446. StringBuilder sb = null;
  447. if (points != null) {
  448. sb = new StringBuilder();
  449. for (int i = 0; i < points.length; i += 2) {
  450. boolean isSensitive = false;
  451. if (qf != null) {
  452. String lsid = qf.getAsString(i / 2);
  453. isSensitive = sensitiveLsids.contains(lsid);
  454. }
  455. if (!isSensitive) {
  456. if (sb.length() == 0) {
  457. //header
  458. sb.append("species,longitude,latitude");
  459. }
  460. sb.append("\nspecies,").append(points[i]).append(",").append(points[i + 1]);
  461. }
  462. }
  463. }
  464. //collate sensitive species found, no header
  465. StringBuilder sen = new StringBuilder();
  466. for (String s : sensitiveSpeciesFound) {
  467. sen.append(s).append("\n");
  468. }
  469. String[] out = {((sb == null) ? null : sb.toString()), (sen.length() == 0) ? null : sen.toString()};
  470. return out;
  471. }
  472. }
  473. @Override
  474. void fixFocus() {
  475. switch (currentStep) {
  476. case 1:
  477. rgArea.setFocus(true);
  478. break;
  479. case 2:
  480. if (rSpeciesSearch.isChecked()) {
  481. searchSpeciesACComp.getAutoComplete().setFocus(true);
  482. } else {
  483. rgSpecies.setFocus(true);
  484. }
  485. break;
  486. case 3:
  487. dResolution.setFocus(true);
  488. break;
  489. }
  490. }
  491. }