コード例 #1
0
        /// <summary>
        /// Bounding Polygon
        /// Get all the hashString covered by the polygon in numberOfChars
        /// </summary>
        /// <param name="polygon">array of coordinates describes the polygon</param>
        /// <param name="numberOfChars"></param>
        /// <returns>array of hash string</returns>
        public static string[] Bpolygon(Coordinates[] polygon, int numberOfChars = 9)
        {
            var hashList = new List <string>();
            // Get all bounding boxes that are possible be covered by polygon
            Coordinates max = new Coordinates {
                Lat = -90, Lon = -180
            };
            Coordinates min = new Coordinates {
                Lat = 90, Lon = 180
            };

            foreach (Coordinates c in polygon)
            {
                max.Lat = Math.Max(max.Lat, c.Lat);
                max.Lon = Math.Max(max.Lon, c.Lon);
                min.Lat = Math.Min(min.Lat, c.Lat);
                min.Lon = Math.Min(min.Lon, c.Lon);
            }
            string[] bboxHash = GeoHash.Bboxes(min.Lat, min.Lon, max.Lat, max.Lon, numberOfChars);
            foreach (string hash in bboxHash)
            {
                BoundingBox box = GeoHash.DecodeBbox(hash);
                if (BoxOverlapPolygon(box, polygon))
                {
                    hashList.Add(hash);
                }
            }
            return(hashList.ToArray());
        }
コード例 #2
0
        /// <summary>
        /// Bounding Box Coordinates
        /// Get all coordinates covered by the box in numberOfChars
        /// </summary>
        /// <param name="minLat"></param>
        /// <param name="minLon"></param>
        /// <param name="maxLat"></param>
        /// <param name="maxLon"></param>
        /// <param name="numberOfChars"></param>
        /// <returns>all coordinates covered by the box in numberOfChars</returns>
        public Coordinates[] BboxCoordinates(double minLat, double minLon, double maxLat, double maxLon, int numberOfChars = 9)
        {
            var coorList = new List <Coordinates>();

            string[] hashList = GeoHash.Bboxes(minLat, minLon, maxLat, maxLat, numberOfChars);

            foreach (string hash in hashList)
            {
                // TODO: search all level or search current level only?
                Coordinates[] coors = GetCoordinates(hash);
                BoundingBox   box   = GeoHash.DecodeBbox(hash);

                if (BoxInBoxRange(box, minLat, minLon, maxLat, maxLon))
                {
                    // All covered by box
                    coorList.AddRange(coors);
                }
                else
                {
                    // Not all covered by box
                    foreach (Coordinates c in coors)
                    {
                        if (CoordinateInBoxRange(c, minLat, minLon, maxLat, maxLon))
                        {
                            coorList.Add(c);
                        }
                    }
                }
            }

            return(coorList.ToArray());
        }
コード例 #3
0
        /// <summary>
        /// Find the length of the shortest side of a box
        /// </summary>
        /// <param name="hash"></param>
        /// <returns>length in meter</returns>
        public static double FindMinSideLength(string hash)
        {
            BoundingBox box   = GeoHash.DecodeBbox(hash);
            double      west  = Measure(box.Minimum.Lat, box.Minimum.Lon, box.Maximum.Lat, box.Minimum.Lon);
            double      east  = Measure(box.Minimum.Lat, box.Maximum.Lon, box.Maximum.Lat, box.Maximum.Lon);
            double      south = Measure(box.Minimum.Lat, box.Minimum.Lon, box.Minimum.Lat, box.Maximum.Lon);
            double      north = Measure(box.Maximum.Lat, box.Maximum.Lon, box.Maximum.Lat, box.Minimum.Lon);

            return(Math.Min(Math.Min(west, east), Math.Min(north, south)));
        }
コード例 #4
0
        /// <summary>
        /// Get all bounding boxes covered by polygon in numberOfChars
        /// </summary>
        /// <param name="polygon">array of coordinates describes the polygon</param>
        /// <param name="numberOfChars"></param>
        /// <returns>array of hash string</returns>
        public static BoundingBox[] BpolygonBoxes(Coordinates[] polygon, int numberOfChars = 9)
        {
            var boxList = new List <BoundingBox>();

            string[] hashList = Bpolygon(polygon, numberOfChars);
            foreach (string hash in hashList)
            {
                boxList.Add(GeoHash.DecodeBbox(hash));
            }
            return(boxList.ToArray());
        }
