12 Mart 2021 Cuma

JTS CBS Kütüphanesi Rehberi 2 - Geometrik İlişki Hesaplamaları

Merhabalar. JTS rehberimizin bir önceki bölümünde geometrik modelleri tanımıştık. Şimdi ise kesişir mi, içerir mi gibi ilişki hesaplamalarının nasıl yapıldığını göreceğiz.

Geometri modeli kapsamındaki tüm nesneler Geometry sınıfından türemektedir. Bu sınıfın bize sunduğu bazı hesaplama metodlarını inceleyeceğiz.

Görselleştirme

Geometrik Kapsama Hesaplama
Geometrik Kapsama Hesaplama

Tüm bu bilgiler görselleştirilmez ise anlaşılması zor olabilirdi. Bu nedenle basit bir Swing arayüzü ile yaptığımız hesaplamaları bir JPanel üzerine çizmek faydalı olacaktır. Bu yazıdaki tüm denemeleri çalıştırıp görselleştirebileceğiniz kodların bulunduğu projeye GitHub'da şuradan ulaşabilirsiniz. 

paintComponent metodunu override ettiğimiz JPanel'den türeyen JTSGorsellestirmePanel sınıfında, java.awt.Graphics nesnesini kullanarak 2D çizimler yapacağız. Yalnız, bu Graphics sınıfının çizim metodları integer türünde değerler almakta. JTS hesaplamaları ise double değerler de dönebilmektedir. Bu nedenle görselleştirmeler %100 gerçek noktalara oturmayıp hafif hassasiyet kaybı yaşanmış şekilde çizilebilecektir.

JTSGorsellestimePanel.java
JTSGorsellestimePanel.java
 

Her görselleştirme için farklı DrawingCommand nesnelerini bu panele draw command olarak ekleyecek ve istediğimiz çizimleri ekranda görebileceğiz. 

DrawingCommand.java
DrawingCommand.java

 Örneğin iki LineString'in kesişimini görselleştirdiğimizde ekranda şöyle bir panel göreceğiz.

Kesişim LineString

Area - Alan

Bir üçgeni temsil edecek Polygon nesnesi oluşturup getArea() metodu ile alanını hesaplatalım. Örnek projemizde AlanHesaplama.java sınıfını çalıştırarak görselleştirebilirsiniz.

        GeometryFactory geometryFactory = new GeometryFactory();

        Coordinate[] coordinates = new Coordinate[] { new Coordinate(150, 60), new Coordinate(200, 150),  new Coordinate(90, 150),new Coordinate(150, 60)};

         Polygon polygon = geometryFactory.createPolygon(coordinates);
               
        double alan = polygon.getArea();

Geometrik Alan Hesaplama
Geometrik Alan Hesaplama

Tanımladığımız üçgenin koordinatlarından, üçgenin yüksekliğinin 150 - 60 = 90 birim, taban uzunluğunun ise, 200 - 90 = 110 birim olduğu görülüyor. Üçgenin alanı formülünden 90 * 110 /2 = 4950 olarak alanı doğru hesapladığını görebiliyoruz.

Length / Perimeter - Uzunluk Çevre

Bir çizgiyi temsil edecek LineString tanımlayıp uzunluğunu hesaplatalım. Çevre hesaplamak için de bir beşgeni temsil edecek Polygon nesnesi tanımlayıp çevresini hesaplatalım. Örnek projemizdeki UzunlukCevreHesaplama.java sınıfını çalıştırarak görselleştirebilirsiniz.

GeometryFactory geometryFactory = new GeometryFactory();

                Coordinate[] coordinates = new Coordinate[] { new Coordinate(150, 60), new Coordinate(200, 150),
                        new Coordinate(80, 80), new Coordinate(40, 160), new Coordinate(50, 60)};

                LineString lineString = geometryFactory.createLineString(coordinates);
               
                double uzunluk = lineString.getLength();
               
               
                Coordinate[] polygonCoordinates = new Coordinate[] { new Coordinate(60, 250), new Coordinate(160, 270),
                        new Coordinate(170, 330), new Coordinate(100, 350), new Coordinate(50, 280), new Coordinate(60, 250)};
               
                Polygon polygon = geometryFactory.createPolygon(polygonCoordinates);
               
                double poligonCevre = polygon.getLength();

Uzunluk Çevre Hesaplama
Uzunluk Çevre Hesaplama

Distance / isWithinDistance - Uzaklık, Mesafe İçinde mi

