Avatar billede rix Praktikant
26. december 2018 - 17:47 Der er 4 kommentarer

Udregn alle gps coord i en Polygonal array.

Jeg skal bruge alle de coord der findes inden for en polygonal grænse.
Hvis det bare vare en retvinklet firkant ville det jo være nemt nok. Men da jeg ikke kender alle vinkler og punkter som ville være mugligheder for har jeg brug for at lidt hjælp.

Alle punkter er gemt som List<MapPoint>

Hvor MapPoint kun inderholder 2 punkter
public double Long = {get; set;}
public double Lati = {get; set;}

Nolge derr har en ide om hvordan man kan udregne det?
Avatar billede claes57 Ekspert
27. december 2018 - 13:21 #1
Du skal dele området op i et antal trekanter. Find først tre punkter, hvor der ikke ligger andre indenfor den trekant. Derefter fra en side i trekanten til et nyt punkt (igen uden andre punkter indenfor den nye trekant. Så har du til sidst et antal trekanter, hvisarealer kan beregnes og adderes.
Avatar billede arne_v Ekspert
01. januar 2019 - 04:54 #2
Du bruger double og ikke int.

Derfor findes der et teoretisk uendeligt antal og i praktisk næsten uendeligt antal koordinater indenfor dit polygon.

Jeg tror at opgaven skal omformuleres.
Avatar billede rix Praktikant
01. januar 2019 - 12:50 #3
@claes57

Det er en god ide men i en område som ikke har en defineret ville det være en alt for stor at opdele områder :?

@arne_v
Det kan godt være du har ret:

Man har en array  med punkter. Latitude oh longtitude.
De er en værdi der kunne se sådan her ud.
52.525
51.517

Aldrig mere end 3 decimaler. Jeg har brug for at finde alle de koordinator som er inden for den polygon lignende område som de koordinater egentlig er.
Avatar billede arne_v Ekspert
02. januar 2019 - 01:31 #4
Så alt med 3 decimaler.

Jeg er bange for at den matematisk korrekte løsning er mere end jeg kan klare.

Jeg kan klare en næsten korekt løsning.


using System;
using System.Collections.Generic;
using System.Linq;

namespace E
{
    public class MapPoint
    {
        public double Long { get; set; }
        public double Lat { get; set; }
    }
    public class XPoint
    {
        public int X { get; set; }
        public int Y { get; set; }
    }
    public static class Extensions
    {
        public static XPoint ToXpoint(this MapPoint mp, int scale)
        {
            return new XPoint { X = (int)(mp.Long * scale + 0.5), Y = (int)(mp.Lat * scale + 0.5) };
        }
        public static MapPoint ToMapPoint(this XPoint xp, int scale)
        {
            return new MapPoint { Long = xp.X * 1.0 / scale, Lat = xp.Y * 1.0 / scale };
        }
        public static XPoint Minus(this XPoint xp, XPoint zero)
        {
            return new XPoint { X = xp.X - zero.X, Y = xp.Y - zero.Y };
        }
        public static XPoint Plus(this XPoint xp, XPoint zero)
        {
            return new XPoint { X = xp.X + zero.X, Y = xp.Y + zero.Y };
        }
    }
    public enum PointValue { OUTER, CORNER, BORDER, INNER };
    public class Analyze
    {
        private static XPoint FindMin(IEnumerable<XPoint> poly)
        {
            return new XPoint { X = poly.Select(xp => xp.X).Min(), Y = poly.Select(xp => xp.Y).Min() };
        }
        private static XPoint FindMax(IEnumerable<XPoint> poly)
        {
            return new XPoint { X = poly.Select(xp => xp.X).Max(), Y = poly.Select(xp => xp.Y).Max() };
        }
        public static PointValue[,] CreateMap(int w, int h)
        {
            PointValue[,] res = new PointValue[w,h];
            for(int x = 0; x < w; x++)
                for(int y = 0; y < h; y++)
                    res[x,y] = PointValue.INNER;
            return res;
        }
        private static void Draw(PointValue[,] map, XPoint start, XPoint finish)
        {
            int minx = Math.Min(start.X, finish.X);
            int maxx = Math.Max(start.X, finish.X);
            int miny = Math.Min(start.Y, finish.Y);
            int maxy = Math.Max(start.Y, finish.Y);
            for(int x = minx; x <= maxx; x++)
            {
                int y2 = (int)((x - minx) * 1.0 / (maxx - minx) * (maxy - miny) + miny + 0.5);
                if(map[x,y2] != PointValue.CORNER)
                    map[x,y2] = PointValue.BORDER;
            }
            for(int y = maxy; y >= miny; y--)
            {
                int x2 = (int)((y - miny) * 1.0 / (maxy - miny) * (maxx - minx) + minx + 0.5);
                if(map[x2,y] != PointValue.CORNER)
                    map[x2,y] = PointValue.BORDER;
            }
        }
        public static void Draw(PointValue[,] map, List<XPoint> poly)
        {
            foreach(XPoint xp in poly)
            {
                map[xp.X,xp.Y] = PointValue.CORNER;
            }
            for(int i = 0; i < poly.Count - 1; i++)
            {
                Draw(map, poly[i], poly[i + 1]);
            }
            Draw(map, poly[poly.Count - 1], poly[0]);
        }
        private static char Visual(PointValue pv)
        {
            switch(pv)
            {
                case PointValue.OUTER: return ' ';
                case PointValue.CORNER: return 'X';
                case PointValue.BORDER: return '*';
                case PointValue.INNER: return '-';
                default: throw new Exception("Ooops");
            }
        }
        public static void Fill(PointValue[,] map)
        {
            Queue<Tuple<int, int>> todo = new Queue<Tuple<int, int>>();
            todo.Enqueue(Tuple.Create(0, 0));
            while(todo.Count > 0)
            {
                Tuple<int, int> temp = todo.Dequeue();
                int x = temp.Item1;
                int y = temp.Item2;
                if(map[x,y] == PointValue.INNER)
                {
                    map[x,y] = PointValue.OUTER;
                    if(x - 1 >= 0 && map[x - 1,y] == PointValue.INNER) todo.Enqueue(Tuple.Create(x - 1, y));
                    if(x + 1 < map.GetLength(0) && map[x + 1,y] == PointValue.INNER) todo.Enqueue(Tuple.Create(x + 1, y));
                    if(y - 1 >= 0 && map[x,y - 1] == PointValue.INNER) todo.Enqueue(Tuple.Create(x, y - 1));
                    if(y + 1 < map.GetLength(1) && map[x,y + 1] == PointValue.INNER) todo.Enqueue(Tuple.Create(x, y + 1));
                }
            }
        }
        public static void Dump(PointValue[,] map)
        {
            for(int y = map.GetLength(1) - 1; y >= 0; y--)
            {
                for(int x = 0; x < map.GetLength(0); x++)
                {
                    Console.Write(Visual(map[x,y]));
                }
                Console.WriteLine();
            }
        }
        private static List<XPoint> Find(PointValue[,] map)
        {
            List<XPoint> res = new List<XPoint>();
            for(int y = map.GetLength(1) - 1; y >= 0; y--)
            {
                for(int x = 0; x < map.GetLength(0); x++)
                {
                    if(map[x,y] == PointValue.INNER)
                    {
                        res.Add(new XPoint { X = x, Y = y });
                    }
                }
            }
            return res;
        }
        public static List<MapPoint> Find(List<MapPoint> poly, int scale)
        {
            IEnumerable<XPoint> temp = poly.Select(mp => mp.ToXpoint(scale));
            XPoint zero = FindMin(temp);
            zero.X--;
            zero.Y--;
            List<XPoint> poly2 = temp.Select(xp => xp.Minus(zero)).ToList();
            XPoint minp = FindMin(poly2);
            XPoint maxp = FindMax(poly2);
            PointValue[,] map = CreateMap(maxp.X - minp.X + 3, maxp.Y - minp.Y + 3);
            Draw(map, poly2);
            Fill(map);
            if(scale == 10) Dump(map);
            List<XPoint> inner = Find(map);
            List<MapPoint> inner2 = inner.Select(xp => xp.Plus(zero).ToMapPoint(scale)).ToList();
            return inner2;
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            List<MapPoint> poly = new List<MapPoint> { new MapPoint { Long = 2.0, Lat = 2.0 },
                                                      new MapPoint { Long = 7.5, Lat = 6.0 },
                                                      new MapPoint { Long = 5.5, Lat = 2.5 } };
            List<MapPoint> inner = Analyze.Find(poly, 10);
            Console.WriteLine("Found: {0}", inner.Count);
            Console.WriteLine("Range: ({0},{1}) ... ({2},{3})", inner.First().Long, inner.First().Lat, inner.Last().Long, inner.Last().Lat);
            inner = Analyze.Find(poly, 100);
            Console.WriteLine("Found: {0}", inner.Count);
            inner = Analyze.Find(poly, 1000);
            Console.WriteLine("Found: {0}", inner.Count);
            Console.ReadKey();
        }
    }
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester