2 * Copyright 2008 ZXing authors
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.google.zxing.client.result;
19 import com.google.zxing.Result;
22 * Represents a "geo:" URI result, which specifices a location on the surface of
23 * the Earth as well as an optional altitude above the surface. See
24 * <a href="http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00">
25 * http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00</a>.
27 * @author srowen@google.com (Sean Owen)
29 public final class GeoParsedResult extends ParsedReaderResult {
31 private final String geoURI;
32 private final float latitude;
33 private final float longitude;
34 private final float altitude;
36 private GeoParsedResult(String geoURI, float latitude, float longitude, float altitude) {
37 super(ParsedReaderResultType.GEO);
39 this.latitude = latitude;
40 this.longitude = longitude;
41 this.altitude = altitude;
44 public static GeoParsedResult parse(Result result) {
45 String rawText = result.getText();
46 if (rawText == null || !rawText.startsWith("geo:")) {
49 // Drop geo, query portion
50 int queryStart = rawText.indexOf('?', 4);
51 String geoURIWithoutQuery;
53 geoURIWithoutQuery = rawText.substring(4);
55 geoURIWithoutQuery = rawText.substring(4, queryStart);
57 int latitudeEnd = geoURIWithoutQuery.indexOf(',');
58 if (latitudeEnd < 0) {
61 float latitude = Float.parseFloat(geoURIWithoutQuery.substring(0, latitudeEnd));
62 int longitudeEnd = geoURIWithoutQuery.indexOf(',', latitudeEnd + 1);
64 float altitude; // in meters
65 if (longitudeEnd < 0) {
66 longitude = Float.parseFloat(geoURIWithoutQuery.substring(latitudeEnd + 1));
69 longitude = Float.parseFloat(geoURIWithoutQuery.substring(latitudeEnd + 1, longitudeEnd));
70 altitude = Float.parseFloat(geoURIWithoutQuery.substring(longitudeEnd + 1));
72 return new GeoParsedResult(rawText, latitude, longitude, altitude);
75 public String getGeoURI() {
80 * @return latitude in degrees
82 public float getLatitude() {
87 * @return longitude in degrees
89 public float getLongitude() {
94 * @return altitude in meters. If not specified, in the geo URI, returns 0.0
96 public float getAltitude() {
100 public String getDisplayResult() {
101 StringBuffer result = new StringBuffer(50);
102 result.append(latitude);
103 result.append(" deg N, ");
104 result.append(longitude);
105 result.append(" deg E");
106 if (altitude > 0.0f) {
108 result.append(altitude);
111 return result.toString();
115 * @return a URI link to Google Maps which display the point on the Earth described
116 * by this instance, and sets the zoom level in a way that roughly reflects the
117 * altitude, if specified
120 public String getGoogleMapsURI() {
121 StringBuffer result = new StringBuffer(50);
122 result.append("http://maps.google.com/?ll=");
123 result.append(latitude);
125 result.append(longitude);
126 if (altitude > 0.0f) {
127 // Map altitude to zoom level, cleverly. Roughly, zoom level 19 is like a
128 // view from 1000ft, 18 is like 2000ft, 17 like 4000ft, and so on.
129 float altitudeInFeet = altitude * 3.28f;
130 int altitudeInKFeet = (int) (altitudeInFeet / 1000.0f);
131 // No Math.log() available here, so compute log base 2 the old fashioned way
132 // Here logBaseTwo will take on a value between 0 and 18 actually
134 while (altitudeInKFeet > 1 && logBaseTwo < 18) {
135 altitudeInKFeet >>= 1;
138 int zoom = 19 - logBaseTwo;
139 result.append("&z=");
142 return result.toString();