Package ar.ext.server

Source Code of ar.ext.server.ARServer

package ar.ext.server;

import java.awt.Color;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ar.Aggregates;
import ar.Aggregator;
import ar.Renderer;
import ar.Selector;
import ar.Transfer;
import ar.ext.avro.AggregateSerializer;
import ar.ext.server.NanoHTTPD.Response.Status;
import ar.glyphsets.DynamicQuadTree;
import ar.glyphsets.MemMapList;
import ar.glyphsets.implicitgeometry.Indexed;
import ar.glyphsets.implicitgeometry.Indexed.Converter.TYPE;
import ar.glyphsets.implicitgeometry.MathValuers;
import ar.glyphsets.implicitgeometry.Valuer;
import ar.renderers.ParallelRenderer;
import ar.rules.Categories;
import ar.rules.Debug;
import ar.rules.General;
import ar.rules.Numbers;
import ar.rules.combinators.Seq;
import ar.selectors.TouchesPixel;
import ar.util.DelimitedReader;
import ar.util.Util;
import ar.Glyphset;



public class ARServer extends NanoHTTPD {
  public static Map<String, Transfer<?,?>> TRANSFERS = new HashMap<String,Transfer<?,?>>();
  public static Map<String, Aggregator<?,?>> AGGREGATORS = new HashMap<String,Aggregator<?,?>>();
  public static Map<String, Glyphset<?,?>> DATASETS = new HashMap<String, Glyphset<?,?>>();
 
  static {
    @SuppressWarnings({"rawtypes" })
    Glyphset circlepoints = Util.load(
        DynamicQuadTree.<Rectangle2D, Integer>make(),
        new DelimitedReader(new File( "../data/circlepoints.csv"), 1, DelimitedReader.CSV),
        new Indexed.Converter(TYPE.X, TYPE.X, TYPE.DOUBLE, TYPE.DOUBLE, TYPE.INT),
        new Indexed.ToRect(1, 2, 3),
        new Indexed.ToValue<>(4, new Valuer.ToInt<Object>()));
   
    @SuppressWarnings({"rawtypes"})
    Glyphset census = new MemMapList<>(
        new File("../data/2010Census_RaceTract.hbin"),
        new Indexed.ToPoint(true, 0, 1),
        new Valuer.CategoryCount<>(new Util.ComparableComparator<String>(), 3,2));
   
    DATASETS.put("CIRCLEPOINTS", circlepoints);
    DATASETS.put("CENSUS", census);
   
   
    TRANSFERS.put("RedWhiteLinear", new Numbers.Interpolate<>(new Color(255,0,0,38), Color.red));
    TRANSFERS.put("RedWhiteLog", new Seq<Number, Double, Color>(
                      new General.ValuerTransfer<>(new MathValuers.Log<Number>(10d, true), 0d),
                      new Numbers.Interpolate<Double>(new Color(255,0,0,38), Color.red, Color.white)));
    TRANSFERS.put("Alpha10", new Numbers.FixedInterpolate<>(Color.white, Color.red, 0, 25.5));
    TRANSFERS.put("AlphaMin", new Numbers.FixedInterpolate<>(Color.white, Color.red, 0, 255));
    TRANSFERS.put("Present", new General.Present<Integer,Color>(Color.red, Color.white));
    TRANSFERS.put("90Percent", new Categories.KeyPercent<Color>(.9, Color.blue, Color.white, Color.blue, Color.red));
    TRANSFERS.put("25Percent", new Categories.KeyPercent<Color>(.25, Color.blue, Color.white, Color.blue, Color.red));
    TRANSFERS.put("Echo", new General.Echo<Color>(Util.CLEAR));
    TRANSFERS.put("HDAlpha", new Categories.HighDefAlpha(Color.white, .1, false));
    TRANSFERS.put("HDAlphaLog", new Categories.HighDefAlpha(Color.white, .1, true));
    TRANSFERS.put("Gradient", new Debug.Gradient());
           
    AGGREGATORS.put("Blue",new General.Const<>(Color.BLUE));
    AGGREGATORS.put("First", new Categories.First());
    AGGREGATORS.put("Last", new General.Last<>(null));
    AGGREGATORS.put("Count", new Numbers.Count<Object>());
    AGGREGATORS.put("CoCColor", new Categories.CountCategories<Color>());
  }
 
  public ARServer(String hostname) {this(hostname, 8739);}
  public ARServer(String hostname, int port) {
    super(hostname, port);
  }

