SpringBoot与PostGIS整合,实现智能交通GIS系统

PostGIS是一个开源的空间数据库扩展,专门用于增强PostgreSQL数据库以支持地理空间对象。智能交通GIS系统就是利用地理信息系统(GIS)技术来管理和分析交通数据,帮助城市管理者优化交通规划、提高交通效率并减少拥堵。

我们为什么选择PostGIS?

  • 存储空间数据:PostGIS 允许你直接在关系型数据库中存储和管理空间数据,而不需要额外的文件或外部系统。

  • 空间索引:通过 GIST(Generalized Search Tree)索引加速空间查询,提高性能。

  • PostGIS 提供了一系列内置函数和操作符,可以高效地处理空间数据,包括距离计算、面积测量、交集检测等。

  • PostGIS 支持多种行业标准和开放协议,确保数据的互操作性和可移植性。

  • 免费使用:完全开源,遵循 GNU General Public License (GPL)。

  • 节省预算:减少对专有 GIS 软件的依赖,降低运营成本。

哪些机构使用了PostGIS?

  • 美国环境保护局:使用 PostGIS 来存储和分析环境数据,包括空气质量、水质等,以支持政策制定和公众健康保护。

  • 加拿大自然资源部: 利用 PostGIS 进行土地覆盖分类、地形分析等,支持国家的自然资源管理和环境保护工作。

  • 英国政府:多个部门使用 PostGIS 来管理公共服务设施的位置数据,如医院、学校、公共交通站点等。

  • Uber: 使用 PostGIS 来优化司机的路线规划,提高出行效率,并进行实时交通数据分析。

  • Airbnb: 使用 PostGIS 存储和查询房源的位置数据,帮助用户找到附近的住宿,并提供个性化的推荐服务。

  • Mapbox : 提供的地图服务和 SDKs 基于 PostGIS,用于存储和处理大规模的地理空间数据,支持全球范围内的地图渲染和分析。

  • TomTom:  使用 PostGIS 进行交通数据的存储和分析,提供实时交通更新和导航建议。

  • QGIS : 一个流行的开源 GIS 软件,支持与 PostGIS 数据库的集成,允许用户在桌面环境中进行空间数据编辑和分析。

  • 悉尼大学: 研究团队使用 PostGIS 分析城市扩张、土地使用变化等环境科学问题。

代码实操

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>smart-traffic-gis-system</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>SmartTrafficGisSystem</name>
    <description>Demo project for Spring Boot with PostgreSQL and PostGIS</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath/><!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- 引入PostgreSQL JDBC驱动 -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- 引入PostGIS JDBC驱动 -->
        <dependency>
            <groupId>net.postgis</groupId>
            <artifactId>postgis-jdbc</artifactId>
            <version>2.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

application.properties

spring.datasource.url=jdbc:postgresql://localhost:5432/trafficdb?currentSchema=public&createDatabaseIfNotExist=true
spring.datasource.username=postgres
spring.datasource.password=123456

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.spatial.dialect.postgis.PostgisDialect

初始化脚本

-- 启用PostGIS扩展
CREATE EXTENSION IF NOT EXISTS postgis;

-- 创建traffic_data表,包含id、name和location字段
CREATE TABLE traffic_data (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255),
    location GEOMETRY(Point, 4326)
);

交通数据实体类

package com.example.smarttrafficsystem.model;

import org.locationtech.jts.geom.Point;
import javax.persistence.*;

/**
 * 交通数据实体类,对应数据库中的traffic_data表
 */
@Entity
@Table(name = "traffic_data")
publicclass TrafficData {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id; // 主键ID,自增

    private String name; // 交通点名称

    /**
     * 地理位置字段,类型为Point,坐标系为WGS84 (EPSG:4326)
     */
    @Column(columnDefinition = "geometry(Point,4326)")
    private Point location;

    // Getters and Setters

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Point getLocation() {
        return location;
    }

    public void setLocation(Point location) {
        this.location = location;
    }
}

Repository接口

package com.example.smarttrafficsystem.repository;

import com.example.smarttrafficsystem.model.TrafficData;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface TrafficDataRepository extends JpaRepository<TrafficData, Long> {
}

Service层

package com.example.smarttrafficsystem.service;

import com.example.smarttrafficsystem.model.TrafficData;
import com.example.smarttrafficsystem.repository.TrafficDataRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 业务逻辑层服务类,处理与交通数据相关的业务逻辑
 */
@Service
publicclass TrafficDataService {

    @Autowired
    private TrafficDataRepository trafficDataRepository;

    /**
     * 获取所有交通数据
     * @return 所有交通数据列表
     */
    public List<TrafficData> getAllTrafficData() {
        return trafficDataRepository.findAll();
    }

    /**
     * 保存新的交通数据
     * @param trafficData 要保存的交通数据对象
     * @return 保存后的交通数据对象
     */
    public TrafficData saveTrafficData(TrafficData trafficData) {
        return trafficDataRepository.save(trafficData);
    }
}

Controller层

package com.example.smarttrafficsystem.controller;

