예제 #1
0
 private bool OtherDuplicationPOIGroupListHasReference(POIDuplicates duplicates, int poiId, DuplicatePOIGroup currentGroup)
 {
     var mentionedGroups = duplicates.DuplicateSummaryList.Where(d => d.DuplicatePOIList.Any(p => p.DuplicateOfPOI.ID == poiId || p.DuplicatePOI.ID == poiId));
     if (mentionedGroups.Any(m => m != currentGroup))
     {
         //POI has a mention in another group
         return true;
     }
     else
     {
         //POI not mentioned in any other group
         return false;
     }
 }
예제 #2
0
        /// <summary>
        /// Recursive grouping of duplicates into groups, removing unused/redundant groups
        /// </summary>
        /// <param name="duplicates"></param>
        /// <returns></returns>
        private bool RearrangeDuplicates(POIDuplicates duplicates)
        {
            var actionRequired = false;

            var removedgroups = new List<DuplicatePOIGroup>();
            foreach (var dupegroup in duplicates.DuplicateSummaryList)
            {
                var removedDupes = new List<DuplicatePOIItem>();
                foreach (var dupe in dupegroup.DuplicatePOIList)
                {
                    //if dupe variation is identified an another group, remove from this group
                    if (OtherDuplicationPOIGroupListHasReference(duplicates, dupe.DuplicatePOI.ID, dupegroup))
                    {
                        removedDupes.Add(dupe);
                    }
                }

                if (removedDupes.Any())
                {
                    actionRequired = true;
                    //remove all dupes already present in other groups
                    dupegroup.DuplicatePOIList.RemoveAll(d => removedDupes.Contains(d));
                }

                if (!dupegroup.DuplicatePOIList.Any())
                {
                    actionRequired = true;
                    removedgroups.Add(dupegroup);
                }
            }

            if (removedgroups.Any())
            {
                actionRequired = true;
                //remove empty groups
                duplicates.DuplicateSummaryList.RemoveAll(g => removedgroups.Contains(g));
            }

            //did something this pass, recurse to see if more needed
            if (actionRequired) RearrangeDuplicates(duplicates);

            return actionRequired;
        }
