GeoTools,GIS的另一个基础设施!

About GeoTools

GeoTools is an open source (LGPL) Java code library which provides standards compliant methods for the manipulation of geospatial data, for example to implement Geographic Information Systems (GIS). The GeoTools library implements Open Geospatial Consortium (OGC) specifications as they are developed.

走进 GeoTools

GeoTools的架构图如下,我们了解GeoTools的架构以及各个jar包所构成的库栈,能够帮助我们更加清晰的了解和学习GeoTools的各个模块,并且还能够帮助我们在项目里面选择适合我们的库。

../_images/geotools.png

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">../_images/geotools.png</figcaption>

这张架构图遵循了软件工程领域里面架构图设计标准,由下而上,第一层是基础设施,上层建筑依赖于基础设施。

比如:你如果想使用Referencing模块里的gt-opengisgt-referencinggt-metadata内容,那么当你使用data模块的时候,gt-mainjtsgt-opengisgt-referencinggt-opengisgt-metadata,上面Referencing的内容也是会引用到的。

GeoTools常用模块的功能列表:

Module Purpose
gt-render Implements of Java2D rendering engine to draw a map
gt-jdbc Implements for accessing spatial database
gt-main Implements for accessing spatial data
gt-xml Implements of common spatial XML formats
gt-cql Implements of Common Query Language for filters
gt-main Interfaces for working with spatial information. Implements filter, feature, etc…
jts Definition and implementation of Geometry
gt-coverage Implementation for accessing raster information
gt-referencing Implementation of co-ordinate location and transformation
gt-metadata Implementation of identification and description
gt-opengis Definition of interfaces for common spatial concepts

GeoTools提供插件来支持额外的数据格式、不同的坐标参考系统权限等等。

Module JAR Plugin
gt-render
gt-jdbc gt-jdbc-db2 Geometry in DB2
gt-jdbc-h2 Pure Java “H2” database
gt-jdbc-mysql Geometry in MySQL
gt-jdbc-oracle Oracle SDO Geometry
gt-jdbc-postgis PostgreSQL extension PostGIS
gt-jdbc-sqlserver SQL Server
gt-jdbc-hana SAP HANA
gt-jdbc-terasdata Teradata
gt-main gt-shape Shapefile read/write support
gt-wfs WFS read/write support
gt-xml
gt-cql
gt-main
jts
gt-coverage gt-geotiff GeoTIFF raster format
gt-arcgrid arcgrid format
gt-mif MIF format
gt-image JPG, PNG, TIFF formats
gt-referencing epsg-access . Official EPSG database in Access
epsg-hsql Pure Java port of EPSG database
epsg-wkt Lightweight copy of EPSG codes
epsg-postgresql PostgreSQL port of EPSG database
gt-metadata
gt-opengis

除此之外,GeoTools团队在GeoTools的基础上实现了一些扩展,当然了,这些扩展是为了提供一些额外的功能。这些扩展是相互独立的,我们可以直接在项目中使用。

../_images/extension.png

<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">../_images/extension.png</figcaption>

JAR Extension
gt-graph Work with graph and network traversals
gt-validation Quality assurance for spatial data
gt-wms Web Map Server client
gt-xsd Parsing/Encoding for common OGC schemas
gt-brewer Generation of styles using color brewer

GeoTools团队为了支持GeoTools中的XML模块,将几个XML模式打包成JAR形式,方便开发者进行调用。

JAR Schema
net.opengis.ows open web services schema
net.opengis.wfs web feature service
net.opengis.wps web processing service schema
net.opengis.wcs web coverage service schema
net.opengis.wfs web feature service schema
org.w3.xlink XLink schema

XSD解析器通过一系列XSD插件使用这些工具。这些插件指示如何使用Eclipse XSD库解析和编码额外的内容来解析XML模式文档,并提供“绑定”,显示如何解析和编码Java类,如String、Date、URL和Geometry。

JAR Bindings
gt-xsd-core Basic types defined by XML schema
gt-xsd-fes filter 2.0
gt-xsd-filter filter (used by OGC CAT and WFS)
gt-xsd-kml keyhole markup language
gt-xsd-wfs web feature service
gt-xsd-wps web processing service
gt-xsd-gml3 geographic markup language 3
gt-xsd-gml2 geographic markup language 2
gt-xsd-ows open web services
gt-xsd-wcs web coverage service
gt-xsd-wms web map service
gt-xsd-sld style layer descriptor

