package com.stylefeng.guns.modular.crossCity.server.impl; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.baomidou.mybatisplus.service.impl.ServiceImpl; import com.stylefeng.guns.core.util.ToolUtil; import com.stylefeng.guns.modular.crossCity.dao.LocationMapper; import com.stylefeng.guns.modular.crossCity.dao.SiteMapper; import com.stylefeng.guns.modular.crossCity.model.Site; import com.stylefeng.guns.modular.crossCity.server.ISiteService; import com.stylefeng.guns.modular.crossCity.warpper.SiteWarpper; import com.stylefeng.guns.modular.system.util.model.GeoFencingPolygon; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.ObjectProvider; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.geo.GeoJsonPoint; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; @Service public class SiteServiceImpl extends ServiceImpl implements ISiteService { @Resource private SiteMapper siteMapper; @Resource private LocationMapper locationMapper; @Autowired private ObjectProvider mongoTemplateProvider; @Autowired private RestTemplate restTemplate; private static final String AMAP_KEY = "6dd64582ed31b84134ac38b2355eb82b"; /** * 获取站点 * @return * @throws Exception */ @Override public List querySite(Integer startSiteId) throws Exception { List> sites = null; if(null == startSiteId){ sites = siteMapper.querySite(null); }else{ sites = siteMapper.querySite(startSiteId); } Set set = new HashSet<>(); for(Map site : sites) { set.add(site.get("cityCode").toString()); } List list = new ArrayList<>(); for(String c : set){ SiteWarpper siteWarpper = new SiteWarpper(); List data = new ArrayList<>(); String name = ""; String code = ""; for(Map s : sites){ if(c.equals(s.get("cityCode").toString())){ Map map = new HashMap<>(); map.put("id", s.get("id")); map.put("name", s.get("name").toString()); name = s.get("cityName").toString(); code = s.get("cityCode").toString(); data.add(map); } } siteWarpper.setName(name); siteWarpper.setCode(code); siteWarpper.setSites(data); list.add(siteWarpper); } return list; } /** * 判断点是都在区域范围内 * @param siteId * @param code * @param lonLat * @return * @throws Exception */ @Override public boolean areaMonitoring(Integer siteId, Integer code, String lonLat) throws Exception { List> list = this.queryLocation(siteId); String province = code.toString().substring(0, 2) + "0000"; String city = code.toString().substring(0, 4) + "00"; for(Map map : list){ if(Integer.valueOf(map.get("type").toString()) == 1){//行政区域 if(null != map.get("districtCode")){ if(code.toString().equals(map.get("districtCode").toString())){ return true; } continue; } if(null != map.get("cityCode")){ if(city.equals(map.get("cityCode").toString())){ return true; } continue; } if(null != map.get("provinceCode")){ if(province.equals(map.get("provinceCode").toString())){ return true; } continue; } } if(Integer.valueOf(map.get("type").toString()) == 2){//电子围栏 if(matchAreaType2(siteId, lonLat)){ return true; } } } return true; } /** * 根据站点id获取地点区域 * @param siteId * @return * @throws Exception */ @Override public List> queryLocation(Integer siteId) throws Exception { return locationMapper.queryLocation(siteId); } /** * 根据经纬度查询所在站点(命中多个时返回第一个) */ @Override public Site querySiteByLonLat(Double lon, Double lat) throws Exception { if (lon == null || lat == null) { return null; } String adCode = getAdCodeByLonLat(lon, lat); String lonLat = lon + "," + lat; List siteList = this.selectList(new EntityWrapper().eq("state", 1).orderBy("id", true)); if (siteList == null || siteList.size() <= 0) { return null; } for (Site site : siteList) { if (site == null || site.getId() == null) { continue; } List> locations = queryLocation(site.getId()); if (locations == null || locations.size() <= 0) { continue; } if (matchAreaType1(locations, adCode) || matchAreaType2(site.getId(), lonLat)) { return site; } } return null; } private boolean matchAreaType1(List> locations, String adCode) { if (ToolUtil.isEmpty(adCode)) { return false; } if (adCode.length() < 4) { return false; } String province = adCode.substring(0, 2) + "0000"; String city = adCode.substring(0, 4) + "00"; for (Map map : locations) { if (map == null || map.get("type") == null) { continue; } if (Integer.valueOf(map.get("type").toString()) != 1) { continue; } if (map.get("districtCode") != null && adCode.equals(map.get("districtCode").toString())) { return true; } if (map.get("cityCode") != null && city.equals(map.get("cityCode").toString())) { return true; } if (map.get("provinceCode") != null && province.equals(map.get("provinceCode").toString())) { return true; } } return false; } private boolean matchAreaType2(Integer siteId, String lonLat) { MongoTemplate mongoTemplate; try { mongoTemplate = mongoTemplateProvider.getIfAvailable(); } catch (Exception ex) { return false; } if (mongoTemplate == null || ToolUtil.isEmpty(lonLat)) { return false; } String[] split = lonLat.split(","); if (split.length != 2) { return false; } GeoJsonPoint point = new GeoJsonPoint(Double.valueOf(split[0]), Double.valueOf(split[1])); Query query = Query.query(Criteria.where("geoJsonPolygon").intersects(point)); List geoFencingPolygons = mongoTemplate.find(query, GeoFencingPolygon.class); if (geoFencingPolygons == null || geoFencingPolygons.size() <= 0) { return false; } List siteIds = geoFencingPolygons.stream().map(GeoFencingPolygon::getSiteId).collect(Collectors.toList()); return siteIds.contains(siteId); } private String getAdCodeByLonLat(Double lon, Double lat) { try { String location = lon + "," + lat; String url = "https://restapi.amap.com/v3/geocode/regeo?key=" + AMAP_KEY + "&location=" + location; String body = restTemplate.getForObject(url, String.class); if (ToolUtil.isEmpty(body)) { return null; } com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSON.parseObject(body); if (!"1".equals(jsonObject.getString("status"))) { return null; } com.alibaba.fastjson.JSONObject regeocode = jsonObject.getJSONObject("regeocode"); if (regeocode == null) { return null; } com.alibaba.fastjson.JSONObject addressComponent = regeocode.getJSONObject("addressComponent"); if (addressComponent == null) { return null; } return addressComponent.getString("adcode"); } catch (Exception ex) { return null; } } }