`

道格拉斯-普克算法

阅读更多
项目中用到,记录下来。

import java.util.ArrayList;
import java.util.List;

import com.vividsolutions.jts.geom.*;

/**
 * 道格拉斯普克抽希
 */
public class Douglas {
    private static GeometryFactory factory = new GeometryFactory();

    /**
     * 对矢量曲线进行压缩
     */
    public static LineString compress(LineString line, double precision) {
        if(line.getNumPoints() < 3)
            return line;

        List<Coordinate> points = compress(line, 0, line.getNumPoints()-1, precision);

        Coordinate[] coordinates = new Coordinate[points.size()];
        points.toArray(coordinates);

        return factory.createLineString(coordinates);
    }

    /**
     *
     * */
    public static List<Coordinate> compress(Coordinate[] coordinates,int fromIndex,int toIndex,double precision){


        List<Coordinate> sparse_pts = new ArrayList<>();

        Coordinate from = coordinates[fromIndex];
        Coordinate to = coordinates[toIndex];

        if ((fromIndex + 1) == toIndex) {
            sparse_pts.add(from);
            sparse_pts.add(to);
            return sparse_pts;
        }

        /**
         * 由起始点和终止点构成的直线方程一般式的系数
         */
        double A = (from.y - to.y)
                / Math.sqrt(Math.pow((from.y - to.y), 2)
                + Math.pow((from.x - to.x), 2));

        /**
         * 由起始点和终止点构成的直线方程一般式的系数
         */
        double B = (to.x - from.x)
                / Math.sqrt(Math.pow((from.y - to.y), 2)
                + Math.pow((from.x - to.x), 2));

        /**
         * 由起始点和终止点构成的直线方程一般式的系数
         */
        double C = (from.x * to.y - to.x * from.y)
                / Math.sqrt(Math.pow((from.y - to.y), 2)
                + Math.pow((from.x - to.x), 2));


        int middleIndex = 0;
        double dmax = 0;

        for (int i = fromIndex + 1; i < toIndex; i++) {
            double dis = Math.abs(A * (coordinates[i].x) + B * (coordinates[i].y) + C)
                    / Math.sqrt(Math.pow(A, 2)
                    + Math.pow(B, 2));

            if(dis < dmax)
                continue;

            dmax = dis;
            middleIndex = i;
        }

        sparse_pts.add(from);

        if (dmax > precision) {
            List<Coordinate> fronts = compress(coordinates, fromIndex, middleIndex, precision);
            fronts.remove(0);
            fronts.remove(fronts.size()-1);
            sparse_pts.addAll(fronts);

            List<Coordinate> backs = compress(coordinates, middleIndex, toIndex, precision);
            backs.remove(backs.size()-1);
            sparse_pts.addAll(backs);
        }

        sparse_pts.add(to);

        return sparse_pts;
    }

    private static List<Coordinate> compress(LineString line, int fromIndex, int toIndex, double precision){
        List<Coordinate> sparse_pts = new ArrayList<>();

        Coordinate from = line.getCoordinateN(fromIndex);
        Coordinate to = line.getCoordinateN(toIndex);

        if ((fromIndex + 1) == toIndex) {
            sparse_pts.add(from);
            sparse_pts.add(to);
            return sparse_pts;
        }

        /**
         * 由起始点和终止点构成的直线方程一般式的系数
         */
        double A = (from.y - to.y)
                / Math.sqrt(Math.pow((from.y - to.y), 2)
                + Math.pow((from.x - to.x), 2));

        /**
         * 由起始点和终止点构成的直线方程一般式的系数
         */
        double B = (to.x - from.x)
                / Math.sqrt(Math.pow((from.y - to.y), 2)
                + Math.pow((from.x - to.x), 2));

        /**
         * 由起始点和终止点构成的直线方程一般式的系数
         */
        double C = (from.x * to.y - to.x * from.y)
                / Math.sqrt(Math.pow((from.y - to.y), 2)
                + Math.pow((from.x - to.x), 2));


        int middleIndex = 0;
        double dmax = 0;

        for (int i = fromIndex + 1; i < toIndex; i++) {
            double dis = Math.abs(A * (line.getCoordinateN(i).x) + B * (line.getCoordinateN(i).y) + C)
                            / Math.sqrt(Math.pow(A, 2)
                            + Math.pow(B, 2));

            if(dis < dmax)
                continue;

            dmax = dis;
            middleIndex = i;
        }

        sparse_pts.add(from);

        if (dmax > precision) {
            List<Coordinate> fronts = compress(line, fromIndex, middleIndex, precision);
            fronts.remove(0);
            fronts.remove(fronts.size()-1);
            sparse_pts.addAll(fronts);

            List<Coordinate> backs = compress(line, middleIndex, toIndex, precision);
            backs.remove(backs.size()-1);
            sparse_pts.addAll(backs);
        }

        sparse_pts.add(to);

        return sparse_pts;
    }
}


关注微信号 codingworld  码农大世界 获取更多信息和作者互动问答。
分享到:
评论

相关推荐

    道格拉斯-普克抽稀算法,java 实现

    道格拉斯-普克抽稀算法,java 实现

    道格拉斯普克算法

    道格拉斯-普克(Douglas-Peucker)算法,是一种在数字地图...通过分析和理解这些代码,我们可以更好地掌握道格拉斯-普克算法的实现细节,并将其应用到实际项目中,例如简化地理路径数据、绘制高效率的图形界面元素等。

    船舶AIS数据道格拉斯-普克(DP)压缩python代码

    代码对于船舶AIS数据进行道格拉斯-普克(DP)算法压缩,并能生成算法压缩后的数据量以及可视化呈现压缩结果。

    用Java实现的道格拉斯-普克压缩算法

    在Java中实现道格拉斯-普克算法,首先需要理解其基本步骤: 1. **选择起点和终点**:算法从一条线段的起始点和结束点开始,这两个点构成了一个基本的子序列。 2. **计算最大距离**:对这条线段上的所有中间点,...

    道格拉斯普克抽稀算法,道格拉斯普克法算法,Python

    - 道格拉斯-普克算法的核心思想是通过选择一个起始点和一个结束点,然后计算所有中间点与起点和终点连线的垂直距离,找出距离最大的点。 - 将最大距离点加入到简化后的线段中,并以这个点为新的起点和终点,重复...

    daogelasi.rar_道格拉斯_道格拉斯-普克_道格拉斯佩克_道格拉斯普克

    **道格拉斯-普克算法详解** 道格拉斯-普克(Douglas-Peucker)算法,也称为DP算法,是计算机图形学和地理信息系统(GIS)领域中一个经典且重要的算法,主要用于简化多边形或曲线,尤其是地理空间数据中的线性特征,...

    DP.rar_DP道格拉斯_线 化简_道格拉斯_道格拉斯-普克_道格拉斯普克

    道格拉斯-普克算法的核心思想是通过测量离直线段最远的点来确定简化过程中的关键点。以下是对该算法的详细步骤和原理的阐述: 1. **选择起点**:选取多边形或曲线的第一个点作为起始点A。 2. **构建直线段**:连接...

    道格拉斯-普克压缩算法

    **道格拉斯-普克压缩算法详解** 道格拉斯-普克(Douglas-Peucker,简称DP)压缩算法是一种常见的点序列简化算法,广泛应用于GIS(地理信息系统)和计算机图形学领域。该算法的主要目的是减少点的数量,同时尽可能...

    道格拉斯普克(Douglas-Peuker)算法抽取几何外形-matlab实现

    总的来说,道格拉斯-普克算法在MATLAB中的实现是一项实用技能,能够帮助我们有效地处理点云数据,尤其是在需要进行图形渲染、数据分析或数据存储时。通过理解算法原理并熟练运用MATLAB编程,我们可以快速实现这一...

    matlab-Douglas-Peucker.zip_Douglas_拉克斯_道格拉斯_道格拉斯 matlab_道格拉斯普克

    道格拉斯-普克算法(Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法、迭代适应点算法、分裂与合并算法)是将曲线近似表示为一系列点,并减少点的数量的一种算法。它的优点是具有平移和旋转不变性,给定...

    增强型道格拉斯_普克压缩算法的设计与实现

    ### 增强型道格拉斯-普克压缩算法的设计与实现 #### 一、引言 随着“数字地球”概念的提出和发展,对于大范围、高精度的地理信息系统(GIS)数据的需求日益增长。在构建这样的系统时,需要处理海量的矢量数据。...

    道格拉斯普克算法的C++实现

    首先,理解道格拉斯-普克算法的基本原理至关重要。该算法的核心思想是通过迭代找到离原路径最远的点,然后将该点及其相邻点之间的线段删除,重复此过程直到满足预设的精度要求。简而言之,算法分为以下几个步骤: 1...

    道格拉斯普克抽稀算法,道格拉斯普克法算法,Python源码.zip

    在Python中实现道格拉斯-普克算法,通常需要以下步骤: 1. 定义一个函数,接受输入参数为原始点集和距离阈值。 2. 初始化起始点和结束点,创建初始线段。 3. 计算所有点到初始线段的垂直距离,找出最大距离点。 4. ...

    GDAL.zip_Douglas-Peucker_GDAL_canallrl_道格拉斯_道格拉斯 普克

    总的来说,"GDAL.zip_Douglas-Peucker_GDAL_canallrl_道格拉斯_道格拉斯_普克"这个压缩包文件很可能包含了关于如何在GDAL库中实现道格拉斯-普克算法的示例代码或文档。对于想要在GIS项目中应用此算法的开发者来说,...

    c#道格拉斯普克算法设计

    根据道格拉斯压缩算法的原理,使用c#语言编写窗体程序,实现坐标点的线性化

    vc++道格拉斯算法源代码

    首先,道格拉斯-普克算法的核心思想是基于欧几里得距离来判断点的重要性。具体步骤如下: 1. **选取起点**:选择一条曲线上的一个端点作为起点。 2. **计算最大距离**:遍历曲线上的所有点,计算它们与起点到终点...

    道格拉斯算法

    道格拉斯-普克算法的核心是判断一个点是否“重要”。对于一条由多个点构成的线段,如果某个点与两端点连线的垂直距离小于一定的阈值,则认为该点对线段的形状影响不大,可以被省略。这个阈值是算法的关键参数,根据...

Global site tag (gtag.js) - Google Analytics