百度地图API-JAVA判断2个区域是否重合(使用java.awt.geom.Line2D)

本文介绍了一种基于线段相交和点在多边形内的算法,用于判断两个地理区域是否重叠。通过百度地图API绘制区域,利用Java的GeneralPath和Line2D类实现区域重叠的判断。

思路

1判断区域的线段是否相交

2判断区域的包含关系

图例

区域使用百度地图API-开源库-鼠标绘制工具条库制作

测试

boolean a = isCoinCide(locationList1, locationList3);
System.out.println("是否存在重合区域:" + a);

是否存在重合区域:false

boolean a = isCoinCide(locationList1, locationList2);
System.out.println("是否存在重合区域:" + a);

是否存在重合区域:true

boolean a = isCoinCide(locationList2, locationList2);
System.out.println("是否存在重合区域:" + a);

是否存在重合区域:true

boolean a = isCoinCide(locationList3, locationList4);
System.out.println("是否存在重合区域:" + a);

是否存在重合区域:true

boolean a = isCoinCide(locationList2, locationList4);
System.out.println("是否存在重合区域:" + a);

是否存在重合区域:false

说明

重点方法

1判断线段是否相交

private static boolean isIntersect(List<Line> lineList, List<Line> lineList2) {
        for (Line line : lineList) {
            for (Line line1 : lineList2) {
                //两条线段是否相交
                boolean b = Line2D.linesIntersect(line.location1.longitude, line.location1.latitude, line.location2.longitude, line.location2.latitude,
                        line1.location1.longitude, line1.location1.latitude, line1.location2.longitude, line1.location2.latitude);
                if (b) {
                    return true;
                }
            }
        }
        return false;
    }

2判断点是否在多边形内

private static boolean isPointInPolygon(Location location, List<Location> locationList2) {
        //点是否在多边形内
        GeneralPath path = new GeneralPath();
        //设定多边形起始点
        path.moveTo(locationList2.get(0).getLongitude(), locationList2.get(0).getLatitude());
        for (Location l : locationList2) {
            path.lineTo(l.getLongitude(), l.getLatitude());
        }
        //图像完成,封闭
        path.moveTo(locationList2.get(0).getLongitude(), locationList2.get(0).getLatitude());
        //多边形结束
        path.closePath();
        return path.contains(location.getLongitude(), location.getLatitude());
    }

源码

package com.asyf.demo.map.test02;

import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;

public class Test {

    /**
     * 判断2个区域是否重合
     *
     * @param args
     */
    public static void main(String[] args) {
        //区域1-四边形
        List<Location> locationList1 = new ArrayList<>();
        locationList1.add(new Location(117.21455815237613, 39.1469865872148));
        locationList1.add(new Location(117.22001984987679, 39.1441884617389));
        locationList1.add(new Location(117.21624696673489, 39.1395713095368));
        locationList1.add(new Location(117.2074795049575, 39.14060669749416));

        //区域2-三角形
        List<Location> locationList2 = new ArrayList<>();
        locationList2.add(new Location(117.21915747658721, 39.147798022626574));
        locationList2.add(new Location(117.22458324186748, 39.14323707353132));
        locationList2.add(new Location(117.21660628893888, 39.14270540976905));

        //区域3-三角形-和其他的不重合
        List<Location> locationList3 = new ArrayList<>();
        locationList3.add(new Location(117.22109781648876, 39.14122232629915));
        locationList3.add(new Location(117.22591273402224, 39.13820009645245));
        locationList3.add(new Location(117.21775611999165, 39.13710870353047));

        //区域4-三角形-在3的外面
        List<Location> locationList4 = new ArrayList<>();
        locationList4.add(new Location(117.22055883318278, 39.14228567236032));
        locationList4.add(new Location(117.22849985389098, 39.137780331962446));
        locationList4.add(new Location(117.2157079834289, 39.13526169203842));

        boolean a = isCoinCide(locationList2, locationList3);
        System.out.println("是否存在重合区域:" + a);

    }

    private static boolean isCoinCide(List<Location> locationList, List<Location> locationList2) {
        //获取四边形的线段
        List<Line> lineList = getLines(locationList);
        //获取三角形的线段
        List<Line> lineList2 = getLines(locationList2);
        //判断是否相交
        boolean isIntersect = isIntersect(lineList, lineList2);
        if (isIntersect) return true;
        //如果不相交判断是否包含-由于没有相交线段只要存在点在多边形内就说明包含
        boolean isPolygonInPolygon = isPolygonInPolygon(locationList, locationList2);
        if (isPolygonInPolygon) return true;
        return false;
    }

    private static boolean isPolygonInPolygon(List<Location> locationList, List<Location> locationList2) {
        //判断第一个多边形是否在第二个多边形内
        for (Location location : locationList) {
            boolean isPointInPolygon = isPointInPolygon(location, locationList2);
            if (isPointInPolygon) return true;
        }
        //判断第二个多边形是否在第一个多边形内
        for (Location location : locationList2) {
            boolean isPointInPolygon = isPointInPolygon(location, locationList);
            if (isPointInPolygon) return true;
        }
        return false;
    }

