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

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

作者:后端小肥肠

目录

1.前言

2. GeoTools简介

3. Geotools使用示例

3.1. 开发环境搭建

3.1.1. 所需版本和工具

3.1.2. pom依赖

3.1.3. 示例代码

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>
3.1.3. 示例代码

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代号 - 知乎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/277585.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用“定时执行专家”软件的25种任务与12种触发器,提升IT系统管理自动化水平

在IT系统管理中&#xff0c;自动化是提高工作效率、减少人为错误的关键。而《定时执行专家》这款软件&#xff0c;以其强大的功能、易用性和毫秒级的执行精度&#xff0c;成为了IT系统管理员的得力助手。今天&#xff0c;我们就来探讨一下如何利用这款软件的25种任务类型和12种…

centos命令history设置记录10000行

今天在操作服务器的时候&#xff0c;用history查看操作记录的时候&#xff0c;发现只能查看10条&#xff0c;这样不行啊&#xff0c;我想查看所有人对服务器操作的命令。 [rootbogon ~]# history解决办法&#xff1a; #1、找到/etc/profile文件中的histsize 把10改成10000 […

jeecg 启动 微服务 更改配置本地host地址

127.0.0.1 jeecg-boot-redis 127.0.0.1 jeecg-boot-mysql 127.0.0.1 jeecg-boot-nacos 127.0.0.1 jeecg-boot-gateway 127.0.0.1 jeecg-boot-system 127.0.0.1 jeecg-boot-sentinel 127.0.0.1 jeecg-boot-xxljob 127.0.0.1 jeecg-boot-rabbitmq1. windows系统下&#xff0c;在开…

基于springboot+vue实现艺术水平考级报名系统【项目源码+论文说明】计算机毕业设计

基于springbootvue实现艺术水平考级报名系统演示 摘要 本次毕业设计基于SpringBoot框架开发了一款艺术水平考级报名管理系统。该系统为考生提供了线上报名、准考证管理等核心功能&#xff0c;并为系统管理员提供了在线发布考试信息、对报名考生进行审核等管理功能。通过该系统…

基于Java+SpringMVC+vue+element实现前后端分离校园失物招领系统详细设计

基于JavaSpringMVCvueelement实现前后端分离校园失物招领系统详细设计 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收…

Java学习笔记------常用API(五)

爬虫 从网站中获取 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.regex.Matcher; import java.util.reg…

AI:149-法律电子邮件图像中的欺诈检测与敲诈勒索追踪—深度学习技术

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带关键代码,详细讲解供大家学习,希望…

一款博客网站源码

一款博客网站源码 源码软件库 为大家内置了主题 清爽又强大真正的永久可用的一条源码&#xff0c;该版本为整合版本&#xff0c;内置了Joe主题&#xff0c;搭建后直接启用即可~ 安装环境要求&#xff1a; PHP 7.2 以上 MySQL, PostgreSQL, SQLite 任意一种数据库支持&#xff…

基于单片机的智能小车泊车系统设计

摘 要:随着信息技术的进步,汽车逐渐朝着安全、智能方向发展,智能泊车系统的出现不仅能帮助人们更加快速、安全地完成泊车操作,而且适用于狭小空间的泊车操作,降低驾驶员泊车负担,减轻泊车交通事故发生率。文章基于单片机设计自动泊车系统,以单片机为核心来实现信息收集及…

Ubuntu 虚拟机安装

最小化安装后常用工具 sudo apt-get install vim# ifconfig apt install net-tools # nload apt install nload # 很多都要用到 apt install build-essential # 开发相关 apt install gcc gapt install iproute2 ntpdate tcpdump telnet traceroute \ nfs-kernel-server nfs…

LeetCode 2684.矩阵中移动的最大次数:一列一列处理,只记能到哪行(BFS)

