示例#1
0
        public HexSectorSelector(ResourceManager resourceManager, Sector sector, Point coords, int jump)
        {
            if (resourceManager == null)
                throw new ArgumentNullException("resourceManager");

            if (sector == null)
                throw new ArgumentNullException("sector");

            m_sector = sector;
            m_resourceManager = resourceManager;
            m_coords = coords;
            m_jump = jump;
        }
示例#2
0
        public HexSectorSelector(ResourceManager resourceManager, Sector sector, Hex coords, int jump)
        {
            if (resourceManager == null)
                throw new ArgumentNullException("resourceManager");

            if (sector == null)
                throw new ArgumentNullException("sector");

            this.sector = sector;
            this.resourceManager = resourceManager;
            this.coords = coords;
            this.jump = jump;
        }
示例#3
0
        public HexSelector(SectorMap map, ResourceManager resourceManager, Location location, int jump)
        {
            if (map == null)
                throw new ArgumentNullException("map");

            if (resourceManager == null)
                throw new ArgumentNullException("resourceManager");

            if (jump < 0 || jump > 36)
                throw new ArgumentOutOfRangeException("jump", jump, "jump must be between 0 and 36 inclusive");

            m_map = map;
            m_resourceManager = resourceManager;
            m_location = location;
            m_jump = jump;
        }
示例#4
0
        public SubsectorSelector(ResourceManager resourceManager, Sector sector, int index)
        {
            if (resourceManager == null)
                throw new ArgumentNullException("resourceManager");

            if (sector == null)
                throw new ArgumentNullException("sector");

            if (index < 0 || index >= 16)
                throw new ArgumentOutOfRangeException("index", "index must be 0...15");

            m_sector = sector;
            m_index = index;
            m_resourceManager = resourceManager;
        }
示例#5
0
        public SectorSelector(ResourceManager resourceManager, Sector sector)
        {
            if (resourceManager == null)
                throw new ArgumentNullException("resourceManager");

            if (sector == null)
                throw new ArgumentNullException("sector");

            m_sector = sector;
            m_resourceManager = resourceManager;
        }
示例#6
0
        public RectSelector(SectorMap map, ResourceManager resourceManager, RectangleF rect)
        {
            if (map == null)
                throw new ArgumentNullException("map");

            if (resourceManager == null)
                throw new ArgumentNullException("resourceManager");

            m_map = map;
            m_resourceManager = resourceManager;
            m_rect = rect;
        }
示例#7
0
        public void Resolve(SectorMap sectorMap, ResourceManager resourceManager, out Sector sector, out World world)
        {
            if (sectorMap == null)
                throw new ArgumentNullException("sectorMap");

            sector = null;
            world = null;

            sector = sectorMap.FromLocation(Sector.X, Sector.Y);
            if (sector == null)
                return;

            WorldCollection worlds = sector.GetWorlds(resourceManager, cacheResults: true);
            if (worlds != null)
                world = worlds[World.X, World.Y];
        }
