Advertisement

GeoTools实战指南:坐标转换的专业工具

阅读量:

GeoTools实战指南:坐标转换的专业工具

介绍

GeoTools是一款具备卓越性能的坐标转换软件,在处理多种坐标系统时展现出极高的精确度与效率水平。该软件不仅具备自动识别功能,并能根据需求进行自定义投影设置,在优化方面也表现优异的能力使其成为地理信息系统领域的理想选择之一;无论是在专业制图工作还是空间数据分析领域亦或是学术研究领域均展现出显著的应用价值;此外该软件采用开放源代码且具有扩展性特征的特点进一步提升了其适应能力使其能够满足各类复杂的地理信息系统需求

项目依赖

首先,请安装GeoTools库到您的项目中。通过Maven工具实现依赖管理,也可以选择直接获取GeoTools的jar包并将其放置在项目的classes目录下。

pom.xml

复制代码
    <properties>
        <java.version>8</java.version>
        <geotools.version>28.0</geotools.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-shapefile</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geotiff</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-image</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-render</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-cql</artifactId>
            <version>${geotools.version}</version>
        </dependency>
    
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-xml</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-process-raster</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-swing</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools.jdbc</groupId>
            <artifactId>gt-jdbc-postgis</artifactId>
            <version>${geotools.version}</version>
        </dependency>
    
        <dependency>
            <groupId>net.sf.geographiclib</groupId>
            <artifactId>GeographicLib-Java</artifactId>
            <version>1.49</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-epsg-hsql</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.locationtech.proj4j</groupId>
            <artifactId>proj4j</artifactId>
            <version>1.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.locationtech.jts</groupId>
            <artifactId>jts-core</artifactId>
            <version>1.18.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>
    
    </dependencies>
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI助手

地理坐标转换代码

该软件包为用户提供了一个强大的坐标转换功能。该软件包支持在多种坐标系统间便捷地进行转换操作,并提供示例说明。其中包含多种几何处理工具如Point、MultiPoint等。

CoordinateTransformation.java