    private static boolean isPointInPolygon(Location location, List<Location> locationList2) {
        //点是否在多边形内
        GeneralPath path = new GeneralPath();
        //设定多边形起始点
        path.moveTo(locationList2.get(0).getLongitude(), locationList2.get(0).getLatitude());
        for (Location l : locationList2) {
            path.lineTo(l.getLongitude(), l.getLatitude());
        }
        //图像完成,封闭
        path.moveTo(locationList2.get(0).getLongitude(), locationList2.get(0).getLatitude());
        //多边形结束
        path.closePath();
        return path.contains(location.getLongitude(), location.getLatitude());
    }

    private static boolean isIntersect(List<Line> lineList, List<Line> lineList2) {
        for (Line line : lineList) {
            for (Line line1 : lineList2) {
                //两条线段是否相交
                boolean b = Line2D.linesIntersect(line.location1.longitude, line.location1.latitude, line.location2.longitude, line.location2.latitude,
                        line1.location1.longitude, line1.location1.latitude, line1.location2.longitude, line1.location2.latitude);
                if (b) {
                    return true;
                }
            }
        }
        return false;
    }

    private static List<Line> getLines(List<Location> locationList) {
        List<Line> lineList = new ArrayList();
        for (int i = 0; i < locationList.size(); i++) {
            if (i < locationList.size() - 1) {
                Location l = locationList.get(i);
                Location l2 = locationList.get(i + 1);
                Line line = new Line(l, l2);
                lineList.add(line);
            } else {
                Location l = locationList.get(i);
                Location l2 = locationList.get(0);
                Line line = new Line(l, l2);
                lineList.add(line);
            }
        }
        return lineList;
    }

    //线段
    public static class Line {
        private Location location1;//起点
        private Location location2;//终点

        public Line(Location location1, Location location2) {
            this.location1 = location1;
            this.location2 = location2;
        }

        public Location getLocation1() {
            return location1;
        }

        public void setLocation1(Location location1) {
            this.location1 = location1;
        }

        public Location getLocation2() {
            return location2;
        }

        public void setLocation2(Location location2) {
            this.location2 = location2;
        }

        @Override
        public String toString() {
            return "Line{" +
                    "location1=" + location1 +
                    ", location2=" + location2 +
                    '}';
        }
    }

    //经纬度坐标
    public static class Location {

        private double longitude;//经度
        private double latitude;//纬度

        public Location(double longitude, double latitude) {
            this.longitude = longitude;
            this.latitude = latitude;
        }

        public double getLongitude() {
            return longitude;
        }

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

        public double getLatitude() {
            return latitude;
        }

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

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

}

参考文献

https://blog.youkuaiyun.com/c5113620/article/details/82014058

提供的引用中未提及解决“class java.awt.geom.Rectangle2D$Double cannot be cast to class java.awt.Rectangle (java.awt.geom.Rectangle2D$Double and java.awt.Rectangle are in module java.desktop of loader 'bootstrap')”错误的方法。不过,通常这种类型转换错误是因为尝试将一个对象强制转换为不兼容的类型。以下是一些可能的解决思路: ### 检查代码逻辑 确保代码中没有错误地尝试将 `java.awt.geom.Rectangle2D.Double` 对象强制转换为 `java.awt.Rectangle` 对象。这两个类虽然都与矩形有关,但它们是不同的类,不能直接进行强制类型转换。 ### 使用适当的转换方法 如果需要从 `Rectangle2D.Double` 获取 `Rectangle` 的等效信息,可以通过提取 `Rectangle2D.Double` 的属性来创建一个新的 `Rectangle` 对象。示例代码如下: ```java import java.awt.Rectangle; import java.awt.geom.Rectangle2D; public class RectangleConversion { public static void main(String[] args) { Rectangle2D.Double rect2D = new Rectangle2D.Double(10, 20, 30, 40); // 创建一个新的 Rectangle 对象 Rectangle rect = new Rectangle( (int) rect2D.getX(), (int) rect2D.getY(), (int) rect2D.getWidth(), (int) rect2D.getHeight() ); System.out.println("Rectangle: " + rect); } } ``` ### 类型检查 在进行类型转换之前,使用 `instanceof` 关键字检查对象的类型,避免不必要的类型转换错误。示例代码如下: ```java import java.awt.Rectangle; import java.awt.geom.Rectangle2D; public class TypeCheckExample { public static void main(String[] args) { Rectangle2D.Double rect2D = new Rectangle2D.Double(10, 20, 30, 40); if (rect2D instanceof Rectangle) { Rectangle rect = (Rectangle) rect2D; System.out.println("Converted to Rectangle: " + rect); } else { System.out.println("Cannot convert Rectangle2D.Double to Rectangle."); } } } ```
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值