1 package tim.prune.function;
3 import java.io.InputStream;
5 import java.util.ArrayList;
7 import javax.xml.parsers.SAXParser;
8 import javax.xml.parsers.SAXParserFactory;
11 import tim.prune.I18nManager;
12 import tim.prune.data.Coordinate;
13 import tim.prune.data.DataPoint;
14 import tim.prune.data.Distance;
15 import tim.prune.data.Field;
16 import tim.prune.data.Latitude;
17 import tim.prune.data.Longitude;
18 import tim.prune.function.search.GenericDownloaderFunction;
19 import tim.prune.function.search.SearchResult;
22 * Function to load nearby point information from OSM
24 public class SearchOsmPoisFunction extends GenericDownloaderFunction
26 /** Maximum distance from point in m */
27 private static final int MAX_DISTANCE = 250;
28 /** Coordinates to search for */
29 private double _searchLatitude = 0.0, _searchLongitude = 0.0;
34 * @param inApp App object
36 public SearchOsmPoisFunction(App inApp) {
43 public String getNameKey() {
44 return "function.searchosmpois";
48 * @param inColNum index of column, 0 or 1
49 * @return key for this column
51 protected String getColumnKey(int inColNum)
53 if (inColNum == 0) return "dialog.osmpois.column.name";
54 return "dialog.osmpois.column.type";
59 * Run method to get the nearby points in a separate thread
63 _statusLabel.setText(I18nManager.getText("confirm.running"));
64 // Get coordinates from current point (if any) or from centre of screen
65 DataPoint point = _app.getTrackInfo().getCurrentPoint();
68 double[] coords = _app.getViewport().getBounds();
69 _searchLatitude = (coords[0] + coords[2]) / 2.0;
70 _searchLongitude = (coords[1] + coords[3]) / 2.0;
74 _searchLatitude = point.getLatitude().getDouble();
75 _searchLongitude = point.getLongitude().getDouble();
78 // Submit search (language not an issue here)
79 submitSearch(_searchLatitude, _searchLongitude);
81 // Set status label according to error or "none found", leave blank if ok
82 if (_errorMessage == null && _trackListModel.isEmpty()) {
83 _errorMessage = I18nManager.getText("dialog.osmpois.nonefound");
85 _statusLabel.setText(_errorMessage == null ? "" : _errorMessage);
89 * Submit the search for the given parameters
90 * @param inLat latitude
91 * @param inLon longitude
93 private void submitSearch(double inLat, double inLon)
95 String coords = "around:" + MAX_DISTANCE + "," + inLat + "," + inLon;
96 String urlString = "http://overpass-api.de/api/interpreter?data=("
97 + "node(" + coords + ")[\"amenity\"][\"name\"];"
98 + "node(" + coords + ")[\"railway\"][\"name\"];"
99 + "node(" + coords + ")[\"highway\"][\"name\"];"
101 //System.out.println(urlString);
102 // Parse the returned XML with a special handler
103 SearchOsmPoisXmlHandler xmlHandler = new SearchOsmPoisXmlHandler();
104 InputStream inStream = null;
108 URL url = new URL(urlString);
109 SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
110 inStream = url.openStream();
111 saxParser.parse(inStream, xmlHandler);
113 catch (Exception e) {
114 _errorMessage = e.getClass().getName() + " - " + e.getMessage();
116 // Close stream and ignore errors
119 } catch (Exception e) {}
121 // Calculate distances for each returned point
122 DataPoint searchPoint = new DataPoint(new Latitude(_searchLatitude, Coordinate.FORMAT_DECIMAL_FORCE_POINT),
123 new Longitude(_searchLongitude, Coordinate.FORMAT_DECIMAL_FORCE_POINT), null);
124 for (SearchResult result : xmlHandler.getPointList())
126 Latitude pointLat = new Latitude(result.getLatitude());
127 Longitude pointLon = new Longitude(result.getLongitude());
128 DataPoint foundPoint = new DataPoint(pointLat, pointLon, null);
129 double dist = DataPoint.calculateRadiansBetween(searchPoint, foundPoint);
130 result.setLength(Distance.convertRadiansToDistance(dist));
133 // TODO: maybe limit number of results using MAX_RESULTS
134 // Add track list to model
135 ArrayList<SearchResult> pointList = xmlHandler.getPointList();
136 _trackListModel.addTracks(pointList, true);
137 _trackListModel.setShowPointTypes(true);
139 // Show error message if any
140 if (_trackListModel.isEmpty())
142 String error = xmlHandler.getErrorMessage();
143 if (error != null && !error.equals(""))
145 _app.showErrorMessageNoLookup(getNameKey(), error);
146 _errorMessage = error;
152 * Load the selected point(s)
154 protected void loadSelected()
156 // Find the rows selected in the table and get the corresponding coords
157 int numSelected = _trackTable.getSelectedRowCount();
158 if (numSelected < 1) return;
159 int[] rowNums = _trackTable.getSelectedRows();
160 for (int i=0; i<numSelected; i++)
162 int rowNum = rowNums[i];
163 if (rowNum >= 0 && rowNum < _trackListModel.getRowCount())
165 String lat = _trackListModel.getTrack(rowNum).getLatitude();
166 String lon = _trackListModel.getTrack(rowNum).getLongitude();
167 if (lat != null && lon != null)
169 DataPoint point = new DataPoint(new Latitude(lat), new Longitude(lon), null);
170 point.setFieldValue(Field.WAYPT_NAME, _trackListModel.getTrack(rowNum).getTrackName(), false);
171 _app.createPoint(point);