blob: 9570b26452e4f3ebce3cf231b3fce048b3a14c33 [file] [log] [blame]
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17package android.location;
18
Mathew Inwood735497e2018-08-09 16:44:32 +010019import android.annotation.UnsupportedAppUsage;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070020import android.os.Parcel;
21import android.os.Parcelable;
22
23/**
Nick Pelly4e31c4f2012-08-13 19:35:39 -070024 * Represents a geographical boundary, also known as a geofence.
25 *
Scott Main8761e142012-10-29 19:11:41 -070026 * <p>Currently only circular geofences are supported and they do not support altitude changes.
Laurent Tu7ab7f532012-10-30 14:54:02 -070027 *
28 * @hide
Nick Pelly6fa9ad42012-07-16 12:18:23 -070029 */
30public final class Geofence implements Parcelable {
31 /** @hide */
32 public static final int TYPE_HORIZONTAL_CIRCLE = 1;
33
34 private final int mType;
35 private final double mLatitude;
36 private final double mLongitude;
37 private final float mRadius;
38
39 /**
Scott Main8761e142012-10-29 19:11:41 -070040 * Create a circular geofence (on a flat, horizontal plane).
Nick Pelly4e31c4f2012-08-13 19:35:39 -070041 *
Victoria Lease3dffb8c2012-10-30 10:44:14 -070042 * @param latitude latitude in degrees, between -90 and +90 inclusive
43 * @param longitude longitude in degrees, between -180 and +180 inclusive
Nick Pelly6fa9ad42012-07-16 12:18:23 -070044 * @param radius radius in meters
45 * @return a new geofence
46 * @throws IllegalArgumentException if any parameters are out of range
47 */
48 public static Geofence createCircle(double latitude, double longitude, float radius) {
49 return new Geofence(latitude, longitude, radius);
50 }
51
52 private Geofence(double latitude, double longitude, float radius) {
53 checkRadius(radius);
54 checkLatLong(latitude, longitude);
55 mType = TYPE_HORIZONTAL_CIRCLE;
56 mLatitude = latitude;
57 mLongitude = longitude;
58 mRadius = radius;
59 }
60
61 /** @hide */
62 public int getType() {
63 return mType;
64 }
65
66 /** @hide */
67 public double getLatitude() {
68 return mLatitude;
69 }
70
71 /** @hide */
72 public double getLongitude() {
73 return mLongitude;
74 }
75
76 /** @hide */
77 public float getRadius() {
78 return mRadius;
79 }
80
81 private static void checkRadius(float radius) {
82 if (radius <= 0) {
83 throw new IllegalArgumentException("invalid radius: " + radius);
84 }
85 }
86
87 private static void checkLatLong(double latitude, double longitude) {
88 if (latitude > 90.0 || latitude < -90.0) {
89 throw new IllegalArgumentException("invalid latitude: " + latitude);
90 }
91 if (longitude > 180.0 || longitude < -180.0) {
92 throw new IllegalArgumentException("invalid longitude: " + longitude);
93 }
94 }
95
96 private static void checkType(int type) {
97 if (type != TYPE_HORIZONTAL_CIRCLE) {
98 throw new IllegalArgumentException("invalid type: " + type);
99 }
100 }
101
Mathew Inwood735497e2018-08-09 16:44:32 +0100102 @UnsupportedAppUsage
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700103 public static final @android.annotation.NonNull Parcelable.Creator<Geofence> CREATOR = new Parcelable.Creator<Geofence>() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700104 @Override
105 public Geofence createFromParcel(Parcel in) {
106 int type = in.readInt();
107 double latitude = in.readDouble();
108 double longitude = in.readDouble();
109 float radius = in.readFloat();
110 checkType(type);
111 return Geofence.createCircle(latitude, longitude, radius);
112 }
113 @Override
114 public Geofence[] newArray(int size) {
115 return new Geofence[size];
116 }
117 };
118
119 @Override
120 public int describeContents() {
121 return 0;
122 }
123
124 @Override
125 public void writeToParcel(Parcel parcel, int flags) {
126 parcel.writeInt(mType);
127 parcel.writeDouble(mLatitude);
128 parcel.writeDouble(mLongitude);
129 parcel.writeFloat(mRadius);
130 }
131
132 private static String typeToString(int type) {
133 switch (type) {
134 case TYPE_HORIZONTAL_CIRCLE:
135 return "CIRCLE";
136 default:
137 checkType(type);
138 return null;
139 }
140 }
141
142 @Override
143 public String toString() {
144 return String.format("Geofence[%s %.6f, %.6f %.0fm]",
145 typeToString(mType), mLatitude, mLongitude, mRadius);
146 }
147
148 @Override
149 public int hashCode() {
150 final int prime = 31;
151 int result = 1;
152 long temp;
153 temp = Double.doubleToLongBits(mLatitude);
154 result = prime * result + (int) (temp ^ (temp >>> 32));
155 temp = Double.doubleToLongBits(mLongitude);
156 result = prime * result + (int) (temp ^ (temp >>> 32));
157 result = prime * result + Float.floatToIntBits(mRadius);
158 result = prime * result + mType;
159 return result;
160 }
161
Nick Pelly4e31c4f2012-08-13 19:35:39 -0700162 /**
163 * Two geofences are equal if they have identical properties.
164 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700165 @Override
166 public boolean equals(Object obj) {
167 if (this == obj)
168 return true;
169 if (obj == null)
170 return false;
171 if (!(obj instanceof Geofence))
172 return false;
173 Geofence other = (Geofence) obj;
174 if (mRadius != other.mRadius)
175 return false;
176 if (mLatitude != other.mLatitude)
177 return false;
178 if (mLongitude != other.mLongitude)
179 return false;
180 if (mType != other.mType)
181 return false;
182 return true;
183 }
184}