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);
        }
Exemple #3
0
 internal TopicType(
     AreaTypeInfo info,
     FlowConstructor constructor,
     FlowObservationSet observations,
     ResumeAlgorithm resumeAlgorithm)
     : base(info, constructor, observations, resumeAlgorithm)
 {
 }
Exemple #4
0
 internal QueryType(
     AreaTypeInfo info,
     FlowConstructor constructor,
     FlowObservationSet observations,
     ResumeAlgorithm resumeAlgorithm,
     int batchSize)
     : base(info, constructor, observations, resumeAlgorithm)
 {
     BatchSize = batchSize;
 }
Exemple #5
0
 internal FlowType(
     AreaTypeInfo info,
     FlowConstructor constructor,
     FlowObservationSet observations,
     ResumeAlgorithm resumeAlgorithm)
     : base(info)
 {
     Constructor     = constructor;
     Observations    = observations;
     ResumeAlgorithm = resumeAlgorithm;
 }
Exemple #6
0
        void DeclareFlow(AreaTypeInfo type)
        {
            var builder = new FlowTypeBuilder(this, type);

            if (builder.TryBuildTopic(out var topic))
            {
                _topics.Add(topic);
            }
            else
            {
                if (builder.TryBuildQuery(out var query))
                {
                    _queries.Add(query);
                }
            }
        }
        //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.");
        }
Exemple #8
0
 void DeclareEvent(AreaTypeInfo info) =>
 _eventsByDeclaredType.Add(info.DeclaredType, new EventType(info));
 internal FlowTypeBuilder(AreaMapBuilder map, AreaTypeInfo info)
 {
     _map  = map;
     _info = info;
 }