起因:1.在中国大部分地区,由于政策原因。对定位的使用必须使用定位为俗称火星坐标的gcj02坐标系。然而,在调用安卓原生的android.location.LocationListener获取定位对象时,给到的将是以默认WGS84为坐标系的点,所以由于该种原因,导致我们在调用的大多数大陆地区api地图时会出错。2.获取到的定位点有可能出现漂移现象,为了给获取到的点打上标记,以便于后续的处理,我希望加上相关的漂移属性
为了解决1问题,我决定重写一个新的Location类,将在类内部对location对象进行判断,以决定是否启用gcj02坐标;若使用gcj02坐标,则在调用location.getLatitude()与location.getLongitude()方法时对直接输出gcj02坐标(同样,本类也同时加入了getLatLng()的方法,也同样遵循相关规则)。
为了解决2问题,我将在location类内加入新的属性
类的定义:采用extends继承安卓原生的android.location.Location
public class Location extends android.location.Location implements Parcelable {
}
重写相关方法:
@Override
public @FloatRange(from = -90.0, to = 90.0) double getLatitude(){
Location location;
if (whetherUseGcj02Coordinate() && coordinate == coordinate_gps84) {
location = getLocationInGCJ02();
}else {location=this;}
return location.getLatitude(coordinate_gps84);
}
public @FloatRange(from = -90.0, to = 90.0) double getLatitude(int coordinate){
if (coordinate==coordinate_gps84){
return super.getLatitude();
}else {return getLatitude();}
}
@Override
public @FloatRange(from = -180.0, to = 180.0) double getLongitude() {
Location location;
if (whetherUseGcj02Coordinate() && coordinate == coordinate_gps84) {
location = getLocationInGCJ02();
}else {location=this;}
return location.getLongitude(coordinate_gps84);
}
public @FloatRange(from = -180.0, to = 180.0) double getLongitude(int coordinate) {
if (coordinate == coordinate_gps84) {
return super.getLongitude();
}else {return getLongitude();}
}
添加多样化的构造函数:
public Location(@Nullable String provider) {
super(provider);
}
public Location(@Nullable String provider, int coordinate) {
super(provider);
this.coordinate = coordinate;
}
public Location(LatLng latLng) {
super("");
setLatitude(latLng.latitude);
setLongitude(latLng.longitude);
}
public Location(LatLng latLng, int coordinate) {
this(latLng);
this.coordinate = coordinate;
}
public Location(Marker marker) {
this(marker.getPosition());
}
public Location(Marker marker, int coordinate) {
this(marker.getPosition(), coordinate);
}
public Location(@NonNull android.location.Location location) {
super(location);
}
添加漂移及坐标系相关属性:
private int whetherDrifting;
private int whetherDriftingSource = 0;
public static final int whetherDriftingSource_sameLongitudeAndLatitude = 1;
public static final int whetherDriftingSource_below5s = 2;
public static final int whetherDriftingSource_accuracyExceeded = 3;
public static final int whetherDriftingSource_handset = 4;
private int refreshedNumber;
public static final int coordinate_gps84 = 0;//wgs84国际坐标系
public static final int coordinate_gcj02 = 1;//中国火星加密坐标
private int coordinate = coordinate_gps84;
1.判断是否使用gcj02坐标:
一般来说,使用gcj02坐标的是处在中国大陆的地区。所以,我们可以近似地认定在中国大陆地区的点使用gcj02坐标。
这样,该判断问题也就转变为了判断一个点是不是处在近似的一块区域内。也就是判断点在多边形内的问题(Point in polygon(PIP))。
对于该类问题,我们可以使用光线投射算法 (Ray casting algorithm)。光线投射算法 (Ray casting algorithm)简单来说就是一个点如果从平面内任意地方发出一条任意方向的射线,如果该线经过多边形围成的区域,就记数一次。由于发出的射线,所以从围成区域内部发出,记数一定是奇数个(假设是一个正方形,从点内发出,一定只有一次记数。如果这个多边形不规则,导致正方形内又跨出了多边形,那它一定会再回到多边形内部。最终到边界后再出去。)而若从围成区域外部发出,记数一定是偶数个。(https://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm)
知道了这个逻辑,我们就可以去考虑计算要求的点在与多边形的穿过次数了
先明确一下射线:由于我们希望计算尽可能地简便,且射线只要满足跨过要判定的点就好。所以我们可以简单地对我们要求的点(x0,y0)定义一个y=y0的线,方向向右。(当然你向左也可以。定义x=x0向上或者向下也可以,但是就会影响到后面的相关判断了)
然后,对于我们的边界,我们可以换成y=y0的线在交点x坐标小于x0情况下(保证射线向右)与多边形上的两点连线的交点问题。
也就是:
通过计算y=y0与y-y1=(y2-y1)/(x2-x1)(x-x1)的交点x(其中,(x1,y1),(x2,y2)是多边形上两个连续的边界点),并且通过判断它与x0的大小关系进行记数。最后对记数结果取模得到是奇数还是偶数。
int n = locationsListUseGCJ02.size();
int count = 0;
double x = getLongitude(coordinate_gps84);
double y = getLatitude(coordinate_gps84);
for (int i = 0; i < n; i++) {
double[] p1 = locationsListUseGCJ02.get(i);
double[] p2 = locationsListUseGCJ02.get((i + 1) % n);
if (y > Math.min(p1[1], p2[1]) && y <= Math.max(p1[1], p2[1])) {
double xinters = (y - p1[1]) * (p2[0] - p1[0]) / (p2[1] - p1[1]) + p1[0];
if (x < xinters) {
count++;
}
}
}
return count % 2 == 1;//记数为奇数代表在该多边形内部
其中,locationsListUseGCJ02为我自己手扣的,其中是以要采用gcj02坐标的情况写的,考虑到沿海及边境地图在跨越时(如沿海在近海时)使用gcj02的效果仍然更加、计算量问题。所以没有按照国境线一点点扣,只是按照预想的需要使用gcj02的场景扣的。其中的点不代表国境线,请不要上纲上线!
private static final List locationsListUseGCJ02= new ArrayList<>(Arrays.asList(
new double[]{120.299594, 25.151488},
new double[]{121.131541, 26.325553},
new double[]{122.027338, 27.462194},
new double[]{122.564319, 28.670188},
new double[]{123.111298, 29.676372},
new double[]{123.458430, 30.449464},
new double[]{122.958226, 31.486470},
new double[]{121.690245, 32.793700},
new double[]{120.515746, 35.099322},
new double[]{122.904175, 36.584982},
new double[]{123.198120, 37.590011},
new double[]{124.501900, 39.838898},
new double[]{124.570231, 40.114967},
new double[]{125.186564, 40.463649},
new double[]{125.864261, 40.788338},
new double[]{126.402151, 41.092832},
new double[]{126.823096, 41.314447},
new double[]{127.314739, 41.318121},
new double[]{128.135222, 41.254724},
new double[]{128.405141, 41.447042},
new double[]{128.527487, 41.641182},
new double[]{128.294486, 41.924950},
new double[]{128.977744, 41.941983},
new double[]{129.507465, 42.262905},
new double[]{129.913364, 42.336937},
new double[]{129.982875, 42.548287},
new double[]{130.305099, 42.522103},
new double[]{130.568901, 42.255908},
new double[]{130.879513, 42.282561},
new double[]{130.762075, 42.734195},
new double[]{131.178310, 42.784229},
new double[]{131.343449, 42.934286},
new double[]{131.493323, 43.304933},
new double[]{131.548896, 43.971455},
new double[]{131.465395, 44.691276},
new double[]{132.038056, 45.029874},
new double[]{132.964414, 44.905325},
new double[]{133.396076, 45.086144},
new double[]{133.787987, 45.641342},
new double[]{134.263185, 46.224706},
new double[]{134.528319, 47.024481},
new double[]{135.032216, 47.587949},
new double[]{135.326048, 48.106896},
new double[]{135.358786, 48.556513},
new double[]{134.683907, 48.633413},
new double[]{133.320648, 48.292721},
new double[]{131.901671, 47.982632},
new double[]{131.092703, 48.224336},
new double[]{130.961940, 48.938637},
new double[]{129.743633, 49.539492},
new double[]{128.866627, 49.904926},
new double[]{127.718181, 50.689692},
new double[]{127.099079, 51.603452},
new double[]{126.653482, 52.609418},
new double[]{126.036530, 53.216477},
new double[]{124.532957, 53.602879},
new double[]{123.259744, 53.775463},
new double[]{121.518389, 53.557035},
new double[]{120.381652, 53.286388},
new double[]{119.705267, 52.700593},
new double[]{120.119527, 52.276346},
new double[]{119.594571, 51.490903},
new double[]{118.909857, 50.531810},
new double[]{117.908867, 50.106373},
new double[]{116.501962, 50.233276},
new double[]{115.476246, 48.577550},
new double[]{115.587730, 47.180858},
new double[]{116.233216, 46.377140},
new double[]{112.814356, 45.314828},
new double[]{111.442580, 45.153573},
new double[]{111.004655, 44.287175},
new double[]{104.959791, 42.294147},
new double[]{100.502475, 43.321830},
new double[]{95.792481, 44.596647},
new double[]{92.027044, 46.466535},
new double[]{90.797631, 48.337059},
new double[]{88.131605, 49.576833},
new double[]{86.519580, 49.318939},
new double[]{85.262649, 48.288853},
new double[]{85.033559, 47.534644},
new double[]{83.097866, 47.639246},
new double[]{82.358842, 46.937514},
new double[]{80.956951, 45.589199},
new double[]{79.787002, 45.234532},
new double[]{79.501196, 44.723603},
new double[]{80.279794, 43.301712},
new double[]{78.814765, 42.142338},
new double[]{76.777823, 41.302580},
new double[]{74.424913, 40.689594},
new double[]{73.085573, 39.708932},
new double[]{73.363694, 38.313817},
new double[]{74.379353, 36.756449},
new double[]{75.948435, 35.470805},
new double[]{77.603164, 34.108110},
new double[]{77.989398, 32.218405},
new double[]{78.840577, 30.763837},
new double[]{81.749800, 29.603147},
new double[]{85.293143, 27.844282},
new double[]{88.049535, 27.248785},
new double[]{89.360615, 26.735904},
new double[]{90.791880, 27.325224},
new double[]{92.185615, 26.500811},
new double[]{97.556456, 27.609503},
new double[]{97.513815, 25.416053},
new double[]{97.087513, 24.213042},
new double[]{98.178288, 23.344487},
new double[]{99.158385, 21.500033},
new double[]{101.291359, 20.628696},
new double[]{102.381815, 20.934239},
new double[]{102.443628, 21.961660},
new double[]{103.767529, 22.084420},
new double[]{105.524981, 22.701842},
new double[]{106.189577, 22.363933},
new double[]{106.517735, 21.763955},
new double[]{107.581041, 21.175545},
new double[]{108.611137, 20.776955},
new double[]{108.576962, 19.844868},
new double[]{108.243756, 19.289284},
new double[]{108.136051, 18.300544},
new double[]{109.584772, 17.562957},
new double[]{111.388383, 18.777635},
new double[]{111.575144, 19.728228},
new double[]{111.202718, 20.739215},
new double[]{112.323804, 21.374751},
new double[]{113.136606, 21.297260},
new double[]{113.631819, 21.856516},
new double[]{114.014781, 21.802438},
new double[]{114.410204, 21.987192},
new double[]{114.898601, 22.292192},
new double[]{115.576209, 22.572782},
new double[]{116.752836, 22.783073},
new double[]{117.799901, 23.477163},
new double[]{119.422678, 23.058463},
new double[]{120.669619, 25.294560},
new double[]{122.196453, 25.738029}
));
若有其他需求,可以自行更改相关数据。请注意:请严格遵守中国或所在地区的法律法规,不要出现国边境的政治问题
注意:在同时处理上千个点时此方法会出现明显卡顿,故不建议大规模使用此算法。
最后,对location类实现describeContents、writeToParcel及Parcelable.Creator功能,以确保相关类可序列化(实现SharedPreferences功能、intent的put功能等)
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(this.whetherDrifting);
if (this.whetherDriftingSource != 0) {
dest.writeInt(1); // 使用一个标志位表示非空
dest.writeInt(this.whetherDriftingSource);
} else {
dest.writeInt(0); // 使用一个标志位表示为空
}
dest.writeInt(this.refreshedNumber);
dest.writeInt(this.coordinate);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public Location createFromParcel(Parcel in) {
Location location = new Location(android.location.Location.CREATOR.createFromParcel(in));
location.whetherDrifting = in.readInt();
location.whetherDriftingSource = in.readInt() == 1 ? in.readInt() : 0;
location.refreshedNumber = in.readInt();
location.coordinate = in.readInt();
return location;
}
@Override
public Location[] newArray(int size) {
// 创建Location对象数组
return new Location[size];
}
};
该class的全部内容:
package com.example.androidtool.LocationDisplay.TrackManager;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.FloatRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.amap.api.maps.AMap;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.example.androidtool.R;
import com.example.androidtool.Tool.GpsFormatTrans;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
public class Location extends android.location.Location implements Parcelable {
private int whetherDrifting;
private int whetherDriftingSource = 0;
public static final int whetherDriftingSource_sameLongitudeAndLatitude = 1;
public static final int whetherDriftingSource_below5s = 2;
public static final int whetherDriftingSource_accuracyExceeded = 3;
public static final int whetherDriftingSource_handset = 4;
private int refreshedNumber;
public static final int coordinate_gps84 = 0;//wgs84国际坐标系
public static final int coordinate_gcj02 = 1;//中国火星加密坐标
private int coordinate = coordinate_gps84;
public int getCoordinate() {
return coordinate;
}
private static final List locationsListUseGCJ02= new ArrayList<>(Arrays.asList(
new double[]{120.299594, 25.151488},
new double[]{121.131541, 26.325553},
new double[]{122.027338, 27.462194},
new double[]{122.564319, 28.670188},
new double[]{123.111298, 29.676372},
new double[]{123.458430, 30.449464},
new double[]{122.958226, 31.486470},
new double[]{121.690245, 32.793700},
new double[]{120.515746, 35.099322},
new double[]{122.904175, 36.584982},
new double[]{123.198120, 37.590011},
new double[]{124.501900, 39.838898},
new double[]{124.570231, 40.114967},
new double[]{125.186564, 40.463649},
new double[]{125.864261, 40.788338},
new double[]{126.402151, 41.092832},
new double[]{126.823096, 41.314447},
new double[]{127.314739, 41.318121},
new double[]{128.135222, 41.254724},
new double[]{128.405141, 41.447042},
new double[]{128.527487, 41.641182},
new double[]{128.294486, 41.924950},
new double[]{128.977744, 41.941983},
new double[]{129.507465, 42.262905},
new double[]{129.913364, 42.336937},
new double[]{129.982875, 42.548287},
new double[]{130.305099, 42.522103},
new double[]{130.568901, 42.255908},
new double[]{130.879513, 42.282561},
new double[]{130.762075, 42.734195},
new double[]{131.178310, 42.784229},
new double[]{131.343449, 42.934286},
new double[]{131.493323, 43.304933},
new double[]{131.548896, 43.971455},
new double[]{131.465395, 44.691276},
new double[]{132.038056, 45.029874},
new double[]{132.964414, 44.905325},
new double[]{133.396076, 45.086144},
new double[]{133.787987, 45.641342},
new double[]{134.263185, 46.224706},
new double[]{134.528319, 47.024481},
new double[]{135.032216, 47.587949},
new double[]{135.326048, 48.106896},
new double[]{135.358786, 48.556513},
new double[]{134.683907, 48.633413},
new double[]{133.320648, 48.292721},
new double[]{131.901671, 47.982632},
new double[]{131.092703, 48.224336},
new double[]{130.961940, 48.938637},
new double[]{129.743633, 49.539492},
new double[]{128.866627, 49.904926},
new double[]{127.718181, 50.689692},
new double[]{127.099079, 51.603452},
new double[]{126.653482, 52.609418},
new double[]{126.036530, 53.216477},
new double[]{124.532957, 53.602879},
new double[]{123.259744, 53.775463},
new double[]{121.518389, 53.557035},
new double[]{120.381652, 53.286388},
new double[]{119.705267, 52.700593},
new double[]{120.119527, 52.276346},
new double[]{119.594571, 51.490903},
new double[]{118.909857, 50.531810},
new double[]{117.908867, 50.106373},
new double[]{116.501962, 50.233276},
new double[]{115.476246, 48.577550},
new double[]{115.587730, 47.180858},
new double[]{116.233216, 46.377140},
new double[]{112.814356, 45.314828},
new double[]{111.442580, 45.153573},
new double[]{111.004655, 44.287175},
new double[]{104.959791, 42.294147},
new double[]{100.502475, 43.321830},
new double[]{95.792481, 44.596647},
new double[]{92.027044, 46.466535},
new double[]{90.797631, 48.337059},
new double[]{88.131605, 49.576833},
new double[]{86.519580, 49.318939},
new double[]{85.262649, 48.288853},
new double[]{85.033559, 47.534644},
new double[]{83.097866, 47.639246},
new double[]{82.358842, 46.937514},
new double[]{80.956951, 45.589199},
new double[]{79.787002, 45.234532},
new double[]{79.501196, 44.723603},
new double[]{80.279794, 43.301712},
new double[]{78.814765, 42.142338},
new double[]{76.777823, 41.302580},
new double[]{74.424913, 40.689594},
new double[]{73.085573, 39.708932},
new double[]{73.363694, 38.313817},
new double[]{74.379353, 36.756449},
new double[]{75.948435, 35.470805},
new double[]{77.603164, 34.108110},
new double[]{77.989398, 32.218405},
new double[]{78.840577, 30.763837},
new double[]{81.749800, 29.603147},
new double[]{85.293143, 27.844282},
new double[]{88.049535, 27.248785},
new double[]{89.360615, 26.735904},
new double[]{90.791880, 27.325224},
new double[]{92.185615, 26.500811},
new double[]{97.556456, 27.609503},
new double[]{97.513815, 25.416053},
new double[]{97.087513, 24.213042},
new double[]{98.178288, 23.344487},
new double[]{99.158385, 21.500033},
new double[]{101.291359, 20.628696},
new double[]{102.381815, 20.934239},
new double[]{102.443628, 21.961660},
new double[]{103.767529, 22.084420},
new double[]{105.524981, 22.701842},
new double[]{106.189577, 22.363933},
new double[]{106.517735, 21.763955},
new double[]{107.581041, 21.175545},
new double[]{108.611137, 20.776955},
new double[]{108.576962, 19.844868},
new double[]{108.243756, 19.289284},
new double[]{108.136051, 18.300544},
new double[]{109.584772, 17.562957},
new double[]{111.388383, 18.777635},
new double[]{111.575144, 19.728228},
new double[]{111.202718, 20.739215},
new double[]{112.323804, 21.374751},
new double[]{113.136606, 21.297260},
new double[]{113.631819, 21.856516},
new double[]{114.014781, 21.802438},
new double[]{114.410204, 21.987192},
new double[]{114.898601, 22.292192},
new double[]{115.576209, 22.572782},
new double[]{116.752836, 22.783073},
new double[]{117.799901, 23.477163},
new double[]{119.422678, 23.058463},
new double[]{120.669619, 25.294560},
new double[]{122.196453, 25.738029}
));
public void setCoordinate(int coordinate) {
this.coordinate = coordinate;
}
public Location(@Nullable String provider) {
super(provider);
}
public Location(@Nullable String provider, int coordinate) {
super(provider);
this.coordinate = coordinate;
}
public Location(LatLng latLng) {
super("");
setLatitude(latLng.latitude);
setLongitude(latLng.longitude);
if (getTime()==0){
setTime(System.currentTimeMillis());
}
}
public Location(LatLng latLng, int coordinate) {
this(latLng);
this.coordinate = coordinate;
}
public Location(Marker marker) {
this(marker.getPosition());
}
public Location(Marker marker, int coordinate) {
this(marker.getPosition(), coordinate);
}
public Location(@NonNull android.location.Location location) {
super(location);
}
public void setLongitudeAndLatitude(double latitude, double longitude) {
setLatitude(latitude);
setLongitude(longitude);
}
public void setLongitudeAndLatitude(double[] latitudeAndLongitude) {
setLongitudeAndLatitude(latitudeAndLongitude[0], latitudeAndLongitude[1]);
}
@Override
public @FloatRange(from = -90.0, to = 90.0) double getLatitude(){
Location location;
if (whetherUseGcj02Coordinate() && coordinate == coordinate_gps84) {
location = getLocationInGCJ02();
}else {location=this;}
return location.getLatitude(coordinate_gps84);
}
public @FloatRange(from = -90.0, to = 90.0) double getLatitude(int coordinate){
if (coordinate==coordinate_gps84){
return super.getLatitude();
}else {return getLatitude();}
}
@Override
public @FloatRange(from = -180.0, to = 180.0) double getLongitude() {
Location location;
if (whetherUseGcj02Coordinate() && coordinate == coordinate_gps84) {
location = getLocationInGCJ02();
}else {location=this;}
return location.getLongitude(coordinate_gps84);
}
public @FloatRange(from = -180.0, to = 180.0) double getLongitude(int coordinate) {
if (coordinate == coordinate_gps84) {
return super.getLongitude();
}else {return getLongitude();}
}
public LatLng getLatLng() {
LatLng latLng = new LatLng(getLatitude(), getLongitude());
return latLng;
}
public boolean whetherUseGcj02Coordinate() {
boolean autoJudge=false;
if (autoJudge) {
int n = locationsListUseGCJ02.size();
int count = 0;
double x = getLongitude(coordinate_gps84);
double y = getLatitude(coordinate_gps84);
for (int i = 0; i < n; i++) {
double[] p1 = locationsListUseGCJ02.get(i);
double[] p2 = locationsListUseGCJ02.get((i + 1) % n);
if (y > Math.min(p1[1], p2[1]) && y <= Math.max(p1[1], p2[1])) {
double xinters = (y - p1[1]) * (p2[0] - p1[0]) / (p2[1] - p1[1]) + p1[0];
if (x < xinters) {
count++;
}
}
}
return count % 2 == 1;//记数为奇数代表在该多边形内部
}else {
return true;
}
}
public MarkerOptions getMarkerOptions(boolean draggable) {
MarkerOptions markerOptions = new MarkerOptions()
.draggable(draggable)
.position(getLatLng());
return markerOptions;
}
public Marker getMarker(AMap aMap, boolean draggable) {
Marker marker = aMap.addMarker(getMarkerOptions(draggable));
if (marker != null) {
marker.showInfoWindow();
}
if (marker == null) {
throw new RuntimeException("currentMarker is not initialized successfully");
}
return marker;
}
public void setWhetherDrifting(int whetherDrifting) {
this.whetherDrifting = whetherDrifting;
}
public int getWhetherDrifting() {
return whetherDrifting;
}
//是否是漂移数据
public int getWhetherDriftingSource() {
return whetherDriftingSource;
}
public void setWhetherDriftingSource(int whetherDriftingSource) {
this.whetherDriftingSource = whetherDriftingSource;
}
public String getWhetherDriftingSourceTitle(Context context) {
String WhetherDriftingSourceTitle = context.getString(R.string.undefined_drift_source);
switch (whetherDriftingSource) {
case 0:
WhetherDriftingSourceTitle = "";
case whetherDriftingSource_handset:
WhetherDriftingSourceTitle = context.getString(R.string.mutual_set);
break;
case whetherDriftingSource_sameLongitudeAndLatitude:
WhetherDriftingSourceTitle = context.getString(R.string.altitude_and_latitude_unchange);
break;
case whetherDriftingSource_below5s:
WhetherDriftingSourceTitle = context.getString(R.string.network_state_existed_below_5s);
break;
case whetherDriftingSource_accuracyExceeded:
WhetherDriftingSourceTitle = context.getString(R.string.accuracy_exceeded);
break;
}
return WhetherDriftingSourceTitle;
}
public void setRefreshedNumber(int refreshedNumber) {
this.refreshedNumber = refreshedNumber;
}
public int getRefreshedNumber() {
return refreshedNumber;
}
public Location Clone() {
Location cloned = new Location(this.getProvider());
cloned.setLatitude(this.getLatitude(coordinate_gps84));
cloned.setLongitude(this.getLongitude(coordinate_gps84));
cloned.setAccuracy(this.getAccuracy());
cloned.setAltitude(this.getAltitude());
cloned.setBearing(this.getBearing());
cloned.setSpeed(this.getSpeed());
cloned.setTime(this.getTime());
cloned.whetherDrifting = this.whetherDrifting;
cloned.whetherDriftingSource = this.whetherDriftingSource;
cloned.refreshedNumber = this.refreshedNumber;
cloned.coordinate = this.coordinate;
return cloned;
}
//原始情况下location用WGS84坐标存储,对于中国大部分导航软件需要使用GCJ02(换火星坐标)
public Location getLocationInGCJ02() {
//WGS84转GCJ02(换火星坐标)
Location transferedLocation = this.Clone();
transferedLocation.setLongitudeAndLatitude(GpsFormatTrans.gps84_To_Gcj02(this.getLatitude(coordinate_gps84), this.getLongitude(coordinate_gps84)));
return transferedLocation;
}
public boolean equal(Location location) {
if (location == null) {
return false;
}
double longitude1 = getLongitude();
double latitude1 = getLatitude(coordinate_gps84);
double altitude1 = getAltitude();
float speed1 = getSpeed();
float bearing1 = getBearing();
float accuracy1 = getAccuracy();
String provider1 = getProvider();
double longitude2 = location.getLongitude();
double latitude2 = location.getLatitude(coordinate_gps84);
double altitude2 = location.getAltitude();
float speed2 = location.getSpeed();
float bearing2 = location.getBearing();
float accuracy2 = location.getAccuracy();
String provider2 = location.getProvider();
return longitude1 == longitude2
&& latitude1 == latitude2
&& altitude1 == altitude2
&& speed1 == speed2
&& bearing1 == bearing2
&& accuracy1 == accuracy2
&& Objects.equals(provider1, provider2);
}
public double getDistance(Location location) {
return GpsFormatTrans.getDistance(this, location);//单位m
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(this.whetherDrifting);
if (this.whetherDriftingSource != 0) {
dest.writeInt(1); // 使用一个标志位表示非空
dest.writeInt(this.whetherDriftingSource);
} else {
dest.writeInt(0); // 使用一个标志位表示为空
}
dest.writeInt(this.refreshedNumber);
dest.writeInt(this.coordinate);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public Location createFromParcel(Parcel in) {
Location location = new Location(android.location.Location.CREATOR.createFromParcel(in));
location.whetherDrifting = in.readInt();
location.whetherDriftingSource = in.readInt() == 1 ? in.readInt() : 0;
location.refreshedNumber = in.readInt();
location.coordinate = in.readInt();
return location;
}
@Override
public Location[] newArray(int size) {
// 创建Location对象数组
return new Location[size];
}
};
}