4 Geotools坐标参考系与转换

在地理信息系统 (GIS) 开发中,坐标参考系统 (Coordinate Reference System, CRS) 是核心概念之一。无论是处理地图投影、坐标转换,还是在 Spring Boot 应用中管理空间数据,理解和正确使用 CRS 都至关重要。本文将围绕 GeoTools 库,深入探讨 CRS 的重要性、EPSG 代码的概念与查询,以及如何在代码中定义 CRS 和执行坐标转换,最后结合 Spring Boot 展示实际应用场景。

坐标参考系统 (CRS) 的重要性

坐标参考系统定义了地理数据如何在二维或三维空间中表示。不同的 CRS 使用不同的投影方法和单位(例如,度、米),以适应特定场景的需求。简单的说坐标系类型分地理坐标(球面坐标,只有椭球信息,以经度为x轴,纬度为Y轴的),投影坐标系(平面坐标,椭球信息+投影方式,以横坐标经线为x轴,纵坐标纬线投影为Y轴。分带的投影有中央经线)以下是几种常见的 CRS 及其应用场景:

  • WGS84 (EPSG:4326): 基于经纬度的全球通用 CRS,常用于 GPS 和全球地图数据。单位是度,适合存储和表示地理坐标。
  • UTM (Universal Transverse Mercator): 基于米单位的投影系统,将地球划分为 60 个区域,适合局部区域的高精度计算。例如,UTM Zone 50N (EPSG:32650) 用于东亚部分地区。
  • Web Mercator (EPSG:3857): 广泛用于在线地图(如 Google Maps、OpenStreetMap),以米为单位,适合网络地图渲染,但会引入投影变形。
  • **CGCS2000(EPSG:4490)**2000国家大地坐标系,是中国当前最新的国家大地坐标系,000国家大地坐标系的原点为包括海洋和大气]的整个地球的质量中心

为什么 CRS 重要?

  1. 数据一致性: 不同数据源可能使用不同 CRS,未正确转换会导致位置错误。
  2. 计算精度: 不同 CRS 的单位和投影会影响距离、面积等计算结果。
  3. 互操作性: 在多系统集成时,统一 CRS 确保数据无缝对接。

示例场景:

  • 假设你有一个 WGS84 坐标点 (经度: 116.4, 纬度: 39.9,北京),需要将其转换为 Web Mercator 以在地图上显示。如果不进行 CRS 转换,直接绘制会导致位置偏差。

EPSG 代码的概念与查询

EPSG 代码是由国际石油工业协会 (OGP) 定义的标准化编号,用于唯一标识 CRS。例如:

  • EPSG:4326 表示 WGS84。
  • EPSG:3857 表示 Web Mercator。
  • EPSG:32650 表示 UTM Zone 50N。

如何查询 EPSG 代码?

  1. 在线资源:
    • epsg.io: 输入地区或 CRS 名称(如 “WGS84” 或 “China”)即可查找相关 EPSG 代码。
    • spatialreference.org: 提供 CRS 定义和 GeoTools 兼容的引用。
  2. GeoTools 内置查询: GeoTools 提供了 CRS.lookupIdentifier() 方法,可以通过 CRS 对象反查 EPSG 代码。

代码示例: 查询 CRS 的 EPSG 代码