示例#8
0
        internal void Serialize(ResourceManager resourceManager, TextWriter writer, string mediaType, bool includeMetadata = true, bool includeHeader = true, bool sscoords = false, WorldFilter filter = null)
        {
            WorldCollection worlds = GetWorlds(resourceManager);

            // TODO: less hacky T5 support
            bool isT5 = (mediaType == "TabDelimited" || mediaType == "SecondSurvey");

            if (mediaType == "TabDelimited")
            {
                if (worlds != null)
                    worlds.Serialize(writer, mediaType, includeHeader: includeHeader, filter: filter);
                return;
            }

            if (includeMetadata)
            {
                // Header
                //
                writer.WriteLine("# Generated by http://travellermap.com");
                writer.WriteLine("# " + DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz", DateTimeFormatInfo.InvariantInfo));
                writer.WriteLine();

                writer.WriteLine("# {0}", Names[0]);
                writer.WriteLine("# {0},{1}", X, Y);

                writer.WriteLine();
                foreach (var name in Names)
                {
                    if (name.Lang != null)
                        writer.WriteLine("# Name: {0} ({1})", name.Text, name.Lang);
                    else
                        writer.WriteLine("# Name: {0}", name);
                }

                if (Credits != null)
                {
                    string stripped = Regex.Replace(Credits, "<.*?>", "");
                    stripped = Regex.Replace(stripped, @"\s+", " ");
                    stripped = stripped.Trim();
                    writer.WriteLine();
                    writer.WriteLine("# Credits: {0}", stripped);
                }

                if (DataFile != null)
                {
                    writer.WriteLine();
                    if (DataFile.Era != null) { writer.WriteLine("# Era: {0}", DataFile.Era); }
                    writer.WriteLine();

                    if (DataFile.Author != null) { writer.WriteLine("# Author:    {0}", DataFile.Author); }
                    if (DataFile.Publisher != null) { writer.WriteLine("# Publisher: {0}", DataFile.Publisher); }
                    if (DataFile.Copyright != null) { writer.WriteLine("# Copyright: {0}", DataFile.Copyright); }
                    if (DataFile.Source != null) { writer.WriteLine("# Source:    {0}", DataFile.Source); }
                    if (DataFile.Ref != null) { writer.WriteLine("# Ref:       {0}", DataFile.Ref); }
                }

                writer.WriteLine();
                for (int i = 0; i < 16; ++i)
                {
                    char c = (char)('A' + i);
                    Subsector ss = Subsector(c);
                    writer.WriteLine("# Subsector {0}: {1}", c, ss?.Name ?? "");
                }
                writer.WriteLine();
            }

            if (worlds == null)
            {
                if (includeMetadata)
                    writer.WriteLine("# No world data available");
                return;
            }

            // Allegiances
            if (includeMetadata)
            {
                // Use codes as present in the data, to match the worlds
                foreach (string code in worlds.AllegianceCodes().OrderBy(s => s))
                {
                    var alleg = GetAllegianceFromCode(code);
                    if (alleg != null)
                        writer.WriteLine("# Alleg: {0}: \"{1}\"", isT5 ? code : SecondSurvey.T5AllegianceCodeToLegacyCode(code), alleg.Name);
                }
                writer.WriteLine();
            }

            // Worlds
            worlds.Serialize(writer, mediaType, includeHeader: includeHeader, sscoords: sscoords, filter: filter);
        }
示例#9
0
        private SectorMap(List<SectorMetafileEntry> metafiles, ResourceManager resourceManager)
        {
            foreach (var metafile in metafiles)
            {
                SectorCollection collection = resourceManager.GetXmlFileObject(metafile.filename, typeof(SectorCollection), cache: false) as SectorCollection;
                foreach (var sector in collection.Sectors)
                    sector.Tags.AddRange(metafile.tags);

                if (sectors == null)
                    sectors = collection;
                else
                    sectors.Merge(collection);
            }

            milieux.Clear();

            foreach (var sector in sectors.Sectors)
            {
                if (sector.MetadataFile != null)
                {
                    Sector metadata = resourceManager.GetXmlFileObject(@"~/res/Sectors/" + sector.MetadataFile, typeof(Sector), cache: false) as Sector;
                    sector.Merge(metadata);
                }

                string milieu = sector.Era ?? sector.DataFile?.Era ?? DEFAULT_MILIEU;
                if (!milieux.ContainsKey(milieu))
                    milieux.Add(milieu, new MilieuMap());

                MilieuMap m = milieux[milieu];
                m.locationMap.Add(sector.Location, sector);

                foreach (var name in sector.Names)
                {
                    if (!m.nameMap.ContainsKey(name.Text))
                        m.nameMap.Add(name.Text, sector);

                    // Automatically alias "SpinwardMarches"
                    string spaceless = name.Text.Replace(" ", "");
                    if (spaceless != name.Text && !m.nameMap.ContainsKey(spaceless))
                        m.nameMap.Add(spaceless, sector);
                }

                if (!string.IsNullOrEmpty(sector.Abbreviation) && !m.nameMap.ContainsKey(sector.Abbreviation))
                    m.nameMap.Add(sector.Abbreviation, sector);
            }
        }
示例#10
0
        public static IEnumerable<ItemLocation> PerformSearch(string query, ResourceManager resourceManager, SearchResultsType types, int numResults)
        {
            List<ItemLocation> results = new List<ItemLocation>();

            using (var connection = DBUtil.MakeConnection())
            {
                List<string> clauses = new List<string>();
                List<string> terms = new List<string>();
                foreach (string t in query.Split((char[])null, StringSplitOptions.RemoveEmptyEntries))
                {
                    string term = t;
                    string clause;
                    if (term.StartsWith("uwp:"))
                    {
                        term = term.Substring(term.IndexOf(':') + 1);
                        clause = "uwp LIKE @term";
                        types = SearchResultsType.UWP;
                    }
                    else if (term.StartsWith("exact:"))
                    {
                        term = term.Substring(term.IndexOf(':') + 1);
                        clause = "name LIKE @term";
                    }
                    else if (term.StartsWith("like:"))
                    {
                        term = term.Substring(term.IndexOf(':') + 1);
                        clause = "SOUNDEX(name) = SOUNDEX(@term)";
                    }
                    else if (term.Contains("%") || term.Contains("_"))
                    {
                        clause = "name LIKE @term";
                    }
                    else
                    {
                        clause = "name LIKE @term + '%' OR name LIKE '% ' + @term + '%'";
                    }

                    clause = clause.Replace("@term", String.Format("@term{0}", terms.Count));
                    clauses.Add("(" + clause + ")");
                    terms.Add(term);
                }

                string where = String.Join(" AND ", clauses.ToArray());

                // NOTE: DISTINCT is to filter out "Ley" and "Ley Sector" (different names, same result).
                // TODO: Include the searched-for name in the results, and show alternate names in the result set.
                // {0} is the list of distinct fields (i.e. coordinates), {1} is the table, {2} is the filter
                string query_format = "SELECT DISTINCT TOP " + numResults + " {0},name FROM {1} WHERE {2} ORDER BY name ASC";

                // Sectors
                if (types.HasFlag(SearchResultsType.Sectors) && numResults > 0)
                {
                    string sql = String.Format(query_format, "x, y", "sectors", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(String.Format("@term{0}", i), terms[i]);
                        }
                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new SectorLocation(row.GetInt32(0), row.GetInt32(1)));
                                numResults -= 1;
                            }
                        }
                    }
                }

                // Subsectors
                if (types.HasFlag(SearchResultsType.Subsectors) && numResults > 0)
                {
                    string sql = String.Format(query_format, "sector_x, sector_y, subsector_index", "subsectors", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(String.Format("@term{0}", i), terms[i]);
                        }
                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                char[] chars = new char[1];
                                row.GetChars(2, 0, chars, 0, chars.Length);

                                results.Add(new SubsectorLocation(row.GetInt32(0), row.GetInt32(1), chars[0]));
                            }
                        }
                    }
                }

                // Worlds & UWPs
                if ((types.HasFlag(SearchResultsType.Worlds) || types.HasFlag(SearchResultsType.UWP)) && numResults > 0)
                {
                    string sql = String.Format(query_format, "sector_x, sector_y, hex_x, hex_y", "worlds", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                        {
                            sqlCommand.Parameters.AddWithValue(String.Format("@term{0}", i), terms[i]);
                        }
                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new WorldLocation(row.GetInt32(0), row.GetInt32(1), row.GetInt32(2), row.GetInt32(3)));
                            }
                        }
                    }
                }
            }

            return results;
        }
