package com.sunlightlabs.congress.services;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sunlightlabs.congress.models.CongressException;
import com.sunlightlabs.congress.models.District;
import com.sunlightlabs.congress.models.Legislator;
import org.geojson.GeoJsonObject;
import org.geojson.MultiPolygon;
import java.io.IOException;
public class DistrictService {
public static String BASE_URL = "http://theunitedstates.io/districts/";
public static String urlForDistrict(String state, String district) {
return BASE_URL + "cds/2012/" + state + "-" + district + "/shape.geojson";
}
public static String urlForState(String state) {
return BASE_URL + "states/" + state + "/shape.geojson";
}
public static String urlForLegislator(Legislator legislator) {
if (legislator.chamber.equals("senate"))
return urlForState(legislator.state);
else
return urlForDistrict(legislator.state, legislator.district);
}
// uses a special Jackson-based GeoJSON parser, not the typical JSONObject-based parser
// https://github.com/opendatalab-de/geojson-jackson
public static District find(Legislator legislator) throws CongressException {
String url = urlForLegislator(legislator);
String json = Congress.fetchJSON(url);
// parse and return the given multipolygon
try {
GeoJsonObject geojson = new ObjectMapper().readValue(json, GeoJsonObject.class);
if (geojson instanceof MultiPolygon) {
District district = new District();
district.polygon = (MultiPolygon) geojson;
district.state = legislator.state;
district.district = legislator.district;
return district;
}
// otherwise, gracefully choke
else return null;
} catch (JsonParseException e) {
throw new CongressException(e, "Error parsing JSON from " + url);
} catch (JsonMappingException e) {
throw new CongressException(e, "Error parsing GeoJSON from " + url);
} catch (IOException e) { // must go last, catch-all
throw new CongressException(e, "Error parsing data from " + url);
}
}
}