diff --git a/app/src/main/java/fr/free/nrw/commons/Media.java b/app/src/main/java/fr/free/nrw/commons/Media.java index 924427cef..f8f90896a 100644 --- a/app/src/main/java/fr/free/nrw/commons/Media.java +++ b/app/src/main/java/fr/free/nrw/commons/Media.java @@ -144,6 +144,14 @@ public class Media implements Parcelable { this.license = license; } + public String getCoordinates() { + return coordinates; + } + + public void setCoordinates(String coordinates) { + this.coordinates = coordinates; + } + // Primary metadata fields protected Uri localUri; protected String imageUrl; @@ -155,6 +163,7 @@ public class Media implements Parcelable { protected int width; protected int height; protected String license; + private String coordinates; protected String creator; protected ArrayList categories; // as loaded at runtime? protected Map descriptions; // multilingual descriptions as loaded diff --git a/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java b/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java index 630cfeaff..344546c7a 100644 --- a/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java +++ b/app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java @@ -1,5 +1,7 @@ package fr.free.nrw.commons; +import fr.free.nrw.commons.location.LatLng; + import org.mediawiki.api.ApiResult; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -38,6 +40,7 @@ public class MediaDataExtractor { private String author; private Date date; private String license; + private String coordinates; private LicenseList licenseList; /** @@ -122,6 +125,14 @@ public class MediaDataExtractor { author = getFlatText(authorNode); } + Node coordinateTemplateNode = findTemplate(doc.getDocumentElement(), "location"); + + if (coordinateTemplateNode != null) { + coordinates = getCoordinates(coordinateTemplateNode); + } else { + coordinates = "No coordinates found"; + } + /* Pull up the license data list... look for the templates in two ways: @@ -242,6 +253,25 @@ public class MediaDataExtractor { return parentNode.getTextContent(); } + /** + * Extracts the coordinates from the template and returns them as pretty formatted string. + * Loops over the children of the coordinate template: + * {{Location|47.50111007666667|19.055700301944444}} + * and extracts the latitude and longitude as a pretty string. + * + * @param parentNode The node of the coordinates template. + * @return Pretty formatted coordinates. + * @throws IOException Parsing failed. + */ + private String getCoordinates(Node parentNode) throws IOException { + NodeList childNodes = parentNode.getChildNodes(); + double latitudeText = Double.parseDouble(childNodes.item(1).getTextContent()); + double longitudeText = Double.parseDouble(childNodes.item(2).getTextContent()); + LatLng coordinates = new LatLng(latitudeText, longitudeText); + + return coordinates.getPrettyCoordinateString(); + } + // Extract a dictionary of multilingual texts from a subset of the parse tree. // Texts are wrapped in things like {{en|foo} or {{en|1=foo bar}}. // Text outside those wrappers is stuffed into a 'default' faux language key if present. @@ -287,6 +317,7 @@ public class MediaDataExtractor { media.setCategories(categories); media.setDescriptions(descriptions); + media.setCoordinates(coordinates); if (license != null) { media.setLicense(license); } diff --git a/app/src/main/java/fr/free/nrw/commons/location/LatLng.java b/app/src/main/java/fr/free/nrw/commons/location/LatLng.java index 839cba14e..47d112991 100644 --- a/app/src/main/java/fr/free/nrw/commons/location/LatLng.java +++ b/app/src/main/java/fr/free/nrw/commons/location/LatLng.java @@ -42,4 +42,52 @@ public class LatLng { public String toString() { return "lat/lng: (" + this.latitude + "," + this.longitude + ")"; } + + /** + * Rounds the float to 4 digits. + * + * @param coordinate A coordinate value as string. + * @return String of the rounded number. + */ + private String formatCoordinate(double coordinate) { + double roundedNumber = Math.round(coordinate * 10000d) / 10000d; + return String.valueOf(roundedNumber); + } + + /** + * Returns "N" or "S" depending on the latitude. + * + * @return "N" or "S". + */ + private String getNorthSouth() { + if (this.latitude < 0) { + return "S"; + } + + return "N"; + } + + /** + * Returns "E" or "W" depending on the longitude. + * + * @return "E" or "W". + */ + private String getEastWest() { + if (this.longitude < 180) { + return "E"; + } + + return "W"; + } + + /** + * Returns a nicely formatted coordinate string. Used e.g. in + * the detail view. + * + * @return The formatted string. + */ + public String getPrettyCoordinateString() { + return formatCoordinate(this.latitude) + " " + this.getNorthSouth() + ", " + + formatCoordinate(this.longitude) + " " + this.getEastWest(); + } } diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java index befc3f9cf..b32d83a31 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java @@ -70,6 +70,7 @@ public class MediaDetailFragment extends Fragment { private TextView title; private TextView desc; private TextView license; + private TextView coordinates; private LinearLayout categoryContainer; private ScrollView scrollView; private ArrayList categoryNames; @@ -123,6 +124,7 @@ public class MediaDetailFragment extends Fragment { title = (TextView) view.findViewById(R.id.mediaDetailTitle); desc = (TextView) view.findViewById(R.id.mediaDetailDesc); license = (TextView) view.findViewById(R.id.mediaDetailLicense); + coordinates = (TextView) view.findViewById(R.id.mediaDetailCoordinates); categoryContainer = (LinearLayout) view.findViewById(R.id.mediaDetailCategoryContainer); licenseList = new LicenseList(getActivity()); @@ -226,6 +228,7 @@ public class MediaDetailFragment extends Fragment { // Set text of desc, license, and categories desc.setText(prettyDescription(media)); license.setText(prettyLicense(media)); + coordinates.setText(prettyCoordinates(media)); categoryNames.removeAll(categoryNames); categoryNames.addAll(media.getCategories()); @@ -388,4 +391,15 @@ public class MediaDetailFragment extends Fragment { return licenseObj.getName(); } } + + /** + * Returns the coordinates nicely formatted. + * + * @return Coordinates as text. + */ + private String prettyCoordinates(Media media) { + String coordinates = media.getCoordinates(); + + return coordinates; + } } diff --git a/app/src/main/res/layout/fragment_media_detail.xml b/app/src/main/res/layout/fragment_media_detail.xml index db03bccba..279957270 100644 --- a/app/src/main/res/layout/fragment_media_detail.xml +++ b/app/src/main/res/layout/fragment_media_detail.xml @@ -159,6 +159,35 @@ /> + + + + +