import org.geotools.referencing.CRS;public class CRSLookupExample {public static void main(String[] args) throws Exception {// 定义 WGS84 CRSCoordinateReferenceSystem crs = CRS.decode("EPSG:4326");// 查询 EPSG 代码String epsgCode = CRS.lookupIdentifier(crs, true);System.out.println("EPSG Code: " + epsgCode); // 输出: EPSG:4326}
}

定义和获取 CRS

GeoTools 使用 CRS.decode() 方法通过 EPSG 代码定义 CRS。以下是常见操作的代码示例。

定义 CRS

import org.geotools.referencing.CRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;public class DefineCRSExample {public static void main(String[] args) throws Exception {// 定义 WGS84 (EPSG:4326)CoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326");System.out.println("WGS84 CRS: " + wgs84.getName());// 定义 Web Mercator (EPSG:3857)CoordinateReferenceSystem webMercator = CRS.decode("EPSG:3857");System.out.println("Web Mercator CRS: " + webMercator.getName());// 定义 UTM Zone 50N (EPSG:32650)CoordinateReferenceSystem utm50N = CRS.decode("EPSG:32650");System.out.println("UTM Zone 50N CRS: " + utm50N.getName());}
}

输出:

WGS84 CRS: WGS 84
Web Mercator CRS: WGS 84 / Pseudo-Mercator
UTM Zone 50N CRS: WGS 84 / UTM zone 50N

处理异常

CRS.decode() 可能抛出 FactoryException,通常是因为 EPSG 代码无效或 GeoTools 无法解析。建议始终使用 try-catch 捕获异常。


坐标转换

坐标转换是将一个 CRS 中的坐标转换为另一个 CRS 的过程。GeoTools 提供了 CRS.findMathTransform() 和 JTS.transform() 方法来实现转换。

基本流程

  1. 获取源和目标 CRS。
  2. 使用 CRS.findMathTransform(sourceCRS, targetCRS) 创建转换器。
  3. 使用 JTS.transform() 执行坐标转换。

代码示例:点转换

以下示例将北京的 WGS84 坐标 (116.4, 39.9) 转换为 Web Mercator。(记得看注意事项)

import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;public class CoordinateTransformExample {public static void main(String[] args) throws Exception {// 定义源和目标 CRSCoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326");CoordinateReferenceSystem webMercator = CRS.decode("EPSG:3857");// 创建坐标转换器MathTransform transform = CRS.findMathTransform(wgs84, webMercator);// 创建 WGS84 坐标点 (北京: 116.4, 39.9)GeometryFactory factory = new GeometryFactory();Point point = factory.createPoint(new Coordinate(116.4, 39.9));// 执行转换Point transformedPoint = (Point) JTS.transform(point, transform);// 输出结果System.out.println("WGS84 Point: " + point);System.out.println("Web Mercator Point: " + transformedPoint);}
}

输出:

WGS84 Point: POINT (116.4 39.9)
Web Mercator Point: POINT (12957326.04 4852936.40)

解释:

  • WGS84 坐标 (116.4, 39.9) 是经纬度,单位为度。
  • Web Mercator 坐标 (12957326.04, 4852936.40) 是以米为单位的投影坐标。

栅格坐标转换

import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.coverage.grid.io.GridCoverage2DReader;
import org.geotools.coverage.grid.io.GridFormatFinder;
import org.geotools.coverage.processing.CoverageProcessor;
import org.geotools.coverage.processing.operation.Resample;
import org.geotools.referencing.CRS;
import org.geotools.util.factory.Hints;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.crs.CoordinateReferenceSystem;import java.io.File;public class RasterTransformExample {public static void main(String[] args) throws Exception {// 输入和输出文件路径File inputFile = new File("input.tif"); // 替换为你的 GeoTIFF 文件File outputFile = new File("output_transformed.tif");// 读取栅格数据GridCoverage2DReader reader = GridFormatFinder.getFormat(inputFile).getReader(inputFile);GridCoverage2D coverage = reader.read(null);// 定义源和目标 CRSCoordinateReferenceSystem sourceCRS = coverage.getCoordinateReferenceSystem();CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:3857"); // Web Mercator// 配置重采样参数CoverageProcessor processor = CoverageProcessor.getInstance();ParameterValueGroup params = processor.getOperation("Resample").getParameters();params.parameter("Source").setValue(coverage);params.parameter("CoordinateReferenceSystem").setValue(targetCRS);params.parameter("InterpolationType").setValue("bilinear"); // 双线性插值// 执行重投影GridCoverage2D reprojected = (GridCoverage2D) processor.doOperation(params);// 保存结果AbstractGridFormat format = GridFormatFinder.getFormat(outputFile);format.write(reprojected, new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE), outputFile);System.out.println("Raster transformation completed. Output saved to: " + outputFile.getAbsolutePath());}
}

说明

  • 输入: 一个 GeoTIFF 文件 (input.tif),假设其 CRS 为 WGS84 (EPSG:4326)。
  • 转换: 使用 CoverageProcessor 和 Resample 操作将栅格数据重投影到 Web Mercator (EPSG:3857)。
  • 插值: 使用双线性插值 (bilinear) 确保像素值平滑过渡,也可选择 nearest(最近邻)或 bicubic(双三次)。
  • 输出: 保存为新的 GeoTIFF 文件 (output_transformed.tif)。
  • 注意: 确保 input.tif 存在且具有正确的 CRS 元数据。GeoTools 依赖文件的 CRS 信息来识别源 CRS。

shape数据转换

import org.geotools.data.DataStore;
import org.geotools.data.DataUtilities;
import org.geotools.data.FeatureWriter;
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.feature.simple.SimpleFeatureTypeBuilder;
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.nio.charset.StandardCharsets;public class ShapefileTransformExample {public static void main(String[] args) throws Exception {// 输入和输出文件File inputFile = new File("input.shp"); // 替换为你的 ShapefileFile outputFile = new File("output_transformed.shp");// 读取 ShapefileShapefileDataStore inputStore = new ShapefileDataStore(inputFile.toURI().toURL());String typeName = inputStore.getTypeNames()[0];SimpleFeatureSource featureSource = inputStore.getFeatureSource(typeName);SimpleFeatureCollection featureCollection = featureSource.getFeatures();// 定义源和目标 CRSCoordinateReferenceSystem sourceCRS = featureSource.getSchema().getCoordinateReferenceSystem();CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:3857"); // Web Mercator// 创建坐标转换器MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS);// 创建输出 Shapefile 的 FeatureTypeSimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();builder.setName(featureSource.getSchema().getName());builder.setAttributes(featureSource.getSchema().getAttributes());builder.setCRS(targetCRS); // 设置目标 CRSSimpleFeatureType targetFeatureType = builder.buildFeatureType();// 创建输出 ShapefileShapefileDataStore outputStore = new ShapefileDataStore(outputFile.toURI().toURL());outputStore.createSchema(targetFeatureType);outputStore.setCharset(StandardCharsets.UTF_8);// 写入转换后的特征try (FeatureWriter<SimpleFeatureType, SimpleFeature> writer = outputStore.getFeatureWriterAppend(typeName)) {try (SimpleFeatureIterator iterator = featureCollection.features()) {while (iterator.hasNext()) {SimpleFeature feature = iterator.next();SimpleFeature newFeature = DataUtilities.createFeature(targetFeatureType, feature.getID());// 复制属性for (int i = 0; i < feature.getAttributeCount(); i++) {newFeature.setAttribute(i, feature.getAttribute(i));}// 转换几何Geometry geometry = (Geometry) feature.getDefaultGeometry();Geometry transformedGeometry = JTS.transform(geometry, transform);newFeature.setDefaultGeometry(transformedGeometry);// 写入新特征writer.next().setAttributes(newFeature.getAttributes());writer.write();}}}// 清理资源inputStore.dispose();outputStore.dispose();System.out.println("Shapefile transformation completed. Output: " + outputFile.getAbsolutePath());}
}

说明

  • 输入: 一个 WGS84 的 Shapefile (input.shp)。
  • 转换: 使用 JTS.transform() 转换每个特征的几何对象。
  • 输出: 保存为新的 Shapefile (output_transformed.shp),CRS 为 Web Mercator。
  • 注意:
    • 确保输入 Shapefile 包含 .shp、.shx、.dbf 和 .prj 文件,尤其是 .prj 文件定义了源 CRS。
    • 使用 StandardCharsets.UTF_8 避免中文属性乱码。

geojson转换

import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geojson.feature.FeatureJSON;
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.FileOutputStream;public class GeoJSONTransformExample {public static void main(String[] args) throws Exception {// 输入和输出文件File inputFile = new File("input.geojson"); // 替换为你的 GeoJSON 文件File outputFile = new File("output_transformed.geojson");// 读取 GeoJSONFeatureJSON featureJSON = new FeatureJSON();SimpleFeatureCollection featureCollection = featureJSON.readFeatureCollection(inputFile);// 定义源和目标 CRSCoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326"); // GeoJSON 默认 WGS84CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:3857"); // Web Mercator// 创建坐标转换器MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS);// 创建输出 FeatureTypeSimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();builder.setName("TransformedFeatures");builder.setAttributes(featureCollection.getSchema().getAttributes());builder.setCRS(targetCRS);SimpleFeatureType targetFeatureType = builder.buildFeatureType();// 创建新的 FeatureCollectionorg.geotools.feature.FeatureCollection<SimpleFeatureType, SimpleFeature> transformedFeatures =DataUtilities.collection(featureCollection.size());// 转换每个特征try (SimpleFeatureIterator iterator = featureCollection.features()) {while (iterator.hasNext()) {SimpleFeature feature = iterator.next();SimpleFeature newFeature = DataUtilities.createFeature(targetFeatureType, feature.getID());// 复制属性for (int i = 0; i < feature.getAttributeCount(); i++) {newFeature.setAttribute(i, feature.getAttribute(i));}// 转换几何Geometry geometry = (Geometry) feature.getDefaultGeometry();Geometry transformedGeometry = JTS.transform(geometry, transform);newFeature.setDefaultGeometry(transformedGeometry);// 添加到集合transformedFeatures.add(newFeature);}}// 保存转换后的 GeoJSONtry (FileOutputStream fos = new FileOutputStream(outputFile)) {featureJSON.writeFeatureCollection(transformedFeatures, fos);}System.out.println("GeoJSON transformation completed. Output: " + outputFile.getAbsolutePath());}
}

说明

  • 输入: 一个 GeoJSON 文件 (input.geojson),默认 CRS 为 WGS84。
  • 转换: 使用 JTS.transform() 转换每个特征的几何。
  • 输出: 保存为新的 GeoJSON 文件 (output_transformed.geojson),几何坐标为 Web Mercator。
  • 注意:
    • GeoJSON 标准默认使用 WGS84,输出的 GeoJSON 文件不会显式存储 CRS 信息,需在文档或元数据中说明。
    • 确保 GeoJSON 文件格式正确,包含 type: FeatureCollection 或 type: Feature。

注意事项

  • 经纬度顺序: WGS84 使用 (经度, 纬度),但某些 CRS 可能要求 (纬度, 经度)。GeoTools 会自动处理,但建议检查 CRS.getAxisOrder()。

  • 性能优化: MathTransform 对象可复用,避免重复创建。

  • 异常处理: 确保捕获 FactoryException 和 TransformException。

    上述示例代码没有任何问题,但是运行绝对不会得到输出的结果,24-R得不到。原因就出在了经纬度顺序上。如果你换一种方式定义,就没问题了

        public  String transformAndBufferWkt(String wkt, double bufferDistance) throws Exception {// 1. 解析 WKT 字符串为 Geometry 对象WKTReader wktReader = new WKTReader();Geometry geometry = wktReader.read(wkt);// 2. 定义源坐标系 (EPSG:4326) 和目标坐标系 (EPSG:3857)CoordinateReferenceSystem sourceCRS = getCRS4326();CoordinateReferenceSystem targetCRS =getCRS3857();// 3. 创建坐标转换器MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);// 4. 将几何对象从 EPSG:4326 转换为 EPSG:3857Geometry geometry3857 = JTS.transform(geometry, transform);// 5. 生成缓冲区(单位为米,因为 EPSG:3857 使用米)Geometry buffer = geometry3857.buffer(bufferDistance);// 6. 将缓冲区几何对象转换回 WKTWKTWriter wktWriter = new WKTWriter();return wktWriter.write(buffer);}private  CoordinateReferenceSystem getCRS4326(){try {String str = "GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433],AUTHORITY[\"EPSG\",4326]]";return CRS.parseWKT(str);}catch (Exception e){System.out.println(e.getMessage());return null;}}private  CoordinateReferenceSystem getCRS3857() {try {String str = "PROJCS[\"WGS_1984_Web_Mercator_Auxiliary_Sphere\",GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Mercator_Auxiliary_Sphere\"],PARAMETER[\"False_Easting\",0.0],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",0.0],PARAMETER[\"Standard_Parallel_1\",0.0],PARAMETER[\"Auxiliary_Sphere_Type\",0.0],UNIT[\"Meter\",1.0],AUTHORITY[\"EPSG\",3857]]";return CRS.parseWKT(str);}catch (Exception e){System.out.println(e.getMessage());return null;}}

在 Spring Boot 应用中处理 CRS 数据

在实际项目中,Spring Boot 常用于构建 REST API,处理不同 CRS 的空间数据。以下是一个完整示例,展示如何在 Spring Boot 中接收 WGS84 坐标,转换为 Web Mercator,并返回结果。

项目依赖

在 pom.xml 中添加 GeoTools 和 JTS 依赖:

<dependencies><!-- GeoTools --><dependency><groupId>org.geotools</groupId><artifactId>gt-main</artifactId><version>25.0</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-epsg-hsql</artifactId><version>25.0</version></dependency><!-- JTS --><dependency><groupId>org.locationtech.jts</groupId><artifactId>jts-core</artifactId><version>1.18.2</version></dependency><!-- 栅格 支持 --><dependency><groupId>org.geotools</groupId><artifactId>gt-geotiff</artifactId><version>25.0</version></dependency><!-- Shapefile 支持 --><dependency><groupId>org.geotools</groupId><artifactId>gt-shapefile</artifactId><version>25.0</version></dependency><!-- GeoJSON 支持 --><dependency><groupId>org.geotools</groupId><artifactId>gt-geojson</artifactId><version>25.0</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-coverage</artifactId><version>25.0</version></dependency><!-- Spring Boot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>3.2.0</version></dependency>
</dependencies><repositories><repository><id>osgeo</id><url>https://repo.osgeo.org/repository/release/</url></repository>
</repositories>

创建 REST API

以下是一个 Spring Boot 控制器,用于接收 WGS84 坐标并转换为 Web Mercator。

import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class CoordinateController {private final GeometryFactory factory = new GeometryFactory();@GetMapping("/transform")public String transformCoordinates(@RequestParam double lon,@RequestParam double lat) throws Exception {// 定义源和目标 CRSCoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326");CoordinateReferenceSystem webMercator = CRS.decode("EPSG:3857");// 创建坐标转换器MathTransform transform = CRS.findMathTransform(wgs84, webMercator);// 创建 WGS84 坐标点Point point = factory.createPoint(new Coordinate(lon, lat));// 执行转换Point transformedPoint = (Point) JTS.transform(point, transform);// 返回结果return String.format("WGS84: %s, Web Mercator: %s", point, transformedPoint);}
}

测试 API

启动 Spring Boot 应用后,使用以下命令测试:

curl "http://localhost:8080/transform?lon=116.4&lat=39.9"

响应:

WGS84: POINT (116.4 39.9), Web Mercator: POINT (12957326.04 4852936.40)

扩展:处理多种 CRS

若需要支持用户指定的目标 CRS,可以添加参数:

@GetMapping("/transform")
public String transformCoordinates(@RequestParam double lon,@RequestParam double lat,@RequestParam String targetEpsg) throws Exception {CoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326");CoordinateReferenceSystem targetCrs = CRS.decode(targetEpsg);MathTransform transform = CRS.findMathTransform(wgs84, targetCrs);Point point = factory.createPoint(new Coordinate(lon, lat));Point transformedPoint = (Point) JTS.transform(point, transform);return String.format("WGS84: %s, %s: %s", point, targetEpsg, transformedPoint);
}

测试:

curl "http://localhost:8080/transform?lon=116.4&lat=39.9&targetEpsg=EPSG:32650"

响应:

WGS84: POINT (116.4 39.9), EPSG:32650: POINT (370139.44 4412630.12)

实际应用中的注意事项

  1. CRS 选择:
    • 根据应用场景选择合适的 CRS。例如,Web 地图使用 EPSG:3857,区域分析使用 UTM。
  2. 性能优化:
    • 缓存 MathTransform 对象,避免重复创建。
    • 使用批量转换处理大量坐标点。
  3. 数据验证:
    • 验证输入坐标是否在 CRS 的有效范围内(例如,UTM 仅适用于特定区域)。
  4. 异常处理:
    • 捕获 FactoryException(CRS 定义失败)和 TransformException(转换失败)。

通过本文,我们深入探讨了 GeoTools 中 CRS 和坐标转换的核心概念:

  • CRS 重要性: 确保数据一致性和计算精度。
  • EPSG 代码: 标准化的 CRS 标识,可通过在线工具或 GeoTools 查询。
  • 定义和转换: 使用 CRS.decode() 定义 CRS,CRS.findMathTransform() 和 JTS.transform() 实现坐标转换。
  • Spring Boot 集成: 通过 REST API 实现灵活的坐标转换服务。

希望这些示例和讲解能帮助你快速上手 GeoTools 的 CRS 功能,并在实际项目中高效处理空间数据!如果有更多问题,欢迎随时交流。


参考资源:

  • GeoTools 官方文档
  • EPSG 数据库
  • GeoTools GitHub

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

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

相关文章

docker start mysql失败,解决方案

文章目录 1.查看端口占用情况2.关闭7767进程3.再次检查4.运行docker start mysql 1.查看端口占用情况 sudo netstat -tanlp | grep :33062.关闭7767进程 sudo kill -9 77673.再次检查 进程已关闭 4.运行docker start mysql 正确启动 备注&#xff1a;可能要关闭防火墙

SQL关键字三分钟入门:DELETE —— 删除数据

在数据库操作中&#xff0c;除了添加和修改记录外&#xff0c;我们有时还需要删除不需要的记录。例如&#xff1a; 清除不再使用的用户账号&#xff1b;删除已完成并归档的订单&#xff1b;移除测试时插入的数据。 这时候就需要用到 SQL 中非常基础但极其重要的关键字 —— D…

electron 全量更新

electron-builder.yml配置更新地址 # 配置自动更新的信息 publish:provider: generic # 更新服务提供者url: http://xxx.xxxx.com/pc/xxx-xx# 更新的地址服务器地址 会自动读取latest.yml 下的版本号比较 检测更新方法autoUpdater.js// src/main/autoUpdater.jsimport { app, d…

《大模型 Agent 应用实战指南》第2章:商业目标与 Agent 能力边界定义

在任何技术项目,特别是像大模型 Agent 这样具有创新性和复杂性的项目启动之初,明确清晰的商业目标是成功的基石。这不仅仅是技术团队的职责,更需要产品、运营、销售甚至高层管理者的深度参与。一个明确的目标能确保所有团队成员步调一致,资源有效分配,并最终衡量项目的成功…

提供稳定可靠的自助共享空间系统,支撑客户无人自助门店运营不错数据,历程感想

以技术产品研发系统为主&#xff0c;为客户提供自助共享空间系统解决方案&#xff0c;适用于共享棋牌室&#xff0c;共享麻将室&#xff0c;共享台球室&#xff0c;共享KTV&#xff0c;共享舞蹈室等场景&#xff0c;以下是其中一位客户真实门店运营数据&#xff0c;第一家店本月…

Golang单例实现

Go语言中&#xff0c;实现单例模式的方式有很多种。单例模式确保一个类只有一个实例&#xff0c;并提供一个全局访问点。Go语言没有类的概念&#xff0c;但是可以通过结构体、函数和包级变量来实现类似的功能。 懒汉实现 type Product interface {DoSomething() }type single…

JVM元空间(Metaspace)详解及其工作流程

JVM元空间(Metaspace)详解与工作流程分析 元空间概述 元空间(Metaspace)是Java虚拟机(JVM)在HotSpot VM 1.8及以后版本中引入的&#xff0c;用于替代永久代(PermGen)的内存区域。它主要存储类的元数据信息&#xff0c;包括&#xff1a; 类的结构信息&#xff08;如方法、字段…

【JAVA】idea中打成jar包后报错错误: 找不到或无法加载主类

排查步骤 首先要排查的是&#xff0c;将jar文件打开&#xff0c;查看里面的内容是否完整是否有META-INF/MANIFEST.MF是否有MANIFEST.MF里面类路径的目录排查路径里面是否有class文件&#xff0c;如主类 com.example.Main 对应的 class 文件应位于 com/example/Main.class 常见…

Fisco Bcos学习 - 开发第一个区块链应用

文章目录 一、前言二、业务场景分析&#xff1a;简易资产管理系统三、智能合约设计与实现3.1 存储结构设计3.2 接口设计3.3 完整合约代码 四、合约编译与Java接口生成五、SDK配置与项目搭建5.1 获取Java工程项目5.2 项目目录结构5.3 引入Web3SDK5.4 证书与配置文件 六、业务开发…

软件设计模式选择、判断解析-1

前言 解析是我个人的理解&#xff0c;相对来说我觉得是能对上定义的逻辑的 目录 一.单选题 1.设计模式的两大主题是(  )  解析&#xff1a;无 2.下列模式中,属于行为型模式的是&#xff08;&#xff09; 解析&#xff1a; 排除A和D&#xff0c;剩下的观察者的“观察”…

【编程基本功】Win11中Git安装配置全攻略,包含Git以及图形化工具TortoiseGit

1 摘要 今天田辛老师给大家带来了一份超实用的博客&#xff0c;手把手教你安装并配置 Git 及其图形化界面 TortoiseGit&#xff0c;从官网下载到最终完成配置&#xff0c;每一个步骤都给大家讲得明明白白&#xff0c;还配有相应的截图&#xff0c;即使是新手小白也能轻松上手&…

细谈QT信号与槽机制

转自个人博客 信号与槽是我个人认为QT中最牛的机制之一&#xff0c;最近没有其他的内容可写&#xff0c;今天就来细细总结一下这个信号与槽机制。 1. 信号与槽机制概述 信号与槽机制可以理解为QT中的一种通信手段&#xff0c;在运行相关代码前&#xff0c;分别声明信号和槽&a…

Docker Swarm 与 Kubernetes 在集群管理上的主要区别

Docker Swarm 和 Kubernetes 是两种流行的容器编排工具&#xff0c;它们都可以用于部署、管理和扩展容器化应用&#xff0c;但在集群管理方面有明显的差异。 下面从多个维度对比它们在集群管理上的主要区别&#xff1a; ✅ 一、总体定位 项目Docker SwarmKubernetes官方支持D…

【StarRocks系列】查询优化

步骤参考官网 分析查询 | StarRocks StarRocks-Profile分析及优化指南 StarRocks-Profile分析及优化指南 - 经验教程 - StarRocks中文社区论坛

软测八股--测试理论 1 测试基础

软件测试&#xff1f; 发现程序中的侧屋执行程序工程 目的&#xff1a;不仅是找出错误&#xff0c;还要分析错误产生原因和错误分布。检查开发如阿健过程出现的bug&#xff0c;使开发人员及时修改。测试只能说明软件中存在错误 目标&#xff1a;尽可能发现多的错误。一个好的…

mfc与vs成功在xp系统所需做的修改

目录 前言一、MFC程序 inet_pton 、CT2A 未声明问题1&#xff09;问题1&#xff1a;inet_pton &#xff1a;undeclared identifier - inet_pton未声明2&#xff09;问题1&#xff1a;CT2A &#xff1a;undeclared identifier - CT2A未声明 二、VS程序 使用事件、委托问题1&…

SpringMVC系列(三)(请求处理的十个实验(上))

0 引言 作者正在学习SpringMVC相关内容&#xff0c;学到了一些知识&#xff0c;希望分享给需要短时间想要了解SpringMVC的读者朋友们&#xff0c;想用通俗的语言讲述其中的知识&#xff0c;希望与诸位共勉&#xff0c;共同进步&#xff01; 本系列会持续更新&#xff01;&…

Python案例练习:函数专题

用函数重新设计文章单词出现次数程序 composition This is my family. We have a father, a mother and two brothers. My father is a doctor. He works in a hospital. My mother is a teacher. She teaches English in a school. My older brother is a student. He stu…

数据驱动 AI 时代:数据库行业的技术跃迁与生态重构

在数据驱动的 AI 战场&#xff0c;真正的决胜武器不是复杂精妙的算法模型&#xff0c;而是深埋在企业核心系统中的高维数据网络&#xff08;图&#xff09;。 时至今日&#xff0c;市场对AI的风向正从“狂飙突进”转向“精耕细作”&#xff0c;就在上周&#xff08;米国时间6月…

码分复用通俗理解

一、码分复用&#xff08;CDMA&#xff09;的通俗理解 码分复用&#xff08;Code Division Multiple Access&#xff0c;CDMA&#xff09;是一种让多个用户在同一时间、同一频段上同时传输数据的技术。它的核心思想是&#xff1a;给每个用户分配一个唯一的“编码钥匙”&#x…