package com.skyversation.poiaddr.service; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.skyversation.poiaddr.addquery.AddressQueryEngine; import com.skyversation.poiaddr.addquery.Constant; import com.skyversation.poiaddr.bean.AddressResult; import com.skyversation.poiaddr.bean.GeoJsonBean; import com.skyversation.poiaddr.bean.Village; import com.skyversation.poiaddr.bean.Zerenwangluo; import com.skyversation.poiaddr.util.CoordTransform; import com.skyversation.poiaddr.util.status.AddressLevel; import org.geotools.geojson.geom.GeometryJSON; import org.geotools.geometry.jts.JTSFactoryFinder; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.MultiPolygon; import org.locationtech.jts.io.ParseException; import org.locationtech.jts.io.WKTReader; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.io.*; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @Service public class AreaService { @Resource private AddressQueryEngine addressQueryEngine; private static AreaService instance; public static AreaService getInstance() { if (instance == null) { return new AreaService(); } return instance; } @Value("${app.area}") private String area; @Value("${app.town}") private String town; WKTReader reader = new WKTReader(JTSFactoryFinder.getGeometryFactory()); List featureList = new ArrayList<>(); List propertiList = new ArrayList<>(); List mulPolygonList = new ArrayList<>(); Zerenwangluo zrwl = null; List zrwlFeatures = null; List zrwlProperties = new ArrayList<>(); List zrwlMulPolygonList = new ArrayList<>(); public List cjPolygonList = new ArrayList<>(); public List zhGridPolygonList = new ArrayList<>(); public List wGridPolygonList = new ArrayList<>(); public List gridPolygonList = new ArrayList<>(); public List shAllAdministrativeDivisionPolygonList = new ArrayList<>(); public List shAllToensPolygonList = new ArrayList<>(); @PostConstruct public void initGeoData() { System.out.println("<<<<<<<<------AreaService>initGeoData------>>>>>>>>>"); instance = this; if ("青浦".equals(area)) { Thread thread1 = new Thread(this::runGeoData); Thread thread2 = new Thread(this::runZEWLData); thread1.start(); thread2.start(); try { // 等待三个线程执行完毕 if ("青浦".equals(area)) { thread1.join(); thread2.join(); } } catch (InterruptedException e) { e.printStackTrace(); } } Thread thread3 = new Thread(this::initPolygons); thread3.start(); try { thread3.join(); } catch (InterruptedException e) { e.printStackTrace(); } // TODO 初始化tableA、tableB /*testTablesService.testData();*/ Constant.setTowns(town.split("、")); Constant.setArea(area); System.out.println("<<<<<<<<------根据配置文件为AREA赋值:" + Constant.getArea()); System.out.println("<<<<<<<<------当前AMAP_CITY_CODE:" + Constant.getAMAP_CITY_CODE()); // TODO 网络连通性测试,可以请求一下测试的市中心地址 try { System.out.println("<<<<<<<<------开始网络连通性测试"); List addrs = new ArrayList<>(); addrs.add("上海市青浦区馨浦苑西区2号楼1201"); AddressResult addressResult = AddressQueryEngine.getInstance().commonSearchByNameForTest(addrs, AddressLevel.values()[0]); System.out.println("<<<<<<<<------网络连通性测试结果:" + addressResult); } catch (Exception e) { System.err.println("<<<<<<<<------网络连通性测试结果:" + e); } // TODO 数据库连接测试,可以查询表数据 /*try { legalPersonServiceimpl.iterativeProcessing(1, 100, 1); } catch (Exception e) { System.err.println("<<<<<<<<------数据库连接测试异常:" + e); }*/ } public void initPolygons() { List> lis = new ArrayList<>(); lis.add(cjPolygonList); lis.add(wGridPolygonList); lis.add(gridPolygonList); lis.add(shAllAdministrativeDivisionPolygonList); lis.add(shAllToensPolygonList); lis.add(zhGridPolygonList); String[] path; path = new String[]{ "geojson/qp_cunju.geojson", "geojson/青浦区微网格-wgs84.geojson", "geojson/责任网格-wgs84.geojson", "geojson/sh_all_administrative_division.geojson", "geojson/sh_all_towns.geojson", "geojson/青浦区综合网格.geojson"}; for (int j = 0; j < path.length; j++) { BufferedReader reader = null; try { // 创建 ClassPathResource 对象,指定静态文件的路径 ClassPathResource resource = new ClassPathResource(path[j]); // 获取文件的输入流 reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)); String line; StringBuilder sb = new StringBuilder(); while ((line = reader.readLine()) != null) { sb.append(line).append("\r\n"); } reader.close(); JSONObject json = JSONObject.parseObject(sb.toString()); JSONArray featrues = json.getJSONArray("features"); for (int i = 0; i < featrues.size(); i++) { JSONObject properties = featrues.getJSONObject(i).getJSONObject("properties"); JSONObject geoJson = new JSONObject(); geoJson.put("type", "MultiPolygon"); geoJson.put("coordinates", featrues.getJSONObject(i).getJSONObject("geometry").getJSONArray("coordinates")); GeometryJSON geometryJSON = new GeometryJSON(); MultiPolygon multiPolygon = geometryJSON.readMultiPolygon(geoJson.toJSONString()); GeoJsonBean geoJsonBean = new GeoJsonBean(); if (path[j].contains("cunju")) { JSONObject resultProp = new JSONObject(); resultProp.put("网格名称", properties.getString("__10")); resultProp.put("shape_leng", properties.getString("shape__length")); resultProp.put("范围信息", properties.getString("__8")); resultProp.put("村居代码", properties.getString("__5")); resultProp.put("街道代码", properties.getString("__9")); // resultProp.put("更新时间", properties.getString("__2")); resultProp.put("shape_area", properties.getString("shape__area")); resultProp.put("所属区县", properties.getString("__4")); resultProp.put("所属居委", properties.getString("cjname")); resultProp.put("所属街道", properties.getString("jz")); resultProp.put("面积", properties.getString("__1")); resultProp.put("objectid", properties.getString("objectid")); geoJsonBean.setProperties(resultProp); } else if (path[j].contains("微网格")) { JSONObject resultProp = new JSONObject(); resultProp.put("objectid", properties.getString("OBJECTID")); resultProp.put("所属街道", properties.getString("æ\u0089\u0080å±\u009Eè¡\u0097")); resultProp.put("Shape_Leng", properties.getString("Shape_Leng")); resultProp.put("微格网代码", properties.getString("å¾®ç½\u0091æ ¼")); resultProp.put("所属区县", properties.getString("æ\u0089\u0080å±\u009Eå\u008Cº")); resultProp.put("Shape_Area", properties.getString("Shape_Area")); resultProp.put("微格网名称", properties.getString("å¾®ç½\u0091_1")); geoJsonBean.setProperties(resultProp); } else { geoJsonBean.setProperties(properties); } geoJsonBean.setMultiPolygon(multiPolygon); lis.get(j).add(geoJsonBean); } } catch (IOException e) { e.printStackTrace(); System.out.println("<<<<<<<<------run geo data error------>>>>>>>>>"); } } System.out.println("<<<<<<<<------run geo data complete------>>>>>>>>>"); } public GeoJsonBean isInGridPolygon(double lon, double lat) { Geometry point = null; try { point = reader.read("POINT (" + lon + " " + lat + ")"); } catch (ParseException e) { throw new RuntimeException(e); } for (GeoJsonBean bean : gridPolygonList) { try { if (bean.getMultiPolygon().contains(point)) { return bean; } } catch (Exception e) { } } return null; } public GeoJsonBean isInWGridPolygon(double lon, double lat) { Geometry point = null; try { point = reader.read("POINT (" + lon + " " + lat + ")"); } catch (ParseException e) { throw new RuntimeException(e); } for (GeoJsonBean bean : wGridPolygonList) { if (bean.getMultiPolygon().contains(point)) { return bean; } } return null; } public GeoJsonBean isInCJPolygon(double lon, double lat) { Geometry point = null; try { point = reader.read("POINT (" + lon + " " + lat + ")"); } catch (ParseException e) { throw new RuntimeException(e); } for (GeoJsonBean bean : cjPolygonList) { if (bean.getMultiPolygon().contains(point)) { return bean; } } return null; } public GeoJsonBean isInZhGridPolygon(double lon, double lat) { Geometry point = null; try { point = reader.read("POINT (" + lon + " " + lat + ")"); } catch (ParseException e) { throw new RuntimeException(e); } for (GeoJsonBean bean : zhGridPolygonList) { if (bean.getMultiPolygon().contains(point)) { return bean; } } return null; } public GeoJsonBean isInadPolygon(double lon, double lat) { Geometry point = null; try { point = reader.read("POINT (" + lon + " " + lat + ")"); } catch (ParseException e) { throw new RuntimeException(e); } for (GeoJsonBean bean : shAllAdministrativeDivisionPolygonList) { if (bean.getMultiPolygon().contains(point)) { return bean; } } return null; } public GeoJsonBean isInTownPolygon(double lon, double lat) { Geometry point = null; try { point = reader.read("POINT (" + lon + " " + lat + ")"); } catch (ParseException e) { throw new RuntimeException(e); } for (GeoJsonBean bean : shAllToensPolygonList) { if (bean.getMultiPolygon().contains(point)) { return bean; } } return null; } /** * 初始化责任网络数据 **/ public void runZEWLData() { try { // 创建 ClassPathResource 对象,指定静态文件的路径 ClassPathResource resource = new ClassPathResource("geojson/zerenwangluo.json"); // 获取文件的输入流 BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream())); String line; StringBuilder sb = new StringBuilder(); while ((line = reader.readLine()) != null) { sb.append(line).append("\r\n"); } reader.close(); zrwl = JSONObject.parseObject(sb.toString(), Zerenwangluo.class); zrwlFeatures = zrwl.getFeatures(); for (int i = 0; i < zrwlFeatures.size(); i++) { Zerenwangluo.FeaturesDTO.AttributesDTO attributes = zrwlFeatures.get(i).getAttributes(); zrwlProperties.add(attributes); Zerenwangluo.FeaturesDTO.GeometryDTO geometry = zrwlFeatures.get(i).getGeometry(); JSONArray coordinates = new JSONArray(); JSONArray coordinates1 = new JSONArray(); for (List> rings : geometry.getRings()) { JSONArray coordinates2 = new JSONArray(); for (List ring : rings) { JSONArray coordinates3 = new JSONArray(); double x = ring.get(0); double y = ring.get(1); double[] dou = CoordTransform.getInstance().SH2000ToWGS84(x, y); coordinates3.add(dou[0]); coordinates3.add(dou[1]); coordinates2.add(coordinates3); } coordinates1.add(coordinates2); } coordinates.add(coordinates1); JSONObject geoJson = new JSONObject(); geoJson.put("type", "MultiPolygon"); geoJson.put("coordinates", coordinates); GeometryJSON geometryJSON = new GeometryJSON(); MultiPolygon multiPolygon = geometryJSON.readMultiPolygon(geoJson.toJSONString()); zrwlMulPolygonList.add(multiPolygon); } } catch (IOException e) { e.printStackTrace(); System.out.println("<<<<<<<<------run geo data error------>>>>>>>>>"); } catch (Exception e) { throw new RuntimeException(e); } System.out.println("<<<<<<<<------run geo data complete------>>>>>>>>>"); } public JSONObject getLiabilityGridByLatlon(double lat, double lon) { Zerenwangluo.FeaturesDTO.AttributesDTO attribute = null; try { Geometry point = reader.read("POINT (" + lon + " " + lat + ")"); boolean done = false; for (int i = 0; i < zrwlMulPolygonList.size(); i++) { if (done) { break; } MultiPolygon multiPolygon = zrwlMulPolygonList.get(i); String wktStr = multiPolygon.toString(); if (wktStr.contains("), (")) {// 如果是多面,则拆分成单面再重新比对 String[] wktStrs = wktStr.split("\\), \\("); List polygons = new ArrayList<>(); for (int j = 0; j < wktStrs.length; j++) { if (j == 0) { MultiPolygon polygon1 = (MultiPolygon) reader.read(wktStrs[0] + ")))"); polygons.add(polygon1); } else if (j == wktStrs.length - 1) { MultiPolygon polygon2 = (MultiPolygon) reader.read("MULTIPOLYGON (((" + wktStrs[j]); polygons.add(polygon2); } else { MultiPolygon polygon3 = (MultiPolygon) reader.read("MULTIPOLYGON (((" + wktStrs[j] + ")))"); polygons.add(polygon3); } } for (MultiPolygon polygon : polygons) { if (polygon.contains(point)) { attribute = zrwlProperties.get(i); done = true; break; } } } else {// 如果是单面,则直接比对 if (multiPolygon.contains(point)) { attribute = zrwlProperties.get(i); break; } } } } catch (Exception e) { e.printStackTrace(); return null; } return JSONObject.parseObject(JSON.toJSONString(attribute)); } /** * 初始化村居数据 **/ public void runGeoData() { try { // 创建 ClassPathResource 对象,指定静态文件的路径 ClassPathResource resource = new ClassPathResource("geojson/qp_cunju.geojson"); // 获取文件的输入流 BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream())); String line; StringBuilder sb = new StringBuilder(); while ((line = reader.readLine()) != null) { sb.append(line).append("\r\n"); } reader.close(); JSONObject json = JSONObject.parseObject(sb.toString()); JSONArray features = json.getJSONArray("features"); for (int i = 0; i < features.size(); i++) { JSONObject feature = features.getJSONObject(i); JSONObject geometry = feature.getJSONObject("geometry"); GeometryJSON geometryJSON = new GeometryJSON(); MultiPolygon multiPolygon = geometryJSON.readMultiPolygon(geometry.toJSONString()); featureList.add(feature); propertiList.add(JSONObject.parseObject(feature.getJSONObject("properties").toJSONString(), Village.class)); mulPolygonList.add(multiPolygon); } } catch (FileNotFoundException e) { e.printStackTrace(); System.out.println("<<<<<<<<------run geo data error------>>>>>>>>>"); } catch (IOException e) { e.printStackTrace(); System.out.println("<<<<<<<<------run geo data error------>>>>>>>>>"); } catch (Exception e) { e.printStackTrace(); System.out.println("<<<<<<<<------run geo data error------>>>>>>>>>"); } System.out.println("<<<<<<<<------run geo data complete------>>>>>>>>>"); } public Village getAreaCodeByLatlon(double lat, double lon) { Village geoAC = null; try { Geometry point = reader.read("POINT (" + lon + " " + lat + ")"); for (int i = 0; i < mulPolygonList.size(); i++) { if (mulPolygonList.get(i).contains(point)) { geoAC = propertiList.get(i); break; } } } catch (Exception e) { e.printStackTrace(); return null; } return geoAC; } public List getAreaCodeByLatlons(JSONArray locations) { if (locations == null || locations.size() < 1) { return null; } else { List result = new ArrayList<>(); try { for (int i = 0; i < locations.size(); i++) { JSONObject jsonObject = locations.getJSONObject(i); Village geoAreaCode = getAreaCodeByLatlon(jsonObject.getDouble("lat"), jsonObject.getDouble("lon")); result.add(geoAreaCode); } return result; } catch (Exception e) { return null; } } } }