以下是GeoTools不支持的扩展,你也可以使用Maven下载它们来使用。

Unsupported Purpose
gt-swt Standard widget toolkit interactive map
gt-swing Swing interactive map
gt-oracle retired oracle support
gt-postgis retired PostGIS support
gt-db2 retired db2 support
gt-wps Web Processing Service client
gt-process Job system for spatial data

牛刀小试

  1. 在POM文件中,首先添加以下内容:

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <geotools.version>24-SNAPSHOT</geotools.version> </properties> </pre>

  1. 然后在POM文件的<repositories>标签中,添加以下依赖,该依赖是GeoTools官方的依赖远程仓库位置:

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><repositories> <repository> <id>osgeo</id> <name>OSGeo Release Repository</name> <url>https://repo.osgeo.org/repository/release/</url> <snapshots><enabled>false</enabled></snapshots> <releases><enabled>true</enabled></releases> </repository> <repository> <id>osgeo-snapshot</id> <name>OSGeo Snapshot Repository</name> <url>https://repo.osgeo.org/repository/snapshot/</url> <snapshots><enabled>true</enabled></snapshots> <releases><enabled>false</enabled></releases> </repository> </repositories> </pre>

  1. 在POM文件中添加以下依赖:

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-shapefile</artifactId> <version>${geotools.version}</version> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-swing</artifactId> <version>${geotools.version}</version> </dependency> <dependency> <groupId>org.locationtech.jts</groupId> <artifactId>jts-core</artifactId> <version>1.16.1</version> </dependency> <dependency> <groupId>org.geotools</groupId> <artifactId>gt-main</artifactId> <version>22-RC</version> </dependency> </dependencies> </pre>

  1. 在你的Spring Boot工程中新建QuickStrat类,并添加以下代码:

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">`import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.styling.SLD;
import org.geotools.styling.Style;
import org.geotools.swing.JMapFrame;
import org.geotools.swing.data.JFileDataStoreChooser;

import java.io.File;

/**

  • @Author Wangb

  • @Date 20/11/2021 下午6:54.

  • @Description
    */
    public class Quickstart {

    /**

    • GeoTools Quickstart demo application. Prompts the user for a shapefile and displays its

    • contents on the screen in a map frame
      */
      public static void main(String[] args) throws Exception {
      // display a data store file chooser dialog for shapefiles
      File file = JFileDataStoreChooser.showOpenFile("shp", null);
      if (file == null) {
      return;
      }

      FileDataStore store = FileDataStoreFinder.getDataStore(file);
      SimpleFeatureSource featureSource = store.getFeatureSource();

      // Create a map content and add our shapefile to it
      MapContent map = new MapContent();
      map.setTitle("Quickstart");

      Style style = SLD.createSimpleStyle(featureSource.getSchema());
      Layer layer = new FeatureLayer(featureSource, style);
      map.addLayer(layer);

      // Now display the map
      JMapFrame.showMap(map);
      }
      }` </pre>

  1. 在该网站http://www.naturalearthdata.com/downloads/50m-cultural-vectors/,根据自己的喜好来下载一个矢量数据文件。

    在下图的窗口中勾选你刚才下载、并解压文件后的位置。

image.png
  1. 接下来就会自动弹出一个窗口,里面展示了你刚才下载的矢量文件,如下图:
image.png

以上是我们对GeoTools的快速启动案例的学习。

CSV转换SHP教程

  1. 在该地址下载location.csv文件:

http://docs.geotools.org/stable/userguide/_downloads/d4bcf8751cc3f33a9fb673902a960e53/locations.csv

  1. 在你的IDE中键入以下代码:

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">`package com.geovis.bin.utils.gis.geotools;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import org.geotools.data.DataUtilities;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.Transaction;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.feature.SchemaException;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.swing.data.JFileDataStoreChooser;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import javax.swing.;
import java.io.
;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**

  • This example reads data for point locations and associated attributes from a comma separated text
  • (CSV) file and exports them as a new shapefile. It illustrates how to build a feature type.
  • <p>Note: to keep things simple in the code below the input file should not have additional spaces
  • or tabs between fields.
    */

