diff --git a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/RouteStepAnalyzerNodeDialog.java b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/RouteStepAnalyzerNodeDialog.java
index 8101c46..3cfc6b3 100644
--- a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/RouteStepAnalyzerNodeDialog.java
+++ b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/RouteStepAnalyzerNodeDialog.java
@@ -2,10 +2,14 @@
import java.awt.Label;
+import javax.swing.ToolTipManager;
+
import org.knime.core.node.defaultnodesettings.DefaultNodeSettingsPane;
import org.knime.core.node.defaultnodesettings.DialogComponentFileChooser;
+import org.knime.core.node.defaultnodesettings.DialogComponentNumberEdit;
import org.knime.core.node.defaultnodesettings.DialogComponentString;
import org.knime.core.node.defaultnodesettings.DialogComponentStringSelection;
+import org.knime.core.node.defaultnodesettings.SettingsModelIntegerBounded;
import org.knime.core.node.defaultnodesettings.SettingsModelString;
/**
@@ -22,13 +26,26 @@
*/
public class RouteStepAnalyzerNodeDialog extends DefaultNodeSettingsPane {
-
+ private static final String MIN_TIME_TOOLTIP = ""
+ + "This value (seconds) is used to determine wether two subsegquent visit to the same"
+ + "
visit to the same segment should be considered as distinct."
+ + "
Visits that are less than this time apart from the last valid visit will be discarded."
+ + "";
/**
* New dialog pane for configuring the node. The dialog created here
* will show up when double clicking on a node in KNIME Analytics Platform.
*/
protected RouteStepAnalyzerNodeDialog() {
super();
+
+ ToolTipManager.sharedInstance().setDismissDelay(15000);
+
+ SettingsModelIntegerBounded minTimeBetween = RouteStepAnalyzerNodeModel.createMinTimeSettings();
+ DialogComponentNumberEdit minTimeSelector = new DialogComponentNumberEdit(minTimeBetween, "Ignore all visits that are less than this value(seconds) away from the last one : ", 10);
+ minTimeSelector.setToolTipText(MIN_TIME_TOOLTIP);
+ minTimeBetween.setEnabled(true);
+ addDialogComponent(minTimeSelector);
+
}
}
diff --git a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/RouteStepAnalyzerNodeFactory.xml b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/RouteStepAnalyzerNodeFactory.xml
index d4a85f0..79fe751 100644
--- a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/RouteStepAnalyzerNodeFactory.xml
+++ b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/RouteStepAnalyzerNodeFactory.xml
@@ -24,9 +24,9 @@
destination_id, the OSM id of the destination node.
tags, the OSM tags associated to the ways to which the origin and destination nodes both belong.
the_geom, a String representation of a route formatted as WKT Linestring.
- The best way to obtain such a table from a specific route is using the Map Matcher Node of the
- KNOT toolkit.
+ The best way to obtain such a table is using the Map Matcher Node of the
+ KNOT toolkit.
A table containing the following information:
diff --git a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/RouteStepAnalyzerNodeModel.java b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/RouteStepAnalyzerNodeModel.java
index aa6bbe5..6e0dd35 100644
--- a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/RouteStepAnalyzerNodeModel.java
+++ b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/RouteStepAnalyzerNodeModel.java
@@ -45,6 +45,7 @@
import org.knime.core.node.NodeModel;
import org.knime.core.node.NodeSettingsRO;
import org.knime.core.node.NodeSettingsWO;
+import org.knime.core.node.defaultnodesettings.SettingsModelIntegerBounded;
import org.unina.spatialanalysis.RouteStepAnalyzer.RouteStepAnalyzerNodeModel;
import org.unina.spatialanalysis.RouteStepAnalyzer.entity.DetailedDataEntry;
import org.unina.spatialanalysis.RouteStepAnalyzer.entity.SimpleDataEntry;
@@ -67,9 +68,21 @@
*/
@SuppressWarnings("deprecation")
public class RouteStepAnalyzerNodeModel extends NodeModel {
+
+ private static final String MIN_TIME_SETTINGS = "m_min_time";
+ private static final int DEFAULT_MIN_TIME_SETTINGS = 0;
+
private static final NodeLogger LOGGER = NodeLogger.getLogger(RouteStepAnalyzerNodeModel.class);
+ private final SettingsModelIntegerBounded m_minTimeBetween = createMinTimeSettings();
+
+
+ public static SettingsModelIntegerBounded createMinTimeSettings() {
+ return new SettingsModelIntegerBounded(MIN_TIME_SETTINGS, DEFAULT_MIN_TIME_SETTINGS, 0, Integer.MAX_VALUE);
+ }
+
+
/**
* Constructor for the node model.
*/
@@ -198,7 +211,7 @@ protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final Ex
}
if(rowId.contains("NEVER_VISITED")) {
- Segment s = new Segment(originId, destinationId, tags, theGeom);
+ Segment s = new Segment(originId, destinationId, tags, theGeom, m_minTimeBetween.getIntValue());
neverVisitedSegmentHolder.addSegment(s);
}else if(ownerId==Integer.MIN_VALUE || theGeom==null || beginAt== null || endAt==null || originId==Long.MIN_VALUE || destinationId == Long.MIN_VALUE) {
LOGGER.info("Row n " + currentRowCounter + " has invalid values! It will be skipped.\n");
@@ -207,7 +220,7 @@ protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final Ex
if(visitedSegmentHolder.containsSegment(originId, destinationId)) {
s = visitedSegmentHolder.getSegment(originId, destinationId);
}else {
- s = new Segment(originId, destinationId, tags, theGeom);
+ s = new Segment(originId, destinationId, tags, theGeom, m_minTimeBetween.getIntValue());
visitedSegmentHolder.addSegment(s);
}
daysInDataSet.add(beginAt.toLocalDate());
@@ -224,11 +237,6 @@ protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final Ex
int counter = 0;
-
- while(exec.getProgressMonitor().getProgress()!=0) {
- exec.setProgress(0.0);
- System.out.println("Do I exit?");
- }
for(Segment s: visitedSegmentHolder.getAllSegments()) {
s.generateResults();
@@ -253,11 +261,6 @@ protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final Ex
}
counter = 0;
-
- while(exec.getProgressMonitor().getProgress()!=0) {
- exec.setProgress(0.0);
- System.out.println("Do I exit?");
- }
for(Segment s: neverVisitedSegmentHolder.getAllSegments()) {
s.generateResults();
@@ -307,7 +310,15 @@ private void addComplexDataEntry(DetailedDataEntry dEntry, int complexEntryCount
avgDayCell = DataType.getMissingCell();
}
complexCells.add(avgDayCell);
-
+
+ DataCell medianDay;
+ if(dEntry.getMedianForDay()!=0) {
+ medianDay= new DoubleCell(dEntry.getMedianForDay());
+ }else {
+ medianDay = DataType.getMissingCell();
+ }
+ complexCells.add(medianDay);
+
//Early Morning
DataCell nEmCell = new IntCell(dEntry.getnVisitsEM());
complexCells.add(nEmCell);
@@ -318,6 +329,15 @@ private void addComplexDataEntry(DetailedDataEntry dEntry, int complexEntryCount
avgEmCell = DataType.getMissingCell();
}
complexCells.add(avgEmCell);
+ DataCell medianEm;
+ if(dEntry.getMedianForEM()!=0) {
+ medianEm= new DoubleCell(dEntry.getMedianForEM());
+ }else {
+ medianEm = DataType.getMissingCell();
+ }
+ complexCells.add(medianEm);
+
+
//Mid Morning
DataCell nMmCell = new IntCell(dEntry.getnVisitsMM());
complexCells.add(nMmCell);
@@ -328,6 +348,14 @@ private void addComplexDataEntry(DetailedDataEntry dEntry, int complexEntryCount
avgMmCell = DataType.getMissingCell();
}
complexCells.add(avgMmCell);
+ DataCell medianMm;
+ if(dEntry.getMedianForMM()!=0) {
+ medianMm= new DoubleCell(dEntry.getMedianForMM());
+ }else {
+ medianMm = DataType.getMissingCell();
+ }
+ complexCells.add(medianMm);
+
//Afternoon
DataCell nACell = new IntCell(dEntry.getnVisistsA());
complexCells.add(nACell);
@@ -338,6 +366,15 @@ private void addComplexDataEntry(DetailedDataEntry dEntry, int complexEntryCount
avgACell = DataType.getMissingCell();
}
complexCells.add(avgACell);
+ DataCell medianA;
+ if(dEntry.getMedianForDay()!=0) {
+ medianA= new DoubleCell(dEntry.getMedianForA());
+ }else {
+ medianA = DataType.getMissingCell();
+ }
+ complexCells.add(medianA);
+
+
//Evening
DataCell nECell = new IntCell(dEntry.getnVisistsE());
complexCells.add(nECell);
@@ -348,6 +385,15 @@ private void addComplexDataEntry(DetailedDataEntry dEntry, int complexEntryCount
avgECell = DataType.getMissingCell();
}
complexCells.add(avgECell);
+ DataCell medianE;
+ if(dEntry.getMedianForE()!=0) {
+ medianE= new DoubleCell(dEntry.getMedianForE());
+ }else {
+ medianE = DataType.getMissingCell();
+ }
+ complexCells.add(medianE);
+
+
DataCell tags = new StringCell(dEntry.getTags());
complexCells.add(tags);
DataCell theGeom = new StringCell(dEntry.getTheGeom());
@@ -377,6 +423,14 @@ private void addSimpleDataEntry(SimpleDataEntry se, int simpleEntryCounter, Buff
avg = DataType.getMissingCell();
}
simpleCells.add(avg);
+
+ DataCell median;
+ if(se.getMedianTime()!=0) {
+ median= new DoubleCell(se.getMedianTime());
+ }else {
+ median = DataType.getMissingCell();
+ }
+ simpleCells.add(median);
DataCell tags = new StringCell(se.getTags());
simpleCells.add(tags);
DataCell theGeom = new StringCell(se.getTheGeom());
@@ -415,6 +469,11 @@ protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) throws Invali
throw new InvalidSettingsException("The input table must contain the following columns: owner_id, begin_at, end_at, origin_id, destination_id, origin_tags, destination_tags, the_geom");
}
+ if(m_minTimeBetween.getIntValue()<0) {
+ throw new InvalidSettingsException("The minimum time between visits cannot be negative!");
+
+ }
+
return new DataTableSpec[] { createOutputForDetailed(),createOutputForSimple() };
}
@@ -434,26 +493,42 @@ private DataTableSpec createOutputForDetailed() {
newColumnSpecs.add(specCreator.createSpec());
specCreator = new DataColumnSpecCreator("Day", DateAndTimeCell.TYPE);
newColumnSpecs.add(specCreator.createSpec());
+
specCreator = new DataColumnSpecCreator("N° Visits(Day)", IntCell.TYPE);
newColumnSpecs.add(specCreator.createSpec());
specCreator = new DataColumnSpecCreator("AvgTime(Day)", DoubleCell.TYPE);
newColumnSpecs.add(specCreator.createSpec());
+ specCreator = new DataColumnSpecCreator("MedianTime(Day)", DoubleCell.TYPE);
+ newColumnSpecs.add(specCreator.createSpec());
+
specCreator = new DataColumnSpecCreator("N° Visits("+TimeSlot.EARLY_MORNING.toString()+")", IntCell.TYPE);
newColumnSpecs.add(specCreator.createSpec());
specCreator = new DataColumnSpecCreator("AvgTime("+TimeSlot.EARLY_MORNING.toString()+")", DoubleCell.TYPE);
newColumnSpecs.add(specCreator.createSpec());
+ specCreator = new DataColumnSpecCreator("MedianTime("+TimeSlot.EARLY_MORNING.toString()+")", DoubleCell.TYPE);
+ newColumnSpecs.add(specCreator.createSpec());
+
specCreator = new DataColumnSpecCreator("N° Visits("+TimeSlot.MID_MORNING.toString()+")", IntCell.TYPE);
newColumnSpecs.add(specCreator.createSpec());
specCreator = new DataColumnSpecCreator("AvgTime("+TimeSlot.MID_MORNING.toString()+")", DoubleCell.TYPE);
- newColumnSpecs.add(specCreator.createSpec());;
+ newColumnSpecs.add(specCreator.createSpec());
+ specCreator = new DataColumnSpecCreator("MedianTime("+TimeSlot.MID_MORNING.toString()+")", DoubleCell.TYPE);
+ newColumnSpecs.add(specCreator.createSpec());
+
specCreator = new DataColumnSpecCreator("N° Visits("+TimeSlot.AFTERNOON.toString()+")", IntCell.TYPE);
newColumnSpecs.add(specCreator.createSpec());
specCreator = new DataColumnSpecCreator("AvgTime("+TimeSlot.AFTERNOON.toString()+")", DoubleCell.TYPE);
newColumnSpecs.add(specCreator.createSpec());
+ specCreator = new DataColumnSpecCreator("MedianTime("+TimeSlot.AFTERNOON.toString()+")", DoubleCell.TYPE);
+ newColumnSpecs.add(specCreator.createSpec());
+
specCreator = new DataColumnSpecCreator("N° Visits("+TimeSlot.EVENING.toString()+")", IntCell.TYPE);
newColumnSpecs.add(specCreator.createSpec());
specCreator = new DataColumnSpecCreator("AvgTime("+TimeSlot.EVENING.toString()+")", DoubleCell.TYPE);
newColumnSpecs.add(specCreator.createSpec());
+ specCreator = new DataColumnSpecCreator("MedianTime("+TimeSlot.EVENING.toString()+")", DoubleCell.TYPE);
+ newColumnSpecs.add(specCreator.createSpec());
+
specCreator = new DataColumnSpecCreator("Tags", StringCell.TYPE);
newColumnSpecs.add(specCreator.createSpec());
HashMap m = new HashMap();
@@ -483,12 +558,10 @@ private DataTableSpec createOutputForSimple() {
simpleColumnSpecs.add(specCreator.createSpec());
specCreator = new DataColumnSpecCreator("N° Visits", IntCell.TYPE);
simpleColumnSpecs.add(specCreator.createSpec());
-
-
-
specCreator = new DataColumnSpecCreator("Avg time Between", DoubleCell.TYPE);
- DataColumnSpec e = specCreator.createSpec();
- simpleColumnSpecs.add(e);
+ simpleColumnSpecs.add(specCreator.createSpec());
+ specCreator = new DataColumnSpecCreator("Median time", DoubleCell.TYPE);
+ simpleColumnSpecs.add(specCreator.createSpec());
specCreator = new DataColumnSpecCreator("Tags", StringCell.TYPE);
simpleColumnSpecs.add(specCreator.createSpec());
HashMap m = new HashMap();
@@ -519,7 +592,7 @@ protected void saveSettingsTo(final NodeSettingsWO settings) {
* all common data types. Hence, you can easily write your settings manually.
* See the methods of the NodeSettingsWO.
*/
-
+ m_minTimeBetween.saveSettingsTo(settings);
}
/**
@@ -534,8 +607,7 @@ protected void loadValidatedSettingsFrom(final NodeSettingsRO settings) throws I
* The SettingsModel will handle the loading. After this call, the current value
* (from the view) can be retrieved from the settings model.
*/
-;
-
+ m_minTimeBetween.loadSettingsFrom(settings);
}
@@ -550,6 +622,7 @@ protected void validateSettings(final NodeSettingsRO settings) throws InvalidSet
* already handled in the dialog. Do not actually set any values of any member
* variables.
*/
+ m_minTimeBetween.validateSettings(settings);
}
diff --git a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/DetailedDataEntry.java b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/DetailedDataEntry.java
index 0ab81cf..bff4ef6 100644
--- a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/DetailedDataEntry.java
+++ b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/DetailedDataEntry.java
@@ -19,22 +19,32 @@ public class DetailedDataEntry {
private Double avgForDay;
+ private double medianForDay;
+
private Integer nVisitsEM;
private Double avgForEM;
+ private double medianForEM;
+
private Integer nVisitsMM;
private Double avgForMM;
+ private double medianForMM;
+
private Integer nVisistsA;
private Double avgForA;
+ private double medianForA;
+
private Integer nVisistsE;
private Double avgForE;
+ private Double medianForE;
+
private String tags;
private String theGeom;
@@ -217,22 +227,54 @@ public void setTheGeom(String theGeom) {
this.theGeom = theGeom;
}
+
+
+ public double getMedianForDay() {
+ return medianForDay;
+ }
+
+ public double getMedianForEM() {
+ return medianForEM;
+ }
+
+ public double getMedianForMM() {
+ return medianForMM;
+ }
+
+ public double getMedianForA() {
+ return medianForA;
+ }
+
+ public Double getMedianForE() {
+ return medianForE;
+ }
+
public DetailedDataEntry(LocalDate ld, Segment s, HitHolder vholder) {
this.originId = s.getOriginId();
this.destinationId = s.getDestinationId();
this.day = ld.atStartOfDay();
this.theGeom = s.getTheGeom();
this.tags = s.getTags();
+
this.avgForEM = vholder.getAverageTimeBetweenVisits(TimeSlot.EARLY_MORNING);
this.nVisitsEM = vholder.getTotalVisits(TimeSlot.EARLY_MORNING);
+ this.medianForEM = vholder.getMedianTimeBetweenVisits(TimeSlot.EARLY_MORNING);
+
this.avgForMM = vholder.getAverageTimeBetweenVisits(TimeSlot.MID_MORNING);
this.nVisitsMM = vholder.getTotalVisits(TimeSlot.MID_MORNING);
+ this.medianForMM = vholder.getMedianTimeBetweenVisits(TimeSlot.MID_MORNING);
+
this.avgForA= vholder.getAverageTimeBetweenVisits(TimeSlot.AFTERNOON);
this.nVisistsA = vholder.getTotalVisits(TimeSlot.AFTERNOON);
+ this.medianForA = vholder.getMedianTimeBetweenVisits(TimeSlot.AFTERNOON);
+
this.avgForE= vholder.getAverageTimeBetweenVisits(TimeSlot.EVENING);
this.nVisistsE = vholder.getTotalVisits(TimeSlot.EVENING);
+ this.medianForE = vholder.getMedianTimeBetweenVisits(TimeSlot.EVENING);
+
this.avgForDay= vholder.getAverageTimeBetweenVisits(TimeSlot.WHOLE_DAY);
this.nVisitsInDay = vholder.getTotalVisits(TimeSlot.WHOLE_DAY);
+ this.medianForDay = vholder.getMedianTimeBetweenVisits(TimeSlot.WHOLE_DAY);
}
public long getOriginId() {
diff --git a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/SimpleDataEntry.java b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/SimpleDataEntry.java
index f969e2f..1de5bf9 100644
--- a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/SimpleDataEntry.java
+++ b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/SimpleDataEntry.java
@@ -9,6 +9,7 @@ public class SimpleDataEntry {
private Integer totalVisit;
private String tags;
private double avgTime;
+ private double medianTime;
/**
* @return the tags
@@ -43,13 +44,18 @@ public SimpleDataEntry(Segment s) {
this.theGeom = s.getTheGeom();
this.tags = s.getTags();
this.totalVisit = s.getNumberOfHits();
- if(totalVisit-1>1) {
- this.avgTime = s.getTotalTimeBetweenHits()/s.getNumberOfHits();
+ if(totalVisit-1>0) {
+ this.avgTime = s.getTotalTimeBetweenHits()/(totalVisit-1);
}else {
this.avgTime = 0;
}
+ this.medianTime = s.getMedianTime();
+ }
+ public double getMedianTime() {
+ return medianTime;
}
+
public double getAvgTime() {
return avgTime;
}
diff --git a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/routesteps/HitHolder.java b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/routesteps/HitHolder.java
index 8bd2167..bb2cdeb 100644
--- a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/routesteps/HitHolder.java
+++ b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/routesteps/HitHolder.java
@@ -2,6 +2,7 @@
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
import org.unina.spatialanalysis.RouteStepAnalyzer.entity.visit.TimeSlot;
@@ -12,6 +13,7 @@ public class HitHolder {
private TimeDataHolder afternoonTimeData;
private TimeDataHolder eveningTimeData;
private TimeDataHolder wholeDayTimeData;
+ private ArrayList timegaps;
public HitHolder(){
super();
@@ -94,12 +96,29 @@ public double getAverageTimeBetweenVisits(TimeSlot timeSlot) {
return 0;
}
+ public double getMedianTimeBetweenVisits(TimeSlot timeSlot) {
+ switch(timeSlot) {
+ case EARLY_MORNING:
+ return earlyMorningTimeData.getMedianTimeBetweenVisits();
+ case MID_MORNING:
+ return midMorningTimeData.getMedianTimeBetweenVisits();
+ case AFTERNOON:
+ return afternoonTimeData.getMedianTimeBetweenVisits();
+ case EVENING:
+ return eveningTimeData.getMedianTimeBetweenVisits();
+ case WHOLE_DAY:
+ return wholeDayTimeData.getMedianTimeBetweenVisits();
+ }
+ return 0;
+ }
private class TimeDataHolder{
private int totalHits = 0;
private double timeBetweenHits = 0;
private LocalDateTime lastVisited = null;
+ private ArrayList timegaps = new ArrayList<>();
+ private ArrayList recovery = new ArrayList<>();
/**
* @return the totalHits
@@ -108,6 +127,30 @@ public int getTotalHits() {
return totalHits;
}
+ public double getMedianTimeBetweenVisits() {
+ double medianTime;
+ timegaps.sort((d1, d2)->{
+ if(d1>d2) {
+ return 1;
+ }else if(d2>d1) {
+ return -1;
+ }else {
+ return 0;
+ }
+ });
+ int size = timegaps.size();
+ if(size>1) {
+ if(size%2==0) {
+ medianTime = (timegaps.get((size/2)-1) + timegaps.get(size/2))/2;
+ }else {
+ medianTime = timegaps.get(((size+1)/2)-1);
+ }
+ return medianTime;
+ }else {
+ return 0;
+ }
+ }
+
/**
* @return the timeBetweenHits
*/
@@ -124,17 +167,33 @@ public double getAverageTimeBetweenVisits() {
}
public void addHit(Hit h) {
+ totalHits++;
if(lastVisited==null) {
this.lastVisited = h.getEnd();
- totalHits++;
+ timegaps.add(0.0);
+ recovery.add(lastVisited);
}else {
- //System.out.println(ChronoUnit.SECONDS.between(lastVisited, h.getBegin()));
- double timeInMicroSeconds = ChronoUnit.MICROS.between(lastVisited, h.getBegin());
- timeBetweenHits+=Math.ceil(timeInMicroSeconds/1000000);
- lastVisited = h.getEnd();
- totalHits++;
+ double timeBetween = Math.ceil(ChronoUnit.SECONDS.between(lastVisited, h.getBegin()));
+ if(timeBetween>0) {
+ double timeInSeconds = Math.ceil(ChronoUnit.SECONDS.between(lastVisited, h.getBegin()));
+ timeBetweenHits+= timeInSeconds;
+ lastVisited = h.getEnd();
+ timegaps.add(timeBetween);
+ recovery.add(lastVisited);
+ }else {
+ int j = 0;
+ while(Math.ceil(ChronoUnit.SECONDS.between(recovery.get(j), h.getBegin()))>0) {
+ j++;
+ }
+ timeBetween = Math.ceil(ChronoUnit.SECONDS.between(recovery.get(j), h.getBegin()));
+ timegaps.add(timeBetween);
+ if(lastVisited.isBefore(h.getEnd())) {
+ lastVisited = h.getEnd();
+ recovery.add(lastVisited);
+ }
+ }
}
}
- }
+ }
}
diff --git a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/routesteps/Segment.java b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/routesteps/Segment.java
index 5ab1ecd..a50fc4b 100644
--- a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/routesteps/Segment.java
+++ b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/routesteps/Segment.java
@@ -1,14 +1,18 @@
package org.unina.spatialanalysis.RouteStepAnalyzer.entity.routesteps;
+import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeSet;
public class Segment {
+ private final int MIN_TIME_BETWEEN_SETTING;
+
private long originId;
private long destinationId;
@@ -25,6 +29,7 @@ public class Segment {
private int numberOfHits;
+ private double medianTime;
/**
* @return the originId
@@ -35,6 +40,12 @@ public long getOriginId() {
+ public double getMedianTime() {
+ return medianTime;
+ }
+
+
+
/**
* @return the data
*/
@@ -96,7 +107,7 @@ public boolean equals(Object obj) {
- public Segment(long originId, long destinationId, String tags, String theGeom) {
+ public Segment(long originId, long destinationId, String tags, String theGeom, int minTimeBetween) {
super();
this.originId = originId;
this.destinationId = destinationId;
@@ -105,6 +116,7 @@ public Segment(long originId, long destinationId, String tags, String theGeom) {
this.hits = new TreeSet();
this.totalTimeBetweenHits = 0;
this.numberOfHits = 0;
+ this.MIN_TIME_BETWEEN_SETTING = minTimeBetween;
}
/**
@@ -115,33 +127,90 @@ public TreeSet getHits() {
}
- public void generateResults() {
+ public void generateResults() throws IOException {
+
this.data = new HashMap();
+ ArrayList timesInBetween = new ArrayList<>();
Iterator i = this.hits.iterator();
+
LocalDateTime lastVisited = null;
+ ArrayList recovery = new ArrayList<>();;
+
while(i.hasNext()) {
- Hit h = i.next();
- if(this.data.containsKey(h.getBegin().toLocalDate())) {
- HitHolder tmp = this.data.get(h.getBegin().toLocalDate());
- tmp.addHit(h);
- }else {
- HitHolder tmp = new HitHolder();
- tmp.addHit(h);
- this.data.put(h.getBegin().toLocalDate(), tmp);
- }
- numberOfHits++;
+ Hit h = i.next();
if(lastVisited==null) {
+ if(this.data.containsKey(h.getBegin().toLocalDate())) {
+ HitHolder tmp = this.data.get(h.getBegin().toLocalDate());
+ tmp.addHit(h);
+ }else {
+ HitHolder tmp = new HitHolder();
+ tmp.addHit(h);
+ this.data.put(h.getBegin().toLocalDate(), tmp);
+ }
+ numberOfHits++;
lastVisited = h.getEnd();
+ recovery.add(h.getEnd());
+ timesInBetween.add(0.0);
}else {
- totalTimeBetweenHits = ChronoUnit.SECONDS.between(lastVisited, h.getBegin());
- lastVisited = h.getEnd();
+ double timeBetween = Math.ceil(ChronoUnit.SECONDS.between(lastVisited, h.getBegin()));
+ if(timeBetween>=MIN_TIME_BETWEEN_SETTING){
+ timesInBetween.add(timeBetween);
+ if(this.data.containsKey(h.getBegin().toLocalDate())) {
+ HitHolder tmp = this.data.get(h.getBegin().toLocalDate());
+ tmp.addHit(h);
+ }else {
+ HitHolder tmp = new HitHolder();
+ tmp.addHit(h);
+ this.data.put(h.getBegin().toLocalDate(), tmp);
+ }
+ totalTimeBetweenHits += timeBetween;
+ numberOfHits++;
+ lastVisited = h.getEnd();
+ recovery.add(h.getEnd());
+ }else if(timeBetween<0) {
+ int j = 0;
+ while(Math.ceil(ChronoUnit.SECONDS.between(recovery.get(j), h.getBegin()))>0) {
+ j++;
+ }
+ timeBetween = Math.ceil(ChronoUnit.SECONDS.between(recovery.get(j), h.getBegin()));
+
+ timesInBetween.add(timeBetween);
+ if(this.data.containsKey(h.getBegin().toLocalDate())) {
+ HitHolder tmp = this.data.get(h.getBegin().toLocalDate());
+ tmp.addHit(h);
+ }else {
+ HitHolder tmp = new HitHolder();
+ tmp.addHit(h);
+ this.data.put(h.getBegin().toLocalDate(), tmp);
+ }
+ numberOfHits++;
+ totalTimeBetweenHits += timeBetween;
+
+ }
}
-
-
i.remove();
}
-
+ timesInBetween.sort((d1, d2)->{
+ if(d1>d2) {
+ return 1;
+ }else if(d2>d1) {
+ return -1;
+ }else {
+ return 0;
+ }
+ });
+ int size = timesInBetween.size();
+ if(size>1) {
+ if(timesInBetween.size()%2==0) {
+ medianTime = (timesInBetween.get((size/2)-1) + timesInBetween.get(size/2))/2;
+ }else {
+ medianTime = timesInBetween.get(((size+1)/2)-1);
+ }
+ }else {
+ medianTime=0;
+ }
}
+
/**
* @return the totalTimeBetweenVisits
@@ -164,7 +233,4 @@ public int getNumberOfHits() {
public boolean addHit(Hit h) {
return this.hits.add(h);
}
-
-
-
}
diff --git a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/visit/TimeSlot.java b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/visit/TimeSlot.java
index 990e0bb..b1c2997 100644
--- a/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/visit/TimeSlot.java
+++ b/nodes/SegmentCoverageAnalyzer/src/org/unina/spatialanalysis/RouteStepAnalyzer/entity/visit/TimeSlot.java
@@ -3,10 +3,10 @@
import java.time.LocalDateTime;
public enum TimeSlot {
- EARLY_MORNING("[00:00-06:00]"),
- MID_MORNING("[00:06-12:00]"),
- AFTERNOON("[12:00-18:00]"),
- EVENING("[18:00-24:00]"),
+ EARLY_MORNING("[00:00-08:00]"),
+ MID_MORNING("[00:08-14:00]"),
+ AFTERNOON("[14:00-20:00]"),
+ EVENING("[20:00-24:00]"),
WHOLE_DAY("");
TimeSlot(String string) {
@@ -22,13 +22,13 @@ public String toString() {
public static TimeSlot getTimeSlot(LocalDateTime ldt) {
TimeSlot timeSlot = null;
int hour = ldt.getHour();
- if(hour>=0 && hour<6) {
+ if(hour>=0 && hour<8) {
timeSlot = TimeSlot.EARLY_MORNING;
- }else if(hour>=6 && hour<12) {
+ }else if(hour>=8 && hour<14) {
timeSlot = TimeSlot.MID_MORNING;
- }else if(hour>=12 && hour<18) {
+ }else if(hour>=14 && hour<20) {
timeSlot = TimeSlot.AFTERNOON;
- }else if(hour>=18 && hour<=23) {
+ }else if(hour>=20 && hour<=23) {
timeSlot = TimeSlot.EVENING;
}
return timeSlot;