示例#1
0
        public static void GetSystemListBySqDistancesFrom(BaseUtils.SortedListDoubleDuplicate <ISystem> distlist, double x, double y, double z,
                                                          int maxitems,
                                                          double mindist, double maxdist, bool spherical)
        {
            if (SystemsDatabase.Instance.RebuildRunning) // Return from cache if rebuild is running
            {
                lock (systemsByEdsmId)
                {
                    var sysdist = systemsByName.Values
                                  .SelectMany(s => s)
                                  .Select(s => new { distsq = s.DistanceSq(x, y, z), sys = s })
                                  .OrderBy(s => s.distsq)
                                  .ToList();
                    var minsq = mindist * mindist;
                    var maxsq = maxdist * maxdist;

                    foreach (var sd in sysdist)
                    {
                        if (sd.distsq <= minsq && sd.distsq >= maxsq)
                        {
                            distlist.Add(sd.distsq, sd.sys);
                        }

                        if (distlist.Count >= maxitems)
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                SystemsDatabase.Instance.ExecuteWithDatabase(conn => GetSystemListBySqDistancesFrom(distlist, x, y, z, maxitems, mindist, maxdist, spherical, conn));
            }
        }
示例#2
0
        public static void GetSystemListBySqDistancesFrom(BaseUtils.SortedListDoubleDuplicate <ISystem> distlist, // MUST use duplicate double list to protect against EDSM having two at the same point
                                                          double x, double y, double z,
                                                          int maxitems,
                                                          double mindist,       // 0 = no min dist, always spherical
                                                          double maxdist,
                                                          bool spherical,       // enforces sphere on maxdist, else its a cube for maxdist
                                                          SQLiteConnectionSystem cn,
                                                          Action <ISystem> LookedUp = null
                                                          )

        {
            // for comparision, using the grid screener is slower than the xy index. keep code for record
            // grid screener..  "s.sectorid IN (Select id FROM Sectors sx where sx.gridid IN (" + strinlist + ")) " +
            //var gridids = GridId.Ids(x - maxdist, x + maxdist, z - maxdist, z + maxdist);       // find applicable grid ids across this range..
            //var strinlist = string.Join(",", (from x1 in gridids select x1.ToStringInvariant()));     // here we convert using invariant for paranoia sake.

            int mindistint = mindist > 0 ? SystemClass.DoubleToInt(mindist) * SystemClass.DoubleToInt(mindist) : 0;

            // needs a xz index for speed

            using (DbCommand cmd = cn.CreateSelect("Systems s",
                                                   MakeSystemQueryEDDB,
                                                   where :
                                                   "s.x >= @xv - @maxdist " +
                                                   "AND s.x <= @xv + @maxdist " +
                                                   "AND s.z >= @zv - @maxdist " +
                                                   "AND s.z <= @zv + @maxdist " +
                                                   "AND s.y >= @yv - @maxdist " +
                                                   "AND s.y <= @yv + @maxdist " +
                                                   (mindist > 0 ? ("AND (s.x-@xv)*(s.x-@xv)+(s.y-@yv)*(s.y-@yv)+(s.z-@zv)*(s.z-@zv)>=" + (mindistint).ToStringInvariant()) : ""),
                                                   orderby: "(s.x-@xv)*(s.x-@xv)+(s.y-@yv)*(s.y-@yv)+(s.z-@zv)*(s.z-@zv)", // just use squares to order
                                                   joinlist: MakeSystemQueryEDDBJoinList,
                                                   limit: "@max"
                                                   ))
            {
                cmd.AddParameterWithValue("@xv", SystemClass.DoubleToInt(x));
                cmd.AddParameterWithValue("@yv", SystemClass.DoubleToInt(y));
                cmd.AddParameterWithValue("@zv", SystemClass.DoubleToInt(z));
                cmd.AddParameterWithValue("@max", maxitems + 1);     // 1 more, because if we are on a System, that will be returned
                cmd.AddParameterWithValue("@maxdist", SystemClass.DoubleToInt(maxdist));

//                System.Diagnostics.Debug.WriteLine(cn.ExplainQueryPlanString(cmd));

                using (DbDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())// && distlist.Count < maxitems)           // already sorted, and already limited to max items
                    {
                        SystemClass s = MakeSystem(reader);
                        LookedUp?.Invoke(s);                            // callback to say looked up

                        double distsq = s.DistanceSq(x, y, z);
                        if ((!spherical || distsq <= maxdist * maxdist))
                        {
                            distlist.Add(distsq, s);                  // which Rob has seen crashing the program! Bad EDSM!
                        }
                    }
                }
            }
        }
示例#3
0
        // Add in any systems we have to the distlist

        public void CalculateSqDistances(BaseUtils.SortedListDoubleDuplicate <ISystem> distlist, double x, double y, double z,
                                         int maxitems, double mindistance, double maxdistance, bool spherical, int maxjumpsback = int.MaxValue)
        {
            HashSet <string> listnames = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase);

            foreach (ISystem sys in distlist.Values.ToList())
            {
                listnames.Add(sys.Name);
            }

            mindistance *= mindistance;

            for (int i = historylist.Count - 1; i >= 0 && maxjumpsback > 0; i--)
            {
                HistoryEntry pos = historylist[i];

                if (pos.IsLocOrJump && pos.System.HasCoordinate && !listnames.Contains(pos.System.Name))
                {
                    double dx     = (pos.System.X - x);
                    double dy     = (pos.System.Y - y);
                    double dz     = (pos.System.Z - z);
                    double distsq = dx * dx + dy * dy + dz * dz;

                    listnames.Add(pos.System.Name); //stops repeats..

                    if (distsq >= mindistance &&
                        (spherical && distsq <= maxdistance * maxdistance ||
                         !spherical && Math.Abs(dx) <= maxdistance && Math.Abs(dy) <= maxdistance && Math.Abs(dz) <= maxdistance))
                    {
                        if (distlist.Count < maxitems)          // if less than max, add..
                        {
                            distlist.Add(distsq, pos.System);
                        }
                        else if (distsq < distlist.Keys[distlist.Count - 1]) // if last entry (which must be the biggest) is greater than dist..
                        {
                            distlist.Add(distsq, pos.System);                // add in
                            distlist.RemoveAt(maxitems);                     // remove last..
                        }
                    }

                    maxjumpsback--;
                }
            }
        }
        ///////////////////////////////////////// List of systems near xyz between mindist and maxdist

        internal static void GetSystemListBySqDistancesFrom(BaseUtils.SortedListDoubleDuplicate <ISystem> distlist, // MUST use duplicate double list to protect against EDSM having two at the same point
                                                            double x, double y, double z,
                                                            int maxitems,
                                                            double mindist,     // 0 = no min dist, always spherical
                                                            double maxdist,
                                                            bool spherical,     // enforces sphere on maxdist, else its a cube for maxdist
                                                            SQLiteConnectionSystem cn,
                                                            Action <ISystem> LookedUp = null
                                                            )

        {
            // for comparision, using the grid screener is slower than the xy index. keep code for record
            // grid screener..  "s.sectorid IN (Select id FROM Sectors sx where sx.gridid IN (" + strinlist + ")) " +
            //var gridids = GridId.Ids(x - maxdist, x + maxdist, z - maxdist, z + maxdist);       // find applicable grid ids across this range..
            //var strinlist = string.Join(",", (from x1 in gridids select x1.ToStringInvariant()));     // here we convert using invariant for paranoia sake.

            // System.Diagnostics.Debug.WriteLine("Time1 " + BaseUtils.AppTicks.TickCountLap("SDC"));

            int mindistint = mindist > 0 ? SystemClass.DoubleToInt(mindist) * SystemClass.DoubleToInt(mindist) : 0;

            // needs a xz index for speed

            using (DbCommand cmd = cn.CreateSelect("Systems s",
                                                   MakeSystemQueryNamed,
                                                   where :
                                                   "s.x >= @xv - @maxdist " +
                                                   "AND s.x <= @xv + @maxdist " +
                                                   "AND s.z >= @zv - @maxdist " +
                                                   "AND s.z <= @zv + @maxdist " +
                                                   "AND s.y >= @yv - @maxdist " +
                                                   "AND s.y <= @yv + @maxdist " +
                                                   (mindist > 0 ? ("AND (s.x-@xv)*(s.x-@xv)+(s.y-@yv)*(s.y-@yv)+(s.z-@zv)*(s.z-@zv)>=" + (mindistint).ToStringInvariant()) : ""),
                                                   orderby: "(s.x-@xv)*(s.x-@xv)+(s.y-@yv)*(s.y-@yv)+(s.z-@zv)*(s.z-@zv)", // just use squares to order
                                                   joinlist: MakeSystemQueryNamedJoinList,
                                                   limit: "@max"
                                                   ))
            {
                cmd.AddParameterWithValue("@xv", SystemClass.DoubleToInt(x));
                cmd.AddParameterWithValue("@yv", SystemClass.DoubleToInt(y));
                cmd.AddParameterWithValue("@zv", SystemClass.DoubleToInt(z));
                cmd.AddParameterWithValue("@max", maxitems + 1);     // 1 more, because if we are on a System, that will be returned
                cmd.AddParameterWithValue("@maxdist", SystemClass.DoubleToInt(maxdist));

                // System.Diagnostics.Debug.WriteLine(cn.ExplainQueryPlanString(cmd));

                int  xi         = SystemClass.DoubleToInt(x);
                int  yi         = SystemClass.DoubleToInt(y);
                int  zi         = SystemClass.DoubleToInt(z);
                long maxdistsqi = (long)SystemClass.DoubleToInt(maxdist) * (long)SystemClass.DoubleToInt(maxdist);

                long count = 0;
                using (DbDataReader reader = cmd.ExecuteReader())
                {
                    //  System.Diagnostics.Debug.WriteLine("Time1.5 " + BaseUtils.AppTicks.TickCountLap("SDC"));

                    while (reader.Read())      // already sorted, and already limited to max items
                    {
                        int sxi = reader.GetInt32(0);
                        int syi = reader.GetInt32(1);
                        int szi = reader.GetInt32(2);

                        long distsqi = (long)(xi - sxi) * (long)(xi - sxi) + (long)(yi - syi) * (long)(yi - syi) + (long)(zi - szi) * (long)(zi - szi);

                        if (!spherical || distsqi <= maxdistsqi)
                        {
                            SystemClass s        = MakeSystem(reader);
                            double      distnorm = ((double)distsqi) / SystemClass.XYZScalar / SystemClass.XYZScalar;
                            //System.Diagnostics.Debug.WriteLine("System " + s.Name + " " + Math.Sqrt(distnorm).ToString("0.0"));
                            LookedUp?.Invoke(s);                        // callback to say looked up
                            distlist.Add(distnorm, s);                  // which Rob has seen crashing the program! Bad EDSM!
                        }

                        count++;
                    }

                    //  System.Diagnostics.Debug.WriteLine("Time2 " + BaseUtils.AppTicks.TickCountLap("SDC") + "  count " + count);
                }
            }
        }