/**

  • @Author Wangb

  • @Date 20/11/2021 下午9:32.

  • @Description
    */
    public class Csv2Shape {
    public static void csv2Shape() throws IOException, SchemaException, ClassNotFoundException, UnsupportedLookAndFeelException, InstantiationException, IllegalAccessException {
    // Set cross-platform look & feel for compatability
    UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());

     File file = JFileDataStoreChooser.showOpenFile("csv", null);
     if (file == null) {
         return;
     }
    
     /**
      * We use the DataUtilities class to create a FeatureType that will describe the data in our
      * shapefile.
      *
      * See also the createFeatureType method below for another, more flexible approach.
      */
     final SimpleFeatureType TYPE =
             DataUtilities.createType(
                     "Location",
                     "the_geom:Point:srid=4326,"
                             + // <- the geometry attribute: Point type
                             "name:String,"
                             + // <- a String attribute
                             "number:Integer" // a number attribute
             );
     System.out.println("TYPE:" + TYPE);
    
     /*
      * A list to collect features as we create them.
      */
     List<SimpleFeature> features = new ArrayList<>();
    
     /*
      * GeometryFactory will be used to create the geometry attribute of each feature,
      * using a Point object for the location.
      */
     GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
    
     SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
    
     try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
         /* First line of the data file is the header */
         String line = reader.readLine();
         System.out.println("Header: " + line);
    
         for (line = reader.readLine(); line != null; line = reader.readLine()) {
             //skip blank lines
             if (line.trim().length() > 0) {
                 String[] tokens = line.split("\\,");
    
                 double latitude = Double.parseDouble(tokens[0]);
                 double longitude = Double.parseDouble(tokens[1]);
                 String name = tokens[2].trim();
                 int number = Integer.parseInt(tokens[3].trim());
    
                 /* Longitude (= x coord) first ! */
                 Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));
    
                 featureBuilder.add(point);
                 featureBuilder.add(name);
                 featureBuilder.add(number);
                 SimpleFeature feature = featureBuilder.buildFeature(null);
                 features.add(feature);
             }
         }
     }
     /*
      * Get an output file name and create the new shapefile
      */
     File newFile = getNewShapeFile(file);
    
     ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
    
     Map<String, Serializable> params = new HashMap<>();
     params.put("url", newFile.toURI().toURL());
     params.put("create spatial index", Boolean.TRUE);
    
     ShapefileDataStore newDataStore =
             (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
    
     /*
      * TYPE is used as a template to describe the file contents
      */
     newDataStore.createSchema(TYPE);
    
     /*
      * Write the features to the shapefile
      */
     Transaction transaction = new DefaultTransaction("create");
    
     String typeName = newDataStore.getTypeNames()[0];
     SimpleFeatureSource featureSource = newDataStore.getFeatureSource(typeName);
     SimpleFeatureType SHAPE_TYPE = featureSource.getSchema();
     /*
      * The Shapefile format has a couple limitations:
      * - "the_geom" is always first, and used for the geometry attribute name
      * - "the_geom" must be of type Point, MultiPoint, MuiltiLineString, MultiPolygon
      * - Attribute names are limited in length
      * - Not all data types are supported (example Timestamp represented as Date)
      *
      * Each data store has different limitations so check the resulting SimpleFeatureType.
      */
     System.out.println("SHAPE:" + SHAPE_TYPE);
    
     if (featureSource instanceof SimpleFeatureStore) {
         SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;
         /*
          * SimpleFeatureStore has a method to add features from a
          * SimpleFeatureCollection object, so we use the ListFeatureCollection
          * class to wrap our list of features.
          */
         SimpleFeatureCollection collection = new ListFeatureCollection(TYPE, features);
         featureStore.setTransaction(transaction);
         try {
             featureStore.addFeatures(collection);
             transaction.commit();
         } catch (Exception problem) {
             problem.printStackTrace();
             transaction.rollback();
         } finally {
             transaction.close();
         }
    

// success!
System.exit(0);
} else {
System.out.println(typeName + " does not support read/write access");
System.exit(1);
}
}

/**
 * Prompt the user for the name and path to use for the output shapefile
 *
 * @param csvFile the input csv file used to create a default shapefile name
 * @return name and path for the shapefile as a new File object
 */