Bir nokta ve poligon tanımlayalım. Noktanın poligona olan uzaklığını hesaplayalım. Daha sonra bu uzaklığa göre, isWithinDistance metodu ile verdiğimiz mesafe içinde poligon nesnesi var mı kontrolünü yapalım. UzaklikHesaplama.java sınıfını çalıştırarak sonuçları ekranda görselleştirebilirsiniz.

GeometryFactory geometryFactory = new GeometryFactory();

                Coordinate[] coordinates = new Coordinate[] { new Coordinate(250, 60), new Coordinate(300, 150),  new Coordinate(190, 150),new Coordinate(250, 60)};

                Polygon polygon = geometryFactory.createPolygon(coordinates);
               
                Point point = geometryFactory.createPoint(new Coordinate(100, 100));
               
                double distance = polygon.distance(point);
               
                DistanceOp op = new DistanceOp(polygon, point);
               
                Coordinate[] nearestPoints = op.nearestPoints();
               
                boolean mesafedeMi103 = point.isWithinDistance(polygon, 103);
               
                boolean mesafedeMi102 = point.isWithinDistance(polygon, 102);

Uzaklık Hesaplama
Uzaklık Hesaplama

Contains / Within - İçeriyor, İçinde

Bir önceki örnekte kullandığımız poligonun içinde olan ve dışında olan iki nokta oluşturalım. contains metodu ile içeriyor kontrolü yapalım. within metodu ile de içinde mi kontrolü yapalım. IceriyorHesaplama.java sınıfını çalıştırarak sonuçları ekranda görselleştirebilirsiniz.

GeometryFactory geometryFactory = new GeometryFactory();

                Coordinate[] coordinates = new Coordinate[] { new Coordinate(250, 60), new Coordinate(300, 150),  new Coordinate(190, 150),new Coordinate(250, 60)};

                Polygon polygon = geometryFactory.createPolygon(coordinates);
               
                Point point = geometryFactory.createPoint(new Coordinate(100, 100));
               
                Point point2 = geometryFactory.createPoint(new Coordinate(250, 85));
               
                boolean poligonPoint1iIceriyorMu = polygon.contains(point);
               
                boolean poligonPoint2yiIceriyorMu = polygon.contains(point2);
               
                boolean point1PoligonunIcindeMi = point.within(polygon);
               
                boolean point2PoligonunIcindeMi = point2.within(polygon);

İçerir Hesaplama
İçerir Hesaplama

Covers / CoveredBy - Kapsıyor, Tarafından Kapsanıyor

Bir dörtgen ve dörtgenin içinde bulunacak şekilde bir üçgen tanımlayalım. covers metodu ile dörtgenin üçgeni kapsadığını, coveredBy metodu ile de üçgenin dörtgen tarafından kapsandığını gösterelim. KapsiyorHesaplama.java sınıfını çalıştırarak sonuçları ekranda görselleştirebilirsiniz.

GeometryFactory geometryFactory = new GeometryFactory();

                Coordinate[] coordinates = new Coordinate[] { new Coordinate(250, 110), new Coordinate(300, 200),  new Coordinate(190, 200),new Coordinate(250, 110)};

                Polygon polygon = geometryFactory.createPolygon(coordinates);
               
                Coordinate[] dortgenCoordinates = new Coordinate[] { new Coordinate(110, 80), new Coordinate(370, 90),  new Coordinate(370, 250),new Coordinate(100, 250) , new Coordinate(110, 80)};

                Polygon dortgen = geometryFactory.createPolygon(dortgenCoordinates);
               
                boolean dortgenPoligonuKapsiyorMu = dortgen.covers(polygon);
               
                boolean poligonDortgenTarafindanKapsaniyorMu = polygon.coveredBy(dortgen);


 

Kapsama Hesaplama
Kapsama Hesaplama

Intersects / Disjoint - Kesişir, Ayrık

3 adet çizgi çizelim ve bunların ilk ikisi kesişiyor olsun. intersects metodu ile çizgi 1 ve çizgi 2'nin kesiştiğini, çizgi 3'ün kesişmediğini gösterelim. disjoint metodu ile de çizgi 3 ve çizgi 1'in ayrık olduğunu gösterelim. KesisimHesaplama.java sınıfını çalıştırarak sonuçları ekranda görselleştirebilirsiniz.

