package it.unito.geosummly.api.cli; import fi.foyt.foursquare.api.FoursquareApiException; import it.unito.geosummly.DynamicReader; import it.unito.geosummly.SamplingOperator; import it.unito.geosummly.tools.CoordinatesNormalizationType; import java.io.IOException; import java.util.ArrayList; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.OptionGroup; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.json.JSONException; /** * @author James * * API for sampling state */ public class Sampling { private String inFile=null; private String outDir=null; private ArrayList<Double> coordinates=new ArrayList<Double>(); private int gridCells=20; private int randomCells=-1; private long sleepMs=0; private CoordinatesNormalizationType coordType=CoordinatesNormalizationType.NORM; private boolean secondLevel=false; //private String socNet="foursquare"; public void run (String[] args) { Options options= initOptions(); //define list of options CommandLineParser parser=new PosixParser(); //create the command line parser HelpFormatter formatter = new HelpFormatter(); Boolean mandatory=false; //check the presence of mandatory options Boolean inputFlag=false; //check the presence either of input or coord; String helpUsage="geosummly sampling -input <path/to/file.geojson>|<path/to/file.cixtyjson> -output <path/to/dir> [options]" +"geosummly sampling -coord north,east,south,west -output <path/to/dir> -gnum 40 -rnum 100 [options]" +"geosummly sampling -social 3cixty -city <city> -publisher <publisher> []"; String helpFooter="\n------------------------------------------------------------------" + "\nThe options coord, input (only if coord is not specified), dynamic (without coord and input), output are mandatory." + "\nThe options input and coord are mutually exclusive." + "\nThe options input and gnum are mutually exclusive." + "\nThe options input and rnum are mutually exclusive. " + "\nThe options input and social are mutually exclusive." + "\nThe output consist of a file of single venues for " + "each of the two levels of the Foursquare categories taxonomy, " + "a log file with the sampling informations." + "\n------------------------------------------------------------------" + "\nExamples:" + "\n1. geosummly sampling -input path/to/file.geojson -output path/to/dir -sleep 730 -ctype missing" + "\n2. geosummly sampling -coord 45.01,8.3,44.0,7.2856 -output path/to/dir -gnum 40 -rnum 100" + "\n3. geosummly sampling -social 3cixty -city <city> -publisher <publisher> [options]"; try { CommandLine line = parser.parse(options, args); if(line.hasOption("input") && line.hasOption("output")) { inFile=line.getOptionValue("input"); //file extension has to be geojson or cixtyjson if(!inFile.endsWith("geojson")) { if(!inFile.endsWith("cixtyjson")) { //add 3cixty data to input formatter.printHelp(helpUsage, "\ncommands list:", options, helpFooter); System.exit(-1); } } outDir=line.getOptionValue("output"); mandatory=true; inputFlag=true; } if(line.hasOption("coord") && line.hasOption("output")) { String[] c=line.getOptionValues("coord"); for(String s: c) coordinates.add(Double.parseDouble(s)); outDir=line.getOptionValue("output"); if(line.hasOption("gnum")) { gridCells=Integer.parseInt(line.getOptionValue("gnum")); if(gridCells<0) { formatter.printHelp(helpUsage, "\ncommands list:", options, helpFooter); System.exit(-1); } } if(line.hasOption("rnum")) { randomCells=Integer.parseInt(line.getOptionValue("rnum")); if(randomCells<0) { formatter.printHelp(helpUsage, "\ncommands list:", options, helpFooter); System.exit(-1); } } mandatory=true; inputFlag=false; } if(line.hasOption("ltype")) { String l=line.getOptionValue("ltype"); if(l.equals("norm")) coordType=CoordinatesNormalizationType.NORM; else if(l.equals("notnorm")) coordType=CoordinatesNormalizationType.NOTNORM; else if(l.equals("missing")) coordType=CoordinatesNormalizationType.MISSING; else { formatter.printHelp(helpUsage, "\ncommands list:", options, helpFooter); System.exit(-1); } } //Handle other social media data, so far we support 3cixty if(line.hasOption("social") && line.hasOption("output")) { String social = line.getOptionValue("social"); //Supported social media, so far we support 3cixty if(social.equals("3cixty")) { if(line.hasOption("city") && line.hasOption("publisher")) { String city = line.getOptionValue("city"); String publisher = line.getOptionValue("publisher"); DynamicReader dynamicReader = new DynamicReader(); //Dynamic read data from online database, using sparql outDir = line.getOptionValue("output"); inFile = dynamicReader.Cixty_Query(city, publisher, outDir); inputFlag = true; mandatory=true; } else{ formatter.printHelp(helpUsage, "\ncommands list:", options, helpFooter); System.exit(-1); } } //manage social media } /* if(line.hasOption("cache")) { //manage cache }*/ if(line.hasOption("sleep")) { sleepMs=Long.parseLong(line.getOptionValue("sleep")); if(sleepMs<0) { formatter.printHelp(helpUsage, "\ncommands list:", options, helpFooter); System.exit(-1); } } if(line.hasOption("taxonomy")) { String result = line.getOptionValue("taxonomy").toLowerCase(); if(result.equals("2")) secondLevel = true; if(!result.equals("2") && !result.equals("1")) { formatter.printHelp(helpUsage,"\ncommands list:", options, helpFooter); System.exit(-1); } } if (line.hasOption("help") || !mandatory) { formatter.printHelp(helpUsage,"\ncommands list:", options, helpFooter); System.exit(-1); } SamplingOperator so=new SamplingOperator(); if(inputFlag) so.executeWithInput(inFile, outDir, coordType, sleepMs, secondLevel, gridCells); else so.executeWithCoord(coordinates, outDir, gridCells, randomCells, coordType, sleepMs, secondLevel); } catch(ParseException | NumberFormatException | FoursquareApiException | IOException | JSONException | InterruptedException e) { System.out.println("Unexpected exception: " + e.getMessage()); } } @SuppressWarnings("static-access") private Options initOptions() { Options options = new Options(); //define list of options //option input Option input=OptionBuilder.withLongOpt("input").withDescription("set the input file") .hasArg().withArgName("path/to/file").create("I"); //options input and coord and social have to be mutually exclusive, for now OptionGroup g1=new OptionGroup(); g1.addOption(input); g1.addOption(OptionBuilder.withLongOpt("coord").withDescription("set the input grid coordinates") .hasArgs(4).withValueSeparator(',').withArgName("n,e,s,w").create("L")); g1.addOption(OptionBuilder.withLongOpt("social").withDescription("set the social network for meta-data collection. So far foursquare and 3cixty is activable. Default fourquare") .hasArg().withArgName("arg").create("s")); //options input and gnum have to be mutually exclusive OptionGroup g2=new OptionGroup(); g2.addOption(input); g2.addOption(OptionBuilder.withLongOpt("gnum").withDescription("set the number of cells of a side of the squared grid. Default 20") .hasArg().withArgName("arg").create("g")); //options input and rnum have to be mutually exclusive OptionGroup g3=new OptionGroup(); g3.addOption(input); g3.addOption(OptionBuilder.withLongOpt("rnum").withDescription("set the number of cells, taken randomly, chosen for the sampling") .hasArg().withArgName("arg").create("r")); //add mutually exclusive options for sampling options.addOptionGroup(g1); options.addOptionGroup(g2); options.addOptionGroup(g3); //add all other options for sampling options.addOption(OptionBuilder.withLongOpt("gnum").withDescription("set the number of cells of a side of the squared grid. Default 20") .hasArg().withArgName("arg").create("g")); options.addOption(OptionBuilder.withLongOpt( "output" ).withDescription("set the output directory") .hasArg().withArgName("path/to/dir").create("O")); options.addOption(OptionBuilder.withLongOpt( "ltype" ).withDescription("set the type of coordinates (latitude and longitude) normalization. Allowed values: norm, notnorm, missing. Default norm") .hasArg().withArgName("arg").create("l")); options.addOption(OptionBuilder.withLongOpt("city").withDescription("set the city from social network for meta-data collection.") .hasArg().withArgName("arg").create("c")); options.addOption(OptionBuilder.withLongOpt("publisher").withDescription("set the publisher from social network for meta-data collection.") .hasArg().withArgName("arg").create("p")); options.addOption(OptionBuilder.withLongOpt( "sleep" ).withDescription("set the milliseconds between two calls to social media server. Default 0") .hasArg().withArgName("arg").create("z")); options.addOption(OptionBuilder.withLongOpt("taxonomy").withDescription("set the level to reach on the " + "Foursquare category hierarchy. " + "Allowed values: 1, 2. Default 1").hasArg().withArgName("arg").create("t")); options.addOption("C", "cache", false, "cache activation. Default deactivated"); //more options options.addOption("H", "help", false, "print the command list"); return options; } }