Skip to content

Commit

Permalink
feat: latitude longitude and elevation calculated for 3rd generation …
Browse files Browse the repository at this point in the history
…parent trees (#1514)

Co-authored-by: mgaseta <[email protected]>
  • Loading branch information
RMCampos and mgaseta authored Aug 16, 2024
1 parent ec8a740 commit 9a045dc
Show file tree
Hide file tree
Showing 10 changed files with 612 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public PtCalculationResDto calculatePtVals(PtValsCalReqDto ptVals) {
}

// --col:W
if (varTotalConeCount.compareTo(BigDecimal.ZERO) > 0) {
if (varTotalPollenCount.compareTo(BigDecimal.ZERO) > 0) {
varParentPropOrchPoll = ptPollenCount.divide(varTotalPollenCount, DIVISION_SCALE, halfUp);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package ca.bc.gov.oracleapi.dto;

import ca.bc.gov.oracleapi.entity.ParentTreeEntity;
import java.util.Optional;
import lombok.NoArgsConstructor;
import lombok.Setter;

/** This class represents a GeoNode with all elevation, lat and long mean values. */
@Setter
@NoArgsConstructor
public class ParentTreeGeoNodeDto {

private Integer elevation;
private Integer latitudeDegrees;
private Integer latitudeMinutes;
private Integer latitudeSeconds;
private Integer longitudeDegrees;
private Integer longitudeMinutes;
private Integer longitudeSeconds;

ParentTreeGeoNodeDto(ParentTreeEntity entity) {
this.elevation = entity.getElevation();
this.latitudeDegrees = entity.getLatitudeDegrees();
this.latitudeMinutes = entity.getLatitudeMinutes();
this.latitudeSeconds = entity.getLatitudeSeconds();
this.longitudeDegrees = entity.getLongitudeDegrees();
this.longitudeMinutes = entity.getLongitudeMinutes();
this.longitudeSeconds = entity.getLongitudeSeconds();
}

public Integer getElevation() {
return this.elevation;
}

public int getElevationIntVal() {
return Optional.ofNullable(elevation).orElse(0);
}

public int getLatitudeDegreesIntVal() {
return Optional.ofNullable(latitudeDegrees).orElse(0);
}

public int getLatitudeMinutesIntVal() {
return Optional.ofNullable(latitudeMinutes).orElse(0);
}

public int getLatitudeSecondsIntVal() {
return Optional.ofNullable(latitudeSeconds).orElse(0);
}

public int getLongitudeDegreesIntVal() {
return Optional.ofNullable(longitudeDegrees).orElse(0);
}

public int getLongitudeMinutesIntVal() {
return Optional.ofNullable(longitudeMinutes).orElse(0);
}

public int getLongitudeSecondsIntVal() {
return Optional.ofNullable(longitudeSeconds).orElse(0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
package ca.bc.gov.oracleapi.dto;

import ca.bc.gov.oracleapi.config.SparLog;
import ca.bc.gov.oracleapi.entity.ParentTreeEntity;
import java.util.Optional;
import lombok.Getter;
import lombok.Setter;

/** This class represents a parent tree node. */
@Getter
@Setter
public class ParentTreeNodeDto {

private final ParentTreeEntity value;
private ParentTreeNodeDto femaleParent;
private ParentTreeNodeDto maleParent;
private ParentTreeGeoNodeDto geoNode;

/**
* Creates a Parent Tree Node.
*
* @param value The parent tree entity instance.
*/
public ParentTreeNodeDto(ParentTreeEntity value) {
this.value = value;
this.geoNode = new ParentTreeGeoNodeDto(value);
}

/**
* Add a parent tree node female or male.
*
* @param parentTreeId the reference parent id tree to look for.
* @param entity the parent tree entity instance.
*/
public void add(Long parentTreeId, ParentTreeEntity entity) {
if (parentTreeId.equals(value.getFemaleParentTreeId())) {
femaleParent = new ParentTreeNodeDto(entity);
} else if (parentTreeId.equals(value.getMaleParentTreeId())) {
maleParent = new ParentTreeNodeDto(entity);
} else {
if (femaleParent != null) {
femaleParent.add(parentTreeId, entity);
}
if (maleParent != null) {
maleParent.add(parentTreeId, entity);
}
}
}

/**
* Get a Parent tree's parent elevation (and all lat and long mean values), recursively, looking
* at parent's parent and finding the 'mean' value when required. The calculation piece of code
* was brought exactly as is in SPR_GET_PT_GEOG.prc file on SPAR Legacy.
*
* @param current Current node in the tree
* @param femaleNode Female parent node in the tree
* @param maleNode Male parent node in the tree
* @return A female node if female has data, or a new node with mean values from female and male.
*/
private ParentTreeGeoNodeDto getParentsMeanElevation(
ParentTreeNodeDto current, ParentTreeNodeDto femaleNode, ParentTreeNodeDto maleNode) {
if (current.geoNode.getElevation() != null) {
return current.geoNode;
}
ParentTreeGeoNodeDto femaleElevation = new ParentTreeGeoNodeDto();
if (current.femaleParent != null) {
femaleElevation =
Optional.ofNullable(
getParentsMeanElevation(
current.femaleParent,
current.femaleParent.femaleParent,
current.femaleParent.maleParent))
.orElse(new ParentTreeGeoNodeDto());
}
ParentTreeGeoNodeDto maleElevation = new ParentTreeGeoNodeDto();
if (current.maleParent != null) {
maleElevation =
Optional.ofNullable(
getParentsMeanElevation(
current.maleParent,
current.maleParent.femaleParent,
current.maleParent.maleParent))
.orElse(new ParentTreeGeoNodeDto());
}
if (maleElevation.getElevationIntVal() == 0 && femaleElevation.getElevationIntVal() > 0) {
return femaleElevation;
} else if (maleElevation.getElevationIntVal() > 0 && femaleElevation.getElevationIntVal() > 0) {
int noOfParents = 2;
ParentTreeGeoNodeDto meanNode = new ParentTreeGeoNodeDto();

// Elevation
int meanElevation =
(maleElevation.getElevationIntVal() + femaleElevation.getElevationIntVal()) / noOfParents;
meanNode.setElevation(meanElevation);

// All other calculations (Lat and Long)
int calc =
(femaleElevation.getLatitudeDegreesIntVal() * 3600)
+ (femaleElevation.getLatitudeMinutesIntVal() * 60)
+ femaleElevation.getLatitudeSecondsIntVal();
calc =
calc
+ (maleElevation.getLatitudeDegreesIntVal() * 3600)
+ (maleElevation.getLatitudeMinutesIntVal() * 60)
+ maleElevation.getLatitudeSecondsIntVal();
// --derive mean
calc = calc / noOfParents;
int latitudeDegrees = calc / 3600;
meanNode.setLatitudeDegrees(latitudeDegrees);

int buff = calc % 3600;
int latitudeMinutes = buff / 60;
meanNode.setLatitudeMinutes(latitudeMinutes);

buff = calc % 60;
int latitudeSeconds = buff;
meanNode.setLatitudeSeconds(latitudeSeconds);

calc =
(femaleElevation.getLongitudeDegreesIntVal() * 3600)
+ (femaleElevation.getLongitudeMinutesIntVal() * 60)
+ femaleElevation.getLongitudeSecondsIntVal();
calc =
calc
+ (maleElevation.getLongitudeDegreesIntVal() * 3600)
+ (maleElevation.getLongitudeMinutesIntVal() * 60)
+ maleElevation.getLongitudeSecondsIntVal();
// --derive mean
calc = calc / noOfParents;
int longitudeDegrees = calc / 3600;
meanNode.setLongitudeDegrees(longitudeDegrees);

buff = calc % 3600;
int longitudeMinutes = buff / 60;
meanNode.setLongitudeMinutes(longitudeMinutes);

buff = calc % 60;
int longitudeSeconds = buff;
meanNode.setLongitudeSeconds(longitudeSeconds);

return meanNode;
}
return null;
}

/**
* Get the parent tree mean elevation looking into parent trees family.
*
* @return an integer representing the mean elevation.
*/
public ParentTreeGeoNodeDto getParentTreeElevation() {
ParentTreeGeoNodeDto elevation =
getParentsMeanElevation(this, this.femaleParent, this.maleParent);
return elevation;
}

/**
* Prints the current node.
*
* @param level Current level in the tree
*/
public String printLevel(int level) {
String message = String.format("Level %d - %s", level, toString());
SparLog.info(message);
if (femaleParent != null) {
return femaleParent.printLevel(level + 1);
}
if (maleParent != null) {
return maleParent.printLevel(level + 1);
}
return message;
}

/** Gets the string version of the node. */
@Override
public String toString() {
StringBuilder sb = new StringBuilder("ParentTreeId=");
sb.append(value.getId());
sb.append(" (elev: ").append(value.getElevation()).append(") ");
sb.append("[");
boolean added = false;
if (value.getFemaleParentTreeId() != null) {
sb.append("femaleParentId=").append(value.getFemaleParentTreeId());
added = true;
}
if (value.getMaleParentTreeId() != null) {
if (added) {
sb.append(", ");
}
sb.append("male=").append(value.getMaleParentTreeId());
}
sb.append("]");
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,9 @@ public class ParentTreeEntity {

@Column(name = "ELEVATION")
private Integer elevation;

@Override
public String toString() {
return getId().toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
/** This class holds methods for retrieving {@link ParentTreeEntity} data from the database. */
public interface ParentTreeRepository extends JpaRepository<ParentTreeEntity, Long> {

@Query("from ParentTreeEntity where id in ?1")
List<ParentTreeEntity> findAllIn(List<Long> ids);
List<ParentTreeEntity> findAllByIdIn(List<Long> ids);

@Query(
value =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ private List<ParentTreeGeneticInfoDto> findAllParentTree(
long endingFour = Instant.now().toEpochMilli();
SparLog.debug("Time elapsed mapping all parent tree orchard ids: {}", endingFour - endingThree);

List<ParentTreeEntity> parentTreeList = parentTreeRepository.findAllIn(parentTreeIdList);
List<ParentTreeEntity> parentTreeList = parentTreeRepository.findAllByIdIn(parentTreeIdList);

long endingFive = Instant.now().toEpochMilli();
SparLog.debug("Time elapsed finding all parent tree (select in): {}", endingFive - endingFour);
Expand Down
Loading

0 comments on commit 9a045dc

Please sign in to comment.