package com.terra.system.controller.data; import com.terra.system.annotation.SysLog; import com.terra.system.config.PropertiesConfig; import com.terra.system.helper.StringHelper; import com.terra.system.helper.WebHelper; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.tags.Tag; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.annotation.Resource; import org.springframework.core.io.ClassPathResource; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.http.server.ServletServerHttpResponse; import org.springframework.web.bind.annotation.*; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.Date; import java.util.List; /** * WMTS服务 * @author WWW */ @Tag(name = "数据管理\\WMTS服务") @RestController @RequestMapping("/wmts") public class WmtsController { @Resource PropertiesConfig config; private final static Log log = LogFactory.getLog(WmtsController.class); @SysLog() @Operation(summary = "获取WMTS元数据") @Parameters({ @Parameter(name = "token", description = "令牌", required = true, example = "token", in = ParameterIn.PATH) }) @GetMapping("select/{token}/WMTSCapabilities.xml") public void selectWmtsCapabilities(@PathVariable(name = "token") String token, HttpServletRequest req, HttpServletResponse res) { try { ClassPathResource resource = new ClassPathResource("wmts/web.xml"); if (!resource.exists()) { return; } InputStream stream = resource.getInputStream(); byte[] data = new byte[stream.available()]; stream.read(data); stream.close(); String url = req.getRequestURL().toString().replace("WMTSCapabilities.xml", "tile?"); String result = new String(data, StandardCharsets.UTF_8); result = result.replace("{url}", url); byte[] bytes = result.getBytes(StandardCharsets.UTF_8); res.setHeader("Content-Type", "application/xml;charset=UTF-8"); ServletOutputStream os = res.getOutputStream(); os.write(bytes); os.flush(); } catch (Exception ex) { log.error(ex.getMessage(), ex); } } @Operation(summary = "获取WMTS瓦片") @Parameters({ @Parameter(name = "token", description = "令牌", required = true, example = "token", in = ParameterIn.PATH), @Parameter(name = "layer", description = "图层类型", required = true, example = "img"), @Parameter(name = "tilematrix", description = "层级", required = true), @Parameter(name = "tilerow", description = "行号", required = true), @Parameter(name = "tilecol", description = "列号", required = true) }) @GetMapping("select/{token}/tile") public void selectWmtsTile(@PathVariable(name = "token") String token, HttpServletRequest req, HttpServletResponse res) { try { String layer = WebHelper.getReqParamVal(req, "layer"); String matrix = WebHelper.getReqParamVal(req, "tilematrix"); String row = WebHelper.getReqParamVal(req, "tilerow"); String col = WebHelper.getReqParamVal(req, "tilecol"); if (StringHelper.isEmpty(layer) || StringHelper.isEmpty(matrix) || StringHelper.isEmpty(layer) || StringHelper.isEmpty(row) || StringHelper.isEmpty(col)) { return; } int z = Integer.parseInt(matrix); int x = Integer.parseInt(row); int y = Integer.parseInt(col); getWmtsTile(layer, z, x, y, req, res); } catch (Exception ex) { log.error(ex.getMessage(), ex); } } /** * 获取WMTS瓦片 */ private void getWmtsTile(String layer, int z, int x, int y, HttpServletRequest req, HttpServletResponse res) throws Exception { ServletServerHttpRequest ssReq = new ServletServerHttpRequest(req); ServletServerHttpResponse ssRes = new ServletServerHttpResponse(res); // 检查缓存是否过期 if (checkIfNotModify(ssReq, ssRes)) { // 设置缓存头 setBrowerCache(ssRes); return; } // 设置缓存参数 setBrowerCache(ssRes); //res.setContentType("image/png") // 通过response对象,获取到输出流 ServletOutputStream outputStream = res.getOutputStream(); // 定义输入流,通过输入流读取文件内容 FileInputStream fileInputStream; // y = (int) Math.pow(2, z) - y - 1; String path = config.getTilePath() + File.separator + layer + File.separator + z + File.separator + y + File.separator + x + ".png"; System.out.println(path); File file = new File(path); if (!file.exists() || file.isDirectory()) { ClassPathResource resource = new ClassPathResource("wmts/nofound.png"); fileInputStream = new FileInputStream(resource.getFile()); } else { System.out.println(path); 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(); } //outputStream.close() fileInputStream.close(); // 设置返回图片类型 ssRes.getHeaders().set("Content-Type", "image/png"); OutputStream os = ssRes.getBody(); os.write(bytes); os.flush(); } /** * 设置浏览器缓存参数 */ private void setBrowerCache(ServerHttpResponse res) { HttpHeaders headers = res.getHeaders(); headers.setCacheControl("public, must-revalidate"); headers.setExpires(System.currentTimeMillis() + 24 * 60 * 60 * 1000); headers.setAccessControlMaxAge(Duration.ofHours(24)); headers.setETag("\"" + new Date().toString() + "\""); // must-revalidate // response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); } /** * 验证缓存参数 */ boolean checkIfNotModify(ServerHttpRequest req, ServerHttpResponse res) { List etags = req.getHeaders().getIfNoneMatch(); if (0 == etags.size() || StringHelper.isEmpty(etags.get(0))) { return false; } res.setStatusCode(HttpStatus.NOT_MODIFIED); return true; } }