示例#11
0
        public static void PopulateDatabase(ResourceManager resourceManager, StatusCallback callback)
        {
            // Lock on this class rather than the cacheResults. Tile requests are not
            // blocked but we don't index twice.
            lock (typeof(SearchEngine))
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                SectorMap map = SectorMap.FromName(SectorMap.DefaultSetting, resourceManager);

                using (var connection = DBUtil.MakeConnection())
                {
                    SqlCommand sqlCommand;

                    //
                    // Repopulate the tables - locally first
                    // FUTURE: will need to batch this up rather than keep it in memory!
                    //

                    DataTable dt_sectors = new DataTable();
                    for (int i = 0; i < 3; ++i)
                        dt_sectors.Columns.Add(new DataColumn());

                    DataTable dt_subsectors = new DataTable();
                    for (int i = 0; i < 4; ++i)
                        dt_subsectors.Columns.Add(new DataColumn());

                    DataTable dt_worlds = new DataTable();
                    for (int i = 0; i < 6; ++i)
                        dt_worlds.Columns.Add(new DataColumn());

                    callback("Parsing data...");
                    foreach (Sector sector in map.Sectors)
                    {
                        if (!sector.Tags.Contains("OTU"))
                            continue;

                        foreach (Name name in sector.Names)
                        {
                            DataRow row = dt_sectors.NewRow();
                            row.ItemArray = new object[] { sector.X, sector.Y, name.Text };
                            dt_sectors.Rows.Add(row);
                        }

                        foreach (Subsector subsector in sector.Subsectors)
                        {
                            DataRow row = dt_subsectors.NewRow();
                            row.ItemArray = new object[] { sector.X, sector.Y, subsector.Index, subsector.Name };
                            dt_subsectors.Rows.Add(row);
                        }

            #if DEBUG
                        if (!sector.Selected)
                            continue;
            #endif
                        // NOTE: May need to page this at some point
                        WorldCollection worlds = sector.GetWorlds(resourceManager, cacheResults: false);
                        if (worlds == null)
                            continue;

                        foreach (World world in worlds)
                        {
                            DataRow row = dt_worlds.NewRow();
                            row.ItemArray = new object[] {
                                    sector.X,
                                    sector.Y,
                                    world.X,
                                    world.Y,
                                    world.Name != null && world.Name.Length > 0
                                        ? (object)world.Name
                                        : (object)DBNull.Value,
                                    world.UWP };

                            dt_worlds.Rows.Add(row);
                        }
                    }

                    //
                    // Rebuild the tables with fresh schema
                    //
                    string[] rebuild_schema = {
                        "IF EXISTS(SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'sectors') AND type = (N'U')) DROP TABLE sectors",
                        "CREATE TABLE sectors(x int NOT NULL,y int NOT NULL,name nvarchar(50) NULL)",
                        "CREATE NONCLUSTERED INDEX sector_name ON sectors ( name ASC ) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)",

                        "IF EXISTS(SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'subsectors') AND type = (N'U')) DROP TABLE subsectors",
                        "CREATE TABLE subsectors (sector_x int NOT NULL, sector_y int NOT NULL, subsector_index char(1) NOT NULL, name nvarchar(50) NULL )",
                        "CREATE NONCLUSTERED INDEX subsector_name ON subsectors ( name ASC )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)",

                        "IF EXISTS(SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'worlds') AND type = (N'U')) DROP TABLE worlds",
                        "CREATE TABLE worlds( sector_x int NOT NULL, sector_y int NOT NULL, hex_x int NOT NULL, hex_y int NOT NULL, name nvarchar(50) NULL, uwp nchar(9) NULL )",
                        "CREATE NONCLUSTERED INDEX world_name ON worlds ( name ASC ) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)",
                        "CREATE NONCLUSTERED INDEX world_uwp ON worlds ( uwp ASC ) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)",
                    };

                    callback("Rebuilding schema...");
                    foreach (string cmd in rebuild_schema)
                    {
                        sqlCommand = new SqlCommand(cmd, connection);
                        sqlCommand.ExecuteNonQuery();
                    }

                    //
                    // And shovel the data into the database en masse
                    //
                    using (var bulk = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null))
                    {
                        callback(String.Format("Writing {0} sectors...", dt_sectors.Rows.Count));
                        bulk.BatchSize = dt_sectors.Rows.Count;
                        bulk.DestinationTableName = "sectors";
                        bulk.WriteToServer(dt_sectors);
                        bulk.Close();
                    }
                    using (var bulk = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null))
                    {
                        callback(String.Format("Writing {0} subsectors...", dt_subsectors.Rows.Count));
                        bulk.BatchSize = dt_subsectors.Rows.Count;
                        bulk.DestinationTableName = "subsectors";
                        bulk.WriteToServer(dt_subsectors);
                        bulk.Close();
                    }
                    using (var bulk = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null))
                    {
                        callback(String.Format("Writing {0} worlds...", dt_worlds.Rows.Count));
                        bulk.BatchSize = 4096;
                        bulk.DestinationTableName = "worlds";
                        bulk.WriteToServer(dt_worlds);
                        bulk.Close();
                    }
                }
                callback("Complete!");
            }
        }
