Enlem ve Boylam Koordinatlarının x ve y Pixel Dönüşümü ve Harita Ölçeklendirmesi

Selamün Aleyküm Arkadaşlar,

Koordinatları verilmiş bir çokgenin çizimi nasıl yapılır bunu inceleyeceğiz.

polygon

 

Çokgen Enlem ve Boylam

Index Boylam (Longitude) Enlem (Latitude)
0 -142.734375 -44.087585
1 -129.726563 -40.313043
2 -117.246094 -45.460131
3 -110.742188 -53.225768
4 -117.070313 -59.800634
5 -132.011719 -64.168107
6 -148.535156 -59.888937
7 -154.335938 -53.014783
8 -142.734375 -44.087585

 

Tablodan enlem ve boylam için maksimum ve minimum değerlerini bulalım.

Boylam max: -110.742188

Boylam min: -154.335938

Enlem max: -40.313043

Enlem min: -64.168107

cizim5

Bu enlem ve boylam değerlerinin x ve y koordinatlarına çevirmemiz gerekir. Bunun için Merkator Projeksiyonundan (Mercator Projection) yararlanırız. Bu projeksiyon bize dünyanın bir dikdörtgen olarak harita açılımını verir. İlk önce enlem ve boylam radyan cinsine çevrilir.

Enlem = Enlem * pi / 180
Boylam = Boylam * pi / 180

Enlem = ln(tan(pi/4 + Enlem/2))

x = Boylam
y = Enlem

C#

public PointF getlatlong2xy (double longitude, double latitude) {
          var radians = Math.PI / 180;
          longitude = longitude * radians;
          latitude = latitude * radians;

          return new PointF(Convert.ToSingle(longitude), Convert.ToSingle(Math.Log(Math.Tan(Math.PI / 4 + 0.5 * latitude))));
        }

Merkator Projeksiyonuna çevirdiğimiz zaman:

PointF min = getlatlong2xy(-154.335938, -64.168107);
PointF max = getlatlong2xy(-110.742188, -40.313043);

 

maxmin

Enlem ve boylamları x ve y koordinatlara çevirelim:

Index X Y
0 -2.49118471 -0.859029233
1 -2.26415563 -0.770058334
2 -2.04633045 -0.892776847
3 -1.93281579 -1.10139823
4 -2.04326248 -1.31001961
5 -2.30403924 -1.47262156
6 -2.59242749 -1.31308758
7 -2.69367027 -1.09526229
8  -2.49118471 -0.859029233

 

Çizim Alanımız:

cizim

Çizim alanımızla çokgenin boyutlarının oranını bulmamız gerekir. İlk önce çizim alanımızdan 10px lik boşluk bırakalım. Genişlikten sağ ve sol olmak üzere 10px boşluk bıraktığımızda genişlik = genişlik – 20. Aynı şekilde yükseklik = yükseklik – 20. Yeni çizim alanımız 562×353

Şimdi ise Çokgenin x ve y deki boyutunu bulalım.

Xboyut = Xmax – Xmin

Yboyut = Ymax – Xmin

cizim5

genislikoran = 562 / Xboyut

yukseklikoran = 353 / Yboyut

Hangi oran daha düşükse o oran bizim genel oranımız olur.

genislikoran = 738.6432

yukseklikoran = 502.4459

geneloran = 502.4459

Genişlik ve Yükseklik boşluklarını bulalım.

Yukseklikbosluk = (373 – (Yboyut * geneloran)) / 2

Genislikbosluk = (582 – (Xboyut * geneloran)) / 2


cizim1

X ve Y koordinatlarımızı çizim için başlangıç durumuna getirelim.

X = X – Xmin

Y = Y – Ymin

Index X – Xmin Y – Ymin
0 0.202485561 0.6135923
1 0.429514647 0.7025632/td>
2 0.6473398 0.5798447
3 0.7608545 0.37122333
4 0.6504078 0.162601948
5 0.389631033 0.0
6 0.101242781 0.159533978
7 0.0 0.377359271
8 0.202485561 0.6135923

 

X ve Y koordinatlarını çizim alanına göre ölçekleyelim.

X = Genislikbosluk + (X * geneloran)

Y koordinatı 0,0 dan başlayacağı için tersine çevirelim.

Y = 373 – Yukseklikbosluk – (Y * geneloran)

Index X Y
0 201.593933 54.703064
1 315.663757 10.0
2 425.109131 71.65941
3 482.1441 176.480362
4 426.6506 281.301331
5 295.62442 363.0
6 150.724915 282.8428
7 99.855896 173.397385
8 201.593933 54.703064

 

cizim5

C#

public PointF getlatlong2xy (double longitude, double latitude) {
          var radians = Math.PI / 180;
          longitude = longitude * radians;
          latitude = latitude * radians;

          return new PointF(Convert.ToSingle(longitude), Convert.ToSingle(Math.Log(Math.Tan(Math.PI / 4 + 0.5 * latitude))));
}

public Image getImage(PointF[] points, int width, int height, int padding = 10)
        {
            if (points.Length == 0)
                return null;

            Image img = new Bitmap(width, height);

            PointF min = new PointF(points[0].X, points[0].Y);
            PointF max = new PointF(points[0].X, points[0].Y);

            foreach (PointF p in points)
            {
                min.X = (p.X < min.X) ? p.X : min.X;
                min.Y = (p.Y < min.Y) ? p.Y : min.Y;

                max.X = (p.X > max.X) ? p.X : max.X;
                max.Y = (p.Y > max.Y) ? p.Y : max.Y;
            }

            min = getlatlong2xy(min.X, min.Y);
            max = getlatlong2xy(max.X, max.Y);

            PointF XYlength = new PointF(max.X - min.X, max.Y - min.Y);

            int mapWidth = img.Width - padding * 2;
            int mapHeight = img.Height - padding * 2;

            float widthRatio = mapWidth / XYlength.X;
            float heightRatio = mapHeight / XYlength.Y;

            float globalRatio = Math.Min(widthRatio, heightRatio);

            int widthPadding = Convert.ToInt32((width - (XYlength.X * globalRatio)) / 2);
            int heightPadding = Convert.ToInt32((height - (XYlength.Y * globalRatio)) / 2);

            List<PointF> dpoints = new List<PointF>();

            foreach (PointF p in points)
            {
                PointF p1 = getlatlong2xy(p.X, p.Y);
                p1.X -= min.X;
                p1.Y -= min.Y;

                float x = widthPadding + p1.X * globalRatio;
                float y = img.Height - heightPadding - (p1.Y * globalRatio);

                dpoints.Add(new PointF(x, y));
            }

            Graphics g = Graphics.FromImage(img);
            g.FillPolygon(Brushes.Blue, dpoints.ToArray(), System.Drawing.Drawing2D.FillMode.Alternate);

            return img;
        }

 

Hayırlı Günler. Sağlıcakla kalın.

Bu döküman www.ibasoglu.com’a aittir. Kaynak belirtmek suretiyle alıntı yapılabilir.