Example #1
0
        public async Task When_fetching_overview_for_routes_the_parameters_passed_correctly()
        {
            // Arrange
            var group = new MooiCluster
            {
                Placemarks =
                {
                    new MooiPlacemark {
                        Coordinates = new []{
                            new GeoCoordinate(1.11, 2.22), new GeoCoordinate(4.22, 3.11)
                        }
                    },
                    new MooiPlacemark {
                        Coordinates = new []{
                            new GeoCoordinate(5.66, 6.55)
                        }
                    }
                }
            };
            var bytesToMatch = SetupWebClient(uri => uri.AbsoluteUri.StartsWith(HereAdapter.IMAGES_ROUTE_URL),
                                              p => p.Contains($"&{HereAdapter.IMAGES_ROUTE_ROUTE_PARAM_NAME}=1.11,2.22,4.22,3.11") &&
                                              p.Contains($"&{HereAdapter.IMAGES_ROUTE_POINT_PARAM_NAME}=5.66,6.55"));

            // Act
            var bytes = await _here.Object.FetchOverviewMap(group);

            // Verify
            CollectionAssert.AreEqual(bytesToMatch, bytes);
        }
Example #2
0
 private IEnumerable <double> CalculateDistances(MooiCluster cluster1, MooiCluster cluster2)
 {
     return(from pm1 in cluster2.Placemarks
            from pm2 in cluster1.Placemarks
            where pm1 != pm2
            select _kmlCalculator.GetDistanceInMeters(pm1, pm2));
 }
Example #3
0
        public async Task When_fetching_images_the_progress_is_being_updated_and_images_downloaded()
        {
            // Arrange
            var placemark = new MooiPlacemark();
            var group     = new MooiCluster {
                Placemarks = { placemark }
            };
            var document = new MooiDocument {
                Sections = { new MooiSection {
                                 Clusters =  { group}
                             } }
            };
            var tempPath       = "temp-path";
            var overviewBytes  = new byte[] { 0x22 };
            var thumbnailBytes = new byte[] { 0x44 };

            _resourceNameMock.Setup(x => x.CreateFileNameForOverviewMap(group)).Returns("overview-path");
            _resourceNameMock.Setup(x => x.CreateFileNameForPlacemarkThumbnail(placemark)).Returns("thumb-path");
            _hereMock.Setup(x => x.FetchOverviewMap(group))
            .Returns(Task.FromResult(overviewBytes));
            _hereMock.Setup(x => x.FetchThumbnail(placemark))
            .Returns(Task.FromResult(thumbnailBytes));

            // Act
            await _fetcher.Object.FetchMapImages(document, tempPath, _progressMock.Object);

            // Verify
            _fileMock.Verify(x => x.WriteBytesAsync(tempPath + @"\overview-path", overviewBytes));
            _fileMock.Verify(x => x.WriteBytesAsync(tempPath + @"\thumb-path", thumbnailBytes));
            _progressMock.Verify(x => x.ReportFetchImagesCount(1 + 1), Times.Once);
            _progressMock.Verify(x => x.ReportFetchImageProcessed(), Times.Exactly(2));
        }
Example #4
0
        public async Task <byte[]> FetchOverviewMap(MooiCluster cluster)
        {
            var baseUrl = cluster.Type == ClusterType.Routes ? IMAGES_ROUTE_URL : IMAGES_MAPVIEW_URL;

            baseUrl = $"{baseUrl}w={OVERVIEW_MAP_WIDTH}&h={OVERVIEW_MAP_HEIGHT}&sb=k&ppi=250";

            var parameters = string.Empty;

            if (cluster.Type == ClusterType.Routes)
            {
                var route       = GetAndTrimRouteCoordinates(cluster);
                var routeCoords = _formatter.FormatCoordinates(COORDINATE_PRECISION_ON_ROUTES, route);

                parameters += $"&{IMAGES_ROUTE_ROUTE_PARAM_NAME}={routeCoords}";
                parameters += $"&{IMAGES_ROUTE_POINT_PARAM_NAME}="
                              + _formatter.FormatCoordinates(COORDINATE_PRECISION_ON_POINTS, cluster.Placemarks
                                                             .Where(x => x.Type == PlacemarkType.Point)
                                                             .Cast <IHasCoordinates>()
                                                             .ToArray());
                parameters += "&lc0=navy&sc0=888888";
            }
            else
            {
                var poi = _formatter.FormatCoordinates(null, cluster.Placemarks.Cast <IHasCoordinates>().ToArray());
                parameters += $"&poi={poi}&poitxc=fff&poifc=444&poitxs=18";

                if (cluster.Placemarks.Count == 1)
                {
                    parameters += "&z=14";
                }
            }

            return(await DownloadData(baseUrl, parameters));
        }
