From 443a226fd731a7ec16c5001f512921c2cc582e1a Mon Sep 17 00:00:00 2001
From: shiyi <shi_yee@outlook.com>
Date: Wed, 3 Jul 2024 09:57:51 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=AD=E5=A4=AE=E6=B0=94?=
 =?UTF-8?q?=E8=B1=A1=E5=8F=B0=E5=9C=B0=E9=9D=A2=E6=B0=94=E8=B1=A1=E9=A2=84?=
 =?UTF-8?q?=E8=AD=A6=E6=95=B0=E6=8D=AE=E6=BA=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../weather/griddata/common/TableConfig.java  |   2 +-
 .../htfp/weather/utils/HttpClientUtils.java   |   7 +-
 .../controller/SurfaceWeatherController.java  |   6 +-
 .../htfp/weather/web/exception/ErrorCode.java |   9 +-
 .../web/pojo/cma/AddressComponent.java        |  32 ++++
 .../web/pojo/cma/AntiGeoCodeResponse.java     |  22 +++
 .../htfp/weather/web/pojo/cma/CmaWarning.java |  32 ++++
 .../pojo/response/SurfaceWeatherWarning.java  |   5 +-
 .../service/surfaceapi/CmaServiceImpl.java    | 154 ++++++++++++++++++
 .../main/resources/application-weather.yml    |   3 +-
 .../src/main/resources/application.yml        |   6 +-
 .../surfaceapi/CmaServiceImplTest.java        |  46 ++++++
 .../test/resources/application-weather.yml    |   6 +-
 13 files changed, 318 insertions(+), 12 deletions(-)
 create mode 100644 weather-service/src/main/java/com/htfp/weather/web/pojo/cma/AddressComponent.java
 create mode 100644 weather-service/src/main/java/com/htfp/weather/web/pojo/cma/AntiGeoCodeResponse.java
 create mode 100644 weather-service/src/main/java/com/htfp/weather/web/pojo/cma/CmaWarning.java
 create mode 100644 weather-service/src/main/java/com/htfp/weather/web/service/surfaceapi/CmaServiceImpl.java
 create mode 100644 weather-service/src/test/java/com/htfp/weather/web/service/surfaceapi/CmaServiceImplTest.java

