示例#1
0
        public string GetStyleSetEntryValues(string styleSet, string entryName)
        {
            var db   = new PraxisContext();
            var data = db.StyleEntries.FirstOrDefault(t => t.StyleSet == styleSet && t.Name == entryName);

            return(data.MatchOrder + "|" + data.Name + "|" + data.IsGameElement + "|" + data.Id);
        }
示例#2
0
        private static void createDb()
        {
            Log.WriteLog("Creating database with current database settings.");
            var db = new PraxisContext();

            db.MakePraxisDB();
        }
示例#3
0
        public string GetStyleSetEntryNames(string styleSet)
        {
            var db   = new PraxisContext();
            var data = db.StyleEntries.Where(t => t.StyleSet == styleSet).OrderBy(t => t.MatchOrder).Select(t => t.Name).ToList();

            return(string.Join('|', data));
        }
        public string PerfData(string password)
        {
            if (password != Configuration.GetValue <string>("adminPwd"))
            {
                return("");
            }

            var db     = new PraxisContext();
            var groups = db.PerformanceInfo.Where(p => p.CalledAt > DateTime.Now.AddDays(-7)).AsEnumerable().GroupBy(g => g.FunctionName).OrderBy(g => g.Key).ToList();
            var avgs   = groups.Select(g => new { name = g.Key, avg = g.Average(gg => gg.RunTime) }).ToList();

            string results = "Performance Info:" + Environment.NewLine;

            results = "Averages:" + Environment.NewLine;
            foreach (var a in avgs)
            {
                results += a.name + ":" + a.avg + Environment.NewLine;
            }
            results += Environment.NewLine;

            results += "Maximums:" + Environment.NewLine;
            foreach (var g in groups)
            {
                results += g.Key + ":" + g.Max(gg => gg.RunTime) + Environment.NewLine;
            }
            results += Environment.NewLine;

            results += "Call Counts:" + Environment.NewLine;
            foreach (var g in groups)
            {
                results += g.Key + ":" + g.Count() + Environment.NewLine;
            }

            return(results);
        }
示例#5
0
        private byte[] FinishSlippyMapTile(ImageStats info, List <CompletePaintOp> paintOps, string tileKey, string styleSet)
        {
            byte[] results = null;
            results = MapTiles.DrawAreaAtSize(info, paintOps);

            if (!SaveMapTiles())
            {
                var db = new PraxisContext();
                var existingResults = db.SlippyMapTiles.FirstOrDefault(mt => mt.Values == tileKey && mt.StyleSet == styleSet);
                if (existingResults == null)
                {
                    existingResults = new SlippyMapTile()
                    {
                        Values = tileKey, StyleSet = styleSet, AreaCovered = Converters.GeoAreaToPolygon(GeometrySupport.MakeBufferedGeoArea(info.area))
                    };
                    db.SlippyMapTiles.Add(existingResults);
                }

                existingResults.ExpireOn = DateTime.Now.AddYears(10);
                existingResults.TileData = results;
                existingResults.GenerationID++;
                db.SaveChanges();
            }

            return(results);
        }
        public ActionResult GetPlaceInfo(long sourceElementId, int sourceElementType)
        {
            var db   = new PraxisContext();
            var area = db.Places.Include(e => e.Tags).FirstOrDefault(e => e.SourceItemID == sourceElementId && e.SourceItemType == sourceElementType);

            if (area == null)
            {
                return(View());
            }

            TagParser.ApplyTags(new System.Collections.Generic.List <DbTables.Place>()
            {
                area
            }, "mapTiles");
            ViewBag.areaname = TagParser.GetPlaceName(area.Tags);
            ViewBag.type     = area.GameElementName;

            var geoarea = Converters.GeometryToGeoArea(area.ElementGeometry.Envelope);

            geoarea = new Google.OpenLocationCode.GeoArea(geoarea.SouthLatitude - ConstantValues.resolutionCell10,
                                                          geoarea.WestLongitude - ConstantValues.resolutionCell10,
                                                          geoarea.NorthLatitude + ConstantValues.resolutionCell10,
                                                          geoarea.EastLongitude + ConstantValues.resolutionCell10); //add some padding to the edges.
            ImageStats istats = new ImageStats(geoarea, (int)(geoarea.LongitudeWidth / ConstantValues.resolutionCell11Lon), (int)(geoarea.LatitudeHeight / ConstantValues.resolutionCell11Lat));

            //sanity check: we don't want to draw stuff that won't fit in memory, so check for size and cap it if needed
            if (istats.imageSizeX * istats.imageSizeY > 8000000)
            {
                var ratio   = geoarea.LongitudeWidth / geoarea.LatitudeHeight; //W:H,
                var newSize = (istats.imageSizeY > 2000 ? 2000 : istats.imageSizeY);
                istats = new ImageStats(geoarea, (int)(newSize * ratio), newSize);
            }
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            //var tileSvg = MapTiles.DrawAreaAtSizeSVG(istats); ViewBag.UseSvg = true;
            var tile = MapTiles.DrawAreaAtSize(istats); ViewBag.UseSvg = false;

            sw.Stop();

            ViewBag.imageString = "data:image/png;base64," + Convert.ToBase64String(tile);
            //ViewBag.imageString = tileSvg.Substring(39); //skip the <xml> tag
            ViewBag.timeToDraw  = sw.Elapsed;
            ViewBag.placeCount  = 0;
            ViewBag.areasByType = "";
            var places = Place.GetPlaces(istats.area);

            ViewBag.placeCount = places.Count();
            var    grouped     = places.GroupBy(p => p.GameElementName);
            string areasByType = "";

            foreach (var g in grouped)
            {
                areasByType += g.Key + g.Count() + "<br />";
            }

            ViewBag.areasByType = areasByType;

            return(View());
        }