コード例 #5
0
        /// <summary>
        /// Get all bounding boxes covered by box
        /// </summary>
        /// <param name="minLat"></param>
        /// <param name="minLon"></param>
        /// <param name="maxLat"></param>
        /// <param name="maxLon"></param>
        /// <param name="numberOfChars"></param>
        /// <returns></returns>
        public static BoundingBox[] BboxBoxes(double minLat, double minLon, double maxLat, double maxLon, int numberOfChars = 9)
        {
            var boxList = new List <BoundingBox>();

            string[] hashList = GeoHash.Bboxes(minLat, minLon, maxLat, maxLon, numberOfChars);
            foreach (string hash in hashList)
            {
                boxList.Add(GeoHash.DecodeBbox(hash));
            }

            return(boxList.ToArray());
        }
コード例 #6
0
        /// <summary>
        /// Get all bounding boxes that covers the circle
        /// </summary>
        /// <param name="latitude">latitude of center point</param>
        /// <param name="longitude">longitude of center point</param>
        /// <param name="radius">radius in meters</param>
        /// <param name="numberOfChars">number of characters of hash string</param>
        /// <returns>bounding box object array</returns>
        public static BoundingBox[] BcircleBoxes(double latitude, double longitude, double radius, int numberOfChars = 9)
        {
            var boxList = new List <BoundingBox>();

            string[] hashList = Bcircle(latitude, longitude, radius, numberOfChars);
            foreach (string hash in hashList)
            {
                boxList.Add(GeoHash.DecodeBbox(hash));
            }

            return(boxList.ToArray());
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: ChenshuXu/geohash-kvs
        public static void BoundingCircleTest()
        {
            Coordinates c = new Coordinates {
                Lat = mLat, Lon = mLon
            };

            Console.WriteLine("point latitude " + c.Lat + ", longitude " + c.Lon);
            var encoded = GeoHash.Encode(c.Lat, c.Lon, mLevel);

            Console.WriteLine("encoded = " + encoded);

            var decoded   = GeoHash.Decode(encoded);
            var latitude  = decoded.Coordinates.Lat;
            var longitude = decoded.Coordinates.Lon;

            Console.WriteLine("decoded box latitude " + latitude + ", longitude " + longitude);

            BoundingBox box    = GeoHash.DecodeBbox(encoded);
            var         maxLat = box.Maximum.Lat;
            var         minLat = box.Minimum.Lat;
            var         maxLon = box.Maximum.Lon;
            var         minLon = box.Minimum.Lon;

            // Measure the box size in meters
            var oneSide     = DataBase.Measure(maxLat, minLon, minLat, minLon);
            var anotherSide = DataBase.Measure(maxLat, maxLon, maxLat, minLon);

            // Bounding circle
            var watch = System.Diagnostics.Stopwatch.StartNew();

            string[] hashList = DataBase.Bcircle(c.Lat, c.Lon, mRadius, mLevel);
            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;

            //foreach (var h in hashList)
            //{
            //    Console.WriteLine(h);
            //}

            Console.WriteLine("box size: " + oneSide + " meters * " + anotherSide + " meters");
            Console.WriteLine("bounding circle radius " + mRadius + " meters, level " + mLevel);
            Console.WriteLine("Get bounding circle, time elapsed: " + elapsedMs + " ms | " + hashList.Length + " results get");
            string filename = "bounding circle" + c.Lat.ToString() + "-" + c.Lon.ToString() + "-" + mRadius.ToString() + "-" + mLevel.ToString();

            KMLGenerator.GenerateKMLBoundingCircle(hashList, c.Lat, c.Lon, mRadius, filename);
            Console.WriteLine("save as file name " + filename);
        }
コード例 #8
0
        /// <summary>
        /// Bounding Circle Coordinates
        /// Get all coordinates covered by the circle in numberOfChars
        /// </summary>
        /// <param name="latitude">latitude of center point</param>
        /// <param name="longitude">longitude of center point</param>
        /// <param name="radius">radius in meters</param>
        /// <param name="numberOfChars">number of characters of hash string</param>
        /// <param name="limit">max number of coordinates return</param>
        /// <returns>array of coordinate object</returns>
        public Coordinates[] BcircleCoordinates(double latitude, double longitude, double radius, int numberOfChars = 9, int limit = 0)
        {
            var coorList = new List <Coordinates>();

            string[] hashList = Bcircle(latitude, longitude, radius, numberOfChars);
            foreach (string hash in hashList)
            {
                // TODO: search all level or search current level only?
                Coordinates[] coors = GetCoordinates(hash);
                BoundingBox   box   = GeoHash.DecodeBbox(hash);

                if (BoxAllInCircleRange(box, latitude, longitude, radius))
                {
                    // All covered by circle
                    coorList.AddRange(coors);
                }
                else
                {
                    // Not all covered by circle
                    foreach (Coordinates c in coors)
                    {
                        if (Measure(c.Lat, c.Lon, latitude, longitude) <= radius)
                        {
                            coorList.Add(c);
                        }
                    }
                }
            }

            if (limit == 0)
            {
                return(coorList.ToArray());
            }

            coorList.Sort((x, y) => Measure(x.Lat, x.Lon, latitude, longitude).CompareTo(Measure(y.Lat, y.Lon, latitude, longitude)));

            if (coorList.Count >= limit)
            {
                return(coorList.GetRange(0, limit).ToArray());
            }

            return(coorList.ToArray());
        }
コード例 #9
0
ファイル: KMLGenerator.cs プロジェクト: ChenshuXu/geohash-kvs
        /**
         * Draw bounding circle
         * Generate kml from a list of boxhash
         */
        public static void GenerateKMLBoundingCircle(string[] hashList, double latitude, double longitude, double radius, string fileName)
        {
            string kmlStr = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
<kml xmlns=""http://www.opengis.net/kml/2.2"" >
    <Document>
        <name>BoundingCircle</name>
        <Style id=""yellowLineGreenPoly"">
            <LineStyle>
                <color> 7f00ffff </color>
                <width> 4 </width>
            </LineStyle>
            <PolyStyle>
                <color> 7f00ff00 </color>
            </PolyStyle>
        </Style>
        <Placemark>
            <styleUrl>#yellowLineGreenPoly</styleUrl>
            <MultiGeometry>";

            foreach (string hash in hashList)
            {
                kmlStr += "\n";
                kmlStr += @"            <LineString>
                    <extrude> 1 </extrude >
                    <tessellate> 1 </tessellate>
                    <altitudeMode> absolute </altitudeMode>
                        <coordinates> ";
                var box = GeoHash.DecodeBbox(hash);

                kmlStr += box.Maximum.Lon.ToString();
                kmlStr += ",";
                kmlStr += box.Maximum.Lat.ToString();
                kmlStr += ",20";
                kmlStr += "\n";

                kmlStr += box.Maximum.Lon.ToString();
                kmlStr += ",";
                kmlStr += box.Minimum.Lat.ToString();
                kmlStr += ",20";
                kmlStr += "\n";

                kmlStr += box.Minimum.Lon.ToString();
                kmlStr += ",";
                kmlStr += box.Minimum.Lat.ToString();
                kmlStr += ",20";
                kmlStr += "\n";

                kmlStr += box.Minimum.Lon.ToString();
                kmlStr += ",";
                kmlStr += box.Maximum.Lat.ToString();
                kmlStr += ",20";
                kmlStr += "\n";

                kmlStr += box.Maximum.Lon.ToString();
                kmlStr += ",";
                kmlStr += box.Maximum.Lat.ToString();
                kmlStr += ",20";
                kmlStr += "\n";

                kmlStr += @"                        </coordinates>
            </LineString>";
            }

            kmlStr += "\n";
            kmlStr += @"            <LineString>
                    <extrude> 1 </extrude >
                    <tessellate> 1 </tessellate>
                    <altitudeMode> absolute </altitudeMode>
                        <coordinates> ";

            // Draw the circle
            for (double degree = 0; degree < 360; degree += 0.5)
            {
                var coor = DataBase.DistanceToPoint(latitude, longitude, radius, degree);


                kmlStr += coor.Lon.ToString();
                kmlStr += ",";
                kmlStr += coor.Lat.ToString();
                kmlStr += ",20";
                kmlStr += "\n";

                //Console.WriteLine(Measure(latitude, longitude, coor.Lat, coor.Lon));
            }
            kmlStr += @"                        </coordinates>
            </LineString>";

            // Draw center
            kmlStr += "<Point><coordinates>" +
                      longitude.ToString() + "," + latitude.ToString()
                      + "</coordinates></Point>";

            kmlStr += @"
            </MultiGeometry>
        </Placemark>
    </Document>
</kml>";
            using (StreamWriter sw = new StreamWriter(fileName + ".kml"))
            {
                sw.WriteLine(kmlStr);
            }
        }
コード例 #10
0
ファイル: KMLGenerator.cs プロジェクト: ChenshuXu/geohash-kvs
        /**
         * Draw bounding boxes
         * Generate kml from a list of boxhash
         */
        public static void GenerateKMLBoundingBoxes(string[] hashList, Coordinates coorMin, Coordinates coorMax, string fileName)
        {
            string kmlStr = $@"<?xml version=""1.0"" encoding=""UTF-8""?>
<kml xmlns=""http://www.opengis.net/kml/2.2"" >
    <Document>
        <name>BoundingBoxes</name>
        <Style id=""yellowLineGreenPoly"">
            <LineStyle>
                <color> 7f00ffff </color>
                <width> 4 </width>
            </LineStyle>
            <PolyStyle>
                <color> 7f00ff00 </color>
            </PolyStyle>
        </Style>
        <Placemark>
            <styleUrl>#redLineGreenPoly</styleUrl>
            <MultiGeometry>";

            foreach (string hash in hashList)
            {
                //Console.WriteLine(hash+",");
                kmlStr += "\n";
                kmlStr += @"
                <LineString>
                    <extrude> 1 </extrude >
                    <tessellate> 1 </tessellate>
                    <altitudeMode> absolute </altitudeMode>
                        <coordinates> ";
                var box = GeoHash.DecodeBbox(hash);

                kmlStr += box.Maximum.Lon.ToString();
                kmlStr += ",";
                kmlStr += box.Maximum.Lat.ToString();
                kmlStr += ",20";
                kmlStr += "\n";

                kmlStr += box.Maximum.Lon.ToString();
                kmlStr += ",";
                kmlStr += box.Minimum.Lat.ToString();
                kmlStr += ",20";
                kmlStr += "\n";

                kmlStr += box.Minimum.Lon.ToString();
                kmlStr += ",";
                kmlStr += box.Minimum.Lat.ToString();
                kmlStr += ",20";
                kmlStr += "\n";

                kmlStr += box.Minimum.Lon.ToString();
                kmlStr += ",";
                kmlStr += box.Maximum.Lat.ToString();
                kmlStr += ",20";
                kmlStr += "\n";

                kmlStr += box.Maximum.Lon.ToString();
                kmlStr += ",";
                kmlStr += box.Maximum.Lat.ToString();
                kmlStr += ",20";
                kmlStr += "\n";

                kmlStr += @"                        </coordinates>
            </LineString>";
            }

            // Draw bounding box
            kmlStr += "\n";
            kmlStr += @"            <LineString>
                    <extrude> 1 </extrude >
                    <tessellate> 1 </tessellate>
                    <altitudeMode> absolute </altitudeMode>
                        <coordinates> ";

            kmlStr += coorMin.Lon.ToString();
            kmlStr += ",";
            kmlStr += coorMin.Lat.ToString();
            kmlStr += ",20";
            kmlStr += "\n";

            kmlStr += coorMin.Lon.ToString();
            kmlStr += ",";
            kmlStr += coorMax.Lat.ToString();
            kmlStr += ",20";
            kmlStr += "\n";

            kmlStr += coorMax.Lon.ToString();
            kmlStr += ",";
            kmlStr += coorMax.Lat.ToString();
            kmlStr += ",20";
            kmlStr += "\n";

            kmlStr += coorMax.Lon.ToString();
            kmlStr += ",";
            kmlStr += coorMin.Lat.ToString();
            kmlStr += ",20";
            kmlStr += "\n";

            kmlStr += coorMin.Lon.ToString();
            kmlStr += ",";
            kmlStr += coorMin.Lat.ToString();
            kmlStr += ",20";
            kmlStr += "\n";

            kmlStr += @"                        </coordinates>
            </LineString>";

            kmlStr += @"
            </MultiGeometry>
        </Placemark>
    </Document>
</kml>";
            using (StreamWriter sw = new StreamWriter(fileName + ".kml"))
            {
                sw.WriteLine(kmlStr);
            }
        }
コード例 #11
0
        /// <summary>
        /// Bounding Circle
        /// Get all the hashString covered by the circle in numberOfChars
        /// </summary>
        /// <param name="latitude">latitude of center point</param>
        /// <param name="longitude">longitude of center point</param>
        /// <param name="radius">radius in meters</param>
        /// <param name="numberOfChars">number of characters of hash string</param>
        /// <returns>hash string array</returns>
        public static string[] Bcircle(double latitude, double longitude, double radius, int numberOfChars = 9)
        {
            var    hashList   = new List <string>();
            string hashCenter = GeoHash.Encode(latitude, longitude, numberOfChars);

            hashList.Add(hashCenter);

            GeohashDecodeResult latLon = GeoHash.Decode(hashCenter);

            // Find left and right end
            // Find west(left) end
            Coordinates leftCoor = DistanceToPoint(latitude, longitude, radius, 270);
            string      hashLeft = GeoHash.Encode(leftCoor.Lat, leftCoor.Lon, numberOfChars);

            NGeoHash.BoundingBox boxLeft = GeoHash.DecodeBbox(hashLeft);

            // Find east(right) end
            Coordinates rightCoor = DistanceToPoint(latitude, longitude, radius, 90);
            string      hashRight = GeoHash.Encode(rightCoor.Lat, rightCoor.Lon, numberOfChars);

            NGeoHash.BoundingBox boxRight = GeoHash.DecodeBbox(hashRight);

            // Find steps(from left to right)
            double perLon  = latLon.Error.Lon * 2; // box size(in degree) on west-east direction
            var    lonStep = Math.Round((boxRight.Minimum.Lon - boxLeft.Minimum.Lon) / perLon);

            double perLat = latLon.Error.Lat * 2; // box size(in dgree) on north–south direction

            for (var lon = 0; lon <= lonStep; lon++)
            {
                // Find current box
                string currentBoxHash           = GeoHash.Neighbor(hashLeft, new[] { 0, lon });
                NGeoHash.BoundingBox currentBox = GeoHash.DecodeBbox(currentBoxHash);

                // Find north(upper) end
                // Find up neighbor
                // Check if in range
                int i = 0;
                NGeoHash.BoundingBox upBox = currentBox;
                string upBoxHash           = currentBoxHash;
                while (BoxInCircleRange(upBox, latitude, longitude, radius))
                {
                    if (!hashList.Contains(upBoxHash))
                    {
                        hashList.Add(upBoxHash);
                    }
                    //Console.WriteLine("Add+ " + upBoxHash);
                    i++;
                    upBoxHash = GeoHash.Neighbor(currentBoxHash, new[] { i, 0 });
                    upBox     = GeoHash.DecodeBbox(upBoxHash);
                }

                // Find south(down) end
                // Find steps(north to south)
                int j = 0;
                NGeoHash.BoundingBox downBox = currentBox;
                string downBoxHash           = currentBoxHash;
                while (BoxInCircleRange(downBox, latitude, longitude, radius))
                {
                    if (!hashList.Contains(downBoxHash))
                    {
                        hashList.Add(downBoxHash);
                    }
                    //Console.WriteLine("Add- " + downBoxHash);
                    j--;
                    downBoxHash = GeoHash.Neighbor(currentBoxHash, new[] { j, 0 });
                    downBox     = GeoHash.DecodeBbox(downBoxHash);
                }
            }

            // Check each point on the circle, see if covers more box
            // Find step length of radius
            double stepOfRadius = FindMinSideLength(hashCenter) * 0.9;
            // Find step of cricle, devide 360 degree to how many parts
            double stepOfCircle = 360 / (Math.PI * 2 * radius / stepOfRadius);

            for (double degree = 0; degree <= 360; degree += stepOfCircle)
            {
                Coordinates coor = DistanceToPoint(latitude, longitude, radius, degree);
                string      hash = GeoHash.Encode(coor.Lat, coor.Lon, numberOfChars);
                if (!hashList.Contains(hash))
                {
                    hashList.Add(hash);
                }
            }


            return(hashList.ToArray());
        }