diff --git a/weather-service/src/main/java/com/htfp/weather/griddata/common/TableConfig.java b/weather-service/src/main/java/com/htfp/weather/griddata/common/TableConfig.java
index e5e7991..6eea121 100644
--- a/weather-service/src/main/java/com/htfp/weather/griddata/common/TableConfig.java
+++ b/weather-service/src/main/java/com/htfp/weather/griddata/common/TableConfig.java
@@ -63,7 +63,7 @@ public class TableConfig {
     // private final String configPath = Objects.requireNonNull(this.getClass().getClassLoader().getResource("config/tableConf.json")).getPath();
     private final String configPath = System.getProperty("user.dir") +"/tableConf.json";
     @PostConstruct
-    private void initTableConfig() {
+    public void initTableConfig() {
         readConfig();
         initLonList();
         initLatList();
diff --git a/weather-service/src/main/java/com/htfp/weather/utils/HttpClientUtils.java b/weather-service/src/main/java/com/htfp/weather/utils/HttpClientUtils.java
index ca293d5..060cf82 100644
--- a/weather-service/src/main/java/com/htfp/weather/utils/HttpClientUtils.java
+++ b/weather-service/src/main/java/com/htfp/weather/utils/HttpClientUtils.java
@@ -58,7 +58,10 @@ public class HttpClientUtils {
     public static String sendGet(String url, Map<String, String> params) throws IOException {
         StringBuilder stringBuilder = new StringBuilder();
         if (!CollectionUtils.isEmpty(params)) {
-            params.keySet().forEach(res -> {
+            for (String res : params.keySet()) {
+                if (res == null || params.get(res) == null) {
+                    continue;
+                }
                 if (StringUtils.isNotBlank(stringBuilder)) {
                     stringBuilder.append("&");
                 } else {
@@ -69,7 +72,7 @@ public class HttpClientUtils {
                 } catch (UnsupportedEncodingException e) {
                     throw new RuntimeException(e);
                 }
-            });
+            }
         }
         Request request = new Builder()
                 .url(url + stringBuilder)
diff --git a/weather-service/src/main/java/com/htfp/weather/web/controller/SurfaceWeatherController.java b/weather-service/src/main/java/com/htfp/weather/web/controller/SurfaceWeatherController.java
index 3ff8705..8fcaf76 100644
--- a/weather-service/src/main/java/com/htfp/weather/web/controller/SurfaceWeatherController.java
+++ b/weather-service/src/main/java/com/htfp/weather/web/controller/SurfaceWeatherController.java
@@ -7,6 +7,7 @@ import com.htfp.weather.web.pojo.response.Result;
 import com.htfp.weather.web.pojo.response.SurfaceWeatherWarning;
 import com.htfp.weather.web.pojo.response.TimeSeriesDataset;
 import com.htfp.weather.web.service.surfaceapi.CaiYunServiceImpl;
+import com.htfp.weather.web.service.surfaceapi.CmaServiceImpl;
 import com.htfp.weather.web.service.surfaceapi.HeFengServiceImpl;
 import com.htfp.weather.web.service.IDataService;
 import com.htfp.weather.web.service.surfaceapi.ISurfaceDataService;
@@ -29,6 +30,8 @@ public class SurfaceWeatherController {
     @Resource(name = "hefeng")
     ISurfaceDataService surfaceDataService;
 
+    @Resource
+    CmaServiceImpl cmaService;
     @PostMapping("/querySurfaceNowWeather")
     public Result queryNowWeather(@Validated @RequestBody Position2D position2D) throws Exception {
         double lat = position2D.getLatitude();
@@ -58,7 +61,8 @@ public class SurfaceWeatherController {
         double lat = position2D.getLatitude();
         double lon = position2D.getLongitude();
         log.info("[data-server] 地面气象预警信息查询 start: param={}", position2D);
-        List<SurfaceWeatherWarning> warning = surfaceDataService.getSurfaceWarning(lat, lon);
+        // List<SurfaceWeatherWarning> warning = surfaceDataService.getSurfaceWarning(lat, lon);
+        List<SurfaceWeatherWarning> warning = cmaService.getSurfaceWarning(lat, lon);
         log.info("[data-server] 地面气象预警信息查询 end");
         return Result.success(warning);
     }
diff --git a/weather-service/src/main/java/com/htfp/weather/web/exception/ErrorCode.java b/weather-service/src/main/java/com/htfp/weather/web/exception/ErrorCode.java
index 21314de..2a12966 100644
--- a/weather-service/src/main/java/com/htfp/weather/web/exception/ErrorCode.java
+++ b/weather-service/src/main/java/com/htfp/weather/web/exception/ErrorCode.java
@@ -21,9 +21,12 @@ public enum ErrorCode {
     // 数据查询
     HE_FENG_THIS_AREA_HAVE_NO_DATA(3001, "查询的数据或地区不存在"),
     HE_FENG_REQUEST_ERROR(3002, "查询请求错误"),
-    CAI_YUN_REQUEST_ERROR(4002, "查询请求错误"),
-    CAI_YUN_DATA_PARSE_ERROR(4003, "数据解析错误"),
-
+    CAI_YUN_REQUEST_ERROR(3003, "查询请求错误"),
+    CAI_YUN_DATA_PARSE_ERROR(3004, "数据解析错误"),
+    CMA_REQUEST_ERROR(3005, "查询请求错误"),
+    CMA_DATA_PARSE_ERROR(3006, "数据解析错误"),
+    TIANDITU_REQUEST_ERROR(3007, "查询请求错误"),
+    TIANDITU_DATA_PARSE_ERROR(3008, "数据解析错误"),
     IMPORT_DATA_INITIAL_FAILED(5001, "导入数据初始化失败"),
     NO_NC_OR_GRIB_FILES(5002, "文件夹不存在或中没有对应的气象数据文件"),
 
diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/AddressComponent.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/AddressComponent.java
new file mode 100644
index 0000000..386524c
--- /dev/null
+++ b/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/AddressComponent.java
@@ -0,0 +1,32 @@
+package com.htfp.weather.web.pojo.cma;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+@Data
+public class AddressComponent {
+
+    private String address;
+    private String city;
+    @JsonProperty("county_code")
+    private String countyCode;
+    private String nation;
+    @JsonProperty("poi_position")
+    private String poiPosition;
+    private String county;
+    @JsonProperty("city_code")
+    private String cityCode;
+    @JsonProperty("address_position")
+    private String addressPosition;
+    private String poi;
+    @JsonProperty("province_code")
+    private String provinceCode;
+    private String province;
+    private String road;
+    @JsonProperty("road_distance")
+    private int roadDistance;
+    @JsonProperty("poi_distance")
+    private int poiDistance;
+    @JsonProperty("address_distance")
+    private int addressDistance;
+}
diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/AntiGeoCodeResponse.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/AntiGeoCodeResponse.java
new file mode 100644
index 0000000..fd3bbf1
--- /dev/null
+++ b/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/AntiGeoCodeResponse.java
@@ -0,0 +1,22 @@
+package com.htfp.weather.web.pojo.cma;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+/**
+ * @Author : shiyi
+ * @Date : 2024/7/2 16:13
+ * @Description : 天地图逆编码响应结构
+ */
+@Data
+public class AntiGeoCodeResponse {
+    Result result;
+    String msg;
+    String status;
+    @Data @JsonIgnoreProperties(value = {"formattedAddress", "location"}, ignoreUnknown = true)
+    public static class Result {
+        AddressComponent addressComponent;
+    }
+}
+
+
diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/CmaWarning.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/CmaWarning.java
new file mode 100644
index 0000000..1be30a3
--- /dev/null
+++ b/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/CmaWarning.java
@@ -0,0 +1,32 @@
+package com.htfp.weather.web.pojo.cma;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+/**
+ * @Author : shiyi
+ * @Date : 2024/7/1 17:58
+ * @Description : 中央气象台预警信息单元
+ */
+@Data @JsonIgnoreProperties(value = {"warnDefine"}, ignoreUnknown = true)
+public class CmaWarning {
+    private String expires;
+    private String procince;
+    private Integer leveltype;
+    private String signalypecode;
+    private Double lon;
+    private Double lat;
+    private Integer zoom;
+    private String issuecontent; // 发布内容
+    private String signallevelcode; // 颜色等级: YELLOW, BLUE, ORANGE, RED
+    private String reference;
+    private String areaId; // 县级行政编码
+    private String signallevel; // 预警等级:黄色,蓝色,橙色,红色
+    private String dataid; // 预警数据ID
+    private String sender; // 数据发布单位
+    private String codename; // 预警信号名称
+    private String name; // 行政单位名称
+    private String time; // 发布时间
+    private String msgtype; // 消息类型:ALERT、UPDATE
+    private String procincecode; // 省级行政编码(前两位)
+}
diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/SurfaceWeatherWarning.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/SurfaceWeatherWarning.java
index 846f0f7..3114fe1 100644
--- a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/SurfaceWeatherWarning.java
+++ b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/SurfaceWeatherWarning.java
@@ -1,5 +1,6 @@
 package com.htfp.weather.web.pojo.response;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import lombok.Data;
 
 /**
@@ -10,10 +11,12 @@ import lombok.Data;
 @Data
 public class SurfaceWeatherWarning {
     String pubTime;
-    // String startTime;
+    String endTime;
     String title;
     String text;
     String typeName;
     String severityColor;
     String source;
+    @JsonIgnore
+    String dataid;
 }
diff --git a/weather-service/src/main/java/com/htfp/weather/web/service/surfaceapi/CmaServiceImpl.java b/weather-service/src/main/java/com/htfp/weather/web/service/surfaceapi/CmaServiceImpl.java
new file mode 100644
index 0000000..acc44dd
--- /dev/null
+++ b/weather-service/src/main/java/com/htfp/weather/web/service/surfaceapi/CmaServiceImpl.java
@@ -0,0 +1,154 @@
+package com.htfp.weather.web.service.surfaceapi;
+
+import com.htfp.weather.info.Constant;
+import com.htfp.weather.utils.DateTimeUtils;
+import com.htfp.weather.utils.JSONUtils;
+import com.htfp.weather.web.exception.AppException;
+import com.htfp.weather.web.exception.ErrorCode;
+import com.htfp.weather.web.pojo.cma.AntiGeoCodeResponse;
+import com.htfp.weather.web.pojo.cma.CmaWarning;
+import com.htfp.weather.web.pojo.response.NowWeatherStatus;
+import com.htfp.weather.web.pojo.response.SurfaceWeatherWarning;
+import com.htfp.weather.web.pojo.response.TimeSeriesDataset;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.time.OffsetDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static com.htfp.weather.utils.HttpClientUtils.sendGet;
+
+/**
+ * @Author : shiyi
+ * @Date : 2024/7/2 14:02
+ * @Description : 中央气象台相关数据
+ */
+@Slf4j
+@Service("cma")
+public class CmaServiceImpl implements ISurfaceDataService{
+    @Value("${tianditu.key}") @Setter
+    private String keyOfTianDiTu;
+    private Map<String, List<SurfaceWeatherWarning>> warningCache = new ConcurrentHashMap<>();
+
+    @Override
+    public NowWeatherStatus getNowSurfaceWeatherStatus(double lat, double lon) throws Exception {
+        return null;
+    }
+
+    @Override
+    public TimeSeriesDataset getForecastSeries(double lat, double lon) throws Exception {
+        return null;
+    }
+
+    @Override
+    public List<SurfaceWeatherWarning> getSurfaceWarning(double lat, double lon) throws Exception {
+        String countyId = getCountyIdByLatLon(lat, lon);
+        return getSurfaceWarningByCounty(countyId);
+    }
+
+    public List<SurfaceWeatherWarning> getSurfaceWarningByCounty(String countyCode) throws Exception {
+        return warningCache.get(countyCode);
+        // else {
+        //     // 如果缓存中没有,则先查一遍
+        //     updateCmaWarning(countyCode);
+        //     return warningCache.get(countyCode);
+        // }
+
+    }
+
+    /**根据经纬度获取县级行政区代码*/
+    public String getCountyIdByLatLon(double lat, double lon) throws Exception {
+        String url = "http://api.tianditu.gov.cn/geocoder";
+        HashMap<String, String> params = new HashMap<>();
+        params.put("postStr", String.format("{'lon':%.6f,'lat':%.6f,'ver':1}", lon, lat));
+        params.put("type", "geocode");
+        params.put("tk", keyOfTianDiTu);
+        AntiGeoCodeResponse antiGeoCodeResponse = sendGet(url, params, AntiGeoCodeResponse.class);
+        if (!"ok".equals(antiGeoCodeResponse.getMsg())) {
+            throw new AppException(ErrorCode.TIANDITU_REQUEST_ERROR, "获取行政区划信息失败:" + antiGeoCodeResponse.getMsg());
+        }
+        String countyCode = antiGeoCodeResponse.getResult().getAddressComponent().getCountyCode();
+        if (StringUtils.isNotEmpty(countyCode)) {
+            return countyCode.substring(countyCode.length()-6);
+        } else {
+            throw new AppException(ErrorCode.TIANDITU_DATA_PARSE_ERROR, "获取行政区代码失败:" + antiGeoCodeResponse.getMsg());
+        }
+    }
+    /**每半小时定时更新全国的气象预警数据;
+     * 存在数据更新不及时,例如地震龙卷飑线等短时强灾害
+     * */
+    @Scheduled(cron = "0 20,50 * * * ?")
+    @PostConstruct
+    public void updateCmaWarning() {
+        updateCmaWarning(null); // 更新全国预警数据
+    }
+
+    /**更新某县区所在省的全部预警数据
+     * @param countyCode 县级行政区代码*/
+    public void updateCmaWarning(String countyCode) {
+        String url = "https://data.cma.cn/dataGis/disasterWarning/getWarningDataByCnty";
+        // 2小时前,24小时后
+        OffsetDateTime startTime = DateTimeUtils.offsetDateTimeToSystemZone(OffsetDateTime.now()).minusHours(2);
+        OffsetDateTime endTime = startTime.plusHours(24);
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd+HH:mm:ss");
+        HashMap<String, String> params = new HashMap<>();
+        params.put("startTime", startTime.format(formatter));
+        params.put("endTime", endTime.format(formatter));
+        params.put("provinceCode", countyCode);
+        log.info("更新预警数据 start:{}", params);
+        try {
+            if (params.get("provinceCode") == null) {
+                warningCache.clear();
+            }
+            String jsonStr = sendGet(url, params);
+            List<CmaWarning> cmaWarningList = JSONUtils.json2list(jsonStr, CmaWarning.class);
+            for (CmaWarning cmaWarning : cmaWarningList) {
+                String countyId = cmaWarning.getAreaId();
+                String dataid = cmaWarning.getDataid();
+                SurfaceWeatherWarning surfaceWeatherWarning = buildSurfaceWeatherWarning(cmaWarning);
+                if (! warningCache.containsKey(countyId)) {
+                    warningCache.put(countyId, new ArrayList<>());
+                }
+                List<SurfaceWeatherWarning> countyCacheList = warningCache.get(countyId);
+                if (countyCacheList.stream().noneMatch(w -> dataid.equals(w.getDataid()))) {
+                    // 该数据未缓存过
+                    warningCache.get(countyId).add(surfaceWeatherWarning);
+                }
+            }
+        } catch (Exception e) {
+            log.error("[中央气象台] 预警信息请求结果处理错误, {}", e.getMessage());
+        }
+        log.info("更新预警数据end");
+    }
+
+    private SurfaceWeatherWarning buildSurfaceWeatherWarning(CmaWarning cmaWarning) {
+        SurfaceWeatherWarning surfaceWeatherWarning = new SurfaceWeatherWarning();
+        surfaceWeatherWarning.setSource(cmaWarning.getSender());
+        surfaceWeatherWarning.setSeverityColor(cmaWarning.getSignallevelcode().toUpperCase());
+        surfaceWeatherWarning.setText(cmaWarning.getIssuecontent());
+        String startTime = cmaWarning.getTime(); // NOTE 2024/7/2: 中央气象台默认使用 GMT+8 北京时
+        if (StringUtils.isNotEmpty(startTime)) {
+            surfaceWeatherWarning.setPubTime(OffsetDateTime.parse(startTime + "+08:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssxxx")).format(Constant.API_TIME_FORMATTER)
+            );
+        }
+        String endTime = cmaWarning.getExpires();
+        if (StringUtils.isNotEmpty(endTime)) {
+            surfaceWeatherWarning.setEndTime(OffsetDateTime.parse(endTime + "+08:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssxxx")).format(Constant.API_TIME_FORMATTER)
+            );
+        }
+        surfaceWeatherWarning.setTypeName(cmaWarning.getCodename());
+        surfaceWeatherWarning.setTitle(String.format("%s发布:%s%s预警", cmaWarning.getSender(), cmaWarning.getCodename(), cmaWarning.getSignallevel()));
+        surfaceWeatherWarning.setDataid(cmaWarning.getDataid());
+        return surfaceWeatherWarning;
+    }
+}
diff --git a/weather-service/src/main/resources/application-weather.yml b/weather-service/src/main/resources/application-weather.yml
index e409048..c3184e6 100644
--- a/weather-service/src/main/resources/application-weather.yml
+++ b/weather-service/src/main/resources/application-weather.yml
@@ -3,7 +3,8 @@ hefeng:
     key: 4df66bb82da04b5bb85624874209fc73
 caiyun:
     key: Tc9tgOYr5jlPPlEw
-
+tianditu:
+    key: 31094f552e1133bc7a82cfea7f03d74a
 # tablestore
 tablestore:
     endpoint: https://gfs-test.cn-hangzhou.ots.aliyuncs.com
diff --git a/weather-service/src/main/resources/application.yml b/weather-service/src/main/resources/application.yml
index 4778567..6e127e4 100644
--- a/weather-service/src/main/resources/application.yml
+++ b/weather-service/src/main/resources/application.yml
@@ -17,7 +17,11 @@ spring:
             auth: true
             enable: true
             required: true
+    task:
+        scheduling:
+            pool:
+                size: 3
 mail:
     send:
         from: shiyi@htsdfp.com
-        to: shiyi@htsdfp.com
\ No newline at end of file
+        to: shiyi@htsdfp.com
diff --git a/weather-service/src/test/java/com/htfp/weather/web/service/surfaceapi/CmaServiceImplTest.java b/weather-service/src/test/java/com/htfp/weather/web/service/surfaceapi/CmaServiceImplTest.java
new file mode 100644
index 0000000..fbec7b6
--- /dev/null
+++ b/weather-service/src/test/java/com/htfp/weather/web/service/surfaceapi/CmaServiceImplTest.java
@@ -0,0 +1,46 @@
+package com.htfp.weather.web.service.surfaceapi;
+
+import com.htfp.weather.web.exception.AppException;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import javax.annotation.Resource;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * @Author : shiyi
+ * @Date : 2024/7/2 16:43
+ * @Description :
+ */
+@SpringBootTest
+class CmaServiceImplTest {
+    @Resource
+    CmaServiceImpl cmaService;
+    @Test
+    void normalTest() throws Exception {
+        String countyIdByLatLon = cmaService.getCountyIdByLatLon(39.9042, 116.4073);
+        Assertions.assertEquals("110101", countyIdByLatLon);
+    }
+    @Test
+    void outOfRange() throws Exception {
+        cmaService.getCountyIdByLatLon(39.9042, 166.4073);
+        Assertions.assertThrows(AppException.class, () -> {
+            cmaService.getCountyIdByLatLon(39.9042, 166.4073);
+        });
+        Assertions.assertThrows(AppException.class, () -> {
+            cmaService.getCountyIdByLatLon(139.9042, 166.4073);
+        });
+    }
+    @Test
+    void updateCmaWarning() throws Exception {
+        cmaService.updateCmaWarning();
+        System.out.println(cmaService.getSurfaceWarningByCounty("310000"));
+    }
+
+    @Test
+    void getWarningByLocation() throws Exception {
+        System.out.println(cmaService.getSurfaceWarning(41.22, 123.07));
+    }
+}
\ No newline at end of file
diff --git a/weather-service/src/test/resources/application-weather.yml b/weather-service/src/test/resources/application-weather.yml
index d73b258..c3184e6 100644
--- a/weather-service/src/test/resources/application-weather.yml
+++ b/weather-service/src/test/resources/application-weather.yml
@@ -3,10 +3,12 @@ hefeng:
     key: 4df66bb82da04b5bb85624874209fc73
 caiyun:
     key: Tc9tgOYr5jlPPlEw
-
+tianditu:
+    key: 31094f552e1133bc7a82cfea7f03d74a
 # tablestore
 tablestore:
     endpoint: https://gfs-test.cn-hangzhou.ots.aliyuncs.com
     accessId: LTAI5tDphvXLfwKJEmVQqrVz
     accessKey: ksioVP1S36PI6plkIIRN4A2xLB94uc
-    instanceName: gfs-test
\ No newline at end of file
+    instanceName: gfs-test
+