Example #5
0
 private MooiClusterDto CreateCluster(MooiCluster cluster)
 {
     return(new MooiClusterDto {
         Id = cluster.Id,
         IsRoute = cluster.Type == ClusterType.Routes,
         OverviewMapFilePath = ConvertToLocalFileUrl(cluster.OverviewMapFilePath),
         Placemarks = cluster.Placemarks.Select(CreatePlacemark).ToArray()
     });
 }
        private async Task FetchClusterMapImage(MooiCluster cluster, string tempPath)
        {
            var imageBytes = await _hereAdapter.FetchOverviewMap(cluster);

            if (imageBytes == null)
            {
                _logger.Warn($"Was unable to download overview map image for '{cluster.Id}'");
                return;
            }
            var filePath = Path.Combine(tempPath, _resourceName.CreateFileNameForOverviewMap(cluster));
            await _file.WriteBytesAsync(filePath, imageBytes);

            _logger.Info($"An overview map image for '{cluster.Id}' has been successfully downloaded");
        }
Example #7
0
        public List <MooiCluster> CreateSingleCluster(List <MooiPlacemark> placemarks, string reportTempPath)
        {
            var cluster = new MooiCluster();

            foreach (var pm in placemarks)
            {
                AppendPlacemarkToCluster(pm, cluster);
            }
            cluster.OverviewMapFilePath = Path.Combine(reportTempPath, _resourceName.CreateFileNameForOverviewMap(cluster));

            return(new List <MooiCluster> {
                cluster
            });
        }
Example #8
0
        internal IHasCoordinates GetAndTrimRouteCoordinates(MooiCluster cluster)
        {
            var route = cluster.Placemarks.Single(x => x.Type == PlacemarkType.Route);

            if (route.Coordinates.Length > TOO_MUCH_OF_COORDINATE_POINTS)
            {
                var factor = (double)route.Coordinates.Length / TOO_MUCH_OF_COORDINATE_POINTS;
                var coords = route.Coordinates
                             .Select((coord, i) => new { rank = Math.Floor(i / factor), coord })
                             .GroupBy(x => x.rank)
                             .Select(x => x.First().coord);

                return(new MooiPlacemark {
                    Coordinates = coords.ToArray()
                });
            }

            return(route);
        }
Example #9
0
        public void Trim_out_coordinates_when_too_much_passed_within_route()
        {
            // Arrange
            var routePlacemarkToInclude = new MooiPlacemark {
                Coordinates = Enumerable.Range(1, HereAdapter.TOO_MUCH_OF_COORDINATE_POINTS * 3)
                              .Select(x => new GeoCoordinate(x * 0.001, x * 0.001)).ToArray()
            };
            var placemarkShouldBeExcluded = new MooiPlacemark {
                Coordinates = new[] { new GeoCoordinate(1, 1) }
            };
            var group = new MooiCluster {
                Placemarks =
                {
                    routePlacemarkToInclude,
                    placemarkShouldBeExcluded
                }
            };

            // Act
            var result = _here.Object.GetAndTrimRouteCoordinates(group);

            // Verify
            Assert.AreEqual(HereAdapter.TOO_MUCH_OF_COORDINATE_POINTS, result.Coordinates.Length);
        }
Example #10
0
 public string CreateFileNameForOverviewMap(MooiCluster cluster)
 {
     return($"overview-{cluster.Id}.jpg");
 }
