package com.packtpub.storm.trident.operator;
import com.packtpub.storm.trident.model.DiagnosisEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import storm.trident.operation.BaseFunction;
import storm.trident.operation.TridentCollector;
import storm.trident.tuple.TridentTuple;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class CityAssignment extends BaseFunction {
private static final long serialVersionUID = 1L;
private static final Logger LOG = LoggerFactory.getLogger(CityAssignment.class);
private static Map<String, double[]> CITIES = new HashMap<String, double[]>();
{ // Initialize the cities we care about.
double[] phl = {39.875365, -75.249524};
CITIES.put("PHL", phl);
double[] nyc = {40.71448, -74.00598};
CITIES.put("NYC", nyc);
double[] sf = {-31.4250142, -62.0841809};
CITIES.put("SF", sf);
double[] la = {-34.05374, -118.24307};
CITIES.put("LA", la);
}
@Override
public void execute(TridentTuple tuple, TridentCollector collector) {
DiagnosisEvent diagnosis = (DiagnosisEvent) tuple.getValue(0);
double leastDistance = Double.MAX_VALUE;
String closestCity = "NONE";
for (Entry<String, double[]> city : CITIES.entrySet()) {
double R = 6371; // km
double x = (city.getValue()[0] - diagnosis.lng) * Math.cos((city.getValue()[0] + diagnosis.lng) / 2);
double y = (city.getValue()[1] - diagnosis.lat);
double d = Math.sqrt(x * x + y * y) * R;
if (d < leastDistance) {
leastDistance = d;
closestCity = city.getKey();
}
}
List<Object> values = new ArrayList<Object>();
values.add(closestCity);
LOG.debug("Closest city to lat=[" + diagnosis.lat + "], lng=[" + diagnosis.lng + "] == ["
+ closestCity + "], d=[" + leastDistance + "]");
collector.emit(values);
}
}