PostGis -基础、Springboot 整合、电子围栏处理

news2024/11/15 17:52:01

目的: 为什么要用PostgreSQL?

  • 因为有时候我们需要存储 空间数据,如:存储一个 多边形 到数据。
  • PostGis中 geometrygeography :基本空间数据类型,用于表达点线面等空间要素,具体类型涵盖了OGC的简单对象模型
  • 在这里插入图片描述

说明:PostGIS是PostgreSQL对象关系数据库的空间数据库扩展。它增加了对地理对象的支持,允许在SQL中运行位置查询。

特点:

  • PostGIS是在对象关系型数据库PostgreSQL上增加了存储管理空间数据的能力的开源空间数据库,空间数据库像存储和操作数据库中其他任何对象一样去存储和操作空间对象。
  • 它是PostgreSQL的扩展插件,在PostgreSQL的core(存储、检索、事务等)层之上实现GIS层的功能,它不能独立于PostgreSQL运行。

常见名词:

  • WKT(Well-known text) 是开放地理空间联盟OGC(Open GIS Consortium )制定的一种文本标记语言,用于表示矢量几何对象、空间参照系统及空间参照系统之间的转换
    • POINT(1 2)
    • 常见描述: Point 点 、LineString 线、 Polygon 多边形 …在这里插入图片描述> - WKB(well-known binary) 是WKT的二进制表示形式,解决了WKT表达方式冗余的问题,便于传输和在数据库中存储相同的信息> - "01020000800200000097E5880801845C404D064F3AF4AE36400000000000000000290A915F01845C40DC90B1A051AE36400000000000000000"> - pg库中 geometry 类型字段,默认存储的就是wkb
  • GeoJson :{[“type": “Point", “coordinates”: [30, 10]}

常见安装:

官网下载地址:
https://www.enterprisedb.com/downloads/postgres-postgresql-downloads

扩展插件,空间数据处理 postgis安装
https://www.postgresql.org/ftp/postgis/
http://download.osgeo.org/postgis/windows/pg10/

docker安装

version: "3.1"
services:
 postgresql:
  image: postgres:12-alpine
  container_name: postgresql
  environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: "root"
      POSTGRES_PASSWORD: "root"
  ports:
    - 5432:5432
  volumes:
    - ./data:/var/lib/postgresql/data

常见函数

-- 创建扩展函数
CREATE EXTENSION postgis;

--  读取wkt字符串为geometry
ST_GeomFromTextST_GeometryFromText--  转换为wkt
ST_AsText
--  转换为geojson
ST_AsGeoJSON

转换函数

  • 运行这个sql https://gitcode.net/mirrors/geocompass/pg-coordtransform/-/blob/master/geoc-pg-coordtransform.sql
-- 坐标系转换
-- WGS84坐标系:地球坐标系,国际通用坐标系
-- GCJ02坐标系:火星坐标系,WGS84坐标系加密后的坐标系;Google国内地图、高德、QQ地图 使用
-- BD09坐标系:    百度坐标系,GCJ02坐标系加密后的坐标系
-- CGCS坐标系:国家2000大地坐标系

-- WGS84转GCJ02
select ST_AsText(geoc_wgs84togcj02(geom)) from md_geom_space

-- GCJ02转WGS84
select geoc_gcj02towgs84(geom) from md_geom_space

-- WGS84转BD09
select geoc_wgs84tobd09(geom) from md_geom_space

-- BD09转WGS84
select geoc_bd09towgs84(geom) from md_geom_space

-- CGCS2000转GCJ02
select geoc_cgcs2000togcj02(geom) from md_geom_space

-- GCJ02转CGCS2000
select geoc_gcj02tocgcs2000(geom) from md_geom_space

-- CGCS2000转BD09
select geoc_cgcs2000tobd09(geom) from md_geom_space

-- BD09转CGCS2000
select geoc_bd09tocgcs2000(geom) from md_geom_space

-- GCJ02转BD09
select geoc_gcj02tobd09(geom) from md_geom_space

-- BD09转GCJ02
select geoc_bd09togcj02(geom) from md_geom_space

代码整合

pom

		<dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.3.8</version>
        </dependency>

        <!-- GeoTools -->
        <dependency>
            <groupId>org.geolatte</groupId>
            <artifactId>geolatte-geom</artifactId>
            <version>1.6.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.geolatte/geolatte-geojson -->
        <dependency>
            <groupId>org.geolatte</groupId>
            <artifactId>geolatte-geojson</artifactId>
            <version>1.6.0</version>
        </dependency>

        <dependency>
            <groupId>net.postgis</groupId>
            <artifactId>postgis-jdbc</artifactId>
            <version>2.5.0</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-main</artifactId>
            <version>28-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>28-SNAPSHOT</version>
        </dependency>

<!-- geotools的远程库 -->
    <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>

mybatisplus 自定义类型处理

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.postgis.Geometry;
import org.postgis.PGgeometry;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@MappedTypes({String.class})
public class MyGeometryTypeHandler extends BaseTypeHandler<String> {
	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
		PGgeometry pGgeometry = new PGgeometry(parameter);
		Geometry geometry = pGgeometry.getGeometry();
		//坐标系
		geometry.setSrid(4326);
		ps.setObject(i, pGgeometry);
	}

	@Override
	public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
		PGgeometry pGgeometry = new PGgeometry(rs.getString(columnName));
		return pGgeometry.getValue().replace("SRID=4326;","");
	}

	@Override
	public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		PGgeometry pGgeometry = new PGgeometry(rs.getString(columnIndex));
		return pGgeometry.toString();
	}

	@Override
	public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		PGgeometry pGgeometry = new PGgeometry(cs.getString(columnIndex));
		return pGgeometry.toString();
	}
}
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.typeHandler.MyGeometryTypeHandler;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;