示例#7
0
        public void StopSproc()
        {
            sw.Stop();
            PraxisContext db = new PraxisContext();

            db.Database.ExecuteSqlRaw("SavePerfInfo @p0, @p1, @p2, @p3", parameters: new object[] { pi.FunctionName, sw.ElapsedMilliseconds, pi.CalledAt, "" });
            return;
        }
示例#8
0
        public void Stop()
        {
            sw.Stop();
            pi.RunTime = sw.ElapsedMilliseconds;
            PraxisContext db = new PraxisContext();

            db.PerformanceInfo.Add(pi);
            db.SaveChanges();
            return;
        }
        public int DeleteUser(string deviceId)
        {
            //GDPR compliance requires this to exist and be available to the user.
            //Custom games that attach players to locations may need additional logic to fully meet legal requirements.
            var db       = new PraxisContext();
            var removing = db.PlayerData.Where(p => p.DeviceID == deviceId).ToArray();

            db.PlayerData.RemoveRange(removing);
            return(db.SaveChanges());
        }
示例#10
0
        public void StopNoChangeTracking()
        {
            sw.Stop();
            pi.RunTime = sw.ElapsedMilliseconds;
            PraxisContext db = new PraxisContext();

            db.ChangeTracker.AutoDetectChangesEnabled = false;
            db.PerformanceInfo.Add(pi);
            db.SaveChanges();
            return;
        }
        public double GetDistanceToPlace(Guid elementId, double lat, double lon)
        {
            var db    = new PraxisContext();
            var place = db.Places.FirstOrDefault(e => e.PrivacyId == elementId);

            if (place == null)
            {
                return(0);
            }
            return(place.ElementGeometry.Distance(new NetTopologySuite.Geometries.Point(lon, lat)));
        }
示例#12
0
        public void UpdateStyleSetEntryValues(string styleSet, long id, int matchOrder, string entryName, bool isGameElement)
        {
            //Hasnt yet been tested.
            var db   = new PraxisContext();
            var data = db.StyleEntries.FirstOrDefault(t => t.Id == id);

            data.MatchOrder    = matchOrder;
            data.Name          = entryName;
            data.IsGameElement = isGameElement;
            db.SaveChanges();
        }
        public ActionResult GetPlaceInfo(Guid privacyId)
        {
            var db   = new PraxisContext();
            var area = db.Places.Include(e => e.Tags).FirstOrDefault(e => e.PrivacyId == privacyId);

            if (area != null)
            {
                return(GetPlaceInfo(area.SourceItemID, area.SourceItemType));
            }

            return(null);
        }
示例#14
0
        public static void LogError(Exception ex)
        {
            var el = new DbTables.ErrorLog();

            el.Message    = ex.Message;
            el.StackTrace = ex.StackTrace;
            el.LoggedAt   = DateTime.Now;
            var db = new PraxisContext();

            db.ChangeTracker.AutoDetectChangesEnabled = false;
            db.ErrorLogs.Add(el);
            db.SaveChanges();
        }
        public string GetCenterOfPlace(Guid elementId)
        {
            var db    = new PraxisContext();
            var place = db.Places.FirstOrDefault(e => e.PrivacyId == elementId);

            if (place == null)
            {
                return("0|0");
            }
            var center = place.ElementGeometry.Centroid;

            return(center.Y.ToString() + "|" + center.X.ToString());
        }
        public DataController(IConfiguration configuration, IMemoryCache memoryCacheSingleton)
        {
            Configuration = configuration;
            cache         = memoryCacheSingleton;

            if (lastExpiryPass < DateTime.Now)
            {
                var db = new PraxisContext();
                db.Database.ExecuteSqlRaw("DELETE FROM PlaceGameData WHERE expiration IS NOT NULL AND expiration < NOW()");
                db.Database.ExecuteSqlRaw("DELETE FROM AreaGameData WHERE expiration IS NOT NULL AND expiration < NOW()");
                db.Database.ExecuteSqlRaw("DELETE FROM PlayerData WHERE expiration IS NOT NULL AND expiration < NOW()");
                lastExpiryPass = DateTime.Now.AddMinutes(30);
            }
        }
        public ActionResult EditData()
        {
            //TODO: break these out into separate views when ready.
            Models.EditData model = new Models.EditData();
            var             db    = new PraxisContext();

            model.accessKey      = "?PraxisAuthKey=" + Configuration["serverAuthKey"];
            model.globalDataKeys = db.GlobalDataEntries.Select(g => new SelectListItem(g.DataKey, g.DataValue.ToUTF8String())).ToList();
            model.playerKeys     = db.PlayerData.Select(p => p.DeviceID).Distinct().Select(g => new SelectListItem(g, g)).ToList();

            model.stylesetKeys = db.StyleEntries.Select(t => t.StyleSet).Distinct().Select(t => new SelectListItem(t, t)).ToList();
            model.stylesetKeys.Insert(0, new SelectListItem("", ""));

            return(View(model));
        }
