package edu.cmu.test.gui; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.HashSet; import java.util.List; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.SwingUtilities; import javax.swing.UIManager; import twitter4j.Status; import twitter4j.TwitterException; import twitter4j.json.DataObjectFactory; import edu.cmu.geolocator.GlobalParam; import edu.cmu.geolocator.Tag; import edu.cmu.geolocator.coder.CoderFactory; import edu.cmu.geolocator.io.GetReader; import edu.cmu.geolocator.io.GetWriter; import edu.cmu.geolocator.model.CandidateAndFeature; import edu.cmu.geolocator.model.LocEntityAnnotation; import edu.cmu.geolocator.model.LocGroupFeatures; import edu.cmu.geolocator.model.Tweet; import edu.cmu.geolocator.parser.ParserFactory; public class NewDesktop extends JPanel implements ActionListener, ItemListener { public static String newline = "\n"; public static String copyright = "© 2012-2014 CMU LTI All Right Reserved"; public static String desc = "CMU GeoLocator v3.0" + newline + newline + "Function: geoparsing and geocoding tweets." + newline + "Input: tweet JSON file, one tweet JSON per line" + newline + "Output: An line-aligned file corresponding to input file. " + newline + "Each line contains the recognized locations extracted from corresponding line in input file." + newline + " Output format is:" + newline + "[location] /whitespace ...[location] /tab [location coordinates]...whitespace... [location coordinates]" + newline + newline + "How to use: " + newline + "1.Open a file by pressing Open, " + newline + "2.Choose save file by pressing Save, " + newline + "3.Choose the gazetteer index that is created (that you created with indexer.jar). " + newline + "4.click run to tag the data." + newline + "The progress will be shown on console"; JButton openButton, saveButton, runButton, palseButton, resumeButton, openIndexButton; JCheckBox tpButton, bdButton, stButton, abButton; JTextArea log; JFileChooser fc; File inputfile, outputfile, indexfile; BufferedWriter bw; BufferedReader br; int linecount = 0; HashMap<String, Boolean> tagFilter; public NewDesktop() { super(new BorderLayout()); // Create the log first, because the action listeners // need to refer to it. log = new JTextArea(5, 20); log.setMargin(new Insets(5, 5, 5, 5)); log.setEditable(false); log.append(desc + newline + newline + copyright + newline + newline); // initilize the tag Filter here tagFilter = new HashMap<String, Boolean>(); tagFilter.put("tp", true); tagFilter.put("bd", true); tagFilter.put("st", true); tagFilter.put("ab", true); JScrollPane logScrollPane = new JScrollPane(log); // Create a file chooser fc = new JFileChooser(); openButton = new JButton("Step 1:\nOpen a JSON tweet File..."); openButton.addActionListener(this); saveButton = new JButton("Step 2:\nChoose save file path..."); saveButton.addActionListener(this); openIndexButton = new JButton("Step 3:\nOpen the Gazetteer Index ..."); openIndexButton.addActionListener(this); runButton = new JButton("Step 5:\nRun"); runButton.addActionListener(this); // create checkbox to select the output result type // Create the check boxes. tpButton = new JCheckBox("toponym"); tpButton.setMnemonic(KeyEvent.VK_T); tpButton.setSelected(true); tpButton.addItemListener(this); bdButton = new JCheckBox("building"); bdButton.setMnemonic(KeyEvent.VK_B); bdButton.setSelected(true); bdButton.addItemListener(this); stButton = new JCheckBox("street"); stButton.setMnemonic(KeyEvent.VK_S); stButton.setSelected(true); stButton.addItemListener(this); abButton = new JCheckBox("abbreviation"); abButton.setMnemonic(KeyEvent.VK_A); abButton.setSelected(true); abButton.addItemListener(this); // For layout purposes, put the buttons in a separate panel JPanel checkPanel = new JPanel(new GridLayout(0, 1)); checkPanel.add(tpButton); checkPanel.add(bdButton); checkPanel.add(stButton); checkPanel.add(abButton); JPanel buttonPanel = new JPanel(new GridLayout(1, 0)); // use FlowLayout buttonPanel.add(openButton); buttonPanel.add(saveButton); buttonPanel.add(openIndexButton); buttonPanel.add(new JTextArea("Step 4:\nChoose output location types:")); buttonPanel.add(checkPanel); buttonPanel.add(runButton); // Add the buttons and the log to this panel. add(buttonPanel, BorderLayout.PAGE_START); add(logScrollPane, BorderLayout.CENTER); // Add the initialization of geolocator } /** * Fill out the tag filter based on the radio selection * * @param e */ @Override public void itemStateChanged(ItemEvent e) { Object source = e.getItemSelectable(); if (e.getStateChange() == ItemEvent.SELECTED) { if (source == tpButton) { tagFilter.put("tp", true); } else if (source == bdButton) { tagFilter.put("bd", true); } else if (source == stButton) { tagFilter.put("st", true); } else if (source == abButton) { tagFilter.put("ab", true); } } else if (e.getStateChange() == ItemEvent.DESELECTED) { if (source == tpButton) { tagFilter.put("tp", false); } else if (source == bdButton) { tagFilter.put("bd", false); } else if (source == stButton) { tagFilter.put("st", false); } else if (source == abButton) { tagFilter.put("ab", false); } } log.append(tagFilter.toString()); } @Override public void actionPerformed(ActionEvent e) { // Handle open button action. if (e.getSource() == this.openButton) { fc.setFileSelectionMode(JFileChooser.FILES_ONLY); int returnVal = fc.showOpenDialog(NewDesktop.this); if (returnVal == JFileChooser.APPROVE_OPTION) { inputfile = fc.getSelectedFile(); linecount = 0; // This is where a real application would open the file. log.append("Opening: " + inputfile.getName() + "." + newline); } else { log.append("Open command cancelled by user." + newline); } log.setCaretPosition(log.getDocument().getLength()); // Handle save button action. } else if (e.getSource() == saveButton) { fc.setFileSelectionMode(JFileChooser.FILES_ONLY); int returnVal = fc.showSaveDialog(NewDesktop.this); if (returnVal == JFileChooser.APPROVE_OPTION) { outputfile = fc.getSelectedFile(); linecount = 0; // This is where a real application would save the file. log.append("Saving: " + outputfile.getName() + "." + newline); } else { log.append("Save command cancelled by user." + newline); } log.setCaretPosition(log.getDocument().getLength()); } else if (e.getSource() == openIndexButton) { fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); int returnVal = fc.showOpenDialog(NewDesktop.this); if (returnVal == JFileChooser.APPROVE_OPTION) { indexfile = fc.getSelectedFile(); // This is where a real application would save the file. log.append("Opening Index: " + indexfile.getName() + "." + newline); } else { log.append("Save command cancelled by user." + newline); } log.setCaretPosition(log.getDocument().getLength()); // set the index file path to indexfile. GlobalParam.setGazIndex(indexfile.getPath()); } else if (e.getSource() == runButton) { try { run(); log.setCaretPosition(log.getDocument().getLength()); } catch (IOException e1) { System.err.println("Runnning Error occured."); } } } private void run() throws IOException { HashSet<String> filter = Tag.getFilter(tagFilter); System.out.println("Run output:" + inputfile.getAbsolutePath()); System.out.println("Run output:" + outputfile.getAbsolutePath()); try { br = GetReader.getUTF8FileReader(inputfile.getAbsolutePath()); } catch (FileNotFoundException e1) { System.err.println("Input file not found."); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } String path = outputfile.getAbsolutePath(); try { bw = GetWriter.getFileWriter(path); } catch (IOException e1) { System.err.println("Output file not found."); } String line = null; Status status; while ((line = br.readLine()) != null) { bw.write(linecount); linecount++; System.out.println("Running tweet line " + linecount); status = null; // create Tweet Status from the JSON file. Status is the structure containing all the // information in tweet. try { status = DataObjectFactory.createStatus(line); } catch (TwitterException e) { // TODO Auto-generated catch block log.append("[ERROR] Tweet JSON Parse Error in input file, line " + linecount); continue; } if (status == null) continue; // create the tweet object from the status. Tweet tweet = new Tweet(status); log.append("\n////////////////// Line " + linecount + " //////////////////\n"); log.append("\n[Tweet message]: " + tweet.getText()); log.append("\n[Tweet coordinates]: " + tweet.getLatitude() + " " + tweet.getLongitude()); log.append("\n[Tweet user location]:" + tweet.getUserLocation()); log.append("\n[Tweet place field]:" + tweet.getPlace()); log.append("\n[GEOPARSING...] "); List<LocEntityAnnotation> topos = ParserFactory.getEnAggrParser().parse(tweet); tweet.setToponyms(topos); for (LocEntityAnnotation topo : topos) { if (filter.contains(topo.getNEType())) { log.append("\n[Recognized]: " + topo.getTokenString() + " [Place type]: " + topo.getNEType()); bw.write("[LOCATION=" + topo.getTokenString() + " ENTITY_TYPE=" + topo.getNEType() + "]"); } } bw.write("\t"); List<CandidateAndFeature> resolved = null; if (topos == null) log.append("\nNO TOPONYMS PARSED."); else { log.append("\n[GEOCODING...]"); try { resolved = CoderFactory.getENAggGeoCoder().resolve(tweet, LocGroupFeatures.DEBUGMODE, LocGroupFeatures.NOFILTER); } catch (Exception e) { log.append("\nLocation Resolution error"); } if (resolved == null) log.append("\n[No location resolved.]"); else { log.append("\n[Rresolved locations]:"); // Note that we could output multiple results for one location. // This is for the user to decide which is the best they want. // We may improve this later to output only one result. for (CandidateAndFeature c : resolved) { if (filter.contains(c.getLe().getNEType())) { log.append(c.getAsciiName() + " Country:" + c.getCountryCode() + " State:" + c.getAdm1Code() + " Latitude:" + c.getLatitude() + " Longitude:" + c.getLongitude()); bw.write("[LOCATION=" + c.getAsciiName() + " COUNTRY_CODE=" + c.getCountryCode() + " STATE_CODE=" + c.getAdm1Code() + " LATITUDE=" + c.getLatitude() + " LONGITUDE=" + c.getLongitude() + " PROBABILITY:" + c.getProb() + "]"); } } } } bw.write("\n"); } bw.close(); } private static void createAndShowGUI() { // Create and set up the window. JFrame frame = new JFrame("CMU GeoLocator version 3.0 Running Helper"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Dimension minimumSize = new Dimension(); minimumSize.setSize(1000, 1000); frame.setMinimumSize(minimumSize); // Add content to the window. frame.add(new NewDesktop()); // Display the window. frame.pack(); frame.setVisible(true); } public static void main(String[] args) { // Schedule a job for the event dispatch thread: // creating and showing this application's GUI. SwingUtilities.invokeLater(new Runnable() { public void run() { // Turn off metal's use of bold fonts UIManager.put("swing.boldMetal", Boolean.FALSE); createAndShowGUI(); } }); } }