public ActionResult UploadGpx(Guid id, FormCollection fields)
        {
            Mission mission = this.db.Missions.Single(f => f.Id == id);
              string kind = null;
              string desc = null;

              if (string.IsNullOrWhiteSpace(fields["description"]))
              {
            ModelState.AddModelError("description", "description is required");
              }
              else
              {
            desc = fields["description"];
            ModelState.SetModelValue("description", new ValueProviderResult(desc, desc, CultureInfo.CurrentUICulture));
              }

              if (string.IsNullOrWhiteSpace(fields["kind"]) || fields["kind"] != "teamtrk")
              {
            ModelState.AddModelError("kind", "only 'Team Track' is supported");
              }
              else
              {
            kind = fields["kind"];
            ModelState.SetModelValue("kind", new ValueProviderResult(kind, kind, CultureInfo.CurrentUICulture));
              }

              if (Request.Files.Count == 0)
              {
            ModelState.AddModelError("file", "No file uploaded");
              }
              else if (Request.Files.Count > 1)
              {
            return new ContentResult { Content = "Invalid Request: Too many files" };
              }

              HttpPostedFileBase hpf = null;
              if (ModelState.IsValid)
              {
            hpf = Request.Files[0] as HttpPostedFileBase;
            if (hpf.ContentLength == 0)
            {
              ModelState.AddModelError("file", "No file uploaded");
            }
              }

              if (ModelState.IsValid)
              {
            try
            {
              XmlDocument doc = new XmlDocument();
              doc.Load(hpf.InputStream);

              XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
              ns.AddNamespace("g", "http://www.topografix.com/GPX/1/1");

              XmlNodeList points = null;
              XmlNodeList tracks = doc.SelectNodes("//g:trk", ns);
              if (tracks.Count < 1)
              {
            ModelState.AddModelError("file", "At least one track required");
              }
              else
              {
            foreach (var track in tracks.Cast<XmlNode>())
            {
              string localDesc = desc;
              var name = track.SelectSingleNode("g:name", ns);
              if (name != null && !string.IsNullOrWhiteSpace(name.InnerText))
              {
                localDesc = name.InnerText;
              }

              points = track.SelectNodes("g:trkseg/g:trkpt", ns);
              if (points != null && points.Count > 2)
              {
                DateTime? minDate;
                //if (!TryExtractGpxGeography(ns, points, out geo, out minDate, 1, points.Count))
                //{
                //    geo = ExtractGeographyExcludeErrors(ns, points, out minDate);
                //}
                SqlGeography geo = ExtractGeography(ns, points, out minDate);
                if (geo == null) continue;

                MissionGeography geog = new MissionGeography
                {
                  Mission = mission,
                  Description = localDesc,
                  Kind = kind,
                  Geography = geo,
                  Time = minDate
                };
                this.db.MissionGeography.Add(geog);
              }
            }
              }
            }
            catch (XmlException)
            {
              ModelState.AddModelError("file", "Invalid GPX file");
            }
              }
              if (ModelState.IsValid)
              {
            this.db.SaveChanges();
            return ClosePopup();
              }
              return View(mission);
        }
        public ActionResult SubmitWaypoint(WaypointView wpt)
        {
            List<SubmitError> errors = new List<SubmitError>();
              Guid result = Guid.Empty;

              if (!User.IsInRole("cdb.missioneditors"))
              {
            return GetLoginError();
              }

              MissionGeography geog = null;

              geog = (from g in this.db.MissionGeography where g.Id == wpt.Id select g).FirstOrDefault();
              if (geog == null)
              {
            geog = new MissionGeography { Mission = (from m in this.db.Missions where m.Id == wpt.EventId select m).First() };
            this.db.MissionGeography.Add(geog);
              }

              //try
              //{
            if (geog.Kind != wpt.Kind) geog.Kind = wpt.Kind;
            if (geog.InstanceId != wpt.InstanceId) geog.InstanceId = wpt.InstanceId;

            SqlGeography defaultCoord = GeographyServices.GetDefaultLocation();
            wpt.Lat = Math.Abs(wpt.Lat) * Math.Sign(defaultCoord.Lat.Value);
            wpt.Long = Math.Abs(wpt.Long) * Math.Sign(defaultCoord.Long.Value);

            SqlGeography geography = wpt.AsSqlGeography();
            if (string.Format("{0}", geog.Geography) != string.Format("{0}", geography)) geog.Geography = geography;
            if (geog.Description != wpt.Description) geog.Description = wpt.Description;
            if (geog.Time != wpt.Time) geog.Time = wpt.Time;

            if (errors.Count == 0)
            {
              this.db.SaveChanges();
            }

              //}
              //catch (RuleViolationsException ex)
              //{
              //  //this.CollectRuleViolations(ex, fields);
              //  foreach (RuleViolation v in ex.Errors)
              //  {
              //    errors.Add(new SubmitError { Error = v.ErrorMessage, Property = v.PropertyName, Id = new[] { v.EntityKey } });
              //  }
              //}

              return Data(new SubmitResult<GeographyView>
              {
            Errors = errors.ToArray(),
            Result = (errors.Count > 0) ?
            (GeographyView)null :
            GeographyView.BuildGeographyView(geog)
            //new WaypointView
            //{
            //    Id = newView.Id,
            //    MissionId = newView.Mission.Id,
            //    Kind = newView.Kind,
            //    Desc = newView.Description,
            //    Lat = GeographyServices.FormatCoordinate(newView.Geography.Lat.Value, this.UserSettings.CoordinateDisplay),
            //    Long = GeographyServices.FormatCoordinate(newView.Geography.Long.Value, this.UserSettings.CoordinateDisplay),
            //    Instance = newView.InstanceId,
            //    Time = newView.Geography.M.IsNull ? (DateTime?)null : DateTime.FromOADate(newView.Geography.M.Value)
            //}
              });
        }