}                                                               //Used so coordinates only have to be reoslved once

            public GeocacheRoutingInformation(Geocache geocache, float DistanceToRoute, float EstimatedExtraDistance, RouterPoint ResolvedCoordinates)
            {
                this.geocache               = geocache;
                this.DistanceToRoute        = DistanceToRoute;
                this.EstimatedExtraDistance = EstimatedExtraDistance;
                this.ResolvedCoordinates    = ResolvedCoordinates;

                RoutingPoints = geocache.Rating / (1 + EstimatedExtraDistance * DistanceToRoute);
            }
Exemple #2
0
        public static void ImportGeocaches()
        {
            string         GPXDatei;
            OpenFileDialog SelectGPXFileDialog = new OpenFileDialog
            {
                InitialDirectory = Program.DB.LastUsedFilepath,
                Filter           = "gpx files (*.gpx)|*.gpx|All files (*.*)|*.*",
                FilterIndex      = 0,
                RestoreDirectory = true,
                Title            = "Import geocaches"
            };

            if (SelectGPXFileDialog.ShowDialog() == DialogResult.OK)
            {
                DialogResult Importmodus = MessageBox.Show("Should the Geocaches be loaded into a new Database?", "Import", MessageBoxButtons.YesNoCancel);
                if (Importmodus == DialogResult.Yes)
                {
                    //Create a new File
                    SaveFileDialog NewFileDialog = new SaveFileDialog
                    {
                        InitialDirectory = Program.DB.LastUsedFilepath,
                        Filter           = "gcdb files (*.gcdb)|*.gcdb|All files (*.*)|*.*",
                        FilterIndex      = 0,
                        RestoreDirectory = true,
                        Title            = "Create new, empty geocachedatabase"
                    };

                    if (NewFileDialog.ShowDialog() == DialogResult.OK)
                    {
                        //Save the curent geocaches to the current file, so no data is lost. Nothing happens if there are no geocaches
                        Backup(Program.Geocaches);

                        //Create new database File
                        File.Create(NewFileDialog.FileName).Close();
                        Program.Geocaches.Clear();
                        Program.DB.GeocacheDB_Filepath = NewFileDialog.FileName;
                    }
                }
                else if (Importmodus == DialogResult.No)
                {
                    //Do nothing
                }
                else                 // a.k.a cancel
                {
                    return;
                }

                try
                {
                    GPXDatei = SelectGPXFileDialog.FileName;
                    Program.DB.LastUsedFilepath = SelectGPXFileDialog.FileName;
                    XElement RootElement = XElement.Load(GPXDatei);

                    XNamespace gpx         = "http://www.topografix.com/GPX/1/0";             //default namespace
                    XNamespace groundspeak = "http://www.groundspeak.com/cache/1/0/1";

                    foreach (XElement elem in RootElement.Elements(gpx + "wpt"))
                    {
                        XElement CacheDetails = elem.Element(groundspeak + "cache");
                        if (CacheDetails != null)                        //Thus the waipoint is a geocache
                        {
                            Geocache geocache = new Geocache {
                            };

                            geocache.lat              = float.Parse(elem.FirstAttribute.ToString().Replace("\"", "").Replace("lat=", ""), CultureInfo.InvariantCulture);
                            geocache.lon              = float.Parse(elem.LastAttribute.ToString().Replace("\"", "").Replace("lon=", ""), CultureInfo.InvariantCulture);
                            geocache.GCCODE           = (string)elem.Element(gpx + "name").Value;
                            geocache.Name             = (string)elem.Element(gpx + "urlname").Value;
                            geocache.DRating          = float.Parse(CacheDetails.Element(groundspeak + "difficulty").Value.ToString(), CultureInfo.InvariantCulture);
                            geocache.TRating          = float.Parse(CacheDetails.Element(groundspeak + "terrain").Value.ToString(), CultureInfo.InvariantCulture);
                            geocache.NeedsMaintenance = CacheDetails.Element(groundspeak + "attributes").Elements().ToList().Exists(x => x.FirstAttribute.Value == 42.ToString());
                            geocache.DateHidden       = DateTime.Parse(elem.Element(gpx + "time").Value.ToString());
                            switch (elem.Element(gpx + "type").Value)
                            {
                            case "Geocache|Unknown Cache":
                                geocache.Type = GeocacheType.Mystery;
                                break;

                            case "Geocache|Traditional Cache":
                                geocache.Type = GeocacheType.Traditional;
                                break;

                            case "Geocache|Multi-cache":
                                geocache.Type = GeocacheType.Multi;
                                break;

                            case "Geocache|Virtual Cache":
                                geocache.Type = GeocacheType.Virtual;
                                break;

                            case "Geocache|Wherigo Cache":
                                geocache.Type = GeocacheType.Wherigo;
                                break;

                            case "Geocache|Webcam Cache":
                                geocache.Type = GeocacheType.Webcam;
                                break;

                            case "Geocache|Letterbox Hybrid":
                                geocache.Type = GeocacheType.Letterbox;
                                break;

                            case "Geocache|Earthcache":
                                geocache.Type = GeocacheType.EarthCache;
                                break;

                            case "Geocache|Mega-Event Cache":
                                geocache.Type = GeocacheType.MegaEvent;
                                break;

                            case "Geocache|Event Cache":
                                geocache.Type = GeocacheType.Event;
                                break;

                            case "Geocache|Cache In Trash Out Event":
                                geocache.Type = GeocacheType.Cito;
                                break;

                            default:
                                geocache.Type = GeocacheType.Other;
                                break;
                            }
                            switch (CacheDetails.Element(groundspeak + "container").Value)
                            {
                            case "Large":
                                geocache.Size = GeocacheSize.Large;
                                break;

                            case "Regular":
                                geocache.Size = GeocacheSize.Regular;
                                break;

                            case "Small":
                                geocache.Size = GeocacheSize.Small;
                                break;

                            case "Micro":
                                geocache.Size = GeocacheSize.Micro;
                                break;

                            default:
                                geocache.Size = GeocacheSize.Other;
                                break;
                            }
                            if (!Program.Geocaches.Any(x => x.GCCODE == geocache.GCCODE))
                            {
                                Program.Geocaches.Add(geocache);
                            }
                            else
                            {
                                //Nothing in the moment, would be good if it would update the Geocaches
                            }

                            Program.MainWindow.UpdateStatus("Successfully imported geocaches");
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
                    Program.MainWindow.UpdateStatus("Import of geocaches failed");
                }
                Backup(Program.Geocaches);
                Program.Geocaches.ResetBindings();
            }
        }
Exemple #3
0
        public static GMapMarker GetGeocacheMarker(Geocache geocache)
        {
            Category GeocacheCategory;
            Bitmap   marker_bmp;

            if (geocache.ForceInclude)
            {
                GeocacheCategory = Category.ForceInclude;
            }
            else if (geocache.Rating > (Program.DB.MinimalRating) + 0.83 * (Program.DB.MaximalRating - Program.DB.MinimalRating))
            {
                GeocacheCategory = Category.Best_Good;
            }
            else if (geocache.Rating > (Program.DB.MinimalRating) + 0.67 * (Program.DB.MaximalRating - Program.DB.MinimalRating))
            {
                GeocacheCategory = Category.Best_Bad;
            }
            else if (geocache.Rating > (Program.DB.MinimalRating) + 0.5 * (Program.DB.MaximalRating - Program.DB.MinimalRating))
            {
                GeocacheCategory = Category.Medium_Good;
            }
            else if (geocache.Rating > (Program.DB.MinimalRating) + 0.33 * (Program.DB.MaximalRating - Program.DB.MinimalRating))
            {
                GeocacheCategory = Category.Medium_Bad;
            }
            else if (geocache.Rating > (Program.DB.MinimalRating) + 0.16 * (Program.DB.MaximalRating - Program.DB.MinimalRating))
            {
                GeocacheCategory = Category.Worst_Good;
            }
            else
            {
                GeocacheCategory = Category.Worst_Bad;
            }

            if (Program.MarkerImageCache.Where(x => x.Value1 == geocache.Type && x.Value2 == (int)GeocacheCategory).Count() > 0)
            {
                marker_bmp = Program.MarkerImageCache.Find(x => x.Value1 == geocache.Type && x.Value2 == (int)GeocacheCategory).Key;
            }
            else
            {
                Image OriginalMarker = Properties.Images.Pin_black;

                ColorMap[] colorMap = new ColorMap[1];
                colorMap[0]          = new ColorMap();
                colorMap[0].OldColor = Color.Black;

                switch (GeocacheCategory)
                {
                case Category.ForceInclude:
                    colorMap[0].NewColor = Color.Blue;
                    break;

                case Category.Best_Good:
                    colorMap[0].NewColor = Color.Green;
                    break;

                case Category.Best_Bad:
                    colorMap[0].NewColor = Color.GreenYellow;
                    break;

                case Category.Medium_Good:
                    colorMap[0].NewColor = Color.Yellow;
                    break;

                case Category.Medium_Bad:
                    colorMap[0].NewColor = Color.Orange;
                    break;

                case Category.Worst_Good:
                    colorMap[0].NewColor = Color.Red;
                    break;

                case Category.Worst_Bad:
                    colorMap[0].NewColor = Color.DarkRed;
                    break;
                }

                ImageAttributes PinAttributes = new ImageAttributes();
                PinAttributes.SetRemapTable(colorMap);

                Image TypeImage;
                switch (geocache.Type)
                {
                case GeocacheType.Ape:
                    TypeImage = Properties.Images.type_ape;
                    break;

                case GeocacheType.Cito:
                    TypeImage = Properties.Images.type_cito;
                    break;

                case GeocacheType.EarthCache:
                    TypeImage = Properties.Images.type_earth;
                    break;

                case GeocacheType.Event:
                    TypeImage = Properties.Images.type_event;
                    break;

                case GeocacheType.GigaEvent:
                    TypeImage = Properties.Images.type_giga;
                    break;

                case GeocacheType.Letterbox:
                    TypeImage = Properties.Images.type_letterbox;
                    break;

                case GeocacheType.MegaEvent:
                    TypeImage = Properties.Images.type_mega;
                    break;

                case GeocacheType.Multi:
                    TypeImage = Properties.Images.type_multi;
                    break;

                case GeocacheType.Mystery:
                    TypeImage = Properties.Images.type_mystery;
                    break;

                case GeocacheType.Traditional:
                    TypeImage = Properties.Images.type_traditional;
                    break;

                case GeocacheType.Virtual:
                    TypeImage = Properties.Images.type_virtual;
                    break;

                case GeocacheType.Webcam:
                    TypeImage = Properties.Images.type_webcam;
                    break;

                case GeocacheType.Wherigo:
                    TypeImage = Properties.Images.type_wherigo;
                    break;

                default:
                    TypeImage = Properties.Images.type_unknown;                             // Currently events and rare cache tyoes fall under this.
                    break;
                }

                Rectangle PinRect    = new Rectangle(0, 0, Program.DB.MarkerSize, (int)(1.5 * Program.DB.MarkerSize));
                Rectangle SymbolRect = new Rectangle(0, 0, Program.DB.MarkerSize, Program.DB.MarkerSize);

                marker_bmp = new Bitmap(Program.DB.MarkerSize, (int)(1.5 * Program.DB.MarkerSize));
                marker_bmp.SetResolution(OriginalMarker.HorizontalResolution, OriginalMarker.VerticalResolution);

                using (Graphics graphics = Graphics.FromImage(marker_bmp))
                {
                    // see https://stackoverflow.com/questions/1922040/resize-an-image-c-sharp
                    graphics.CompositingMode    = CompositingMode.SourceOver;
                    graphics.CompositingQuality = CompositingQuality.HighQuality;
                    graphics.InterpolationMode  = InterpolationMode.HighQualityBicubic;
                    graphics.SmoothingMode      = SmoothingMode.HighQuality;
                    graphics.PixelOffsetMode    = PixelOffsetMode.HighQuality;

                    PinAttributes.SetWrapMode(WrapMode.TileFlipXY);
                    graphics.DrawImage(OriginalMarker, PinRect, 0, 0, OriginalMarker.Width, OriginalMarker.Height, GraphicsUnit.Pixel, PinAttributes);

                    ImageAttributes SymbolAttribute = new ImageAttributes();
                    SymbolAttribute.SetWrapMode(WrapMode.TileFlipXY);

                    graphics.DrawImage(TypeImage, SymbolRect, 0, 0, TypeImage.Width, TypeImage.Height, GraphicsUnit.Pixel, PinAttributes);
                }

                Program.MarkerImageCache.Add(new KeyValueTriple <Bitmap, GeocacheType, int>(marker_bmp, geocache.Type, (int)GeocacheCategory));
            }

            //Create final marker
            GMapMarker GCMarker = new GMarkerGoogle(new PointLatLng(geocache.lat, geocache.lon), marker_bmp);

            GCMarker.ToolTipText = geocache.GCCODE + "\n" + geocache.Name + "\n" + geocache.Type + " (" + geocache.DateHidden.Date.ToString().Remove(10) + ")\nD: " + geocache.DRating + " T: " + geocache.TRating + " " + geocache.Size + "\nPoints: " + geocache.Rating;
            GCMarker.Tag         = geocache.GCCODE;

            return(GCMarker);
        }
 public GeocacheRoutingInformation(Geocache geocache, float EstimatedExtraDistance, RouterPoint ResolvedCoordinates)
 {
     this.geocache = geocache;
     this.EstimatedExtraDistance = EstimatedExtraDistance;
     this.ResolvedCoordinates    = ResolvedCoordinates;
 }
 public void AddGeocacheOnRoute(Geocache geocache)
 {
     _GeocachesOnRoute.Add(geocache);
     TotalPoints += geocache.Rating;
 }
        private RouteData DirectionDecision(RouteData CompleteRouteData, List <Geocache> GeocachesToConsider)
        {
            GeocachesToConsider = GeocachesToConsider.OrderByDescending(x => x.Rating).ToList();

            List <RouteData> Suggestions = new List <RouteData>();

            int NumberofRouteslongerthanlimit = 0;

            int FirstGeocacheNotUsedAsSuggestionBase = Program.DB.RoutefindingWidth + 1;

            try
            {
                Parallel.For(0, Program.DB.RoutefindingWidth, NumberOfSuggestions =>
                {
                    Fileoperations.Routerlog.LogCollector Log = new Fileoperations.Routerlog.LogCollector("DirectionDecision" + NumberOfSuggestions);

                    RouteData SuggestionRouteData;
                    lock (CompleteRouteData)
                    {
                        SuggestionRouteData = CompleteRouteData.DeepCopy();
                    }
                    lock (Suggestions)
                    {
                        Suggestions.Add(SuggestionRouteData);
                    }

                    int SuggestedCacheIndex = NumberOfSuggestions;

                    //Add geocaches to suggested route, as long as the route is shorter than the min allowed length, but also make sure it doesn't get too long in time and distance
                    while (SuggestionRouteData.TotalDistance < Program.DB.PercentageOfDistanceInAutoTargetselection_Min * SuggestionRouteData.Profile.MaxDistance * 1000 && SuggestedCacheIndex < GeocachesToConsider.Count)
                    {
                        Geocache SuggestedCache = GeocachesToConsider[SuggestedCacheIndex];
                        Log.AddMainInformation("Suggested " + SuggestedCache + " at Index Position " + SuggestedCacheIndex);

                        #region Find shortest resulting route if cache is inserted Route
                        int IndexOfRouteToInsertIn         = 0;
                        float MinEstimatedExtraRouteLength = -1;
                        for (int PartialRouteIndex = 0; PartialRouteIndex < SuggestionRouteData.partialRoutes.Count; PartialRouteIndex++)                   //Thus each partial route
                        {
                            float Length = GetEstimatedExtraDistance(SuggestionRouteData.partialRoutes[PartialRouteIndex].partialRoute, new Coordinate(SuggestedCache.lat, SuggestedCache.lon));
                            //Whether this is the route the geocache is currently closest to
                            if (MinEstimatedExtraRouteLength < 0 || Length < MinEstimatedExtraRouteLength)
                            {
                                IndexOfRouteToInsertIn       = PartialRouteIndex;
                                MinEstimatedExtraRouteLength = Length;
                            }
                        }
                        #endregion

                        Log.AddSubInformation("Estimated Route length: " + MinEstimatedExtraRouteLength);

                        //Check if the Cache seems to be in range. Error_Percentage * Max_Percentage * Remaining Distance, since the roads to the cache are quite surely not in a straight line and we want to fill up to the percentage only
                        if (MinEstimatedExtraRouteLength < Program.DB.PercentageOfDistanceInAutoTargetselection_Max * (SuggestionRouteData.Profile.MaxDistance * 1000 - SuggestionRouteData.TotalDistance))
                        {
                            Result <RouterPoint> GeocacheToAddResolveResult = Router1.TryResolve(SuggestionRouteData.Profile.ItineroProfile.profile, SuggestedCache.lat, SuggestedCache.lon, SearchDistanceInMeters);
                            Route RouteToInsertIn = SuggestionRouteData.partialRoutes[IndexOfRouteToInsertIn].partialRoute;

                            GeocacheRoutingInformation SuggestionBaseCache_Info;
                            if (!GeocacheToAddResolveResult.IsError)
                            {
                                SuggestionBaseCache_Info = new GeocacheRoutingInformation(SuggestedCache, MinEstimatedExtraRouteLength, GeocacheToAddResolveResult.Value);

                                Result <Tuple <Route, Route> > RoutingResult = GetPartialRoutes(SuggestionRouteData, RouteToInsertIn, SuggestionBaseCache_Info.ResolvedCoordinates);
                                if (!RoutingResult.IsError)
                                {
                                    // So one doesn't have to iterate through all routes
                                    //TestRouteDistance, as one doesn't know wether this on is taken
                                    float NewDistance = SuggestionRouteData.TotalDistance - RouteToInsertIn.TotalDistance + RoutingResult.Value.Item1.TotalDistance + RoutingResult.Value.Item1.TotalDistance;
                                    float NewTime     = SuggestionRouteData.TotalTime - RouteToInsertIn.TotalTime + RoutingResult.Value.Item1.TotalTime + RoutingResult.Value.Item1.TotalTime;

                                    if (NewDistance < Program.DB.PercentageOfDistanceInAutoTargetselection_Max * SuggestionRouteData.Profile.MaxDistance * 1000 && NewTime < Program.DB.PercentageOfDistanceInAutoTargetselection_Max * SuggestionRouteData.Profile.MaxTime * 60)
                                    {
                                        Log.AddSubInformation("Added the Geocache to the Route. New Distance:" + NewDistance);
                                        SuggestionRouteData = ReplaceRoute(SuggestionRouteData, RoutingResult.Value.Item1, RoutingResult.Value.Item2, IndexOfRouteToInsertIn);
                                        SuggestionRouteData.AddGeocacheOnRoute(SuggestedCache);
                                    }                               //Else just skip this cache.
                                    else
                                    {
                                        Log.AddSubInformation("The Resulting Distance was too long");
                                        NumberofRouteslongerthanlimit++;
                                    }
                                }
                            }
                            else                        //Couldn't resolve
                            {
                                Log.AddSubInformation("Couldn't resolve Geocache");
                                if (SuggestedCacheIndex == FirstGeocacheNotUsedAsSuggestionBase)
                                {
                                    FirstGeocacheNotUsedAsSuggestionBase++;                               //To avoid using the same cache as base twice
                                    SuggestedCacheIndex = FirstGeocacheNotUsedAsSuggestionBase--;         //Since ++ will happen
                                }
                                lock (GeocachesToConsider)
                                {
                                    GeocachesToConsider.RemoveAt(SuggestedCacheIndex);                               //Since it will never be possible to resolve it
                                }
                            }
                        }
                        else
                        {
                            Log.AddSubInformation("Estimated Distance was too long");
                        }

                        if (FailedRouteCalculations > FailedRouteCalculationsLimit)
                        {
                            break;
                        }
                        else
                        {
                            SuggestedCacheIndex++;
                        }
                    }

                    Log.Write();                // Since this thread is done
                });
            }
            catch (Exception)
            {
                Fileoperations.Routerlog.AddSubInformation("At least one exception has been caused.");
            }
            Fileoperations.Routerlog.AddSubInformation(NumberofRouteslongerthanlimit + " Routes have been to long.");

            if (Suggestions.Count != 0)
            {
                //Return best suggestion
                return(Suggestions.Find(x => x.TotalPoints == Suggestions.Max(y => y.TotalPoints)));
            }
            //If no suggestion has been found, just return the uncanged original Data
            return(CompleteRouteData);
        }