java经纬度抽稀算法 (拉默–道格拉斯–普克算法)

public static List<LatLng> simplify(List<LatLng> list, double tolerance) {
    int index = 0;
    double dmax = 0;
    int lastIndex = list.size() - 1;

    // Find the point with the maximum distance
    for (int i = 1; i < lastIndex; i++) {
        double d = pointToLineDistance(list.get(0), list.get(lastIndex), list.get(i));
        if (d > dmax) {
            index = i;
            dmax = d;
        }
    }

    // If max distance is greater than epsilon, recursively simplify
    List<LatLong> ResultList = new ArrayList<LatLong>();
    if (dmax > tolerance) {
        // Recursive call
        List<LatLong> recResults1 = simplify(list.subList(0, index + 1), tolerance);
        List<LatLong> recResults2 = simplify(list.subList(index, lastIndex + 1), tolerance);

        // Build the result list
        recResults1.remove(recResults1.size() - 1);
        ResultList.addAll(recResults1);
        ResultList.addAll(recResults2);
    } else {
        ResultList.add(list.get(0));
        ResultList.add(list.get(lastIndex));
    }

    // Return the result
    return ResultList;
}
/**
 * 提供从点P到穿过a - B的线段的距离。如果点不在直线的一边,则返回到最近点的距离
 * Provides the distance from a point P to the line segment that passes
 * distance to the closest point
 *
 * @param p1    First point of the line
 * @param p2    Second point of the line
 * @param point Point to measure the distance
 * through A-B. If the point is not on the side of the line, returns the
 */
public static double pointToLineDistance(LatLong p1, LatLong p2, LatLong point) {
    double A = point.getLatitude() - p1.getLatitude();
    double B = point.getLongitude() - p1.getLongitude();
    double C = p2.getLatitude() - p1.getLatitude();
    double D = p2.getLongitude() - p1.getLongitude();

    double dot = A * C + B * D;
    double len_sq = C * C + D * D;
    double param = dot / len_sq;

    double xx, yy;

    if (param < 0) // point behind the segment
    {
        xx = p1.getLatitude();
        yy = p1.getLongitude();
    } else if (param > 1) // point after the segment
    {
        xx = p2.getLatitude();
        yy = p2.getLongitude();
    } else { // point on the side of the segment
        xx = p1.getLatitude() + param * C;
        yy = p1.getLongitude() + param * D;
    }

    return Math.hypot(xx - point.getLatitude(), yy - point.getLongitude());
}
public class LatLong implements Parcelable, Serializable {

    /**
     * Stores latitude, and longitude in degrees
     */
    public double latitude;
    public double longitude;
    private boolean important = true;
    public boolean isImportant() {
        return important;
    }

    public void setImportant(boolean important) {
        this.important = important;
    }
    public LatLong(double latitude, double longitude) {
        this.latitude = latitude;
        this.longitude = longitude;
    }

    public LatLong(LatLong copy) {
        this(copy.getLatitude(), copy.getLongitude());
    }

    public void set(LatLong update) {
        this.latitude = update.latitude;
        this.longitude = update.longitude;
    }

    public boolean isNull() {
        return latitude == 0 && longitude == 0;
    }

    /**
     * @return the latitude in degrees
     */
    public double getLatitude() {
        return latitude;
    }

    /**
     * @return the longitude in degrees
     */
    public double getLongitude() {
        return longitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public LatLong dot(double scalar) {
        return new LatLong(latitude * scalar, longitude * scalar);
    }

    public LatLong negate() {
        return new LatLong(latitude * -1, longitude * -1);
    }

    public LatLong subtract(LatLong coord) {
        return new LatLong(latitude - coord.latitude, longitude - coord.longitude);
    }

    public LatLong sum(LatLong coord) {
        return new LatLong(latitude + coord.latitude, longitude + coord.longitude);
    }

    public static LatLong sum(LatLong... toBeAdded) {
        double latitude = 0;
        double longitude = 0;
        for (LatLong coord : toBeAdded) {
            latitude += coord.latitude;
            longitude += coord.longitude;
        }
        return new LatLong(latitude, longitude);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof LatLong)) {
            return false;
        }

        LatLong latLong = (LatLong) o;

        if (Double.compare(latLong.latitude, latitude) != 0) {
            return false;
        }
        if (Double.compare(latLong.longitude, longitude) != 0) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        int result;
        long temp;
        temp = Double.doubleToLongBits(latitude);
        result = (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(longitude);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

    @Override
    public String toString() {
        return "LatLong{" +
                "latitude=" + latitude +
                ", longitude=" + longitude +
                '}';
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeSerializable(this);
    }

    public static final Parcelable.Creator<LatLong> CREATOR = new Parcelable.Creator<LatLong>() {
        public LatLong createFromParcel(Parcel source) {
            return (LatLong) source.readSerializable();
        }

        public LatLong[] newArray(int size) {
            return new LatLong[size];
        }
    };
}

猜你喜欢

转载自blog.csdn.net/weixin_44819566/article/details/106049943
今日推荐