示例#18
0
        public void Stop(string notes)
        {
            if (!EnableLogging)
            {
                return;
            }
            sw.Stop();
            pi.RunTime = sw.ElapsedMilliseconds;
            pi.Notes   = notes;
            PraxisContext db = new PraxisContext();

            db.ChangeTracker.AutoDetectChangesEnabled = false; //Diabling this saves ~17ms per call, which can be important on the webserver. Sproc is trivially faster than this setup.
            db.PerformanceInfo.Add(pi);
            db.SaveChanges();
            return;
        }
示例#19
0
        public byte[] getExistingTile(string code, string styleSet)
        {
            if (!SaveMapTiles())
            {
                return(null);
            }

            var db = new PraxisContext();
            var existingResults = db.MapTiles.FirstOrDefault(mt => mt.PlusCode == code && mt.StyleSet == styleSet);

            if (existingResults == null || existingResults.ExpireOn < DateTime.Now)
            {
                return(null);
            }

            return(existingResults.TileData);
        }
示例#20
0
        public byte[] getExistingSlippyTile(string tileKey, string styleSet)
        {
            if (!SaveMapTiles())
            {
                return(null);
            }

            var db = new PraxisContext();
            var existingResults = db.SlippyMapTiles.FirstOrDefault(mt => mt.Values == tileKey && mt.StyleSet == styleSet);

            if (existingResults == null || existingResults.ExpireOn < DateTime.Now)
            {
                return(null);
            }

            return(existingResults.TileData);
        }
示例#21
0
        private static void DrawPosterOfServer()
        {
            var db     = new PraxisContext();
            var bounds = db.ServerSettings.First();

            var geoArea = new GeoArea(bounds.SouthBound, bounds.WestBound, bounds.NorthBound, bounds.EastBound);
            //do the math to scale image.
            //the smaller side is set to 24", the larger size scales up proportionally up to a max of 36"
            //if the longer side is > 36", scale both down by the difference?

            //36x24 is target poster size, at 300 dpi, our image size will allow for a half-inch of margin on both axes.
            var dpi      = 300;
            var maxXSide = 35 * dpi;
            var maxYSide = 23 * dpi;
            var xSize    = 0;
            var ySize    = 0;

            var heightScale = geoArea.LatitudeHeight / geoArea.LongitudeWidth; //Y pixels per X pixel

            if (heightScale > 1)                                               // Y axis is longer than X axis
            {
                heightScale = geoArea.LongitudeWidth / geoArea.LatitudeHeight;
                maxXSide    = 23 * dpi;
                maxYSide    = 35 * dpi;
                ySize       = maxYSide;
                xSize       = (int)(maxXSide * heightScale);
            }
            else
            {
                xSize = maxXSide;
                ySize = (int)(maxYSide * heightScale);
            }

            Log.WriteLog("Loading all places from DB");
            var places = GetPlaces(geoArea);
            var iStats = new ImageStats(geoArea, xSize, ySize);

            Log.WriteLog("Generating paint operations");
            var paintOps = MapTileSupport.GetPaintOpsForStoredElements(places, "mapTiles", iStats);

            Log.WriteLog("Drawing image");
            var image = MapTiles.DrawAreaAtSize(iStats, paintOps);

            File.WriteAllBytes("ServerPoster.png", image);
            Log.WriteLog("Image saved to disk");
        }
        public string TestDummyEndpoint()
        {
            //For debug purposes to confirm the server is running and reachable.
            string results = "Function OK";

            try
            {
                var DB    = new PraxisContext();
                var check = DB.PlayerData.FirstOrDefault();
                results += "|Database OK";
            }
            catch (Exception ex)
            {
                results += "|" + ex.Message + "|" + ex.StackTrace;
            }

            return(results);
        }
示例#23
0
        public JsonResult GetStyleJson(string styleSet)
        {
            var         db = new PraxisContext();
            JsonOptions jo = new JsonOptions();

            jo.JsonSerializerOptions.IncludeFields = true;
            jo.JsonSerializerOptions.MaxDepth      = 2;
            var data       = db.StyleEntries.Include("TagParserMatchRules").Include("paintOperations").Where(t => t.StyleSet == styleSet).ToList();
            var returnData = data.Select(x => new {
                x.Id,
                x.Name,
                x.StyleSet,
                x.IsGameElement,
                x.MatchOrder,
                paintOperations     = x.PaintOperations.Select(po => new { po.FileName, po.FillOrStroke, po.FromTag, po.HtmlColorCode, po.Id, po.LayerId, po.LinePattern, po.LineWidthDegrees, po.MaxDrawRes, po.MinDrawRes, po.Randomize }).ToList(),
                TagParserMatchRules = x.StyleMatchRules.Select(mr => new { mr.Id, mr.Key, mr.MatchType, mr.Value }).ToList()
            });

            return(Json(returnData));
        }
