V1_0.java [src/java/m/rhem/rhem02_getclimatestations] Revision: b4532614e56521e407dbd03a73779498a8516f23  Date: Wed Dec 29 18:55:25 MST 2021
/*
 * $Id$
 *
 * This file is part of the Cloud Services Integration Platform (CSIP),
 * a Model-as-a-Service framework, API, and application suite.
 *
 * 2012-2017, OMSLab, Colorado State University.
 *
 * OMSLab licenses this file to you under the MIT license.
 * See the LICENSE file in the project root for more information.
 */
package m.rhem.rhem02_getclimatestations;

import csip.ModelDataService;
import csip.api.server.ServiceException;
import csip.annotations.Polling;
import csip.annotations.Resource;
import csip.utils.JSONUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import javax.ws.rs.Path;
import csip.annotations.Description;
import csip.annotations.Name;
import java.util.List;
import org.codehaus.jettison.json.JSONArray;
import rhem.utils.RHEMUtils;
import m.rhem.DBResources;
import static rhem.utils.RHEMUtils.MONTH_NAMES_LIST;

/**
 * RHEM-02:Get Climate Stations
 *
 * @version 1.0
 * @author Rumpal Sidhu
 */
@Name("RHEM-02: Get Climate Stations")
@Description("Returns a list of climate stations associated with the state "
    + "selected by the user. Information associated with each climate "
    + "station will be station name, latitude, longitude, number of "
    + "years of observed data, elevation (feet) and 300 year average "
    + "and monthly precipitation amounts (millimeters).")
@Path("m/rhem/getclimatestations/1.0")
@Polling(first = 10000, next = 2000)
@Resource(from = DBResources.class)
public class V1_0 extends ModelDataService {

  private String stateId;
  private ClimateStationStates climateStationStates;


  @Override
  public void preProcess() throws ServiceException {
    stateId = parameter().getString("stateid");
  }


  @Override
  public void doProcess() throws Exception {
    try (Connection connection = resources().getJDBC(DBResources.CRDB);
        Statement statement = connection.createStatement()) {

      try (ResultSet resultSet = statement.executeQuery(DBResources.RHEM02Query01(stateId))) {
        while (resultSet.next()) {
          climateStationStates = new ClimateStationStates(stateId,
              resultSet.getString("state_name"),
              resultSet.getDouble("latitude"),
              resultSet.getDouble("longitude"),
              resultSet.getInt("zoom"));
        }
      }

      try (ResultSet resultSet = statement.executeQuery(DBResources.RHEM02Query02(stateId))) {
        List<ClimateStation> climateStationsList = new ArrayList<>();
        while (resultSet.next()) {
          double[] monthlyPrecip = new double[12];
          for (int i = 0; i < 12; i++) {
            monthlyPrecip[i] = resultSet.getDouble(MONTH_NAMES_LIST[i].toLowerCase().substring(0, 3) + "_precip_mm");
          }

          climateStationsList.add(new ClimateStation(
              resultSet.getString("station_id"),
              resultSet.getString("station"),
              resultSet.getDouble("latitude"),
              resultSet.getDouble("longitude"),
              resultSet.getInt("years"),
              resultSet.getInt("elevation"),
              resultSet.getDouble("avg_yearly_precip_mm"),
              monthlyPrecip));
        }
        climateStationStates.addClimateStationsList(climateStationsList);
      }
    }
  }


  @Override
  public void postProcess() throws Exception {
    results().put("stateid", climateStationStates.getStateId(), "State abbreviation of climate station location");
    results().put("state_name", climateStationStates.getStateName(), "State name");
    results().put("latitude", climateStationStates.getStateLatitude(), "Central latitude of the state");
    results().put("longitude", climateStationStates.getStateLongitude(), "Central longitude of the state");
    results().put("zoom", climateStationStates.getZoom(), "Zoom level utilized to display state map on UI");

    JSONArray climateStationArray = new JSONArray();
    for (ClimateStation cs : climateStationStates.getClimateStationsList()) {
      JSONArray innerArray = new JSONArray()
          .put(JSONUtils.dataDesc("station_id", cs.getStationId(), "Climate station identification number"))
          .put(JSONUtils.dataDesc("station_name", cs.getStationName(), "Climate station name"))
          .put(JSONUtils.dataDesc("lat", cs.getStationLatitude(), "Climate station latitude"))
          .put(JSONUtils.dataDesc("long", cs.getStationLongitude(), "Climate station longitude"))
          .put(JSONUtils.dataDesc("year_recorded", cs.getYearRecorded(), "Number of years of recorded observations for climate station"))
          .put(JSONUtils.dataDesc("elevation_ft", cs.getElevation(), "Climate station elevation"))
          .put(JSONUtils.dataDesc("avg_yearly_precip_mm", RHEMUtils.roundValues(cs.getAvgYearlyPrecip(), 2), "300 year average annual precipitation (mm)"));
      for (int i = 0; i < 12; i++) {
        innerArray.put(JSONUtils.dataDesc(MONTH_NAMES_LIST[i].substring(0, 3).toLowerCase() + "_precip_mm",
            RHEMUtils.roundValues(cs.getMonthlyPrecip()[i], 2), MONTH_NAMES_LIST[i] + " estimated monthly average precipitation (mm)"));
      }
      climateStationArray.put(JSONUtils.dataDesc("climate_stations", innerArray, "Climate station attributes"));
    }
    results().put("climate_station_list", climateStationArray, "Climate Station List");
  }

  static class ClimateStationStates {

    String stateId;
    String stateName;
    double latitude;
    double longitude;
    int zoom;
    List<ClimateStation> climateStationsList;


    public ClimateStationStates(String stateId, String stateName, double latitude,
        double longitude, int zoom) {
      this.stateId = stateId;
      this.stateName = stateName;
      this.latitude = latitude;
      this.longitude = longitude;
      this.zoom = zoom;
    }


    public String getStateId() {
      return stateId;
    }


    public String getStateName() {
      return stateName;
    }


    public double getStateLatitude() {
      return latitude;
    }


    public double getStateLongitude() {
      return longitude;
    }


    public int getZoom() {
      return zoom;
    }


    public List<ClimateStation> getClimateStationsList() {
      return climateStationsList;
    }


    public void addClimateStationsList(List<ClimateStation> list) {
      this.climateStationsList = list;
    }

  }

  static class ClimateStation {

    String stationId;
    String stationName;
    double latitude;
    double longitude;
    int yearRecorded;
    int elevation_ft;
    double avgYearlyPrecip_mm;
    double[] monthlyPrecip_mm;


    public ClimateStation(String stationId, String stationName, double latitude,
        double longitude, int yearRecorded, int elevation,
        double avg_yearly_precip_mm, double[] monthlyPrecip_mm) {

      this.stationId = stationId;
      this.stationName = stationName;
      this.latitude = latitude;
      this.longitude = longitude;
      this.yearRecorded = yearRecorded;
      this.elevation_ft = elevation;
      this.avgYearlyPrecip_mm = avg_yearly_precip_mm;
      this.monthlyPrecip_mm = monthlyPrecip_mm;
    }


    public String getStationId() {
      return stationId;
    }


    public String getStationName() {
      return stationName;
    }


    public double getStationLatitude() {
      return latitude;
    }


    public double getStationLongitude() {
      return longitude;
    }


    public int getYearRecorded() {
      return yearRecorded;
    }


    public int getElevation() {
      return elevation_ft;
    }


    public double getAvgYearlyPrecip() {
      return avgYearlyPrecip_mm;
    }


    public double[] getMonthlyPrecip() {
      return monthlyPrecip_mm;
    }

  }
}