Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class AnalysisController {
| └ diseaseId | 원인 질병 ID | Long | |
| └ diseaseName | 원인 질병 이름 | String | |
| └ weatherScore | 질환별 날씨 점수 (0=최악, 100=최고) | int | 위험 요인이 없어도 점수는 제공 |
| └ scoreFactors | 점수를 크게 깎은 주요 날씨 지수 이름 배열 (예: 초미세먼지) | List<String> | 영향 큰 순, 최대 2개. 양호하면 빈 배열 |
| └ factorGuides | 날씨 원인 및 맞춤 행동 강령 배열 | List<Object> | 위험 요인이 없으면 빈 배열 |
| &nbsp;&nbsp;&nbsp;└ factorName | 초과한 날씨 요인 (예: 미세먼지) | String | |
| &nbsp;&nbsp;&nbsp;└ guide | 행동 추천 가이드 | String | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public static class RiskDetail {
private Long diseaseId;
private String diseaseName;
private int weatherScore; // 질환별 날씨 점수 (0=최악, 100=최고)
private List<String> scoreFactors; // 점수를 크게 깎은 주요 날씨 지수 (최대 2개, 영향 큰 순)
private List<FactorGuide> factorGuides;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.haapyProcess.domain.analysis.rule;

import com.haapyProcess.domain.analysis.dto.RiskAnalysisResult.FactorGuide;
import com.haapyProcess.domain.analysis.score.WeatherScore;
import com.haapyProcess.domain.member.entity.PrecipPreference;
import com.haapyProcess.domain.weather.dto.WeatherResponseDto;

Expand All @@ -19,10 +20,10 @@ public interface DiseaseRiskRule {
List<FactorGuide> evaluateFactorGuides(WeatherResponseDto weather);

/**
* 질환별 가중치를 적용한 날씨 점수(0~100) 반환합니다.
* 질환별 가중치를 적용한 날씨 점수(0~100)와 점수 하락의 주요 원인 지수를 반환합니다.
* 0점 = 최악의 날씨, 100점 = 최고의 날씨.
* precipPreference는 질병 없는 사용자의 강수 불편도 산정에만 사용됩니다.
*/
int evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference);
WeatherScore evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.haapyProcess.domain.analysis.criteria.WeatherRiskCriteria;
import com.haapyProcess.domain.analysis.dto.RiskAnalysisResult.FactorGuide;
import com.haapyProcess.domain.analysis.rule.DiseaseRiskRule;
import com.haapyProcess.domain.analysis.score.ScoreBuilder;
import com.haapyProcess.domain.analysis.score.WeatherScore;
import com.haapyProcess.domain.analysis.score.WeatherScoreTables;
import com.haapyProcess.domain.member.entity.PrecipPreference;
import com.haapyProcess.domain.weather.dto.WeatherResponseDto;
Expand Down Expand Up @@ -42,13 +44,15 @@ public List<FactorGuide> evaluateFactorGuides(WeatherResponseDto weather) {
}

@Override
public int evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
public WeatherScore evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
// 6시간 기온 급감 (하강 폭만 사용)
int tempDrop = WeatherScoreTables.tempChange(weather.getTempDropIn6Hours());
// 강수형태 코드 1(비), 2(비/눈), 3(눈)만 적용
int precip = WeatherScoreTables.precipSensitive(weather.getParsedCurrentPty(), Set.of(1, 2, 3));

double raw = tempDrop * 0.60 + precip * 0.40;
return 100 - (int) Math.round(raw);
return ScoreBuilder.create()
.add("기온 급강하", tempDrop, 0.60)
.add("강수", precip, 0.40)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.haapyProcess.domain.analysis.criteria.WeatherRiskCriteria;
import com.haapyProcess.domain.analysis.dto.RiskAnalysisResult.FactorGuide;
import com.haapyProcess.domain.analysis.rule.DiseaseRiskRule;
import com.haapyProcess.domain.analysis.score.ScoreBuilder;
import com.haapyProcess.domain.analysis.score.WeatherScore;
import com.haapyProcess.domain.analysis.score.WeatherScoreTables;
import com.haapyProcess.domain.member.entity.PrecipPreference;
import com.haapyProcess.domain.weather.dto.WeatherResponseDto;
Expand Down Expand Up @@ -44,24 +46,32 @@ public List<FactorGuide> evaluateFactorGuides(WeatherResponseDto weather) {
}

@Override
public int evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
public WeatherScore evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
int pm25 = WeatherScoreTables.pm25(weather.getParsedPm25Value());
int pm10 = WeatherScoreTables.pm10(weather.getParsedPm10Value());
int temp = WeatherScoreTables.temp(weather.getParsedCurrentTemp());
double tempChangeVal = Math.max(weather.getTempDropIn6Hours(), weather.getTempRiseIn6Hours());
int tempChange = WeatherScoreTables.tempChange(tempChangeVal);

double raw;
int month = java.time.LocalDate.now().getMonthValue();
boolean pollenOffSeason = (month == 7 || month == 11 || month == 12 || month == 1 || month == 2);

if (pollenOffSeason) {
// 꽃가루 계수(0.35) 제외 후 나머지 변수를 재정규화 (÷0.65)
raw = (pm25 * 0.30 + pm10 * 0.20 + temp * 0.10 + tempChange * 0.05) / 0.65;
} else {
int pollen = WeatherScoreTables.pollen(weather.getParsedPollenRisk());
raw = pollen * 0.35 + pm25 * 0.30 + pm10 * 0.20 + temp * 0.10 + tempChange * 0.05;
return ScoreBuilder.create()
.add("초미세먼지", pm25, 0.30 / 0.65)
.add("미세먼지", pm10, 0.20 / 0.65)
.add("기온", temp, 0.10 / 0.65)
.add("기온 급변", tempChange, 0.05 / 0.65)
.build();
}
return 100 - (int) Math.round(raw);
int pollen = WeatherScoreTables.pollen(weather.getParsedPollenRisk());
return ScoreBuilder.create()
.add("꽃가루", pollen, 0.35)
.add("초미세먼지", pm25, 0.30)
.add("미세먼지", pm10, 0.20)
.add("기온", temp, 0.10)
.add("기온 급변", tempChange, 0.05)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.haapyProcess.domain.analysis.criteria.WeatherRiskCriteria;
import com.haapyProcess.domain.analysis.dto.RiskAnalysisResult.FactorGuide;
import com.haapyProcess.domain.analysis.rule.DiseaseRiskRule;
import com.haapyProcess.domain.analysis.score.ScoreBuilder;
import com.haapyProcess.domain.analysis.score.WeatherScore;
import com.haapyProcess.domain.analysis.score.WeatherScoreTables;
import com.haapyProcess.domain.member.entity.PrecipPreference;
import com.haapyProcess.domain.weather.dto.WeatherResponseDto;
Expand Down Expand Up @@ -49,12 +51,13 @@ public List<FactorGuide> evaluateFactorGuides(WeatherResponseDto weather) {
}

@Override
public int evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
double raw = WeatherScoreTables.pm25(weather.getParsedPm25Value()) * 0.30
+ WeatherScoreTables.pm10(weather.getParsedPm10Value()) * 0.25
+ WeatherScoreTables.temp(weather.getParsedCurrentTemp()) * 0.20
+ WeatherScoreTables.uv(weather.getParsedUvRisk()) * 0.15
+ WeatherScoreTables.precipSensitive(weather.getParsedCurrentPty(), Set.of(1, 2, 3)) * 0.10;
return 100 - (int) Math.round(raw);
public WeatherScore evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
return ScoreBuilder.create()
.add("초미세먼지", WeatherScoreTables.pm25(weather.getParsedPm25Value()), 0.30)
.add("미세먼지", WeatherScoreTables.pm10(weather.getParsedPm10Value()), 0.25)
.add("기온", WeatherScoreTables.temp(weather.getParsedCurrentTemp()), 0.20)
.add("자외선", WeatherScoreTables.uv(weather.getParsedUvRisk()), 0.15)
.add("강수", WeatherScoreTables.precipSensitive(weather.getParsedCurrentPty(), Set.of(1, 2, 3)), 0.10)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.haapyProcess.domain.analysis.criteria.WeatherRiskCriteria;
import com.haapyProcess.domain.analysis.dto.RiskAnalysisResult.FactorGuide;
import com.haapyProcess.domain.analysis.rule.DiseaseRiskRule;
import com.haapyProcess.domain.analysis.score.ScoreBuilder;
import com.haapyProcess.domain.analysis.score.WeatherScore;
import com.haapyProcess.domain.analysis.score.WeatherScoreTables;
import com.haapyProcess.domain.member.entity.PrecipPreference;
import com.haapyProcess.domain.weather.dto.WeatherResponseDto;
Expand Down Expand Up @@ -42,20 +44,19 @@ public List<FactorGuide> evaluateFactorGuides(WeatherResponseDto weather) {
}

@Override
public int evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
public WeatherScore evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
double humidity = weather.getParsedHumidity();

ScoreBuilder builder = ScoreBuilder.create()
.add("자외선", WeatherScoreTables.uv(weather.getParsedUvRisk()), 0.50);

// 습도 낮음(30% 미만)과 높음(80% 이상)은 반대 방향 조건이라 별도 처리한다.
double humidityScore;
if (humidity < 30) {
humidityScore = WeatherScoreTables.humidityDry(humidity) * 0.30;
builder.add("건조", WeatherScoreTables.humidityDry(humidity), 0.30);
} else if (humidity >= 80) {
humidityScore = WeatherScoreTables.humidityWet(humidity) * 0.20;
} else {
humidityScore = 0;
builder.add("높은 습도", WeatherScoreTables.humidityWet(humidity), 0.20);
}

double raw = WeatherScoreTables.uv(weather.getParsedUvRisk()) * 0.50 + humidityScore;
return 100 - (int) Math.round(raw);
return builder.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.haapyProcess.domain.analysis.criteria.WeatherRiskCriteria;
import com.haapyProcess.domain.analysis.dto.RiskAnalysisResult.FactorGuide;
import com.haapyProcess.domain.analysis.rule.DiseaseRiskRule;
import com.haapyProcess.domain.analysis.score.ScoreBuilder;
import com.haapyProcess.domain.analysis.score.WeatherScore;
import com.haapyProcess.domain.analysis.score.WeatherScoreTables;
import com.haapyProcess.domain.member.entity.PrecipPreference;
import com.haapyProcess.domain.weather.dto.WeatherResponseDto;
Expand Down Expand Up @@ -40,10 +42,11 @@ public List<FactorGuide> evaluateFactorGuides(WeatherResponseDto weather) {
}

@Override
public int evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
public WeatherScore evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
// 당뇨는 폭염(탈수)이 핵심이므로 고온 점수를 사용한다.
double raw = WeatherScoreTables.tempHeat(weather.getParsedCurrentTemp()) * 0.65
+ WeatherScoreTables.humidityWet(weather.getParsedHumidity()) * 0.35;
return 100 - (int) Math.round(raw);
return ScoreBuilder.create()
.add("기온", WeatherScoreTables.tempHeat(weather.getParsedCurrentTemp()), 0.65)
.add("높은 습도", WeatherScoreTables.humidityWet(weather.getParsedHumidity()), 0.35)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.haapyProcess.domain.analysis.criteria.WeatherRiskCriteria;
import com.haapyProcess.domain.analysis.dto.RiskAnalysisResult.FactorGuide;
import com.haapyProcess.domain.analysis.rule.DiseaseRiskRule;
import com.haapyProcess.domain.analysis.score.ScoreBuilder;
import com.haapyProcess.domain.analysis.score.WeatherScore;
import com.haapyProcess.domain.analysis.score.WeatherScoreTables;
import com.haapyProcess.domain.member.entity.PrecipPreference;
import com.haapyProcess.domain.weather.dto.WeatherResponseDto;
Expand Down Expand Up @@ -40,9 +42,10 @@ public List<FactorGuide> evaluateFactorGuides(WeatherResponseDto weather) {
}

@Override
public int evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
double raw = WeatherScoreTables.humidityDry(weather.getParsedHumidity()) * 0.75
+ WeatherScoreTables.uv(weather.getParsedUvRisk()) * 0.25;
return 100 - (int) Math.round(raw);
public WeatherScore evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
return ScoreBuilder.create()
.add("건조", WeatherScoreTables.humidityDry(weather.getParsedHumidity()), 0.75)
.add("자외선", WeatherScoreTables.uv(weather.getParsedUvRisk()), 0.25)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.haapyProcess.domain.analysis.criteria.WeatherRiskCriteria;
import com.haapyProcess.domain.analysis.dto.RiskAnalysisResult.FactorGuide;
import com.haapyProcess.domain.analysis.rule.DiseaseRiskRule;
import com.haapyProcess.domain.analysis.score.ScoreBuilder;
import com.haapyProcess.domain.analysis.score.WeatherScore;
import com.haapyProcess.domain.analysis.score.WeatherScoreTables;
import com.haapyProcess.domain.member.entity.PrecipPreference;
import com.haapyProcess.domain.weather.dto.WeatherResponseDto;
Expand Down Expand Up @@ -48,13 +50,14 @@ public List<FactorGuide> evaluateFactorGuides(WeatherResponseDto weather) {
}

@Override
public int evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
public WeatherScore evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
double changeVal = Math.max(weather.getTempDropIn6Hours(), weather.getTempRiseIn6Hours());
// 고령 강수형태는 빙판길 낙상 위험 중심으로 코드 2(비/눈), 3(눈)만 적용
double raw = WeatherScoreTables.temp(weather.getParsedCurrentTemp()) * 0.30
+ WeatherScoreTables.tempChange(changeVal) * 0.30
+ WeatherScoreTables.pm10(weather.getParsedPm10Value()) * 0.20
+ WeatherScoreTables.precipSensitive(weather.getParsedCurrentPty(), Set.of(2, 3)) * 0.20;
return 100 - (int) Math.round(raw);
return ScoreBuilder.create()
.add("기온", WeatherScoreTables.temp(weather.getParsedCurrentTemp()), 0.30)
.add("기온 급변", WeatherScoreTables.tempChange(changeVal), 0.30)
.add("미세먼지", WeatherScoreTables.pm10(weather.getParsedPm10Value()), 0.20)
.add("강수", WeatherScoreTables.precipSensitive(weather.getParsedCurrentPty(), Set.of(2, 3)), 0.20)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.haapyProcess.domain.analysis.criteria.WeatherRiskCriteria;
import com.haapyProcess.domain.analysis.dto.RiskAnalysisResult.FactorGuide;
import com.haapyProcess.domain.analysis.rule.DiseaseRiskRule;
import com.haapyProcess.domain.analysis.score.ScoreBuilder;
import com.haapyProcess.domain.analysis.score.WeatherScore;
import com.haapyProcess.domain.analysis.score.WeatherScoreTables;
import com.haapyProcess.domain.member.entity.PrecipPreference;
import com.haapyProcess.domain.weather.dto.WeatherResponseDto;
Expand Down Expand Up @@ -42,11 +44,12 @@ public List<FactorGuide> evaluateFactorGuides(WeatherResponseDto weather) {
}

@Override
public int evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
public WeatherScore evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
double changeVal = Math.max(weather.getTempDropIn6Hours(), weather.getTempRiseIn6Hours());
double raw = WeatherScoreTables.pm25(weather.getParsedPm25Value()) * 0.40
+ WeatherScoreTables.temp(weather.getParsedCurrentTemp()) * 0.35
+ WeatherScoreTables.tempChange(changeVal) * 0.25;
return 100 - (int) Math.round(raw);
return ScoreBuilder.create()
.add("초미세먼지", WeatherScoreTables.pm25(weather.getParsedPm25Value()), 0.40)
.add("기온", WeatherScoreTables.temp(weather.getParsedCurrentTemp()), 0.35)
.add("기온 급변", WeatherScoreTables.tempChange(changeVal), 0.25)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.haapyProcess.domain.analysis.criteria.WeatherRiskCriteria;
import com.haapyProcess.domain.analysis.dto.RiskAnalysisResult.FactorGuide;
import com.haapyProcess.domain.analysis.rule.DiseaseRiskRule;
import com.haapyProcess.domain.analysis.score.ScoreBuilder;
import com.haapyProcess.domain.analysis.score.WeatherScore;
import com.haapyProcess.domain.analysis.score.WeatherScoreTables;
import com.haapyProcess.domain.member.entity.PrecipPreference;
import com.haapyProcess.domain.weather.dto.WeatherResponseDto;
Expand Down Expand Up @@ -46,12 +48,14 @@ public List<FactorGuide> evaluateFactorGuides(WeatherResponseDto weather) {
}

@Override
public int evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
public WeatherScore evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
int temp = WeatherScoreTables.temp(weather.getParsedCurrentTemp());
double changeVal = Math.max(weather.getTempDropIn6Hours(), weather.getTempRiseIn6Hours());
int tempChange = WeatherScoreTables.tempChange(changeVal);

double raw = temp * 0.55 + tempChange * 0.45;
return 100 - (int) Math.round(raw);
return ScoreBuilder.create()
.add("기온", temp, 0.55)
.add("기온 급변", tempChange, 0.45)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.haapyProcess.domain.analysis.criteria.WeatherRiskCriteria;
import com.haapyProcess.domain.analysis.dto.RiskAnalysisResult.FactorGuide;
import com.haapyProcess.domain.analysis.rule.DiseaseRiskRule;
import com.haapyProcess.domain.analysis.score.ScoreBuilder;
import com.haapyProcess.domain.analysis.score.WeatherScore;
import com.haapyProcess.domain.analysis.score.WeatherScoreTables;
import com.haapyProcess.domain.member.entity.PrecipPreference;
import com.haapyProcess.domain.weather.dto.WeatherResponseDto;
Expand Down Expand Up @@ -65,17 +67,14 @@ public List<FactorGuide> evaluateFactorGuides(WeatherResponseDto weather) {
}

@Override
public int evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
// 건강 위험도 (공통)
double health = WeatherScoreTables.pm10(weather.getParsedPm10Value()) * 0.35
+ WeatherScoreTables.pm25(weather.getParsedPm25Value()) * 0.35
+ WeatherScoreTables.temp(weather.getParsedCurrentTemp()) * 0.20
+ WeatherScoreTables.uv(weather.getParsedUvRisk()) * 0.10;

// 강수 불편도 (개인 선호 기반 가산점)
double precip = WeatherScoreTables.precipNormal(weather.getParsedCurrentPty(), precipPreference) * 0.13;

double raw = Math.min(health + precip, 100.0);
return 100 - (int) Math.round(raw);
public WeatherScore evaluateWeatherScore(WeatherResponseDto weather, PrecipPreference precipPreference) {
// 건강 위험도(공통) + 강수 불편도(개인 선호 기반 가산점). 총합은 build()에서 100으로 상한 처리된다.
return ScoreBuilder.create()
.add("미세먼지", WeatherScoreTables.pm10(weather.getParsedPm10Value()), 0.35)
.add("초미세먼지", WeatherScoreTables.pm25(weather.getParsedPm25Value()), 0.35)
.add("기온", WeatherScoreTables.temp(weather.getParsedCurrentTemp()), 0.20)
.add("자외선", WeatherScoreTables.uv(weather.getParsedUvRisk()), 0.10)
.add("강수", WeatherScoreTables.precipNormal(weather.getParsedCurrentPty(), precipPreference), 0.13)
.build();
}
}
Loading