private static File getNewShapeFile(File csvFile) {
    String path = csvFile.getAbsolutePath();
    String newPath = path.substring(0, path.length() - 4) + ".shp";

    JFileDataStoreChooser chooser = new JFileDataStoreChooser("shp");
    chooser.setDialogTitle("Save shapefile");
    chooser.setSelectedFile(new File(newPath));

    int returnVal = chooser.showSaveDialog(null);

    if (returnVal != JFileDataStoreChooser.APPROVE_OPTION) {
        // the user cancelled the dialog
        System.exit(0);
    }

    File newFile = chooser.getSelectedFile();
    if (newFile.equals(csvFile)) {
        System.out.println("Error: cannot replace " + csvFile);
        System.exit(0);
    }

    return newFile;
}

public static void main(String[] args) throws Exception {
    csv2Shape();
}

}` </pre>

  1. 运行该代码,会弹出对话框,需要你选择下载并解压后的location.csv文件
image.png
  1. 选好之后会在同级目录生成shape file,我们把location.shp文件拖入ArcGIS DeskTop软件中,就可以看到如下界面:
image.png
  1. 至此,我们完成csv至shp文件的转换工作。

从shp文件读取要素集

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">`/**
* 获取shp几何对象集合
*
* @param fileUrl 文件地址
* @return 几何集合
*/
public static List<Geometry> getGeometryList(String fileUrl) throws IOException {
List<Geometry> geometryList = new ArrayList<>();
ShapefileReader r = null;
try {
r = new ShapefileReader(new ShpFiles(fileUrl), false, false, new GeometryFactory());
while (r.hasNext()) {
Geometry shape = (Geometry) r.nextRecord().shape();
ShapeType shapeType = r.getHeader().getShapeType();
double x1 = r.getHeader().maxX();
double y1 = r.getHeader().maxY();
double x2 = r.getHeader().minX();
double y2 = r.getHeader().minY();

            geometryList.add(shape);
        }
    } catch (Exception e) {
        if (r != null) {
            r.close();
        }
        e.printStackTrace();
    }

    return geometryList;
}` </pre>

运行结果如下:

image.png

自定义GeoTools工具类

以下代码是自定义的一个GeoTools工具类,主要实现了一些点、线、面以及简单的空间分析的操作。

<pre class="custom" data-tool="mdnice编辑器" style="margin-top: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;">`/**

  • @Author:Wangb
  • @Date:2021/4/14 10:33
    */
    package com.geovis.bin.utils.gis.geotools;

import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKBReader;
import com.vividsolutions.jts.io.WKBWriter;
import com.vividsolutions.jts.io.WKTReader;
import org.geotools.geometry.jts.JTSFactoryFinder;

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