GeometryFactory geometryFactory = new GeometryFactory();

                Coordinate[] coordinates = new Coordinate[] { new Coordinate(50, 50), new Coordinate(150, 150) };

                LineString cizgi1 = geometryFactory.createLineString(coordinates);

                LineString cizgi2 = geometryFactory.createLineString(new Coordinate[] { new Coordinate(80, 40), new Coordinate(30, 250) });

                boolean cizgi1Cizgi2KesisirMi = cizgi1.intersects(cizgi1);
               
                Point intersectionPoint = (Point) cizgi1.intersection(cizgi2);
               
                LineString cizgi3 = geometryFactory.createLineString(new Coordinate[] { new Coordinate(210, 75), new Coordinate(350, 170) });

               
                boolean cizgi3Cizgi1AyrikMi = cizgi3.disjoint(cizgi1);
               
                boolean cizgi3Cizgi1KesşsşrMi = cizgi3.intersects(cizgi1);

Kesişim Hesaplama
Kesişim Hesaplama

Crosses - Kesiyor

Birbirini kesen geometrilerde crosses çağrısı true dönmektedir. KesiyorHesaplama.java sınıfını çalıştırarak sonuçları ekranda görselleştirebilirsiniz.

GeometryFactory geometryFactory = new GeometryFactory();

                Coordinate[] coordinates1 = new Coordinate[] { new Coordinate(60, 60), new Coordinate(110, 110), new Coordinate(155, 60),
                        new Coordinate(60, 60)};

                Coordinate[] coordinates2 = new Coordinate[] { new Coordinate(150, 120), new Coordinate(300, 120),
                        new Coordinate(300, 180), new Coordinate(150, 180), new Coordinate(150, 120) };
               
                Coordinate[] coordinates3 = new Coordinate[] { new Coordinate(40, 75), new Coordinate(350, 120) };
               
                Coordinate[] coordinates4 = new Coordinate[] { new Coordinate(210, 160), new Coordinate(350, 250) };

                Polygon poly1 = geometryFactory.createPolygon(coordinates1);

                Polygon poly2 = geometryFactory.createPolygon(coordinates2);
               
                LineString line1 = geometryFactory.createLineString(coordinates3);
               
                LineString line2 = geometryFactory.createLineString(coordinates4);


                System.out.println("poly1.crosses(line1)  " + (poly1.crosses(line1)));
              
                System.out.println("-----------------");

                System.out.println("line1.crosses(poly2)  " + (line1.crosses(poly2)));
          
                System.out.println("-----------------");

                System.out.println("line1.crosses(poly1)  " + (line1.crosses(poly1)));
               
                System.out.println("-----------------");
               
                System.out.println("poly2.crosses(line2)  " + poly2.crosses(line2));
               
                System.out.println("-----------------");
               
                System.out.println("line2.crosses(poly2)  " + line2.crosses(poly2)); 

Kesme Hesaplama
Kesme Hesaplama

Overlaps - Kaplıyor, Örtüşüyor ve Touches - Dokunuyor

overlaps ve touches metodlarını ortak bir örnekte gösterelim. Sadece köşe noktaları aynı olan, alan olarak birbirinin üstüne düşmeyen geometriler, birbirine dokunuyor demektir. touches çağrıları true döner. Köşe noktalarından da ileri gidip, birbirinin üstüne gelen alanları olan geometriler de örtüşüyor demektir. overlaps çağrıları true döner. DokunmaHesaplama.java sınıfındaki görselleştirmeyi incelediğimizde daha anlaşılır olacaktır. 

GeometryFactory geometryFactory = new GeometryFactory();

                Coordinate[] coordinates1 = new Coordinate[] { new Coordinate(60, 60), new Coordinate(110, 110), new Coordinate(155, 60),
                        new Coordinate(60, 60)};

                Coordinate[] coordinates2 = new Coordinate[] { new Coordinate(155, 60), new Coordinate(250, 150), new Coordinate(310, 40),
                        new Coordinate(155, 60)};

                Coordinate[] coordinates3 = new Coordinate[] { new Coordinate(150, 120), new Coordinate(300, 120),
                        new Coordinate(300, 180), new Coordinate(150, 180), new Coordinate(150, 120) };
               
                Polygon poly1 = geometryFactory.createPolygon(coordinates1);

                Polygon poly2 = geometryFactory.createPolygon(coordinates2);
              
                Polygon poly3 = geometryFactory.createPolygon(coordinates3);
               
                System.out.println("poly1.touches(poly2)  " + (poly1.touches(poly2)));

                System.out.println("poly1.intersects(poly2)  " + (poly1.intersects(poly2)));

                System.out.println("poly1.overlaps(poly2)  " + (poly1.overlaps(poly2)));
              
                System.out.println("-----------------");
                System.out.println("poly1.touches(poly3)  " + (poly1.touches(poly3)));

                System.out.println("poly1.intersects(poly3)  " + (poly1.intersects(poly3)));

                System.out.println("poly1.overlaps(poly3)  " + (poly1.overlaps(poly3)));
              
                System.out.println("-----------------");
                System.out.println("poly3.touches(poly1) " + (poly3.touches(poly1)));

                System.out.println("poly3.intersects(poly1)  " + (poly3.intersects(poly1)));

                System.out.println("poly3.overlaps(poly1)  " + (poly3.overlaps(poly1)));
              
                System.out.println("-----------------");

                System.out.println("poly3.touches(poly2)  " + (poly3.touches(poly2)));

                System.out.println("poly3.intersects(poly2)  " + (poly3.intersects(poly2)));

                System.out.println("poly3.overlaps(poly2)  " + (poly3.overlaps(poly2)));
              
              
                System.out.println("-----------------");

                System.out.println("poly2.touches(poly3)  " + (poly2.touches(poly3)));

                System.out.println("poly2.intersects(poly3)  " + (poly2.intersects(poly3)));

                System.out.println("poly2.overlaps(poly3)  " + (poly2.overlaps(poly3)));

