基于JTS实现对空间绘图的WTK语言标记

在项目中用到在地图上绘图进行区域标记,为了便于存储这些区域的绘图信息,以及方便其他GIS工具识别,于是采用WTK标记语言作为空间图形存储,可以方便地将点、圆、多边形的经纬度转成可识别的字符串存储到数据库中,以及从数据库中读取这些数据,转换成经纬度上图。

需要用到的jar包

gt-api-19.1.jar
gt-main-19.1.jar
gt-metadata-19.1.jar
gt-referencing-19.1.jar
jts-core-1.14.0.jar
jts-io-1.14.0.jar

或者通过maven管理:

<!-- geometry -->
<dependency>
    <groupId>com.vividsolutions</groupId>
    <artifactId>jts-core</artifactId>
    <version>1.14.0</version>
</dependency>

<dependency>
    <groupId>com.vividsolutions</groupId>
    <artifactId>jts-io</artifactId>
    <version>1.14.0</version>
</dependency>

<dependency>
    <groupId>org.geotools</groupId>
    <artifactId>gt-main</artifactId>
    <version>2.7.4-GBE-276</version>
</dependency>

实现代码

/**
 * 基于JTS实现对空间绘图的WTK语言标记
 */
public class GeometryDemo {
    private static GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);

    /**
     * 将字符串转成{@code Point}对象
     *
     * @param pointStr 形如{@code POINT (1.1,1.2)}
     * @return
     * @see Point
     */
    public static Point createPoint(String pointStr) {
        checkArgument(Objects.nonNull(pointStr), "pointStr must not be null.");
        WKTReader reader = new WKTReader(geometryFactory);
        Point point = null;
        try {
            point = (Point) reader.read(pointStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return point;
    }

    /**
     * 将一个经纬度转成{@code Point}对象
     *
     * @param longitude 经度
     * @param latitude  纬度
     * @return
     */
    public static Point createPoint(double longitude, double latitude) {
        return createPoint(createPointString(new WarpLatitude(longitude, latitude)));
    }

    /**
     * 将WKT标记的点转换成经纬度对象
     *
     * @param pointStr
     * @return
     */
    public static WarpLatitude pointToLonLan(String pointStr) {
        Point point = createPoint(pointStr);
        return new WarpLatitude(point.getX(), point.getY());
    }

    /**
     * 将WKT字符串转换成Polygon对象
     *
     * @param areaStr
     * @return
     */
    public static Polygon createPolygon(String areaStr) {
        WKTReader reader = new WKTReader(geometryFactory);
        Polygon polygon = null;
        try {
            polygon = (Polygon) reader.read(areaStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return polygon;
    }

    /**
     * 根据给定的经纬度创建一个面
     *
     * @param longitude1 第一个点的经度
     * @param latitude1  第一个点的纬度
     * @param longitude2 第二个点的经度
     * @param latitude2  第二个点的纬度
     * @param longitude3 第三个点的经度
     * @param latitude3  第三个点的纬度
     * @param longlan    其他点的经纬度,必须成对出现
     * @return
     */
    public static Polygon craetePolygon(double longitude1, double latitude1, double longitude2, double latitude2, double longitude3, double latitude3, double... longlan) {
        List<WarpLatitude> latitudes = Lists.newArrayList();
        latitudes.add(new WarpLatitude(longitude1, latitude1));
        latitudes.add(new WarpLatitude(longitude2, latitude2));
        latitudes.add(new WarpLatitude(longitude3, latitude3));
        if (longlan != null && longlan.length > 0) {
            if (longlan.length % 2 != 0) {
                throw new IllegalArgumentException("其他点的经纬度必须成对出现");
            }
            int cursor = 0;
            double longitude = 0d, latitude = 0d;
            for (int i = 0; i < longlan.length; i++) {
                if (i % 2 == 0) {
                    longitude = longlan[i];
                } else {
                    latitude = longlan[i];
                }
                if (cursor == 1) {
                    latitudes.add(new WarpLatitude(longitude, latitude));
                    cursor = 0;
                } else {
                    cursor++;
                }
            }
        }
        return createPolygon(createPolygonString(latitudes));
    }

    /**
     * 将WKT标记的面转换成经纬度集合
     *
     * @param polygonStr
     * @return
     */
    public static List<WarpLatitude> polygonToLonLans(String polygonStr) {
        Polygon polygon = createPolygon(polygonStr);
        Coordinate[] coordinates = polygon.getCoordinates();
        List<WarpLatitude> warpLatitudes = Lists.newArrayListWithCapacity(coordinates.length);
        for (int i = 0; i < coordinates.length; i++) {
            Coordinate coordinate = coordinates[i];
            warpLatitudes.add(new WarpLatitude(coordinate.x, coordinate.y));
        }
        return warpLatitudes;
    }

    /**
     * 将一个经纬度数据转换成WKT能够解读的点的字符串
     *
     * @param warpLatitude
     * @return
     */
    private static String createPointString(WarpLatitude warpLatitude) {
        return "POINT (" + warpLatitude + ")";
    }


    /**
     * 将多个经纬度数据转换成一个面
     *
     * @param warpLatitudes
     * @return
     */
    private static String createPolygonString(List<WarpLatitude> warpLatitudes) {
        StringBuilder polygons = new StringBuilder("POLYGON((");
        polygons.append(Joiner.on(",").join(warpLatitudes));
        polygons.append("))");
        return polygons.toString();
    }

    private static class WarpLatitude {
        /**
         * 经度
         */
        private double longitude;
        /**
         * 纬度
         */
        private double latitude;

        public WarpLatitude(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 this.longitude + " " + this.latitude;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/twypx/article/details/81178439