示例#24
0
        public static void UpdateExistingEntries(string path)
        {
            List <string>   filenames = Directory.EnumerateFiles(path, "*.geomData").ToList();
            ParallelOptions po        = new ParallelOptions();

            Parallel.ForEach(filenames, po, (filename) =>
            {
                try
                {
                    var db = new PraxisContext();
                    Log.WriteLog("Loading " + filename);
                    var entries = GeometrySupport.ReadStoredElementsFileToMemory(filename); //tagsData file loaded automatically here.
                    Log.WriteLog(entries.Count() + " entries to update in database for " + filename);
                    db.UpdateExistingEntries(entries);
                    File.Move(filename, filename + "Done");
                    Log.WriteLog(filename + " completed at " + DateTime.Now);
                }
                catch (Exception ex)
                {
                    Log.WriteLog("Error multithreading: " + ex.Message + ex.StackTrace, Log.VerbosityLevels.Errors);
                }
            });
        }
示例#25
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IMemoryCache cache)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            //app.UseHttpsRedirection(); //Testing using only http on app instead of https to allow me to use a personal PC while getting a server functional
            app.UseStaticFiles(new StaticFileOptions()
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "Content")), RequestPath = "/Content"
            });
            app.UseRouting();
            app.UseResponseCompression();

            app.UsePraxisHeaderCheck();
            app.UseGlobalErrorHandler();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            //Populate the memory cache with some data we won't edit until a restart occurs.
            var entryOptions = new MemoryCacheEntryOptions().SetPriority(CacheItemPriority.NeverRemove);

            var db       = new PraxisContext();
            var settings = db.ServerSettings.First();

            cache.Set <DbTables.ServerSetting>("settings", settings, entryOptions);
            var serverBounds = Converters.GeoAreaToPreparedPolygon(new Google.OpenLocationCode.GeoArea(settings.SouthBound, settings.WestBound, settings.NorthBound, settings.EastBound));

            cache.Set <IPreparedGeometry>("serverBounds", serverBounds, entryOptions);
            cache.Set("saveMapTiles", Configuration.GetValue <bool>("saveMapTiles"));

            Log.WriteLog("PraxisMapper configured and running.");
        }
示例#26
0
 public long GetSlippyTileGenerationId(string x, string y, string zoom, string styleSet)
 {
     //Returns generationID on the tile on the server
     //if value is *more* than previous value, client should refresh it.
     //if value is equal to previous value, tile has not changed.
     try
     {
         PerformanceTracker pt = new PerformanceTracker("GetTileGenerationId");
         var  db        = new PraxisContext();
         long tileGenId = -1;
         var  tile      = db.SlippyMapTiles.FirstOrDefault(m => m.Values == x + "|" + y + "|" + zoom && m.StyleSet == styleSet);
         if (tile != null)
         {
             tileGenId = tile.GenerationID;
         }
         pt.Stop();
         return(tileGenId);
     }
     catch (Exception ex)
     {
         ErrorLogger.LogError(ex);
         return(-1); //negative answers will be treated as an expiration.
     }
 }