import com.example.smarttrafficsystem.model.TrafficData;
import com.example.smarttrafficsystem.service.TrafficDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/v1/traffic")
publicclass TrafficController {

    @Autowired
    private TrafficDataService trafficDataService;

    /**
     * 获取所有交通数据
     * @return 所有交通数据列表
     */
    @GetMapping("/")
    public List<TrafficData> getAllTrafficData() {
        return trafficDataService.getAllTrafficData();
    }

    /**
     * 创建新的交通数据
     * @param trafficData 要创建的交通数据对象
     * @return 创建后的交通数据对象
     */
    @PostMapping("/")
    public TrafficData createTrafficData(@RequestBody TrafficData trafficData) {
        return trafficDataService.saveTrafficData(trafficData);
    }
}

Application

package com.example.smarttrafficsystem;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SmartTrafficSystemApplication {

    public static void main(String[] args) {
        SpringApplication.run(SmartTrafficSystemApplication.class, args);
    }
}

测试

插入新的交通数据

$ curl -X POST http://localhost:8080/api/v1/traffic/ \
-H "Content-Type: application/json" \
-d '{"name": "New Traffic Point", "location": {"type": "Point", "coordinates": [125.678, 80.123]}}'

Respons:

{
    "id": 1,
    "name": "New Traffic Point",
    "location": {
        "type": "Point",
        "coordinates": [125.678, 80.123]
    }
}

获取所有交通数据以验证插入结果

$ curl -X GET http://localhost:8080/api/v1/traffic/

Respons:

[
    {
        "id": 1,
        "name": "New Traffic Point",
        "location": {
            "type": "Point",
            "coordinates": [125.678, 80.123]
        }
    }
]

关注我,送Java福利

/**
 * 这段代码只有Java开发者才能看得懂!
 * 关注我微信公众号之后,
 * 发送:"666",
 * 即可获得一本由Java大神一手面试经验诚意出品
 * 《Java开发者面试百宝书》Pdf电子书
 * 福利截止日期为2025年02月28日止
 * 手快有手慢没!!!
*/
System.out.println("请关注我的微信公众号:");
System.out.println("Java知识日历");
### 实现地图定位功能 在 Spring Boot 项目中实现地图定位功能可以通过多种方式完成,具体取决于所选的地图服务提供商和技术栈。以下是几种常见的方式: #### 使用 Redis GEO 进行地理位置管理 通过整合 Redis 的 GEO 功能可以方便地管理和操作地理数据。这允许应用程序执行诸如插入地点、查询附近的地方或计算两点间距离的操作。 ```java @Autowired private StringRedisTemplate redisTemplate; public void addLocation(String key, double longitude, double latitude, String member){ redisTemplate.opsForGeo().add(key, new Point(longitude,latitude),member); } public List<String> findNearbyLocations(String key,double longitude,double latitude,int distanceInMeters){ GeoResults<GeoLocation<String>> results = redisTemplate.opsForGeo() .radius(key,new Circle(new Point(longitude,latitude),new Distance(distanceInMeters,Metrics.METERS))); return results.getContent().stream().map(content -> content.getContent()).collect(Collectors.toList()); } ``` 此方法适用于需要高效处理大量地理空间数据的应用场景[^1]。 #### 结合 PostgreSQL 和 MyBatis Plus 计算距离 对于基于 SQL 数据库存储位置信息的情况,则可利用 PostGIS 扩展来增强 PostgreSQL 对 GIS 支持的能力,并借助 MyBatis Plus 来简化 ORM 映射过程。这样不仅能够保存坐标点还可以轻松求解两处之间的实际直线距离。 ```sql SELECT ST_Distance_Sphere( point(longitude_a, latitude_a), point(longitude_b, latitude_b)) AS distance; ``` 这种方式适合那些已经采用关系型数据库作为主要持久化层的现有系统[^2]。 #### 调用第三方 API 如百度地图 Web Service API 如果希望获得更精确的位置信息服务或是想要访问更多高级特性(比如路线规划),那么调用专业的在线地图服务商所提供的 RESTful 接口会是一个不错的选择。以百度为例,在获取到合法密钥之后便可通过 HTTP 请求发送指令并解析返回的结果集来进行进一步业务逻辑编写。 ```java // 构造请求URL String url = "http://api.map.baidu.com/route/v2/transit?" + "origin=" + originLatitude + "," + originLongitude + "&destination=" + destLatitude + "," + destLongitude + "&ak=YOUR_API_KEY"; RestTemplate restTemplate = new RestTemplate(); ResponseEntity<String> response = restTemplate.getForEntity(url,String.class); // 解析JSON响应... ``` 这种方法特别适合于对外卖配送这类依赖精准导航指引的服务类型[^3]。 #### UWB 室内精确定位方案 当涉及到室内环境下的高精度定位需求时,超宽带 (Ultra-Wideband,UWB) 技术因其出色的测距性能而备受青睐。结合前端 Vue.js 开发界面展示当前位置及其他关联对象的状态变化情况;而后端则负责接收来自标签设备上报的数据包进而更新服务器上的最新记录。 ```javascript // 前端部分:实时刷新页面上显示的目标物体所在区域 setInterval(() => { axios.get('/api/locations') .then(response => { this.locations = response.data; // 更新视图中的位置列表 }); }, 5000); // 每隔五秒拉取一次新消息 ``` 这种组合非常适合构建企业级资产追踪解决方案或其他任何要求亚米级别分辨率的任务场合[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值