/**
 * xxx
 *
 * @author heyonghao
 * @date 2023/7/17
 */
@TableName(autoResultMap = true)
@ApiModel(value = "电子围栏")
@Accessors(chain = true)
@Data
public class GeomSpace implements Serializable {

    @ApiModelProperty(value = "主键")
    private Long id;
	//对应数据库 geometry 类型
    @ApiModelProperty(value = "围栏geo参数- 返回wkt")
    @TableField(typeHandler = MyGeometryTypeHandler.class)
    private String geom;

    @ApiModelProperty(value = "电子围栏名称")
    private String title;

    @ApiModelProperty(value = "其它组成参数 eg: 圆 半径 {\\\"radius\\\":0.00030345730927194836,\\\"radiusTrue\\\":29.068128024579657}")
    private String other;

}

新增空间类型数据

@ApiModel(value = "围栏点位参数")
@Accessors(chain = true)
@Data
public class GeoJsonVo implements Serializable {

    @ApiModelProperty(value = "类型: POINT、MULTIPOINT、LINESTRING、MULTILINESTRING、POLYGON、MULTIPOLYGON")
    private String type;

    @ApiModelProperty(value = "点位 eg: [ [\"106.29384466232433\",\"31.2648657606391\"] ]")
    private List<List<String>> coordinates;

    public String getGeomStr(){
        String coordinate="SRID=4326;%s(%s)";
        String collect = this.coordinates.stream().map(s -> s.stream().map(String::valueOf).collect(Collectors.joining(" ")))
                .collect(Collectors.joining(","));
        coordinate=String.format(coordinate,this.getType(),collect);
        return coordinate;
    }

}
@ApiModel(value = "围栏新增VO")
@Data
public class MdGeomSpaceSaveVo implements Serializable {

    @ApiModelProperty(value = "围栏信息")
    private GeomSpace mdGeomSpace;

    @ApiModelProperty(value = "围栏点位信息")
    private GeoJsonVo geoJsonVo;

}
@ApiOperation(value = "添加围栏")
@PostMapping("/save")
public R<Boolean> save(@RequestBody MdGeomSpaceSaveVo geomSpaceSaveVo){
    GeoJsonVo geoJsonVo = geomSpaceSaveVo.getGeoJsonVo();
    String geomStr = geoJsonVo.getGeomStr();
    GeomSpace mdGeomSpace = geomSpaceSaveVo.getMdGeomSpace();
    mdGeomSpace.setGeom(geomStr);
    mdGeomSpace.setId(IdUtil.getSnowflakeNextId());
    boolean save = mdGeomSpaceService.save(mdGeomSpace);
    return R.ok(save);
}

电子围栏:

  • 用一个虚拟的栅栏围出一个虚拟地理边界;
  • 在地图上 圈出一个圆形范围、或多边形范围;绑定特点规则,如 超速滞留偏离聚集等,做出相应告警
  • 传入空间数据,存入PG库

表:

-- ----------------------------
DROP TABLE IF EXISTS "public"."geom_space";
CREATE TABLE "public"."geom_space" (
  "id" int8 NOT NULL DEFAULT nextval('testgeomobj_id_seq'::regclass),
  "geom" geometry(GEOMETRY) NOT NULL,
  "title" varchar(255) COLLATE "pg_catalog"."default",
  "other" varchar(255) COLLATE "pg_catalog"."default"
)
;
COMMENT ON COLUMN "public"."geom_space"."id" IS '主键';
COMMENT ON COLUMN "public"."geom_space"."geom" IS '围栏geo参数';
COMMENT ON COLUMN "public"."geom_space"."title" IS '电子围栏名称';
COMMENT ON COLUMN "public"."geom_space"."other" IS '其它组成参数 eg: 圆 半径';

