public void TestFromGeoPoints() { var area = GeoArea.FromGeoPoints(new[] { new GeoPoint(1, 2), new GeoPoint(2, 1), new GeoPoint(2, 3) }); Assert.AreEqual(new GeoPoint(1, 1), area.SouthWest); Assert.AreEqual(new GeoPoint(2, 3), area.NorthEast); }
/// <summary> /// Generates all SlippyMap tiles for a given area and zoom level, and saves them to the database. /// </summary> /// <param name="buffered">the GeoArea to generate tiles for</param> /// <param name="zoomLevel">the zoom level to generate tiles at.</param> public static void PregenSlippyMapTilesForArea(GeoArea buffered, int zoomLevel) { //There is a very similar function for this in Standalone.cs, but this one writes back to the main DB. var db = new PraxisContext(); db.ChangeTracker.AutoDetectChangesEnabled = false; var intersectCheck = Converters.GeoAreaToPolygon(buffered); //start drawing maptiles and sorting out data. var swCornerLon = Converters.GetSlippyXFromLon(intersectCheck.EnvelopeInternal.MinX, zoomLevel); var neCornerLon = Converters.GetSlippyXFromLon(intersectCheck.EnvelopeInternal.MaxX, zoomLevel); var swCornerLat = Converters.GetSlippyYFromLat(intersectCheck.EnvelopeInternal.MinY, zoomLevel); var neCornerLat = Converters.GetSlippyYFromLat(intersectCheck.EnvelopeInternal.MaxY, zoomLevel); //declare how many map tiles will be drawn var xTiles = neCornerLon - swCornerLon + 1; var yTiles = swCornerLat - neCornerLat + 1; var totalTiles = xTiles * yTiles; Log.WriteLog("Starting processing " + totalTiles + " maptiles for zoom level " + zoomLevel); long mapTileCounter = 0; System.Diagnostics.Stopwatch progressTimer = new System.Diagnostics.Stopwatch(); progressTimer.Start(); //foreach (var y in yCoords) for (var y = neCornerLat; y <= swCornerLat; y++) { //Make a collision box for just this row of Cell8s, and send the loop below just the list of things that might be relevant. //Add a Cell8 buffer space so all elements are loaded and drawn without needing to loop through the entire area. GeoArea thisRow = new GeoArea(Converters.SlippyYToLat(y + 1, zoomLevel) - ConstantValues.resolutionCell8, Converters.SlippyXToLon(swCornerLon, zoomLevel) - ConstantValues.resolutionCell8, Converters.SlippyYToLat(y, zoomLevel) + ConstantValues.resolutionCell8, Converters.SlippyXToLon(neCornerLon, zoomLevel) + resolutionCell8); var row = Converters.GeoAreaToPolygon(thisRow); var rowList = GetPlaces(thisRow); var tilesToSave = new ConcurrentBag <SlippyMapTile>(); Parallel.For(swCornerLon, neCornerLon + 1, (x) => { //make map tile. var info = new ImageStats(zoomLevel, x, y, IMapTiles.SlippyTileSizeSquare); var acheck = Converters.GeoAreaToPolygon(info.area); //this is faster than using a PreparedPolygon in testing, which was unexpected. var areaList = rowList.Where(a => acheck.Intersects(a.ElementGeometry)).ToList(); //This one is for the maptile var tile = MapTiles.DrawAreaAtSize(info, areaList); tilesToSave.Add(new SlippyMapTile() { TileData = tile, Values = x + "|" + y + "|" + zoomLevel, ExpireOn = DateTime.Now.AddDays(3650), AreaCovered = Converters.GeoAreaToPolygon(info.area), StyleSet = "mapTiles" }); mapTileCounter++; }); db.SlippyMapTiles.AddRange(tilesToSave); db.SaveChanges(); Log.WriteLog(mapTileCounter + " tiles processed, " + Math.Round(((mapTileCounter / (double)totalTiles * 100)), 2) + "% complete"); }//); progressTimer.Stop(); Log.WriteLog("Zoom " + zoomLevel + " map tiles drawn in " + progressTimer.Elapsed.ToString()); }
public JsonResult GeoAreasConfirm() { var geoAreaID = Request["GeoAreaID"]; var equationYearID = Request["EquationYearID"]; GeoArea geoArea = null; EquationYear equationYear = null; if (!string.IsNullOrWhiteSpace(geoAreaID)) { geoArea = db.GeoAreas.Find(int.Parse(geoAreaID)); } if (!string.IsNullOrWhiteSpace(geoAreaID)) { int _equationYearID = int.Parse(equationYearID); equationYear = db.EquationYears.Include(x => x.Equation.Indicator).Where(x => x.ID == _equationYearID).FirstOrDefault(); } if (equationYear == null || geoArea == null) { return(Json(new { success = false, error = "برجاء إدخال بيانات صحيحة" })); } double value = CalculateEquation(equationYear, geoArea); DeleteCalculated(geoArea, equationYear); Commit(geoArea, equationYear, value); db.SaveChanges(); UpdateLog(geoArea, equationYear, "commit"); return(Json(new { success = true })); }
/// <summary> /// Find which element in the list intersect with which PlusCodes inside the area. Returns one element per PlusCode /// </summary> /// <param name="area">GeoArea from a decoded PlusCode</param> /// <param name="elements">A list of OSM elements</param> /// <returns>returns a dictionary using PlusCode as the key and name/areatype/client facing Id of the smallest element intersecting that PlusCode</returns> public static Dictionary <string, TerrainData> SearchArea(ref GeoArea area, ref List <DbTables.Place> elements) { //Singular function, returns 1 item entry per cell10. if (elements.Count() == 0) { return(null); } Dictionary <string, TerrainData> results = new Dictionary <string, TerrainData>(400); //starting capacity for a full Cell8 var xCells = area.LongitudeWidth / resolutionCell10; var yCells = area.LatitudeHeight / resolutionCell10; double x = area.Min.Longitude; double y = area.Min.Latitude; for (double xx = 0; xx < xCells; xx += 1) { for (double yy = 0; yy < yCells; yy += 1) { var placeFound = FindPlaceInCell10(x, y, ref elements); if (placeFound != null) { results.Add(placeFound.Item1, placeFound.Item2); } y = Math.Round(y + resolutionCell10, 6); //Round ensures we get to the next pluscode in the event of floating point errors. } x = Math.Round(x + resolutionCell10, 6); y = area.Min.Latitude; } return(results); }
protected override void ProcessFeature(IFeature feature, GeoArea geoArea) { geoArea.Type = GeoAreaType.District; geoArea.Id = "D" + feature.Attributes["prov_istat_code_num"].ToString(); geoArea.Name = (string)feature.Attributes["prov_name"]; geoArea.ParentId = "R" + feature.Attributes["reg_istat_code_num"].ToString(); }
private static IEnumerable <SuburbBoundary> GetBoundaries(IEnumerable <OpenDataSuburb> sameNameSuburbs) { var suburbList = sameNameSuburbs.ToList(); if (suburbList.Count <= 1) { return new[] { CreateSuburbBoundary(suburbList) } } ; var idSuburbs = suburbList.GroupBy(x => x.Id).Select(x => x.ToList()).ToList(); if (idSuburbs.Count <= 1) { return new[] { CreateSuburbBoundary(suburbList) } } ; var boundaries = idSuburbs.Select(suburbs => { var boundary = CreateSuburbBoundary(suburbs); return(LastUpdateTime: suburbs.First().UpdateDate, Boundary: boundary, GeoArea: GeoArea.FromGeoPoints(boundary.Boundary.Polygons.SelectMany(x => x))); }).OrderByDescending(x => x.LastUpdateTime); return(GetNoneOverlappedBoundaries(boundaries)); }
public ActionResult Edit([Bind(Include = "ID,Code,Name,Type")] GeoArea geoAreaBundle, int[] geo_area_ids) { if (ModelState.IsValid) { db.Entry(geoAreaBundle).State = EntityState.Modified; geoAreaBundle.GeoAreaBundles = db.GeoAreas.Where(x => x.ID == geoAreaBundle.ID).Include(x => x.GeoAreaBundles).FirstOrDefault().GeoAreaBundles; if (geoAreaBundle.GeoAreaBundles == null) { geoAreaBundle.GeoAreaBundles = new List <GeoAreaBundle>(); } geoAreaBundle.GeoAreaBundles.Clear(); var childGeoAreas = db.GeoAreas.Where(x => geo_area_ids.Contains(x.ID)).ToList(); foreach (var geoArea in childGeoAreas) { geoAreaBundle.GeoAreaBundles.Add(new GeoAreaBundle() { ChildGeoAreaID = geoArea.ID, }); } db.SaveChanges(); Log(LogAction.Update, geoAreaBundle); return(RedirectToAction("Index")); } GeoArea.Types.Reverse(); ViewBag.GeoAreaTypes = GeoArea.Types; ViewBag.GeoAreas = db.GeoAreas.Where(x => x.Type != "Bundle").ToList(); return(View(geoAreaBundle)); }
private List <CalculatedValue> GetData(int indicatorId, int[] geoAreaIds, int[] years) { List <CalculatedValue> result = new List <CalculatedValue>(); Indicator indicator = db.Indicators.Where(x => x.ID == indicatorId).FirstOrDefault(); if (indicator == null) { throw new Exception("Indicator Not Found"); } foreach (int geoAreaId in geoAreaIds) { GeoArea geoArea = db.GeoAreas.Where(x => x.ID == geoAreaId).FirstOrDefault(); if (geoArea == null) { throw new Exception("GeoArea Not Found"); } foreach (int year in years) { var calcVal = db.CalculatedValues .Where(x => x.GeoAreaID == geoAreaId && x.EquationYear.Equation.IndicatorID == indicatorId && x.EquationYear.Year == year) .Include(x => x.GeoArea) .Include(x => x.EquationYear.Equation.Indicator) .FirstOrDefault(); if (calcVal != null) { result.Add(calcVal); } } } return(result); }
/// <summary> /// Take a path provided by a user, draw it as a maptile. Potentially useful for exercise trackers. Resulting file must not be saved to the server as that would be user tracking. /// </summary> /// <param name="pointListAsString">a string of points separate by , and | </param> /// <returns>the png file with the path drawn over the mapdata in the area.</returns> public byte[] DrawUserPath(string pointListAsString) { //String is formatted as Lat,Lon~Lat,Lon~ repeating. Characters chosen to not be percent-encoded if submitted as part of the URL. //first, convert this to a list of latlon points string[] pointToConvert = pointListAsString.Split("|"); List <Coordinate> coords = pointToConvert.Select(p => new Coordinate(double.Parse(p.Split(',')[0]), double.Parse(p.Split(',')[1]))).ToList(); var mapBuffer = resolutionCell8 / 2; //Leave some area around the edges of where they went. GeoArea mapToDraw = new GeoArea(coords.Min(c => c.Y) - mapBuffer, coords.Min(c => c.X) - mapBuffer, coords.Max(c => c.Y) + mapBuffer, coords.Max(c => c.X) + mapBuffer); ImageStats info = new ImageStats(mapToDraw, 1024, 1024); LineString line = new LineString(coords.ToArray()); var drawableLine = PolygonToDrawingLine(line, mapToDraw, info.degreesPerPixelX, info.degreesPerPixelY); //Now, draw that path on the map. var places = GetPlaces(mapToDraw); var baseImage = DrawAreaAtSize(info, places); Image <Rgba32> image = new Image <Rgba32>(info.imageSizeX, info.imageSizeY); Rgba32 strokeColor = Rgba32.ParseHex("000000"); image.Mutate(x => x.Draw(strokeColor, 4, new SixLabors.ImageSharp.Drawing.Path(drawableLine))); image.Mutate(x => x.Flip(FlipMode.Vertical)); //Plus codes are south-to-north, so invert the image to make it correct. var ms = new MemoryStream(); image.SaveAsPng(ms); return(ms.ToArray()); }
public GeoArea SetServerBounds(long singleArea) { //This is an important command if you don't want to track data outside of your initial area. GeoArea results = null; if (singleArea != 0) { var area = Places.First(e => e.SourceItemID == singleArea); var envelop = area.ElementGeometry.EnvelopeInternal; results = new GeoArea(envelop.MinY, envelop.MinX, envelop.MaxY, envelop.MaxX); } else { results = Place.DetectServerBounds(ConstantValues.resolutionCell8); } var settings = ServerSettings.FirstOrDefault(); settings.NorthBound = results.NorthLatitude; settings.SouthBound = results.SouthLatitude; settings.EastBound = results.EastLongitude; settings.WestBound = results.WestLongitude; SaveChanges(); return(results); }
public string GetPlusCodeTerrainDataFull(string plusCode) { //This function returns 1 line per Cell10 per intersecting element. For an app that needs to know all things in all points. PerformanceTracker pt = new PerformanceTracker("GetPlusCodeTerrainDataFull"); GeoArea box = OpenLocationCode.DecodeValid(plusCode); if (!DataCheck.IsInBounds(cache.Get <IPreparedGeometry>("serverBounds"), box)) { return(""); } var places = GetPlaces(box); //All the places in this Cell8 places = places.Where(p => p.GameElementName != TagParser.defaultStyle.Name).ToList(); StringBuilder sb = new StringBuilder(); //pluscode|name|type|privacyID(named wrong but its the Guid) var data = AreaTypeInfo.SearchAreaFull(ref box, ref places); foreach (var d in data) { foreach (var v in d.Value) { sb.Append(d.Key).Append("|").Append(v.Name).Append("|").Append(v.areaType).Append("|").Append(v.PrivacyId).Append("\r\n"); } } var results = sb.ToString(); pt.Stop(plusCode); return(results); }
public string GetPlusCodeTerrainData(string plusCode) { //This function returns 1 line per Cell10, the smallest (and therefore highest priority) item intersecting that cell10. PerformanceTracker pt = new PerformanceTracker("GetPlusCodeTerrainData"); GeoArea box = OpenLocationCode.DecodeValid(plusCode); if (!DataCheck.IsInBounds(cache.Get <IPreparedGeometry>("serverBounds"), box)) { return(""); } var places = GetPlaces(box); places = places.Where(p => p.GameElementName != TagParser.defaultStyle.Name).ToList(); StringBuilder sb = new StringBuilder(); //pluscode|name|type|PrivacyID var data = AreaTypeInfo.SearchArea(ref box, ref places); foreach (var d in data) { sb.Append(d.Key).Append("|").Append(d.Value.Name).Append("|").Append(d.Value.areaType).Append("|").Append(d.Value.PrivacyId).Append("\r\n"); } var results = sb.ToString(); pt.Stop(plusCode); return(results); }
/// <summary> /// Creates a new ImageStats for a set of SlippyMap parameters. /// Default slippy tiles are drawn at 512x512 versus the standard 256x256. Setting your Slippymap view's zoom offset to -1 creates an identical experience for the user. /// </summary> /// <param name="zoomLevel">Integer 2-20, per SlippyMap conventions</param> /// <param name="xTile">X coords of the requested tile</param> /// <param name="yTile">Y coords of the requested tile</param> /// <param name="imageSize">Image width in pixels. Usually 512 in PraxisMapper</param> public ImageStats(int zoomLevel, int xTile, int yTile, int imageSize) { //Slippy map parameters var n = Math.Pow(2, zoomLevel); var lon_degree_w = xTile / n * 360 - 180; var lon_degree_e = (xTile + 1) / n * 360 - 180; var lat_rads_n = Math.Atan(Math.Sinh(Math.PI * (1 - 2 * yTile / n))); var lat_degree_n = lat_rads_n * 180 / Math.PI; var lat_rads_s = Math.Atan(Math.Sinh(Math.PI * (1 - 2 * (yTile + 1) / n))); var lat_degree_s = lat_rads_s * 180 / Math.PI; var areaHeightDegrees = lat_degree_n - lat_degree_s; var areaWidthDegrees = 360 / n; area = new GeoArea(lat_degree_s, lon_degree_w, lat_degree_n, lon_degree_e); imageSizeX = imageSize; imageSizeY = imageSize; degreesPerPixelX = areaWidthDegrees / imageSize; degreesPerPixelY = areaHeightDegrees / imageSize; pixelsPerDegreeX = imageSize / areaWidthDegrees; pixelsPerDegreeY = imageSize / areaHeightDegrees; }
/// <summary> /// Draws grid lines to match boundaries for 10 character PlusCodes. /// </summary> /// <param name="totalArea">the GeoArea to draw lines in</param> /// <returns>the byte array for the maptile png file</returns> public byte[] DrawCell10GridLines(GeoArea totalArea) { int imageSizeX = IMapTiles.SlippyTileSizeSquare; int imageSizeY = IMapTiles.SlippyTileSizeSquare; SKBitmap bitmap = new SKBitmap(imageSizeX, imageSizeY, SKColorType.Rgba8888, SKAlphaType.Premul); SKCanvas canvas = new SKCanvas(bitmap); var bgColor = new SKColor(); SKColor.TryParse("00000000", out bgColor); canvas.Clear(bgColor); canvas.Scale(1, -1, imageSizeX / 2, imageSizeY / 2); SKPaint paint = new SKPaint(); SKColor color = new SKColor(); SKColor.TryParse("#00CCFF", out color); paint.Color = color; paint.Style = SKPaintStyle.Stroke; paint.StrokeWidth = 1; paint.IsAntialias = true; double degreesPerPixelX = totalArea.LongitudeWidth / imageSizeX; double degreesPerPixelY = totalArea.LatitudeHeight / imageSizeY; //This is hardcoded to Cell 8 spaced gridlines. var imageLeft = totalArea.WestLongitude; var spaceToFirstLineLeft = (imageLeft % resolutionCell10); var imageBottom = totalArea.SouthLatitude; var spaceToFirstLineBottom = (imageBottom % resolutionCell10); double lonLineTrackerDegrees = imageLeft - spaceToFirstLineLeft; //This is degree coords while (lonLineTrackerDegrees <= totalArea.EastLongitude + resolutionCell10) //This means we should always draw at least 2 lines, even if they're off-canvas. { var geoLine = new LineString(new Coordinate[] { new Coordinate(lonLineTrackerDegrees, 90), new Coordinate(lonLineTrackerDegrees, -90) }); var points = PolygonToSKPoints(geoLine, totalArea, degreesPerPixelX, degreesPerPixelY); canvas.DrawLine(points[0], points[1], paint); lonLineTrackerDegrees += resolutionCell10; } double latLineTrackerDegrees = imageBottom - spaceToFirstLineBottom; //This is degree coords while (latLineTrackerDegrees <= totalArea.NorthLatitude + resolutionCell10) //This means we should always draw at least 2 lines, even if they're off-canvas. { var geoLine = new LineString(new Coordinate[] { new Coordinate(180, latLineTrackerDegrees), new Coordinate(-180, latLineTrackerDegrees) }); var points = PolygonToSKPoints(geoLine, totalArea, degreesPerPixelX, degreesPerPixelY); canvas.DrawLine(points[0], points[1], paint); latLineTrackerDegrees += resolutionCell10; } var ms = new MemoryStream(); var skms = new SkiaSharp.SKManagedWStream(ms); bitmap.Encode(skms, SkiaSharp.SKEncodedImageFormat.Png, 100); var results = ms.ToArray(); skms.Dispose(); ms.Close(); ms.Dispose(); return(results); }
//This is for getting all places that have a specific TagParser style/match. Admin boundaries, parks, etc. /// <summary> /// Pull in all elements from a list that have a given style. /// </summary> /// <param name="type">the name of the style to select elements for</param> /// <param name="area">the GeoArea to select elements from.</param> /// <param name="places">A list of OSM Elements to search. If null, loaded from the database based on the area provided.</param> /// <returns>a list of OSM Elements with the requested style in the given area.</returns> public static List <DbTables.Place> GetPlacesByStyle(string type, GeoArea area, List <DbTables.Place> places = null) { if (places == null) { places = GetPlaces(area); } return(places.Where(p => p.GameElementName == type).ToList()); }
public ActionResult DeleteConfirmed(int id) { GeoArea geoarea = db.GeoAreas.Find(id); db.GeoAreas.Remove(geoarea); db.SaveChanges(); return(RedirectToAction("Index")); }
/// <summary> /// Create an index table for the standalone offline game db. Takes everything inside a 6 digit PlusCode area, and save a list of elements inside it. /// </summary> /// <param name="buffered">the GeoArea to generate this indexed lookup for</param> /// <param name="allPlaces">the elements to search while making the index</param> /// <returns>a Dictionary of 6 digit PlusCodes and the list of OSM elements that intersect it. </returns> public static ConcurrentDictionary <string, List <DbTables.Place> > IndexAreasPerCell6(GeoArea buffered, List <DbTables.Place> allPlaces) { //NOTE: this could use the same optimization I applied to drawing map tiles var intersectCheck = Converters.GeoAreaToPolygon(buffered); //start drawing maptiles and sorting out data. var swCorner = new OpenLocationCode(intersectCheck.EnvelopeInternal.MinY, intersectCheck.EnvelopeInternal.MinX); var neCorner = new OpenLocationCode(intersectCheck.EnvelopeInternal.MaxY, intersectCheck.EnvelopeInternal.MaxX); //declare how many map tiles will be checked var xTiles = buffered.LongitudeWidth / resolutionCell6; var yTiles = buffered.LatitudeHeight / resolutionCell6; var totalTiles = Math.Truncate(xTiles * yTiles); var yCoords = new List <double>(); var yVal = swCorner.Decode().SouthLatitude; while (yVal <= neCorner.Decode().NorthLatitude) { yCoords.Add(yVal); yVal += resolutionCell6; } var xCoords = new List <double>(); var xVal = swCorner.Decode().WestLongitude; while (xVal <= neCorner.Decode().EastLongitude) { xCoords.Add(xVal); xVal += resolutionCell6; } ConcurrentDictionary <string, List <DbTables.Place> > results = new ConcurrentDictionary <string, List <DbTables.Place> >(); foreach (var y in yCoords) { //Make a collision box for just this row of Cell8s, and send the loop below just the list of things that might be relevant. //Add a Cell8 buffer space so all elements are loaded and drawn without needing to loop through the entire area. GeoArea thisRow = new GeoArea(y - ConstantValues.resolutionCell8, xCoords.First() - ConstantValues.resolutionCell8, y + ConstantValues.resolutionCell8 + ConstantValues.resolutionCell8, xCoords.Last() + resolutionCell8); var row = Converters.GeoAreaToPolygon(thisRow); var rowList = allPlaces.Where(a => row.Intersects(a.ElementGeometry)).ToList(); Parallel.ForEach(xCoords, x => //foreach (var x in xCoords) { var plusCode = new OpenLocationCode(y, x, 10); var plusCode6 = plusCode.CodeDigits.Substring(0, 6); var plusCodeArea = OpenLocationCode.DecodeValid(plusCode6); var areaForTile = new GeoArea(new GeoPoint(plusCodeArea.SouthLatitude, plusCodeArea.WestLongitude), new GeoPoint(plusCodeArea.NorthLatitude, plusCodeArea.EastLongitude)); var acheck = Converters.GeoAreaToPolygon(areaForTile); //this is faster than using a PreparedPolygon in testing, which was unexpected. var areaList = rowList.Where(a => acheck.Intersects(a.ElementGeometry)).ToList(); results.TryAdd(plusCode6, areaList); }); } return(results); }
public LinearLineSegment PolygonToDrawingLine(Geometry place, GeoArea drawingArea, double resolutionX, double resolutionY) { //NOTE: this doesn't handle holes if you add them to the end in the reverse order. Those must be handled by a function in ImageSharp. var typeConvertedPoints = place.Coordinates.Select(o => new SixLabors.ImageSharp.PointF((float)((o.X - drawingArea.WestLongitude) * (1 / resolutionX)), (float)((o.Y - drawingArea.SouthLatitude) * (1 / resolutionY)))); LinearLineSegment part = new LinearLineSegment(typeConvertedPoints.ToArray()); var x = new SixLabors.ImageSharp.Drawing.Path(); return(part); }
/// <summary> /// Determine if a GeoArea (presumably from a PlusCode) intersects with the data contained in the server. /// </summary> /// <param name="bounds">PreparedGeometry representing the server's usable boundaries</param> /// <param name="place">GeoArea to check against the server's bounds</param> /// <returns>true if the 2 parameters intersect, or false if they do not.</returns> public static bool IsInBounds(IPreparedGeometry bounds, GeoArea place) { if (DisableBoundsCheck || bounds.Intersects(Converters.GeoAreaToPolygon(place))) { return(true); } return(false); }
public JsonResult GeoAreas() { var geoAreaID = Request["GeoAreaID"]; var equationYearID = Request["EquationYearID"]; var action = Request["action"]; string[] elementValuesKeys = Request.Form.AllKeys.Where(x => x.StartsWith("ElementValue_")).ToArray(); GeoArea geoArea = null; EquationYear equationYear = null; if (!string.IsNullOrWhiteSpace(geoAreaID)) { geoArea = db.GeoAreas.Find(int.Parse(geoAreaID)); } if (!string.IsNullOrWhiteSpace(geoAreaID)) { int _equationYearID = int.Parse(equationYearID); equationYear = db.EquationYears.Include(x => x.Equation.Indicator).Where(x => x.ID == _equationYearID).FirstOrDefault(); } if (equationYear == null || geoArea == null) { return(Json(new { success = false, error = "برجاء إدخال بيانات صحيحة" })); } string userId = User.Identity.GetUserId(); try { var calculate = false; if (action.Equals("delete")) { DeleteUpdate(geoArea, equationYear); DeleteCalculated(geoArea, equationYear); } else if (action.Equals("add")) { calculate = AddUpdate(geoArea, equationYear, userId, elementValuesKeys); } else if (action.Equals("edit")) { calculate = EditUpdate(geoArea, equationYear, userId, elementValuesKeys); } DeleteCalculated(geoArea, equationYear); if ((action.Equals("add") || action.Equals("edit")) && calculate) { double value = CalculateEquation(equationYear, geoArea); Commit(geoArea, equationYear, value); } db.SaveChanges(); UpdateLog(geoArea, equationYear, action); } catch (Exception ex) { return(Json(new { success = false, error = "برجاء إدخال بيانات صحيحة" })); } return(Json(new { success = true, action })); }
private void DeleteCalculated(GeoArea geoArea, EquationYear equationYear) { var oldCalculatedValues = db.CalculatedValues.Where(x => x.EquationYearID == equationYear.ID && x.GeoAreaID == geoArea.ID).ToList(); for (int i = oldCalculatedValues.Count - 1; i >= 0; i--) { db.CalculatedValues.Remove(oldCalculatedValues[i]); } }
private bool AddUpdate(GeoArea geoArea, EquationYear equationYear, string userId, string[] elementValuesKeys) { var calculate = true; string values = ""; var elementIds = new List <int>(); foreach (string evs in elementValuesKeys) { string eeId = evs.Replace("ElementValue_", ""); EquationElement equationElement = db.EquationElements.Find(int.Parse(eeId)); if (equationElement == null) { throw new Exception("Equation Element Not Found"); } string strValue = Request[evs].Trim(); double _fValue = 0; double?fValue = null; if (string.IsNullOrEmpty(strValue) || double.TryParse(strValue, out _fValue)) { if (!string.IsNullOrEmpty(strValue)) { fValue = _fValue; } else { calculate = false; } values += string.Format("{0} : {1}\r\n", equationElement.Element.Name, strValue); var createdAt = DateTime.Now; var elementValue = new ElementValue() { EquationElementID = equationElement.ID, EquationYearID = equationYear.ID, GeoAreaID = geoArea.ID, Value = fValue, ApplicationUserID = userId, CreatedAt = createdAt, }; db.ElementValues.Add(elementValue); elementIds.Add(equationElement.ElementID); } else { throw new Exception("Value is in correct"); } } if (calculate) { var elementYearValues = db.ElementYearValues.Where(x => x.GeoAreaID == geoArea.ID && x.Year == equationYear.Year && elementIds.Contains(x.ElementID)).ToList(); foreach (var eyv in elementYearValues) { eyv.IsCommited = true; db.Entry(eyv).State = EntityState.Modified; } } return(calculate); }
public void Fill() { var area = new GeoArea(); Rand.Fill(area); Assert.True(area.Code > 0); Assert.NotEmpty(area.Name); }
private GeoArea GetModel() { var model = new GeoArea { Code = Rand.Next(), Name = Rand.NextString(14), }; return(model); }
public ActionResult Edit(GeoArea geoarea) { if (ModelState.IsValid) { db.Entry(geoarea).State = EntityState.Modified; db.SaveChanges(); return(RedirectToAction("Index")); } return(View("Create", geoarea)); }
private string SetType(string type) { if (string.IsNullOrWhiteSpace(type) || !GeoArea.Types.ContainsKey(type)) { type = "Region"; } ViewBag.Type = type; ViewBag.TypeName = GeoArea.Types[type]; ViewBag.Parent = GeoArea.GetParentName(type); ViewBag.ParentName = GeoArea.Types[GeoArea.GetParentName(type)]; return(type); }
/// <summary> /// Converts an NTS Geometry object into a GeoArea object matching the Geometry's internal envelope. /// </summary> /// <param name="g">The NTS Geometry object to convert</param> /// <returns>the GeoArea covering the Geometry's internal envelope, or null if the conversion fails.</returns> public static GeoArea GeometryToGeoArea(Geometry g) { try { GeoArea results = new GeoArea(g.EnvelopeInternal.MinY, g.EnvelopeInternal.MinX, g.EnvelopeInternal.MaxY, g.EnvelopeInternal.MaxX); return(results); } catch (Exception ex) { return(null); } }
/// <summary> /// Converts a GeoArea into a NTS coordinate array /// </summary> /// <param name="plusCodeArea">The GeoArea to convert</param> /// <returns>a Coordinate array using the GeoArea's boundaries</returns> public static Coordinate[] GeoAreaToCoordArray(GeoArea plusCodeArea) { var cord1 = new Coordinate(plusCodeArea.Min.Longitude, plusCodeArea.Min.Latitude); var cord2 = new Coordinate(plusCodeArea.Min.Longitude, plusCodeArea.Max.Latitude); var cord3 = new Coordinate(plusCodeArea.Max.Longitude, plusCodeArea.Max.Latitude); var cord4 = new Coordinate(plusCodeArea.Max.Longitude, plusCodeArea.Min.Latitude); var cordSeq = new Coordinate[5] { cord4, cord3, cord2, cord1, cord4 }; return(cordSeq); }
public ActionResult Create(GeoArea geoarea) { if (ModelState.IsValid) { Guid userID = (Guid)Membership.GetUser().ProviderUserKey; geoarea.User = db.Users.Find(userID); db.GeoAreas.Add(geoarea); db.SaveChanges(); return(RedirectToAction("Index")); } return(View(geoarea)); }
/// <summary> /// Creates a new ImageStats for a given GeoArea from a PlusCode to match the defined width and height. /// Plus Codes are usually rendered at a 4:5 aspect ratio in Praxismapper due to defining a base pixel as an 11-char PlusCode /// </summary> /// <param name="geoArea">Decoded pluscode, or converted coordinates into a GeoArea</param> /// <param name="imageWidth">image width in pixels</param> /// <param name="imageHeight">image height in pixels</param> public ImageStats(GeoArea geoArea, int imageWidth, int imageHeight) { //Pluscode parameters imageSizeX = imageWidth; imageSizeY = imageHeight; area = geoArea; degreesPerPixelX = area.LongitudeWidth / imageSizeX; degreesPerPixelY = area.LatitudeHeight / imageSizeY; pixelsPerDegreeX = imageSizeX / area.LongitudeWidth; pixelsPerDegreeY = imageSizeY / area.LatitudeHeight; }