Dokunma Hesaplama
Dokunma Hesaplama

Equals - Eşit

JTS kütüphanesinde geometrilerin eşitlik kontrolü 2 farklı şekilde yapılabilmektedir. 

  • Geometrilerin ifade ettiği manaların eşit olup olmadığını hesaplayan equals(Geometry other) metodu. Bu metod iki geometri nesnesinin koordinat verileri farklı dahi olsa ifade ettikleri şekil aynı ise true dönmektedir. Örneğin, (0, 1), (0, 3) ve (0, 5)  noktalarından oluşan çizgi ile (0,5) ve (0, 1) noktalarından oluşan çizgi aynı şekli ifade etmektedir. Ayrıca dikkat çekilmesi gereken bir nokta var. Bu metodun equals şeklinde isimlendirilmesi hoş olmamış. Çünkü Java Object nesnesinin equals(Object obj) metodu ile karıştırılması oldukça olası. Kaldı ki aşağıda örneklerde görüleceği üzere JTS'in equals metodunu çağırmak için parametre (Geometry) nesnesine cast edilmek zorunda. Geometry tipinde olmayan bir parametre ile çağrılırsa Object equals metodu çalıştırılmış oluyor. 
  • Geometrilerin içerdiği koordinat verilerinin aynı olup olmadığına bakan equalsExact(Geometry other) metodu. Burada geometrilerin ifade ettiği şekil önemli değildir. Tüm koordinat verilerinin aynı olup olmadığına bakılmaktadır. equalsExact(Geometry other) metodu, equals(Geometry other) metodundan daha hızlı çalışmaktadır.

EsitlikHesaplama.java sınıfını çalıştırarak sonuçları ekranda görselleştirebilirsiniz.

GeometryFactory geometryFactory = new GeometryFactory();

                Coordinate[] coordinates1 = new Coordinate[] { new Coordinate(60, 60), new Coordinate(150, 60), new Coordinate(350, 60)};
                  
                Coordinate[] coordinates2 = new Coordinate[] { new Coordinate(350, 60), new Coordinate(60, 60)};
              
                LineString line1 = geometryFactory.createLineString(coordinates1);
              
                LineString line2 = geometryFactory.createLineString(coordinates2);
              
                System.out.println("(line1.equals((Object)line2)) " + (line1.equals((Object)line2)));
              
                System.out.println("(line1.equals(line2)) " + (line1.equals(line2)));
              
                System.out.println("(line1.equals((Geometry)line2)) " + (line1.equals((Geometry)line2)));
              
                System.out.println("(line1.equalsExact(line2)) " + (line1.equalsExact(line2)));

Eşitlik Hesaplama
Eşitlik Hesaplama

Önceki Bölüm:

JTS CBS Kütüphanesi Rehberi 1 - Geometri Modeli

Sonraki Bölümler

JTS CBS Kütüphanesi Rehberi 3 - Geometrik Alan Hesaplamaları

JTS CBS Kütüphanesi Rehberi 4 - Delaunay Üçgenleme, Voronoi Diyagram, Convex Hull  

JTS CBS Kütüphanesi Rehberi 5 - Quadtree Nedir? Java'da Örnek Kullanım

 


 

 

 



Hiç yorum yok:

Yorum Gönderme

Java'da Thread ve Semaphore Kullanımı Bayram Harçlığı Örneği

Normal Dede, SemaphoreDede, AtomicDede ve SynchronizedDede torunlarına bayram harçlığını doğru bir şekilde dağıtabilecek mi? Bayram harçlığı...