Example #11
0
        public List <MooiCluster> CreateList(KmlFolder folder, List <DiscoveredPlace> discoveredPlaces, string reportTempPath)
        {
            var clusters = new List <MooiCluster>();

            var placemarksConverted = folder.Placemarks
                                      .Select(x => _mooiPlacemarkFactory.Create(x,
                                                                                discoveredPlaces?.Where(dp => dp.AttachedToPlacemark == x).Select(dp => dp.Venue),
                                                                                reportTempPath))
                                      .ToList();

            if (placemarksConverted.Count <= MIN_COUNT_PER_CLUSTER)
            {
                return(CreateSingleCluster(placemarksConverted, reportTempPath));
            }

            if (folder.ContainsRoute && _kmlCalculator.CompleteFolderIsRoute(folder))
            {
                return(CreateSingleCluster(placemarksConverted, reportTempPath));
            }

            // TODO: Add support of lines within a folder which are not 'routes'
            placemarksConverted = placemarksConverted.Where(x => x.Coordinates.Length == 1).ToList();
            // ^^^

            var placemarksWithNeighbors       = GetPlacemarksWithNeighbors(placemarksConverted).ToList();
            var placemarksWithNeighborsLookup = placemarksWithNeighbors.ToDictionary(x => x.Placemark);

            var currentCluster = new MooiCluster();

            clusters.Add(currentCluster);

            var placemarksToProcess = placemarksWithNeighbors.ToList();

            while (placemarksToProcess.Any())
            {
                var startingPoint = placemarksToProcess[0];
                placemarksToProcess.RemoveAt(0);

                // Skip if the placemark has been added to any cluster before
                if (clusters.Any(g => g.Placemarks.Any(p => p == startingPoint.Placemark)))
                {
                    continue;
                }

                AppendPlacemarkToCluster(startingPoint.Placemark, currentCluster);

                // Add its closest neighbor to current cluster
                if (!clusters.Any(g => g.Placemarks.Any(p => p == startingPoint.NeighborWithMinDistance.Placemark)))
                {
                    AppendPlacemarkToCluster(startingPoint.NeighborWithMinDistance.Placemark, currentCluster);
                }

                foreach (var pm in placemarksToProcess.Skip(1).ToList())
                {
                    if (currentCluster.Placemarks.Any(x => x == pm.Placemark ||
                                                      x == pm.NeighborWithMinDistance.Placemark ||
                                                      pm.Neighbors.Any(n => n.Placemark == x && pm.NeighborWithMinDistance.AllowedDistance > n.Distance)
                                                      ))
                    {
                        if (currentCluster.Placemarks.Count >= MIN_COUNT_PER_CLUSTER)
                        {
                            var maxDistanceAmongAddedPlacemarks = placemarksWithNeighborsLookup[currentCluster.Placemarks[0]]
                                                                  .Neighbors.Where(x => currentCluster.Placemarks.Any(y => y == x.Placemark))
                                                                  .Select(x => x.AllowedDistance)
                                                                  .Max();

                            if (pm.NeighborWithMinDistance.Distance > maxDistanceAmongAddedPlacemarks)
                            {
                                continue;
                            }
                        }

                        AppendPlacemarkToCluster(pm.Placemark, currentCluster);
                        placemarksToProcess.Remove(pm);
                    }

                    if (currentCluster.Placemarks.Count == MAX_COUNT_PER_CLUSTER)
                    {
                        break;
                    }
                }

                currentCluster.OverviewMapFilePath = Path.Combine(reportTempPath, _resourceName.CreateFileNameForOverviewMap(currentCluster));
                currentCluster = new MooiCluster();
                clusters.Add(currentCluster);
            }

            // Trim out the last cluster which is always empty
            clusters = clusters.Where(x => x.Placemarks.Count > 0).ToList();

            MergeClusters(clusters);

            return(clusters);
        }
Example #12
0
 private void AppendPlacemarkToCluster(MooiPlacemark placemark, MooiCluster cluster)
 {
     placemark.Cluster = cluster;
     cluster.Placemarks.Add(placemark);
 }