예제 #3
0
        public POIDuplicates GetAllPOIDuplicates(POIManager poiManager, int countryId, double maxDupeRange = 500)
        {
            List<DuplicatePOIItem> allDuplicates = new List<DuplicatePOIItem>();

            var dataModel = new OCM.Core.Data.OCMEntities();

            double DUPLICATE_DISTANCE_METERS = 25;
            double POSSIBLE_DUPLICATE_DISTANCE_METERS = maxDupeRange;

            //TODO: better method for large number of POIs
            //grab all live POIs (30-100,000 items)
            //var allPOIs = dataModel.ChargePoints.Where(s => s.AddressInfo.CountryID == countryId && (s.SubmissionStatusTypeID == 100 || s.SubmissionStatusTypeID == 200)).ToList();
            var allPOIs = poiManager.GetChargePoints(new APIRequestParams { CountryIDs = new int[] { countryId }, MaxResults=100000 });

            foreach (var poi in allPOIs)
            {
                //find pois which duplicate the given poi
                var dupePOIs = allPOIs.Where(p => p.ID != poi.ID &&
                    (
                        p.DataProvidersReference != null && p.DataProvidersReference.Length > 0 && p.DataProvidersReference == poi.DataProvidersReference
                        || new System.Device.Location.GeoCoordinate(p.AddressInfo.Latitude, p.AddressInfo.Longitude).GetDistanceTo(new System.Device.Location.GeoCoordinate(poi.AddressInfo.Latitude, poi.AddressInfo.Longitude)) < POSSIBLE_DUPLICATE_DISTANCE_METERS
                    )
                    );

                if (dupePOIs.Any())
                {
                    var poiModel = poi;// OCM.API.Common.Model.Extensions.ChargePoint.FromDataModel(poi, true, true, true, true);

                    foreach (var dupe in dupePOIs)
                    {
                        //poi has duplicates
                        DuplicatePOIItem dupePoi = new DuplicatePOIItem { DuplicatePOI = dupe, DuplicateOfPOI = poiModel };
                        dupePoi.Reasons = new List<string>();
                        if (dupe.AddressInfo.Latitude == poi.AddressInfo.Latitude && dupe.AddressInfo.Longitude == poi.AddressInfo.Longitude)
                        {
                            dupePoi.Reasons.Add("POI location is exact match for OCM-" + poi.ID);
                            dupePoi.Confidence = 95;
                        }
                        else
                        {
                            double distanceMeters = new System.Device.Location.GeoCoordinate(dupe.AddressInfo.Latitude, dupe.AddressInfo.Longitude).GetDistanceTo(new System.Device.Location.GeoCoordinate(poi.AddressInfo.Latitude, poi.AddressInfo.Longitude));
                            if (distanceMeters < DUPLICATE_DISTANCE_METERS)
                            {
                                dupePoi.Reasons.Add("POI location is close proximity (" + distanceMeters + "m) to OCM-" + poi.ID);
                                dupePoi.Confidence = 75;
                            }
                            else
                            {
                                if (distanceMeters < POSSIBLE_DUPLICATE_DISTANCE_METERS)
                                {
                                    dupePoi.Reasons.Add("POI location is in surrounding proximity (" + distanceMeters + "m) to OCM-" + poi.ID);
                                    dupePoi.Confidence = 50;
                                }
                            }
                        }

                        allDuplicates.Add(dupePoi);
                    }
                }
            }

            //arrange all duplicates into groups
            POIDuplicates duplicatesSummary = new POIDuplicates();
            duplicatesSummary.DuplicateSummaryList = new List<DuplicatePOIGroup>();
            foreach (var dupe in allDuplicates)
            {
                bool isNewGroup = false;
                var dupeGroup = duplicatesSummary.DuplicateSummaryList.FirstOrDefault(d => d.DuplicatePOIList.Any(p => p.DuplicateOfPOI.ID == dupe.DuplicateOfPOI.ID || p.DuplicatePOI.ID == dupe.DuplicatePOI.ID) || d.SuggestedBestPOI.ID == dupe.DuplicatePOI.ID);
                if (dupeGroup == null)
                {
                    isNewGroup = true;
                    dupeGroup = new DuplicatePOIGroup();
                    dupeGroup.SuggestedBestPOI = dupe.DuplicatePOI;//TODO: select best

                    dupeGroup.DuplicatePOIList = new List<DuplicatePOIItem>();
                }

                //only add to dupe group if not already added for another reason
                if (!dupeGroup.DuplicatePOIList.Contains(dupe) && !dupeGroup.DuplicatePOIList.Any(d => d.DuplicatePOI.ID == dupe.DuplicatePOI.ID))
                {
                    dupeGroup.DuplicatePOIList.Add(dupe);
                }

                if (isNewGroup)
                {
                    duplicatesSummary.DuplicateSummaryList.Add(dupeGroup);
                }
            }

            //loop through groups and rearrange
            RearrangeDuplicates(duplicatesSummary);

            //go through all groups and populate final list of All POI per group
            foreach (var g in duplicatesSummary.DuplicateSummaryList)
            {
                var poiList = new List<OCM.API.Common.Model.ChargePoint>();
                foreach (var d in g.DuplicatePOIList)
                {
                    if (!poiList.Contains(d.DuplicatePOI))
                    {
                        poiList.Add(d.DuplicatePOI);
                    }

                    if (!poiList.Contains(d.DuplicateOfPOI))
                    {
                        poiList.Add(d.DuplicateOfPOI);
                    }

                    g.AllPOI = poiList;
                }
            }

            //TODO: go through all dupe groups and nominate best poi to be main poi (most comments, most equipment info etc)
            return duplicatesSummary;
        }