X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=tim%2Fprune%2Ffunction%2Fsearch%2FSearchMapillaryFunction.java;fp=tim%2Fprune%2Ffunction%2Fsearch%2FSearchMapillaryFunction.java;h=32c58bd8898a93143e65ebfe7b375cfff632969d;hp=0000000000000000000000000000000000000000;hb=0a2480df5845e2d7190dfdec9b2653b1609e853d;hpb=2154b1969ac2995cca46546f217f53c066b0b749 diff --git a/tim/prune/function/search/SearchMapillaryFunction.java b/tim/prune/function/search/SearchMapillaryFunction.java new file mode 100644 index 0000000..32c58bd --- /dev/null +++ b/tim/prune/function/search/SearchMapillaryFunction.java @@ -0,0 +1,231 @@ +package tim.prune.function.search; + +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; + +import tim.prune.App; +import tim.prune.I18nManager; +import tim.prune.data.DataPoint; +import tim.prune.data.Distance; +import tim.prune.data.Field; +import tim.prune.data.Latitude; +import tim.prune.data.Longitude; +import tim.prune.data.SourceInfo; +import tim.prune.data.UnitSetLibrary; +import tim.prune.load.MediaLinkInfo; + +/** + * Function to search mapillary for photos + */ +public class SearchMapillaryFunction extends GenericDownloaderFunction +{ + /** Maximum number of results to get */ + private static final int MAX_RESULTS = 20; + + + /** + * Constructor + * @param inApp app object + */ + public SearchMapillaryFunction(App inApp) + { + super(inApp); + } + + @Override + public String getNameKey() { + return "function.mapillary"; + } + + @Override + protected String getColumnKey(int inColNum) + { + if (inColNum == 0) return "dialog.wikipedia.column.name"; + return "dialog.wikipedia.column.distance"; + } + + /** + * Run method, for searching 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 + double lat = 0.0, lon = 0.0; + DataPoint currentPoint = _app.getTrackInfo().getCurrentPoint(); + if (currentPoint == null) + { + double[] coords = _app.getViewport().getBounds(); + lat = (coords[0] + coords[2]) / 2.0; + lon = (coords[1] + coords[3]) / 2.0; + } + else + { + lat = currentPoint.getLatitude().getDouble(); + lon = currentPoint.getLongitude().getDouble(); + } + + // Construct URL + final String urlString = "http://api.mapillary.com/v1/im/close?lat=" + + lat + "&lon=" + lon + "&distance=1000&limit=" + MAX_RESULTS; + //System.out.println(urlString); + InputStream inStream = null; + try + { + inStream = new URL(urlString).openStream(); + StringBuilder sb = new StringBuilder(); + int ch = 0; + while ((ch = inStream.read()) >= 0) + { + sb.append((char) ch); + } + //System.out.println("Got answer: '" + sb.toString() + "'"); + + ArrayList resultList = new ArrayList(); + for (String result : sb.toString().split("\\},\\{")) + { + //System.out.println("Result: '" + result + "'"); + SearchResult sr = new SearchResult(); + for (String prop : result.split(",")) + { + String key = getKey(prop); + if (key == null) {continue;} + if (key.equals("key")) + { + final String value = getValue(prop); + sr.setDownloadLink("http://images.mapillary.com/" + value + "/thumb-1024.jpg"); + sr.setWebUrl("http://www.mapillary.com/map/im/" + value); + sr.setTrackName(value); + } + else if (key.equals("lat")) { + sr.setLatitude(getValue(prop)); + } + else if (key.equals("lon")) { + sr.setLongitude(getValue(prop)); + } + } + + if (sr.getLatitude() != null && sr.getLongitude() != null && sr.getTrackName() != null) + { + // Calculate distance away from current point and set this in sr.setLength + DataPoint resultPoint = new DataPoint(new Latitude(sr.getLatitude()), new Longitude(sr.getLongitude()), null); + if (resultPoint.isValid() && currentPoint != null && currentPoint.isValid()) + { + double radianDist = DataPoint.calculateRadiansBetween(currentPoint, resultPoint); + double metresAway = Distance.convertRadiansToDistance(radianDist, UnitSetLibrary.UNITS_METRES); + sr.setLength(metresAway); + } + + // If there's a valid result, add it to the temporary list + if (sr.getTrackName() != null) { + resultList.add(sr); + } + } + } + // Add all the results to the table model in one go + if (!resultList.isEmpty()) { + _trackListModel.addTracks(resultList); + } + } + catch (Exception e) { + _errorMessage = e.getClass().getName() + " - " + e.getMessage(); + } + // Close stream and ignore errors + try { + inStream.close(); + } catch (Exception e) {} + + // Set status label according to error or "none found", leave blank if ok + if (_errorMessage == null && _trackListModel.isEmpty()) { + _errorMessage = I18nManager.getText("dialog.mapillary.nonefound"); + } + _statusLabel.setText(_errorMessage == null ? "" : _errorMessage); + } + + /** + * From a JSON key:value string, return just the key + * @param inString string to parse + * @return just the key without the surrounding quotes, or null if not found + */ + private static String getKey(String inString) + { + if (inString == null || inString.equals("")) {return null;} + final int colonPos = inString.indexOf(':'); + if (colonPos <= 0) {return null;} + int startPos = 0; + char c; + while ((c = inString.charAt(startPos)) == '[' + || c == '{' || c == '\"') + { + startPos++; + } + int endPos = colonPos; + while ((c = inString.charAt(endPos-1)) == '\"') + { + endPos--; + } + return inString.substring(startPos, endPos); + } + + /** + * From a JSON key:value string, return just the value + * @param inString string to parse + * @return just the value without the surrounding quotes + */ + private static String getValue(String inString) + { + final int colonPos = inString.indexOf(':'); + if (colonPos <= 0 || colonPos >= inString.length()) {return null;} + int startPos = colonPos+1; + char c; + while ((c = inString.charAt(startPos)) == '\"') + { + startPos++; + } + int endPos = inString.length()-1; + while ((c = inString.charAt(endPos-1)) == '\"' + || c == '}' || c == ']') + { + endPos--; + } + return inString.substring(startPos, endPos); + } + + @Override + protected void loadSelected() + { + // Find the row(s) selected in the table and get the corresponding track + int numSelected = _trackTable.getSelectedRowCount(); + if (numSelected < 1) return; + int[] rowNums = _trackTable.getSelectedRows(); + + String[][] pointData = new String[numSelected][]; + String[] linkArray = new String[numSelected]; + + // Loop over each of the selected points + for (int i=0; i= 0 && rowNum < _trackListModel.getRowCount()) + { + SearchResult result = _trackListModel.getTrack(rowNum); + //String url = result.getDownloadLink(); + pointData[i][0] = result.getLatitude(); + pointData[i][1] = result.getLongitude(); + pointData[i][2] = "1"; // all points have a new segment + linkArray[i] = result.getDownloadLink(); + } + } + // Prepare the data for the app + final Field[] fields = {Field.LATITUDE, Field.LONGITUDE, Field.NEW_SEGMENT}; + _app.autoAppendNextFile(); + _app.informDataLoaded(fields, pointData, null, new SourceInfo("mapillary", SourceInfo.FILE_TYPE.JSON), + null, new MediaLinkInfo(linkArray)); + + // Close the dialog + _cancelled = true; + _dialog.dispose(); + } +}