public class GeoToolsUtil {

private static  com.vividsolutions.jts.geom.GeometryFactory GEOMETRYFACTORY = JTSFactoryFinder.getGeometryFactory();
private static WKTReader WKTREADER = new WKTReader(GEOMETRYFACTORY);
private static WKBWriter WKBWRITER = new WKBWriter();
private static WKBReader WKBREADER = new WKBReader();

/**
 * 以下内容为几何地理实体类的wkt形式样例,供开发参考
 *
 * POINT -> POINT(108.36 34.36)
 *
 * LINESTRING -> LINRSTRING("108.36 34.36","108.37 34.37","108.37 34.37")
 *
 * POLYGON -> POLYGON((108.36 34.36,108.37 34.37,108.38 34.38,108.36 34.36))
 *
 * POLYGON -> POLYGON((108.36 34.36,108.37 34.37,108.38 34.38,108.36 34.36),(108.36 34.36,108.37 34.37,108.38 34.38,108.36 34.36))
 *
 * MULTIPOLYGON  -> MULTIPOLYGON((1 1,5 1,5 5,5 1,1 1 ),(2 2,6 3,6 4,6 5,2 2),( 2 1, 3 2,3 3, 2 1))
 *
 */

/**
 * 面转换为线
 *
 * @param geom
 * @return
 */
public static Geometry polygon2LineString(Geometry geom) {

    String geometryType = geom.getGeometryType().toUpperCase();
    Geometry res;

    if ("MULTIPOLYGON".equals(geometryType)) {
        int geoNum = geom.getNumGeometries();
        ArrayList<LineString> lineList = new ArrayList<>();
        if (geoNum > 1) {
            // 包含多个面,面中包含环
            for (int i = 0; i < geoNum; i++) {
                Polygon geo = (Polygon) geom.getGeometryN(i);
                lineList.add(GEOMETRYFACTORY.createLineString(geo.getExteriorRing().getCoordinates()));
                for (int j = 0; j < geo.getNumInteriorRing(); j++) {
                    lineList.add(GEOMETRYFACTORY.createLineString(geo.getInteriorRingN(i).getCoordinates()));
                }
            }
            LineString[] lines = new LineString[lineList.size()];
            lineList.toArray(lines);
            res = GEOMETRYFACTORY.createMultiLineString(lines);
        } else {
            //包含一个面,面中包含环
            Polygon poly = (Polygon) geom.getGeometryN(0);
            lineList.add(GEOMETRYFACTORY.createLineString(poly.getExteriorRing().getCoordinates()));
            for (int i = 0; i < poly.getNumInteriorRing(); i++) {
                lineList.add(GEOMETRYFACTORY.createLineString(poly.getInteriorRingN(i).getCoordinates()));
            }
            LineString[] lines = new LineString[lineList.size()];
            lineList.toArray(lines);
            res = GEOMETRYFACTORY.createMultiLineString(lines);
        }
    } else if ("POLYGON".equals(geometryType)) {
        //只包含一个面
        res = GEOMETRYFACTORY.createLineString(geom.getCoordinates());
    } else {
        res = null;
    }
    return res;
}

/**
 * 计算面与线的交点
 *
 * @param geom
 * @param line
 * @return
 */
public static Geometry getPointOfIntersection(Geometry geom, Geometry line) {
    Geometry lines = polygon2LineString(geom);
    return lines.intersection(line);
}

/**
 * wkt转Geometry
 *
 * @param wkt
 * @return
 */
public static Geometry wkt2Geometry(String wkt) {
    GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
    WKTReader wktReader = new WKTReader(geometryFactory);
    Geometry geometry = null;

    try {
        Geometry read = wktReader.read(wkt);
        return geometry;
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return null;

}

/**
 * 创建一个点
 *
 * @param lon
 * @param lat
 * @return
 */
public static Point creatrPoint(String lon, String lat) {
    Coordinate coordinate = new Coordinate(Double.parseDouble(lon), Double.parseDouble(lat));
    Point point = GEOMETRYFACTORY.createPoint(coordinate);
    return point;
}

/**
 * 使用拼好的字符串来创建一个点
 *
 * @param coor
 * @return
 * @throws ParseException
 */
public static Point creatrPoint(String coor) throws ParseException {
    Point p = (Point) WKTREADER.read(coor);
    return p;
}

/**
 * 创建一个Polygon
 *
 * @param polygon
 * @return
 * @throws ParseException
 */
public static Polygon createPolygon(String polygon) throws ParseException {
    Polygon p = (Polygon) WKTREADER.read(polygon);
    return p;
}

/**
 * 使用拼接好的字符串来创建一个LineString
 *
 * @param line
 * @return
 * @throws ParseException
 */
public static LineString createLineString(String line) throws ParseException {
    LineString lineString = (LineString) WKTREADER.read(line);
    return lineString;
}

/**
 * 比较两个点是否相同,
 *
 * @param p1
 * @param p2
 * @return
 * @throws ParseException
 */
public static boolean equalsLinePoint(String p1, String p2, int srid) throws ParseException {
    Point geom1 = (Point) WKTREADER.read(p1);
    geom1.setSRID(srid);
    Point geom2 = (Point) WKTREADER.read(p2);
    geom2.setSRID(srid);
    return geom1.equals(geom2);
}

/**
 * 比较两个线是否相同
 *
 * @param l1
 * @param l2
 * @return
 * @throws ParseException
 */
public static boolean equalsLineString(String l1, String l2) throws ParseException {
    LineString geom1 = (LineString) WKTREADER.read(l1);
    LineString geom2 = (LineString) WKTREADER.read(l2);
    return geom1.equals(geom2);
}

/**
 * 比较两个面是否相同
 *
 * @param p1
 * @param p2
 * @return
 * @throws ParseException
 */
public static boolean equalsPolygon(String p1, String p2) throws ParseException {
    Polygon geom1 = (Polygon) WKTREADER.read(p1);
    Polygon geom2 = (Polygon) WKTREADER.read(p2);
    return geom1.equals(geom2);
}

/**
 * 线对象有没有交点
 *
 * @param s1
 * @param s2
 * @return
 * @throws ParseException
 */
public static boolean disjoinLineString(String s1, String s2) throws ParseException {
    LineString line1 = (LineString) WKTREADER.read(s1);
    LineString line2 = (LineString) WKTREADER.read(s2);
    return line1.disjoint(line2);
}

/**
 * 面对象有没有交点
 *
 * @param s1
 * @param s2
 * @return
 * @throws ParseException
 */
public static boolean disjoinPolygon(String s1, String s2) throws ParseException {
    Polygon p1 = (Polygon) WKTREADER.read(s1);
    Polygon p2 = (Polygon) WKTREADER.read(s2);
    return p1.disjoint(p2);
}

/**
 * 判断两条线是否相交
 *
 * @param s1
 * @param s2
 * @return
 * @throws ParseException
 */
public static boolean interSectionOfLineStringAndLineString(String s1, String s2) throws ParseException {
    LineString l1 = (LineString) WKTREADER.read(s1);
    LineString l2 = (LineString) WKTREADER.read(s1);
    Geometry points = l1.intersection(l2);
    return l1.intersects(l2);
}

/**
 * 判断两条线是否相交,并返回坐标数组
 * 该方法为初写方法,未经实际检验
 *
 * @param s1
 * @param s2
 * @return
 * @throws ParseException
 */
public static Coordinate[] interSectionOfLineStringAndLineString(String s1, String s2, int srid) throws ParseException {
    LineString l1 = (LineString) WKTREADER.read(s1);
    LineString l2 = (LineString) WKTREADER.read(s1);
    Geometry points = l1.intersection(l2);
    Coordinate[] coordinates = points.getCoordinates();
    return coordinates;
}

/**
 * point[]转Polygon
 *
 * @param s
 * @return
 * @throws ParseException
 */
public static Polygon pointArray2Polygon(String s) throws ParseException {
    return (Polygon) WKTREADER.read(s);
}

/**
 * 返回Polygon区域的点数组
 *
 * @param polygon
 * @param lon
 * @param lat
 * @return
 */
public static List<Point> IntersectionPointsAndPolygon(Polygon polygon, String lon, String lat) {
    List<Point> points = new ArrayList<>();
    Point point = creatrPoint(lon, lat);
    boolean contains = polygon.contains(point);
    if (contains) {
        points.add(point);
    }
    return points;
}

/**
 * 返回Polygon区域的点数组
 *
 * @param polygon
 * @param coor
 * @return
 */
public static List<Point> IntersectionPointsAndPolygon(Polygon polygon, String coor) throws ParseException {
    List<Point> points = new ArrayList<>();
    Point point = creatrPoint(coor);
    boolean contains = polygon.contains(point);
    if (contains) {
        points.add(point);
    }
    return points;
}

/**
 * 计算两个区域的是否相交
 *
 * @param p1
 * @param p2
 * @return
 */
public static boolean isIntersects(Polygon p1, Polygon p2) {
    boolean flag = p1.intersects(p2);
    return flag;
}

/**
 * 计算两个区域是否相交,并返回交叉区域
 *
 * @param p1
 * @param p2
 * @return
 */
public static Polygon intersectsArea(Polygon p1, Polygon p2) {
    Polygon geom = (Polygon) p1.intersection(p2);
    return geom;
}

/**
 * 返回给定位置的缓冲区范围
 *
 * @param point
 * @param range
 * @return
 * @throws ParseException
 */
public static Polygon fireArea(String point, double range) throws ParseException {
    Point fire = (Point) WKTREADER.read(point);
    Polygon buffer = (Polygon) fire.buffer(range);
    return buffer;
}

/**
 * 返回两个点之间的距离
 *
 * @param p1
 * @param p2
 * @return
 */
public static double distanceOfPoint(Point p1, Point p2) {
    return p1.distance(p2);
}

/**
 * 返回两个点之间的距离
 *
 * @param lon1
 * @param lon2
 * @param lat1
 * @param lat2
 * @return
 */
public static double distanceOfPoint(String lon1, String lon2, String lat1, String lat2) {
    Point p1 = creatrPoint(lon1, lat1);
    Point p2 = creatrPoint(lat2, lon2);
    return p1.distance(p2);
}

/**
 * 给定起始点、目标点和移动速度,返回机动至目标点的使用时间
 *
 * @param start
 * @param end
 * @param speed
 * @return
 */
public static double timeOfGoal(Coordinate start, Coordinate end, float speed) {
    return (start.distance3D(end)) / speed;
}

}` </pre>

希望这个初步教程可以帮助到你,也欢迎私信交流、一起进步~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容