示例#12
0
        public static IEnumerable<ItemLocation> PerformSearch(string query, ResourceManager resourceManager, SearchResultsType types, int maxResultsPerType)
        {
            List<ItemLocation> results = new List<ItemLocation>();

            List<string> clauses;
            List<string> terms;
            types = ParseQuery(query, types, out clauses, out terms);

            if (clauses.Count() == 0)
                return results;

            string where = String.Join(" AND ", clauses.ToArray());

            // NOTE: DISTINCT is to filter out "Ley" and "Ley Sector" (different names, same result).
            // TODO: Include the searched-for name in the results, and show alternate names in the result set.
            // {0} is the list of distinct fields (i.e. coordinates), {1} is the list of fields in the subquery (same as {0} but with "name" added, {2} is the table, {3} is the filter
            // Since we need the distinct values from the term {0} but don't use the name for the results construction, we can ignore name in the resultset.
            // This allows us to get the top N results from the database, sort by name, and then toss out duplicates not based on name but on the other, used, columns
            // Here's a sample subquery that works for the sector table.
            // SELECT DISTINCT TOP 160 tt.x, tt.y FROM (SELECT TOP 160 x, y,name FROM sectors WHERE (name LIKE 'LEY%' OR name LIKE '%LEY%') ORDER BY name ASC) AS tt;
            string query_format = "SELECT DISTINCT TOP " + maxResultsPerType + " {0} FROM (SELECT TOP " + maxResultsPerType + " {1} FROM {2} WHERE {3}) AS TT";

            using (var connection = DBUtil.MakeConnection())
            {
                // Sectors
                if (types.HasFlag(SearchResultsType.Sectors))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = String.Format(query_format, "TT.x, TT.y", "x, y", "sectors", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                            sqlCommand.Parameters.AddWithValue(String.Format("@term{0}", i), terms[i]);

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                results.Add(new SectorLocation(row.GetInt32(0), row.GetInt32(1)));
                            }
                        }
                    }
                }

                // Subsectors
                if (types.HasFlag(SearchResultsType.Subsectors))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = String.Format(query_format, "TT.sector_x, TT.sector_y, TT.subsector_index", "sector_x, sector_y, subsector_index", "subsectors", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                            sqlCommand.Parameters.AddWithValue(String.Format("@term{0}", i), terms[i]);

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                            {
                                char[] chars = new char[1];
                                row.GetChars(2, 0, chars, 0, chars.Length);

                                results.Add(new SubsectorLocation(row.GetInt32(0), row.GetInt32(1), chars[0]));
                            }
                        }
                    }
                }

                // Worlds & UWPs, etc
                if (types.HasFlag(SearchResultsType.Worlds))
                {
                    // Note duplicated field names so the results of both queries can come out right.
                    string sql = String.Format(query_format, "TT.sector_x, TT.sector_y, TT.hex_x, TT.hex_y", "sector_x, sector_y, hex_x, hex_y", "worlds", where);
                    using (var sqlCommand = new SqlCommand(sql, connection))
                    {
                        for (int i = 0; i < terms.Count; ++i)
                            sqlCommand.Parameters.AddWithValue(String.Format("@term{0}", i), terms[i]);

                        using (var row = sqlCommand.ExecuteReader())
                        {
                            while (row.Read())
                                results.Add(new WorldLocation(row.GetInt32(0), row.GetInt32(1), row.GetInt32(2), row.GetInt32(3)));
                        }
                    }
                }
            }
            return results;
        }