-- ----------------------------
-- Primary Key structure for table geom_space
-- ----------------------------
ALTER TABLE "public"."geom_space" ADD CONSTRAINT "md_geom_space_pkey" PRIMARY KEY ("id");

-- ----------------------------
DROP TABLE IF EXISTS "public"."geom_space_rule";
CREATE TABLE "public"."geom_space_rule" (
  "id" int8 NOT NULL,
  "name" varchar(255) COLLATE "pg_catalog"."default",
  "type" int2,
  "rule" varchar(255) COLLATE "pg_catalog"."default"
)
;
COMMENT ON COLUMN "public"."geom_space_rule"."id" IS '主键';
COMMENT ON COLUMN "public"."geom_space_rule"."name" IS '规则名称';
COMMENT ON COLUMN "public"."geom_space_rule"."type" IS '规则类型 1-超速 2-聚焦 3-规矩偏离 4-滞留';
COMMENT ON COLUMN "public"."geom_space_rule"."rule" IS '规则JSON';

-- ----------------------------
-- Records of geom_space_rule
-- ----------------------------
INSERT INTO "public"."geom_space_rule" VALUES (1685206843057606656, '超速', 1, '{"speed":60,"duration":10}');

-- ----------------------------
-- Primary Key structure for table geom_space_rule
-- ----------------------------
ALTER TABLE "public"."geom_space_rule" ADD CONSTRAINT "geom_space_rule_pkey" PRIMARY KEY ("id");

-- ----------------------------
DROP TABLE IF EXISTS "public"."geom_space_bind";
CREATE TABLE "public"."geom_space_bind" (
  "id" int8 NOT NULL,
  "space_id" int8,
  "rule_id" int8
)
;
COMMENT ON COLUMN "public"."geom_space_bind"."id" IS '主键';
COMMENT ON COLUMN "public"."geom_space_bind"."space_id" IS '围栏id';
COMMENT ON COLUMN "public"."geom_space_bind"."rule_id" IS '规则id';

-- ----------------------------
-- Records of geom_space_bind
-- ----------------------------
INSERT INTO "public"."geom_space_bind" VALUES (1685206981247340544, 1685205995128717312, 1685206843057606656);

-- ----------------------------
-- Primary Key structure for table geom_space_bind
-- ----------------------------
ALTER TABLE "public"."geom_space_bind" ADD CONSTRAINT "geom_space_bind_pkey" PRIMARY KEY ("id");

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

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

相关文章

Java类的加载过程是什么?

本文重点 本文将学习类的加载过程,java命令将class文件放到类加载器中,那么之后经历了什么?本文将对其进行学习。 类加载方式? 两种加载方式:隐式加载(静态加载)和显式加载(动态加载) 隐式加载指的是在程序使用new等方式创建对象的时候,会隐式地调用类的加载器把…

人工智能轨道交通行业周刊-第53期(2023.7.24-7.30)

本期关键词&#xff1a;交通大模型、铁路十大创新、隧道病害检测、信号专业标准、Llama-2测评 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通RailMetr…

golang中降本增效的常规实践

最近一年各大中小厂都在搞"优化"&#xff0c;说到优化&#xff0c;目的还是"降本增效"&#xff0c;降低成本&#xff0c;增加效益&#xff08;效率&#xff09;。 技术层面&#xff0c;也有一些降本增效的常规操作。 比如池化、io缓冲区技术 golangC#eg.池…

stable diffusion打造自己专属的LORA模型

通过Lora小模型可以控制很多特定场景的内容生成。 但是那些模型是别人训练好的&#xff0c;你肯定很好奇&#xff0c;我也想训练一个自己的专属模型&#xff08;也叫炼丹&#xff5e;_&#xff5e;&#xff09;。 甚至可以训练一个专属家庭版的模型&#xff08;family model&…

【每天40分钟,我们一起用50天刷完 (剑指Offer)】第四十一天 41/50【异或】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

自定义类型知识详解(结构体,位段,枚举,联合体)

目录 结构体 定义&#xff0c;初始化&#xff0c;自引用 内存对齐&#xff0c;修改默认对齐数 传参 位段 位段内存问题 跨平台及其应用问题 枚举 定义&#xff0c;初始化 实战举例使用及其优点 联合体 联合体定义 特点 大小计算问题 结构体 定义&#xff0c;初始化&#xff…

揭秘 ChatGPT:构建 AI 搜索的不同方法

