1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
package tim.prune.function.search;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import tim.prune.App;
import tim.prune.I18nManager;
import tim.prune.data.DataPoint;
import tim.prune.data.Distance;
import tim.prune.data.Latitude;
import tim.prune.data.Longitude;
import tim.prune.data.Unit;
/**
* Function to load nearby point information from OSM
*/
public class SearchOsmPoisFunction extends GenericDownloaderFunction
{
/** Maximum distance from point in m */
private static final int MAX_DISTANCE = 250;
/** Coordinates to search for */
private double _searchLatitude = 0.0, _searchLongitude = 0.0;
/**
* Constructor
* @param inApp App object
*/
public SearchOsmPoisFunction(App inApp) {
super(inApp);
}
/**
* @return name key
*/
public String getNameKey() {
return "function.searchosmpois";
}
/**
* @param inColNum index of column, 0 or 1
* @return key for this column
*/
protected String getColumnKey(int inColNum)
{
if (inColNum == 0) return "dialog.osmpois.column.name";
return "dialog.osmpois.column.type";
}
/**
* Run method to get the nearby points in a separate thread
*/
public void run()
{
_statusLabel.setText(I18nManager.getText("confirm.running"));
// Get coordinates from current point (if any) or from centre of screen
DataPoint point = _app.getTrackInfo().getCurrentPoint();
if (point == null)
{
_searchLatitude = _app.getViewport().getCentreLatitude();
_searchLongitude = _app.getViewport().getCentreLongitude();
}
else
{
_searchLatitude = point.getLatitude().getDouble();
_searchLongitude = point.getLongitude().getDouble();
}
// Submit search (language not an issue here)
submitSearch(_searchLatitude, _searchLongitude);
// Set status label according to error or "none found", leave blank if ok
if (_errorMessage == null && _trackListModel.isEmpty()) {
_errorMessage = I18nManager.getText("dialog.osmpois.nonefound");
}
_statusLabel.setText(_errorMessage == null ? "" : _errorMessage);
finishedSearch();
}
/**
* Submit the search for the given parameters
* @param inLat latitude
* @param inLon longitude
*/
private void submitSearch(double inLat, double inLon)
{
String coords = "around:" + MAX_DISTANCE + "," + inLat + "," + inLon;
String urlString = "http://overpass-api.de/api/interpreter?data=("
+ "node(" + coords + ")[\"amenity\"][\"name\"];"
+ "node(" + coords + ")[\"railway\"][\"name\"];"
+ "node(" + coords + ")[\"highway\"][\"name\"];"
+ ");out%20qt;";
//System.out.println(urlString);
// Parse the returned XML with a special handler
SearchOsmPoisXmlHandler xmlHandler = new SearchOsmPoisXmlHandler();
try
{
URL url = new URL(urlString);
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
try (InputStream inStream = url.openStream()) {
saxParser.parse(inStream, xmlHandler);
} catch (Exception e) {
_errorMessage = e.getClass().getName() + " - " + e.getMessage();
}
} catch (MalformedURLException | SAXException | ParserConfigurationException ignored) {
}
// Calculate distances for each returned point
DataPoint searchPoint = new DataPoint(Latitude.make(_searchLatitude),
Longitude.make(_searchLongitude));
Unit distUnit = getConfig().getUnitSet().getDistanceUnit();
for (SearchResult result : xmlHandler.getPointList())
{
DataPoint foundPoint = new DataPoint(Latitude.make(result.getLatitude()),
Longitude.make(result.getLongitude()));
double dist = DataPoint.calculateRadiansBetween(searchPoint, foundPoint);
result.setLength(Distance.convertRadiansToDistance(dist, distUnit));
}
// TODO: maybe limit number of results using MAX_RESULTS
// Add track list to model
ArrayList<SearchResult> pointList = xmlHandler.getPointList();
_trackListModel.addTracks(pointList, true);
_trackListModel.setShowPointTypes(true);
}
}
|