【GIS系列】GeoTools简介及工具类分享

2024-03-19 05:36

本文主要是介绍【GIS系列】GeoTools简介及工具类分享,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文将对GeoTools相关概念进行介绍,同时会给大家分享我工作中用到的工具类及使用方法。

作者:后端小肥肠

目录

1.前言

2. GeoTools简介

3. Geotools使用示例

3.1. 开发环境搭建

3.1.1. 所需版本和工具

3.1.2. pom依赖​​​​​​​

4. 工具类介绍

4.1. 读取shp工具类

4.1.1 准备数据

4.1.2. 部分方法

4.1.3. 完整工具类代码

4.2. 坐标转换工具类

4.2.1. 准备数据

4.2.2. 完整工具类代码

5. 结语

6. 参考链接 


1.前言

GeoTools是一个功能强大的开源GIS工具库,为地理空间数据处理和分析提供了丰富的功能和便利的接口。无论您是GIS专业人士还是对地理空间数据感兴趣的开发人员,掌握GeoTools都是必不可少的。本文将从基本概念入手,介绍GeoTools的功能和使用方法,并重点分享一些实用的工具类和技巧,希望能为您在GIS应用开发中提供帮助和启发。

2. GeoTools简介

GeoTools是一个开源的Java库,用于处理和分析地理空间数据。它提供了一系列用于读取、写入、处理和可视化地理空间数据的工具和API。以下是与GeoTools相关的一些重要概念:

  1. 地理空间数据(Geospatial Data): GeoTools主要用于处理地理空间数据,这包括地图、地形、卫星影像、矢量数据等地理信息。这些数据通常具有地理坐标信息和地理属性信息。

  2. 地理坐标系统(Geographic Coordinate System,GCS): 地理坐标系统是用于在地球上定位点的一种方法。GeoTools支持多种地理坐标系统,包括经纬度坐标系统等。

  3. 投影坐标系统(Projected Coordinate System,PCS): 投影坐标系统是将地球表面的地理坐标投影到平面上的一种方法。GeoTools提供了许多常用的投影方法和投影坐标系统的支持。

  4. 数据格式(Data Formats): GeoTools支持多种地理空间数据格式,如Shapefile、GeoJSON、KML、GML等,可以方便地读取和写入这些数据格式。

  5. 空间分析(Spatial Analysis): GeoTools提供了丰富的空间分析功能,包括缓冲区分析、空间查询、空间叠加分析等,可以帮助用户进行地理空间数据的处理和分析。

总的来说,GeoTools是一个功能丰富的GIS工具库,提供了丰富的功能和工具,可以帮助用户处理和分析各种地理空间数据,并构建地理空间应用。

3. Geotools使用示例

3.1. 开发环境搭建

3.1.1. 所需版本和工具
依赖版本
Spring Boot2.6.14
GeoTools4.4.18
java1.8以上
ArcGis10.8

我这里用的不是GeoTools的最新版本,需要最新版本的同学可登录GeoTools的官网(GeoTools The Open Source Java GIS Toolkit — GeoTools)查看最新版本和其使用规则。

如上图所示,最新版本的GeoTools跟java11适配。

3.1.2. pom依赖
         <dependency><groupId>org.geotools</groupId><artifactId>gt-shapefile</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-geojson</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-swing</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>

4. 工具类介绍

4.1. 读取shp工具类

4.1.1 准备数据

打开ArcGis绘制面数据,我这里绘制了4490坐标系的几个面要素。

4.1.2. 部分方法

1. 读取shp中的空间要素信息(wkt)