  @Override
  public Response serve(String uri, Method method,
      Map<String, String> headers,
      Map<String, String> parms,
      Map<String, String> files) {
   
    try {
      String datasetID = errorGet(parms, "data");
      String aggID = safeGet(parms, "aggregate", "count");
      String transferIDS = safeGet(parms, "transfers", "");
      String format = safeGet(parms, "format", "json");
      int width = Integer.parseInt(safeGet(parms, "width", "500"));
      int height = Integer.parseInt(safeGet(parms, "format", "500"));
      String viewTransTXT = safeGet(parms, "vt", null);
     
      if (!format.equals("json") && !format.equals("binary")) {throw new RuntimeException("Invalid return format: " + format);}
     
      Glyphset<?,?> dataset = loadData(datasetID);
      Aggregator<?,?> agg = getAgg(aggID);
      List<Transfer<?,?>> transfers = getTransfers(transferIDS);
      AffineTransform vt = viewTransform(viewTransTXT, dataset, width, height);
     
      Aggregates<?> aggs = execute(dataset, agg, transfers, vt, width, height);
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      AggregateSerializer.serialize(aggs, baos, AggregateSerializer.FORMAT.JSON);
      Response response = new Response(Status.OK, "avro/" + format, new String(baos.toByteArray(), "UTF-8"));
      return response;
    } catch (Exception e) {
      e.printStackTrace();
      return new Response(Status.ACCEPTED, MIME_PLAINTEXT, "Error:" + e.toString());
    }
  }

 
  /**Execute the passed aggregator and list of transfers.
   * This is inherently not statically type-safe, so it may produce type errors at runtime. 
   */
  @SuppressWarnings({ "rawtypes", "unchecked" })
  public Aggregates<?> execute(Glyphset<?,?> glyphs, Aggregator agg, List<Transfer<?,?>> transfers, AffineTransform view, int width, int height) {
    Renderer r = new ParallelRenderer();
    Selector s = TouchesPixel.make(glyphs);
    Aggregates aggs = r.aggregate(glyphs, s, agg, view, width, height);

    Transfer transfer;
    if (transfers.size() >= 2) {
      Seq t = new Seq(transfers.get(0), transfers.get(1));
      for (int i=2; i< transfers.size(); i++) {t.then(transfers.get(i));}
      transfer = t;
    } else {
      transfer = transfers.get(0);
    }
   
    Transfer.Specialized ts = transfer.specialize(aggs);
    Aggregates<?> rslt = r.transfer(aggs, ts);
    return rslt;
  }
 
  public AffineTransform viewTransform(String vtTXT, Glyphset<?,?> g, int width, int height) {
    if (vtTXT == null) {
      Rectangle2D bounds = g.bounds();
      return Util.zoomFit(bounds, width, height);
    } else {
      String[] parts = vtTXT.split(",");
      double sx = Double.parseDouble(parts[0]);
      double sy = Double.parseDouble(parts[1]);
      double tx = Double.parseDouble(parts[2]);
      double ty = Double.parseDouble(parts[3]);
      AffineTransform vt = new AffineTransform(sx,0,0,sy,tx,ty);
      return vt;
    }
  }
 
  public Glyphset<?,?> loadData(String id) {
    Glyphset<?,?> d = DATASETS.get(id.toUpperCase());
    if (d == null) {throw new RuntimeException("Dataset not found: " + id);}
    return d;
  }
 
  public Aggregator<?,?> getAgg(String aggID) {
    Aggregator<?,?> agg = AGGREGATORS.get(aggID);
    if (agg==null) {throw new RuntimeException("Aggregator not found: " + aggID);}
    return agg;
  }
 
  public List<Transfer<?,?>> getTransfers(String transfers) {
    String[] trans = transfers.split(";");
    List<Transfer<?,?>> ts = new ArrayList<Transfer<?,?>>(trans.length);
    for (String tID:trans) {
      Transfer<?,?> t = TRANSFERS.get(tID);
      if (t==null) {throw new RuntimeException("Transfer not found: " + tID);}
      ts.add(t);
    }
    return ts;
  }
 
  /**Get an item from the parameters dictionary.
   * If it is not present, return the default value.**/
  public String safeGet(Map<String,String> params, String key, String def) {
    String v = params.get(key);
    if (v != null) {return v;}
    return def;
  }
 

  /**Get an item from the parameters dictionary.
   * If it is not present, return an exception with the given error message.**/
  public String errorGet(Map<String,String> params, String key) {
    String v = params.get(key);
    if (v != null) {return v;}
    throw new RuntimeException(String.format("Entry not found '%s'", key));
  }

 
  /**@return Collection of known aggregator names**/
  public Collection<String> getAggregators() {return AGGREGATORS.keySet();}
 
  /**@return collection of known transfer names**/
  public Collection<String> getTransfers() {return TRANSFERS.keySet();}
 
  public static void main(String[] args) throws Exception {
    String host = ar.util.Util.argKey(args, "-host", "localhost");
    int port = Integer.parseInt(ar.util.Util.argKey(args, "-port", "8080"));
    ARServer server = new ARServer(host, port);
   
    server.start();
   
    System.out.printf("AR Server started on %s:%d", host, port);
    while (server.isAlive()) {synchronized(server) {server.wait(10000);;}}
  }
}
TOP

Related Classes of ar.ext.server.ARServer

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.