package com.stylefeng.guns.modular.system.util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.stylefeng.guns.core.util.ToolUtil; //import com.stylefeng.guns.modular.system.model.GDFence; //import com.stylefeng.guns.modular.system.service.IGDFenceService; import com.stylefeng.guns.modular.system.service.IGDInterfaceService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; /** * 电子围栏工具类 */ @Component public class GDMapElectricFenceUtil { @Autowired private RestTemplate restTemplate; @Autowired private IGDInterfaceService gdInterfaceService; private String key = "c3e2c90e17d69f793f839aa736d5e8d9"; private JSONArray jsonArray = new JSONArray(); @Bean public ClientHttpRequestFactory simpleClientHttpRequestFactory() { // SimpleClientHttpRequestFactory factory=new SimpleClientHttpRequestFactory(); // 上一行被注释掉的是Spring自己的实现,下面是依赖了httpclient包后的实现 HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); factory.setConnectTimeout(5000); factory.setReadTimeout(5000); return factory; } /** * 创建电子围栏 * @param id * @param points * @return */ public List createFence(String id, String points){ Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 1); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); String format = simpleDateFormat.format(calendar.getTime()); //开始调用高德接口创建围栏 String[] s = points.split("_"); List resoult = new ArrayList<>(); for(int i = 0; i < s.length; i++){ String[] split = s[i].split(";"); JSONObject json = new JSONObject(); json.put("name", id); if(split.length == 2){ json.put("center", split[0]); json.put("radius", split[1]); }else{ json.put("points", s[i]); } json.put("enable", "true"); json.put("valid_time", format); json.put("repeat", "Mon,Tues,Wed,Thur,Fri,Sat,Sun"); json.put("alert_condition", "enter;leave"); json.put("desc", id); HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); HttpEntity formEntity = new HttpEntity<>(json.toString(), headers); String url = "https://restapi.amap.com/v4/geofence/meta?key=" + key; String js = restTemplate.postForObject(url, formEntity, String.class); JSONObject jsonObject = JSON.parseObject(js); JSONObject data = jsonObject.getJSONObject("data"); String status = data.getString("status"); // gdInterfaceService.saveData("https://restapi.amap.com/v4/geofence/meta", "创建电子围栏"); // if(status.equals("0")){//创建成功 // GDFence gdFence = new GDFence(); // gdFence.setGdfenceId(UUIDUtil.getRandomCode()); // gdFence.setGid(data.getString("gid")); // gdFence.setPoints(s[i]); // gdFence.setLineElectricfenceIds(id); // gdFenceService.insert(gdFence); // } // // if(status.equals("106")){//创建点电子围栏已经存在(只有坐标完全相同的电子围栏才会报重复) // try { // GDFence data1 = gdFenceService.getData(s[i]); // int index = data1.getLineElectricfenceIds().indexOf(id); // if(index < 0){ // data1.setLineElectricfenceIds(data1.getLineElectricfenceIds() + "," + id); // gdFenceService.updateById(data1); // } // } catch (Exception e) { // e.printStackTrace(); // } // } // resoult.add(js); } return resoult; } /** * 创建电子围栏 * @param id 围栏名称----绘制的数据id值 * @param points 多边形围栏坐标 */ public List createElectricFenc(String id, String points){ List fence = this.createFence(id, points); List gids = new ArrayList<>(); for(String f : fence){ JSONObject jsonObject = JSON.parseObject(f); JSONObject data = jsonObject.getJSONObject("data"); String status = data.getString("status"); if(status.equals("0")){ gids.add(data.getString("gid")); } } return gids; } /** * 查询以创建的所有电子围栏 */ public String findElectricFenc(String center, String radius, String points){ String url = "https://restapi.amap.com/v4/geofence/meta?key=" + key; String forObject = restTemplate.getForObject(url, String.class); JSONObject jsonObject = JSON.parseObject(forObject); JSONObject data = jsonObject.getJSONObject("data"); // gdInterfaceService.saveData("https://restapi.amap.com/v4/geofence/meta", "查询电子围栏"); if(ToolUtil.isNotEmpty(center)){//圆形电子围栏 JSONArray rs_list = data.getJSONArray("rs_list"); for(int i = 0; i < rs_list.size(); i++){ String c = rs_list.getJSONObject(i).getString("center"); Double r = rs_list.getJSONObject(i).getDouble("radius"); if(c.equals(center) && radius.equals(String.valueOf(r))){ return rs_list.getJSONObject(i).getString("gid"); } } }else{ JSONArray rs_list = data.getJSONArray("rs_list"); for(int i = 0; i < rs_list.size(); i++){ String p = rs_list.getJSONObject(i).getString("points"); if(points.equals(p)){ return rs_list.getJSONObject(i).getString("gid"); } } } return null; } /** * 查询所有绘制好的电子围栏 * @return */ public JSONArray findAllElectricFenc(int page){ if(page == 1){ jsonArray = new JSONArray(); } String url = "https://restapi.amap.com/v4/geofence/meta?key=" + key + "&page_no=" + page + "&page_size=" + 30; String forObject = restTemplate.getForObject(url, String.class); JSONObject jsonObject = JSON.parseObject(forObject); JSONObject data = jsonObject.getJSONObject("data"); JSONArray rs_list = data.getJSONArray("rs_list"); jsonArray.addAll(rs_list); // gdInterfaceService.saveData("https://restapi.amap.com/v4/geofence/meta", "查询电子围栏"); //判断是否有分页 int total_record = data.getIntValue("total_record"); if(total_record > jsonArray.size()){ //有分页,递归调用自己 page++; this.findAllElectricFenc(page); } return jsonArray; } /** * 批量更新电子围栏(失效的数据) * @param jsonArray * @throws ParseException */ public void updateElectricFenc(JSONArray jsonArray) throws ParseException{ //批量更新查询出的失效的电子围栏,围栏失效日期在当前日期之后的数据 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); for(int i = 0; i < jsonArray.size(); i++){ JSONObject jsonObject = jsonArray.getJSONObject(i); Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.set(Calendar.HOUR_OF_DAY, 8); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); long timeInMillis1 = calendar.getTimeInMillis(); String valid_time = jsonObject.getString("valid_time"); Date parse = sdf.parse(valid_time); Calendar cale = Calendar.getInstance(); cale.setTime(parse); cale.set(Calendar.HOUR_OF_DAY, 8); cale.set(Calendar.MINUTE, 0); cale.set(Calendar.SECOND, 0); cale.set(Calendar.MILLISECOND, 0); long timeInMillis = cale.getTimeInMillis(); if(timeInMillis1 >= timeInMillis){ String gid = jsonObject.getString("gid"); String id = jsonObject.getString("name"); String center = jsonObject.getString("center"); String radius = jsonObject.getString("radius"); String points = jsonObject.getString("points"); this.updateElectricFenc(gid, id, center, radius, points); } } } /** * 更新电子围栏 * @param gid * @param id * @param center * @param radius * @param points */ public void updateElectricFenc(String gid, String id, String center, String radius, String points) throws ParseException { Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 1); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); String format = simpleDateFormat.format(calendar.getTime()); //开始调用高德接口创建围栏 JSONObject json = new JSONObject(); json.put("name", id); if(ToolUtil.isNotEmpty(center)){ json.put("center", center); json.put("radius", radius); }else{ json.put("points", points); } json.put("valid_time", format); json.put("repeat", "Mon,Tues,Wed,Thur,Fri,Sat,Sun"); json.put("alert_condition", "enter;leave"); json.put("desc", id + "围栏更新描述"); HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); HttpEntity formEntity = new HttpEntity<>(json.toString(), headers); String url = "https://restapi.amap.com/v4/geofence/meta?key=" + key + "&gid=" + gid; String s = restTemplate.patchForObject(url, formEntity, String.class); System.out.println(s); // gdInterfaceService.saveData("https://restapi.amap.com/v4/geofence/meta", "更新电子围栏"); } /** * 电子围栏监控 * @param diu 设备唯一标识符,作为记录依据,不影响判断结果。Android设备一般使用imei号码,iOS一般使用idfv号,其余设备可根据业务自定义。 * @param locations 数据为坐标数据和坐标产生的时间戳数据,至少包含一个坐标对和时间戳。 * 1、传入1个点时,直接判断交互关系。 * 2、当传入多个点时,可以通过前后时间判断动态交互关系。 * 格式: x1,y1,unix_ts1;x2,y2,unix_ts2 * 动态交互判断方法:第一个点作为当前时间的点,然后从其余点中选出在当前点之前10s~1小时范围内的最早点,用这两个时间点的位置判断设备与围栏的动态交互关系。若数据无效交互关系默认返回leave。 * @return */ public List monitorElectricFenc(String diu, String locations){ if(ToolUtil.isEmpty(diu)){ diu = "B78F99DD-2496-4A43-843B-172CDA2D9798"; } locations = locations + "," + (new Date().getTime() / 1000); String url = "https://restapi.amap.com/v4/geofence/status?key=" + key + "&diu=" + diu + "&locations=" + locations; String forObject = restTemplate.getForObject(url, String.class); JSONObject jsonObject = JSON.parseObject(forObject); List ids = new ArrayList<>(); JSONObject data = jsonObject.getJSONObject("data"); int status = data.getIntValue("status"); if(0 == status){ JSONArray fencingEventList = data.getJSONArray("fencing_event_list"); for(int i = 0; i < fencingEventList.size(); i++){ String clientStatus = fencingEventList.getJSONObject(i).getString("client_status"); if(clientStatus.equals("in")){//包含给定坐标的电子围栏 JSONObject fence_info = fencingEventList.getJSONObject(i).getJSONObject("fence_info");//获取电子围栏信息 String gid = fence_info.getString("fence_gid"); ids.add(gid); } } } System.out.println("检测:" + forObject); // gdInterfaceService.saveData("https://restapi.amap.com/v4/geofence/status", "电子围栏监控"); return ids; } /** * 删除电子围栏 * @param gid * @return */ public boolean deleteElectricFenc(String gid){ restTemplate.delete("https://restapi.amap.com/v4/geofence/meta?key={1}&gid={2}", key, gid); System.out.println("删除:" ); // gdInterfaceService.saveData("https://restapi.amap.com/v4/geofence/meta", "删除电子围栏"); return true; } /** * 获取两点的距离 * @param origins 起点坐标 * @param destination 终点坐标 * @param type 计算类型:0:直线距离 1:驾车导航距离(仅支持国内坐标)。 * @return */ public Map getDistance(String origins, String destination, Integer type){ String url = "https://restapi.amap.com/v3/distance?key=" + key + "&origins=" + origins + "&destination=" + destination + "&type=" + type; String forObject = restTemplate.getForObject(url, String.class); JSONObject jsonObject = JSON.parseObject(forObject); String status = jsonObject.getString("status"); // gdInterfaceService.saveData("https://restapi.amap.com/v3/distance", "查询两点间的距离"); if(status.equals("1")){ JSONArray results = jsonObject.getJSONArray("results"); JSONObject jsonObject1 = results.getJSONObject(0); Map map = new HashMap<>(); map.put("distance", jsonObject1.getString("distance"));//距离(米) map.put("duration", jsonObject1.getString("duration"));//预计时间(秒) return map; }else{ System.err.println(forObject); } return null; } /** * 获取路径规划 * @param origins 起点坐标 * @param destination 终点坐标 * @param waypoints 途经点 * @return */ public Map getDriving(String origins, String destination, String waypoints){ String url = "https://restapi.amap.com/v3/direction/driving?key=" + key + "&origin=" + origins + "&destination=" + destination + "&waypoints=" + waypoints + "&extensions=base&strategy=0"; String forObject = restTemplate.getForObject(url, String.class); JSONObject jsonObject = JSON.parseObject(forObject); String status = jsonObject.getString("status"); // gdInterfaceService.saveData("https://restapi.amap.com/v3/direction/driving", "获取路径规划"); if(status.equals("1")){ JSONObject route = jsonObject.getJSONObject("route"); JSONArray results = route.getJSONArray("paths"); JSONObject jsonObject1 = results.getJSONObject(0); Map map = new HashMap<>(); map.put("distance", jsonObject1.getString("distance"));//距离(米) map.put("duration", jsonObject1.getString("duration"));//预计时间(秒) return map; } return null; } }