当前位置:   article > 正文

GeoTools实战指南: 一步步教您轻松实现Shapefile矢量图层可视化_geotools教程

geotools教程

GeoTools实战指南: 一步步教您轻松实现Shapefile矢量图层可视化

介绍

本教程旨在指导您使用GeoTools库渲染并显示Shapefile矢量图层。GeoTools是一个开源的地理信息系统(GIS)工具包,用于处理地理数据。以下是本教程的主要步骤:

  1. 准备环境
  2. 代码解析
  3. 示例应用程序
  4. 自定义样式

准备环境

首先,您需要将GeoTools库添加到您的项目中。使用Maven或Gradle添加依赖项,或者直接下载GeoTools的jar文件并添加到您的类路径中。下面是我项目中用的全部依赖。

Maven

<properties>
  <geotools.version>28.0</geotools.version>
</properties>
<dependencies>
        <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-epsg-hsql</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>
</dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

Gradle

dependencies {
    implementation "org.geotools:gt-shapefile:${geotoolsVersion}"
    implementation "org.geotools:gt-swing:${geotoolsVersion}"
}
  • 1
  • 2
  • 3
  • 4

代码解析

在代码示例中,我们创建了一个名为ShapeFileLab的类,该类可以读取Shapefile文件,并在地图上显示渲染后的图层。

工厂类实例

我们创建了两个工厂类实例,一个是StyleFactory,用于创建样式对象;另一个是FilterFactory2,用于创建过滤器对象。

    private final StyleFactory sf = CommonFactoryFinder.getStyleFactory();
    private final FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
  • 1
  • 2

显示Shapefile

displayShapefile()方法会弹出一个向导窗口,要求用户选择要显示的Shapefile文件。用户选择文件后,该方法将调用displayLayers()方法。

