/// <summary> /// Create a MapViewModel, holding all data needed to render a map using the Google Maps API. /// </summary> /// <param name="height">the height of the map.</param> /// <param name="width">the width of the map.</param> /// <param name="minZoom">the minimum zoom on loading.</param> /// <param name="center">The center of the map.</param> /// <param name="locations">The list of locations to render as markers on this map.</param> public MapViewModel(int height, int width, int minZoom, Location center, ICollection<Location> locations) { this.Height = height; this.Width = width; this.MinZoom = minZoom; this.Center = center; this.Locations = locations; }
/// <summary> /// Retrieve the State for the specified Location using Google's Reverse Geocoding API. /// Use this to set the value of a Location initially. Use Location's State property /// to access information about a Location's State during regular use. /// </summary> /// <returns>The Abbreviation of the US State of this Location.</returns> public static string ReverseGeocodeState(Location location) { string state = null; string requestUri = string.Format(GEOCODE_BASE_URI, location.Latitude.ToString(), location.Longitude.ToString()); using (WebClient wc = new WebClient()) { string result = wc.DownloadString(requestUri); var xmlElm = XElement.Parse(result); var status = (from elm in xmlElm.Descendants() where elm.Name == "status" select elm).FirstOrDefault(); if (status.Value.ToLower() == "ok") { var res = xmlElm.Descendants("address_component") .Where(x => (string)x.Element("type") == "administrative_area_level_1" ) .Select(x => (string)x.Element("short_name")).FirstOrDefault(); state = res.ToString(); } } return state; }
/// <summary> /// Initialize the values from the given location. /// </summary> /// <param name="location"></param> public EditLocationViewModel(Location location) { this.LocationID = location.LocationID; this.Label = location.Label; this.Latitude = location.Latitude; this.Longitude = location.Longitude; this.Description = location.Description; }
public ActionResult Create(CreateLocationViewModel model) { Location location = new Location(); string country = Location.ReverseGeocodeCountry(model.Latitude, model.Longitude); if (!country.Equals("US") || country.Equals(null) || country.Equals("")) { ModelState.AddModelError("Longitude", "The location must be within the United States of America."); } if (ModelState.IsValid) { // transfer info location.Label = model.Label; location.Latitude = model.Latitude; location.Longitude = model.Longitude; location.Description = model.Description; location.Difficulty = (Location.DifficultyRatings) model.Difficulty; // initialize DateTime Stamps location.DateCreated = DateTime.UtcNow; location.DateModified = location.DateCreated; location.Rating(); location.UpVotes(); location.DownVotes(); string abbrev = Location.ReverseGeocodeState(location); location.State = db.States.Where(s => s.StateID.Equals(abbrev)).SingleOrDefault(); // save changes db.Locations.Add(location); db.SaveChanges();//must save before we move on so that location gets an ID // edit Recreations System.Diagnostics.Debug.WriteLine("SelectedRecreations = " + GetArrayFormattedString(model.SelectedFeatures)); EditRecreationsFor(location, model.SelectedRecreations); // edit NaturalFeatures System.Diagnostics.Debug.WriteLine("SelectedFeatures = " + GetArrayFormattedString(model.SelectedFeatures)); EditNaturalFeaturesFor(location, model.SelectedFeatures ?? new List<string>()); return RedirectToAction("Index"); } ModelState.AddModelError("Overall", "You are missing one or more required fields."); CreateLocationViewModel viewModel = new CreateLocationViewModel(); viewModel.Label = model.Label; viewModel.Latitude = model.Latitude; viewModel.Longitude = model.Longitude; viewModel.Description = model.Description; viewModel.Difficulty = model.Difficulty; viewModel.SelectedRecreations = model.SelectedRecreations ?? new List<String>(); viewModel.AllRecreations = db.Recreations .Select(r => r.Label) .ToList(); viewModel.SelectedFeatures = model.SelectedFeatures ?? new List<String>(); viewModel.AllNaturalFeatures = db.NaturalFeatures .Select(nf => nf.Name) .ToList(); return View(viewModel); }
/// <summary> /// Helper method to edit the Recreations of the specified Location by modifying /// the entries of the bridge entity LocationRecreations. /// </summary> ///<param name="location">The Location to modify the associated Recreations of.</param> /// <param name="SelectedRecreations"> /// <para> /// The labels of which Recreations to associate. /// </para><para> /// Any labels which don't match an existing Recreation will be /// added as a new Recreation. /// </para><para> /// Any Recreations which are associated with the Location /// but are are not in this list will be removed from the Location. /// </para><para> /// Any Recreations which not are associated with the Location /// but are in this list will be added to the Location. /// </para><para> /// All other Recreation associations will remain untouched. /// </para> /// </param> public void EditRecreationsFor(Location location, ICollection<string> SelectedRecreations) { int locationID = location.LocationID; System.Diagnostics.Debug.WriteLine("ModelState is valid."); // 1) - Set aside all previous LocationRecreations for comparison. var associated = db.LocationRecreations .Include(lr => lr.Recreation) .Where(lr => lr.LocationID == locationID) .ToList(); // **************************************************** // 2) - Add any new Recreations. // **************************************************** int newRecCount = 0; foreach (string label in SelectedRecreations) { var match = db.Recreations.SingleOrDefault(r => r.Label.Equals(label)); if (match == null) { db.Recreations.Add(new Recreation(label)); newRecCount++; } } db.SaveChanges(); System.Diagnostics.Debug.WriteLine(String.Format("successfully added {0} new Recreations.", newRecCount)); // get all Recreations to iterate over. var selected = db.Recreations .Where(nf => SelectedRecreations.Contains(nf.Label)) .ToList(); // **************************************************** // 3) - Remove any LocationRecreations that are currently // associated, but aren't selected. // **************************************************** int removedLrCount = 0; foreach (LocationRecreation item in associated) { var result = selected.SingleOrDefault(lr => lr.RecreationID == item.RecreationID); if (result == null) { System.Diagnostics.Debug.WriteLine(String.Format("'{0}' is associated with '{1}', but needs to be removed.", item.Recreation.Label, location.Label)); db.LocationRecreations.Remove(item); removedLrCount++; } } db.SaveChanges(); System.Diagnostics.Debug.WriteLine(String.Format("successfully removed {0} LocationRecreations from {1}.", removedLrCount, location.Label)); // **************************************************** // 4) - Add any LocationRecreations that are currently // selected, but aren't associated. // **************************************************** int addedRlCount = 0; foreach (Recreation item in selected) { var result = associated.SingleOrDefault(lr => lr.RecreationID == item.RecreationID); if (result == null) { System.Diagnostics.Debug.WriteLine(String.Format("'{0}' is not associated with '{1}', but needs to be added.", item.Label, location.Label)); db.LocationRecreations.Add(new LocationRecreation(locationID, item.RecreationID)); addedRlCount++; } } db.SaveChanges(); System.Diagnostics.Debug.WriteLine(String.Format("successfully added {0} new LocationRecreations for {1}.", addedRlCount, location.Label)); }
/// <summary> /// Helper method to edit the NaturalFeatures of the specified Location by modifying /// the entries of the bridge entity LocationFeatures. /// </summary> ///<param name="location">The Location to modify the associated NaturalFeatures of.</param> /// <param name="SelectedFeatures"> /// <para> /// The names of which NaturalFeatures to associate. /// </para><para> /// Any names which don't match an existing NaturalFeature will be /// added as a new NaturalFeature. /// </para><para> /// Any NaturalFeatures which are associated with the Location /// but are are not in this list will be removed from the Location. /// </para><para> /// Any NaturalFeatures which not are associated with the Location /// but are in this list will be added to the Location. /// </para><para> /// All other NaturalFeature associations will remain untouched. /// </para> /// </param> public void EditNaturalFeaturesFor(Location location, ICollection<string> SelectedFeatures) { int locationID = location.LocationID; System.Diagnostics.Debug.WriteLine("ModelState is valid."); // 1) - Set aside all previous location features for comparison. var associated = db.LocationFeatures .Include(lf => lf.NaturalFeature) .Where(lf => lf.LocationID == locationID) .ToList(); // **************************************************** // 2) - add any new NaturalFeatures. // **************************************************** int newNfCount = 0; foreach (string name in SelectedFeatures) { var match = db.NaturalFeatures.SingleOrDefault(nf => nf.Name.Equals(name)); if (match == null) { db.NaturalFeatures.Add(new NaturalFeature(name)); newNfCount++; } } db.SaveChanges(); System.Diagnostics.Debug.WriteLine(String.Format("successfully added {0} new NaturalFeatures.", newNfCount)); // get all features to iterate over. var selected = db.NaturalFeatures .Where(nf => SelectedFeatures.Contains(nf.Name)) .ToList(); // **************************************************** // 3) - remove any LocationFeatures that are currently // associated, but aren't selected. // **************************************************** int removedLfcount = 0; foreach (LocationFeature item in associated) { var result = selected.SingleOrDefault(nf => nf.ID == item.NaturalFeatureID); if (result == null) { System.Diagnostics.Debug.WriteLine(String.Format("'{0}' is associated with '{1}', but needs to be removed.", item.NaturalFeature.Name, location.Label)); db.LocationFeatures.Remove(item); removedLfcount++; } } db.SaveChanges(); System.Diagnostics.Debug.WriteLine(String.Format("successfully removed {0} LocationFeatures from {1}.", removedLfcount, location.Label)); // **************************************************** // 4) - add any LocationFeatures that are currently // selected, but aren't associated. // **************************************************** int addedLfCount = 0; foreach (NaturalFeature item in selected) { var result = associated.SingleOrDefault(lf => lf.NaturalFeatureID == item.ID); if (result == null) { System.Diagnostics.Debug.WriteLine(String.Format("'{0}' is not associated with '{1}', but needs to be added.", item.Name, location.Label)); db.LocationFeatures.Add(new LocationFeature(locationID, item.ID)); addedLfCount++; } } db.SaveChanges(); System.Diagnostics.Debug.WriteLine(String.Format("successfully added {0} new LocationFeatures for {1}.", addedLfCount, location.Label)); }
// ************************************************************************************************************ // GOOGLE MAPS // ************************************************************************************************************ /// <summary> /// Render a Google Map in a div with the specified attributes. /// (Note: this only works for regular locations; for non-standard views, use the script tags directly in the view.) /// </summary> /// <param name="height">the height of the map.</param> /// <param name="width">the width of the map.</param> /// <param name="minZoom">the minimum zoom on loading.</param> /// <param name="center">The center of the map.</param> /// <param name="locations">The list of locations to render as markers on this map.</param> public ActionResult GoogleMap(int height, int width, int minZoom, Location center, ICollection<Location> locations) { MapViewModel viewModel = new MapViewModel(height, width, minZoom, center, locations); return PartialView(viewModel); }