示例#27
0
        public void ExpireTiles(Guid elementId, string styleSet)
        {
            var db = new PraxisContext();

            db.ExpireMapTiles(elementId, styleSet);
        }
        //These functions are for taking a PraxisMapper DB and making a workable mobile version. Much less accurate, requires 0 data connectivity.
        //No longer a high priority but I do want to keep this code around.

        public static void CreateStandaloneDB(long relationID = 0, GeoArea bounds = null, bool saveToDB = false, bool saveToFolder = true)
        {
            //TODO: could rename TerrainInfo to TrailInfo, terrainDataSmall to trailData

            string name = "";

            if (bounds != null)
            {
                name = Math.Truncate(bounds.SouthLatitude) + "_" + Math.Truncate(bounds.WestLongitude) + "_" + Math.Truncate(bounds.NorthLatitude) + "_" + Math.Truncate(bounds.EastLongitude) + ".sqlite";
            }

            if (relationID > 0)
            {
                name = relationID.ToString() + ".sqlite";
            }

            if (File.Exists(name))
            {
                File.Delete(name);
            }

            var mainDb   = new PraxisContext();
            var sqliteDb = new StandaloneContext(relationID.ToString());

            sqliteDb.ChangeTracker.AutoDetectChangesEnabled = false;
            sqliteDb.Database.EnsureCreated();
            Log.WriteLog("Standalone DB created for relation " + relationID + " at " + DateTime.Now);

            GeoArea buffered;

            if (relationID > 0)
            {
                var fullArea = mainDb.Places.FirstOrDefault(m => m.SourceItemID == relationID && m.SourceItemType == 3);
                if (fullArea == null)
                {
                    return;
                }

                buffered = Converters.GeometryToGeoArea(fullArea.ElementGeometry);
                //This should also be able to take a bounding box in addition in the future.
            }
            else
            {
                buffered = bounds;
            }

            //TODO: set a flag to allow this to pull straight from a PBF file?
            List <DbTables.Place> allPlaces = new List <DbTables.Place>();
            var  intersectCheck             = Converters.GeoAreaToPolygon(buffered);
            bool pullFromPbf = false; //Set via arg at startup? or setting file?

            if (!pullFromPbf)
            {
                allPlaces = PraxisCore.Place.GetPlaces(buffered);
            }
            else
            {
                //need a file to read from.
                //optionally a bounding box on that file.
                //Starting to think i might want to track some generic parameters I refer to later. like -box|s|w|n|e or -point|lat|long or -singleFile|here.osm.pbf
                //allPlaces = PbfFileParser.ProcessSkipDatabase();
            }

            Log.WriteLog("Loaded all intersecting geometry at " + DateTime.Now);

            string minCode          = new OpenLocationCode(buffered.SouthLatitude, buffered.WestLongitude).CodeDigits;
            string maxCode          = new OpenLocationCode(buffered.NorthLatitude, buffered.EastLongitude).CodeDigits;
            int    removableLetters = 0;

            for (int i = 0; i < 10; i++)
            {
                if (minCode[i] == maxCode[i])
                {
                    removableLetters++;
                }
                else
                {
                    i += 10;
                }
            }
            string commonStart = minCode.Substring(0, removableLetters);

            var wikiList = allPlaces.Where(a => a.Tags.Any(t => t.Key == "wikipedia") && TagParser.GetPlaceName(a.Tags) != "").Select(a => TagParser.GetPlaceName(a.Tags)).Distinct().ToList();
            //Leaving this nearly wide open, since it's not the main driver of DB size.
            var basePlaces    = allPlaces.Where(a => TagParser.GetPlaceName(a.Tags) != "" || a.GameElementName != "unmatched").ToList(); //.Where(a => a.name != "").ToList();// && (a.IsGameElement || wikiList.Contains(a.name))).ToList();
            var distinctNames = basePlaces.Select(p => TagParser.GetPlaceName(p.Tags)).Distinct().ToList();                              //This distinct might be causing things in multiple pieces to only detect one of them, not all of them?

            var placeInfo = PraxisCore.Standalone.Standalone.GetPlaceInfo(basePlaces);
            //Remove trails later.
            //SHORTCUT: for roads that are a straight-enough line (under 1 Cell10 in width or height)
            //just treat them as being 1 Cell10 in that axis, and skip tracking them by each Cell10 they cover.
            HashSet <long> skipEntries = new HashSet <long>();

            foreach (var pi in placeInfo.Where(p => p.areaType == "road" || p.areaType == "trail"))
            {
                //If a road is nearly a straight line, treat it as though it was 1 cell10 wide, and don't index its coverage per-cell later.
                if (pi.height <= ConstantValues.resolutionCell10 && pi.width >= ConstantValues.resolutionCell10)
                {
                    pi.height = ConstantValues.resolutionCell10; skipEntries.Add(pi.PlaceId);
                }
                else if (pi.height >= ConstantValues.resolutionCell10 && pi.width <= ConstantValues.resolutionCell10)
                {
                    pi.width = ConstantValues.resolutionCell10; skipEntries.Add(pi.PlaceId);
                }
            }

            sqliteDb.PlaceInfo2s.AddRange(placeInfo);
            sqliteDb.SaveChanges();
            Log.WriteLog("Processed geometry at " + DateTime.Now);
            var placeDictionary = placeInfo.ToDictionary(k => k.PlaceId, v => v);

            //to save time, i need to index which areas are in which Cell6.
            //So i know which entries I can skip when running.
            var indexCell6 = PraxisCore.Standalone.Standalone.IndexAreasPerCell6(buffered, basePlaces);
            var indexes    = indexCell6.SelectMany(i => i.Value.Select(v => new PlaceIndex()
            {
                PlusCode = i.Key, placeInfoId = placeDictionary[v.SourceItemID].id
            })).ToList();

            sqliteDb.PlaceIndexs.AddRange(indexes);

            sqliteDb.SaveChanges();
            Log.WriteLog("Processed Cell6 index table at " + DateTime.Now);

            //trails need processed the old way, per Cell10, when they're not simply a straight-line.
            //Roads too.
            var tdSmalls = new Dictionary <string, TerrainDataSmall>(); //Possible issue: a trail and a road with the same name would only show up as whichever one got in the DB first.
            var toRemove = new List <PlaceInfo2>();

            foreach (var trail in basePlaces.Where(p => (p.GameElementName == "trail" || p.GameElementName == "road"))) //TODO: add rivers here?
            {
                if (skipEntries.Contains(trail.SourceItemID))
                {
                    continue; //Don't per-cell index this one, we shifted it's envelope to handle it instead.
                }
                if (TagParser.GetPlaceName(trail.Tags) == "")
                {
                    continue; //So sorry, but there's too damn many roads without names inflating DB size without being useful as-is.
                }
                var p = placeDictionary[trail.SourceItemID];
                toRemove.Add(p);

                GeoArea thisPath = Converters.GeometryToGeoArea(trail.ElementGeometry);
                List <DbTables.Place> oneEntry = new List <DbTables.Place>();
                oneEntry.Add(trail);

                var overlapped = AreaTypeInfo.SearchArea(ref thisPath, ref oneEntry);
                if (overlapped.Count() > 0)
                {
                    tdSmalls.TryAdd(TagParser.GetPlaceName(trail.Tags), new TerrainDataSmall()
                    {
                        Name = TagParser.GetPlaceName(trail.Tags), areaType = trail.GameElementName
                    });
                }
                foreach (var o in overlapped)
                {
                    var ti = new TerrainInfo();
                    ti.PlusCode         = o.Key.Substring(removableLetters, 10 - removableLetters);
                    ti.TerrainDataSmall = new List <TerrainDataSmall>();
                    ti.TerrainDataSmall.Add(tdSmalls[o.Value.Name]);
                    sqliteDb.TerrainInfo.Add(ti);
                }
                sqliteDb.SaveChanges();
            }

            foreach (var r in toRemove.Distinct())
            {
                sqliteDb.PlaceInfo2s.Remove(r);
            }
            sqliteDb.SaveChanges();
            Log.WriteLog("Trails processed at " + DateTime.Now);

            //make scavenger hunts
            var sh = PraxisCore.Standalone.Standalone.GetScavengerHunts(allPlaces);

            sqliteDb.ScavengerHunts.AddRange(sh);
            sqliteDb.SaveChanges();
            Log.WriteLog("Auto-created scavenger hunt entries at " + DateTime.Now);

            var swCorner = new OpenLocationCode(intersectCheck.EnvelopeInternal.MinY, intersectCheck.EnvelopeInternal.MinX);
            var neCorner = new OpenLocationCode(intersectCheck.EnvelopeInternal.MaxY, intersectCheck.EnvelopeInternal.MaxX);

            //insert default entries for a new player.
            sqliteDb.PlayerStats.Add(new PlayerStats()
            {
                timePlayed = 0, distanceWalked = 0, score = 0
            });
            sqliteDb.Bounds.Add(new Bounds()
            {
                EastBound = neCorner.Decode().EastLongitude, NorthBound = neCorner.Decode().NorthLatitude, SouthBound = swCorner.Decode().SouthLatitude, WestBound = swCorner.Decode().WestLongitude, commonCodeLetters = commonStart, BestIdleCompletionTime = 0, LastPlayedOn = 0, StartedCurrentIdleRun = 0
            });
            sqliteDb.IdleStats.Add(new IdleStats()
            {
                emptySpacePerSecond = 0, emptySpaceTotal = 0, graveyardSpacePerSecond = 0, graveyardSpaceTotal = 0, natureReserveSpacePerSecond = 0, natureReserveSpaceTotal = 0, parkSpacePerSecond = 0, parkSpaceTotal = 0, touristSpacePerSecond = 0, touristSpaceTotal = 0, trailSpacePerSecond = 0, trailSpaceTotal = 0
            });
            sqliteDb.SaveChanges();

            //now we have the list of places we need to be concerned with.
            System.IO.Directory.CreateDirectory(relationID + "Tiles");
            PraxisCore.Standalone.Standalone.DrawMapTilesStandalone(relationID, buffered, allPlaces, saveToFolder);
            sqliteDb.SaveChanges();
            Log.WriteLog("Maptiles drawn at " + DateTime.Now);

            //Copy the files as necessary to their correct location.
            //if (saveToFolder)
            //Directory.Move(relationID + "Tiles", config["Solar2dExportFolder"] + "Tiles");

            //File.Copy(relationID + ".sqlite", config["Solar2dExportFolder"] + "database.sqlite");

            Log.WriteLog("Standalone gameplay DB done.");
        }
