public class Cartogram {
public static void main(String[] args) throws Exception {
Rectangle viewBounds = new Rectangle(0, 0, 1200,800);
Renderer renderer = new ParallelRenderer();
//Glyphset<Point2D, Character> populationSource = ar.app.components.sequentialComposer.OptionDataset.CENSUS_SYN_PEOPLE.dataset();
final Glyphset<Point2D, CategoricalCounts<String>> populationSource = ar.app.components.sequentialComposer.OptionDataset.CENSUS_TRACTS.glyphset;
System.out.println("Population glyphset loaded.");
File statesSource = new File("../data/maps/USStates/");
final Map<String, Shape> rawShapes = simplifyKeys(GeoJSONTools.flipY(GeoJSONTools.loadShapesJSON(statesSource, false)));
rawShapes.remove("AK");
rawShapes.remove("HI");
final Glyphset<Shape, String> states = WrappedCollection.wrap(rawShapes.entrySet(), new Shaper.MapValue<String, Shape>(), new Valuer.MapKey<String, Shape>());
System.out.println("State shapes loaded.");
final AffineTransform viewTransform = Util.zoomFit(populationSource.bounds().createUnion(states.bounds()), viewBounds.width, viewBounds.height);
final Aggregates<Integer> population = renderer.aggregate(populationSource, TouchesPixel.make(populationSource), new Numbers.Count<>(), viewTransform, viewBounds.width, viewBounds.height);
final Aggregates<String> labels = renderer.aggregate(states, TouchesPixel.make(states), new General.Last<>(""), viewTransform, viewBounds.width, viewBounds.height);
Aggregates<Pair<String,Integer>> pairs = CompositeWrapper.wrap(labels, population);
System.out.println("Base aggregates created.\n");
int step=100;
//final Transfer.Specialized<Pair<String,Integer>,Pair<String,Integer>> smear = new General.Smear<>(EMPTY);
//Aggregates<Pair<String,Integer>> smeared = renderer.transfer(pairs, smear);
final Transfer<Integer, Color> colorPopulation =
Seq.start(new General.ValuerTransfer<>(new MathValuers.Log<Integer>(10d), 0d))
.then(new General.Replace<>(Double.NEGATIVE_INFINITY, 0d, 0d))
.then(new Numbers.Interpolate<Double>(new Color(255,0,0,25), new Color(255,0,0,255)));
final General.MapWrapper<String, Color> color2012= new General.MapWrapper<>(results2012, Color.gray);
final General.MapWrapper<String, Color> color2008= new General.MapWrapper<>(results2008, Color.gray);
for (int seams=0; seams<viewBounds.width; seams+=step) {
System.out.println("Starting removing " + seams + " seams");
//Transfer.Specialized<Pair<String,Integer>, Pair<String,Integer>> carver = new SeamCarving.CarveIncremental<>(new DeltaPair(), Direction.V, EMPTY, seams);
Transfer.Specialized<Pair<String,Integer>, Pair<String,Integer>> carver = new SeamCarving.CarveSweep<>(new DeltaPair(), Direction.V, EMPTY, seams);
Aggregates<Pair<String,Integer>> carved = renderer.transfer(pairs, carver);
//carved = renderer.transfer(carved, new Borders(EMPTY));
CompositeWrapper<String,Integer, ?> composite = CompositeWrapper.convert(carved, "", 0);
Aggregates<Integer> carvedPop = composite.right();
Aggregates<String> carvedStates = composite.left();
Aggregates<Color> popImg = renderer.transfer(carvedPop, colorPopulation.specialize(carvedPop));
Aggregates<Color> states2012 = renderer.transfer(carvedStates, color2012);
Aggregates<Color> states2008 = renderer.transfer(carvedStates, color2008);
Util.writeImage(AggregateUtils.asImage(popImg), new File(String.format("./testResults/seams/%d-seams-population.png",seams)));
Util.writeImage(AggregateUtils.asImage(states2008), new File(String.format("./testResults/seams/%d-2008-seams-election.png",seams)));
Util.writeImage(AggregateUtils.asImage(states2012), new File(String.format("./testResults/seams/%d-2012-seams-election.png",seams)));
System.out.println("Completed export on " + seams + " seams\n");