复制代码
    import org.geotools.geometry.jts.JTS;
    import org.geotools.geometry.jts.JTSFactoryFinder;
    import org.geotools.referencing.CRS;
    import org.locationtech.jts.geom.*;
    import org.locationtech.jts.io.WKTReader;
    
    import org.opengis.referencing.crs.CoordinateReferenceSystem;
    import org.opengis.referencing.operation.MathTransform;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    
    /** * 坐标转换工具
     * * @author sunbt
     * @date 2023/8/20 0:55
     */
    public class CoordinateTransformation {
    
    private static final Logger log = LoggerFactory.getLogger(CoordinateTransformation.class);
    
    static GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
    static WKTReader reader = new WKTReader(geometryFactory);
    
    
    /** * 该模式适用于匹配两个数字的坐标,例如地理坐标或二维平面上的点,其中每个数字都不能以0开头
     * * [1-9]: 匹配一个1到9之间的数字(不包括0)。
     * \ d*: 匹配零个或多个数字字符(\ d表示数字,*表示零次或多次匹配)。
     * \ .?: 匹配零个或一个点字符(.通常在正则表达式中用作特殊字符,所以需要使用\ .来匹配实际的点字符。?表示零次或一次匹配)。
     * \ d*: 再次匹配零个或多个数字字符。
     * \ s: 匹配一个空白字符(例如空格、制表符等)。
     * [1-9]\ d*\ .?\ d*: 和前面相同,匹配一个1到9之间的数字,然后是零个或多个数字,然后是可选的小数点和更多的数字。
     */
    private static final Pattern COORDINATE_PATTERN = Pattern.compile("[1-9]\ d*\ .?\ d*\ s[1-9]\ d*\ .?\ d*");
    
    
    /** * Geometry Multi 坐标转换
     * 支持所有类型Geometry 坐标转换
     * * @param geom           地理实体
     * @param sourceEPSGCode 源坐标系
     * @param targetEPSGCode 目标坐标系
     * @return Geometry
     */
    public static Geometry geometryTransformMulti(Geometry geom, int sourceEPSGCode, int targetEPSGCode) {
        try {
            CoordinateReferenceSystem crsResource = CRS.decode("EPSG:" + sourceEPSGCode);
            CoordinateReferenceSystem crsTarget = CRS.decode("EPSG:" + targetEPSGCode);
            MathTransform transform = CRS.findMathTransform(crsResource, crsTarget, true);
            String wktString = geom.toString();
            log.debug("转换前的WKT字符串:" + wktString);
    
            Matcher matcher = COORDINATE_PATTERN.matcher(wktString);
            while (matcher.find()) {
                String cordStr = matcher.group();
                String[] cord = cordStr.split("\ s+");
                double x = Double.parseDouble(cord[0]);
                double y = Double.parseDouble(cord[1]);
    
                String point = "POINT(" + y + " " + x + ")";
                Geometry pointGeom = reader.read(point);
                Geometry resGeom = JTS.transform(pointGeom, transform);
                String[] str = resGeom.toString().substring(resGeom.toString().lastIndexOf("(") + 1, resGeom.toString().length() - 1).split("\ s+");
                String cordStr2 = str[1] + " " + str[0];
                wktString = wktString.replaceAll(cordStr, cordStr2);
            }
            log.debug("转换后的WKT字符串:" + wktString);
            return reader.read(wktString);
        } catch (Exception e) {
            log.debug("坐标系转换出错:" + e.getMessage());
            return null;
        }
    }
    
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI助手

测试方法

点坐标转换

对于单个点的转换,测试方法如下:

复制代码
    /** * Geometry 坐标转换 点
     * 4326转3857
     */
    @Test
    public void pointTest() {
        try {
            // 一个位于中国的点(例如杭州附近)
            String wktPoint = "POINT(119.81410595703113 29.86877021528116)";
            WKTReader reader = new WKTReader();
            Geometry geom = reader.read(wktPoint);
            // WGS 84
            int sourceEPSGCode = 4326;
            // Web Mercator
            int targetEPSGCode = 3857;
    
            Geometry transformedGeom = CoordinateTransformation.geometryTransformMulti(geom, sourceEPSGCode, targetEPSGCode);
            System.out.println("原始图形:" + wktPoint);
            System.out.println("转换后的图形:" + transformedGeom.toText());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI助手
image-20230820232234984

多点坐标转换

对于多点的转换,测试方法如下:

复制代码
    /** * Geometry 坐标转换 多点
     * 4326转3857
     */
    @Test
    public void multiPointTest() {
        try {
            // 一个位于中国的点(例如杭州附近)
            String wkt = "MULTIPOINT(30 20, 40 30, 20 40, 50 60)";
            WKTReader reader = new WKTReader();
            Geometry geom = reader.read(wkt);
            // WGS 84
            int sourceEPSGCode = 4326;
            // Web Mercator
            int targetEPSGCode = 3857;
    
            Geometry transformedGeom = CoordinateTransformation.geometryTransformMulti(geom, sourceEPSGCode, targetEPSGCode);
            System.out.println("原始图形:" + wkt);
            System.out.println("转换后的图形:" + transformedGeom.toText());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI助手
image-20230820232347878

线坐标转换

对于线的转换,测试方法如下:

复制代码
    /** * Geometry 坐标转换 线
     * 4326 to 3857
     */
    @Test
    public void lineStringTest() {
        String wkt = "LINESTRING(30 10, 40 30, 20 40, 50 60)";
        WKTReader reader = new WKTReader();
        try {
            Geometry geom = reader.read(wkt);
            System.out.println("原始图形: " + geom);
            // 进行坐标转换
            int sourceEPSGCode = 4326;
            int targetEPSGCode = 3857;
            // 使用上述方法进行转换
            Geometry transformedLineString = CoordinateTransformation.geometryTransformMulti(geom, sourceEPSGCode, targetEPSGCode);
    
            // 输出转换后的LineString
            System.out.println("转换后的图形: " + transformedLineString.toText());
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI助手
image-20230820232510180

多线坐标转换

对于多线的转换,测试方法如下:

复制代码
    /** * Geometry 坐标转换 多线
     * 4326 to 3857
     */
    @Test
    public void multiLineStringTest() {
        String wkt = "MULTILINESTRING((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))";
        WKTReader reader = new WKTReader();
        try {
            Geometry geom = reader.read(wkt);
            System.out.println("原始图形: " + geom);
            // 进行坐标转换
            int sourceEPSGCode = 4326;
            int targetEPSGCode = 3857;
            // 使用上述方法进行转换
            Geometry transformedLineString = CoordinateTransformation.geometryTransformMulti(geom, sourceEPSGCode, targetEPSGCode);
    
            // 输出转换后的LineString
            System.out.println("转换后的图形: " + transformedLineString.toText());
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI助手
image-20230820232617401

多边形坐标转换

对于多边形的转换,测试方法如下:

复制代码
    /** * Geometry 坐标转换 多边形
     * 4326 to 3857
     */
    @Test
    public void polygonTest() {
        // 另一个WKT格式的多边形示例
        String wkt = "POLYGON ((10 10, 50 10, 50 50, 10 50, 10 10), (20 20, 40 20, 40 40, 20 40, 20 20))";
    
        WKTReader reader = new WKTReader();
        try {
            Geometry geom = reader.read(wkt);
            System.out.println("原始图形: " + geom);
            // 进行坐标转换
            int sourceEPSGCode = 4326;
            int targetEPSGCode = 3857;
            Geometry transformedPolygon = CoordinateTransformation.geometryTransformMulti(geom, sourceEPSGCode, targetEPSGCode);
            System.out.println("转换后的图形: " + transformedPolygon);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI助手
image-20230820232819637

多多边形坐标转换

对于多多边形的转换,测试方法如下:

复制代码
    /** * Geometry 坐标转换 多多边形
     * 4326 to 3857
     */
    @Test
    public void multiPolygonTest() {
        // 另一个WKT格式的多边形示例
        String wkt = "MULTIPOLYGON(((75 14, 135 14, 135 53, 75 53, 75 14)), ((60 30, 90 30, 90 40, 60 40, 60 30)))";
    
        WKTReader reader = new WKTReader();
        try {
            Geometry geom = reader.read(wkt);
            System.out.println("原始图形: " + geom);
            // 进行坐标转换
            int sourceEPSGCode = 4326;
            int targetEPSGCode = 3857;
            Geometry transformedPolygon = CoordinateTransformation.geometryTransformMulti(geom, sourceEPSGCode, targetEPSGCode);
            System.out.println("转换后的图形: " + transformedPolygon);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI助手
image-20230820232922217

仓库代码地址

我已将所有代码上传到GitHub上,你可以通过以下链接访问:

Github代码地址

image-20230820235802421

总结

《地理信息系统开发必看》系列教程致力于为众多地理信息系统开发人员和爱好者提供一个详尽且实用的坐标转换工具集。本文将重点介绍项目依赖设置的重要性及如何利用 GeoTools 实现各种类型的坐标转换,涵盖单点到多边形结构等多种转换场景。

通过深入分析不同类型的几何变换特性, GeoTools展现出其在地理信息处理领域独特的优势与应用潜力。该系统不仅能够实现点坐标变换,还能有效处理包括多线和多多边形在内的复杂空间实体变换问题,支持用户完成高精度和快速处理能力的任务需求。通过一系列典型案例分析,验证了该方法在保持转换结果的准确性以及系统稳定性方面的有效性

总体而言,
该库在功能上既强大又灵活,
可用于多种 地理坐标转换 以及 空间分析 任务。
不论你是 专业人士 还是 地理学科 的学者
本指南都将 助你 更好地掌握 并善用 GeoTools
让你在 地理数据 分析 和 可视化 方面 开启 更广阔的前景

全部评论 (0)

还没有任何评论哟~