Package ar.ext.seamCarving

Source Code of ar.ext.seamCarving.Cartogram$DeltaPair

package ar.ext.seamCarving;

import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import ar.Aggregates;
import ar.Glyphset;
import ar.Renderer;
import ar.Transfer;
import ar.aggregates.AggregateUtils;
import ar.aggregates.wrappers.CompositeWrapper;
import ar.aggregates.wrappers.CompositeWrapper.Pair;
import ar.app.util.GeoJSONTools;
import ar.glyphsets.WrappedCollection;
import ar.glyphsets.implicitgeometry.MathValuers;
import ar.glyphsets.implicitgeometry.Shaper;
import ar.glyphsets.implicitgeometry.Valuer;
import ar.renderers.ParallelRenderer;
import ar.rules.CategoricalCounts;
import ar.rules.General;
import ar.rules.Numbers;
import ar.rules.SeamCarving;
import ar.rules.SeamCarving.Direction;
import ar.rules.combinators.Seq;
import ar.selectors.TouchesPixel;
import ar.util.Util;

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");
    }
  }
 
  public static final Color PARTY1 = Color.green;
  public static final Color PARTY2 = Color.pink;
  public static final String BOARDER = "BOARDER";
  public static Map<String, Color> results2008 = new HashMap<>();
  public static Map<String, Color> results2012 = new HashMap<>();
  static {
    File input = new File("../data/elections.csv");
    try (BufferedReader r = new BufferedReader(new FileReader(input))) {
      String line = r.readLine();
      while (line!=null) {
        String[] parts = line.split(",");
        results2012.put(parts[0], parts[1].equals("1") ? PARTY1 : PARTY2);
        results2008.put(parts[0], parts[2].equals("1") ? PARTY1 : PARTY2);
        line = r.readLine();
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
    results2012.put(BOARDER, Color.black);
    results2008.put(BOARDER, Color.black);
    System.out.println("Loaded results data.");
  }

  public static final Pair<String, Integer> EMPTY = new Pair<>("",0);
 
  public static final class DeltaPair implements SeamCarving.Delta<Pair<String, Integer>> {
    @Override
    public double delta(Pair<String, Integer> left, Pair<String, Integer> right) {
      return left.right - right.right;
    }
  }
 
  /**Strip off file extensions from keys (if present).**/
  public static final Map<String,Shape> simplifyKeys(Map<String,Shape> input) {
    Map<String, Shape> out =new HashMap<>();
    for (Map.Entry<String, Shape> e:input.entrySet()) {
      String simpleKey = e.getKey().split("\\.")[0];
      out.put(simpleKey, e.getValue());
    }
    return out;
  }
 
  public static final class Borders implements Transfer.ItemWise<Pair<String,Integer>, Pair<String,Integer>> {
    private final Pair<String,Integer> empty;
    public Borders(Pair<String,Integer> empty) {this.empty = empty;}
   
    @Override
    public Aggregates<Pair<String, Integer>> process(Aggregates<? extends Pair<String, Integer>> aggregates, Renderer rend) {
      return rend.transfer(aggregates, this);
    }

    @Override public Pair<String, Integer> emptyValue() {return empty;}

    @Override
    public ar.Transfer.Specialized<Pair<String, Integer>, Pair<String, Integer>> specialize(
        Aggregates<? extends Pair<String, Integer>> aggregates) {
      return this;
    }

    @Override
    public Pair<String, Integer> at(int x, int y, Aggregates<? extends Pair<String, Integer>> aggs) {
      String ref = state(aggs, x,y);
     
      String up = state(aggs,x,y+1);
      String down = state(aggs,x,y-1);
      String left = state(aggs,x-1,y);
      String right = state(aggs,x+1,y);
     
      Pair<String,Integer> v = aggs.get(x, y);
      if (ref.equals(up) && ref.equals(down) && ref.equals(left) && ref.equals(right)) {
        return v;
      } else {
        return new Pair<>(BOARDER,v.right);
      }
     
    }
   
    private static final String state(Aggregates<? extends Pair<String, Integer>> aggs, int x, int y) {return aggs.get(x,y).left;}
   
  }
}
TOP

Related Classes of ar.ext.seamCarving.Cartogram$DeltaPair

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.