1 /* 2 * Copyright (C) 2018 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 17 package android.location; 18 19 import android.annotation.FloatRange; 20 import android.annotation.IntRange; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.SystemApi; 24 import android.os.Parcel; 25 import android.os.Parcelable; 26 27 import com.android.internal.util.Preconditions; 28 29 import java.util.ArrayList; 30 import java.util.Collections; 31 import java.util.List; 32 33 /** 34 * A class representing a GNSS measurement corrections for all used GNSS satellites at the location 35 * and time specified 36 * 37 * @hide 38 */ 39 @SystemApi 40 public final class GnssMeasurementCorrections implements Parcelable { 41 42 /** Represents latitude in degrees at which the corrections are computed. */ 43 @FloatRange(from = -90.0f, to = 90.0f) 44 private final double mLatitudeDegrees; 45 /** Represents longitude in degrees at which the corrections are computed. */ 46 @FloatRange(from = -180.0f, to = 180.0f) 47 private final double mLongitudeDegrees; 48 /** 49 * Represents altitude in meters above the WGS 84 reference ellipsoid at which the corrections 50 * are computed. 51 */ 52 @FloatRange(from = -1000.0, to = 10000.0f) 53 private final double mAltitudeMeters; 54 /** 55 * Represents the horizontal uncertainty (68% confidence) in meters on the device position at 56 * which the corrections are provided. 57 * 58 * <p> This value is useful for example to judge how accurate the provided corrections are. 59 */ 60 @FloatRange(from = 0.0f) 61 private final double mHorizontalPositionUncertaintyMeters; 62 /** 63 * Represents the vertical uncertainty (68% confidence) in meters on the device position at 64 * which the corrections are provided. 65 * 66 * <p> This value is useful for example to judge how accurate the provided corrections are. 67 */ 68 @FloatRange(from = 0.0f) 69 private final double mVerticalPositionUncertaintyMeters; 70 71 /** Time Of Applicability, GPS time of week in nanoseconds. */ 72 @IntRange(from = 0) 73 private final long mToaGpsNanosecondsOfWeek; 74 75 /** 76 * A set of {@link GnssSingleSatCorrection} each containing measurement corrections for a 77 * satellite in view. 78 */ 79 @NonNull 80 private final List<GnssSingleSatCorrection> mSingleSatCorrectionList; 81 82 /** 83 * Indicates whether the environment bearing is available. 84 */ 85 private final boolean mHasEnvironmentBearing; 86 87 /** 88 * Environment bearing in degrees clockwise from true north, in the direction of user motion. 89 * Environment bearing is provided when it is known with high probability that velocity is 90 * aligned with an environment feature (such as edge of a building, or road). 91 */ 92 @FloatRange(from = 0.0f, to = 360.0f) 93 private final float mEnvironmentBearingDegrees; 94 95 /** 96 * Environment bearing uncertainty in degrees. 97 */ 98 @FloatRange(from = 0.0f, to = 180.0f) 99 private final float mEnvironmentBearingUncertaintyDegrees; 100 GnssMeasurementCorrections(Builder builder)101 private GnssMeasurementCorrections(Builder builder) { 102 mLatitudeDegrees = builder.mLatitudeDegrees; 103 mLongitudeDegrees = builder.mLongitudeDegrees; 104 mAltitudeMeters = builder.mAltitudeMeters; 105 mHorizontalPositionUncertaintyMeters = builder.mHorizontalPositionUncertaintyMeters; 106 mVerticalPositionUncertaintyMeters = builder.mVerticalPositionUncertaintyMeters; 107 mToaGpsNanosecondsOfWeek = builder.mToaGpsNanosecondsOfWeek; 108 final List<GnssSingleSatCorrection> singleSatCorrList = builder.mSingleSatCorrectionList; 109 Preconditions.checkArgument(singleSatCorrList != null && !singleSatCorrList.isEmpty()); 110 mSingleSatCorrectionList = Collections.unmodifiableList(new ArrayList<>(singleSatCorrList)); 111 mHasEnvironmentBearing = builder.mEnvironmentBearingIsSet 112 && builder.mEnvironmentBearingUncertaintyIsSet; 113 mEnvironmentBearingDegrees = builder.mEnvironmentBearingDegrees; 114 mEnvironmentBearingUncertaintyDegrees = builder.mEnvironmentBearingUncertaintyDegrees; 115 } 116 117 /** Gets the latitude in degrees at which the corrections are computed. */ 118 @FloatRange(from = -90.0f, to = 90.0f) getLatitudeDegrees()119 public double getLatitudeDegrees() { 120 return mLatitudeDegrees; 121 } 122 123 /** Gets the longitude in degrees at which the corrections are computed. */ 124 @FloatRange(from = -180.0f, to = 180.0f) getLongitudeDegrees()125 public double getLongitudeDegrees() { 126 return mLongitudeDegrees; 127 } 128 129 /** 130 * Gets the altitude in meters above the WGS 84 reference ellipsoid at which the corrections are 131 * computed. 132 */ 133 @FloatRange(from = -1000.0f, to = 10000.0f) getAltitudeMeters()134 public double getAltitudeMeters() { 135 return mAltitudeMeters; 136 } 137 138 /** 139 * Gets the horizontal uncertainty (68% confidence) in meters on the device position at 140 * which the corrections are provided. 141 */ 142 @FloatRange(from = 0.0f) getHorizontalPositionUncertaintyMeters()143 public double getHorizontalPositionUncertaintyMeters() { 144 return mHorizontalPositionUncertaintyMeters; 145 } 146 147 /** 148 * Gets the vertical uncertainty (68% confidence) in meters on the device position at 149 * which the corrections are provided. 150 */ 151 @FloatRange(from = 0.0f) getVerticalPositionUncertaintyMeters()152 public double getVerticalPositionUncertaintyMeters() { 153 return mVerticalPositionUncertaintyMeters; 154 } 155 156 /** Gets the time of applicability, GPS time of week in nanoseconds. */ 157 @IntRange(from = 0) getToaGpsNanosecondsOfWeek()158 public long getToaGpsNanosecondsOfWeek() { 159 return mToaGpsNanosecondsOfWeek; 160 } 161 162 /** 163 * Gets a set of {@link GnssSingleSatCorrection} each containing measurement corrections for a 164 * satellite in view 165 */ 166 @NonNull getSingleSatelliteCorrectionList()167 public List<GnssSingleSatCorrection> getSingleSatelliteCorrectionList() { 168 return mSingleSatCorrectionList; 169 } 170 171 /** 172 * If true, environment bearing will be available. 173 */ hasEnvironmentBearing()174 public boolean hasEnvironmentBearing() { 175 return mHasEnvironmentBearing; 176 } 177 178 /** 179 * Gets the environment bearing in degrees clockwise from true north, in the direction of user 180 * motion. Environment bearing is provided when it is known with high probability that 181 * velocity is aligned with an environment feature (such as edge of a building, or road). 182 * 183 * {@link #hasEnvironmentBearing} should be called to check the environment bearing is available 184 * before calling this method. The value is undefined if {@link #hasEnvironmentBearing} returns 185 * false. 186 */ 187 @FloatRange(from = 0.0f, to = 360.0f) getEnvironmentBearingDegrees()188 public float getEnvironmentBearingDegrees() { 189 return mEnvironmentBearingDegrees; 190 } 191 192 /** 193 * Gets the environment bearing uncertainty in degrees. It represents the standard deviation of 194 * the physical structure in the circle of position uncertainty. The uncertainty can take values 195 * between 0 and 180 degrees. The {@link #hasEnvironmentBearing} becomes false as the 196 * uncertainty value passes a predefined threshold depending on the physical structure around 197 * the user. 198 * 199 * {@link #hasEnvironmentBearing} should be called to check the environment bearing is available 200 * before calling this method. The value is undefined if {@link #hasEnvironmentBearing} returns 201 * false. 202 */ 203 @FloatRange(from = 0.0f, to = 180.0f) getEnvironmentBearingUncertaintyDegrees()204 public float getEnvironmentBearingUncertaintyDegrees() { 205 return mEnvironmentBearingUncertaintyDegrees; 206 } 207 208 @Override describeContents()209 public int describeContents() { 210 return 0; 211 } 212 213 public static final Creator<GnssMeasurementCorrections> CREATOR = 214 new Creator<GnssMeasurementCorrections>() { 215 @Override 216 @NonNull 217 public GnssMeasurementCorrections createFromParcel(@NonNull Parcel parcel) { 218 final GnssMeasurementCorrections.Builder gnssMeasurementCorrectons = 219 new Builder() 220 .setLatitudeDegrees(parcel.readDouble()) 221 .setLongitudeDegrees(parcel.readDouble()) 222 .setAltitudeMeters(parcel.readDouble()) 223 .setHorizontalPositionUncertaintyMeters(parcel.readDouble()) 224 .setVerticalPositionUncertaintyMeters(parcel.readDouble()) 225 .setToaGpsNanosecondsOfWeek(parcel.readLong()); 226 List<GnssSingleSatCorrection> singleSatCorrectionList = new ArrayList<>(); 227 parcel.readTypedList(singleSatCorrectionList, GnssSingleSatCorrection.CREATOR); 228 gnssMeasurementCorrectons.setSingleSatelliteCorrectionList( 229 singleSatCorrectionList); 230 boolean hasEnvironmentBearing = parcel.readBoolean(); 231 if (hasEnvironmentBearing) { 232 gnssMeasurementCorrectons.setEnvironmentBearingDegrees(parcel.readFloat()); 233 gnssMeasurementCorrectons.setEnvironmentBearingUncertaintyDegrees( 234 parcel.readFloat()); 235 } 236 return gnssMeasurementCorrectons.build(); 237 } 238 239 @Override 240 public GnssMeasurementCorrections[] newArray(int i) { 241 return new GnssMeasurementCorrections[i]; 242 } 243 }; 244 245 @NonNull 246 @Override toString()247 public String toString() { 248 final String format = " %-29s = %s\n"; 249 StringBuilder builder = new StringBuilder("GnssMeasurementCorrections:\n"); 250 builder.append(String.format(format, "LatitudeDegrees = ", mLatitudeDegrees)); 251 builder.append(String.format(format, "LongitudeDegrees = ", mLongitudeDegrees)); 252 builder.append(String.format(format, "AltitudeMeters = ", mAltitudeMeters)); 253 builder.append(String.format(format, "HorizontalPositionUncertaintyMeters = ", 254 mHorizontalPositionUncertaintyMeters)); 255 builder.append(String.format(format, "VerticalPositionUncertaintyMeters = ", 256 mVerticalPositionUncertaintyMeters)); 257 builder.append( 258 String.format(format, "ToaGpsNanosecondsOfWeek = ", mToaGpsNanosecondsOfWeek)); 259 builder.append( 260 String.format(format, "mSingleSatCorrectionList = ", mSingleSatCorrectionList)); 261 builder.append( 262 String.format(format, "HasEnvironmentBearing = ", mHasEnvironmentBearing)); 263 builder.append( 264 String.format(format, "EnvironmentBearingDegrees = ", 265 mEnvironmentBearingDegrees)); 266 builder.append( 267 String.format(format, "EnvironmentBearingUncertaintyDegrees = ", 268 mEnvironmentBearingUncertaintyDegrees)); 269 return builder.toString(); 270 } 271 272 @Override writeToParcel(@onNull Parcel parcel, int flags)273 public void writeToParcel(@NonNull Parcel parcel, int flags) { 274 parcel.writeDouble(mLatitudeDegrees); 275 parcel.writeDouble(mLongitudeDegrees); 276 parcel.writeDouble(mAltitudeMeters); 277 parcel.writeDouble(mHorizontalPositionUncertaintyMeters); 278 parcel.writeDouble(mVerticalPositionUncertaintyMeters); 279 parcel.writeLong(mToaGpsNanosecondsOfWeek); 280 parcel.writeTypedList(mSingleSatCorrectionList); 281 parcel.writeBoolean(mHasEnvironmentBearing); 282 if (mHasEnvironmentBearing) { 283 parcel.writeFloat(mEnvironmentBearingDegrees); 284 parcel.writeFloat(mEnvironmentBearingUncertaintyDegrees); 285 } 286 } 287 288 /** Builder for {@link GnssMeasurementCorrections} */ 289 public static final class Builder { 290 /** 291 * For documentation of below fields, see corresponding fields in {@link 292 * GnssMeasurementCorrections}. 293 */ 294 private double mLatitudeDegrees; 295 private double mLongitudeDegrees; 296 private double mAltitudeMeters; 297 private double mHorizontalPositionUncertaintyMeters; 298 private double mVerticalPositionUncertaintyMeters; 299 private long mToaGpsNanosecondsOfWeek; 300 @Nullable private List<GnssSingleSatCorrection> mSingleSatCorrectionList; 301 private float mEnvironmentBearingDegrees; 302 private boolean mEnvironmentBearingIsSet = false; 303 private float mEnvironmentBearingUncertaintyDegrees; 304 private boolean mEnvironmentBearingUncertaintyIsSet = false; 305 306 /** Sets the latitude in degrees at which the corrections are computed. */ setLatitudeDegrees( @loatRangefrom = -90.0f, to = 90.0f) double latitudeDegrees)307 @NonNull public Builder setLatitudeDegrees( 308 @FloatRange(from = -90.0f, to = 90.0f) double latitudeDegrees) { 309 mLatitudeDegrees = latitudeDegrees; 310 return this; 311 } 312 313 /** Sets the longitude in degrees at which the corrections are computed. */ setLongitudeDegrees( @loatRangefrom = -180.0f, to = 180.0f) double longitudeDegrees)314 @NonNull public Builder setLongitudeDegrees( 315 @FloatRange(from = -180.0f, to = 180.0f) double longitudeDegrees) { 316 mLongitudeDegrees = longitudeDegrees; 317 return this; 318 } 319 320 /** 321 * Sets the altitude in meters above the WGS 84 reference ellipsoid at which the corrections 322 * are computed. 323 */ setAltitudeMeters( @loatRangefrom = -1000.0f, to = 10000.0f) double altitudeMeters)324 @NonNull public Builder setAltitudeMeters( 325 @FloatRange(from = -1000.0f, to = 10000.0f) double altitudeMeters) { 326 mAltitudeMeters = altitudeMeters; 327 return this; 328 } 329 330 331 /** 332 * Sets the horizontal uncertainty (68% confidence) in meters on the device position at 333 * which the corrections are provided. 334 */ setHorizontalPositionUncertaintyMeters( @loatRangefrom = 0.0f) double horizontalPositionUncertaintyMeters)335 @NonNull public Builder setHorizontalPositionUncertaintyMeters( 336 @FloatRange(from = 0.0f) double horizontalPositionUncertaintyMeters) { 337 mHorizontalPositionUncertaintyMeters = horizontalPositionUncertaintyMeters; 338 return this; 339 } 340 341 /** 342 * Sets the vertical uncertainty (68% confidence) in meters on the device position at which 343 * the corrections are provided. 344 */ setVerticalPositionUncertaintyMeters( @loatRangefrom = 0.0f) double verticalPositionUncertaintyMeters)345 @NonNull public Builder setVerticalPositionUncertaintyMeters( 346 @FloatRange(from = 0.0f) double verticalPositionUncertaintyMeters) { 347 mVerticalPositionUncertaintyMeters = verticalPositionUncertaintyMeters; 348 return this; 349 } 350 351 /** Sets the time of applicability, GPS time of week in nanoseconds. */ setToaGpsNanosecondsOfWeek( @ntRangefrom = 0) long toaGpsNanosecondsOfWeek)352 @NonNull public Builder setToaGpsNanosecondsOfWeek( 353 @IntRange(from = 0) long toaGpsNanosecondsOfWeek) { 354 mToaGpsNanosecondsOfWeek = toaGpsNanosecondsOfWeek; 355 return this; 356 } 357 358 /** 359 * Sets a the list of {@link GnssSingleSatCorrection} containing measurement corrections for 360 * a satellite in view 361 */ setSingleSatelliteCorrectionList( @onNull List<GnssSingleSatCorrection> singleSatCorrectionList)362 @NonNull public Builder setSingleSatelliteCorrectionList( 363 @NonNull List<GnssSingleSatCorrection> singleSatCorrectionList) { 364 mSingleSatCorrectionList = singleSatCorrectionList; 365 return this; 366 } 367 368 /** 369 * Sets the environment bearing in degrees clockwise from true north, in the direction of 370 * user motion. Environment bearing is provided when it is known with high probability 371 * that velocity is aligned with an environment feature (such as edge of a building, or 372 * road). 373 * 374 * Both the bearing and uncertainty must be set for the environment bearing to be valid. 375 */ setEnvironmentBearingDegrees( @loatRangefrom = 0.0f, to = 360.0f) float environmentBearingDegrees)376 @NonNull public Builder setEnvironmentBearingDegrees( 377 @FloatRange(from = 0.0f, to = 360.0f) 378 float environmentBearingDegrees) { 379 mEnvironmentBearingDegrees = environmentBearingDegrees; 380 mEnvironmentBearingIsSet = true; 381 return this; 382 } 383 384 /** 385 * Sets the environment bearing uncertainty in degrees. 386 * 387 * Both the bearing and uncertainty must be set for the environment bearing to be valid. 388 */ setEnvironmentBearingUncertaintyDegrees( @loatRangefrom = 0.0f, to = 180.0f) float environmentBearingUncertaintyDegrees)389 @NonNull public Builder setEnvironmentBearingUncertaintyDegrees( 390 @FloatRange(from = 0.0f, to = 180.0f) 391 float environmentBearingUncertaintyDegrees) { 392 mEnvironmentBearingUncertaintyDegrees = environmentBearingUncertaintyDegrees; 393 mEnvironmentBearingUncertaintyIsSet = true; 394 return this; 395 } 396 397 /** Builds a {@link GnssMeasurementCorrections} instance as specified by this builder. */ build()398 @NonNull public GnssMeasurementCorrections build() { 399 if (mEnvironmentBearingIsSet ^ mEnvironmentBearingUncertaintyIsSet) { 400 throw new IllegalStateException("Both environment bearing and environment bearing " 401 + "uncertainty must be set."); 402 } 403 return new GnssMeasurementCorrections(this); 404 } 405 } 406 } 407