示例#13
0
        public QuadrantSelector(ResourceManager resourceManager, Sector sector, int index)
        {
            if (resourceManager == null)
                throw new ArgumentNullException("resourceManager");

            if (sector == null)
                throw new ArgumentNullException("sector");

            if (index < 0 || index >= 4)
                throw new ArgumentOutOfRangeException("index", "index must be 0...3");

            this.sector = sector;
            this.index = index;
            this.resourceManager = resourceManager;
        }
示例#14
0
        public static SectorMap GetInstance(ResourceManager resourceManager)
        {
            lock (SectorMap.s_lock)
            {
                if (s_instance == null)
                {
                    List<SectorMetafileEntry> files = new List<SectorMetafileEntry>
                    {
                        // Meta
                        new SectorMetafileEntry(@"~/res/legend.xml", new List<string> { "meta" } ),

                        // OTU - Default Milieu
                        new SectorMetafileEntry(@"~/res/sectors.xml", new List<string> { "OTU" } ),
                        new SectorMetafileEntry(@"~/res/ZhodaniCoreRoute.xml", new List<string> { "ZCR" } ),

                        // OTU - Other Milieu
                        new SectorMetafileEntry(@"~/res/Sectors/M1000/m1000.xml", new List<string> {} ),

                        // Non-OTU
                        new SectorMetafileEntry(@"~/res/faraway.xml", new List<string> { "Faraway" } ),
                    };

                    s_instance = new SectorMap(files, resourceManager);
                }
            }

            return s_instance;
        }