public static List<String> getWktFromShp(String shpPath) {List<String> shpList = new ArrayList<>();SimpleFeatureCollection simpleFeatureCollection = null;try {//获取文件File file = new File(shpPath);// 读取到数据存储中FileDataStore dataStore = FileDataStoreFinder.getDataStore(file);// 获取特征资源SimpleFeatureSource simpleFeatureSource = dataStore.getFeatureSource();// 要素集合simpleFeatureCollection = simpleFeatureSource.getFeatures();} catch (IOException e) {e.printStackTrace();}// 获取要素迭代器SimpleFeatureIterator featureIterator = simpleFeatureCollection.features();while (featureIterator.hasNext()) {// 要素对象SimpleFeature feature = featureIterator.next();Object geometryText = feature.getDefaultGeometry();log.info(geometryText.toString());shpList.add(geometryText.toString());}featureIterator.close();return shpList;}

2. 运行结果

3. 读取shp文件并将其转换为Geojson

    /*** 构造Geojson结构体* @param featuresJson* @return*/public static JSONObject buildGeoJson(JSONArray featuresJson) {JSONObject Geojson = new JSONObject();Geojson.put("type", "FeatureCollection");Geojson.put("features", featuresJson);return Geojson;}/*** 构造Geojson的features部分 单个** @param geoObject* @param properties* @return*/public static JSONObject buildFeature(Map geoObject, Map properties) {JSONObject featureObject = new JSONObject();Map featureMap = new HashMap();featureMap.put("type", "Feature");featureMap.putAll(geoObject);featureMap.put("properties", properties);featureObject.putAll(featureMap);return featureObject;}/*** 获取空间信息并构造为Map* @param wkt* @return*/public static Map getGeoMap(String wkt) {Map<String, Object> geoMap = new HashMap<>();String json = null;try {WKTReader reader = new WKTReader();Geometry geometry = reader.read(wkt);StringWriter writer = new StringWriter();GeometryJSON g = new GeometryJSON();g.write(geometry, writer);geoMap.put("geometry", writer);} catch (Exception e) {e.printStackTrace();}return geoMap;}/*** 基于shp构造geojson并返回** @param shpPath* @return*/public static JSONObject buildGeojsonFromShp(String shpPath) {JSONArray featureArray = new JSONArray();
//        List<String>shpList=new ArrayList<>();SimpleFeatureCollection simpleFeatureCollection = null;try {
//            要素合集//获取文件File file = new File(shpPath);// 读取到数据存储中ShapefileDataStore dataStore = (ShapefileDataStore) FileDataStoreFinder.getDataStore(file);dataStore.setCharset(Charset.forName("GBK"));// 获取特征资源SimpleFeatureSource simpleFeatureSource = dataStore.getFeatureSource();// 要素集合simpleFeatureCollection = simpleFeatureSource.getFeatures();} catch (IOException e) {e.printStackTrace();}SimpleFeatureIterator featureIterator = simpleFeatureCollection.features();
//            // 要素数量int featureSize = simpleFeatureCollection.size();
//            log.info("要素数量"+featureSize);//创建properties  Mapwhile (featureIterator.hasNext()) {// 要素对象SimpleFeature feature = featureIterator.next();Collection<Property> propertyCollection = (Collection<Property>) feature.getValue();//填充属性mapMap<String, Object> properMap = new HashMap<>();for (Property property : propertyCollection) {if (property.getName().toString().equals("the_geom")) {continue;}properMap.put(property.getName().toString(), property.getValue());}//获取geo信息Object geometryText = feature.getDefaultGeometry();Map geoMap = getGeoMap(geometryText.toString());JSONObject featureObject = buildFeature(geoMap, properMap);featureArray.add(featureObject);}featureIterator.close();JSONObject GeoJson = buildGeoJson(featureArray);return GeoJson;}

4. 运行结果

4.1.3. 完整工具类代码
import lombok.extern.slf4j.Slf4j;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.geojson.geom.GeometryJSON;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.util.*;/*** @version 1.0* @description: gis工具类* @author: chenss* @date 2024-03-14 16:19*/
@Slf4j
public class GisUtil {public static void main(String[] args) {JSONObject Geojson=buildGeojsonFromShp("D:\\arcgisdata\\mesh4490.shp");log.info(Geojson.toJSONString());
//        List<String> wkts = getWktFromShp("D:\\arcgisdata\\mesh4490.shp");
//        for (String wkt : wkts) {
//            log.info(wkt);
//        }}/*** 构造Geojson结构体* @param featuresJson* @return*/public static JSONObject buildGeoJson(JSONArray featuresJson) {JSONObject Geojson = new JSONObject();Geojson.put("type", "FeatureCollection");Geojson.put("features", featuresJson);return Geojson;}/*** 构造Geojson的features部分 单个** @param geoObject* @param properties* @return*/public static JSONObject buildFeature(Map geoObject, Map properties) {JSONObject featureObject = new JSONObject();Map featureMap = new HashMap();featureMap.put("type", "Feature");featureMap.putAll(geoObject);featureMap.put("properties", properties);featureObject.putAll(featureMap);return featureObject;}/*** 获取空间信息并构造为Map* @param wkt* @return*/public static Map getGeoMap(String wkt) {Map<String, Object> geoMap = new HashMap<>();String json = null;try {WKTReader reader = new WKTReader();Geometry geometry = reader.read(wkt);StringWriter writer = new StringWriter();GeometryJSON g = new GeometryJSON();g.write(geometry, writer);geoMap.put("geometry", writer);} catch (Exception e) {e.printStackTrace();}return geoMap;}/*** 只读取geo信息 wkt** @param shpPath* @return*/public static List<String> getWktFromShp(String shpPath) {List<String> shpList = new ArrayList<>();SimpleFeatureCollection simpleFeatureCollection = null;try {//获取文件File file = new File(shpPath);// 读取到数据存储中FileDataStore dataStore = FileDataStoreFinder.getDataStore(file);// 获取特征资源SimpleFeatureSource simpleFeatureSource = dataStore.getFeatureSource();// 要素集合simpleFeatureCollection = simpleFeatureSource.getFeatures();} catch (IOException e) {e.printStackTrace();}// 获取要素迭代器SimpleFeatureIterator featureIterator = simpleFeatureCollection.features();while (featureIterator.hasNext()) {// 要素对象SimpleFeature feature = featureIterator.next();Object geometryText = feature.getDefaultGeometry();log.info(geometryText.toString());shpList.add(geometryText.toString());}featureIterator.close();return shpList;}/*** 基于shp构造geojson并返回** @param shpPath* @return*/public static JSONObject buildGeojsonFromShp(String shpPath) {JSONArray featureArray = new JSONArray();
//        List<String>shpList=new ArrayList<>();SimpleFeatureCollection simpleFeatureCollection = null;try {
//            要素合集//获取文件File file = new File(shpPath);// 读取到数据存储中ShapefileDataStore dataStore = (ShapefileDataStore) FileDataStoreFinder.getDataStore(file);dataStore.setCharset(Charset.forName("GBK"));// 获取特征资源SimpleFeatureSource simpleFeatureSource = dataStore.getFeatureSource();// 要素集合simpleFeatureCollection = simpleFeatureSource.getFeatures();} catch (IOException e) {e.printStackTrace();}SimpleFeatureIterator featureIterator = simpleFeatureCollection.features();
//            // 要素数量int featureSize = simpleFeatureCollection.size();
//            log.info("要素数量"+featureSize);//创建properties  Mapwhile (featureIterator.hasNext()) {// 要素对象SimpleFeature feature = featureIterator.next();Collection<Property> propertyCollection = (Collection<Property>) feature.getValue();//填充属性mapMap<String, Object> properMap = new HashMap<>();for (Property property : propertyCollection) {if (property.getName().toString().equals("the_geom")) {continue;}properMap.put(property.getName().toString(), property.getValue());}//获取geo信息Object geometryText = feature.getDefaultGeometry();Map geoMap = getGeoMap(geometryText.toString());JSONObject featureObject = buildFeature(geoMap, properMap);featureArray.add(featureObject);}featureIterator.close();JSONObject GeoJson = buildGeoJson(featureArray);return GeoJson;}/*** 根据给定的wkt面求出中心点,并以wkt形式返回*/public static String calculateCenter(String wktPolygon) throws ParseException {// 创建 WKT 解析器和写入器WKTReader reader = new WKTReader(new GeometryFactory());WKTWriter writer = new WKTWriter();// 解析面的几何对象Geometry geometry = reader.read(wktPolygon);// 计算面的中心点Point center = geometry.getCentroid();// 将中心点转换为 WKT 格式String wktCenter = writer.write(center);return wktCenter;}}

4.2. 坐标转换工具类

我这个坐标转换工具只应用于同椭球(本文示例为2000坐标系-EPSG:4490)坐标投影转换。已云南的投影带为33-35,对应的EPSG为4521、4522、4523。

4.2.1. 准备数据

1. 准备4490、4521、4522、4523的shp

2. 获取.prj中坐标描述信息

3. 将坐标描述信息存放到常量Map中

static final  Map<String,String> projMap=new HashMap();
static {projMap.put("4522","PROJCS["CGCS2000_3_Degree_GK_Zone_34",GEOGCS["GCS_China_Geodetic_Coordinate_System_2000",DATUM["D_China_2000",SPHEROID["CGCS2000",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",34500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",102.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]");projMap.put("4490","GEOGCS["China Geodetic Coordinate System 2000",\n" +"    DATUM["China_2000",\n" +"        SPHEROID["CGCS2000",6378137,298.257222101,\n" +"            AUTHORITY["EPSG","1024"]],\n" +"        AUTHORITY["EPSG","1043"]],\n" +"    PRIMEM["Greenwich",0,\n" +"        AUTHORITY["EPSG","8901"]],\n" +"    UNIT["degree",0.0174532925199433,\n" +"        AUTHORITY["EPSG","9122"]],\n" +"    AUTHORITY["EPSG","4490"]]");projMap.put("4521","PROJCS["CGCS2000_3_Degree_GK_Zone_33",GEOGCS["GCS_China_Geodetic_Coordinate_System_2000",DATUM["D_China_2000",SPHEROID["CGCS2000",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",33500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",99.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]");projMap.put("4523","PROJCS["CGCS2000_3_Degree_GK_Zone_35",GEOGCS["GCS_China_Geodetic_Coordinate_System_2000",DATUM["D_China_2000",SPHEROID["CGCS2000",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",35500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",105.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]");
}
4.2.2. 完整工具类代码
import lombok.extern.slf4j.Slf4j;
import org.geotools.data.FeatureWriter;
import org.geotools.data.FileDataStoreFactorySpi;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Geometry;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;@Slf4j
public class ProjTransUtil {static final  Map<String,String> projMap=new HashMap();static {projMap.put("4522","PROJCS[\"CGCS2000_3_Degree_GK_Zone_34\",GEOGCS[\"GCS_China_Geodetic_Coordinate_System_2000\",DATUM[\"D_China_2000\",SPHEROID[\"CGCS2000\",6378137.0,298.257222101]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Gauss_Kruger\"],PARAMETER[\"False_Easting\",34500000.0],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",102.0],PARAMETER[\"Scale_Factor\",1.0],PARAMETER[\"Latitude_Of_Origin\",0.0],UNIT[\"Meter\",1.0]]");projMap.put("4490","GEOGCS[\"China Geodetic Coordinate System 2000\",\n" +"    DATUM[\"China_2000\",\n" +"        SPHEROID[\"CGCS2000\",6378137,298.257222101,\n" +"            AUTHORITY[\"EPSG\",\"1024\"]],\n" +"        AUTHORITY[\"EPSG\",\"1043\"]],\n" +"    PRIMEM[\"Greenwich\",0,\n" +"        AUTHORITY[\"EPSG\",\"8901\"]],\n" +"    UNIT[\"degree\",0.0174532925199433,\n" +"        AUTHORITY[\"EPSG\",\"9122\"]],\n" +"    AUTHORITY[\"EPSG\",\"4490\"]]");projMap.put("4521","PROJCS[\"CGCS2000_3_Degree_GK_Zone_33\",GEOGCS[\"GCS_China_Geodetic_Coordinate_System_2000\",DATUM[\"D_China_2000\",SPHEROID[\"CGCS2000\",6378137.0,298.257222101]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Gauss_Kruger\"],PARAMETER[\"False_Easting\",33500000.0],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",99.0],PARAMETER[\"Scale_Factor\",1.0],PARAMETER[\"Latitude_Of_Origin\",0.0],UNIT[\"Meter\",1.0]]");projMap.put("4523","PROJCS[\"CGCS2000_3_Degree_GK_Zone_35\",GEOGCS[\"GCS_China_Geodetic_Coordinate_System_2000\",DATUM[\"D_China_2000\",SPHEROID[\"CGCS2000\",6378137.0,298.257222101]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Gauss_Kruger\"],PARAMETER[\"False_Easting\",35500000.0],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",105.0],PARAMETER[\"Scale_Factor\",1.0],PARAMETER[\"Latitude_Of_Origin\",0.0],UNIT[\"Meter\",1.0]]");}/*** 根据传入wkt获取数据坐标系* @param wkt* @return*/public static String getProj(String wkt){String resEpsg="";int lonLatStart=-1;//根据wkt字符串判断平面坐标位于哪一度带try {for (int i = 0; i < wkt.length(); i++) {if(Integer.valueOf(wkt.charAt(i))>=48&&Integer.valueOf(wkt.charAt(i))<58){lonLatStart=i;break;}}int lonLatEnd=wkt.indexOf(",");String projLonLat=wkt.substring(lonLatStart,lonLatEnd);String[]lonlat=projLonLat.split(" ");String projLon=lonlat[0];if(projLon.substring(0,2).equals("33")){resEpsg="4521";}else if(projLon.substring(0,2).equals("34")){resEpsg="4522";}else if(projLon.substring(0,2).equals("35")){resEpsg="4523";}elsereturn "4490";} catch (Exception e) {log.info(wkt+"出错");log.error(e.getMessage(),e);}return resEpsg;}/*** 坐标转换* @param geom* @param sourceEpsg* @return*/public static Geometry lonlat2WebMactor(Geometry geom,String sourceEpsg){try{//这里是以OGC WKT形式定义的是World Mercator投影,网页地图一般使用该投影CoordinateReferenceSystem crsSource=CRS.parseWKT(projMap.get(sourceEpsg));CoordinateReferenceSystem crsTarget = CRS.parseWKT(projMap.get("4490"));// 投影转换
//            MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, crsTarget);MathTransform transform = CRS.findMathTransform(crsSource, crsTarget);return JTS.transform(geom, transform);}catch (Exception e) {// TODO Auto-generated catch blocklog.error(e.getMessage(),e);return null;}}/***给定inputshp转换为targetEpsg坐标系,并输出到outputShp位置* @param inputShp* @param outputShp* @param targetEpsg* @return*/public static Map projectShape(String inputShp, String outputShp,String targetEpsg){Map map = new HashMap();try {//源shape文件ShapefileDataStore shapeDS = (ShapefileDataStore) new ShapefileDataStoreFactory().createDataStore(new File(inputShp).toURI().toURL());//创建目标shape文件对象Map<String, Serializable> params = new HashMap<String, Serializable>();FileDataStoreFactorySpi factory = new ShapefileDataStoreFactory();File file=FileUtil.createFileByPath(outputShp);
//            if(!file.exists()){params.put(ShapefileDataStoreFactory.URLP.key,file.toURI().toURL());ShapefileDataStore ds = (ShapefileDataStore) factory.createNewDataStore(params);
//            Charset charset = Charset.forName("UTF-8");
//            ds.setCharset(charset);// 设置属性SimpleFeatureSource fs = shapeDS.getFeatureSource(shapeDS.getTypeNames()[0]);//下面这行还有其他写法,根据源shape文件的simpleFeatureType可以不用retype,而直接用fs.getSchema设置
//            CoordinateReferenceSystem crs = CRS.parseWKT(strWKTMercator);CoordinateReferenceSystem crs = CRS.parseWKT(projMap.get("4490"));ds.createSchema(SimpleFeatureTypeBuilder.retype(fs.getSchema(), crs));//设置writerFeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);//写记录SimpleFeatureIterator it = fs.getFeatures().features();try {while (it.hasNext()) {SimpleFeature f = it.next();SimpleFeature fNew = writer.next();fNew.setAttributes(f.getAttributes());Geometry geom = lonlat2WebMactor((Geometry)f.getAttribute("the_geom"),targetEpsg);fNew.setAttribute("the_geom", geom);}}finally {it.close();}writer.write();writer.close();ds.dispose();shapeDS.dispose();
//            }map.put("status", "success");map.put("message", outputShp);}catch (Exception e) {log.error(e.getMessage(),e);map.put("status", "failure");map.put("message", e.getMessage());}return map;}//    public static void main(String[] args) {
//        String input="D:\\jsonshp\\test.shp";
//        String output="D:\\jsonshp\\test4490.shp";
//        projectShape(input,output);
//    }}

5. 结语

本文对GeoTools的基本概念进行了简介,之后介绍了Geotools的工具类及其具体用法。下一篇文章将讲解Postgis+Geotools+MybatisPlus实现数据的读取,写入及前端展示。对Gis开发领域感兴趣的同学可动动你们发财的小手点点关注~

6. 参考链接 

常见2000坐标系对应的EPSG代号 - 知乎

这篇关于【GIS系列】GeoTools简介及工具类分享的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/824959

相关文章

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

GIS图形库更新2024.8.4-9.9

更多精彩内容请访问 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加微信:digital_twin123 Cesium 本期发布了1.121 版本。重大新闻,Cesium被Bentley收购。 ✨ 功能和改进 默认启用 MSAA,采样 4 次。若要关闭 MSAA,则可以设置scene.msaaSamples = 1。但是通过比较,发现并没有多大改善。

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0