private void displayShapefile() {
        // 创建参数列表,矢量文件(Shapefile)
        List<Parameter<?>> list = new ArrayList<>();
        list.add(
                new Parameter<>(
                        "shape",
                        File.class,
                        "Shapefile文件",
                        "选择需要叠加的Shapefile文件",
                        new KVP(Parameter.EXT, "shp")));
        // 创建一个向导,让用户输入这些参数
        JParameterListWizard wizard =
                new JParameterListWizard("矢量图层叠加展示", "Fill in the following layers", list);
        int finish = wizard.showModalDialog();
        // 如果用户没有完成输入,则退出
        if (finish != JWizard.FINISH) {
            System.exit(0);
        }
        File shapeFile = (File) wizard.getConnectionParameters().get("shape");
        // 从向导中获取用户输入的文件,并调用displayLayers方法显示图层
        displayLayers(shapeFile);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

加载和渲染Shapefile

displayLayers()方法首先使用FileDataStoreFinder加载Shapefile文件。然后,为Shapefile图层创建一个样式,并将图层添加到MapContent对象中。最后,使用JMapFrame显示地图。

    private void displayLayers(File shapeFile) {
        // 接Shapefile并设置渲染风格
        FileDataStore dataStore = null;
        SimpleFeatureSource shapefileSource = null;
        try {
            dataStore = FileDataStoreFinder.getDataStore(shapeFile);
            shapefileSource = dataStore.getFeatureSource();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // 创建一个带有黄线且无填充的基本样式
//        Style shpStyle = SLD.createPolygonStyle(Color.YELLOW, null, 0.0f);
        Style shpStyle = createCustomStyle(sf, ff);
        // 创建JMapFrame并设置菜单、工具栏等
        final MapContent map = new MapContent();
        map.setTitle("图层叠加");

        Layer shpLayer = new FeatureLayer(shapefileSource, shpStyle);
        map.addLayer(shpLayer);

        // C创建一个JMapFrame框架
        frame = new JMapFrame(map);
        frame.setSize(800, 600);
        frame.enableStatusBar(true);
//        frame.enableTool(JMapFrame.Tool.ZOOM, JMapFrame.Tool.PAN, JMapFrame.Tool.RESET);
        frame.enableToolBar(true);
        frame.enableLayerTable(true);

        // 显示地图窗口,当窗口关闭时,应用程序将退出
        frame.setVisible(true);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

自定义样式

createCustomStyle()方法中,我们创建了一个自定义样式,该样式为Shapefile图层添加了红色边框。您可以修改此方法以应用其他样式,例如更改边框颜色、宽度或添加填充。

    /**
     * 创建矢量图层样式
     * @param styleFactory 样式工厂
     * @param filterFactory 过滤器工厂
     * @return  矢量图层样式
     */
    public static Style createCustomStyle(StyleFactory styleFactory, FilterFactory2 filterFactory) {
        // Create a black line for the stroke
        Stroke stroke = styleFactory.createStroke(filterFactory.literal(Color.RED), filterFactory.literal(1));

        // Create a line symbolizer using the stroke
        LineSymbolizer lineSymbolizer = styleFactory.createLineSymbolizer(stroke, null);

        // Create a rule with the line symbolizer
        Rule rule = styleFactory.createRule();
        rule.symbolizers().add(lineSymbolizer);

        // Create a style with the rule
        Style style = styleFactory.createStyle();
        style.featureTypeStyles().add(styleFactory.createFeatureTypeStyle(rule));

        return style;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

示例代码

import org.geotools.coverage.grid.io.GridCoverage2DReader;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.Parameter;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.styling.*;
import org.geotools.styling.Stroke;
import org.geotools.swing.JMapFrame;
import org.geotools.swing.data.JParameterListWizard;
import org.geotools.swing.wizard.JWizard;
import org.geotools.util.KVP;
import org.opengis.filter.FilterFactory2;

import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 渲染shape文件,并显示在地图上
 */
public class ShapeFileLab {

    //这行代码创建了一个 StyleFactory 实例,它是 GeoTools 中的一个工厂类,用于创建样式对象。样式对象用于定义地图中地理要素(如点、线、面)的显示方式,包括颜色、线型、填充等。
    private final StyleFactory sf = CommonFactoryFinder.getStyleFactory();
    //这行代码创建了一个 FilterFactory2 实例。FilterFactory2 是 GeoTools 中的一个工厂类,用于创建过滤器对象。过滤器对象用于筛选地理要素,可以基于属性或几何关系来选择特定的地理要素。这个类是 FilterFactory 的一个扩展版本,提供了更多的功能。
    private final FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
    //这行代码声明了一个 JMapFrame 类型的私有变量 frame。JMapFrame 是 GeoTools 提供的一个 Swing 组件,用于在窗口中显示地图。通过这个变量,您可以创建一个地图窗口,添加图层、工具栏等组件。
    private JMapFrame frame;
    //这行代码声明了一个 GridCoverage2DReader 类型的私有变量 reader。GridCoverage2DReader 是一个接口,用于读取栅格数据(如 GeoTIFF、NetCDF 等格式)。通过实现这个接口的类(如 GeoTiffReader、NetCDFReader 等),您可以读取和处理栅格数据。
    private GridCoverage2DReader reader;

    public static void main(String[] args) {
        ShapeFileLab app = new ShapeFileLab();
        app.displayShapefile();
    }

    private void displayShapefile() {
        // 创建参数列表,矢量文件(Shapefile)
        List<Parameter<?>> list = new ArrayList<>();
        list.add(
                new Parameter<>(
                        "shape",
                        File.class,
                        "Shapefile文件",
                        "选择需要叠加的Shapefile文件",
                        new KVP(Parameter.EXT, "shp")));
        // 创建一个向导,让用户输入这些参数
        JParameterListWizard wizard =
                new JParameterListWizard("矢量图层叠加展示", "Fill in the following layers", list);
        int finish = wizard.showModalDialog();
        // 如果用户没有完成输入,则退出
        if (finish != JWizard.FINISH) {
            System.exit(0);
        }
        File shapeFile = (File) wizard.getConnectionParameters().get("shape");
        // 从向导中获取用户输入的文件,并调用displayLayers方法显示图层
        displayLayers(shapeFile);
    }

    private void displayLayers(File shapeFile) {
        // 接Shapefile并设置渲染风格
        FileDataStore dataStore = null;
        SimpleFeatureSource shapefileSource = null;
        try {
            dataStore = FileDataStoreFinder.getDataStore(shapeFile);
            shapefileSource = dataStore.getFeatureSource();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // 创建一个带有黄线且无填充的基本样式
//        Style shpStyle = SLD.createPolygonStyle(Color.YELLOW, null, 0.0f);
        Style shpStyle = createCustomStyle(sf, ff);
        // 创建JMapFrame并设置菜单、工具栏等
        final MapContent map = new MapContent();
        map.setTitle("图层叠加");

        Layer shpLayer = new FeatureLayer(shapefileSource, shpStyle);
        map.addLayer(shpLayer);

        // C创建一个JMapFrame框架
        frame = new JMapFrame(map);
        frame.setSize(800, 600);
        frame.enableStatusBar(true);
//        frame.enableTool(JMapFrame.Tool.ZOOM, JMapFrame.Tool.PAN, JMapFrame.Tool.RESET);
        frame.enableToolBar(true);
        frame.enableLayerTable(true);

        // 显示地图窗口,当窗口关闭时,应用程序将退出
        frame.setVisible(true);
    }

    /**
     * 创建矢量图层样式
     * @param styleFactory 样式工厂
     * @param filterFactory 过滤器工厂
     * @return  矢量图层样式
     */
    public static Style createCustomStyle(StyleFactory styleFactory, FilterFactory2 filterFactory) {
        // Create a black line for the stroke
        Stroke stroke = styleFactory.createStroke(filterFactory.literal(Color.RED), filterFactory.literal(1));

        // Create a line symbolizer using the stroke
        LineSymbolizer lineSymbolizer = styleFactory.createLineSymbolizer(stroke, null);

        // Create a rule with the line symbolizer
        Rule rule = styleFactory.createRule();
        rule.symbolizers().add(lineSymbolizer);

        // Create a style with the rule
        Style style = styleFactory.createStyle();
        style.featureTypeStyles().add(styleFactory.createFeatureTypeStyle(rule));

        return style;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122

示例应用程序

要运行示例应用程序,请将代码复制到一个名为ShapeFileLab.java的文件中。然后,编译并运行该文件。您应该能够看到一个地图窗口,其中包含您选择的Shapefile图层。

image-20230428140138716

image-20230428140148659

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/476146
推荐阅读
相关标签
  

闽ICP备14008679号