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 |
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 |
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 |
Örneğin iki LineString'in kesişimini görselleştirdiğimizde ekranda şöyle bir panel göreceğiz.
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 |
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 |
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 |
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 |
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 |
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(cizgi2); 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 cizgi3Cizgi1KesisirMi = cizgi3.intersects(cizgi1);
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 |
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 |
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 |
Ö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
JTS CBS Kütüphanesi Rehberi 6 - Douglas Peucker Geometri Basitleştirme ve Yoğunlaştırma
0 Yorumlar