AreaService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. package com.skyversation.poiaddr.service;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.skyversation.poiaddr.addquery.AddressQueryEngine;
  5. import com.skyversation.poiaddr.addquery.Constant;
  6. import com.skyversation.poiaddr.bean.AddressResult;
  7. import com.skyversation.poiaddr.bean.GeoJsonBean;
  8. import com.skyversation.poiaddr.entity.*;
  9. import com.skyversation.poiaddr.service.impl.*;
  10. import com.skyversation.poiaddr.util.AddressMatcher;
  11. import org.geotools.geojson.geom.GeometryJSON;
  12. import org.geotools.geometry.jts.JTSFactoryFinder;
  13. import org.locationtech.jts.geom.Geometry;
  14. import org.locationtech.jts.geom.MultiPolygon;
  15. import org.locationtech.jts.io.ParseException;
  16. import org.locationtech.jts.io.WKTReader;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.beans.factory.annotation.Value;
  19. import org.springframework.core.io.ClassPathResource;
  20. import org.springframework.stereotype.Service;
  21. import org.springframework.util.StringUtils;
  22. import javax.annotation.PostConstruct;
  23. import javax.annotation.Resource;
  24. import java.io.*;
  25. import java.util.ArrayList;
  26. import java.util.HashMap;
  27. import java.util.List;
  28. import java.util.Map;
  29. import java.util.concurrent.ConcurrentHashMap;
  30. @Service
  31. public class AreaService {
  32. @Resource
  33. private YyskAddressStandardizationServiceImpl yyskAddressStandardizationService;
  34. @Autowired
  35. private AmapAddressV3Service amapAddressV3Service;
  36. @Autowired
  37. private YyskAddressStandardizationSerice yyskAddressStandardizationSerice;
  38. @Autowired
  39. private FusionKjdlTydzWfSerice fusionKjdlTydzWfSerice;
  40. @Autowired
  41. private YyszAddressQpService yyszAddressQpService;
  42. // 暂存数据库中的所有数据
  43. private Map<String, AmapAddressV3> allAddressData = new ConcurrentHashMap<>();
  44. private static AreaService instance;
  45. public static AreaService getInstance() {
  46. if (instance == null) {
  47. instance = new AreaService();
  48. }
  49. return instance;
  50. }
  51. @Value("${app.area}")
  52. private String area;
  53. @Value("${app.town}")
  54. private String town;
  55. WKTReader reader = new WKTReader(JTSFactoryFinder.getGeometryFactory());
  56. public List<GeoJsonBean> shAllAdministrativeDivisionPolygonList = new ArrayList<>();
  57. public List<GeoJsonBean> shAllToensPolygonList = new ArrayList<>();
  58. public List<GeoJsonBean> shAllResidentialCommitteeList = new ArrayList<>();
  59. @PostConstruct
  60. public void initGeoData() {
  61. System.out.println("<<<<<<<<------AreaService>initGeoData------>>>>>>>>>");
  62. instance = this;
  63. Thread thread3 = new Thread(this::initPolygons);
  64. thread3.start();
  65. try {
  66. thread3.join();
  67. } catch (InterruptedException e) {
  68. e.printStackTrace();
  69. }
  70. // TODO 初始化配置文件变量
  71. Constant.setTowns(town.split(","));
  72. Constant.setArea(area);
  73. System.out.println("<<<<<<<<------根据配置文件为AREA赋值:" + Constant.getArea());
  74. System.out.println("<<<<<<<<------当前AMAP_CITY_CODE:" + Constant.getAMAP_CITY_CODE());
  75. // TODO 数据库连通性测试
  76. /*try {
  77. long startTime = System.currentTimeMillis();
  78. System.out.println("<<<<<<<<------开始数据库连通性测试");
  79. List<AmapAddressV3> amapAddressV3List = amapAddressV3Service.getAllData();
  80. long endTime = System.currentTimeMillis();
  81. System.out.println(">>>>>>>>------数据库连通性测试完成!用时" + (endTime - startTime) / 1000 + "秒!当前数据库数据条数:" + amapAddressV3List.size());
  82. System.out.println("<<<<<<<<------开始缓存数据库数据");
  83. for (AmapAddressV3 amapAddressV3 : amapAddressV3List) {
  84. if(amapAddressV3 != null && amapAddressV3.getAddress() != null){
  85. allAddressData.put(amapAddressV3.getAddress(), amapAddressV3);
  86. }
  87. }
  88. amapAddressV3List.clear();
  89. System.out.println(">>>>>>>>------缓存数据库数据完成!allAddressData.size()=" + allAddressData.size());
  90. } catch (Exception e) {
  91. e.printStackTrace();
  92. System.err.println(">>>>>>>>------数据库连通性测试结果:" + e);
  93. }*/
  94. // TODO 网络连通性测试,可以请求一下测试的市中心地址
  95. /*try {
  96. System.out.println("电脑最大线程数:" + Runtime.getRuntime().availableProcessors());
  97. System.out.println("<<<<<<<<------开始网络连通性测试");
  98. long startTime = System.currentTimeMillis();
  99. List<String> addrs = new ArrayList<>();
  100. addrs.add("上海市松江区乐都路339号");
  101. AddressResult addressResult = AddressQueryEngine.getInstance().commonSearchByName(addrs);
  102. long endTime = System.currentTimeMillis();
  103. System.out.println(">>>>>>>>------网络连通性测试完成!用时" + (endTime - startTime) / 1000 + "秒!结果:" + addressResult);
  104. } catch (Exception e) {
  105. e.printStackTrace();
  106. System.err.println(">>>>>>>>------网络连通性测试结果:" + e);
  107. }*/
  108. }
  109. public void initPolygons() {
  110. List<List<GeoJsonBean>> lis = new ArrayList<>();
  111. lis.add(shAllAdministrativeDivisionPolygonList);
  112. lis.add(shAllToensPolygonList);
  113. lis.add(shAllResidentialCommitteeList);
  114. String[] path = new String[]{"geojson/上海市_区县边界.geojson", "geojson/上海市_乡镇边界.geojson", "geojson/上海市_村居边界.geojson"};
  115. for (int j = 0; j < path.length; j++) {
  116. BufferedReader reader = null;
  117. try {
  118. // 创建 ClassPathResource 对象,指定静态文件的路径
  119. ClassPathResource resource = new ClassPathResource(path[j]);
  120. // 获取文件的输入流
  121. reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
  122. String line;
  123. StringBuilder sb = new StringBuilder();
  124. while ((line = reader.readLine()) != null) {
  125. sb.append(line).append("\r\n");
  126. }
  127. reader.close();
  128. JSONObject json = JSONObject.parseObject(sb.toString());
  129. JSONArray featrues = json.getJSONArray("features");
  130. for (int i = 0; i < featrues.size(); i++) {
  131. JSONObject properties = featrues.getJSONObject(i).getJSONObject("properties");
  132. JSONObject geoJson = new JSONObject();
  133. geoJson.put("type", "MultiPolygon");
  134. geoJson.put("coordinates",
  135. featrues.getJSONObject(i).getJSONObject("geometry").getJSONArray("coordinates"));
  136. GeometryJSON geometryJSON = new GeometryJSON();
  137. MultiPolygon multiPolygon = geometryJSON.readMultiPolygon(geoJson.toJSONString());
  138. GeoJsonBean geoJsonBean = new GeoJsonBean();
  139. geoJsonBean.setProperties(properties);
  140. geoJsonBean.setMultiPolygon(multiPolygon);
  141. lis.get(j).add(geoJsonBean);
  142. }
  143. } catch (IOException e) {
  144. e.printStackTrace();
  145. System.out.println("<<<<<<<<------run geo data error------>>>>>>>>>");
  146. }
  147. }
  148. System.out.println("<<<<<<<<------run geo data complete------>>>>>>>>>");
  149. }
  150. public void saveAmapAddressV3(List<AmapAddressV3> amapAddressV3List) {
  151. List<AmapAddressV3> amapAddressV3SaveList = new ArrayList<>();
  152. for (AmapAddressV3 amapAddressV3 : amapAddressV3List) {
  153. if (!allAddressData.containsKey(amapAddressV3.getAddress())) {
  154. allAddressData.put(amapAddressV3.getAddress(), amapAddressV3);
  155. amapAddressV3SaveList.add(amapAddressV3);
  156. }
  157. }
  158. amapAddressV3List.clear();
  159. if (amapAddressV3SaveList.size() > 0) {
  160. amapAddressV3Service.saveAmapAddressV3(amapAddressV3SaveList);
  161. amapAddressV3List.clear();
  162. }
  163. }
  164. public void saveYyskAddress(List<YyskDmdzAddressStandardization> datas) {
  165. yyskAddressStandardizationSerice.saveDatas(datas);
  166. datas.clear();
  167. }
  168. public void saveFktws(List<FusionKjdlTydzWf> datas){
  169. fusionKjdlTydzWfSerice.saveDatas(datas);
  170. datas.clear();
  171. }
  172. public List<YyszAddressQp> getAddressPoisByAddr(String addr) {
  173. /*List<YyszAddressQp> resultData = new ArrayList<>();
  174. String[] strs = AddressMatcher.matchProvinceAndCity(addr);
  175. if (strs != null) {
  176. for (String str : strs) {
  177. if (StringUtils.hasText(str)) {
  178. addr = addr.replace(str, "");
  179. }
  180. }
  181. }
  182. if (addr.contains("号")) {
  183. addr = addr.substring(0, addr.lastIndexOf("号"));// 红宝石50号 红宝石50 返回 红宝石503弄
  184. }
  185. if (addr.contains("弄")) {
  186. addr = addr.substring(0, addr.lastIndexOf("弄"));
  187. }
  188. if (allAddressData.containsKey(addr)) {
  189. resultData.add(allAddressData.get(addr));
  190. return resultData;
  191. } else {
  192. int sumSize = 100;
  193. for (String address : allAddressData.keySet()) {
  194. if (address != null && address.contains(addr) && sumSize > 0) {
  195. sumSize--;
  196. resultData.add(allAddressData.get(address));
  197. }
  198. }
  199. }
  200. return resultData;*/
  201. // TODO 使用缓存替换数据库查询
  202. // System.out.println("<<<<<<<----- 开始数据库查询,数据查询地址为:" + addr);
  203. return yyszAddressQpService.getAddressPoisByAddr(addr);
  204. }
  205. public GeoJsonBean isInadPolygon(double lon, double lat) {
  206. try {
  207. Geometry point = reader.read("POINT (" + lon + " " + lat + ")");
  208. for (GeoJsonBean bean : shAllAdministrativeDivisionPolygonList) {
  209. if (bean.getMultiPolygon().contains(point)) {
  210. return bean;
  211. }
  212. }
  213. return null;
  214. } catch (ParseException e) {
  215. throw new RuntimeException(e);
  216. }
  217. }
  218. public GeoJsonBean isInTownPolygon(double lon, double lat) {
  219. try {
  220. Geometry point = reader.read("POINT (" + lon + " " + lat + ")");
  221. for (GeoJsonBean bean : shAllToensPolygonList) {
  222. if (bean.getMultiPolygon().contains(point)) {
  223. return bean;
  224. }
  225. }
  226. return null;
  227. } catch (ParseException e) {
  228. throw new RuntimeException(e);
  229. }
  230. }
  231. public GeoJsonBean isInResidentialCommitteePolygon(double lon, double lat) {
  232. try {
  233. Geometry point = reader.read("POINT (" + lon + " " + lat + ")");
  234. for (GeoJsonBean bean : shAllResidentialCommitteeList) {
  235. if (bean.getMultiPolygon().contains(point)) {
  236. return bean;
  237. }
  238. }
  239. return null;
  240. } catch (ParseException e) {
  241. throw new RuntimeException(e);
  242. }
  243. }
  244. }