| | |
| | | import org.springframework.boot.builder.SpringApplicationBuilder; |
| | | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; |
| | | |
| | | /** |
| | | * 启动程序类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-07-16 |
| | | * |
| | | * exclude = {DataSourceAutoConfiguration.class}, |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | // exclude = {DataSourceAutoConfiguration.class}, |
| | | @SpringBootApplication(scanBasePackages = {"com.se.simu"}) |
| | | public class SimuApplication extends SpringBootServletInitializer { |
| | | public static void main(String[] args) { |
| | |
| | | import org.springframework.web.server.WebFilterChain; |
| | | import reactor.core.publisher.Mono; |
| | | |
| | | /** |
| | | * 跨域配置 |
| | | * |
| | | * @author se |
| | | * @date 2024-08-28 |
| | | */ |
| | | //@Configuration |
| | | @SuppressWarnings("ALL") |
| | | public class CorsConfig |
| | | { |
| | | /** |
| | | * 这里为支持的请求头,如果有自定义的header字段请自己添加 |
| | | */ |
| | | // private static final String ALLOWED_HEADERS = "X-Requested-With, Content-Type, Authorization, credential, X-XSRF-TOKEN, token, Admin-Token, App-Token" |
| | | private static final String ALLOWED_HEADERS = "*"; |
| | | private static final String ALLOWED_METHODS = "GET,POST,PUT,DELETE,OPTIONS,HEAD"; |
| | |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | /** |
| | | * 初始化配置类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-12 |
| | | */ |
| | | @Slf4j |
| | | @Component |
| | | @SuppressWarnings("ALL") |
| | | public class InitConfig implements ApplicationRunner { |
| | | @Resource |
| | | Environment env; |
| | |
| | | import springfox.documentation.spi.DocumentationType; |
| | | import springfox.documentation.spring.web.plugins.Docket; |
| | | |
| | | /** |
| | | * Knife4j配置类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-12 |
| | | */ |
| | | @Configuration |
| | | @EnableKnife4j |
| | | @SuppressWarnings("ALL") |
| | | public class Knife4jConfig extends WebMvcConfigurationSupport { |
| | | @Value("${server.port}") |
| | | String serverPort; |
| | |
| | | @Bean |
| | | public Docket createRestApi() { |
| | | return new Docket(new DocumentationType("openApi", "3.0")) |
| | | // 是否启用Swagger |
| | | .enable(enabled) |
| | | // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) |
| | | .apiInfo(apiInfo()) |
| | | // 分组名称 |
| | | .groupName("服务") |
| | | // 设置哪些接口暴露给Swagger展示 |
| | | .select() |
| | | // 扫描所有有注解的api,用这种方式更灵活 |
| | | .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) |
| | | // 扫描指定包中的swagger注解 |
| | | // .apis(RequestHandlerSelectors.basePackage("com.cn.project.tool.swagger")) |
| | | // 扫描所有 .apis(RequestHandlerSelectors.any()) |
| | | .paths(PathSelectors.any()) |
| | | .build() |
| | | /* 设置安全模式,swagger可以设置访问token */ |
| | | // .securitySchemes(securitySchemes()) |
| | | .pathMapping(pathMapping); |
| | | } |
| | | |
| | | private ApiInfo apiInfo() { |
| | | return new ApiInfoBuilder() |
| | | //描述字段支持Markdown语法 |
| | | .description("接口文档") |
| | | .contact(new Contact("WuWeiwei", "http://127.0.0.1:" + serverPort + contextPath + "/doc.html", "252740454@qq.com")) |
| | | .version("0.2") |
| | |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.transaction.annotation.EnableTransactionManagement; |
| | | |
| | | /** |
| | | * Mybatis-Plus分页配置 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-12 |
| | | */ |
| | | @EnableTransactionManagement |
| | | @Configuration |
| | | @MapperScan("com.se.simu.mapper") |
| | | @SuppressWarnings("ALL") |
| | | public class MybatisPlusConfig { |
| | | /** |
| | | * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 |
| | | * MybatisConfiguration#useDeprecatedExecutor = false |
| | | * 避免缓存出现问题(该属性会在旧插件移除后一同移除) |
| | | */ |
| | | @Bean |
| | | public MybatisPlusInterceptor mybatisPlusInterceptor() { |
| | | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); |
| | |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 属性配置类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-26 |
| | | */ |
| | | @Configuration |
| | | @SuppressWarnings("ALL") |
| | | @ConfigurationProperties(prefix = "config") |
| | |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * RestTemplate配置类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-12 |
| | | */ |
| | | @Configuration |
| | | @SuppressWarnings("ALL") |
| | | public class RestTemplateConfig { |
| | | /** |
| | | * 连接池的最大连接数默认为0,不限制 |
| | | */ |
| | | @Value("${remote.maxTotalConnect:0}") |
| | | private int maxTotalConnect; |
| | | |
| | | /** |
| | | * 单个主机的最大连接数 |
| | | */ |
| | | @Value("${remote.maxConnectPerRoute:1000}") |
| | | private int maxConnectPerRoute; |
| | | |
| | | /** |
| | | * 连接超时默认5s,-1为不限制 |
| | | */ |
| | | @Value("${remote.connectTimeout:5000}") |
| | | private int connectTimeout; |
| | | |
| | | /** |
| | | * 读取超时默认30s,-1为不限制 |
| | | */ |
| | | @Value("${remote.readTimeout:30000}") |
| | | private int readTimeout; |
| | | |
| | | /** |
| | | * 创建HTTP客户端工厂 |
| | | * |
| | | * @return 客户端工厂 |
| | | */ |
| | | private ClientHttpRequestFactory createFactory() { |
| | | if (this.maxTotalConnect <= 0) { |
| | | SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); |
| | |
| | | return factory; |
| | | } |
| | | |
| | | /** |
| | | * 初始化RestTemplate,并加入spring的Bean工厂,由spring统一管理 |
| | | * 必须加注解@LoadBalanced |
| | | * |
| | | * @return |
| | | */ |
| | | @Bean |
| | | @ConditionalOnMissingBean(RestTemplate.class) |
| | | public RestTemplate getRestTemplate() { |
| | | RestTemplate restTemplate = new RestTemplate(this.createFactory()); |
| | | List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters(); |
| | | |
| | | // 重新设置StringHttpMessageConverter字符集为UTF-8,解决中文乱码问题 |
| | | HttpMessageConverter<?> converterTarget = null; |
| | | for (HttpMessageConverter<?> item : converterList) { |
| | | if (StringHttpMessageConverter.class == item.getClass()) { |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Web配置类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-07-17 |
| | | */ |
| | | @Configuration |
| | | @SuppressWarnings("ALL") |
| | | public class WebConfig extends WebMvcConfigurationSupport { |
| | | /** |
| | | * 跨域请求 |
| | | */ |
| | | @Override |
| | | protected void addCorsMappings(CorsRegistry registry) { |
| | | registry.addMapping("/**") |
| | |
| | | .maxAge(3600); |
| | | } |
| | | |
| | | /** |
| | | * 处理json格式,值null的转换为"" |
| | | */ |
| | | @Override |
| | | public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { |
| | | FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); |
| | |
| | | SerializerFeature.WriteNullStringAsEmpty, |
| | | SerializerFeature.WriteNullNumberAsZero, |
| | | SerializerFeature.WriteNullBooleanAsFalse); |
| | | // 结果是否格式化,默认为false |
| | | //SerializerFeature.PrettyFormat); |
| | | |
| | | List<MediaType> supportedMediaTypes = new ArrayList<>(); |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.http.HttpStatus; |
| | | |
| | | /** |
| | | * 基础控制器 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-07-30 |
| | | */ |
| | | @Slf4j |
| | | @SuppressWarnings("ALL") |
| | | public class BaseController { |
| | | public <T> R<T> success(T data) { |
| | | return new R<T>(HttpStatus.OK, data); |
| | |
| | | package com.se.simu.controller; |
| | | |
| | | import cn.hutool.json.JSONArray; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.se.simu.domain.dto.GeDb; |
| | | import com.se.simu.domain.dto.GeLayer; |
| | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 仿真管理 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-18 |
| | | */ |
| | | @Api(tags = "仿真管理") |
| | | @Slf4j |
| | | @RestController |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 使用空间范围查询 管点,管线,建筑物 3个图层,且每个图层的数量大于0,返回 true。 |
| | | */ |
| | | @ApiOperation(value = "降水范围校验") |
| | | @GetMapping("/rangeVerify") |
| | | public R<Object> rangeVerify(@RequestParam @ApiParam("最小X") double minx, |
| | |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | /** |
| | | * Test控制器 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-10-30 |
| | | */ |
| | | @Api(tags = "Test") |
| | | @Slf4j |
| | | @RestController |
| | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | /** |
| | | * 内涝管理 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-07-16 |
| | | */ |
| | | @Api(tags = "内涝管理") |
| | | @Slf4j |
| | | @RestController |
| | | @SuppressWarnings("ALL") |
| | | @RequestMapping("/waterlogging") |
| | | public class WaterController extends BaseController { |
| | | @Resource |
| | |
| | | |
| | | import org.gdal.ogr.Geometry; |
| | | |
| | | /** |
| | | * 建筑物数据实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-10-17 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class BuildingDto { |
| | | private String id; |
| | | |
| | |
| | | import java.util.Calendar; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * uwsolver配置类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-26 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class ConfigDto { |
| | | public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); |
| | | |
| | | // 案例文件夹,必须指定,可以是相对路径,默认在求解器当前目录下 |
| | | private String casedir = "case"; |
| | | // 地形文件,仅需指定文件名(同下),无需指定路径,默认路径在案例文件夹下 |
| | | private String terrain_file = "DEM4548.tif"; |
| | | // 网格文件,在不提供的情况下默认通过studyzone_file进行生成 |
| | | private String mesh_file = "tongzhou-mini.msh"; |
| | | // 演算区域文件,在不提供网格文件的前提下必须指定 |
| | | private String studyzone_file = "studyzone_difference.shp"; |
| | | // 细化区域文件,通过studyzone_file生成网格文件时使用,可不提供,则默认均匀网格尺寸 |
| | | private String refinezones_file = "refinezones.shp"; |
| | | // 建筑区域文件,通过studyzone_file生成网格文件时使用,可不提供 |
| | | private String buildings_file = "buildings_inside.shp"; |
| | | // 管网节点文件,必须指定,用于生成求解文件 |
| | | private String nodes_file = "pipeline-demo-point.shp"; |
| | | // 管网管段文件,必须指定,用于生成求解文件 |
| | | private String links_file = "pipeline-demo-conduit.shp"; |
| | | // 管网集水点文件,即具有汇集一定范围内降水的雨水箅、雨水井等,必须指定,用于生成求解文件 |
| | | private String junctions_file = "pipeline-demo-point-junctions.shp"; |
| | | // 降雨文件,必须指定,用于生成求解文件 |
| | | private String raingage_file = "RainGage.dat"; |
| | | // 防洪障碍物文件,可不提供 |
| | | private String barrier_file = "barrier.shp"; |
| | | // 排水系统结果文件,用于保存管段/管点的水位、流量等信息 |
| | | private String drainage_outfile = "tongzhou-mini-drainage.h5"; |
| | | // 地面水位结果文件,用于保存地面水位信息 |
| | | private String sww_outfile = "tongzhou-mini.sww"; |
| | | // 流量单位,仅提供LPS(升/秒)、CMS(立方米/秒)、CFS(立方英尺/秒)三种单位 |
| | | private String flow_units = "LPS"; |
| | | private String infiltration = "HORTON"; |
| | | private String link_offsets = "DEPTH"; |
| | |
| | | private String allow_ponding = "NO"; |
| | | private String skip_steady_state = "NO"; |
| | | private String flow_routing = "DYNWAVE"; |
| | | // 演算开始时刻 |
| | | private String start_datetime = "06/12/2024 12:00:00"; |
| | | // 演算结束时刻 |
| | | private String end_datetime = "06/12/2024 13:00:00"; |
| | | // 结果保存的起始时刻 |
| | | private String report_start_datetime = "06/12/2024 00:00:00"; |
| | | // 结果保存时间间隔 |
| | | private String report_step = "00:01:00"; |
| | | // 排水管网演算时间步长,默认单位为s |
| | | private String routing_step = "00:00:10"; |
| | | private String inertial_damping = "PARTIAL"; |
| | | private String normal_flow_limited = "BOTH"; |
| | |
| | | private Double friction = 0.01; |
| | | private Double terrain_smoothing = 0.1; |
| | | private String flow_algorithm = "DE1"; |
| | | // 网格单元最大面积,默认单位为m |
| | | private Integer mesh_size = 5; |
| | | // 结果保存频率,相对report_step来说,比如save_step=3就表示每间隔2个report_step保存一次结果 |
| | | private Integer save_step = 1; |
| | | |
| | | public void setProperties(String dirName, Date startTime, Integer minutes, PropertiesConfig config) { |
| | |
| | | package com.se.simu.domain.dto; |
| | | |
| | | /** |
| | | * 持续时间实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-30 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class DurationDto { |
| | | private long start; |
| | | |
| | |
| | | package com.se.simu.domain.dto; |
| | | |
| | | /** |
| | | * 范围实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-30 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class ExtensionDto { |
| | | private double minx; |
| | | |
| | |
| | | import org.gdal.osr.SpatialReference; |
| | | import org.gdal.osr.osr; |
| | | |
| | | /** |
| | | * GEDB数据库实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-13 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class GeDb { |
| | | private String dbid; |
| | |
| | | package com.se.simu.domain.dto; |
| | | |
| | | /** |
| | | * GEDB字段实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-13 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class GeField { |
| | | String name; |
| | | |
| | |
| | | package com.se.simu.domain.dto; |
| | | |
| | | /** |
| | | * GEDB文件实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-14 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class GeFile { |
| | | String name; |
| | | |
| | |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * GEDB图层实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-13 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class GeLayer { |
| | | private String id; |
| | | |
| | |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 图层实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-30 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class LayerDto { |
| | | private String version; |
| | | |
| | |
| | | import java.io.File; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * 结果实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-30 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class ResultDto { |
| | | private String serviceName; |
| | | |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 范围实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-30 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class TerrainDto { |
| | | private List<int[]> size; |
| | | |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 水面实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-30 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class WaterDto { |
| | | @JSONField(serialize = false) |
| | | private List<String> files; |
| | |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 仿真数据实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-18 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class DataPo { |
| | | @ApiModelProperty("父ID") |
| | | private Integer pid; |
| | |
| | | |
| | | import java.sql.Timestamp; |
| | | |
| | | /** |
| | | * 仿真实体类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-18 |
| | | */ |
| | | @TableName("bs.simu") |
| | | @SuppressWarnings("ALL") |
| | | public class SimuPo { |
| | |
| | | import lombok.EqualsAndHashCode; |
| | | import lombok.ToString; |
| | | |
| | | /** |
| | | * 建筑物涉水深度视图类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-11-01 |
| | | */ |
| | | @ToString |
| | | @SuppressWarnings("ALL") |
| | | @ApiModel(value = "建筑物涉水深度视图类") |
| | |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 创建仿真视图类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-18 |
| | | */ |
| | | @ToString |
| | | @SuppressWarnings("ALL") |
| | | @ApiModel(value = "创建仿真视图类") |
| | |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | |
| | | /** |
| | | * 积水视图类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-11-06 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class PondingVo { |
| | | @ApiModelProperty("积水深度") |
| | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import org.springframework.http.HttpStatus; |
| | | |
| | | /** |
| | | * 响应视图类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-07-30 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class R<T> { |
| | | @ApiModelProperty("状态码:200-正常,400-请求错误,500-服务器错误") |
| | |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 仿真视图类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-18 |
| | | */ |
| | | @TableName("bs.simu") |
| | | @SuppressWarnings("ALL") |
| | | public class SimuVo { |
| | |
| | | import java.util.List; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * Caffeine帮助类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-11-05 |
| | | */ |
| | | @Slf4j |
| | | @SuppressWarnings("ALL") |
| | | public class CaffeineHelper { |
| | | private static Cache<String, Object> cache; |
| | | |
| | |
| | | |
| | | BigInteger bigInt = new BigInteger(1, byteArray); |
| | | |
| | | // 参数16表示16进制 |
| | | String result = bigInt.toString(16); |
| | | |
| | | // 不足32位高位补零 |
| | | while (result.length() < 32) { |
| | | result = "0" + result; |
| | | } |
| | |
| | | import java.text.DecimalFormat; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 文件帮助类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-12 |
| | | */ |
| | | @Slf4j |
| | | @SuppressWarnings("ALL") |
| | | public class FileHelper { |
| | | public final static String POINT = "."; |
| | | |
| | |
| | | |
| | | public static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; |
| | | |
| | | /** |
| | | * 获取文件名 |
| | | */ |
| | | public static String getFileName(String file) { |
| | | int idx = file.lastIndexOf(File.separator); |
| | | if (idx > -1) { |
| | |
| | | return ""; |
| | | } |
| | | |
| | | /** |
| | | * 获取文件名称 |
| | | */ |
| | | public static String getName(String file) { |
| | | String fileName = getFileName(file); |
| | | int idx = fileName.lastIndexOf("."); |
| | |
| | | return fileName; |
| | | } |
| | | |
| | | /** |
| | | * 获取文件扩展名 |
| | | */ |
| | | public static String getExtension(File file) { |
| | | if (file == null) { |
| | | return null; |
| | |
| | | return fileName.substring(idx); |
| | | } |
| | | |
| | | /** |
| | | * 获取文件扩展名 |
| | | */ |
| | | public static String getExtension(String fileName) { |
| | | if (StringHelper.isEmpty(fileName)) { |
| | | return ""; |
| | |
| | | return fileName.substring(idx).toLowerCase(); |
| | | } |
| | | |
| | | /** |
| | | * 获取多用途互联网邮件扩展类型 |
| | | */ |
| | | public static String getMime(String ext) { |
| | | switch (ext) { |
| | | // 图片 |
| | | case ".tif": |
| | | case ".tiff": |
| | | return "image/tiff"; |
| | | case ".img": |
| | | return "application/x-img"; |
| | | case ".gif": |
| | | return "image/gif"; |
| | | case ".jpg": |
| | | case ".jpeg": |
| | | return "image/jpeg"; |
| | | case ".png": |
| | | return "image/png"; |
| | | // 音/视频 |
| | | case ".mp3": |
| | | return "audio/mp3"; |
| | | case ".mp4": |
| | | return "video/mpeg4"; |
| | | case ".avi": |
| | | return "video/avi"; |
| | | case ".mpg": |
| | | case ".mpeg": |
| | | return "video/mpg"; |
| | | case ".wav": |
| | | return "audio/wav"; |
| | | case ".wma": |
| | | return "audio/x-ms-wma"; |
| | | case ".swf": |
| | | return "application/x-shockwave-flash"; |
| | | case ".wmv": |
| | | return "video/x-ms-wmv"; |
| | | case ".rm": |
| | | return "application/vnd.rn-realmedia"; |
| | | case ".rmvb": |
| | | return "application/vnd.rn-realmedia-vbr"; |
| | | // 网页 |
| | | case ".js": |
| | | return "application/x-javascript"; |
| | | case ".css": |
| | | return "text/css"; |
| | | case ".asp": |
| | | return "text/asp"; |
| | | case ".mht": |
| | | return "message/rfc822"; |
| | | case ".jsp": |
| | | case ".htm": |
| | | case ".html": |
| | | case ".xhtml": |
| | | return "text/html"; |
| | | case ".xml": |
| | | case ".svg": |
| | | return "text/xml"; |
| | | // 文件 |
| | | case ".txt": |
| | | return "text/plain"; |
| | | case ".dbf": |
| | | return "application/x-dbf"; |
| | | case ".mdb": |
| | | return "application/msaccess"; |
| | | case ".pdf": |
| | | return "application/pdf"; |
| | | case ".ppt": |
| | | case ".pptx": |
| | | return "application/x-ppt"; |
| | | case ".doc": |
| | | case ".docx": |
| | | return "application/msword"; |
| | | case ".xls": |
| | | case ".xlsx": |
| | | return "application/vnd.ms-excel"; |
| | | case ".dgn": |
| | | return "application/x-dgn"; |
| | | case ".dwg": |
| | | return "application/x-dwg"; |
| | | case ".ext": |
| | | return "application/x-msdownload"; |
| | | // 默认 |
| | | default: |
| | | return "application/octet-stream"; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 字节单位换算 |
| | | */ |
| | | public static String formatByte(long byteNumber) { |
| | | double kbNumber = byteNumber / D1024; |
| | | if (kbNumber < D1024) { |
| | |
| | | return new DecimalFormat("#.##TB").format(tbNumber); |
| | | } |
| | | |
| | | /** |
| | | * 获取平方米 |
| | | */ |
| | | public static String getSquareMeter(double num) { |
| | | if (num < I1000000) { |
| | | return new DecimalFormat("#.##平方米").format(num); |
| | |
| | | return new DecimalFormat("#.##平方千米").format(knum); |
| | | } |
| | | |
| | | /** |
| | | * byte转MB |
| | | */ |
| | | public static double sizeToMb(long size) { |
| | | if (size < D1050) { |
| | | return 0.001; |
| | |
| | | return Double.parseDouble(str); |
| | | } |
| | | |
| | | /** |
| | | * 3.获取文件MD5码(JDK) |
| | | */ |
| | | public static String getMd5ByJdk(String filePath) throws IOException { |
| | | FileInputStream fileStream = new FileInputStream(filePath); |
| | | String md5 = DigestUtils.md5Hex(fileStream); |
| | |
| | | return md5; |
| | | } |
| | | |
| | | /** |
| | | * 2.获取快速 MD5 码 |
| | | */ |
| | | public static String getFastMd5(String filePath) throws IOException { |
| | | String hash = MD5.asHex(MD5.getHash(new File(filePath))); |
| | | |
| | |
| | | return md5.asHex(); |
| | | } |
| | | |
| | | /** |
| | | * 删除文件夹 |
| | | * |
| | | * @param dir 文件夹 |
| | | */ |
| | | public static void deleteDir(String dir) { |
| | | File file = new File(dir); |
| | | |
| | | deleteFiles(file); |
| | | } |
| | | |
| | | /** |
| | | * 级联删除文件 |
| | | * |
| | | * @param file 文件 |
| | | */ |
| | | public static void deleteFiles(File file) { |
| | | if (null == file || !file.exists()) { |
| | | return; |
| | |
| | | file.delete(); |
| | | } |
| | | |
| | | /** |
| | | * 获取相对路径 |
| | | * |
| | | * @param file 文件 |
| | | * @return 相对路径 |
| | | */ |
| | | public static String getRelativePath(String file) { |
| | | if (StringHelper.isEmpty(file)) { |
| | | return null; |
| | |
| | | return file.substring(start + 1); |
| | | } |
| | | |
| | | /** |
| | | * 获取路径 |
| | | * |
| | | * @param file 文件 |
| | | * @return 文件路径 |
| | | */ |
| | | public static String getPath(String file) { |
| | | if (StringHelper.isEmpty(file)) { |
| | | return null; |
| | |
| | | return file.substring(0, end); |
| | | } |
| | | |
| | | /** |
| | | * 1.获取文件的MD5 |
| | | */ |
| | | @SuppressWarnings("unused") |
| | | public static String getFileMd5(String filePath) { |
| | | FileInputStream fis = null; |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 字节码转16进制 |
| | | */ |
| | | public static String byteToHexString(byte[] tmp) { |
| | | // 每个字节用 16 进制表示的话,使用两个字符, |
| | | char[] str = new char[16 * 2]; |
| | | |
| | | // 所以表示成 16 进制需要 32 个字符,表示转换结果中对应的字符位置 |
| | | int k = 0; |
| | | // 从第一个字节开始,对 MD5 的每一个字节 |
| | | for (int i = 0; i < I16; i++) { |
| | | // 转换成 16 进制字符的转换 |
| | | byte byte0 = tmp[i]; |
| | | // 取字节中高 4 位的数字转换 |
| | | str[k++] = HEX_DIGITS[byte0 >>> 4 & 0xf]; |
| | | // >>> 为逻辑右移,将符号位一起右移, 取字节中低 4 位的数字转换 |
| | | str[k++] = HEX_DIGITS[byte0 & 0xf]; |
| | | } |
| | | // 换后的结果转换为字符串 |
| | | |
| | | return new String(str); |
| | | } |
| | | |
| | | /** |
| | | * 获取字符串的MD5码 |
| | | */ |
| | | public static String getStringMd5(String text) { |
| | | StringBuilder builder = new StringBuilder(); |
| | | try { |
| | |
| | | return builder.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 根据路径获取文件 |
| | | */ |
| | | public static void getFilesByPath(List<String> list, String path) { |
| | | File file = new File(path); |
| | | if (file.isDirectory()) { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 复制文件 |
| | | * |
| | | * @param src 源文件 |
| | | * @param dest 目录文件 |
| | | */ |
| | | public static void copyFile(File src, File dest) throws IOException { |
| | | InputStream is = null; |
| | | OutputStream os = null; |
| | |
| | | |
| | | import java.io.File; |
| | | |
| | | /** |
| | | * GDAL帮助类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-12 |
| | | */ |
| | | @Slf4j |
| | | @SuppressWarnings("ALL") |
| | | public class GdalHelper { |
| | |
| | | } |
| | | } |
| | | |
| | | // 支持中文路径 |
| | | gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); |
| | | // 属性表支持中文:CP936 |
| | | gdal.SetConfigOption("SHAPE_ENCODING", ""); |
| | | gdal.SetConfigOption("PGEO_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s"); |
| | | gdal.SetConfigOption("MDB_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s"); |
| | | |
| | | // 注册所有的驱动 |
| | | gdal.AllRegister(); |
| | | ogr.RegisterAll(); |
| | | initSr(); |
| | | } |
| | | |
| | | /** |
| | | * 初始化坐标系 |
| | | * <p> |
| | | * https://blog.csdn.net/CallmeAdo/article/details/127558139 |
| | | */ |
| | | public static void initSr() { |
| | | try { |
| | | SR4326 = new SpatialReference(); |
| | | SR4326.ImportFromEPSG(I4326); |
| | | // 对于lat/long顺序的地理CRS,数据仍然是long/lat顺序的 |
| | | SR4326.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER); |
| | | |
| | | SR4490 = new SpatialReference(); |
| | |
| | | return sr; |
| | | } |
| | | |
| | | /** |
| | | * 创建金字塔 |
| | | */ |
| | | public static void createPyramid(String file) { |
| | | Dataset ds = null; |
| | | try { |
| | |
| | | return; |
| | | } |
| | | |
| | | // 创建金字塔 |
| | | Band band = ds.GetRasterBand(1); |
| | | if (0 == band.GetOverviewCount()) { |
| | | ds.BuildOverviews("nearest", new int[]{2, 4, 6, 8, 16}, null); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 销毁资源 |
| | | */ |
| | | public static void delete(Layer layer, DataSource dataSource, Driver driver) { |
| | | try { |
| | | if (null != layer) { |
| | |
| | | |
| | | public static Geometry getMaxPoint(Dataset ds) |
| | | { |
| | | /* |
| | | * transform[0] 左上角x坐标 |
| | | * transform[1] 东西方向分辨率 |
| | | * transform[2] 旋转角度, 0表示图像 "北方朝上" |
| | | * |
| | | * transform[3] 左上角y坐标 |
| | | * transform[4] 旋转角度, 0表示图像 "北方朝上" |
| | | * transform[5] 南北方向分辨率 |
| | | */ |
| | | double[] transform = new double[6]; |
| | | ds.GetGeoTransform(transform); |
| | | |
| | |
| | | return point; |
| | | } |
| | | |
| | | /** |
| | | * 转换为WGS84坐标 |
| | | */ |
| | | public static Geometry toWgs84(SpatialReference sr, double x, double y) { |
| | | Geometry point = new Geometry(ogr.wkbPoint); |
| | | point.AssignSpatialReference(sr); |
| | |
| | | return point; |
| | | } |
| | | |
| | | /** |
| | | * WGS84转换为目标坐标 |
| | | */ |
| | | public static double[] fromWgs84(SpatialReference sr, double x, double y) { |
| | | // https://blog.csdn.net/weixin_34910922/article/details/129208661 |
| | | CoordinateTransformation ct = new CoordinateTransformation(GdalHelper.SR4326, sr); |
| | | if (sr.IsProjected() != 1) { |
| | | sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER); |
| | |
| | | return ct.TransformPoint(x, y); |
| | | } |
| | | |
| | | /** |
| | | * WGS84转换为目标坐标 |
| | | */ |
| | | public static int fromWgs84(SpatialReference sr, Geometry g) { |
| | | // https://blog.csdn.net/weixin_34910922/article/details/129208661 |
| | | CoordinateTransformation ct = new CoordinateTransformation(GdalHelper.SR4326, sr); |
| | | if (sr.IsProjected() != 1) { |
| | | sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER); |
| | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * RSA工具类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-13 |
| | | */ |
| | | @Slf4j |
| | | @SuppressWarnings("ALL") |
| | | public class RsaHelper { |
| | | /** |
| | | * 私钥 |
| | | */ |
| | | private static String privateKey; |
| | | |
| | | /** |
| | | * 公钥 |
| | | */ |
| | | private static String publicKey; |
| | | |
| | | /** |
| | | * 密钥算法 |
| | | */ |
| | | private static final String KEY_ALGORITHM = "RSA"; |
| | | |
| | | /** |
| | | * RSA密钥长度:1024 或 2048 |
| | | */ |
| | | private static final int DEFAULT_RSA_KEY_SIZE = 1024; |
| | | |
| | | /** |
| | | * 生成公私钥 |
| | | */ |
| | | public static void generate() { |
| | | Map<String, String> result = generateRsaKey(DEFAULT_RSA_KEY_SIZE); |
| | | System.out.println("公钥为:" + result.get("publicKey")); |
| | | System.out.println("私钥为:" + result.get("privateKey")); |
| | | } |
| | | |
| | | /** |
| | | * 获取RSA加密私钥 |
| | | * |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | public static String getPrivateKey() throws IOException { |
| | | if (privateKey == null) { |
| | | InputStream inPrivate = new ClassPathResource("config" + File.separator + "rsa_private_key.txt").getInputStream(); |
| | |
| | | publicKey = key; |
| | | } |
| | | |
| | | /** |
| | | * 获取RSA加密公钥 |
| | | * |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | public static String getPublicKey() throws IOException { |
| | | if (publicKey == null) { |
| | | InputStream inPrivate = new ClassPathResource("config" + File.separator + "rsa_public_key.txt").getInputStream(); |
| | |
| | | return publicKey; |
| | | } |
| | | |
| | | /** |
| | | * 读取文本文件 |
| | | * |
| | | * @param fileName 文件路径 |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | public static String readFile(String fileName) throws IOException { |
| | | File file = new File(fileName); |
| | | BufferedReader br = new BufferedReader(new FileReader(file)); |
| | |
| | | return result.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 把inputStream转成String |
| | | * |
| | | * @param is |
| | | * @return |
| | | * @throws IOException |
| | | */ |
| | | private static String inputStream2String(InputStream is) throws IOException { |
| | | ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| | | |
| | |
| | | return str; |
| | | } |
| | | |
| | | /** |
| | | * 生成RSA的公私钥 |
| | | * |
| | | * @param keySize 1025 或 2048 |
| | | * @return |
| | | */ |
| | | public static Map<String, String> generateRsaKey(int keySize) { |
| | | Map<String, String> result = new HashMap<>(2); |
| | | try { |
| | | KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); |
| | | |
| | | // 初始化密钥对生成器,密钥大小为1024 2048位 |
| | | keyPairGen.initialize(keySize, new SecureRandom()); |
| | | |
| | | // 生成一个密钥对,保存在keyPair中 |
| | | KeyPair keyPair = keyPairGen.generateKeyPair(); |
| | | |
| | | // 得到公钥字符串 |
| | | String pub = new String(Base64.encodeBase64(keyPair.getPublic().getEncoded())); |
| | | result.put("publicKey", pub); |
| | | |
| | | // 得到私钥字符串 |
| | | String pri = new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded())); |
| | | result.put("privateKey", pri); |
| | | } catch (Exception ex) { |
| | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * RSA私钥解密 |
| | | * |
| | | * @param str 加密的字符串 |
| | | * @return 解密字符串 |
| | | * @throws Exception 加密过程中的异常信息 |
| | | */ |
| | | public static String decrypt(String str) throws Exception { |
| | | // 64位解码加密后的字符串 |
| | | byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8)); |
| | | |
| | | // Base64编码的私钥 |
| | | byte[] decoded = Base64.decodeBase64(getPrivateKey()); |
| | | RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)); |
| | | |
| | | // RSA解密:RSA/ECB/NoPadding |
| | | Cipher cipher = Cipher.getInstance("RSA"); |
| | | cipher.init(Cipher.DECRYPT_MODE, priKey); |
| | | |
| | |
| | | return outStr; |
| | | } |
| | | |
| | | /** |
| | | * RSA公钥加密 |
| | | * |
| | | * @param str 需要加密的字符串 |
| | | * @return 密文 |
| | | * @throws Exception 加密过程中的异常信息 |
| | | */ |
| | | public static String encrypt(String str) throws Exception { |
| | | // Base64编码的公钥 |
| | | byte[] decoded = Base64.decodeBase64(getPublicKey()); |
| | | |
| | | RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); |
| | | |
| | | // RSA加密:RSA/ECB/NoPadding |
| | | Cipher cipher = Cipher.getInstance("RSA"); |
| | | cipher.init(Cipher.ENCRYPT_MODE, pubKey); |
| | | |
| | |
| | | import java.util.Map; |
| | | import java.util.Vector; |
| | | |
| | | /** |
| | | * ShapeFile帮助类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-13 |
| | | */ |
| | | @Slf4j |
| | | @SuppressWarnings("ALL") |
| | | public class ShpHelper { |
| | |
| | | f.SetField(i, local.getYear(), local.getMonthValue(), local.getDayOfMonth(), local.getHour(), local.getMinute(), local.getSecond(), 8); |
| | | } |
| | | |
| | | /** |
| | | * 创建Geometry对象 |
| | | */ |
| | | public static Geometry createGeometry(GeLayer geLayer, JSONObject geom) { |
| | | String type = geom.getStr("type"); |
| | | JSONArray cs = geom.getJSONArray("coordinates"); |
| | |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * 字符串帮助类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-12 |
| | | */ |
| | | @SuppressWarnings("ALL") |
| | | public class StringHelper { |
| | | public final static String COMMA = ","; |
| | | |
| | | public final static String PWD_REG = "^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W!@#$%^&*`~()\\-_+=,.?;<>]+$)(?![a-z0-9]+$)(?![a-z\\W!@#$%^&*`~()\\-_+=,.?;<>]+$)(?![0-9\\W!@#$%^&*`~()\\-_+=,.?;<>]+$)[a-zA-Z0-9\\W!@#$%^&*`~()\\-_+=,.?;<>]{12,20}$"; |
| | | |
| | | /** |
| | | * 数字正则 |
| | | */ |
| | | public static final Pattern NUMBER_PATTERN = Pattern.compile("-?\\d+(\\.\\d+)?"); |
| | | |
| | | /** |
| | | * 格式化当前系统日期 1 |
| | | */ |
| | | public static final SimpleDateFormat YMD_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); |
| | | |
| | | /** |
| | | * 格式化当前系统日期 2 |
| | | */ |
| | | public static final SimpleDateFormat YMDHMS_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | |
| | | /** |
| | | * 格式化当前系统日期 3 |
| | | */ |
| | | public static final SimpleDateFormat YMD2_FORMAT = new SimpleDateFormat("yyyyMMdd"); |
| | | |
| | | /** |
| | | * 格式化当前系统日期 4 |
| | | */ |
| | | public static final SimpleDateFormat YMDHMS2_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss"); |
| | | |
| | | /** |
| | | * 判断字符串,是否为整数 |
| | | */ |
| | | public static boolean isInteger(String str) { |
| | | return str != null && str.matches("[0-9]+"); |
| | | } |
| | | |
| | | /** |
| | | * 判断字符串,是否为浮点数 |
| | | */ |
| | | public static boolean isNumeric(String str) { |
| | | return str != null && str.matches("-?\\d+(\\.\\d+)?"); |
| | | } |
| | | |
| | | /** |
| | | * 判断字符串,是否为浮点数 |
| | | */ |
| | | public static boolean isNumeric2(String str) { |
| | | return str != null && NUMBER_PATTERN.matcher(str).matches(); |
| | | } |
| | | |
| | | /** |
| | | * 日期正则 |
| | | */ |
| | | public static Pattern datePattern = Pattern.compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/]((((0?[13578])|(1[02]))[\\-\\/]((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/]((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/]((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/]((((0?[13578])|(1[02]))[\\-\\/]((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/]((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/]((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$"); |
| | | |
| | | /** |
| | | * SQL正则 |
| | | */ |
| | | public static Pattern sqlPattern = Pattern.compile("|and|exec|execute|insert|select|delete|update|count|drop|\\*|%|chr|mid|master|truncate|char|declare|sitename|net user|xp_cmdshell|;|or|-|\\+|,|like"); |
| | | |
| | | /** |
| | | * 字符串转为日期 |
| | | */ |
| | | public static Date parseDate(String str) { |
| | | try { |
| | | return YMD_FORMAT.parse(str); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 字符串转为日期时间 |
| | | */ |
| | | public static Date parseTime(String str) { |
| | | try { |
| | | return YMDHMS_FORMAT.parse(str); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 判断值是否为日期格式 |
| | | */ |
| | | public static boolean isDate(String strDate) { |
| | | Matcher m = datePattern.matcher(strDate); |
| | | |
| | | return m.matches(); |
| | | } |
| | | |
| | | /** |
| | | * 字符串,是否为null 或 "" |
| | | */ |
| | | public static boolean isNull(String str) { |
| | | return null == str || str.length() == 0; |
| | | } |
| | | |
| | | /** |
| | | * 字符串,是否为空null和空格 |
| | | */ |
| | | public static boolean isEmpty(String str) { |
| | | // return null == str || "".equals(str) |
| | | return null == str || "".equals(str.trim()); |
| | | } |
| | | |
| | | /** |
| | | * 获取 like 字符串 |
| | | */ |
| | | public static String getLikeStr(String str) { |
| | | return isEmpty(str) ? null : "%" + str.trim() + "%"; |
| | | } |
| | | |
| | | /** |
| | | * 获取 like 字符串 |
| | | */ |
| | | public static String getLikeUpperStr(String str) { |
| | | return isEmpty(str) ? null : "%" + str.trim().toUpperCase() + "%"; |
| | | } |
| | | |
| | | /** |
| | | * 获取 右like 字符串 |
| | | */ |
| | | public static String getRightLike(String str) { |
| | | return isEmpty(str) ? null : str.trim() + "%"; |
| | | } |
| | | |
| | | /** |
| | | * 获取图形的WKT字符串 |
| | | */ |
| | | public static String getGeomWkt(String wkt) { |
| | | if (isEmpty(wkt)) { |
| | | return "null"; |
| | |
| | | return String.format("ST_GeomFromText('%s')", wkt); |
| | | } |
| | | |
| | | /** |
| | | * 首字母大写 |
| | | */ |
| | | public static String firstCharToUpperCase(String str) { |
| | | return str.substring(0, 1).toUpperCase() + str.substring(1); |
| | | } |
| | | |
| | | /** |
| | | * 首字母小写 |
| | | */ |
| | | public static String firstCharToLowerCase(String str) { |
| | | return str.substring(0, 1).toLowerCase() + str.substring(1); |
| | | } |
| | | |
| | | /** |
| | | * 判断值是否存在SQL注入 |
| | | * |
| | | * @param str 字符串 |
| | | * @return 是/否 |
| | | */ |
| | | public static boolean isSqlInjection(String str) { |
| | | if (null == str) { |
| | | return false; |
| | |
| | | return m.matches(); |
| | | } |
| | | |
| | | /** |
| | | * 校验密码是/否合法 |
| | | * |
| | | * @param pwd 密码 |
| | | * @return 是/否为无效的 |
| | | */ |
| | | public static boolean isPwdInvalid(String pwd) { |
| | | return !Pattern.matches(PWD_REG, pwd); |
| | | } |
| | | |
| | | /** |
| | | * 获取GUID |
| | | */ |
| | | public static String getGuid() { |
| | | return UUID.randomUUID().toString(); |
| | | } |
| | | |
| | | /** |
| | | * 获取分钟差数 |
| | | */ |
| | | public static long getMinuteDifference(Timestamp ts) { |
| | | return (ts.getTime() - System.currentTimeMillis()) / 1000 / 60; |
| | | } |
| | | |
| | | /** |
| | | * 连接List集合 |
| | | * |
| | | * @param list list 整数集合 |
| | | * @param join join 连接字符 |
| | | * @param <T> 泛型类 |
| | | * @return 字符串 |
| | | */ |
| | | public static <T> String join(List<T> list, String join) { |
| | | if (null == list || list.isEmpty()) { |
| | | return ""; |
| | |
| | | } |
| | | |
| | | if (sb.length() > 0 && sb.lastIndexOf(join) == sb.length() - join.length()) { |
| | | // 删除从索引 start 开始到 end 之间的字符,即 前包括 后不包括。 |
| | | sb.delete(sb.length() - join.length(), sb.length()); |
| | | } |
| | | |
| | | return sb.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 字符串转整数集合 |
| | | */ |
| | | public static List<Integer> strToIntegers(String str) { |
| | | if (isEmpty(str)) { |
| | | return null; |
| | |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * Web帮助类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-07-16 |
| | | */ |
| | | @Slf4j |
| | | @SuppressWarnings("ALL") |
| | | public class WebHelper { |
| | | public final static String POINT = "."; |
| | | |
| | |
| | | return osName.startsWith("Windows"); |
| | | } |
| | | |
| | | /** |
| | | * 获取CPU核心数 |
| | | */ |
| | | public static int getCpuCores() { |
| | | return Runtime.getRuntime().availableProcessors(); |
| | | } |
| | | |
| | | /** |
| | | * 格式化日期 |
| | | */ |
| | | public final static SimpleDateFormat YMDHMS = new SimpleDateFormat("yyyyMMddHHmmss"); |
| | | |
| | | /** |
| | | * 字符串,是否为空null和空格 |
| | | */ |
| | | public static boolean isEmpty(String str) { |
| | | return null == str || "".equals(str.trim()); |
| | | } |
| | | |
| | | /** |
| | | * 获取GUID |
| | | */ |
| | | public static String getGuid() { |
| | | return UUID.randomUUID().toString(); |
| | | } |
| | | |
| | | /** |
| | | * 获取主机IP |
| | | */ |
| | | public static String getHostIp() { |
| | | try { |
| | | return InetAddress.getLocalHost().getHostAddress(); |
| | |
| | | return "127.0.0.1"; |
| | | } |
| | | |
| | | /** |
| | | * 获取用户IP |
| | | */ |
| | | public static String getIpAddress(HttpServletRequest request) { |
| | | String ip = request.getHeader("X-Forwarded-For"); |
| | | if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { |
| | |
| | | return ip; |
| | | } |
| | | |
| | | /** |
| | | * 获取当前时间的Timestamp |
| | | */ |
| | | public static Timestamp getCurrentTimestamp() { |
| | | return new Timestamp(System.currentTimeMillis()); |
| | | } |
| | | |
| | | /** |
| | | * 获取Request |
| | | */ |
| | | public static HttpServletRequest getRequest() { |
| | | ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); |
| | | |
| | | return servletRequestAttributes.getRequest(); |
| | | } |
| | | |
| | | /** |
| | | * 获取Response |
| | | */ |
| | | public static HttpServletResponse getResponse() { |
| | | ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); |
| | | |
| | | return servletRequestAttributes.getResponse(); |
| | | } |
| | | |
| | | /** |
| | | * 输出JSON至页面 |
| | | */ |
| | | public static boolean writeJson2Page(HttpServletResponse res, HttpStatus status, Object obj) { |
| | | res.setStatus(status.value()); |
| | | |
| | | return writeStr2Page(res, JSON.toJSONString(obj)); |
| | | } |
| | | |
| | | /** |
| | | * 输出JSON至页面 |
| | | */ |
| | | public static boolean writeJson2Page(HttpServletResponse res, HttpStatus status, String str) { |
| | | res.setStatus(status.value()); |
| | | |
| | |
| | | return writeStr2Page(res, JSON.toJSONString(map)); |
| | | } |
| | | |
| | | /** |
| | | * 输出str至页面 |
| | | */ |
| | | public static boolean writeStr2Page(HttpServletResponse res, HttpStatus status, String str) { |
| | | res.setStatus(status.value()); |
| | | |
| | | return writeStr2Page(res, str); |
| | | } |
| | | |
| | | /** |
| | | * 输出str至页面 |
| | | */ |
| | | public static boolean writeStr2Page(HttpServletResponse res, String str) { |
| | | try { |
| | | res.setContentType("application/json;charset=UTF-8"); |
| | |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 输出字节数组 |
| | | */ |
| | | public static void writeBytes(byte[] bytes, HttpServletResponse res) throws IOException { |
| | | res.setContentType("application/octet-stream"); |
| | | |
| | |
| | | os.close(); |
| | | } |
| | | |
| | | /** |
| | | * 输出Png文件 |
| | | */ |
| | | public static void writePng(String filePath, HttpServletResponse res) throws IOException { |
| | | File file = new File(filePath); |
| | | if (!file.exists() || file.isDirectory()) { |
| | |
| | | writeFile(filePath, res); |
| | | } |
| | | |
| | | /** |
| | | * 获取随机整数 |
| | | */ |
| | | public static int getRandomInt(int min, int max) { |
| | | return new Random().nextInt(max) % (max - min + 1) + min; |
| | | } |
| | | |
| | | /** |
| | | * 下载文件 |
| | | */ |
| | | public static void download(String file, String fileName, HttpServletResponse res) throws Exception { |
| | | download(file, fileName, false, res); |
| | | } |
| | | |
| | | /** |
| | | * 下载文件 |
| | | * |
| | | * @param file 文件 |
| | | * @param fileName 文件名 |
| | | * @param res 响应 |
| | | * @throws Exception 异常 |
| | | */ |
| | | public static void download(String file, String fileName, boolean inline, HttpServletResponse res) throws Exception { |
| | | if (isEmpty(fileName)) { |
| | | fileName = YMDHMS.format(new Date()); |
| | |
| | | fileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20"); |
| | | String dispose = inline ? "inline" : "attachment"; |
| | | |
| | | // 设置响应头中文件的下载方式为附件方式,以及设置文件名 |
| | | res.setHeader("Content-Disposition", dispose + "; filename*=UTF-8''" + fileName); |
| | | // 设置响应头的编码格式为 UTF-8 |
| | | res.setCharacterEncoding("UTF-8"); |
| | | |
| | | // 通过response对象设置响应数据格式(如:"text/plain; charset=utf-8") |
| | | String ext = getExtension(file); |
| | | String mime = getMime(ext); |
| | | res.setContentType(mime); |
| | |
| | | writeFile(file, res); |
| | | } |
| | | |
| | | /** |
| | | * 写文件 |
| | | */ |
| | | private static void writeFile(String file, HttpServletResponse res) throws IOException { |
| | | // 通过response对象,获取到输出流 |
| | | ServletOutputStream outputStream = res.getOutputStream(); |
| | | // 定义输入流,通过输入流读取文件内容 |
| | | FileInputStream fileInputStream = new FileInputStream(file); |
| | | |
| | | int len = 0; |
| | | byte[] bytes = new byte[1024]; |
| | | while ((len = fileInputStream.read(bytes)) != -1) { |
| | | // 通过输入流读取文件数据,然后通过上述的输出流写回浏览器 |
| | | outputStream.write(bytes, 0, len); |
| | | outputStream.flush(); |
| | | } |
| | | |
| | | // 关闭资源 |
| | | fileInputStream.close(); |
| | | outputStream.close(); |
| | | } |
| | | |
| | | /** |
| | | * 获取文件扩展名 |
| | | */ |
| | | public static String getExtension(String fileName) { |
| | | if (isEmpty(fileName)) { |
| | | return ""; |
| | |
| | | return fileName.substring(idx).toLowerCase(); |
| | | } |
| | | |
| | | /** |
| | | * 获取多用途互联网邮件扩展类型 |
| | | */ |
| | | public static String getMime(String ext) { |
| | | switch (ext) { |
| | | // 图片 |
| | | case ".tif": |
| | | case ".tiff": |
| | | return "image/tiff"; |
| | |
| | | return "image/jpeg"; |
| | | case ".png": |
| | | return "image/png"; |
| | | // 音/视频 |
| | | case ".mp3": |
| | | return "audio/mp3"; |
| | | case ".mp4": |
| | |
| | | return "application/vnd.rn-realmedia"; |
| | | case ".rmvb": |
| | | return "application/vnd.rn-realmedia-vbr"; |
| | | // 网页 |
| | | case ".js": |
| | | return "application/x-javascript"; |
| | | case ".css": |
| | |
| | | case ".xml": |
| | | case ".svg": |
| | | return "text/xml"; |
| | | // 文件 |
| | | case ".txt": |
| | | return "text/plain"; |
| | | case ".dbf": |
| | |
| | | return "application/x-dwg"; |
| | | case ".ext": |
| | | return "application/x-msdownload"; |
| | | // 默认 |
| | | default: |
| | | return "application/octet-stream"; |
| | | } |
| | |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | /** |
| | | * 仿真Mapper |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-18 |
| | | */ |
| | | @Mapper |
| | | @Repository |
| | | @SuppressWarnings("ALL") |
| | | public interface SimuMapper extends BaseMapper<SimuPo> { |
| | | /** |
| | | * 查询最大ID |
| | | * |
| | | * @return 最大ID |
| | | */ |
| | | Integer selectMaxId(); |
| | | } |
| | |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * GEDB服务类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-12 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | @SuppressWarnings("ALL") |
| | |
| | | |
| | | @Resource |
| | | RestTemplate restTemplate; |
| | | |
| | | private final static String DB_KEY = "gedb_db"; |
| | | |
| | | private final static String TOKEN_KEY = "gedb_token"; |
| | | |
| | |
| | | return db; |
| | | } |
| | | |
| | | private GeDb getSeDb(String token) { |
| | | public GeDb getSeDb(String token) { |
| | | Object obj = CaffeineHelper.get(DB_KEY); |
| | | if (obj instanceof GeDb) { |
| | | return (GeDb) obj; |
| | | } |
| | | |
| | | Map<String, Object> map = new HashMap<>(1); |
| | | map.put("token", token); |
| | | |
| | | JSONObject obj = restTemplate.postForObject(config.getHost() + "geo-service/entitydb/list/canview", map, JSONObject.class); |
| | | JSONArray data = obj.getJSONArray("data"); |
| | | JSONObject jsonObject = restTemplate.postForObject(config.getHost() + "geo-service/entitydb/list/canview", map, JSONObject.class); |
| | | JSONArray data = jsonObject.getJSONArray("data"); |
| | | |
| | | List<GeDb> list = JSONUtil.toList(data, GeDb.class); |
| | | if (CollectionUtils.isEmpty(list)) return null; |
| | | |
| | | return list.stream().filter(db -> null != db.getName() && db.getName().contains(config.getDbName())).findFirst().orElse(null); |
| | | GeDb gedb = list.stream().filter(db -> null != db.getName() && db.getName().contains(config.getDbName())).findFirst().orElse(null); |
| | | if (null != gedb) CaffeineHelper.put(DB_KEY, gedb); |
| | | |
| | | return gedb; |
| | | } |
| | | |
| | | public List<GeLayer> getLayers(String token, GeDb db) { |
| | |
| | | import java.util.List; |
| | | import java.util.concurrent.CopyOnWriteArrayList; |
| | | |
| | | /** |
| | | * 处理结果服务类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-29 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | @SuppressWarnings("ALL") |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 地形 |
| | | */ |
| | | private void copeTerrain(ResultDto dto, LayerDto layer) { |
| | | Dataset ds = null; |
| | | try { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 重采样: https://blog.51cto.com/u_16099346/6691820 |
| | | */ |
| | | private static void Resample(Dataset ds, String dest, int width, int height, LayerDto layer) { |
| | | Vector<String> vector = new Vector<>(); |
| | | //vector.add("-s_srs"); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 建筑 |
| | | */ |
| | | private void copeBuilding(ResultDto dto, LayerDto layer) { |
| | | Driver driver = null; |
| | | DataSource dataSource = null; |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 水面 |
| | | */ |
| | | private void setWaterInfo(ResultDto dto, LayerDto layer) { |
| | | List<String> files = getFiles(dto.getWaterPath(), ".tif"); |
| | | layer.getWaters().setFiles(files); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 是否相交 |
| | | * https://blog.csdn.net/flyingshineangel/article/details/135423025 |
| | | */ |
| | | private static BuildingDto intersects(ResultDto dto, double x, double y) { |
| | | Geometry p = new Geometry(ogr.wkbPoint); |
| | | p.AddPoint_2D(x, y); |
| | |
| | | |
| | | private static void createFlowPng(float[] vxBuffer, float[] vyBuffer, String png, int width, int height) { |
| | | BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); |
| | | // 用 R通道表示,流向为归一化的二维向量(x,y),G通道表示为 x *255 , B通道表示为 y * 255 |
| | | for (int x = 0; x < width; x++) { |
| | | for (int y = 0; y < height; y++) { |
| | | int offset = x + y * width; |
| | |
| | | return val; |
| | | } |
| | | |
| | | /** |
| | | * 元数据 |
| | | */ |
| | | private void copeLayerJson(ResultDto dto, LayerDto layer) throws IOException { |
| | | layer.getWaters().setFiles(null); |
| | | layer.getTerrain().setEpsg(null); |
| | |
| | | writeJson(filePath, json); |
| | | } |
| | | |
| | | /** |
| | | * 处理降水曲线文件曲线图 |
| | | */ |
| | | public void copeRainFallJson(ResultDto dto, LayerDto layer) throws IOException, ParseException { |
| | | String rainGageFilePath = config.getInPath() + File.separator + dto.getServiceName() + File.separator + "RainGage.dat"; |
| | | String filePath = dto.getOutPath() + File.separator + "rainfall.json"; |
| | |
| | | import java.util.concurrent.ExecutorService; |
| | | import java.util.concurrent.Executors; |
| | | |
| | | /** |
| | | * 仿真服务类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-18 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | @SuppressWarnings("ALL") |
| | |
| | | @Resource |
| | | ResultService resultService; |
| | | |
| | | /** |
| | | * 获取 |
| | | */ |
| | | public IPage<SimuPo> get(SimuVo vo) { |
| | | QueryWrapper<SimuPo> wrapper = getPageWrapper(vo); |
| | | |
| | |
| | | return wrapper; |
| | | } |
| | | |
| | | /** |
| | | * 删除 |
| | | */ |
| | | public int del(List<Integer> ids) { |
| | | List<SimuPo> list = simuMapper.selectBatchIds(ids); |
| | | if (null != list && list.size() > 0) { |
| | |
| | | executor.shutdown(); |
| | | } |
| | | |
| | | /** |
| | | * 处理数据,状态标识: |
| | | * 0-创建仿真任务,1-连接GEDB库,2-下载空间数据,3-下载高程数据, |
| | | * 4-生成降雨文件,5-生成配置文件,6-模拟内涝仿真,7-处理水位文件, |
| | | * 8-处理排水文件,9-处理仿真结果,10-完成,-10-出错 |
| | | */ |
| | | private void cope(SimuPo simu) { |
| | | try { |
| | | DataPo data = JSONUtil.toBean(simu.getData(), DataPo.class); |
| | |
| | | import javax.annotation.Resource; |
| | | import java.io.*; |
| | | |
| | | /** |
| | | * 内涝求解器服务类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-09-29 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | @SuppressWarnings("ALL") |
| | |
| | | return _rainfall; |
| | | } |
| | | |
| | | /** |
| | | * 创建降雨文件 |
| | | * <p> |
| | | * https://blog.csdn.net/Dark_Drgon/article/details/139739924 |
| | | * C:\Program Files\matlab\R2020a\runtime\win64 |
| | | */ |
| | | public void createRainFile(DataPo data) throws Exception { |
| | | String filePath = config.getInPath() + File.separator + data.getInPath() + File.separator + config.getRaingage(); |
| | | String startTime = StringHelper.YMDHMS_FORMAT.format(data.getStartTime()); |
| | |
| | | log.error(errorLine); |
| | | } |
| | | |
| | | // 等待程序执行结束并输出状态 |
| | | int exitCode = process.waitFor(); |
| | | |
| | | return sb.toString(); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 执行命令行,并等待命令执行完毕 |
| | | * |
| | | * https://www.cnblogs.com/stars-one/p/16482964.html |
| | | * @param cmd 命令,window记得要使用cmd /c开头,如cmd /c ipconfig |
| | | * @throws IOException |
| | | * @throws InterruptedException |
| | | */ |
| | | private String execCmdLine(String cmd) throws IOException, InterruptedException { |
| | | Process process = Runtime.getRuntime().exec(cmd); |
| | | |
| | |
| | | import javax.annotation.Resource; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 内涝服务类 |
| | | * |
| | | * @author WWW |
| | | * @date 2024-07-16 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | @SuppressWarnings("ALL") |
| | |
| | | @Resource |
| | | PropertiesConfig config; |
| | | |
| | | /** |
| | | * 获取元数据信息 |
| | | */ |
| | | public byte[] getson(String serviceName, String json) { |
| | | try { |
| | | String filePath = config.getOutPath() + File.separator + serviceName + File.separator + json; |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取地形高度图 |
| | | */ |
| | | public String getTerraMap(String serviceName, Integer width, Integer height) { |
| | | return config.getOutPath() + File.separator + serviceName + File.separator + "terrain" + File.separator + width + "_" + height + ".png"; |
| | | } |
| | | |
| | | /** |
| | | * 获取水面高度图 |
| | | */ |
| | | public String getWaterMap(String serviceName, Integer width, Integer height, Long timestamp) { |
| | | return config.getOutPath() + File.separator + serviceName + File.separator + "waters" + File.separator + timestamp + File.separator + width + "_" + height + ".png"; |
| | | } |
| | | |
| | | /** |
| | | * 获取水流向流速图 |
| | | */ |
| | | public String getFlowMap(String serviceName, Integer width, Integer height, Long timestamp) { |
| | | return config.getOutPath() + File.separator + serviceName + File.separator + "flows" + File.separator + timestamp + File.separator + width + "_" + height + ".png"; |
| | | } |
| | | |
| | | /** |
| | | * 根据坐标查询积水深度:gdalconst.GA_Update |
| | | */ |
| | | public Double getWaterHeight(SimuPo simu, double x, double y, Long timestamp) { |
| | | String filePath = config.getOutPath() + File.separator + simu.getServiceName() + File.separator + "waters" |
| | | + File.separator + timestamp + File.separator + "water.tif"; |
| | |
| | | return data.getSpatialReference(); |
| | | } |
| | | |
| | | /** |
| | | * 将地图坐标转换为栅格像素坐标 |
| | | * |
| | | * @param gt 仿射变换参数 |
| | | * @param x 横坐标 |
| | | * @param y 纵坐标 |
| | | * @return 像素坐标 |
| | | */ |
| | | public int[] coordinates2ColRow(double[] gt, double x, double y) { |
| | | // 向下取整,如果向上取整会导致计算结果偏大,从而在后面读取到邻近像元的数据 |
| | | //Double col = Math.floor(((y - gt[3]) * gt[1] - (x - gt[0]) * gt[4]) / (gt[5] * gt[1] - gt[2] * gt[4])); |
| | | Double col = Math.floor((y * gt[1] - x * gt[4] + gt[0] * gt[4] - gt[3] * gt[1]) / (gt[5] * gt[1] - gt[2] * gt[4])); |
| | | Double row = Math.floor((x - gt[0] - col * gt[2]) / gt[1]); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据seid查询建筑物涉水深度 |
| | | */ |
| | | public List<BuildingDepthVo> getBuildingDepthBySeid(String serviceName, String seid) { |
| | | List<BuildingDepthVo> list = readBuildingJson(serviceName); |
| | | if (CollectionUtils.isEmpty(list)) return null; |