cccreator / GIS

Gis releated
1 stars 0 forks source link

Get Data From Cache And Bus Cluster Algorithm #8

Open cccreator opened 5 years ago

cccreator commented 5 years ago

缓存取数据

    public List getRealDataInfoByCarNo(String carNo){
        Map<String, BusGpsMessage> busGPSDataCache;
        busGPSDataCache = BusRealDataCacheService.getBusGPSDataCache();
        Map<String, BusClusterData> busClusterDataMap = new ConcurrentHashMap<String, BusClusterData>(); //productID,busClusterData
        List<BusClusterData> listClusterResult = new ArrayList<BusClusterData>();
        Set<String> set = busGPSDataCache.keySet();

        /*使用迭代器*/
        Iterator itor = set.iterator();
        String keyCar;
        while (itor.hasNext()) {
            keyCar = (String) itor.next();
            BusClusterData busClusterData = new BusClusterData();
            /*根据缓存中的key值,获取对应得实体类*/
            BusGpsMessage busGpsMsg = busGPSDataCache.get(keyCar);
            String str = busGpsMsg.getBusCardNo();
            if(carNo.contains(busGpsMsg.getBusCardNo()) && !str.equals("")) {
                busClusterData.setRouteName(busGpsMsg.getRouteName());
                busClusterData.setRouteID(busGpsMsg.getRouteID());
                busClusterData.setSubRouteID(busGpsMsg.getSubRouteID());
                busClusterData.setLongitude((double)Math.round(busGpsMsg.getLongitude()*1000000)/1000000);
                busClusterData.setLatitude((double)Math.round(busGpsMsg.getLatitude()*1000000)/1000000);
                if(busGpsMsg.getSequenceType() == 4){
                    busClusterData.setDirectionName("上行 ");
                }else if(busGpsMsg.getSequenceType() == 5){
                    busClusterData.setDirectionName("下行");
                }else if(busGpsMsg.getSequenceType() == 6){
                    busClusterData.setDirectionName("环行");
                }
                try {
                    busClusterDataMap.put(busGpsMsg.getProductID(),busClusterData);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
        Set<String> setCluster = busClusterDataMap.keySet();
        Iterator itorCluster = setCluster.iterator();
        String keyCluster;
        List<BusClusterData> listCluster = new ArrayList<BusClusterData>();
        while (itorCluster.hasNext()){
            BusClusterData busClusterData1;
            keyCluster = (String)itorCluster.next();
            busClusterData1 = busClusterDataMap.get(keyCluster);
            listCluster.add(busClusterData1);
        }
        return listCluster;
    }

Set<String> set = busGPSDataCache.keySet()用来获取getBusGPSDataCache返回Map数据类型的key值并放在一个Set对象集合里面; 使用迭代器来遍历这个集合 Iterator itor = set.iterator();keyCar = (String)itor.next();获取Map第n次key值,通过返回缓存对象busGPSDataCache.get(keyCar)得到缓存中某一辆车的信息,将其赋值给实体类BusGpsMessage; 通过实体类BusGpsMessage的get方法获取每个元素,将每个元素通过聚合实体类BusClusterData,封装进Map中,keyproductID; 将这个map的每个value值放进一个List中;

cccreator commented 5 years ago

聚合算法

    public List getBusClusterData(String carNo, String[] routeIds, String orgName, Double xmax, Double xmin, Double ymax, Double ymin, Double rangeFactor, Boolean isConverge, Boolean isMoved, String directionName) {

        Map<String, BusGpsMessage> busGPSDataCache;
        busGPSDataCache = BusRealDataCacheService.getBusGPSDataCache();
        Map<String, BusArrLeftMessage> busArrLeftDataCache;
        busArrLeftDataCache = BusRealDataCacheService.getBusArrLevDataCache();
        Map<String, List<Double>> routeAvgSpeed = new LinkedHashMap<String, List<Double>>();
        Map<String, PassengerInformationMessage> passengerData = BusRealDataCacheService.getPassengerInformationCache();  //gisMonitorDao.getPassengerData();
        Map<String, BusClusterData> busClusterDataMap = new ConcurrentHashMap<String, BusClusterData>(); //productID,busClusterData
        List<BusClusterData> listClusterResult = new ArrayList<BusClusterData>();
        Set<String> set = busGPSDataCache.keySet();
        List<CompanyInfo> listUserCompany = UserUtils.getFZCompanyList();//用户拥有的组织权限
        List<String> listUserOrgName = new ArrayList<>();
        DecimalFormat dcmFmtLat = new DecimalFormat("#.000000");
        for (int i = 0; i < listUserCompany.size(); i++) {
            listUserOrgName.add(listUserCompany.get(i).getOrgName());
        }

        /*使用迭代器*/
        Iterator itor = set.iterator();
        Iterator itor_1 = set.iterator();
        DecimalFormat dcmFmt = new DecimalFormat("#.0000");

        String key;
        String keyRoute;
        Double aggRange = 0.0;
        if (isConverge) {
            aggRange = rangeFactor;
        }
        Set<String> routeSet = new HashSet<String>();
        Integer routePassengers = new Integer(0);
        //定义聚合的时间戳
        Date dt = new Date();
        List<String> orgIdList = gisMonitorDao.getSubOrg(orgName);

        int max = 100;
        int min = 0;

         while (itor_1.hasNext()) {
            keyRoute = (String) itor_1.next();
            /*根据缓存中的key值,获取对应得实体类*/
            BusGpsMessage busGpsMsg = busGPSDataCache.get(keyRoute);
            if (!busGpsMsg.getRouteID().isEmpty() && !routeAvgSpeed.containsKey(busGpsMsg.getRouteID())) {
                List<Double> list = new ArrayList<Double>();
                list.add(busGpsMsg.getSpeed());
                routeAvgSpeed.put(busGpsMsg.getRouteID(), list);
            } else if (!busGpsMsg.getRouteID().isEmpty() && routeAvgSpeed.containsKey(busGpsMsg.getRouteID())) {
                routeAvgSpeed.get(busGpsMsg.getRouteID()).add(busGpsMsg.getSpeed());
            }
        }
        /*while循环,如果还有下一个数据就一直执行*/
        while (itor.hasNext()) {
            key = (String) itor.next();
            /*根据缓存中的key值,获取对应得实体类*/
            BusGpsMessage busGpsMsg = busGPSDataCache.get(key);
            BusClusterData busClusterData = new BusClusterData();

            if (StringUtil.isNotEmpty(busGpsMsg.getProductID())) {
/*
                if (Constants.CITYNAME_FZ.equals(propertiesUtil.getCityName())) {
*/
                //如果选择了总组织,那么判断用户所拥有的组织权限
                if (orgName.equals("") || orgName.equals(propertiesUtil.getFullCityName())) {
                    if (busGpsMsg.getOrgName().equals("")) {
                        continue;
                    }
                    if (!listUserOrgName.contains(busGpsMsg.getOrgName())) {
                        continue;
                    }
                } else {
                    if (!orgIdList.contains(busGpsMsg.getOrgId())) {
                        continue;
                    }
                }
                /*}*/
                busClusterData.setRouteName(busGpsMsg.getRouteName());
                busClusterData.setFuelType(busGpsMsg.getFuelType());
                busClusterData.setBusGrade(busGpsMsg.getBusGrade());
                /*将获取的实体类放入一个list集合中*/
                busClusterData.setAngle(busGpsMsg.getAngle());
                busClusterData.setAvgSpeed(busGpsMsg.getAvgSpeed());
                busClusterData.setBusCardNo(busGpsMsg.getBusCardNo());
                busClusterData.setBusCount(1);
                //busClusterData.setCameraCodeArray(busGpsMsg.getCameraCodeArray());
                busClusterData.setBusId(busGpsMsg.getBusId());
                busClusterData.setHeight(busGpsMsg.getHeight());
                //保留6位小数
                busClusterData.setLatitude((double) Math.round(busGpsMsg.getLatitude() * 1000000) / 1000000);
                busClusterData.setLongitude((double) Math.round(busGpsMsg.getLongitude() * 1000000) / 1000000);
                busClusterData.setMileage(busGpsMsg.getMileage());
                busClusterData.setOrgName(busGpsMsg.getOrgName());
                busClusterData.setProductID(busGpsMsg.getProductID());
                busClusterData.setRouteID(busGpsMsg.getRouteID());
                busClusterData.setSubRouteID(busGpsMsg.getSubRouteID());
                busClusterData.setSequenceType(busGpsMsg.getSequenceType());
                busClusterData.setSpeed(new BigDecimal(busGpsMsg.getSpeed()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                busClusterData.setActTime(busGpsMsg.getMsgTime());
                busClusterData.setPassengers(busGpsMsg.getPassengers());
                busClusterData.setParentOrgName(busGpsMsg.getParentOrgName());
                busClusterData.setIsMoved(busGpsMsg.getMoved());
                busClusterData.setClusterDate(DateUtil.datetime2Str(dt));
                //设置单辆车的图标
                String routeIcon = MapCacheManager.cacheMapRouteIcon.get(busGpsMsg.getRouteID());
                busClusterData.setBusIcon(routeIcon == null ? "" : routeIcon.split(",")[0]);

                if (routeAvgSpeed.get(busGpsMsg.getRouteID()) != null && routeAvgSpeed.get(busGpsMsg.getRouteID()).size() > 0) {
                    Double sum = 0.0;
                    for (int i = 0; i < routeAvgSpeed.get(busGpsMsg.getRouteID()).size(); i++) {
                        sum = routeAvgSpeed.get(busGpsMsg.getRouteID()).get(i) + sum;
                    }
                    busClusterData.setRouteAvgSpeed(Double.parseDouble(dcmFmt.format(sum / routeAvgSpeed.get(busGpsMsg.getRouteID()).size())));
                } else {
                    busClusterData.setRouteAvgSpeed(0.0);
                }
                if (busArrLeftDataCache.containsKey(busGpsMsg.getProductID())) {
                    busClusterData.setStationTime(busArrLeftDataCache.get(busGpsMsg.getProductID()).getMsgTime());
                }
                if (busGpsMsg.getSequenceType() == 4) {
                    busClusterData.setDirectionName("上行");
                } else if (busGpsMsg.getSequenceType() == 5) {
                    busClusterData.setDirectionName("下行");
                } else if (busGpsMsg.getSequenceType() == 6) {
                    busClusterData.setDirectionName("环行");
                }
                try {
                    if (!"".equals(directionName)) {
                        if (directionName.equals(busClusterData.getDirectionName())) {
                            busClusterDataMap.put(busClusterData.getProductID(), busClusterData);
                        }
                    } else {
                        busClusterDataMap.put(busClusterData.getProductID(), busClusterData);
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }

            }
        }

        Set<String> setCluster = busClusterDataMap.keySet();
        /*使用迭代器*/
        Iterator itorCluster = setCluster.iterator();

        String keyCluster;
        List<BusClusterData> listCluster = new ArrayList<BusClusterData>();
        /*while循环,如果还有下一个数据就一直执行*/
        //得到listCluster值
        while (itorCluster.hasNext()) {
            BusClusterData busClusterData1;
            keyCluster = (String) itorCluster.next();
            /*根据缓存中的key值,获取对应得实体类*/
            busClusterData1 = busClusterDataMap.get(keyCluster);
            listCluster.add(busClusterData1);
        }
        //线路id不为空,不聚合车辆,只显示车辆选中线路的车辆
        if (routeIds.length > 0) {
            for (int i = 0; i < routeIds.length; i++) {
                routeSet.add(routeIds[i]);
            }
            for (Map.Entry me : passengerData.entrySet()) {
                PassengerInformationMessage pi = (PassengerInformationMessage) me.getValue();
                if (routeSet.contains(pi.getRouteID())) {
                    routePassengers += pi.getTotalPassengerFlow();
                }
            }
            for (int m = 0; m < listCluster.size(); m++) {
                if (listCluster.get(m) != null && routeSet.contains(listCluster.get(m).getRouteID())) {
                    Double px0 = listCluster.get(m).getLongitude(); //经
                    Double py0 = listCluster.get(m).getLatitude(); //纬
                    //判断车辆地图内
                    if (px0 < xmax && px0 > xmin && py0 < ymax && py0 > ymin) {
                        listClusterResult.add(listCluster.get(m));
                    }
                }
            }
            if (isMoved) {
                for (int i = 0; i < listClusterResult.size(); i++) {
                    try {
                        BusClusterData busClusterData = listClusterResult.get(i);
                        if (busClusterData.getIsMoved() != null && !busClusterData.getIsMoved()) {
                            listClusterResult.remove(busClusterData);
                        }
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                }
            }
            return listClusterResult;
        }
        //线路Id为空,聚合所有的车辆
        List car = new ArrayList();
        car.add(carNo);
        //循环使每一辆车作为聚合焦点的车辆
        for (int m = 0; m < listCluster.size(); m++) {
            if (listCluster.get(m) != null) {
                String carno1 = listCluster.get(m).getBusCardNo(); //车辆属性:车牌号
                //如果该车不存在于已被聚合的车辆数组中
                if (car.indexOf(carno1) == -1) {
                    Double lat = listCluster.get(m).getLongitude();
                    Double lon = listCluster.get(m).getLatitude();

                    //设置聚合范围
                    Double spxmin = lat - aggRange;
                    Double spxmax = lat + aggRange;
                    Double spymin = lon - aggRange;
                    Double spymax = lon + aggRange;
                    //车的数量默认是1,不存在同一个经纬度,存在两辆车的问题。因为车是根据图层上已经标好的车来算的,放到数组里。每个车都有唯一的下标。
                    int count = listCluster.get(m).getBusCount(); //车辆属性:车量数
                    //int passengers = listCluster.get(m).getPassengers(); //车辆属性:车量数
                    //遍历图层上所有车辆;
                    for (int n = 0; n < listCluster.size(); n++) {
                        if (listCluster.get(n) != null) {
                            String carno = listCluster.get(n).getBusCardNo(); //车辆属性:车牌号
                            int count1 = listCluster.get(n).getBusCount(); //车辆属性:数量
                            //int passengers1 = listCluster.get(n).getPassengers(); //车辆属性:数量
                            Double px0 = listCluster.get(n).getLongitude(); //经
                            Double py0 = listCluster.get(n).getLatitude(); //纬

                            //判断车辆是否在聚合范围内,不包含聚合焦点车辆,不包含视野外车辆
                            if (px0 < spxmax && px0 > spxmin && py0 < spymax && py0 > spymin && n != m &&
                                    px0 < xmax && px0 > xmin && py0 < ymax && py0 > ymin) {
                                //如果聚合数组中不存在聚合范围内的车辆
                                if (car.indexOf(carno) == -1) {
                                    count = count + count1; //范围内的车辆的数量相加
                                    ///passengers = passengers + passengers1; //范围内的车辆的数量相加
                                    car.add(carno); //把聚合焦点车辆范围内的车辆放入聚合车辆数组中
                                    listCluster.set(n, null); //设置聚合焦点车辆属性的数量值
                                }
                            }
                        }
                    }
                    listCluster.get(m).setBusCount(count); //设置聚合焦点车辆属性的数量值
                    if (count > 1) {
                        String routeIcon = MapCacheManager.cacheMapRouteIcon.get(listCluster.get(m).getRouteID());
                        listCluster.get(m).setBusIcon(routeIcon == null ? "" : routeIcon.split(",")[1]);
                    }
                }
            }
        }

        for (int l = 0; l < listCluster.size(); l++) {
            if (listCluster.get(l) != null) {
                listClusterResult.add(listCluster.get(l));
            }
        }
        if (isMoved) {
            for (int i = 0; i < listClusterResult.size(); i++) {
                try {
                    BusClusterData busClusterData = listClusterResult.get(i);
                    if (busClusterData.getIsMoved() != null && !busClusterData.getIsMoved()) {
                        listClusterResult.remove(busClusterData);
                    }
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
            }
        }

        return listClusterResult;
    }

聚合里面当routeid为空时,通过经纬度范围聚合所有车辆

cccreator commented 5 years ago

缓存

使用ConcurrentHashMap