GeoTools,GIS的另一個基礎(chǔ)設(shè)施!

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的架構(gòu)圖如下,我們了解GeoTools的架構(gòu)以及各個jar包所構(gòu)成的庫棧,能夠幫助我們更加清晰的了解和學(xué)習(xí)GeoTools的各個模塊,并且還能夠幫助我們在項目里面選擇適合我們的庫。

../_images/geotools.png

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

這張架構(gòu)圖遵循了軟件工程領(lǐng)域里面架構(gòu)圖設(shè)計標(biāo)準(zhǔn),由下而上,第一層是基礎(chǔ)設(shè)施,上層建筑依賴于基礎(chǔ)設(shè)施。

比如:你如果想使用Referencing模塊里的gt-opengis,gt-referencing,gt-metadata內(nèi)容,那么當(dāng)你使用data模塊的時候,gt-main,jts,gt-opengis,gt-referencing,gt-opengisgt-metadata,上面Referencing的內(nèi)容也是會引用到的。

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提供插件來支持額外的數(shù)據(jù)格式、不同的坐標(biāo)參考系統(tǒng)權(quán)限等等。

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的基礎(chǔ)上實現(xiàn)了一些擴展,當(dāng)然了,這些擴展是為了提供一些額外的功能。這些擴展是相互獨立的,我們可以直接在項目中使用。

../_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形式,方便開發(fā)者進行調(diào)用。

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庫解析和編碼額外的內(nèi)容來解析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文件中,首先添加以下內(nèi)容:

<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>標(biāo)簽中,添加以下依賴,該依賴是GeoTools官方的依賴遠(yuǎn)程倉庫位置:

<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. 在該網(wǎng)站http://www.naturalearthdata.com/downloads/50m-cultural-vectors/,根據(jù)自己的喜好來下載一個矢量數(shù)據(jù)文件。

    在下圖的窗口中勾選你剛才下載、并解壓文件后的位置。

image.png
  1. 接下來就會自動彈出一個窗口,里面展示了你剛才下載的矢量文件,如下圖:
image.png

以上是我們對GeoTools的快速啟動案例的學(xué)習(xí)。

CSV轉(zhuǎn)換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文件的轉(zhuǎn)換工作。

從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>

運行結(jié)果如下:

image.png

自定義GeoTools工具類

以下代碼是自定義的一個GeoTools工具類,主要實現(xiàn)了一些點、線、面以及簡單的空間分析的操作。

<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();

/**
 * 以下內(nèi)容為幾何地理實體類的wkt形式樣例,供開發(fā)參考
 *
 * 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))
 *
 */

/**
 * 面轉(zhuǎn)換為線
 *
 * @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) {
            // 包含多個面,面中包含環(huán)
            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 {
            //包含一個面,面中包含環(huán)
            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轉(zhuǎn)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;

}

/**
 * 創(chuàng)建一個點
 *
 * @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;
}

/**
 * 使用拼好的字符串來創(chuàng)建一個點
 *
 * @param coor
 * @return
 * @throws ParseException
 */
public static Point creatrPoint(String coor) throws ParseException {
    Point p = (Point) WKTREADER.read(coor);
    return p;
}

/**
 * 創(chuàng)建一個Polygon
 *
 * @param polygon
 * @return
 * @throws ParseException
 */
public static Polygon createPolygon(String polygon) throws ParseException {
    Polygon p = (Polygon) WKTREADER.read(polygon);
    return p;
}

/**
 * 使用拼接好的字符串來創(chuàng)建一個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);
}

/**
 * 判斷兩條線是否相交,并返回坐標(biāo)數(shù)組
 * 該方法為初寫方法,未經(jīng)實際檢驗
 *
 * @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[]轉(zhuǎn)Polygon
 *
 * @param s
 * @return
 * @throws ParseException
 */
public static Polygon pointArray2Polygon(String s) throws ParseException {
    return (Polygon) WKTREADER.read(s);
}

/**
 * 返回Polygon區(qū)域的點數(shù)組
 *
 * @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區(qū)域的點數(shù)組
 *
 * @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;
}

/**
 * 計算兩個區(qū)域的是否相交
 *
 * @param p1
 * @param p2
 * @return
 */
public static boolean isIntersects(Polygon p1, Polygon p2) {
    boolean flag = p1.intersects(p2);
    return flag;
}

/**
 * 計算兩個區(qū)域是否相交,并返回交叉區(qū)域
 *
 * @param p1
 * @param p2
 * @return
 */
public static Polygon intersectsArea(Polygon p1, Polygon p2) {
    Polygon geom = (Polygon) p1.intersection(p2);
    return geom;
}

/**
 * 返回給定位置的緩沖區(qū)范圍
 *
 * @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);
}

/**
 * 給定起始點、目標(biāo)點和移動速度,返回機動至目標(biāo)點的使用時間
 *
 * @param start
 * @param end
 * @param speed
 * @return
 */
public static double timeOfGoal(Coordinate start, Coordinate end, float speed) {
    return (start.distance3D(end)) / speed;
}

}` </pre>

希望這個初步教程可以幫助到你,也歡迎私信交流、一起進步~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容