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