AreaService.java 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. package com.skyversation.poiaddr.service;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.skyversation.poiaddr.addquery.AddressQueryEngine;
  6. import com.skyversation.poiaddr.addquery.Constant;
  7. import com.skyversation.poiaddr.bean.AddressResult;
  8. import com.skyversation.poiaddr.bean.GeoJsonBean;
  9. import com.skyversation.poiaddr.bean.Village;
  10. import com.skyversation.poiaddr.bean.Zerenwangluo;
  11. import com.skyversation.poiaddr.util.CoordTransform;
  12. import com.skyversation.poiaddr.util.status.AddressLevel;
  13. import org.geotools.geojson.geom.GeometryJSON;
  14. import org.geotools.geometry.jts.JTSFactoryFinder;
  15. import org.locationtech.jts.geom.Geometry;
  16. import org.locationtech.jts.geom.MultiPolygon;
  17. import org.locationtech.jts.io.ParseException;
  18. import org.locationtech.jts.io.WKTReader;
  19. import org.springframework.beans.factory.annotation.Value;
  20. import org.springframework.core.io.ClassPathResource;
  21. import org.springframework.stereotype.Service;
  22. import javax.annotation.PostConstruct;
  23. import javax.annotation.Resource;
  24. import java.io.*;
  25. import java.nio.charset.StandardCharsets;
  26. import java.util.ArrayList;
  27. import java.util.List;
  28. @Service
  29. public class AreaService {
  30. @Resource
  31. private AddressQueryEngine addressQueryEngine;
  32. private static AreaService instance;
  33. public static AreaService getInstance() {
  34. if (instance == null) {
  35. return new AreaService();
  36. }
  37. return instance;
  38. }
  39. @Value("${app.area}")
  40. private String area;
  41. @Value("${app.town}")
  42. private String town;
  43. WKTReader reader = new WKTReader(JTSFactoryFinder.getGeometryFactory());
  44. List<JSONObject> featureList = new ArrayList<>();
  45. List<Village> propertiList = new ArrayList<>();
  46. List<MultiPolygon> mulPolygonList = new ArrayList<>();
  47. Zerenwangluo zrwl = null;
  48. List<Zerenwangluo.FeaturesDTO> zrwlFeatures = null;
  49. List<Zerenwangluo.FeaturesDTO.AttributesDTO> zrwlProperties = new ArrayList<>();
  50. List<MultiPolygon> zrwlMulPolygonList = new ArrayList<>();
  51. public List<GeoJsonBean> cjPolygonList = new ArrayList<>();
  52. public List<GeoJsonBean> zhGridPolygonList = new ArrayList<>();
  53. public List<GeoJsonBean> wGridPolygonList = new ArrayList<>();
  54. public List<GeoJsonBean> gridPolygonList = new ArrayList<>();
  55. public List<GeoJsonBean> shAllAdministrativeDivisionPolygonList = new ArrayList<>();
  56. public List<GeoJsonBean> shAllToensPolygonList = new ArrayList<>();
  57. @PostConstruct
  58. public void initGeoData() {
  59. System.out.println("<<<<<<<<------AreaService>initGeoData------>>>>>>>>>");
  60. instance = this;
  61. if ("青浦".equals(area)) {
  62. Thread thread1 = new Thread(this::runGeoData);
  63. Thread thread2 = new Thread(this::runZEWLData);
  64. thread1.start();
  65. thread2.start();
  66. try {
  67. // 等待三个线程执行完毕
  68. if ("青浦".equals(area)) {
  69. thread1.join();
  70. thread2.join();
  71. }
  72. } catch (InterruptedException e) {
  73. e.printStackTrace();
  74. }
  75. }
  76. Thread thread3 = new Thread(this::initPolygons);
  77. thread3.start();
  78. try {
  79. thread3.join();
  80. } catch (InterruptedException e) {
  81. e.printStackTrace();
  82. }
  83. // TODO 初始化tableA、tableB
  84. /*testTablesService.testData();*/
  85. Constant.setTowns(town.split("、"));
  86. Constant.setArea(area);
  87. System.out.println("<<<<<<<<------根据配置文件为AREA赋值:" + Constant.getArea());
  88. System.out.println("<<<<<<<<------当前AMAP_CITY_CODE:" + Constant.getAMAP_CITY_CODE());
  89. // TODO 网络连通性测试,可以请求一下测试的市中心地址
  90. try {
  91. System.out.println("<<<<<<<<------开始网络连通性测试");
  92. List<String> addrs = new ArrayList<>();
  93. addrs.add("上海市青浦区馨浦苑西区2号楼1201");
  94. AddressResult addressResult = AddressQueryEngine.getInstance().commonSearchByNameForTest(addrs, AddressLevel.values()[0]);
  95. System.out.println("<<<<<<<<------网络连通性测试结果:" + addressResult);
  96. } catch (Exception e) {
  97. System.err.println("<<<<<<<<------网络连通性测试结果:" + e);
  98. }
  99. // TODO 数据库连接测试,可以查询表数据
  100. /*try {
  101. legalPersonServiceimpl.iterativeProcessing(1, 100, 1);
  102. } catch (Exception e) {
  103. System.err.println("<<<<<<<<------数据库连接测试异常:" + e);
  104. }*/
  105. }
  106. public void initPolygons() {
  107. List<List<GeoJsonBean>> lis = new ArrayList<>();
  108. lis.add(cjPolygonList);
  109. lis.add(wGridPolygonList);
  110. lis.add(gridPolygonList);
  111. lis.add(shAllAdministrativeDivisionPolygonList);
  112. lis.add(shAllToensPolygonList);
  113. lis.add(zhGridPolygonList);
  114. String[] path;
  115. path = new String[]{
  116. "geojson/qp_cunju.geojson",
  117. "geojson/青浦区微网格-wgs84.geojson",
  118. "geojson/责任网格-wgs84.geojson",
  119. "geojson/sh_all_administrative_division.geojson",
  120. "geojson/sh_all_towns.geojson",
  121. "geojson/青浦区综合网格.geojson"};
  122. for (int j = 0; j < path.length; j++) {
  123. BufferedReader reader = null;
  124. try {
  125. // 创建 ClassPathResource 对象,指定静态文件的路径
  126. ClassPathResource resource = new ClassPathResource(path[j]);
  127. // 获取文件的输入流
  128. reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8));
  129. String line;
  130. StringBuilder sb = new StringBuilder();
  131. while ((line = reader.readLine()) != null) {
  132. sb.append(line).append("\r\n");
  133. }
  134. reader.close();
  135. JSONObject json = JSONObject.parseObject(sb.toString());
  136. JSONArray featrues = json.getJSONArray("features");
  137. for (int i = 0; i < featrues.size(); i++) {
  138. JSONObject properties = featrues.getJSONObject(i).getJSONObject("properties");
  139. JSONObject geoJson = new JSONObject();
  140. geoJson.put("type", "MultiPolygon");
  141. geoJson.put("coordinates",
  142. featrues.getJSONObject(i).getJSONObject("geometry").getJSONArray("coordinates"));
  143. GeometryJSON geometryJSON = new GeometryJSON();
  144. MultiPolygon multiPolygon = geometryJSON.readMultiPolygon(geoJson.toJSONString());
  145. GeoJsonBean geoJsonBean = new GeoJsonBean();
  146. if (path[j].contains("cunju")) {
  147. JSONObject resultProp = new JSONObject();
  148. resultProp.put("网格名称", properties.getString("__10"));
  149. resultProp.put("shape_leng", properties.getString("shape__length"));
  150. resultProp.put("范围信息", properties.getString("__8"));
  151. resultProp.put("村居代码", properties.getString("__5"));
  152. resultProp.put("街道代码", properties.getString("__9"));
  153. // resultProp.put("更新时间", properties.getString("__2"));
  154. resultProp.put("shape_area", properties.getString("shape__area"));
  155. resultProp.put("所属区县", properties.getString("__4"));
  156. resultProp.put("所属居委", properties.getString("cjname"));
  157. resultProp.put("所属街道", properties.getString("jz"));
  158. resultProp.put("面积", properties.getString("__1"));
  159. resultProp.put("objectid", properties.getString("objectid"));
  160. geoJsonBean.setProperties(resultProp);
  161. } else if (path[j].contains("微网格")) {
  162. JSONObject resultProp = new JSONObject();
  163. resultProp.put("objectid", properties.getString("OBJECTID"));
  164. resultProp.put("所属街道", properties.getString("æ\u0089\u0080å±\u009Eè¡\u0097"));
  165. resultProp.put("Shape_Leng", properties.getString("Shape_Leng"));
  166. resultProp.put("微格网代码", properties.getString("å¾®ç½\u0091æ ¼"));
  167. resultProp.put("所属区县", properties.getString("æ\u0089\u0080å±\u009Eå\u008Cº"));
  168. resultProp.put("Shape_Area", properties.getString("Shape_Area"));
  169. resultProp.put("微格网名称", properties.getString("å¾®ç½\u0091_1"));
  170. geoJsonBean.setProperties(resultProp);
  171. } else {
  172. geoJsonBean.setProperties(properties);
  173. }
  174. geoJsonBean.setMultiPolygon(multiPolygon);
  175. lis.get(j).add(geoJsonBean);
  176. }
  177. } catch (IOException e) {
  178. e.printStackTrace();
  179. System.out.println("<<<<<<<<------run geo data error------>>>>>>>>>");
  180. }
  181. }
  182. System.out.println("<<<<<<<<------run geo data complete------>>>>>>>>>");
  183. }
  184. public GeoJsonBean isInGridPolygon(double lon, double lat) {
  185. Geometry point = null;
  186. try {
  187. point = reader.read("POINT (" + lon + " " + lat + ")");
  188. } catch (ParseException e) {
  189. throw new RuntimeException(e);
  190. }
  191. for (GeoJsonBean bean : gridPolygonList) {
  192. try {
  193. if (bean.getMultiPolygon().contains(point)) {
  194. return bean;
  195. }
  196. } catch (Exception e) {
  197. }
  198. }
  199. return null;
  200. }
  201. public GeoJsonBean isInWGridPolygon(double lon, double lat) {
  202. Geometry point = null;
  203. try {
  204. point = reader.read("POINT (" + lon + " " + lat + ")");
  205. } catch (ParseException e) {
  206. throw new RuntimeException(e);
  207. }
  208. for (GeoJsonBean bean : wGridPolygonList) {
  209. if (bean.getMultiPolygon().contains(point)) {
  210. return bean;
  211. }
  212. }
  213. return null;
  214. }
  215. public GeoJsonBean isInCJPolygon(double lon, double lat) {
  216. Geometry point = null;
  217. try {
  218. point = reader.read("POINT (" + lon + " " + lat + ")");
  219. } catch (ParseException e) {
  220. throw new RuntimeException(e);
  221. }
  222. for (GeoJsonBean bean : cjPolygonList) {
  223. if (bean.getMultiPolygon().contains(point)) {
  224. return bean;
  225. }
  226. }
  227. return null;
  228. }
  229. public GeoJsonBean isInZhGridPolygon(double lon, double lat) {
  230. Geometry point = null;
  231. try {
  232. point = reader.read("POINT (" + lon + " " + lat + ")");
  233. } catch (ParseException e) {
  234. throw new RuntimeException(e);
  235. }
  236. for (GeoJsonBean bean : zhGridPolygonList) {
  237. if (bean.getMultiPolygon().contains(point)) {
  238. return bean;
  239. }
  240. }
  241. return null;
  242. }
  243. public GeoJsonBean isInadPolygon(double lon, double lat) {
  244. Geometry point = null;
  245. try {
  246. point = reader.read("POINT (" + lon + " " + lat + ")");
  247. } catch (ParseException e) {
  248. throw new RuntimeException(e);
  249. }
  250. for (GeoJsonBean bean : shAllAdministrativeDivisionPolygonList) {
  251. if (bean.getMultiPolygon().contains(point)) {
  252. return bean;
  253. }
  254. }
  255. return null;
  256. }
  257. public GeoJsonBean isInTownPolygon(double lon, double lat) {
  258. Geometry point = null;
  259. try {
  260. point = reader.read("POINT (" + lon + " " + lat + ")");
  261. } catch (ParseException e) {
  262. throw new RuntimeException(e);
  263. }
  264. for (GeoJsonBean bean : shAllToensPolygonList) {
  265. if (bean.getMultiPolygon().contains(point)) {
  266. return bean;
  267. }
  268. }
  269. return null;
  270. }
  271. /**
  272. * 初始化责任网络数据
  273. **/
  274. public void runZEWLData() {
  275. try {
  276. // 创建 ClassPathResource 对象,指定静态文件的路径
  277. ClassPathResource resource = new ClassPathResource("geojson/zerenwangluo.json");
  278. // 获取文件的输入流
  279. BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
  280. String line;
  281. StringBuilder sb = new StringBuilder();
  282. while ((line = reader.readLine()) != null) {
  283. sb.append(line).append("\r\n");
  284. }
  285. reader.close();
  286. zrwl = JSONObject.parseObject(sb.toString(), Zerenwangluo.class);
  287. zrwlFeatures = zrwl.getFeatures();
  288. for (int i = 0; i < zrwlFeatures.size(); i++) {
  289. Zerenwangluo.FeaturesDTO.AttributesDTO attributes = zrwlFeatures.get(i).getAttributes();
  290. zrwlProperties.add(attributes);
  291. Zerenwangluo.FeaturesDTO.GeometryDTO geometry = zrwlFeatures.get(i).getGeometry();
  292. JSONArray coordinates = new JSONArray();
  293. JSONArray coordinates1 = new JSONArray();
  294. for (List<List<Double>> rings : geometry.getRings()) {
  295. JSONArray coordinates2 = new JSONArray();
  296. for (List<Double> ring : rings) {
  297. JSONArray coordinates3 = new JSONArray();
  298. double x = ring.get(0);
  299. double y = ring.get(1);
  300. double[] dou = CoordTransform.getInstance().SH2000ToWGS84(x, y);
  301. coordinates3.add(dou[0]);
  302. coordinates3.add(dou[1]);
  303. coordinates2.add(coordinates3);
  304. }
  305. coordinates1.add(coordinates2);
  306. }
  307. coordinates.add(coordinates1);
  308. JSONObject geoJson = new JSONObject();
  309. geoJson.put("type", "MultiPolygon");
  310. geoJson.put("coordinates", coordinates);
  311. GeometryJSON geometryJSON = new GeometryJSON();
  312. MultiPolygon multiPolygon = geometryJSON.readMultiPolygon(geoJson.toJSONString());
  313. zrwlMulPolygonList.add(multiPolygon);
  314. }
  315. } catch (IOException e) {
  316. e.printStackTrace();
  317. System.out.println("<<<<<<<<------run geo data error------>>>>>>>>>");
  318. } catch (Exception e) {
  319. throw new RuntimeException(e);
  320. }
  321. System.out.println("<<<<<<<<------run geo data complete------>>>>>>>>>");
  322. }
  323. public JSONObject getLiabilityGridByLatlon(double lat, double lon) {
  324. Zerenwangluo.FeaturesDTO.AttributesDTO attribute = null;
  325. try {
  326. Geometry point = reader.read("POINT (" + lon + " " + lat + ")");
  327. boolean done = false;
  328. for (int i = 0; i < zrwlMulPolygonList.size(); i++) {
  329. if (done) {
  330. break;
  331. }
  332. MultiPolygon multiPolygon = zrwlMulPolygonList.get(i);
  333. String wktStr = multiPolygon.toString();
  334. if (wktStr.contains("), (")) {// 如果是多面,则拆分成单面再重新比对
  335. String[] wktStrs = wktStr.split("\\), \\(");
  336. List<MultiPolygon> polygons = new ArrayList<>();
  337. for (int j = 0; j < wktStrs.length; j++) {
  338. if (j == 0) {
  339. MultiPolygon polygon1 = (MultiPolygon) reader.read(wktStrs[0] + ")))");
  340. polygons.add(polygon1);
  341. } else if (j == wktStrs.length - 1) {
  342. MultiPolygon polygon2 = (MultiPolygon) reader.read("MULTIPOLYGON (((" + wktStrs[j]);
  343. polygons.add(polygon2);
  344. } else {
  345. MultiPolygon polygon3 = (MultiPolygon) reader.read("MULTIPOLYGON (((" + wktStrs[j] + ")))");
  346. polygons.add(polygon3);
  347. }
  348. }
  349. for (MultiPolygon polygon : polygons) {
  350. if (polygon.contains(point)) {
  351. attribute = zrwlProperties.get(i);
  352. done = true;
  353. break;
  354. }
  355. }
  356. } else {// 如果是单面,则直接比对
  357. if (multiPolygon.contains(point)) {
  358. attribute = zrwlProperties.get(i);
  359. break;
  360. }
  361. }
  362. }
  363. } catch (Exception e) {
  364. e.printStackTrace();
  365. return null;
  366. }
  367. return JSONObject.parseObject(JSON.toJSONString(attribute));
  368. }
  369. /**
  370. * 初始化村居数据
  371. **/
  372. public void runGeoData() {
  373. try {
  374. // 创建 ClassPathResource 对象,指定静态文件的路径
  375. ClassPathResource resource = new ClassPathResource("geojson/qp_cunju.geojson");
  376. // 获取文件的输入流
  377. BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
  378. String line;
  379. StringBuilder sb = new StringBuilder();
  380. while ((line = reader.readLine()) != null) {
  381. sb.append(line).append("\r\n");
  382. }
  383. reader.close();
  384. JSONObject json = JSONObject.parseObject(sb.toString());
  385. JSONArray features = json.getJSONArray("features");
  386. for (int i = 0; i < features.size(); i++) {
  387. JSONObject feature = features.getJSONObject(i);
  388. JSONObject geometry = feature.getJSONObject("geometry");
  389. GeometryJSON geometryJSON = new GeometryJSON();
  390. MultiPolygon multiPolygon = geometryJSON.readMultiPolygon(geometry.toJSONString());
  391. featureList.add(feature);
  392. propertiList.add(JSONObject.parseObject(feature.getJSONObject("properties").toJSONString(), Village.class));
  393. mulPolygonList.add(multiPolygon);
  394. }
  395. } catch (FileNotFoundException e) {
  396. e.printStackTrace();
  397. System.out.println("<<<<<<<<------run geo data error------>>>>>>>>>");
  398. } catch (IOException e) {
  399. e.printStackTrace();
  400. System.out.println("<<<<<<<<------run geo data error------>>>>>>>>>");
  401. } catch (Exception e) {
  402. e.printStackTrace();
  403. System.out.println("<<<<<<<<------run geo data error------>>>>>>>>>");
  404. }
  405. System.out.println("<<<<<<<<------run geo data complete------>>>>>>>>>");
  406. }
  407. public Village getAreaCodeByLatlon(double lat, double lon) {
  408. Village geoAC = null;
  409. try {
  410. Geometry point = reader.read("POINT (" + lon + " " + lat + ")");
  411. for (int i = 0; i < mulPolygonList.size(); i++) {
  412. if (mulPolygonList.get(i).contains(point)) {
  413. geoAC = propertiList.get(i);
  414. break;
  415. }
  416. }
  417. } catch (Exception e) {
  418. e.printStackTrace();
  419. return null;
  420. }
  421. return geoAC;
  422. }
  423. public List<Village> getAreaCodeByLatlons(JSONArray locations) {
  424. if (locations == null || locations.size() < 1) {
  425. return null;
  426. } else {
  427. List<Village> result = new ArrayList<>();
  428. try {
  429. for (int i = 0; i < locations.size(); i++) {
  430. JSONObject jsonObject = locations.getJSONObject(i);
  431. Village geoAreaCode = getAreaCodeByLatlon(jsonObject.getDouble("lat"), jsonObject.getDouble("lon"));
  432. result.add(geoAreaCode);
  433. }
  434. return result;
  435. } catch (Exception e) {
  436. return null;
  437. }
  438. }
  439. }
  440. }