File indexing completed on 2025-01-05 03:58:56
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2008 Torsten Rahn <rahn@kde.org> 0004 // 0005 0006 0007 #include "GeoDataLinearRing.h" 0008 #include "GeoDataLinearRing_p.h" 0009 0010 #include "GeoDataTypes.h" 0011 #include "digikam_debug.h" 0012 0013 namespace Marble 0014 { 0015 0016 GeoDataLinearRing::GeoDataLinearRing( TessellationFlags f ) 0017 : GeoDataLineString( new GeoDataLinearRingPrivate( f ) ) 0018 { 0019 } 0020 0021 GeoDataLinearRing::GeoDataLinearRing( const GeoDataGeometry & other ) 0022 : GeoDataLineString( other ) 0023 { 0024 } 0025 0026 GeoDataLinearRing::~GeoDataLinearRing() 0027 { 0028 } 0029 0030 const char *GeoDataLinearRing::nodeType() const 0031 { 0032 return GeoDataTypes::GeoDataLinearRingType; 0033 } 0034 0035 EnumGeometryId GeoDataLinearRing::geometryId() const 0036 { 0037 return GeoDataLinearRingId; 0038 } 0039 0040 GeoDataGeometry *GeoDataLinearRing::copy() const 0041 { 0042 return new GeoDataLinearRing(*this); 0043 } 0044 0045 bool GeoDataLinearRing::operator==( const GeoDataLinearRing &other ) const 0046 { 0047 return isClosed() == other.isClosed() && 0048 GeoDataLineString::operator==( other ); 0049 } 0050 0051 bool GeoDataLinearRing::operator!=( const GeoDataLinearRing &other ) const 0052 { 0053 return !this->operator==(other); 0054 } 0055 0056 bool GeoDataLinearRing::isClosed() const 0057 { 0058 return true; 0059 } 0060 0061 qreal GeoDataLinearRing::length( qreal planetRadius, int offset ) const 0062 { 0063 qreal length = GeoDataLineString::length( planetRadius, offset ); 0064 0065 return length + planetRadius * last().sphericalDistanceTo(first()); 0066 } 0067 0068 bool GeoDataLinearRing::contains( const GeoDataCoordinates &coordinates ) const 0069 { 0070 // Quick bounding box check 0071 if ( !latLonAltBox().contains( coordinates ) ) { 0072 return false; 0073 } 0074 0075 int const points = size(); 0076 bool inside = false; // also true for points = 0 0077 int j = points - 1; 0078 0079 for ( int i=0; i<points; ++i ) { 0080 GeoDataCoordinates const & one = operator[]( i ); 0081 GeoDataCoordinates const & two = operator[]( j ); 0082 0083 if ( ( one.longitude() < coordinates.longitude() && two.longitude() >= coordinates.longitude() ) || 0084 ( two.longitude() < coordinates.longitude() && one.longitude() >= coordinates.longitude() ) ) { 0085 if ( one.latitude() + ( coordinates.longitude() - one.longitude()) / ( two.longitude() - one.longitude()) * ( two.latitude()-one.latitude() ) < coordinates.latitude() ) { 0086 inside = !inside; 0087 } 0088 } 0089 0090 j = i; 0091 } 0092 0093 return inside; 0094 } 0095 0096 bool GeoDataLinearRing::isClockwise() const 0097 { 0098 int const n = size(); 0099 qreal area = 0; 0100 for ( int i = 1; i < n; ++i ){ 0101 area += ( operator[]( i ).longitude() - operator[]( i - 1 ).longitude() ) * ( operator[]( i ).latitude() + operator[]( i - 1 ).latitude() ); 0102 } 0103 area += ( operator[]( 0 ).longitude() - operator[]( n - 1 ).longitude() ) * ( operator[] ( 0 ).latitude() + operator[]( n - 1 ).latitude() ); 0104 0105 return area > 0; 0106 } 0107 0108 }