【LetMeFly】2684.矩阵中移动的最大次数&#xff1a;一列一列处理&#xff0c;只记能到哪行(BFS) 力扣题目链接&#xff1a;https://leetcode.cn/problems/maximum-number-of-moves-in-a-grid/ 给你一个下标从 0 开始、大小为 m x n 的矩阵 grid &#xff0c;矩阵由若干 正 整…

《如何使用C语言去下三子棋?》

目录 一、环境配置 二、功能模块 1.打印菜单 2.初始化并打印棋盘 3、行棋 3.1玩家行棋 3.2电脑行棋 4、判断是否和棋 5.判赢 三、代码实现 1、test.c文件 2、game.c文件 3、game.h文件 一、环境配置 本游戏用到三个文件&#xff0c;分别是两个源文件test.c game.c 和…

【网络原理】TCP 协议中比较重要的一些特性(三)

目录 1、拥塞控制 2、延时应答 3、捎带应答 4、面向字节流 5、异常情况处理 5.1、其中一方出现了进程崩溃 5.2、其中一方出现关机&#xff08;正常流程的关机&#xff09; 5.3、其中一方出现断电&#xff08;直接拔电源&#xff0c;也是关机&#xff0c;更突然的关机&am…

计算机网络 |内网穿透

其实内网穿透&#xff0c;也挺好玩的&#xff0c;如果在大学的时候&#xff0c;那个时候讲计算机网络的老师能横向延展&#xff0c;估计课也会更有趣不少&#xff0c;本来计算机网络这门课就是计算机课程中可玩性最搞的。 只能说&#xff0c;怪可惜的 回到正题&#xff0c;内网…

SQL-Labs靶场“32-33”关通关教程

君衍. 一、32关 GET单引号闭合宽字节注入1、源码分析2、宽字节注入原理3、联合查询注入4、updatexml报错注入5、floor报错注入 二、33关 GET单引号addslashes逃逸注入1、源码分析2、联合查询注入3、updatexml报错注入4、floor报错注入 SQL-Labs靶场通关教程&#xff1a; SQL注入…

GaN HEMTs在电力电子应用中的交叉耦合与基板电容分析与建模

来源&#xff1a;Analysis and Modeling of Cross-Coupling and Substrate Capacitances in GaN HEMTs for Power-Electronic Applications&#xff08; TED 17年&#xff09; 摘要 本文提出了一种考虑了基板电容与场板之间交叉耦合效应的场板AlGaN/GaN高电子迁移率晶体管(HE…

zookeeper快速入门二:zookeeper基本概念

本文是zookeeper系列之快速入门中的第二篇&#xff0c;欢迎大家观看与指出不足。 目录 一、zookeeper的存储结构 二、什么是znode 三、znode节点的四种类型 四、权限控制ACL&#xff08;Access Control List&#xff09; 五、事件监听watcher 一、zookeeper的存储结构 z…

【Java系列】OOM 时,JVM 堆栈信息保存和分析

一、前言 在日常开发中&#xff0c;即使代码写得再谨慎&#xff0c;免不了还是会发生各种意外的事件&#xff0c;比如服务器内存突然飙高&#xff0c;又或者发生内存溢出(OOM)。当发生这种情况时&#xff0c;我们怎么去排查&#xff0c;怎么去分析原因呢&#xff1f; 一般遇到…

MySQL8空间索引失效

发现问题 表结构如下&#xff0c;boundary字段建立空间索引 CREATE TABLE area (id int(11) NOT NULL COMMENT 行政区划编码,pid int(11) NOT NULL COMMENT 上级编码,deep int(11) NOT NULL COMMENT 深度,name varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_…

深入理解RAG:检索与生成的融合

原文地址&#xff1a;https://dev.to/portkey/understanding-rag-a-deeper-dive-into-the-fusion-of-retrieval-and-generation-1l4b 深入理解RAG:检索与生成的融合 检索增强生成(RAG)模型代表了检索系统和生成模型两大不同但互补组件完美结合的杰作。通过无缝集成相关信息检…