示例#29
0
        private static void loadProcessedData()
        {
            Log.WriteLog("Starting load from processed files at " + DateTime.Now);
            System.Diagnostics.Stopwatch fullProcess = new System.Diagnostics.Stopwatch();
            fullProcess.Start();
            PraxisContext db = new PraxisContext();

            db.Database.SetCommandTimeout(Int32.MaxValue);
            db.ChangeTracker.AutoDetectChangesEnabled = false;

            List <string> geomFilenames = Directory.EnumerateFiles(config["OutputDataFolder"], "*.geomData").ToList();
            List <string> tagsFilenames = Directory.EnumerateFiles(config["OutputDataFolder"], "*.tagsData").ToList();

            if (config["KeepElementsInMemory"] == "True") //ignore DB, doing some one-off operation.
            {
                //Skip database work. Use an in-memory list for a temporary operation.
                foreach (var fileName in geomFilenames)
                {
                    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                    Log.WriteLog("Loading " + fileName + " to memory at " + DateTime.Now);
                    var entries = File.ReadAllLines(fileName);
                    foreach (var entry in entries)
                    {
                        DbTables.Place stored = GeometrySupport.ConvertSingleTsvPlace(entry);
                        memorySource.Add(stored);
                    }

                    Log.WriteLog("File loaded to memory in " + sw.Elapsed);
                    sw.Stop();
                }
                foreach (var fileName in tagsFilenames)
                {
                    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                    Log.WriteLog("Loading " + fileName + " to memory at " + DateTime.Now);
                    var entries = File.ReadAllLines(fileName);
                    foreach (var entry in entries)
                    {
                        PlaceTags stored    = GeometrySupport.ConvertSingleTsvTag(entry);
                        var       taggedGeo = memorySource.First(m => m.SourceItemType == stored.SourceItemType && m.SourceItemID == stored.SourceItemId);
                        //MemorySource will need to be a more efficient collection for searching if this is to be a major feature, but this functions.
                        taggedGeo.Tags.Add(stored);
                    }

                    Log.WriteLog("File applied to memory in " + sw.Elapsed);
                    sw.Stop();
                }
                return;
            }
            else if (config["UseMariaDBInFile"] == "True") //Use the LOAD DATA INFILE command to skip the EF for loading.
            {
                foreach (var fileName in geomFilenames)
                {
                    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                    sw.Start();
                    var mariaPath = fileName.Replace("\\", "\\\\");
                    db.Database.ExecuteSqlRaw("LOAD DATA INFILE '" + mariaPath + "' IGNORE INTO TABLE Places fields terminated by '\t' lines terminated by '\r\n' (sourceItemID, sourceItemType, @elementGeometry, AreaSize, privacyId) SET elementGeometry = ST_GeomFromText(@elementGeometry) ");
                    sw.Stop();
                    Log.WriteLog("Geometry loaded from " + fileName + " in " + sw.Elapsed);
                    File.Move(fileName, fileName + "done");
                }

                foreach (var fileName in tagsFilenames)
                {
                    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                    sw.Start();
                    var mariaPath = fileName.Replace("\\", "\\\\");
                    db.Database.ExecuteSqlRaw("LOAD DATA INFILE '" + mariaPath + "' IGNORE INTO TABLE PlaceTags fields terminated by '\t' lines terminated by '\r\n' (SourceItemId, SourceItemType, `key`, `value`)");
                    sw.Stop();
                    Log.WriteLog("Tags loaded from " + fileName + " in " + sw.Elapsed);
                    File.Move(fileName, fileName + "done");
                }
            }
            else //Main path.
            {
                Parallel.ForEach(geomFilenames, fileName =>
                {
                    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                    sw.Start();
                    var db = new PraxisContext();
                    db.Database.SetCommandTimeout(Int32.MaxValue);
                    db.ChangeTracker.AutoDetectChangesEnabled = false;
                    var lines = File.ReadAllLines(fileName); //Might be faster to use streams and dodge the memory allocation?
                    foreach (var line in lines)
                    {
                        db.Places.Add(GeometrySupport.ConvertSingleTsvPlace(line));
                    }
                    db.SaveChanges();
                    sw.Stop();
                    Log.WriteLog("Geometry loaded from " + fileName + " in " + sw.Elapsed);
                    File.Move(fileName, fileName + "done");
                });
                Parallel.ForEach(tagsFilenames, fileName =>
                {
                    System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                    sw.Start();
                    var db = new PraxisContext();
                    db.Database.SetCommandTimeout(Int32.MaxValue);
                    db.ChangeTracker.AutoDetectChangesEnabled = false;
                    var lines = File.ReadAllLines(fileName);
                    foreach (var line in lines)
                    {
                        db.PlaceTags.Add(GeometrySupport.ConvertSingleTsvTag(line));
                    }
                    db.SaveChanges();
                    sw.Stop();
                    Log.WriteLog("Tags loaded from " + fileName + " in " + sw.Elapsed);
                    File.Move(fileName, fileName + "done");
                });
            }

            fullProcess.Stop();
            Log.WriteLog("Files processed in " + fullProcess.Elapsed);
            fullProcess.Restart();
            db.RecreateIndexes();
            fullProcess.Stop();
            Log.WriteLog("Indexes generated in " + fullProcess.Elapsed);
        }
