public static Location closestKnownLocation(GeoCoordinate currentLoc, Location[] knownLocations) { GeoCoordinate otherLoc = new GeoCoordinate(knownLocations[0].Latitude, knownLocations[0].Longitude); double minDistToKnownLocation = AlgoUtils.calcDist(currentLoc, otherLoc); Location closestKnownLocation = knownLocations[0]; double currentDist; for (int i = 1; i < knownLocations.Length; i++) { otherLoc.Latitude = knownLocations[i].Latitude; otherLoc.Longitude = knownLocations[i].Longitude; currentDist = AlgoUtils.calcDist(currentLoc, otherLoc); if (currentDist < minDistToKnownLocation) { minDistToKnownLocation = currentDist; closestKnownLocation = knownLocations[i]; } } return(closestKnownLocation); }
/// Step B - MONITORING public AlgoUtils.Status monitorAndAlert(string currentPatientID) { //***************** SETUP *****************// bool lessThanHalf = false; bool lessThan2 = false; bool lessThan5 = false; bool lessThan10 = false; double minDistToKnownLocation = AlgoUtils.calcDist(currentLoc, new GeoCoordinate(closestKnownLocation.Latitude, closestKnownLocation.Longitude)); Trace.TraceInformation(String.Format("Dist to closest known location is {0}", minDistToKnownLocation)); //get normal time range parameters for closest known location int[] timeRangeParameters = AlgoUtils.getSafeTimeRangeForLocation(latestSample, currentPatientID); bottomNormalTimeRange = timeRangeParameters[0]; topNormalTimeRange = timeRangeParameters[1]; avgNormalTimeRange = timeRangeParameters[2]; Trace.TraceInformation(String.Format("bottom normal time range is {0}", bottomNormalTimeRange)); Trace.TraceInformation(String.Format("top normal time range is {0}", topNormalTimeRange)); Trace.TraceInformation(String.Format("avg normal time range is {0}", avgNormalTimeRange)); if (minDistToKnownLocation <= 10) { lessThan10 = true; } if (minDistToKnownLocation <= 5) { lessThan5 = true; } if (minDistToKnownLocation <= 2) { lessThan2 = true; } if (minDistToKnownLocation <= 0.5) { lessThanHalf = true; } //*****************************************// if ((DateTime.Now.Hour - sampleTime.Hour) > CONNECTION_LOST_TIME_DIF) { return(AlgoUtils.Status.ConnectionLost); } Trace.TraceInformation(String.Format("latest sample hour is: {0}", sampleTime.Hour)); AlgoUtils.HeatMapDensity measuredDensity = AlgoUtils.heatMapAreaDensityLevel(currentLoc); if (lessThanHalf) //patient is very close to a known location { //time doesn't matter, just make sure heartRate is okay if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate)) { Trace.TraceInformation(String.Format("less than half, heart is okay - Safety")); return(AlgoUtils.Status.Safety); } else { Trace.TraceInformation(String.Format("less than half, heart is BAD - Distress")); return(AlgoUtils.Status.Distress); //potential distress or heart issues } } //check if it's an emergency time period else if (AlgoUtils.isTimeInSafeRange(sampleTime.Hour) == false) { //patient is not close enough to a known location + it's currently the EMERGENCY TIME PERIOD Trace.TraceInformation(String.Format("more than half, EMERGENCY TIME PERIOD - Risk")); return(AlgoUtils.Status.Risk); } else if (lessThan2 || measuredDensity == AlgoUtils.HeatMapDensity.High) { //patient is somewhat close to a known location, not in a dangerous time if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate)) { Trace.TraceInformation(String.Format("less than 2, normal time, heart is okay - Safety")); return(AlgoUtils.Status.Safety); //if (AlgoUtils.isTimeInNormalRange(sampleTime.Hour)) //{ // Trace.TraceInformation(String.Format("less than 2, normal time, heart is okay - Safety")); // return AlgoUtils.Status.Safety; //} //else //{ // Trace.TraceInformation(String.Format("less than 2, BAD time, heart is okay - Wandering")); // return AlgoUtils.Status.Wandering; //} } else { Trace.TraceInformation(String.Format("less than 2, heart is BAD - Distress")); return(AlgoUtils.Status.Distress); //potential distress or heart issues } } else if (lessThan5 || measuredDensity == AlgoUtils.HeatMapDensity.Medium) { //patient is not too far from a known location if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate)) { if (AlgoUtils.isTimeInNormalRange(sampleTime.Hour) == false || (sampleTime.Hour < avgNormalTimeRange * 0.6 || (sampleTime.Hour > avgNormalTimeRange * 1.4))) { Trace.TraceInformation(String.Format("less than 5, BAD time, heart is okay - Wandering")); return(AlgoUtils.Status.Wandering); } } else { Trace.TraceInformation(String.Format("less than 5, heart is BAD - Distress")); return(AlgoUtils.Status.Distress); //potential distress or heart issues } } else if (lessThan10 || measuredDensity == AlgoUtils.HeatMapDensity.Low) { //patient is somewhat far from a known location if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate)) { Trace.TraceInformation(String.Format("less than 10, heart is okay - Wandering")); return(AlgoUtils.Status.Wandering); } else { Trace.TraceInformation(String.Format("less than 10, heart is BAD - Distress")); return(AlgoUtils.Status.Distress); //potential distress or heart issues } } //patient is very far from a known location, and in probably ZERO-Density area in heat map //patient is possibly lost! Trace.TraceInformation(String.Format("more than 10 - Risk")); return(AlgoUtils.Status.Risk); /// 2.4 Default: sample.location>10km from known location OR in never visited before poligon on heatmap /// 2.4.1 send PUSH to caregiver - "Your beloved John is at (sample.location) area - do you know it?" /// 2.4.1.1 if caregiver knows it then let him add location as known location (with desc. etc.) /// 2.4.1.2 else if caregiver marks patient as wandering then enter POSSIBLE_RISK_MODE }
/// Step B - MONITORING_MODE /// public AlgoUtils.Status monitorAndAlert(string currentPatientID, Sample latestSample) { //***************** SETUP *****************// bool lessThanHalf = false; bool lessThan2 = false; bool lessThan5 = false; bool lessThan10 = false; GeoCoordinate currentLoc = new GeoCoordinate(latestSample.Latitude, latestSample.Longitude); Location closestKnownLocation = AlgoUtils.closestKnownLocation(currentLoc, knownLocations); double minDistToKnownLocation = AlgoUtils.calcDist(currentLoc, new GeoCoordinate(closestKnownLocation.Latitude, closestKnownLocation.Longitude)); //get normal time range parameters for closest known location int[] timeRangeParameters = AlgoUtils.getSafeTimeRangeForLocation(closestKnownLocation, currentPatientID); bottomNormalTimeRange = timeRangeParameters[0]; topNormalTimeRange = timeRangeParameters[1]; avgNormalTimeRange = timeRangeParameters[2]; if (minDistToKnownLocation <= 10) { lessThan10 = true; } if (minDistToKnownLocation <= 5) { lessThan5 = true; } if (minDistToKnownLocation <= 2) { lessThan2 = true; } if (minDistToKnownLocation <= 0.5) { lessThanHalf = true; } //*****************************************// if (lessThanHalf) //patient is very close to a known location { //time doesn't matter, just make sure heartRate is okay if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate)) { return(AlgoUtils.Status.Safety); } else { return(AlgoUtils.Status.Distress); //potential distress or heart issues } } //check if it's an emergency time period else if (AlgoUtils.isTimeInSafeRange(sampleTime.Hour) == false) { //patient is not close enough to a known location + it's currently the EMERGENCY TIME PERIOD return(AlgoUtils.Status.Risk); } else if (lessThan2 || AlgoUtils.isInDensedHeatMapArea(currentLoc) == AlgoUtils.HeatMapDensity.High) { //patient is somewhat close to a known location, not in a dangerous time if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate)) { if (AlgoUtils.isTimeInNormalRange(sampleTime.Hour) == false) { return(AlgoUtils.Status.Safety); } else { return(AlgoUtils.Status.Wandering); } } else { return(AlgoUtils.Status.Distress); //potential distress or heart issues } } else if (lessThan5 || AlgoUtils.isInDensedHeatMapArea(currentLoc) == AlgoUtils.HeatMapDensity.Medium) { //patient is not too far from a known location if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate)) { if (AlgoUtils.isTimeInNormalRange(sampleTime.Hour) == false || (sampleTime.Hour < avgNormalTimeRange * 0.6 || (sampleTime.Hour > avgNormalTimeRange * 1.4))) { return(AlgoUtils.Status.Wandering); } } else { return(AlgoUtils.Status.Distress); //potential distress or heart issues } } else if (lessThan10 || AlgoUtils.isInDensedHeatMapArea(currentLoc) == AlgoUtils.HeatMapDensity.Low) { //patient is somewhat far from a known location if (AlgoUtils.isHeartRateInSafeRange(latestSample.HeartRate)) { return(AlgoUtils.Status.Wandering); } else { return(AlgoUtils.Status.Distress); //potential distress or heart issues } } //patient is very far from a known location, and in probably ZERO-Density area in heat map //patient is possibly lost! return(AlgoUtils.Status.Risk); /// 2.4 Default: sample.location>10km from known location OR in never visited before poligon on heatmap /// 2.4.1 send PUSH to caregiver - "Your beloved John is at (sample.location) area - do you know it?" /// 2.4.1.1 if caregiver knows it then let him add location as known location (with desc. etc.) /// 2.4.1.2 else if caregiver marks patient as wandering then enter POSSIBLE_RISK_MODE }