示例#15
0
 public static Milieu ForMilieu(ResourceManager resourceManager, string milieu)
 {
     return new Milieu(SectorMap.GetInstance(resourceManager), milieu);
 }
示例#16
0
        internal WorldCollection GetWorlds(ResourceManager resourceManager, bool cacheResults = true)
        {
            lock (this)
            {
                // Have it cached - just return it
                if (worlds != null)
                    return worlds;

                // Can't look it up; failure case
                if (DataFile == null)
                    return null;

                // Otherwise, look it up
                WorldCollection data = resourceManager.GetDeserializableFileObject(@"~/res/Sectors/" + DataFile, typeof(WorldCollection), cacheResults: false, mediaType: DataFile.Type) as WorldCollection;
                foreach (World world in data)
                    world.Sector = this;

                if (cacheResults)
                    worlds = data;

                return data;
            }
        }
示例#17
0
        public static void PopulateDatabase(ResourceManager resourceManager, StatusCallback callback)
        {
            // Lock to prevent indexing twice, without blocking tile requests.
            lock (SearchEngine.s_lock)
            {
                // NOTE: This (re)initializes a static data structure used for
                // resolving names into sector locations, so needs to be run
                // before any other objects (e.g. Worlds) are loaded.
                SectorMap map = SectorMap.GetInstance(resourceManager);

                using (var connection = DBUtil.MakeConnection())
                {
                    SqlCommand sqlCommand;

                    //
                    // Repopulate the tables - locally first
                    // FUTURE: will need to batch this up rather than keep it in memory!
                    //

                    DataTable dt_sectors = new DataTable();
                    for (int i = 0; i < 3; ++i)
                        dt_sectors.Columns.Add(new DataColumn());

                    DataTable dt_subsectors = new DataTable();
                    for (int i = 0; i < 4; ++i)
                        dt_subsectors.Columns.Add(new DataColumn());

                    DataTable dt_worlds = new DataTable();
                    for (int i = 0; i < 13; ++i)
                        dt_worlds.Columns.Add(new DataColumn());

                    DataTable dt_labels = new DataTable();
                    for (int i = 0; i < 4; ++i)
                        dt_labels.Columns.Add(new DataColumn());

                    Dictionary<string, List<Point>> labels = new Dictionary<string, List<Point>>();
                    Action<string, Point> AddLabel = (string text, Point coords) => {
                        if (text == null) return;
                        text = SanifyLabel(text);
                        if (!labels.ContainsKey(text))
                            labels.Add(text, new List<Point>());
                        labels[text].Add(coords);
                    };

                    callback("Parsing data...");
                    foreach (Sector sector in map.Sectors)
                    {
                        if (!sector.Tags.Contains("OTU") && !sector.Tags.Contains("Faraway"))
                            continue;

                        foreach (Name name in sector.Names)
                        {
                            DataRow row = dt_sectors.NewRow();
                            row.ItemArray = new object[] { sector.X, sector.Y, name.Text };
                            dt_sectors.Rows.Add(row);
                        }
                        if (!string.IsNullOrEmpty(sector.Abbreviation))
                        {
                            DataRow row = dt_sectors.NewRow();
                            row.ItemArray = new object[] { sector.X, sector.Y, sector.Abbreviation };
                            dt_sectors.Rows.Add(row);
                        }

                        foreach (Subsector subsector in sector.Subsectors)
                        {
                            DataRow row = dt_subsectors.NewRow();
                            row.ItemArray = new object[] { sector.X, sector.Y, subsector.Index, subsector.Name };
                            dt_subsectors.Rows.Add(row);
                        }

                        foreach (Border border in sector.Borders.Where(b => b.ShowLabel))
                        {
                            AddLabel(border.GetLabel(sector),
                                Astrometrics.LocationToCoordinates(new Location(sector.Location, border.LabelPosition)));
                        }

                        foreach (Label label in sector.Labels)
                        {
                            AddLabel(label.Text, Astrometrics.LocationToCoordinates(new Location(sector.Location, label.Hex)));
                        }

            #if DEBUG
                        if (!sector.Selected)
                            continue;
            #endif
                        // NOTE: May need to page this at some point
                        WorldCollection worlds = sector.GetWorlds(resourceManager, cacheResults: false);
                        if (worlds == null)
                            continue;

                        var world_query = from world in worlds
                                          where !world.IsPlaceholder
                                          select world;
                        foreach (World world in world_query)
                        {
                            DataRow row = dt_worlds.NewRow();
                            row.ItemArray = new object[] {
                                    world.Coordinates.X,
                                    world.Coordinates.Y,
                                    sector.X,
                                    sector.Y,
                                    world.X,
                                    world.Y,
                                    string.IsNullOrEmpty(world.Name) ? (object)DBNull.Value : (object)world.Name,
                                    world.UWP,
                                    world.Remarks,
                                    world.PBG,
                                    string.IsNullOrEmpty(world.Zone) ? "G" : world.Zone,
                                    world.Allegiance,
                                    sector.Names.Count > 0 ? (object)sector.Names[0] : (object)DBNull.Value
                            };

                            dt_worlds.Rows.Add(row);
                        }
                    }

                    foreach (KeyValuePair<string, List<Point>> entry in labels)
                    {
                        string name = entry.Key;
                        List<Point> points = entry.Value;

                        Point avg = new Point(
                            (int)Math.Round(points.Select(p => p.X).Average()),
                            (int)Math.Round(points.Select(p => p.Y).Average()));
                        Point min = new Point(points.Select(p => p.X).Min(), points.Select(p => p.Y).Min());
                        Point max = new Point(points.Select(p => p.X).Max(), points.Select(p => p.Y).Max());
                        Size size = new Size(max.X - min.X, max.Y - min.Y);
                        int radius = Math.Max(size.Width, size.Height);

                        DataRow row = dt_labels.NewRow();
                        row.ItemArray = new object[] {
                            avg.X,
                            avg.Y,
                            radius,
                            entry.Key
                        };
                        dt_labels.Rows.Add(row);
                    }

                    //
                    // Rebuild the tables with fresh schema
                    //

                    const string INDEX_OPTIONS = " WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)";

                    const string DROP_TABLE_IF_EXISTS = "IF EXISTS(SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'{0}') AND type = (N'U')) DROP TABLE {0}";

                    string[] rebuild_schema = {
                        string.Format(DROP_TABLE_IF_EXISTS, "sectors"),
                        "CREATE TABLE sectors (x int NOT NULL, y int NOT NULL, name nvarchar(50) NULL)",
                        "CREATE NONCLUSTERED INDEX sector_name ON sectors ( name ASC )" + INDEX_OPTIONS,

                        string.Format(DROP_TABLE_IF_EXISTS, "subsectors"),
                        "CREATE TABLE subsectors (sector_x int NOT NULL, sector_y int NOT NULL, subsector_index char(1) NOT NULL, name nvarchar(50) NULL)",
                        "CREATE NONCLUSTERED INDEX subsector_name ON subsectors ( name ASC )" + INDEX_OPTIONS,

                        string.Format(DROP_TABLE_IF_EXISTS, "worlds"),
                        "CREATE TABLE worlds ("
                            + "x int NOT NULL, "
                            + "y int NOT NULL, "
                            + "sector_x int NOT NULL, "
                            + "sector_y int NOT NULL, "
                            + "hex_x int NOT NULL, "
                            + "hex_y int NOT NULL, "
                            + "name nvarchar(50) NULL, "
                            + "uwp nchar(9) NULL, "
                            + "remarks nvarchar(50) NULL, "
                            + "pbg nchar(3) NULL, "
                            + "zone nchar(1) NULL, "
                            + "alleg nchar(4) NULL, "
                            + "sector_name nvarchar(50) NULL)",
                        "CREATE NONCLUSTERED INDEX world_name ON worlds ( name ASC )" + INDEX_OPTIONS,
                        "CREATE NONCLUSTERED INDEX world_uwp ON worlds ( uwp ASC )" + INDEX_OPTIONS,
                        "CREATE NONCLUSTERED INDEX world_pbg ON worlds ( pbg ASC )" + INDEX_OPTIONS,
                        "CREATE NONCLUSTERED INDEX world_alleg ON worlds ( alleg ASC )" + INDEX_OPTIONS,
                        "CREATE NONCLUSTERED INDEX world_sector_name ON worlds ( sector_name ASC )" + INDEX_OPTIONS,

                        string.Format(DROP_TABLE_IF_EXISTS, "labels"),
                        "CREATE TABLE labels (x int NOT NULL, y int NOT NULL, radius int NOT NULL, name nvarchar(50) NULL)",
                        "CREATE NONCLUSTERED INDEX name ON labels ( name ASC )" + INDEX_OPTIONS,
                    };

                    callback("Rebuilding schema...");
                    foreach (string cmd in rebuild_schema)
                    {
                        sqlCommand = new SqlCommand(cmd, connection);
                        sqlCommand.ExecuteNonQuery();
                    }

                    //
                    // And shovel the data into the database en masse
                    //
                    Action<string, DataTable, int> BulkInsert = (string name, DataTable table, int batchSize) => {
                        using (var bulk = new SqlBulkCopy(connection, SqlBulkCopyOptions.TableLock, null))
                        {
                            callback(string.Format("Writing {0} {1}...", table.Rows.Count, name));
                            bulk.BatchSize = batchSize;
                            bulk.DestinationTableName = name;
                            bulk.WriteToServer(table);
                        }
                    };

                    BulkInsert("sectors", dt_sectors, dt_sectors.Rows.Count);
                    BulkInsert("subsectors", dt_subsectors, dt_subsectors.Rows.Count);
                    BulkInsert("worlds", dt_worlds, 4096);
                    BulkInsert("labels", dt_labels, dt_labels.Rows.Count);
                }
                callback("Complete!");
            }
        }
示例#18
0
        public RectSelector(SectorMap.Milieu map, ResourceManager resourceManager, RectangleF rect, bool slop = true)
        {
            if (map == null)
                throw new ArgumentNullException("map");

            if (resourceManager == null)
                throw new ArgumentNullException("resourceManager");

            this.map = map;
            this.resourceManager = resourceManager;
            this.rect = rect;

            Slop = slop;
            SlopFactor = 0.25f;
        }