示例#30
0
        static void Main(string[] args)
        {
            var builder = new ConfigurationBuilder()
                          .AddJsonFile("Larry.config.json");

            config = builder.Build();

            ApplyConfigValues();
            //If multiple args are supplied, run them in the order that make sense, not the order the args are supplied.
            if (args.Any(a => a == "-createDB")) //setup the destination database
            {
                createDb();
            }

            if (!args.Any(a => a == "-makeServerDb"))                                   //This will not be available until after creating the DB slightly later.
            {
                TagParser.Initialize(config["ForceStyleDefaults"] == "True", MapTiles); //This last bit of config must be done after DB creation check
            }
            Log.WriteLog("Larry started at " + DateTime.Now);

            if (args.Count() == 0)
            {
                Log.WriteLog("You must pass an arguement to this application", Log.VerbosityLevels.High);
                //TODO: list valid commands or point at the docs file
                return;
            }

            //if (args.Any(a => a.StartsWith("-getPbf:")))
            //{
            //    //Wants 3 pieces. Drops in placeholders if some are missing. Giving no parameters downloads Ohio.
            //    string arg = args.First(a => a.StartsWith("-getPbf:")).Replace("-getPbf:", "");
            //    var splitData = arg.Split('|'); //remember the first one will be empty.
            //    string level1 = splitData.Count() >= 4 ? splitData[3] : "north-america";
            //    string level2 = splitData.Count() >= 3 ? splitData[2] : "us";
            //    string level3 = splitData.Count() >= 2 ? splitData[1] : "ohio";

            //    DownloadPbfFile(level1, level2, level3, config["PbfFolder"]);
            //}

            if (args.Any(a => a == "-resetPbf"))
            {
                ResetFiles(config["PbfFolder"]);
            }

            if (args.Any(a => a == "-resetGeomData"))
            {
                ResetFiles(config["OutputDataFolder"]);
            }

            if (args.Any(a => a == "-resetStyles"))
            {
                var db = new PraxisContext();
                db.ResetStyles();
            }

            if (args.Any(a => a == "-processPbfs"))
            {
                processPbfs();
            }

            if (args.Any(a => a == "-loadProcessedData"))
            {
                loadProcessedData();
            }

            //This is the single command to get a server going, assuming you have done all the setup steps yourself beforehand and your config is correct.
            if (args.Any(a => a == "-makeServerDb"))
            {
                System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                sw.Start();
                SetEnvValues();
                var db = new PraxisContext();
                createDb();
                db.DropIndexes();
                processPbfs();
                loadProcessedData();
                db.SetServerBounds(long.Parse(config["UseOneRelationID"]));
                Log.WriteLog("Server setup complete in " + sw.Elapsed);
            }

            if (args.Any(a => a == "-makeWholeServer")) //Not a release 1 feature, but taking notes now.
            {
                SetEnvValues();
                //This is the wizard command, try to check and do everything at once.
                Log.WriteLog("Checking for installed DB per config (" + config["DbMode"] + ")");
                PraxisContext db;
                try
                {
                    db = new PraxisContext();
                }
                //Specific exceptions should hint at what to do, a general one covers ones I dont know how to handle.
                catch (Exception ex)
                {
                    Log.WriteLog("Hit an error checking for the existing database that I'm not sure how to handle:" + ex.Message);
                    return;
                }

                Log.WriteLog("Creating the Praxis DB per the connection string...");
                try
                {
                    createDb();
                }
                catch (Exception ex)
                {
                    //figure out why i can't create. Probably account settings?
                }

                PwdSpeedTest();


                //Check for MariaDB and install/configure if missing (including service account)
                //check for a PBF file and prompt to download one if none found
                //if data files are present, use them. otherwise process the PBF file per settings
                //Pre-generate gameplay map tiles, but present it as an option. It's faster to do it ahead of time but uses up more DB space if you aren't gonna need them all immediately.
                //Possible: Grab the Solar2D example app, adjust it to work with the server running on this machine.
                //--check external IP, update .lua source file to point to this pc.
                //Fire up the Kestral exe to get the server working
                //Open up a browser to the adminview slippytile page.
                //}
            }

            if (args.Any(a => a == "-updateDatabase"))
            {
                UpdateExistingEntries(config["OutputDataFolder"]);
            }

            if (args.Any(a => a.StartsWith("-createStandaloneRelation")))
            {
                //This makes a standalone DB for a specific relation passed in as a paramter.
                int relationId = Int32.Parse(config["UseOneRelationID"]);
                StandaloneCreation.CreateStandaloneDB(relationId, null, false, true); //How map tiles are handled is determined by the optional parameters
            }

            if (args.Any(a => a.StartsWith("-createStandaloneBox")))
            {
                //This makes a standalone DB for a specific area passed in as a paramter.
                //If you want to cover a region in a less-specific way, or the best available relation is much larger than you thought, this might be better.
                string[] bounds     = args.First(a => a.StartsWith("-createStandaloneBox")).Split('|');
                GeoArea  boundsArea = new GeoArea(bounds[1].ToDouble(), bounds[2].ToDouble(), bounds[3].ToDouble(), bounds[4].ToDouble());

                //in order, these go south/west/north/east.
                StandaloneCreation.CreateStandaloneDB(0, boundsArea, false, true); //How map tiles are handled is determined by the optional parameters
            }

            if (args.Any(a => a.StartsWith("-createStandalonePoint")))
            {
                //This makes a standalone DB centered on a specific point, it will grab a Cell6's area around that point.
                string[] bounds = args.First(a => a.StartsWith("-createStandalonePoint")).Split('|');

                var     resSplit   = resolutionCell6 / 2;
                GeoArea boundsArea = new GeoArea(bounds[1].ToDouble() - resSplit, bounds[2].ToDouble() - resSplit, bounds[1].ToDouble() + resSplit, bounds[2].ToDouble() + resSplit);

                //in order, these go south/west/north/east.
                StandaloneCreation.CreateStandaloneDB(0, boundsArea, false, true); //How map tiles are handled is determined by the optional parameters
            }

            if (args.Any(a => a == "-autoCreateMapTiles"))
            {
                var db     = new PraxisContext();
                var bounds = db.SetServerBounds(long.Parse(config["UseOneRelationID"]));
                MapTileSupport.PregenMapTilesForArea(bounds);
            }

            if (args.Any(a => a == "-findServerBounds"))
            {
                var db = new PraxisContext();
                db.SetServerBounds(long.Parse(config["UseOneRelationID"]));
            }

            if (args.Any(a => a.StartsWith("-drawOneImage:")))
            {
                DrawOneImage(args.First(a => a.StartsWith("-drawOneImage:")).Split(":")[1]);
            }

            if (args.Any(a => a.StartsWith("-processCoastlines:")))
            {
                string filename = args.First(a => a.StartsWith("-processCoastlines:")).Split(":")[1];
                ReadCoastlineShapefile(filename);
            }

            if (args.Any(a => a == "-makePosterImage"))
            {
                DrawPosterOfServer();
            }

            if (args.Any(a => a == "-pwdSpeedTest"))
            {
                PwdSpeedTest();
            }

            if (args.Any(a => a == "-setEnvValues"))
            {
                SetEnvValues();
            }

            //This is not currently finished or testing in the current setup. Will return in a future release.
            //if (args.Any(a => a.StartsWith("-populateEmptyArea:")))
            //{
            //    populateEmptyAreas(args.First(a => a.StartsWith("-populateEmptyArea:")).Split(":")[1]);
            //}
        }