作者&#xff1a;Sherry Ger 什么是 ChatGPT&#xff1f; 首先&#xff0c;ChatGPT 太棒了&#xff01; 它可以帮助你更高效地工作 —— 从总结 10,000 字的文档到提供竞争产品之间的差异列表&#xff0c;以及许多其他任务。 ChatGPT 是最著名的基于 Transformer 架构的大型语…

SpringBoot读取配置文件顺序

文章目录 一、前言二、SpringBoot配置文件目录读取顺序源码解析 三、SpringBoot配置文件类型读取顺序源码解析 一、前言 本文通过源码分析 SpringBoot 加载配置文件目录的顺序&#xff0c;以及 properties、xml、yml、yaml文件的读取顺序 二、SpringBoot配置文件目录读取顺序…

前端学习——Vue (Day7)

vuex 构建 vuex [多组件数据共享] 环境 state状态 mutations状态 mapMutations actions mapActions getters 模块 module (进阶语法) 综合案例 - 购物车 axios报错解决方案 import axios from axiosexport default {namespaced: true,state () {return {list: []}},mutations…

用户体系之账户设计

文章目录 前言一、需求分析1、登录功能2、退出功能3、账号绑定功能3、其他注意事项 二、账户设计1、表设计2、QA 三、实践1、账户密码登录2、手机号登录3、第三方授权登录4、账户统一 前言 随着互联网的发展&#xff0c;越来越多的应用、网站需要用户进行登录才能使用。为了方…

LeetCode 刷题 数据结构 数组 283题 移动零

难度&#xff1a;简单 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0]示例 2: 输入:…

QGraphicsView实现简易地图2『瓦片经纬度』

前文链接&#xff1a;QGraphicsView实现简易地图1『加载离线瓦片地图』 地图采用GCJ02 Web 墨卡托投影&#xff0c;最小坐标&#xff1a;(-180.00000000000000,-85.05112877980655)&#xff0c;最大坐标&#xff1a;(180.00000000000000,85.05112877980655)。瓦片地图单张图片像…

如何通俗理解扩散模型?

扩散模型(Diffusion Model)是一类十分先进的基于扩散思想的深度学习生 成模型。生成模型除了扩散模型之外&#xff0c;还有出现较早的 VAE ( Variational Auto- Encoder&#xff0c;变分自编码器) 和 GAN ( Generative Adversarial Net &#xff0c;生成对抗网络) 等。 虽然它们…

Cpp学习——类与对象(2)

思维导图&#xff1a; 一&#xff0c;构造函数 1.定义 对于构造函数首先就要知道构造函数怎么写&#xff0c;构造函数怎么写呢&#xff1f;你要知道如下两点&#xff1a; 1.构造函数的函数名要与类名相同 2.构造函数是没有返回值的&#xff0c;但可以有参数。 因为这第二点&am…

ubuntu目录分析

在Ubuntu根目录下&#xff0c;以下是一些常见文件夹的含义&#xff1a; /bin&#xff1a;存放可执行文件&#xff0c;包含一些基本的命令和工具。 /boot&#xff1a;存放启动时所需的文件&#xff0c;如内核和引导加载程序。 /dev&#xff1a;包含设备文件&#xff0c;用于与硬…

关于计算机视觉的Open3D简介

一、说明 Open3D 是一个开源库&#xff0c;使开发人员能够处理 3D 数据。它提供了一组用于 3D 数据处理、可视化和机器学习任务的工具。该库支持各种数据格式&#xff0c;例如 .ply、.obj、.stl 和 .xyz&#xff0c;并允许用户创建自定义数据结构并在程序中访问它们。 Open3D 广…

【雕爷学编程】MicroPython动手做(16)——掌控板之图片图像显示

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

进程_PCB 的理解

目录 一. PCB 的概念 1. 为什么需要PCB 2. PCB的属性 二. task struct 1. task struct 介绍 2. 查看进程指令 3. PID 4. PPID 父进程是什么&#xff1f; 为什么要有父进程&#xff1f; 5. fork 创建子进程 1) fork 后的现象 为什么会打印两次&#xff1f; 2) 的返…

用C语言实现插入排序算法

1.设计思路 用插入排序对长度为n的待排序数组A进行排序的伪代码&#xff08;在代码中&#xff0c;A中元素的数目n用A.length来表示&#xff09;。 伪代码如下&#xff1a; INSERTION-SORT(A) for j2 to A.length:keyA[j] //将A[j]插入已排序序列A[1..j-1]ij-1while i>0…

【MTI 6.S081 Lab】Copy-on-write

【MTI 6.S081 Lab】Copy-on-write The problemThe solutionImplement copy-on-write fork (hard)实验任务Hints解决方案问题解决思考uvmcopykfreekallockpagerefcow_handlertrap 虚拟内存提供了一定程度的间接性&#xff1a;内核可以通过将PTE标记为无效或只读来拦截内存引用&a…