From 4c1777c22b6ef22879bf60d9b604b3cfd40b973e Mon Sep 17 00:00:00 2001 From: Cory Foy Date: Mon, 6 Nov 2023 12:37:25 -0500 Subject: [PATCH] Adds MGRS Support (#41) --- Podfile | 17 + Podfile.lock | 31 + Pods/Manifest.lock | 31 + Pods/Pods.xcodeproj/project.pbxproj | 2073 +++++++++++++++++ ...Pods-TAKTracker-TAKTrackerTests-Info.plist | 26 + ...-TAKTrackerTests-acknowledgements.markdown | 103 + ...ker-TAKTrackerTests-acknowledgements.plist | 153 ++ .../Pods-TAKTracker-TAKTrackerTests-dummy.m | 5 + ...ts-frameworks-Debug-input-files.xcfilelist | 5 + ...s-frameworks-Debug-output-files.xcfilelist | 4 + ...-frameworks-Release-input-files.xcfilelist | 5 + ...frameworks-Release-output-files.xcfilelist | 4 + ...s-TAKTracker-TAKTrackerTests-frameworks.sh | 192 ++ ...Pods-TAKTracker-TAKTrackerTests-umbrella.h | 16 + ...-TAKTracker-TAKTrackerTests.debug.xcconfig | 15 + .../Pods-TAKTracker-TAKTrackerTests.modulemap | 6 + ...AKTracker-TAKTrackerTests.release.xcconfig | 15 + .../Pods-TAKTracker-Info.plist | 26 + .../Pods-TAKTracker-acknowledgements.markdown | 103 + .../Pods-TAKTracker-acknowledgements.plist | 153 ++ .../Pods-TAKTracker/Pods-TAKTracker-dummy.m | 5 + ...er-frameworks-Debug-input-files.xcfilelist | 5 + ...r-frameworks-Debug-output-files.xcfilelist | 4 + ...-frameworks-Release-input-files.xcfilelist | 5 + ...frameworks-Release-output-files.xcfilelist | 4 + .../Pods-TAKTracker-frameworks.sh | 192 ++ .../Pods-TAKTracker-umbrella.h | 16 + .../Pods-TAKTracker.debug.xcconfig | 15 + .../Pods-TAKTracker/Pods-TAKTracker.modulemap | 6 + .../Pods-TAKTracker.release.xcconfig | 15 + .../color-ios/color-ios-Info.plist | 26 + .../color-ios/color-ios-dummy.m | 5 + .../color-ios/color-ios-prefix.pch | 12 + .../color-ios/color-ios-umbrella.h | 21 + .../color-ios/color-ios.debug.xcconfig | 13 + .../color-ios/color-ios.modulemap | 6 + .../color-ios/color-ios.release.xcconfig | 13 + .../grid-ios/grid-ios-Info.plist | 26 + .../grid-ios/grid-ios-dummy.m | 5 + .../grid-ios/grid-ios-prefix.pch | 12 + .../grid-ios/grid-ios-umbrella.h | 16 + .../grid-ios/grid-ios.debug.xcconfig | 16 + .../grid-ios/grid-ios.modulemap | 6 + .../grid-ios/grid-ios.release.xcconfig | 16 + ...esourceBundle-mgrs-ios-mgrs-ios-Info.plist | 24 + .../mgrs-ios/mgrs-ios-Info.plist | 26 + .../mgrs-ios/mgrs-ios-dummy.m | 5 + .../mgrs-ios/mgrs-ios-prefix.pch | 12 + .../mgrs-ios/mgrs-ios-umbrella.h | 16 + .../mgrs-ios/mgrs-ios.debug.xcconfig | 16 + .../mgrs-ios/mgrs-ios.modulemap | 6 + .../mgrs-ios/mgrs-ios.release.xcconfig | 16 + .../sf-ios/sf-ios-Info.plist | 26 + .../sf-ios/sf-ios-dummy.m | 5 + .../sf-ios/sf-ios-prefix.pch | 12 + .../sf-ios/sf-ios-umbrella.h | 61 + .../sf-ios/sf-ios.debug.xcconfig | 13 + .../sf-ios/sf-ios.modulemap | 6 + .../sf-ios/sf-ios.release.xcconfig | 13 + Pods/color-ios/LICENSE | 21 + Pods/color-ios/README.md | 139 ++ Pods/color-ios/color-ios/CLRColor.h | 1026 ++++++++ Pods/color-ios/color-ios/CLRColor.m | 537 +++++ Pods/color-ios/color-ios/CLRColorConstants.h | 30 + Pods/color-ios/color-ios/CLRColorConstants.m | 30 + Pods/color-ios/color-ios/CLRColorUtils.h | 578 +++++ Pods/color-ios/color-ios/CLRColorUtils.m | 482 ++++ .../color-ios/color-ios-Bridging-Header.h | 17 + Pods/color-ios/color-ios/color_ios.h | 13 + Pods/grid-ios/LICENSE | 21 + Pods/grid-ios/README.md | 72 + Pods/grid-ios/grid-ios/BaseGrid.swift | 205 ++ Pods/grid-ios/grid-ios/BaseGrids.swift | 521 +++++ Pods/grid-ios/grid-ios/BaseZoomGrids.swift | 86 + Pods/grid-ios/grid-ios/GridConstants.swift | 76 + Pods/grid-ios/grid-ios/GridStyle.swift | 46 + Pods/grid-ios/grid-ios/GridUtils.swift | 375 +++ Pods/grid-ios/grid-ios/Hemisphere.swift | 51 + Pods/grid-ios/grid-ios/Label.swift | 50 + Pods/grid-ios/grid-ios/Labeler.swift | 134 ++ Pods/grid-ios/grid-ios/features/Bounds.swift | 586 +++++ .../grid-ios/features/GridPoint.swift | 327 +++ Pods/grid-ios/grid-ios/features/Line.swift | 212 ++ Pods/grid-ios/grid-ios/features/Unit.swift | 29 + .../grid-ios/property/GridProperties.swift | 341 +++ .../grid-ios/property/PropertyConstants.swift | 85 + Pods/grid-ios/grid-ios/tile/GridTile.swift | 171 ++ Pods/grid-ios/grid-ios/tile/Pixel.swift | 38 + Pods/grid-ios/grid-ios/tile/PixelRange.swift | 148 ++ Pods/grid-ios/grid-ios/tile/TileDraw.swift | 124 + Pods/grid-ios/grid-ios/tile/TileUtils.swift | 197 ++ Pods/mgrs-ios/LICENSE | 21 + Pods/mgrs-ios/README.md | 245 ++ Pods/mgrs-ios/mgrs-ios/MGRS.swift | 916 ++++++++ Pods/mgrs-ios/mgrs-ios/MGRSConstants.swift | 121 + Pods/mgrs-ios/mgrs-ios/MGRSUtils.swift | 102 + .../mgrs-ios/mgrs-ios/features/MGRSLine.swift | 137 ++ Pods/mgrs-ios/mgrs-ios/grid/Grid.swift | 305 +++ Pods/mgrs-ios/mgrs-ios/grid/GridLabel.swift | 46 + Pods/mgrs-ios/mgrs-ios/grid/GridLabeler.swift | 196 ++ Pods/mgrs-ios/mgrs-ios/grid/GridType.swift | 157 ++ Pods/mgrs-ios/mgrs-ios/grid/Grids.swift | 1004 ++++++++ Pods/mgrs-ios/mgrs-ios/grid/MGRSLabeler.swift | 103 + Pods/mgrs-ios/mgrs-ios/grid/ZoomGrids.swift | 34 + .../mgrs-ios/gzd/BandLetterRange.swift | 88 + Pods/mgrs-ios/mgrs-ios/gzd/GZDLabeler.swift | 24 + Pods/mgrs-ios/mgrs-ios/gzd/GridRange.swift | 149 ++ Pods/mgrs-ios/mgrs-ios/gzd/GridZone.swift | 329 +++ Pods/mgrs-ios/mgrs-ios/gzd/GridZones.swift | 592 +++++ Pods/mgrs-ios/mgrs-ios/gzd/LatitudeBand.swift | 63 + .../mgrs-ios/gzd/LongitudinalStrip.swift | 68 + .../mgrs-ios/gzd/ZoneNumberRange.swift | 88 + Pods/mgrs-ios/mgrs-ios/mgrs.plist | 160 ++ .../mgrs-ios/property/MGRSProperties.swift | 37 + .../mgrs-ios/tile/MGRSTileOverlay.swift | 354 +++ Pods/mgrs-ios/mgrs-ios/utm/UTM.swift | 509 ++++ Pods/sf-ios/LICENSE | 21 + Pods/sf-ios/README.md | 59 + Pods/sf-ios/sf-ios/SFCircularString.h | 88 + Pods/sf-ios/sf-ios/SFCircularString.m | 62 + Pods/sf-ios/sf-ios/SFCompoundCurve.h | 146 ++ Pods/sf-ios/sf-ios/SFCompoundCurve.m | 185 ++ Pods/sf-ios/sf-ios/SFCurve.h | 59 + Pods/sf-ios/sf-ios/SFCurve.m | 36 + Pods/sf-ios/sf-ios/SFCurvePolygon.h | 183 ++ Pods/sf-ios/sf-ios/SFCurvePolygon.m | 174 ++ Pods/sf-ios/sf-ios/SFGeometry.h | 124 + Pods/sf-ios/sf-ios/SFGeometry.m | 132 ++ Pods/sf-ios/sf-ios/SFGeometryCollection.h | 261 +++ Pods/sf-ios/sf-ios/SFGeometryCollection.m | 308 +++ Pods/sf-ios/sf-ios/SFGeometryEnvelope.h | 635 +++++ Pods/sf-ios/sf-ios/SFGeometryEnvelope.m | 491 ++++ Pods/sf-ios/sf-ios/SFGeometryTypes.h | 79 + Pods/sf-ios/sf-ios/SFGeometryTypes.m | 135 ++ Pods/sf-ios/sf-ios/SFLine.h | 108 + Pods/sf-ios/sf-ios/SFLine.m | 81 + Pods/sf-ios/sf-ios/SFLineString.h | 137 ++ Pods/sf-ios/sf-ios/SFLineString.m | 166 ++ Pods/sf-ios/sf-ios/SFLinearRing.h | 90 + Pods/sf-ios/sf-ios/SFLinearRing.m | 73 + Pods/sf-ios/sf-ios/SFMultiCurve.h | 82 + Pods/sf-ios/sf-ios/SFMultiCurve.m | 53 + Pods/sf-ios/sf-ios/SFMultiLineString.h | 157 ++ Pods/sf-ios/sf-ios/SFMultiLineString.m | 98 + Pods/sf-ios/sf-ios/SFMultiPoint.h | 156 ++ Pods/sf-ios/sf-ios/SFMultiPoint.m | 103 + Pods/sf-ios/sf-ios/SFMultiPolygon.h | 157 ++ Pods/sf-ios/sf-ios/SFMultiPolygon.m | 98 + Pods/sf-ios/sf-ios/SFMultiSurface.h | 74 + Pods/sf-ios/sf-ios/SFMultiSurface.m | 42 + Pods/sf-ios/sf-ios/SFPoint.h | 350 +++ Pods/sf-ios/sf-ios/SFPoint.m | 259 ++ Pods/sf-ios/sf-ios/SFPolygon.h | 164 ++ Pods/sf-ios/sf-ios/SFPolygon.m | 103 + Pods/sf-ios/sf-ios/SFPolyhedralSurface.h | 205 ++ Pods/sf-ios/sf-ios/SFPolyhedralSurface.m | 186 ++ Pods/sf-ios/sf-ios/SFSurface.h | 28 + Pods/sf-ios/sf-ios/SFSurface.m | 18 + Pods/sf-ios/sf-ios/SFTIN.h | 111 + Pods/sf-ios/sf-ios/SFTIN.m | 74 + Pods/sf-ios/sf-ios/SFTriangle.h | 110 + Pods/sf-ios/sf-ios/SFTriangle.m | 74 + .../extended/SFExtendedGeometryCollection.h | 62 + .../extended/SFExtendedGeometryCollection.m | 128 + Pods/sf-ios/sf-ios/sf-ios-Bridging-Header.h | 57 + Pods/sf-ios/sf-ios/sf_ios.h | 13 + Pods/sf-ios/sf-ios/util/SFByteReader.h | 94 + Pods/sf-ios/sf-ios/util/SFByteReader.m | 98 + Pods/sf-ios/sf-ios/util/SFByteWriter.h | 106 + Pods/sf-ios/sf-ios/util/SFByteWriter.m | 93 + Pods/sf-ios/sf-ios/util/SFGeometryConstants.h | 83 + Pods/sf-ios/sf-ios/util/SFGeometryConstants.m | 28 + .../sf-ios/util/SFGeometryEnvelopeBuilder.h | 43 + .../sf-ios/util/SFGeometryEnvelopeBuilder.m | 235 ++ Pods/sf-ios/sf-ios/util/SFGeometryPrinter.h | 25 + Pods/sf-ios/sf-ios/util/SFGeometryPrinter.m | 185 ++ Pods/sf-ios/sf-ios/util/SFGeometryUtils.h | 1229 ++++++++++ Pods/sf-ios/sf-ios/util/SFGeometryUtils.m | 1832 +++++++++++++++ Pods/sf-ios/sf-ios/util/SFTextReader.h | 55 + Pods/sf-ios/sf-ios/util/SFTextReader.m | 134 ++ .../sf-ios/util/centroid/SFCentroidCurve.h | 49 + .../sf-ios/util/centroid/SFCentroidCurve.m | 124 + .../sf-ios/util/centroid/SFCentroidPoint.h | 48 + .../sf-ios/util/centroid/SFCentroidPoint.m | 89 + .../sf-ios/util/centroid/SFCentroidSurface.h | 49 + .../sf-ios/util/centroid/SFCentroidSurface.m | 273 +++ .../sf-ios/util/centroid/SFDegreesCentroid.h | 41 + .../sf-ios/util/centroid/SFDegreesCentroid.m | 239 ++ .../sf-ios/util/filter/SFFiniteFilterTypes.h | 23 + .../sf-ios/util/filter/SFFiniteFilterTypes.m | 13 + .../sf-ios/util/filter/SFGeometryFilter.h | 34 + .../sf-ios/util/filter/SFPointFiniteFilter.h | 108 + .../sf-ios/util/filter/SFPointFiniteFilter.m | 132 ++ Pods/sf-ios/sf-ios/util/sweep/SFEvent.h | 70 + Pods/sf-ios/sf-ios/util/sweep/SFEvent.m | 78 + Pods/sf-ios/sf-ios/util/sweep/SFEventQueue.h | 42 + Pods/sf-ios/sf-ios/util/sweep/SFEventQueue.m | 67 + Pods/sf-ios/sf-ios/util/sweep/SFEventTypes.h | 21 + Pods/sf-ios/sf-ios/util/sweep/SFEventTypes.m | 13 + Pods/sf-ios/sf-ios/util/sweep/SFSegment.h | 72 + Pods/sf-ios/sf-ios/util/sweep/SFSegment.m | 67 + Pods/sf-ios/sf-ios/util/sweep/SFShamosHoey.h | 72 + Pods/sf-ios/sf-ios/util/sweep/SFShamosHoey.m | 142 ++ Pods/sf-ios/sf-ios/util/sweep/SFSweepLine.h | 75 + Pods/sf-ios/sf-ios/util/sweep/SFSweepLine.m | 305 +++ README.md | 17 +- TAKTracker.xcodeproj/project.pbxproj | 125 + .../contents.xcworkspacedata | 3 + TAKTracker/Screens/MainScreen.swift | 9 +- TAKTracker/Utilities/Converter.swift | 13 +- TAKTrackerTests/ConverterTests.swift | 33 +- 211 files changed, 29768 insertions(+), 29 deletions(-) create mode 100644 Podfile create mode 100644 Podfile.lock create mode 100644 Pods/Manifest.lock create mode 100644 Pods/Pods.xcodeproj/project.pbxproj create mode 100644 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-Info.plist create mode 100644 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-acknowledgements.markdown create mode 100644 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-acknowledgements.plist create mode 100644 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-dummy.m create mode 100644 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Debug-input-files.xcfilelist create mode 100644 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Debug-output-files.xcfilelist create mode 100644 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Release-input-files.xcfilelist create mode 100644 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Release-output-files.xcfilelist create mode 100755 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks.sh create mode 100644 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-umbrella.h create mode 100644 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.debug.xcconfig create mode 100644 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.modulemap create mode 100644 Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.release.xcconfig create mode 100644 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-Info.plist create mode 100644 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-acknowledgements.markdown create mode 100644 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-acknowledgements.plist create mode 100644 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-dummy.m create mode 100644 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Debug-input-files.xcfilelist create mode 100644 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Debug-output-files.xcfilelist create mode 100644 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Release-input-files.xcfilelist create mode 100644 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Release-output-files.xcfilelist create mode 100755 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks.sh create mode 100644 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-umbrella.h create mode 100644 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker.debug.xcconfig create mode 100644 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker.modulemap create mode 100644 Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker.release.xcconfig create mode 100644 Pods/Target Support Files/color-ios/color-ios-Info.plist create mode 100644 Pods/Target Support Files/color-ios/color-ios-dummy.m create mode 100644 Pods/Target Support Files/color-ios/color-ios-prefix.pch create mode 100644 Pods/Target Support Files/color-ios/color-ios-umbrella.h create mode 100644 Pods/Target Support Files/color-ios/color-ios.debug.xcconfig create mode 100644 Pods/Target Support Files/color-ios/color-ios.modulemap create mode 100644 Pods/Target Support Files/color-ios/color-ios.release.xcconfig create mode 100644 Pods/Target Support Files/grid-ios/grid-ios-Info.plist create mode 100644 Pods/Target Support Files/grid-ios/grid-ios-dummy.m create mode 100644 Pods/Target Support Files/grid-ios/grid-ios-prefix.pch create mode 100644 Pods/Target Support Files/grid-ios/grid-ios-umbrella.h create mode 100644 Pods/Target Support Files/grid-ios/grid-ios.debug.xcconfig create mode 100644 Pods/Target Support Files/grid-ios/grid-ios.modulemap create mode 100644 Pods/Target Support Files/grid-ios/grid-ios.release.xcconfig create mode 100644 Pods/Target Support Files/mgrs-ios/ResourceBundle-mgrs-ios-mgrs-ios-Info.plist create mode 100644 Pods/Target Support Files/mgrs-ios/mgrs-ios-Info.plist create mode 100644 Pods/Target Support Files/mgrs-ios/mgrs-ios-dummy.m create mode 100644 Pods/Target Support Files/mgrs-ios/mgrs-ios-prefix.pch create mode 100644 Pods/Target Support Files/mgrs-ios/mgrs-ios-umbrella.h create mode 100644 Pods/Target Support Files/mgrs-ios/mgrs-ios.debug.xcconfig create mode 100644 Pods/Target Support Files/mgrs-ios/mgrs-ios.modulemap create mode 100644 Pods/Target Support Files/mgrs-ios/mgrs-ios.release.xcconfig create mode 100644 Pods/Target Support Files/sf-ios/sf-ios-Info.plist create mode 100644 Pods/Target Support Files/sf-ios/sf-ios-dummy.m create mode 100644 Pods/Target Support Files/sf-ios/sf-ios-prefix.pch create mode 100644 Pods/Target Support Files/sf-ios/sf-ios-umbrella.h create mode 100644 Pods/Target Support Files/sf-ios/sf-ios.debug.xcconfig create mode 100644 Pods/Target Support Files/sf-ios/sf-ios.modulemap create mode 100644 Pods/Target Support Files/sf-ios/sf-ios.release.xcconfig create mode 100644 Pods/color-ios/LICENSE create mode 100644 Pods/color-ios/README.md create mode 100644 Pods/color-ios/color-ios/CLRColor.h create mode 100644 Pods/color-ios/color-ios/CLRColor.m create mode 100644 Pods/color-ios/color-ios/CLRColorConstants.h create mode 100644 Pods/color-ios/color-ios/CLRColorConstants.m create mode 100644 Pods/color-ios/color-ios/CLRColorUtils.h create mode 100644 Pods/color-ios/color-ios/CLRColorUtils.m create mode 100644 Pods/color-ios/color-ios/color-ios-Bridging-Header.h create mode 100644 Pods/color-ios/color-ios/color_ios.h create mode 100644 Pods/grid-ios/LICENSE create mode 100644 Pods/grid-ios/README.md create mode 100644 Pods/grid-ios/grid-ios/BaseGrid.swift create mode 100644 Pods/grid-ios/grid-ios/BaseGrids.swift create mode 100644 Pods/grid-ios/grid-ios/BaseZoomGrids.swift create mode 100644 Pods/grid-ios/grid-ios/GridConstants.swift create mode 100644 Pods/grid-ios/grid-ios/GridStyle.swift create mode 100644 Pods/grid-ios/grid-ios/GridUtils.swift create mode 100644 Pods/grid-ios/grid-ios/Hemisphere.swift create mode 100644 Pods/grid-ios/grid-ios/Label.swift create mode 100644 Pods/grid-ios/grid-ios/Labeler.swift create mode 100644 Pods/grid-ios/grid-ios/features/Bounds.swift create mode 100644 Pods/grid-ios/grid-ios/features/GridPoint.swift create mode 100644 Pods/grid-ios/grid-ios/features/Line.swift create mode 100644 Pods/grid-ios/grid-ios/features/Unit.swift create mode 100644 Pods/grid-ios/grid-ios/property/GridProperties.swift create mode 100644 Pods/grid-ios/grid-ios/property/PropertyConstants.swift create mode 100644 Pods/grid-ios/grid-ios/tile/GridTile.swift create mode 100644 Pods/grid-ios/grid-ios/tile/Pixel.swift create mode 100644 Pods/grid-ios/grid-ios/tile/PixelRange.swift create mode 100644 Pods/grid-ios/grid-ios/tile/TileDraw.swift create mode 100644 Pods/grid-ios/grid-ios/tile/TileUtils.swift create mode 100644 Pods/mgrs-ios/LICENSE create mode 100644 Pods/mgrs-ios/README.md create mode 100644 Pods/mgrs-ios/mgrs-ios/MGRS.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/MGRSConstants.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/MGRSUtils.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/features/MGRSLine.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/grid/Grid.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/grid/GridLabel.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/grid/GridLabeler.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/grid/GridType.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/grid/Grids.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/grid/MGRSLabeler.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/grid/ZoomGrids.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/gzd/BandLetterRange.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/gzd/GZDLabeler.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/gzd/GridRange.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/gzd/GridZone.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/gzd/GridZones.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/gzd/LatitudeBand.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/gzd/LongitudinalStrip.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/gzd/ZoneNumberRange.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/mgrs.plist create mode 100644 Pods/mgrs-ios/mgrs-ios/property/MGRSProperties.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/tile/MGRSTileOverlay.swift create mode 100644 Pods/mgrs-ios/mgrs-ios/utm/UTM.swift create mode 100644 Pods/sf-ios/LICENSE create mode 100644 Pods/sf-ios/README.md create mode 100644 Pods/sf-ios/sf-ios/SFCircularString.h create mode 100644 Pods/sf-ios/sf-ios/SFCircularString.m create mode 100644 Pods/sf-ios/sf-ios/SFCompoundCurve.h create mode 100644 Pods/sf-ios/sf-ios/SFCompoundCurve.m create mode 100644 Pods/sf-ios/sf-ios/SFCurve.h create mode 100644 Pods/sf-ios/sf-ios/SFCurve.m create mode 100644 Pods/sf-ios/sf-ios/SFCurvePolygon.h create mode 100644 Pods/sf-ios/sf-ios/SFCurvePolygon.m create mode 100644 Pods/sf-ios/sf-ios/SFGeometry.h create mode 100644 Pods/sf-ios/sf-ios/SFGeometry.m create mode 100644 Pods/sf-ios/sf-ios/SFGeometryCollection.h create mode 100644 Pods/sf-ios/sf-ios/SFGeometryCollection.m create mode 100644 Pods/sf-ios/sf-ios/SFGeometryEnvelope.h create mode 100644 Pods/sf-ios/sf-ios/SFGeometryEnvelope.m create mode 100644 Pods/sf-ios/sf-ios/SFGeometryTypes.h create mode 100644 Pods/sf-ios/sf-ios/SFGeometryTypes.m create mode 100644 Pods/sf-ios/sf-ios/SFLine.h create mode 100644 Pods/sf-ios/sf-ios/SFLine.m create mode 100644 Pods/sf-ios/sf-ios/SFLineString.h create mode 100644 Pods/sf-ios/sf-ios/SFLineString.m create mode 100644 Pods/sf-ios/sf-ios/SFLinearRing.h create mode 100644 Pods/sf-ios/sf-ios/SFLinearRing.m create mode 100644 Pods/sf-ios/sf-ios/SFMultiCurve.h create mode 100644 Pods/sf-ios/sf-ios/SFMultiCurve.m create mode 100644 Pods/sf-ios/sf-ios/SFMultiLineString.h create mode 100644 Pods/sf-ios/sf-ios/SFMultiLineString.m create mode 100644 Pods/sf-ios/sf-ios/SFMultiPoint.h create mode 100644 Pods/sf-ios/sf-ios/SFMultiPoint.m create mode 100644 Pods/sf-ios/sf-ios/SFMultiPolygon.h create mode 100644 Pods/sf-ios/sf-ios/SFMultiPolygon.m create mode 100644 Pods/sf-ios/sf-ios/SFMultiSurface.h create mode 100644 Pods/sf-ios/sf-ios/SFMultiSurface.m create mode 100644 Pods/sf-ios/sf-ios/SFPoint.h create mode 100644 Pods/sf-ios/sf-ios/SFPoint.m create mode 100644 Pods/sf-ios/sf-ios/SFPolygon.h create mode 100644 Pods/sf-ios/sf-ios/SFPolygon.m create mode 100644 Pods/sf-ios/sf-ios/SFPolyhedralSurface.h create mode 100644 Pods/sf-ios/sf-ios/SFPolyhedralSurface.m create mode 100644 Pods/sf-ios/sf-ios/SFSurface.h create mode 100644 Pods/sf-ios/sf-ios/SFSurface.m create mode 100644 Pods/sf-ios/sf-ios/SFTIN.h create mode 100644 Pods/sf-ios/sf-ios/SFTIN.m create mode 100644 Pods/sf-ios/sf-ios/SFTriangle.h create mode 100644 Pods/sf-ios/sf-ios/SFTriangle.m create mode 100644 Pods/sf-ios/sf-ios/extended/SFExtendedGeometryCollection.h create mode 100644 Pods/sf-ios/sf-ios/extended/SFExtendedGeometryCollection.m create mode 100644 Pods/sf-ios/sf-ios/sf-ios-Bridging-Header.h create mode 100644 Pods/sf-ios/sf-ios/sf_ios.h create mode 100644 Pods/sf-ios/sf-ios/util/SFByteReader.h create mode 100644 Pods/sf-ios/sf-ios/util/SFByteReader.m create mode 100644 Pods/sf-ios/sf-ios/util/SFByteWriter.h create mode 100644 Pods/sf-ios/sf-ios/util/SFByteWriter.m create mode 100644 Pods/sf-ios/sf-ios/util/SFGeometryConstants.h create mode 100644 Pods/sf-ios/sf-ios/util/SFGeometryConstants.m create mode 100644 Pods/sf-ios/sf-ios/util/SFGeometryEnvelopeBuilder.h create mode 100644 Pods/sf-ios/sf-ios/util/SFGeometryEnvelopeBuilder.m create mode 100644 Pods/sf-ios/sf-ios/util/SFGeometryPrinter.h create mode 100644 Pods/sf-ios/sf-ios/util/SFGeometryPrinter.m create mode 100644 Pods/sf-ios/sf-ios/util/SFGeometryUtils.h create mode 100644 Pods/sf-ios/sf-ios/util/SFGeometryUtils.m create mode 100644 Pods/sf-ios/sf-ios/util/SFTextReader.h create mode 100644 Pods/sf-ios/sf-ios/util/SFTextReader.m create mode 100644 Pods/sf-ios/sf-ios/util/centroid/SFCentroidCurve.h create mode 100644 Pods/sf-ios/sf-ios/util/centroid/SFCentroidCurve.m create mode 100644 Pods/sf-ios/sf-ios/util/centroid/SFCentroidPoint.h create mode 100644 Pods/sf-ios/sf-ios/util/centroid/SFCentroidPoint.m create mode 100644 Pods/sf-ios/sf-ios/util/centroid/SFCentroidSurface.h create mode 100644 Pods/sf-ios/sf-ios/util/centroid/SFCentroidSurface.m create mode 100644 Pods/sf-ios/sf-ios/util/centroid/SFDegreesCentroid.h create mode 100644 Pods/sf-ios/sf-ios/util/centroid/SFDegreesCentroid.m create mode 100644 Pods/sf-ios/sf-ios/util/filter/SFFiniteFilterTypes.h create mode 100644 Pods/sf-ios/sf-ios/util/filter/SFFiniteFilterTypes.m create mode 100644 Pods/sf-ios/sf-ios/util/filter/SFGeometryFilter.h create mode 100644 Pods/sf-ios/sf-ios/util/filter/SFPointFiniteFilter.h create mode 100644 Pods/sf-ios/sf-ios/util/filter/SFPointFiniteFilter.m create mode 100644 Pods/sf-ios/sf-ios/util/sweep/SFEvent.h create mode 100644 Pods/sf-ios/sf-ios/util/sweep/SFEvent.m create mode 100644 Pods/sf-ios/sf-ios/util/sweep/SFEventQueue.h create mode 100644 Pods/sf-ios/sf-ios/util/sweep/SFEventQueue.m create mode 100644 Pods/sf-ios/sf-ios/util/sweep/SFEventTypes.h create mode 100644 Pods/sf-ios/sf-ios/util/sweep/SFEventTypes.m create mode 100644 Pods/sf-ios/sf-ios/util/sweep/SFSegment.h create mode 100644 Pods/sf-ios/sf-ios/util/sweep/SFSegment.m create mode 100644 Pods/sf-ios/sf-ios/util/sweep/SFShamosHoey.h create mode 100644 Pods/sf-ios/sf-ios/util/sweep/SFShamosHoey.m create mode 100644 Pods/sf-ios/sf-ios/util/sweep/SFSweepLine.h create mode 100644 Pods/sf-ios/sf-ios/util/sweep/SFSweepLine.m diff --git a/Podfile b/Podfile new file mode 100644 index 0000000..016bd0b --- /dev/null +++ b/Podfile @@ -0,0 +1,17 @@ +# Uncomment the next line to define a global platform for your project +platform :ios, '15.0' + +target 'TAKTracker' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for TAKTracker + pod 'sf-ios', '~> 4.1.2' + pod 'color-ios', '~> 1.0.1' + pod 'grid-ios', '~> 1.0.5' + pod 'mgrs-ios', '~> 1.1.4' + + target 'TAKTrackerTests' do + pod 'mgrs-ios', '~> 1.1.4' + end +end diff --git a/Podfile.lock b/Podfile.lock new file mode 100644 index 0000000..661b090 --- /dev/null +++ b/Podfile.lock @@ -0,0 +1,31 @@ +PODS: + - color-ios (1.0.1) + - grid-ios (1.0.5): + - color-ios (~> 1.0.1) + - sf-ios (~> 4.1.2) + - mgrs-ios (1.1.4): + - grid-ios (~> 1.0.5) + - sf-ios (4.1.2) + +DEPENDENCIES: + - color-ios (~> 1.0.1) + - grid-ios (~> 1.0.5) + - mgrs-ios (~> 1.1.4) + - sf-ios (~> 4.1.2) + +SPEC REPOS: + trunk: + - color-ios + - grid-ios + - mgrs-ios + - sf-ios + +SPEC CHECKSUMS: + color-ios: ab7521e896b4e061905d292aa7ff675d7e7f801d + grid-ios: 29d32ac8d78771b1d7a91ebeba85c5d49785c4bd + mgrs-ios: d96be2123562dbd99194bcdc75d54d8ac13afa3a + sf-ios: 16cfda9dd8971cb0216ac911840bb72727bf2397 + +PODFILE CHECKSUM: dbd0a9268ba081e0455ceff020ce5b76d767b558 + +COCOAPODS: 1.14.2 diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock new file mode 100644 index 0000000..661b090 --- /dev/null +++ b/Pods/Manifest.lock @@ -0,0 +1,31 @@ +PODS: + - color-ios (1.0.1) + - grid-ios (1.0.5): + - color-ios (~> 1.0.1) + - sf-ios (~> 4.1.2) + - mgrs-ios (1.1.4): + - grid-ios (~> 1.0.5) + - sf-ios (4.1.2) + +DEPENDENCIES: + - color-ios (~> 1.0.1) + - grid-ios (~> 1.0.5) + - mgrs-ios (~> 1.1.4) + - sf-ios (~> 4.1.2) + +SPEC REPOS: + trunk: + - color-ios + - grid-ios + - mgrs-ios + - sf-ios + +SPEC CHECKSUMS: + color-ios: ab7521e896b4e061905d292aa7ff675d7e7f801d + grid-ios: 29d32ac8d78771b1d7a91ebeba85c5d49785c4bd + mgrs-ios: d96be2123562dbd99194bcdc75d54d8ac13afa3a + sf-ios: 16cfda9dd8971cb0216ac911840bb72727bf2397 + +PODFILE CHECKSUM: dbd0a9268ba081e0455ceff020ce5b76d767b558 + +COCOAPODS: 1.14.2 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..bbc01fb --- /dev/null +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,2073 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 001F68F56A633058BF4BA7B66B76B71F /* SFGeometryEnvelope.m in Sources */ = {isa = PBXBuildFile; fileRef = 84AEC61DCB8D681446EC274B37E177C7 /* SFGeometryEnvelope.m */; }; + 023B6A92AA418BF179DCD89C3432D21B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; + 04B3A6327E57113297E147F45AB86AC2 /* BaseZoomGrids.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F97C8CE346DDCF07EE3F169C6B7DB06 /* BaseZoomGrids.swift */; }; + 067C7ED7510521BE277F755220E822C5 /* ZoneNumberRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAFEE98C191B783F8D38CE278995BB54 /* ZoneNumberRange.swift */; }; + 06D18D87D8504AC2715A0863CCDAED96 /* Hemisphere.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CA0ACD3CEF47962069826A7DA81A2D9 /* Hemisphere.swift */; }; + 071F303DFF627313B76DE65A777F15C1 /* LongitudinalStrip.swift in Sources */ = {isa = PBXBuildFile; fileRef = F075E3F1D811860229ED8C0072BB6F84 /* LongitudinalStrip.swift */; }; + 08A82D98A2958761B0C37502C499ECCC /* GridPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = E65E11BF4833C38B18D081EEE90CCA02 /* GridPoint.swift */; }; + 09A55B5B12C8F97AD7A9F4A5E4DC98C4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; + 0A42D4949996376A528CC9DE5933FFED /* PropertyConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3243D50FEEEF0AA58FCBDA9037733C95 /* PropertyConstants.swift */; }; + 0A7A071437788D2CD978AC14600164C4 /* SFEventQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 35F014EC7FAFEDD1FD2BC06705152166 /* SFEventQueue.m */; }; + 0D16C71CF738F3BBA2C63FEC24CBAE3F /* Grid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57A69667D76341A8D69E0FC97BFD81F8 /* Grid.swift */; }; + 0D613B084A281CFFE84AD258E78BCF46 /* SFByteReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 684EBC6DFA0FFDE2E145ADE8EE2CEF9D /* SFByteReader.m */; }; + 0E39041630EF2F1DBCFD440BA4382F37 /* SFPolyhedralSurface.m in Sources */ = {isa = PBXBuildFile; fileRef = F3EDF6D2E962047A3C2009AEAE795218 /* SFPolyhedralSurface.m */; }; + 0E48F269B264AC4DF3B3DC9E834251FC /* color-ios-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A285519FAD68A4B91EF421B349AEB9D9 /* color-ios-dummy.m */; }; + 11C8F47D1A8C14C2D7EBB896EDD5ABD0 /* SFGeometryConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 45EDE46C074CBF3E3C6844B4FD831B49 /* SFGeometryConstants.m */; }; + 12C72C459546562A4C7A8D046B5BE963 /* Grids.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEA04A00723B024B82E2BE6552BBE7D4 /* Grids.swift */; }; + 14520EB15EE4C93038B8F8C08D801249 /* SFSweepLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 774DB00815D3CAB2F00CEE49CADA14AF /* SFSweepLine.m */; }; + 151C527DAC489E8572AC35ABC2906DD3 /* SFMultiLineString.m in Sources */ = {isa = PBXBuildFile; fileRef = 290D43FF8A536D340A0768C91F6100C0 /* SFMultiLineString.m */; }; + 18BFF2E239D0B1D9185EB96608E12D7E /* SFEventTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF3776E7D2B4FB9DCCF8754FBBC0968 /* SFEventTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1AC9C136DF9DC5C9A64F6ED3527450C6 /* SFTriangle.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B3EDB3F6C36DC0596E30D4B9C4B9077 /* SFTriangle.m */; }; + 1CE9DCE43EE4AD7049582C77ED9B8AA8 /* SFGeometry.m in Sources */ = {isa = PBXBuildFile; fileRef = F08EDF875F45F6F05DAA577FA13BD612 /* SFGeometry.m */; }; + 1D698A50DD3E699C98DBDB6069F55692 /* SFDegreesCentroid.m in Sources */ = {isa = PBXBuildFile; fileRef = E78DEACAED1651147C3138A3C387A819 /* SFDegreesCentroid.m */; }; + 1EF5A466ACFC030D286EEC26D340A1C5 /* SFPolygon.h in Headers */ = {isa = PBXBuildFile; fileRef = F15D2E1A619B2F2B360124EAC98D3051 /* SFPolygon.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 21903FB8A17A7598FCBE8D2F4D1CA0BE /* SFGeometryCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 28621C8035DA87D89A8A2B187EF98A12 /* SFGeometryCollection.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2393BAE200B3EEC1FA10FB24D06242C8 /* SFEventQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F6EB542086BD931C888EE2394148556 /* SFEventQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2529DBFC6D7F8A5C2223025BC04F19C7 /* SFByteWriter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A7924890AF51FC698FDC4BA555F8203 /* SFByteWriter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 27805EB07D85C9E0D83B18CA0ADB2480 /* SFGeometryUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 400F91DA42E6FC7C22FE3F06D34AA353 /* SFGeometryUtils.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2FD630B28BBEBA4BCBF16B2A4F0839BE /* SFMultiSurface.h in Headers */ = {isa = PBXBuildFile; fileRef = B29C44830FBB834CBB0A1947FE188EFE /* SFMultiSurface.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 334990EB900D463BE5872BBC3B5F3958 /* SFExtendedGeometryCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = ED9A6DEDF060D707D58AE0AE9D2F5949 /* SFExtendedGeometryCollection.m */; }; + 340A22AEEA4B642789E75D2D18E10799 /* SFMultiSurface.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FDD7A8AF9BD4A6F04C55146B97B851E /* SFMultiSurface.m */; }; + 345CA1488DECB422072705006D13346B /* SFGeometryUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 32323DCD7ED9B830CD0092ADA15048D9 /* SFGeometryUtils.m */; }; + 3460722D8AB9B7B5492A2F71D52A2635 /* SFExtendedGeometryCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B452511DBDAF5420CBB798B10651D74 /* SFExtendedGeometryCollection.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 357C97B40448E6D0796FD6E50B3FC37D /* SFByteReader.h in Headers */ = {isa = PBXBuildFile; fileRef = DD2D26A77DB958E7CEAEDEA102EB0B9C /* SFByteReader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 35A0D6930B1375D439168D1746877049 /* BaseGrids.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FCE035B2EBA1E24D020924CABFD59DF /* BaseGrids.swift */; }; + 3641423CA329A8EE581EE79262B8A114 /* SFMultiPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DC2B5D322035FCF210E33EF2A14FD88 /* SFMultiPoint.m */; }; + 391601FB8693640EBE5D411023C746A9 /* GridUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C28424481CE8A0A6B868B0DCFDEF48A /* GridUtils.swift */; }; + 3CD803A89F48503EDFB120BF71FBE80E /* Unit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81AC2DC77BEA1280D97530A4D94D6B4F /* Unit.swift */; }; + 40B0D84C70D2A91336BA9BE6812F1907 /* SFCentroidSurface.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F200FC096E28386D09EDFAEAFB92FE2 /* SFCentroidSurface.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 43917DB945C7B0D7ADAD92DF8A1AE0D8 /* SFCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = EA45EEA7958D8FBA57D574798993A122 /* SFCurve.m */; }; + 441868A71789DE750628E4049B68C1B5 /* SFGeometryConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DFF9DB321426B8017B1228290F3AAB5 /* SFGeometryConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 45FAE0AE275B0268A3A0AFF513BD46D1 /* MGRSConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 519EFC06EF426F8AC40C818C658518C5 /* MGRSConstants.swift */; }; + 4857891EB4E50C0313B47AAE82257B91 /* PixelRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023DA3166A0D28C4202C6C0C70B9F68A /* PixelRange.swift */; }; + 4A916B1EC4FFB5029D417B3F8221C935 /* SFSurface.m in Sources */ = {isa = PBXBuildFile; fileRef = 891086E5D78592128EB4829E5ED1C607 /* SFSurface.m */; }; + 4B8A895EECFCB0E14F31C9B854CA7283 /* mgrs-ios-mgrs-ios in Resources */ = {isa = PBXBuildFile; fileRef = F3C55B46709D88246CAD4116FE38617D /* mgrs-ios-mgrs-ios */; }; + 4D20A8913616CE13CCBF92EAE5CBA703 /* SFEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = B9A67935C386EE102ECA25199A7CA64F /* SFEvent.m */; }; + 4E9DB3A55799AD6A7BB6CABC2792DA9D /* GridLabeler.swift in Sources */ = {isa = PBXBuildFile; fileRef = E56B4688749ADDF7AC9988F47575DC68 /* GridLabeler.swift */; }; + 4FAEF057D06A2FE9452EC6402A646935 /* CLRColorConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BD7CF883331619E55A228A609D5B4FC /* CLRColorConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 50276582786348FBA53DF53E1734ACBF /* SFSegment.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A8672C317E1B2F31B285ED1D844E8D7 /* SFSegment.m */; }; + 504452CAC12585B620DE82B41AE2F0EF /* GridType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A6F1DA8E32F7FCADAADECB83DD0A589 /* GridType.swift */; }; + 5162CC563DB7C40556F7A3BD47A6D729 /* SFCurvePolygon.h in Headers */ = {isa = PBXBuildFile; fileRef = 82E900BF27CD52A05EDC4212E2C1B5A0 /* SFCurvePolygon.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 54EAAB8901C3599E3BB17E356F1EC4BA /* Pods-TAKTracker-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 92657D4891B16DB9A760A2CACAB21B5D /* Pods-TAKTracker-dummy.m */; }; + 55B8CD797D15B06F6DEDE3942C531909 /* SFMultiPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 2E4DEEEDE538673CA7C5898930DF1107 /* SFMultiPoint.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 58090A8C68FE54524677FD5B059D279B /* MGRSTileOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 745062C814B6822E3B0AB0BF84084A9E /* MGRSTileOverlay.swift */; }; + 5C1D095DB70CFC467C2D49D1260472BF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; + 5C7B38DB5D67811CD288E23EC7E6AEE1 /* SFGeometryEnvelopeBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = AE65D7763433AC19571DEB36D6C83382 /* SFGeometryEnvelopeBuilder.m */; }; + 5C7E5B3EDE4E1B01D44A1A264E13DC41 /* SFShamosHoey.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D410E4F6B59F78F8AEF5F2BB42EB2F0 /* SFShamosHoey.m */; }; + 5DEEDED84D1B4B01781E6DABA90EDF98 /* GZDLabeler.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADF51B735731FC1640FFA8E53BB0FE7F /* GZDLabeler.swift */; }; + 5E8C298257FC8FA288AB6E017CF94ADF /* Bounds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EB862483347246602E51E31B1672A17 /* Bounds.swift */; }; + 5F16E3EF1FAABDF6C5C1DDB451948919 /* GridLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E66FC9607D8ED810ABE9565E229680C8 /* GridLabel.swift */; }; + 5F657D10EC9C1F621FE145E6961CDBDA /* Pixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3188BF3FFF7A26DB5CEBD202CECCBD36 /* Pixel.swift */; }; + 6237D17F94DAFD71C873EF84725A63E5 /* Pods-TAKTracker-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = DA5A5A76709FE146F3DADA8D075E9BA2 /* Pods-TAKTracker-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 64909F0D34050F9337AA5D9EBCB91866 /* sf-ios-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = DF664E3F9DAB8D9C8257C16A493BAA1E /* sf-ios-Bridging-Header.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 655B618AA7337F91593380D603986548 /* GridStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1DB673288284B00CF39D90C5394CC09 /* GridStyle.swift */; }; + 66AAA766D7293D6DE733D3C0DFD53472 /* TileDraw.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77947688E6969089695B2CE6EAF25AC9 /* TileDraw.swift */; }; + 689B2DF51EECBC692E7C2507180E7696 /* CLRColor.h in Headers */ = {isa = PBXBuildFile; fileRef = BDB1652DF414492116E57A6DCDFE5638 /* CLRColor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6AAFEA4BDADEF8014A7D3DC9E6611F2C /* SFPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = AD95786446785A780D3D0B2BBBA6E805 /* SFPoint.m */; }; + 6B5A3FCF2A85991D83DE4B91C8EF94BB /* SFCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = AE54A558ADF6D24D5B574F99C9DC4242 /* SFCurve.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6BC65B2810FE7DB2E497A14CAED5C073 /* SFGeometryTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F9275398D56434E1B4E7F9AEF17F84A /* SFGeometryTypes.m */; }; + 7170630BAFBB1EDE838A1A12E85A76F8 /* SFCentroidPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = D2BD9093CC836E72F46BAB2083FFAEEC /* SFCentroidPoint.m */; }; + 728724F5C466127FDB1028BDF3967D66 /* sf-ios-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 32DCF4DE8312F64B0CF3AE04DD81FAD9 /* sf-ios-dummy.m */; }; + 7531B4F97700F1C84513A7A8B43C75FE /* BaseGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7874A44F81E440BAC9758119CD3156DA /* BaseGrid.swift */; }; + 75664AD0731FCA7F5CF05B0AF0C6E1EA /* SFByteWriter.m in Sources */ = {isa = PBXBuildFile; fileRef = AF480DCB19D1E9B5BA62A83199AF81F8 /* SFByteWriter.m */; }; + 77112F31BD9AE65246FE4854BCF0DA88 /* SFMultiCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AB54852F23C634C09A6DEBEC793E4D /* SFMultiCurve.m */; }; + 7900FB4C393C1450079977D3C2415D57 /* SFGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC2C4FEAE7B1010D93F1747B4E6BB47 /* SFGeometry.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7AB45672E1B9BF48632144D30410BEE8 /* grid-ios-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 4876E252C69826AC93D26C995DB564A4 /* grid-ios-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7BDBE294B8E37DACFB2A3CC11E36B474 /* SFCentroidPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A1CFE976EEBFC3B285E36AAEF90C0DA /* SFCentroidPoint.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7D5233B65991E88DE0977460745DE72C /* SFSweepLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C75A5D9330CC221D70D0D70068C2F74 /* SFSweepLine.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7F7DD9882849C54605DED9DDB34F5782 /* Pods-TAKTracker-TAKTrackerTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F2B3F1E103283BBF6AE1AD3F21AFAFAA /* Pods-TAKTracker-TAKTrackerTests-dummy.m */; }; + 7FA49CA3EDC298CA7C55C460F06B0DC2 /* mgrs-ios-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F389AFCA8100D47A138EEFC50343EF98 /* mgrs-ios-dummy.m */; }; + 8024C8311B04F3A5A45D3CF28D01DF45 /* SFTIN.h in Headers */ = {isa = PBXBuildFile; fileRef = DD70F1CD97D9E83C30A00C26579A125A /* SFTIN.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8447B58BA06145AA077143850FFDDFD6 /* MGRS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85B441B11CBE4AF8D1E105AF04473653 /* MGRS.swift */; }; + 85033FED5CBFB7D24E7CAB85F76D7DED /* GridZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE19EED15D25BF0CADC9B3C5A04E8A0B /* GridZone.swift */; }; + 88C9C42049FF76699B4AEA2D808C9DF4 /* SFGeometryCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = E2609AC25973D169691399F3034F8C45 /* SFGeometryCollection.m */; }; + 8ABF748E99B2D156FBE63D67D56BD2D4 /* SFGeometryPrinter.h in Headers */ = {isa = PBXBuildFile; fileRef = BE4FE0A48BC1665780534BB195F72F06 /* SFGeometryPrinter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9199F3D813C5616AB348DC0D123B0A9A /* CLRColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A6EE4E33BC33969C2E18DCE42A4AFBE /* CLRColor.m */; }; + 92AD7B6978B043A6D87647E147EE2763 /* GridRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0059E54790BE84D69AD979ADE254085F /* GridRange.swift */; }; + 94125BE9C2D04C2400314FDCB37274EE /* SFLinearRing.m in Sources */ = {isa = PBXBuildFile; fileRef = 4FFF5393EA951873D1A95226E5C54A29 /* SFLinearRing.m */; }; + 985F593E1D8188ACCD22A09C30E1782E /* SFLine.h in Headers */ = {isa = PBXBuildFile; fileRef = CD338F8209C92757C6B886A7D5C12FD9 /* SFLine.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 990A5FCE56D34701ED0B1F4FC5732286 /* sf-ios-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C33A35A825DAC697493A517F8D23C455 /* sf-ios-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 99D63002859B00ED49BE5D481965B751 /* LatitudeBand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06203B66AFC188A6DAD8AB31800410A8 /* LatitudeBand.swift */; }; + 9A1CF5F77CBB50B95AB79D27214BF2FC /* CLRColorUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = C5B7341D5D21DEBB1E948B31E5483AEC /* CLRColorUtils.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9A607F3DDB4BEA8548A2D427E1A3A408 /* SFLinearRing.h in Headers */ = {isa = PBXBuildFile; fileRef = CFB4CED1A185DF0BD9E8CB853E35D10A /* SFLinearRing.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9C7ABCDEDF00ADE6D09E5280E1949D96 /* SFFiniteFilterTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 7412B9AC933AB40511AC70B9B83E44C7 /* SFFiniteFilterTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9DC9FC4ED00BD4E4E8B49CFD41484DDA /* SFMultiPolygon.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CAA0B3C0128A4A471AC3A01501CC604 /* SFMultiPolygon.m */; }; + A0CD1692DF3059ECF8AC5D1084B8FFD8 /* SFEventTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DB0CB350ADC3E8182E69C445536CD5 /* SFEventTypes.m */; }; + A0E521FEB9A172074CAFA62B36928BA1 /* SFSurface.h in Headers */ = {isa = PBXBuildFile; fileRef = AC1B528E9D3CF87CCECE5D5025B6B77F /* SFSurface.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A21A61C28C044618FE47ABFEE13775B2 /* SFTextReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 31932A4DAB4F160BFB79EBE8A8391471 /* SFTextReader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A5B5C387B6AC85CF40057BCCD1716C0D /* SFMultiLineString.h in Headers */ = {isa = PBXBuildFile; fileRef = D3ACFE5C52409F1F3838413D0BE0A0ED /* SFMultiLineString.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A6046769D45D10FA4428712EA0D85881 /* SFEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B893DB37D9F9BD4589F99C5E3099B42 /* SFEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A7CE6C3CCF8202E05EF3F343B5FCE41C /* SFCircularString.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE023898F386905A91529F1767ACBCC /* SFCircularString.m */; }; + A93701B9BD555583EFFFA7C8A4BBBC32 /* SFCentroidCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = E62B92847D5C6C4EE2059D7C20A2BF58 /* SFCentroidCurve.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A9953A9C364C5785061E35D13E1DDE9E /* SFGeometryEnvelopeBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = B2B7CF69670153E3A5E66EDAFE73F986 /* SFGeometryEnvelopeBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A9CC986E40D14C54FE31268A4F77F7D5 /* mgrs.plist in Resources */ = {isa = PBXBuildFile; fileRef = A6B717F198BFC1E490565769FCF09C8C /* mgrs.plist */; }; + AC01C60701C16C3FA2840CD916457A10 /* SFCentroidSurface.m in Sources */ = {isa = PBXBuildFile; fileRef = 20E9140136FCFC5180C5DB8560B389CE /* SFCentroidSurface.m */; }; + AD8C9C36F0AA8257A1C23D2547CCF8EE /* SFDegreesCentroid.h in Headers */ = {isa = PBXBuildFile; fileRef = 951F07FBF3A71F6BF1BE5D46496C09B4 /* SFDegreesCentroid.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AE7434CD15CBEFF4168F1B9A071887E2 /* CLRColorUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = B671FDAAB743C4A7A52731BA988B470F /* CLRColorUtils.m */; }; + B0A5D78F5B2F79AFE98D4AF98D8610E5 /* SFCompoundCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = E3DF9B5CBF0D7628C48F436A93CFD1DE /* SFCompoundCurve.m */; }; + B1BFDB9E4706D492A8052A8DCB2FBB3F /* GridTile.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E2268B4DA732BBC9B37AA10B923B43 /* GridTile.swift */; }; + B3D24A91D499AE8FA8686B61B67C8DE5 /* MGRSLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614E4DC7FCBCFBF1AB99EB35E18147F6 /* MGRSLine.swift */; }; + B9CE441CDCD318CB9A977B27705DE792 /* GridZones.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20CF66FDB03CF7513BE322D53EA7A8E /* GridZones.swift */; }; + C00DB75C81D8D19823B4E0BB955FE592 /* SFLineString.m in Sources */ = {isa = PBXBuildFile; fileRef = 46FAD3DD8438C6C2AE7D2DBE9BBAAD91 /* SFLineString.m */; }; + C185114905B3BD1C7E3030807794FAF8 /* SFMultiPolygon.h in Headers */ = {isa = PBXBuildFile; fileRef = A1F34BA5218CED0EB4EC1ADC65FA96CB /* SFMultiPolygon.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C1A99C38DE8AD8351521E2822380350D /* mgrs-ios-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 907D7CCB83DA375467750C89CA1B8726 /* mgrs-ios-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C58C3CBDFADC280064A3E6AC33A1BE85 /* MGRSLabeler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B2604DF0685BC3BD832C3BC77629C88 /* MGRSLabeler.swift */; }; + C594ABC4AB985A512289A9036A83AE3F /* SFTriangle.h in Headers */ = {isa = PBXBuildFile; fileRef = D88EF2992992020D850AE6B957799B4D /* SFTriangle.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C5B5DCE9E4DD10638628100C1FE8A5C4 /* SFTextReader.m in Sources */ = {isa = PBXBuildFile; fileRef = B3FDD43CE01C21257235D709E637CA23 /* SFTextReader.m */; }; + C83F587DC28A1AB00D96D3A63F41E8CA /* SFGeometryTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 71813FA652DFA5A20023C050E554547F /* SFGeometryTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C855782F17ECC25066916923DF7822D4 /* SFLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A4D194D9A6DAE1A91AD99CE4929EE9D /* SFLine.m */; }; + CA70C6033B0236EA356CF545F6FBF902 /* SFLineString.h in Headers */ = {isa = PBXBuildFile; fileRef = F39EA9BF5EE5B05ACF23EE24D29895B3 /* SFLineString.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CA931BED8FFF97222F2E4C1DD002C117 /* Labeler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44199CB6497D763F64EA56E4CB675094 /* Labeler.swift */; }; + CADA2601EAA2068C3187325E4781B24E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; + CB40FE6AC60EC5BB6FF4EAB06C112E87 /* SFFiniteFilterTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 812AFFB5750766A63544908B43017FE7 /* SFFiniteFilterTypes.m */; }; + CD58FCD440C3CB39746FC62196361E7C /* GridProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9716780C3D43D1339FC7B18EC5ED2233 /* GridProperties.swift */; }; + CD7C88F27F98E1D9D6FE102DA5EABB69 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; + CD7F04E818114536D2C57D946B3C5DB3 /* SFPointFiniteFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = B10D2636A8F752C00B34BD04F83FF39E /* SFPointFiniteFilter.m */; }; + CFD10A6078AE92707E4384B735A56A1E /* SFPolyhedralSurface.h in Headers */ = {isa = PBXBuildFile; fileRef = 125F8B13569BE402D8E2C259ADAAB66F /* SFPolyhedralSurface.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D2010CA20405CD2A3732AAA7BAA00FA0 /* sf_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FFB31884F86F64238B17527FE10DB62 /* sf_ios.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D3F13422D83C27C47FE24B2B7927DB34 /* SFCircularString.h in Headers */ = {isa = PBXBuildFile; fileRef = 59075292CE1938FB375C16B89BF274E7 /* SFCircularString.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D4A82FE97D097418A6D469327D543E5B /* grid-ios-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 069CFF7B43BA7459DDE7C404C143433E /* grid-ios-dummy.m */; }; + D6E316C5261E3521DF26C41224CBEAAB /* SFGeometryEnvelope.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5B469490FCAA1B343E671F023A4601 /* SFGeometryEnvelope.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D7BFE536C2B5007FDEBDCBDE23724038 /* SFPointFiniteFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = B8E90925ACED35EF26688DC909BF9AF5 /* SFPointFiniteFilter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D8DCE0CC793032CA3E70637A69047DC8 /* SFPolygon.m in Sources */ = {isa = PBXBuildFile; fileRef = 564541973760DAF89844D15379F26DB9 /* SFPolygon.m */; }; + D9A1DF495BF9773DD784205359712CC5 /* GridConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27639AB3E5EDFB5C68BEDB3362F4401 /* GridConstants.swift */; }; + DD65F2AE6A5A60EFFBB748D446FF7486 /* Pods-TAKTracker-TAKTrackerTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = FB5C0F22631A441A3AAA6E76A6C87836 /* Pods-TAKTracker-TAKTrackerTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DD7720DA2C6F5945301B013F5939A9A7 /* SFCurvePolygon.m in Sources */ = {isa = PBXBuildFile; fileRef = E4BF99730F9B069C1683F0F653E57950 /* SFCurvePolygon.m */; }; + DDB3C0D281907A9677CDFD87A5579DBB /* SFCompoundCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BF125EC77C10CFFE724AB465DBEF5E7 /* SFCompoundCurve.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DDED62BD2C447F6C5E7297D20D697A1A /* MGRSProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8CAE1273786EF26500A13DD4E478CFA /* MGRSProperties.swift */; }; + DE0812E35F28B6F0E1647226542ACC11 /* TileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0038CB601C3E78C41757D3B76D9233F /* TileUtils.swift */; }; + DF9D7D1FCFA243E6EFE52B9ADBAFF56D /* CLRColorConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = CFCD2C92AF6B4622C9CFC8ED1A1A1BB6 /* CLRColorConstants.m */; }; + E060AD3B694BEDAFA5B5395BC2D52805 /* SFMultiCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = 03943E94A1C99BFA9457B8F632CD7B01 /* SFMultiCurve.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E12A603B4C1E9DD0C53E4DBEC19062AD /* SFSegment.h in Headers */ = {isa = PBXBuildFile; fileRef = DC3BEB53F37F4E4A6E6881AEF5E5CD96 /* SFSegment.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E22456102F0ECC1CFC7E8BDF8C02CFD4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; + E4FCEA16DE75F4A694D3726150FB3E93 /* ZoomGrids.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83938DA3BEFB6935725749F99E153865 /* ZoomGrids.swift */; }; + EB718323DA2FB3B09B68405FBE2F2B0A /* SFShamosHoey.h in Headers */ = {isa = PBXBuildFile; fileRef = 1113AEB5317A5C730AF2E5E9BE675A27 /* SFShamosHoey.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EE12BDF6B07146DCE7D71A1FD9BB5C58 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B14AEE13923842FE76AA062F3961BFC /* Line.swift */; }; + EF1C288D10C68E69DA5FCF9BFAB6F854 /* color-ios-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 227C7AAAC00962177108BF75AD2A281F /* color-ios-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EF7FB19EC749C2AF91625156E43FDED4 /* color-ios-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F14634AB5D2F308AED53764F7CF3110 /* color-ios-Bridging-Header.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F02E316A96C8263449A52ADE34EBF15A /* SFTIN.m in Sources */ = {isa = PBXBuildFile; fileRef = DEBA3DA768B7114FD90DE29E628D8502 /* SFTIN.m */; }; + F05096E84B02ABA64A76FF3AC8482C45 /* SFPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = BC518689A7A47FD476B1D6CE52A93481 /* SFPoint.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F3357B9FCA92F8DAB22DD0FA79A561EC /* SFGeometryPrinter.m in Sources */ = {isa = PBXBuildFile; fileRef = 92FF470E4F1B25D8F608830CA5349553 /* SFGeometryPrinter.m */; }; + F5DA2BD5458F7EA65CD2E599D35CC4F8 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7313130C1987E342AC69ADF16091DB3D /* Label.swift */; }; + F74B1D2D126E49BB9B0FF8DA9CC05E63 /* MGRSUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D012EE976AFA7F4AF6209DF9310D290 /* MGRSUtils.swift */; }; + F84FCFCAC9BCAB72DD72486E6B8E7A68 /* UTM.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBA0A6FE8CD4B179D459AC44C23D2344 /* UTM.swift */; }; + FB417D91B5E2AF28BE667B217E060A5C /* SFGeometryFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 18A7B13EE54A4BC21C570D2272B52641 /* SFGeometryFilter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FBA0B6116F184AEE48111DCA56484F4F /* color_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = 271FE6CD6C70D881EC77AD64E8071CD8 /* color_ios.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FF53E26D8746E0EFEE73E7EBC06115C1 /* SFCentroidCurve.m in Sources */ = {isa = PBXBuildFile; fileRef = F9AC01D61B807E620F86FF04553A7E22 /* SFCentroidCurve.m */; }; + FF828B06B69B612AF17AE40C3149481C /* BandLetterRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = E430F83CF0FB1A101EB50408F8E0CB1C /* BandLetterRange.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 14A5AAF358A1460F34DE9CCD243DBBA7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5D942CA48BAB353546F6B788AC3EA195; + remoteInfo = "color-ios"; + }; + 27E0EDA9B6A89F8A568D38404519028B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F99C60B9711DB2529FC6C4FC9904B3F9; + remoteInfo = "grid-ios"; + }; + 416EBD680E4DC7D01C89A47357693AA7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F99C60B9711DB2529FC6C4FC9904B3F9; + remoteInfo = "grid-ios"; + }; + 51E822EB846DD678032CF511C2D194D4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3D3A419CC7A327DAABA72019D5CE9F57; + remoteInfo = "sf-ios"; + }; + 62027A19ED0F1A46E0231A220C1FA062 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = FA341BB40DB010A6FF2E54DFC3D1E5D8; + remoteInfo = "mgrs-ios"; + }; + 802089AF3970F80C87B0F258B9AD5E12 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F99C60B9711DB2529FC6C4FC9904B3F9; + remoteInfo = "grid-ios"; + }; + 93E2BBEF8CD4EB2D2B588892CB4A12AA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3D3A419CC7A327DAABA72019D5CE9F57; + remoteInfo = "sf-ios"; + }; + B6A0CB8D262C7A709DAB014FD7B06778 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5D942CA48BAB353546F6B788AC3EA195; + remoteInfo = "color-ios"; + }; + BC1A641CC3110E62E5DE83A0A7252F32 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 577E91B04D12C328F76DD4B7C16DBAEF; + remoteInfo = "mgrs-ios-mgrs-ios"; + }; + D415627711DED532AAA0B6A36DCC5948 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5D942CA48BAB353546F6B788AC3EA195; + remoteInfo = "color-ios"; + }; + F174B54D03D29015D5379B9F2E91AC8B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3D3A419CC7A327DAABA72019D5CE9F57; + remoteInfo = "sf-ios"; + }; + FC0BA8E95EAB6077B80B2BD277E70F20 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = FA341BB40DB010A6FF2E54DFC3D1E5D8; + remoteInfo = "mgrs-ios"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 0059E54790BE84D69AD979ADE254085F /* GridRange.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GridRange.swift; path = "mgrs-ios/gzd/GridRange.swift"; sourceTree = ""; }; + 023DA3166A0D28C4202C6C0C70B9F68A /* PixelRange.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PixelRange.swift; path = "grid-ios/tile/PixelRange.swift"; sourceTree = ""; }; + 03943E94A1C99BFA9457B8F632CD7B01 /* SFMultiCurve.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFMultiCurve.h; path = "sf-ios/SFMultiCurve.h"; sourceTree = ""; }; + 06203B66AFC188A6DAD8AB31800410A8 /* LatitudeBand.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LatitudeBand.swift; path = "mgrs-ios/gzd/LatitudeBand.swift"; sourceTree = ""; }; + 069CFF7B43BA7459DDE7C404C143433E /* grid-ios-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "grid-ios-dummy.m"; sourceTree = ""; }; + 0894E95C0890A27CB27EE722440C3E15 /* Pods-TAKTracker.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TAKTracker.debug.xcconfig"; sourceTree = ""; }; + 0A8672C317E1B2F31B285ED1D844E8D7 /* SFSegment.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFSegment.m; path = "sf-ios/util/sweep/SFSegment.m"; sourceTree = ""; }; + 0BD7CF883331619E55A228A609D5B4FC /* CLRColorConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CLRColorConstants.h; path = "color-ios/CLRColorConstants.h"; sourceTree = ""; }; + 0F5B469490FCAA1B343E671F023A4601 /* SFGeometryEnvelope.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFGeometryEnvelope.h; path = "sf-ios/SFGeometryEnvelope.h"; sourceTree = ""; }; + 0F5CB11B2BADDF906FFAFA890F456CE2 /* mgrs-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "mgrs-ios.debug.xcconfig"; sourceTree = ""; }; + 0FF3776E7D2B4FB9DCCF8754FBBC0968 /* SFEventTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFEventTypes.h; path = "sf-ios/util/sweep/SFEventTypes.h"; sourceTree = ""; }; + 1113AEB5317A5C730AF2E5E9BE675A27 /* SFShamosHoey.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFShamosHoey.h; path = "sf-ios/util/sweep/SFShamosHoey.h"; sourceTree = ""; }; + 125F8B13569BE402D8E2C259ADAAB66F /* SFPolyhedralSurface.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFPolyhedralSurface.h; path = "sf-ios/SFPolyhedralSurface.h"; sourceTree = ""; }; + 16A3E2FB923722F098638604FB7EDE7B /* color-ios.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "color-ios.modulemap"; sourceTree = ""; }; + 18A7B13EE54A4BC21C570D2272B52641 /* SFGeometryFilter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFGeometryFilter.h; path = "sf-ios/util/filter/SFGeometryFilter.h"; sourceTree = ""; }; + 1A6F1DA8E32F7FCADAADECB83DD0A589 /* GridType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GridType.swift; path = "mgrs-ios/grid/GridType.swift"; sourceTree = ""; }; + 1B3EDB3F6C36DC0596E30D4B9C4B9077 /* SFTriangle.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFTriangle.m; path = "sf-ios/SFTriangle.m"; sourceTree = ""; }; + 1C75A5D9330CC221D70D0D70068C2F74 /* SFSweepLine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFSweepLine.h; path = "sf-ios/util/sweep/SFSweepLine.h"; sourceTree = ""; }; + 1FDD7A8AF9BD4A6F04C55146B97B851E /* SFMultiSurface.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFMultiSurface.m; path = "sf-ios/SFMultiSurface.m"; sourceTree = ""; }; + 20E9140136FCFC5180C5DB8560B389CE /* SFCentroidSurface.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFCentroidSurface.m; path = "sf-ios/util/centroid/SFCentroidSurface.m"; sourceTree = ""; }; + 227C7AAAC00962177108BF75AD2A281F /* color-ios-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "color-ios-umbrella.h"; sourceTree = ""; }; + 2660C7AFBBC2D87AB2FE6D0563716923 /* mgrs-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "mgrs-ios.release.xcconfig"; sourceTree = ""; }; + 271FE6CD6C70D881EC77AD64E8071CD8 /* color_ios.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = color_ios.h; path = "color-ios/color_ios.h"; sourceTree = ""; }; + 28621C8035DA87D89A8A2B187EF98A12 /* SFGeometryCollection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFGeometryCollection.h; path = "sf-ios/SFGeometryCollection.h"; sourceTree = ""; }; + 290D43FF8A536D340A0768C91F6100C0 /* SFMultiLineString.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFMultiLineString.m; path = "sf-ios/SFMultiLineString.m"; sourceTree = ""; }; + 2CAA0B3C0128A4A471AC3A01501CC604 /* SFMultiPolygon.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFMultiPolygon.m; path = "sf-ios/SFMultiPolygon.m"; sourceTree = ""; }; + 2DC2B5D322035FCF210E33EF2A14FD88 /* SFMultiPoint.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFMultiPoint.m; path = "sf-ios/SFMultiPoint.m"; sourceTree = ""; }; + 2DFF9DB321426B8017B1228290F3AAB5 /* SFGeometryConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFGeometryConstants.h; path = "sf-ios/util/SFGeometryConstants.h"; sourceTree = ""; }; + 2E4DEEEDE538673CA7C5898930DF1107 /* SFMultiPoint.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFMultiPoint.h; path = "sf-ios/SFMultiPoint.h"; sourceTree = ""; }; + 2EB862483347246602E51E31B1672A17 /* Bounds.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bounds.swift; path = "grid-ios/features/Bounds.swift"; sourceTree = ""; }; + 2F97C8CE346DDCF07EE3F169C6B7DB06 /* BaseZoomGrids.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BaseZoomGrids.swift; path = "grid-ios/BaseZoomGrids.swift"; sourceTree = ""; }; + 3188BF3FFF7A26DB5CEBD202CECCBD36 /* Pixel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Pixel.swift; path = "grid-ios/tile/Pixel.swift"; sourceTree = ""; }; + 31932A4DAB4F160BFB79EBE8A8391471 /* SFTextReader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFTextReader.h; path = "sf-ios/util/SFTextReader.h"; sourceTree = ""; }; + 32323DCD7ED9B830CD0092ADA15048D9 /* SFGeometryUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFGeometryUtils.m; path = "sf-ios/util/SFGeometryUtils.m"; sourceTree = ""; }; + 3243D50FEEEF0AA58FCBDA9037733C95 /* PropertyConstants.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PropertyConstants.swift; path = "grid-ios/property/PropertyConstants.swift"; sourceTree = ""; }; + 32DCF4DE8312F64B0CF3AE04DD81FAD9 /* sf-ios-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "sf-ios-dummy.m"; sourceTree = ""; }; + 34DB0CB350ADC3E8182E69C445536CD5 /* SFEventTypes.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFEventTypes.m; path = "sf-ios/util/sweep/SFEventTypes.m"; sourceTree = ""; }; + 35F014EC7FAFEDD1FD2BC06705152166 /* SFEventQueue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFEventQueue.m; path = "sf-ios/util/sweep/SFEventQueue.m"; sourceTree = ""; }; + 3A4D194D9A6DAE1A91AD99CE4929EE9D /* SFLine.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFLine.m; path = "sf-ios/SFLine.m"; sourceTree = ""; }; + 3A7924890AF51FC698FDC4BA555F8203 /* SFByteWriter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFByteWriter.h; path = "sf-ios/util/SFByteWriter.h"; sourceTree = ""; }; + 3C6F396086EA9EAEC1052CF1B0E8D0BD /* color-ios-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "color-ios-prefix.pch"; sourceTree = ""; }; + 3CA0ACD3CEF47962069826A7DA81A2D9 /* Hemisphere.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Hemisphere.swift; path = "grid-ios/Hemisphere.swift"; sourceTree = ""; }; + 3F9275398D56434E1B4E7F9AEF17F84A /* SFGeometryTypes.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFGeometryTypes.m; path = "sf-ios/SFGeometryTypes.m"; sourceTree = ""; }; + 3FCE035B2EBA1E24D020924CABFD59DF /* BaseGrids.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BaseGrids.swift; path = "grid-ios/BaseGrids.swift"; sourceTree = ""; }; + 3FFB31884F86F64238B17527FE10DB62 /* sf_ios.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = sf_ios.h; path = "sf-ios/sf_ios.h"; sourceTree = ""; }; + 400F91DA42E6FC7C22FE3F06D34AA353 /* SFGeometryUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFGeometryUtils.h; path = "sf-ios/util/SFGeometryUtils.h"; sourceTree = ""; }; + 4030261639065FB6E758E20B46AD84BC /* sf-ios-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "sf-ios-Info.plist"; sourceTree = ""; }; + 4335711A79C8B9F2C44CCEC7DA2F7256 /* sf-ios-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "sf-ios-prefix.pch"; sourceTree = ""; }; + 44199CB6497D763F64EA56E4CB675094 /* Labeler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Labeler.swift; path = "grid-ios/Labeler.swift"; sourceTree = ""; }; + 45EDE46C074CBF3E3C6844B4FD831B49 /* SFGeometryConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFGeometryConstants.m; path = "sf-ios/util/SFGeometryConstants.m"; sourceTree = ""; }; + 46FAD3DD8438C6C2AE7D2DBE9BBAAD91 /* SFLineString.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFLineString.m; path = "sf-ios/SFLineString.m"; sourceTree = ""; }; + 4876E252C69826AC93D26C995DB564A4 /* grid-ios-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "grid-ios-umbrella.h"; sourceTree = ""; }; + 487DDF25A56AFBBDE95A6A50CD438336 /* Pods-TAKTracker-TAKTrackerTests */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-TAKTracker-TAKTrackerTests"; path = Pods_TAKTracker_TAKTrackerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4B893DB37D9F9BD4589F99C5E3099B42 /* SFEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFEvent.h; path = "sf-ios/util/sweep/SFEvent.h"; sourceTree = ""; }; + 4D410E4F6B59F78F8AEF5F2BB42EB2F0 /* SFShamosHoey.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFShamosHoey.m; path = "sf-ios/util/sweep/SFShamosHoey.m"; sourceTree = ""; }; + 4F200FC096E28386D09EDFAEAFB92FE2 /* SFCentroidSurface.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFCentroidSurface.h; path = "sf-ios/util/centroid/SFCentroidSurface.h"; sourceTree = ""; }; + 4FFF5393EA951873D1A95226E5C54A29 /* SFLinearRing.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFLinearRing.m; path = "sf-ios/SFLinearRing.m"; sourceTree = ""; }; + 500FF3361BF5F512BBC1567F56848F83 /* Pods-TAKTracker.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TAKTracker.release.xcconfig"; sourceTree = ""; }; + 519EFC06EF426F8AC40C818C658518C5 /* MGRSConstants.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MGRSConstants.swift; path = "mgrs-ios/MGRSConstants.swift"; sourceTree = ""; }; + 564541973760DAF89844D15379F26DB9 /* SFPolygon.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFPolygon.m; path = "sf-ios/SFPolygon.m"; sourceTree = ""; }; + 57A69667D76341A8D69E0FC97BFD81F8 /* Grid.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Grid.swift; path = "mgrs-ios/grid/Grid.swift"; sourceTree = ""; }; + 59075292CE1938FB375C16B89BF274E7 /* SFCircularString.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFCircularString.h; path = "sf-ios/SFCircularString.h"; sourceTree = ""; }; + 5C28424481CE8A0A6B868B0DCFDEF48A /* GridUtils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GridUtils.swift; path = "grid-ios/GridUtils.swift"; sourceTree = ""; }; + 5D012EE976AFA7F4AF6209DF9310D290 /* MGRSUtils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MGRSUtils.swift; path = "mgrs-ios/MGRSUtils.swift"; sourceTree = ""; }; + 5F5CA0BA5BF886F174396918B4A6FF68 /* Pods-TAKTracker-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-TAKTracker-acknowledgements.markdown"; sourceTree = ""; }; + 61300EDB21C649EB201A2B745D3D2EE7 /* sf-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "sf-ios.release.xcconfig"; sourceTree = ""; }; + 614E4DC7FCBCFBF1AB99EB35E18147F6 /* MGRSLine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MGRSLine.swift; path = "mgrs-ios/features/MGRSLine.swift"; sourceTree = ""; }; + 65D7E8FDA268069E4DBE471FD4B51C43 /* sf-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "sf-ios.debug.xcconfig"; sourceTree = ""; }; + 663C73DDDC517802F4DAE8E3BA5D2167 /* grid-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "grid-ios.debug.xcconfig"; sourceTree = ""; }; + 6701E1E7881E37B884FEEA9B3F803E0B /* color-ios */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "color-ios"; path = color_ios.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 6808C4820AAF7EDCA945DC4E43C42FDA /* Pods-TAKTracker-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TAKTracker-acknowledgements.plist"; sourceTree = ""; }; + 684EBC6DFA0FFDE2E145ADE8EE2CEF9D /* SFByteReader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFByteReader.m; path = "sf-ios/util/SFByteReader.m"; sourceTree = ""; }; + 6B14AEE13923842FE76AA062F3961BFC /* Line.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Line.swift; path = "grid-ios/features/Line.swift"; sourceTree = ""; }; + 6B2604DF0685BC3BD832C3BC77629C88 /* MGRSLabeler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MGRSLabeler.swift; path = "mgrs-ios/grid/MGRSLabeler.swift"; sourceTree = ""; }; + 6F14634AB5D2F308AED53764F7CF3110 /* color-ios-Bridging-Header.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "color-ios-Bridging-Header.h"; path = "color-ios/color-ios-Bridging-Header.h"; sourceTree = ""; }; + 70361BBB0CD461A2B88827416F8B3D75 /* mgrs-ios-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "mgrs-ios-Info.plist"; sourceTree = ""; }; + 71813FA652DFA5A20023C050E554547F /* SFGeometryTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFGeometryTypes.h; path = "sf-ios/SFGeometryTypes.h"; sourceTree = ""; }; + 7270B776073BDF7F886F410375A2468D /* sf-ios.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "sf-ios.modulemap"; sourceTree = ""; }; + 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 7313130C1987E342AC69ADF16091DB3D /* Label.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Label.swift; path = "grid-ios/Label.swift"; sourceTree = ""; }; + 7412B9AC933AB40511AC70B9B83E44C7 /* SFFiniteFilterTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFFiniteFilterTypes.h; path = "sf-ios/util/filter/SFFiniteFilterTypes.h"; sourceTree = ""; }; + 745062C814B6822E3B0AB0BF84084A9E /* MGRSTileOverlay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MGRSTileOverlay.swift; path = "mgrs-ios/tile/MGRSTileOverlay.swift"; sourceTree = ""; }; + 774DB00815D3CAB2F00CEE49CADA14AF /* SFSweepLine.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFSweepLine.m; path = "sf-ios/util/sweep/SFSweepLine.m"; sourceTree = ""; }; + 77947688E6969089695B2CE6EAF25AC9 /* TileDraw.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TileDraw.swift; path = "grid-ios/tile/TileDraw.swift"; sourceTree = ""; }; + 77AB54852F23C634C09A6DEBEC793E4D /* SFMultiCurve.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFMultiCurve.m; path = "sf-ios/SFMultiCurve.m"; sourceTree = ""; }; + 7874A44F81E440BAC9758119CD3156DA /* BaseGrid.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BaseGrid.swift; path = "grid-ios/BaseGrid.swift"; sourceTree = ""; }; + 7A1CFE976EEBFC3B285E36AAEF90C0DA /* SFCentroidPoint.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFCentroidPoint.h; path = "sf-ios/util/centroid/SFCentroidPoint.h"; sourceTree = ""; }; + 7A6EE4E33BC33969C2E18DCE42A4AFBE /* CLRColor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = CLRColor.m; path = "color-ios/CLRColor.m"; sourceTree = ""; }; + 7BC2C4FEAE7B1010D93F1747B4E6BB47 /* SFGeometry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFGeometry.h; path = "sf-ios/SFGeometry.h"; sourceTree = ""; }; + 7EE66363A245AC8A4B45D95E5CEC6B09 /* grid-ios */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "grid-ios"; path = grid_ios.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 812AFFB5750766A63544908B43017FE7 /* SFFiniteFilterTypes.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFFiniteFilterTypes.m; path = "sf-ios/util/filter/SFFiniteFilterTypes.m"; sourceTree = ""; }; + 81AC2DC77BEA1280D97530A4D94D6B4F /* Unit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Unit.swift; path = "grid-ios/features/Unit.swift"; sourceTree = ""; }; + 82D03984775AF1EF6A96680E12E265B0 /* color-ios-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "color-ios-Info.plist"; sourceTree = ""; }; + 82E900BF27CD52A05EDC4212E2C1B5A0 /* SFCurvePolygon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFCurvePolygon.h; path = "sf-ios/SFCurvePolygon.h"; sourceTree = ""; }; + 83938DA3BEFB6935725749F99E153865 /* ZoomGrids.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ZoomGrids.swift; path = "mgrs-ios/grid/ZoomGrids.swift"; sourceTree = ""; }; + 84AEC61DCB8D681446EC274B37E177C7 /* SFGeometryEnvelope.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFGeometryEnvelope.m; path = "sf-ios/SFGeometryEnvelope.m"; sourceTree = ""; }; + 85B441B11CBE4AF8D1E105AF04473653 /* MGRS.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MGRS.swift; path = "mgrs-ios/MGRS.swift"; sourceTree = ""; }; + 891086E5D78592128EB4829E5ED1C607 /* SFSurface.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFSurface.m; path = "sf-ios/SFSurface.m"; sourceTree = ""; }; + 8B452511DBDAF5420CBB798B10651D74 /* SFExtendedGeometryCollection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFExtendedGeometryCollection.h; path = "sf-ios/extended/SFExtendedGeometryCollection.h"; sourceTree = ""; }; + 8EC140AAED4A59F5712E30903769C415 /* grid-ios-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "grid-ios-prefix.pch"; sourceTree = ""; }; + 907D7CCB83DA375467750C89CA1B8726 /* mgrs-ios-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "mgrs-ios-umbrella.h"; sourceTree = ""; }; + 92657D4891B16DB9A760A2CACAB21B5D /* Pods-TAKTracker-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TAKTracker-dummy.m"; sourceTree = ""; }; + 92FF470E4F1B25D8F608830CA5349553 /* SFGeometryPrinter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFGeometryPrinter.m; path = "sf-ios/util/SFGeometryPrinter.m"; sourceTree = ""; }; + 951F07FBF3A71F6BF1BE5D46496C09B4 /* SFDegreesCentroid.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFDegreesCentroid.h; path = "sf-ios/util/centroid/SFDegreesCentroid.h"; sourceTree = ""; }; + 9716780C3D43D1339FC7B18EC5ED2233 /* GridProperties.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GridProperties.swift; path = "grid-ios/property/GridProperties.swift"; sourceTree = ""; }; + 9912976AE55386F8962DE76F6C738746 /* Pods-TAKTracker-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-TAKTracker-frameworks.sh"; sourceTree = ""; }; + 9BF125EC77C10CFFE724AB465DBEF5E7 /* SFCompoundCurve.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFCompoundCurve.h; path = "sf-ios/SFCompoundCurve.h"; sourceTree = ""; }; + 9D31CEE8BD52C5C0BD08FC7F3D9E9257 /* Pods-TAKTracker-TAKTrackerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TAKTracker-TAKTrackerTests.debug.xcconfig"; sourceTree = ""; }; + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 9F6EB542086BD931C888EE2394148556 /* SFEventQueue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFEventQueue.h; path = "sf-ios/util/sweep/SFEventQueue.h"; sourceTree = ""; }; + A1F34BA5218CED0EB4EC1ADC65FA96CB /* SFMultiPolygon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFMultiPolygon.h; path = "sf-ios/SFMultiPolygon.h"; sourceTree = ""; }; + A285519FAD68A4B91EF421B349AEB9D9 /* color-ios-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "color-ios-dummy.m"; sourceTree = ""; }; + A6B717F198BFC1E490565769FCF09C8C /* mgrs.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = mgrs.plist; path = "mgrs-ios/mgrs.plist"; sourceTree = ""; }; + A7C9A3A6996DA4888EC230C2771D1EBC /* Pods-TAKTracker-TAKTrackerTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TAKTracker-TAKTrackerTests-acknowledgements.plist"; sourceTree = ""; }; + AC1B528E9D3CF87CCECE5D5025B6B77F /* SFSurface.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFSurface.h; path = "sf-ios/SFSurface.h"; sourceTree = ""; }; + AC441E0CCA300B10B61526D8882F0475 /* Pods-TAKTracker-TAKTrackerTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-TAKTracker-TAKTrackerTests-acknowledgements.markdown"; sourceTree = ""; }; + AD95786446785A780D3D0B2BBBA6E805 /* SFPoint.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFPoint.m; path = "sf-ios/SFPoint.m"; sourceTree = ""; }; + ADF51B735731FC1640FFA8E53BB0FE7F /* GZDLabeler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GZDLabeler.swift; path = "mgrs-ios/gzd/GZDLabeler.swift"; sourceTree = ""; }; + AE54A558ADF6D24D5B574F99C9DC4242 /* SFCurve.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFCurve.h; path = "sf-ios/SFCurve.h"; sourceTree = ""; }; + AE65D7763433AC19571DEB36D6C83382 /* SFGeometryEnvelopeBuilder.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFGeometryEnvelopeBuilder.m; path = "sf-ios/util/SFGeometryEnvelopeBuilder.m"; sourceTree = ""; }; + AEDE3F2148291E06268235146C8D4F1B /* Pods-TAKTracker-TAKTrackerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TAKTracker-TAKTrackerTests.release.xcconfig"; sourceTree = ""; }; + AF480DCB19D1E9B5BA62A83199AF81F8 /* SFByteWriter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFByteWriter.m; path = "sf-ios/util/SFByteWriter.m"; sourceTree = ""; }; + B10D2636A8F752C00B34BD04F83FF39E /* SFPointFiniteFilter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFPointFiniteFilter.m; path = "sf-ios/util/filter/SFPointFiniteFilter.m"; sourceTree = ""; }; + B1DB673288284B00CF39D90C5394CC09 /* GridStyle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GridStyle.swift; path = "grid-ios/GridStyle.swift"; sourceTree = ""; }; + B29C44830FBB834CBB0A1947FE188EFE /* SFMultiSurface.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFMultiSurface.h; path = "sf-ios/SFMultiSurface.h"; sourceTree = ""; }; + B2B7CF69670153E3A5E66EDAFE73F986 /* SFGeometryEnvelopeBuilder.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFGeometryEnvelopeBuilder.h; path = "sf-ios/util/SFGeometryEnvelopeBuilder.h"; sourceTree = ""; }; + B3FDD43CE01C21257235D709E637CA23 /* SFTextReader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFTextReader.m; path = "sf-ios/util/SFTextReader.m"; sourceTree = ""; }; + B5E2268B4DA732BBC9B37AA10B923B43 /* GridTile.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GridTile.swift; path = "grid-ios/tile/GridTile.swift"; sourceTree = ""; }; + B671FDAAB743C4A7A52731BA988B470F /* CLRColorUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = CLRColorUtils.m; path = "color-ios/CLRColorUtils.m"; sourceTree = ""; }; + B6CD63F50A987FC9D3C394C510C654E5 /* color-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "color-ios.release.xcconfig"; sourceTree = ""; }; + B8E90925ACED35EF26688DC909BF9AF5 /* SFPointFiniteFilter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFPointFiniteFilter.h; path = "sf-ios/util/filter/SFPointFiniteFilter.h"; sourceTree = ""; }; + B9A67935C386EE102ECA25199A7CA64F /* SFEvent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFEvent.m; path = "sf-ios/util/sweep/SFEvent.m"; sourceTree = ""; }; + BBA0A6FE8CD4B179D459AC44C23D2344 /* UTM.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UTM.swift; path = "mgrs-ios/utm/UTM.swift"; sourceTree = ""; }; + BC518689A7A47FD476B1D6CE52A93481 /* SFPoint.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFPoint.h; path = "sf-ios/SFPoint.h"; sourceTree = ""; }; + BDB1652DF414492116E57A6DCDFE5638 /* CLRColor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CLRColor.h; path = "color-ios/CLRColor.h"; sourceTree = ""; }; + BE19EED15D25BF0CADC9B3C5A04E8A0B /* GridZone.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GridZone.swift; path = "mgrs-ios/gzd/GridZone.swift"; sourceTree = ""; }; + BE4B520CD9BD34295645E90C1D7675ED /* ResourceBundle-mgrs-ios-mgrs-ios-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-mgrs-ios-mgrs-ios-Info.plist"; sourceTree = ""; }; + BE4FE0A48BC1665780534BB195F72F06 /* SFGeometryPrinter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFGeometryPrinter.h; path = "sf-ios/util/SFGeometryPrinter.h"; sourceTree = ""; }; + BF00186B3E3031ACB739D50A86CD8B5A /* Pods-TAKTracker.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-TAKTracker.modulemap"; sourceTree = ""; }; + BFE44A74E81D258D43BB588B958D14FC /* Pods-TAKTracker-TAKTrackerTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-TAKTracker-TAKTrackerTests.modulemap"; sourceTree = ""; }; + C0038CB601C3E78C41757D3B76D9233F /* TileUtils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TileUtils.swift; path = "grid-ios/tile/TileUtils.swift"; sourceTree = ""; }; + C199554CD3554B4968A8F7259C630DA8 /* Pods-TAKTracker-TAKTrackerTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-TAKTracker-TAKTrackerTests-frameworks.sh"; sourceTree = ""; }; + C1D37DBF2B7B7BCE0213BC0468DA7AB5 /* mgrs-ios */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "mgrs-ios"; path = mgrs_ios.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C33A35A825DAC697493A517F8D23C455 /* sf-ios-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "sf-ios-umbrella.h"; sourceTree = ""; }; + C5B7341D5D21DEBB1E948B31E5483AEC /* CLRColorUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = CLRColorUtils.h; path = "color-ios/CLRColorUtils.h"; sourceTree = ""; }; + C784F19CB8F1F6BFB2768B8D8C62D136 /* Pods-TAKTracker */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-TAKTracker"; path = Pods_TAKTracker.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C8FB3FFB026BA83BAD3A19C9728B7104 /* mgrs-ios.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "mgrs-ios.modulemap"; sourceTree = ""; }; + CD338F8209C92757C6B886A7D5C12FD9 /* SFLine.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFLine.h; path = "sf-ios/SFLine.h"; sourceTree = ""; }; + CF4CB5075D3B4C81C5E865EDE12A1C28 /* grid-ios-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "grid-ios-Info.plist"; sourceTree = ""; }; + CFB4CED1A185DF0BD9E8CB853E35D10A /* SFLinearRing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFLinearRing.h; path = "sf-ios/SFLinearRing.h"; sourceTree = ""; }; + CFCD2C92AF6B4622C9CFC8ED1A1A1BB6 /* CLRColorConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = CLRColorConstants.m; path = "color-ios/CLRColorConstants.m"; sourceTree = ""; }; + D20CF66FDB03CF7513BE322D53EA7A8E /* GridZones.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GridZones.swift; path = "mgrs-ios/gzd/GridZones.swift"; sourceTree = ""; }; + D2BD9093CC836E72F46BAB2083FFAEEC /* SFCentroidPoint.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFCentroidPoint.m; path = "sf-ios/util/centroid/SFCentroidPoint.m"; sourceTree = ""; }; + D3ACFE5C52409F1F3838413D0BE0A0ED /* SFMultiLineString.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFMultiLineString.h; path = "sf-ios/SFMultiLineString.h"; sourceTree = ""; }; + D568030E05D091C56309AF39466B9771 /* color-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "color-ios.debug.xcconfig"; sourceTree = ""; }; + D57C1FAB77A663260850740EEB9C3590 /* sf-ios */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "sf-ios"; path = sf_ios.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D5FCE36CEC5EB6ECBCC39E71F2E05AC4 /* grid-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "grid-ios.release.xcconfig"; sourceTree = ""; }; + D88EF2992992020D850AE6B957799B4D /* SFTriangle.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFTriangle.h; path = "sf-ios/SFTriangle.h"; sourceTree = ""; }; + D8CAE1273786EF26500A13DD4E478CFA /* MGRSProperties.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MGRSProperties.swift; path = "mgrs-ios/property/MGRSProperties.swift"; sourceTree = ""; }; + DA5A5A76709FE146F3DADA8D075E9BA2 /* Pods-TAKTracker-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TAKTracker-umbrella.h"; sourceTree = ""; }; + DAFDB1F24C2EAD375521FE67433827B8 /* Pods-TAKTracker-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TAKTracker-Info.plist"; sourceTree = ""; }; + DC3BEB53F37F4E4A6E6881AEF5E5CD96 /* SFSegment.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFSegment.h; path = "sf-ios/util/sweep/SFSegment.h"; sourceTree = ""; }; + DCE023898F386905A91529F1767ACBCC /* SFCircularString.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFCircularString.m; path = "sf-ios/SFCircularString.m"; sourceTree = ""; }; + DD2D26A77DB958E7CEAEDEA102EB0B9C /* SFByteReader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFByteReader.h; path = "sf-ios/util/SFByteReader.h"; sourceTree = ""; }; + DD70F1CD97D9E83C30A00C26579A125A /* SFTIN.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFTIN.h; path = "sf-ios/SFTIN.h"; sourceTree = ""; }; + DEBA3DA768B7114FD90DE29E628D8502 /* SFTIN.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFTIN.m; path = "sf-ios/SFTIN.m"; sourceTree = ""; }; + DF664E3F9DAB8D9C8257C16A493BAA1E /* sf-ios-Bridging-Header.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "sf-ios-Bridging-Header.h"; path = "sf-ios/sf-ios-Bridging-Header.h"; sourceTree = ""; }; + E2609AC25973D169691399F3034F8C45 /* SFGeometryCollection.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFGeometryCollection.m; path = "sf-ios/SFGeometryCollection.m"; sourceTree = ""; }; + E27639AB3E5EDFB5C68BEDB3362F4401 /* GridConstants.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GridConstants.swift; path = "grid-ios/GridConstants.swift"; sourceTree = ""; }; + E3DF9B5CBF0D7628C48F436A93CFD1DE /* SFCompoundCurve.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFCompoundCurve.m; path = "sf-ios/SFCompoundCurve.m"; sourceTree = ""; }; + E430F83CF0FB1A101EB50408F8E0CB1C /* BandLetterRange.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BandLetterRange.swift; path = "mgrs-ios/gzd/BandLetterRange.swift"; sourceTree = ""; }; + E4BF99730F9B069C1683F0F653E57950 /* SFCurvePolygon.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFCurvePolygon.m; path = "sf-ios/SFCurvePolygon.m"; sourceTree = ""; }; + E56B4688749ADDF7AC9988F47575DC68 /* GridLabeler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GridLabeler.swift; path = "mgrs-ios/grid/GridLabeler.swift"; sourceTree = ""; }; + E62B92847D5C6C4EE2059D7C20A2BF58 /* SFCentroidCurve.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFCentroidCurve.h; path = "sf-ios/util/centroid/SFCentroidCurve.h"; sourceTree = ""; }; + E65E11BF4833C38B18D081EEE90CCA02 /* GridPoint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GridPoint.swift; path = "grid-ios/features/GridPoint.swift"; sourceTree = ""; }; + E66FC9607D8ED810ABE9565E229680C8 /* GridLabel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GridLabel.swift; path = "mgrs-ios/grid/GridLabel.swift"; sourceTree = ""; }; + E6838AFF78B2AE0E46AB69727ECAA884 /* grid-ios.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "grid-ios.modulemap"; sourceTree = ""; }; + E78DEACAED1651147C3138A3C387A819 /* SFDegreesCentroid.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFDegreesCentroid.m; path = "sf-ios/util/centroid/SFDegreesCentroid.m"; sourceTree = ""; }; + EA45EEA7958D8FBA57D574798993A122 /* SFCurve.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFCurve.m; path = "sf-ios/SFCurve.m"; sourceTree = ""; }; + ED9A6DEDF060D707D58AE0AE9D2F5949 /* SFExtendedGeometryCollection.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFExtendedGeometryCollection.m; path = "sf-ios/extended/SFExtendedGeometryCollection.m"; sourceTree = ""; }; + F075E3F1D811860229ED8C0072BB6F84 /* LongitudinalStrip.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LongitudinalStrip.swift; path = "mgrs-ios/gzd/LongitudinalStrip.swift"; sourceTree = ""; }; + F08EDF875F45F6F05DAA577FA13BD612 /* SFGeometry.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFGeometry.m; path = "sf-ios/SFGeometry.m"; sourceTree = ""; }; + F15D2E1A619B2F2B360124EAC98D3051 /* SFPolygon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFPolygon.h; path = "sf-ios/SFPolygon.h"; sourceTree = ""; }; + F2B3F1E103283BBF6AE1AD3F21AFAFAA /* Pods-TAKTracker-TAKTrackerTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TAKTracker-TAKTrackerTests-dummy.m"; sourceTree = ""; }; + F389AFCA8100D47A138EEFC50343EF98 /* mgrs-ios-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "mgrs-ios-dummy.m"; sourceTree = ""; }; + F39EA9BF5EE5B05ACF23EE24D29895B3 /* SFLineString.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SFLineString.h; path = "sf-ios/SFLineString.h"; sourceTree = ""; }; + F3C55B46709D88246CAD4116FE38617D /* mgrs-ios-mgrs-ios */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = "mgrs-ios-mgrs-ios"; path = "mgrs-ios.bundle"; sourceTree = BUILT_PRODUCTS_DIR; }; + F3EDF6D2E962047A3C2009AEAE795218 /* SFPolyhedralSurface.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFPolyhedralSurface.m; path = "sf-ios/SFPolyhedralSurface.m"; sourceTree = ""; }; + F9AC01D61B807E620F86FF04553A7E22 /* SFCentroidCurve.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SFCentroidCurve.m; path = "sf-ios/util/centroid/SFCentroidCurve.m"; sourceTree = ""; }; + FAFEE98C191B783F8D38CE278995BB54 /* ZoneNumberRange.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ZoneNumberRange.swift; path = "mgrs-ios/gzd/ZoneNumberRange.swift"; sourceTree = ""; }; + FB5C0F22631A441A3AAA6E76A6C87836 /* Pods-TAKTracker-TAKTrackerTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TAKTracker-TAKTrackerTests-umbrella.h"; sourceTree = ""; }; + FBBAF7EC67C3701545D97F90DAF0181D /* mgrs-ios-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "mgrs-ios-prefix.pch"; sourceTree = ""; }; + FE564BBC2CEB4C56B515192A559DEA51 /* Pods-TAKTracker-TAKTrackerTests-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TAKTracker-TAKTrackerTests-Info.plist"; sourceTree = ""; }; + FEA04A00723B024B82E2BE6552BBE7D4 /* Grids.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Grids.swift; path = "mgrs-ios/grid/Grids.swift"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 0443C9B1523B9AE431B3BE4BBC474FBA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 023B6A92AA418BF179DCD89C3432D21B /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3AFA87906F1B606FC83D0A13EF6ECC71 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5C1D095DB70CFC467C2D49D1260472BF /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6308171C03AEF1CDA84E20E11290150A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CD7C88F27F98E1D9D6FE102DA5EABB69 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C097081D1FF513514B88F3881164333E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CADA2601EAA2068C3187325E4781B24E /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C13B6A24A42C76F264E1B2425722B05F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E22456102F0ECC1CFC7E8BDF8C02CFD4 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D8B41C70B6573A19AA0DF5D423643549 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 09A55B5B12C8F97AD7A9F4A5E4DC98C4 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E56CF42C1BFAECCD56E15B543F2F1364 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1905B00953440D8C51C6E44D9D4A60C6 /* Support Files */ = { + isa = PBXGroup; + children = ( + E6838AFF78B2AE0E46AB69727ECAA884 /* grid-ios.modulemap */, + 069CFF7B43BA7459DDE7C404C143433E /* grid-ios-dummy.m */, + CF4CB5075D3B4C81C5E865EDE12A1C28 /* grid-ios-Info.plist */, + 8EC140AAED4A59F5712E30903769C415 /* grid-ios-prefix.pch */, + 4876E252C69826AC93D26C995DB564A4 /* grid-ios-umbrella.h */, + 663C73DDDC517802F4DAE8E3BA5D2167 /* grid-ios.debug.xcconfig */, + D5FCE36CEC5EB6ECBCC39E71F2E05AC4 /* grid-ios.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/grid-ios"; + sourceTree = ""; + }; + 237D90EB353C559BA65113A4D0C2208C /* grid-ios */ = { + isa = PBXGroup; + children = ( + 7874A44F81E440BAC9758119CD3156DA /* BaseGrid.swift */, + 3FCE035B2EBA1E24D020924CABFD59DF /* BaseGrids.swift */, + 2F97C8CE346DDCF07EE3F169C6B7DB06 /* BaseZoomGrids.swift */, + 2EB862483347246602E51E31B1672A17 /* Bounds.swift */, + E27639AB3E5EDFB5C68BEDB3362F4401 /* GridConstants.swift */, + E65E11BF4833C38B18D081EEE90CCA02 /* GridPoint.swift */, + 9716780C3D43D1339FC7B18EC5ED2233 /* GridProperties.swift */, + B1DB673288284B00CF39D90C5394CC09 /* GridStyle.swift */, + B5E2268B4DA732BBC9B37AA10B923B43 /* GridTile.swift */, + 5C28424481CE8A0A6B868B0DCFDEF48A /* GridUtils.swift */, + 3CA0ACD3CEF47962069826A7DA81A2D9 /* Hemisphere.swift */, + 7313130C1987E342AC69ADF16091DB3D /* Label.swift */, + 44199CB6497D763F64EA56E4CB675094 /* Labeler.swift */, + 6B14AEE13923842FE76AA062F3961BFC /* Line.swift */, + 3188BF3FFF7A26DB5CEBD202CECCBD36 /* Pixel.swift */, + 023DA3166A0D28C4202C6C0C70B9F68A /* PixelRange.swift */, + 3243D50FEEEF0AA58FCBDA9037733C95 /* PropertyConstants.swift */, + 77947688E6969089695B2CE6EAF25AC9 /* TileDraw.swift */, + C0038CB601C3E78C41757D3B76D9233F /* TileUtils.swift */, + 81AC2DC77BEA1280D97530A4D94D6B4F /* Unit.swift */, + 1905B00953440D8C51C6E44D9D4A60C6 /* Support Files */, + ); + name = "grid-ios"; + path = "grid-ios"; + sourceTree = ""; + }; + 40E871020383161C55A9EF703069213C /* mgrs-ios */ = { + isa = PBXGroup; + children = ( + E430F83CF0FB1A101EB50408F8E0CB1C /* BandLetterRange.swift */, + 57A69667D76341A8D69E0FC97BFD81F8 /* Grid.swift */, + E66FC9607D8ED810ABE9565E229680C8 /* GridLabel.swift */, + E56B4688749ADDF7AC9988F47575DC68 /* GridLabeler.swift */, + 0059E54790BE84D69AD979ADE254085F /* GridRange.swift */, + FEA04A00723B024B82E2BE6552BBE7D4 /* Grids.swift */, + 1A6F1DA8E32F7FCADAADECB83DD0A589 /* GridType.swift */, + BE19EED15D25BF0CADC9B3C5A04E8A0B /* GridZone.swift */, + D20CF66FDB03CF7513BE322D53EA7A8E /* GridZones.swift */, + ADF51B735731FC1640FFA8E53BB0FE7F /* GZDLabeler.swift */, + 06203B66AFC188A6DAD8AB31800410A8 /* LatitudeBand.swift */, + F075E3F1D811860229ED8C0072BB6F84 /* LongitudinalStrip.swift */, + 85B441B11CBE4AF8D1E105AF04473653 /* MGRS.swift */, + 519EFC06EF426F8AC40C818C658518C5 /* MGRSConstants.swift */, + 6B2604DF0685BC3BD832C3BC77629C88 /* MGRSLabeler.swift */, + 614E4DC7FCBCFBF1AB99EB35E18147F6 /* MGRSLine.swift */, + D8CAE1273786EF26500A13DD4E478CFA /* MGRSProperties.swift */, + 745062C814B6822E3B0AB0BF84084A9E /* MGRSTileOverlay.swift */, + 5D012EE976AFA7F4AF6209DF9310D290 /* MGRSUtils.swift */, + BBA0A6FE8CD4B179D459AC44C23D2344 /* UTM.swift */, + FAFEE98C191B783F8D38CE278995BB54 /* ZoneNumberRange.swift */, + 83938DA3BEFB6935725749F99E153865 /* ZoomGrids.swift */, + 7E5CB85025787D52ED52C39CD46D349D /* Resources */, + AC0E7BF3FB86C37094AE26C0875BEFBA /* Support Files */, + ); + name = "mgrs-ios"; + path = "mgrs-ios"; + sourceTree = ""; + }; + 487431FECFE54FC71ED5B8C251CCDC7B /* Pods-TAKTracker-TAKTrackerTests */ = { + isa = PBXGroup; + children = ( + BFE44A74E81D258D43BB588B958D14FC /* Pods-TAKTracker-TAKTrackerTests.modulemap */, + AC441E0CCA300B10B61526D8882F0475 /* Pods-TAKTracker-TAKTrackerTests-acknowledgements.markdown */, + A7C9A3A6996DA4888EC230C2771D1EBC /* Pods-TAKTracker-TAKTrackerTests-acknowledgements.plist */, + F2B3F1E103283BBF6AE1AD3F21AFAFAA /* Pods-TAKTracker-TAKTrackerTests-dummy.m */, + C199554CD3554B4968A8F7259C630DA8 /* Pods-TAKTracker-TAKTrackerTests-frameworks.sh */, + FE564BBC2CEB4C56B515192A559DEA51 /* Pods-TAKTracker-TAKTrackerTests-Info.plist */, + FB5C0F22631A441A3AAA6E76A6C87836 /* Pods-TAKTracker-TAKTrackerTests-umbrella.h */, + 9D31CEE8BD52C5C0BD08FC7F3D9E9257 /* Pods-TAKTracker-TAKTrackerTests.debug.xcconfig */, + AEDE3F2148291E06268235146C8D4F1B /* Pods-TAKTracker-TAKTrackerTests.release.xcconfig */, + ); + name = "Pods-TAKTracker-TAKTrackerTests"; + path = "Target Support Files/Pods-TAKTracker-TAKTrackerTests"; + sourceTree = ""; + }; + 55BB9E49B32063886EE0A4E31449AD47 /* Pods-TAKTracker */ = { + isa = PBXGroup; + children = ( + BF00186B3E3031ACB739D50A86CD8B5A /* Pods-TAKTracker.modulemap */, + 5F5CA0BA5BF886F174396918B4A6FF68 /* Pods-TAKTracker-acknowledgements.markdown */, + 6808C4820AAF7EDCA945DC4E43C42FDA /* Pods-TAKTracker-acknowledgements.plist */, + 92657D4891B16DB9A760A2CACAB21B5D /* Pods-TAKTracker-dummy.m */, + 9912976AE55386F8962DE76F6C738746 /* Pods-TAKTracker-frameworks.sh */, + DAFDB1F24C2EAD375521FE67433827B8 /* Pods-TAKTracker-Info.plist */, + DA5A5A76709FE146F3DADA8D075E9BA2 /* Pods-TAKTracker-umbrella.h */, + 0894E95C0890A27CB27EE722440C3E15 /* Pods-TAKTracker.debug.xcconfig */, + 500FF3361BF5F512BBC1567F56848F83 /* Pods-TAKTracker.release.xcconfig */, + ); + name = "Pods-TAKTracker"; + path = "Target Support Files/Pods-TAKTracker"; + sourceTree = ""; + }; + 578452D2E740E91742655AC8F1636D1F /* iOS */ = { + isa = PBXGroup; + children = ( + 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */, + ); + name = iOS; + sourceTree = ""; + }; + 5942738BDCDEE7566D643B3CB79841B6 /* Pods */ = { + isa = PBXGroup; + children = ( + A604AFF07916E4C28E64106739ED0D27 /* color-ios */, + 237D90EB353C559BA65113A4D0C2208C /* grid-ios */, + 40E871020383161C55A9EF703069213C /* mgrs-ios */, + 723A55B7C95F7B398E39638AC37039F4 /* sf-ios */, + ); + name = Pods; + sourceTree = ""; + }; + 5FA7FA848B7CA227A5B84BDF30D3E0F5 /* Products */ = { + isa = PBXGroup; + children = ( + 6701E1E7881E37B884FEEA9B3F803E0B /* color-ios */, + 7EE66363A245AC8A4B45D95E5CEC6B09 /* grid-ios */, + C1D37DBF2B7B7BCE0213BC0468DA7AB5 /* mgrs-ios */, + F3C55B46709D88246CAD4116FE38617D /* mgrs-ios-mgrs-ios */, + C784F19CB8F1F6BFB2768B8D8C62D136 /* Pods-TAKTracker */, + 487DDF25A56AFBBDE95A6A50CD438336 /* Pods-TAKTracker-TAKTrackerTests */, + D57C1FAB77A663260850740EEB9C3590 /* sf-ios */, + ); + name = Products; + sourceTree = ""; + }; + 5FB02F906F212F4182A69889F9F45CBD /* Support Files */ = { + isa = PBXGroup; + children = ( + 16A3E2FB923722F098638604FB7EDE7B /* color-ios.modulemap */, + A285519FAD68A4B91EF421B349AEB9D9 /* color-ios-dummy.m */, + 82D03984775AF1EF6A96680E12E265B0 /* color-ios-Info.plist */, + 3C6F396086EA9EAEC1052CF1B0E8D0BD /* color-ios-prefix.pch */, + 227C7AAAC00962177108BF75AD2A281F /* color-ios-umbrella.h */, + D568030E05D091C56309AF39466B9771 /* color-ios.debug.xcconfig */, + B6CD63F50A987FC9D3C394C510C654E5 /* color-ios.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/color-ios"; + sourceTree = ""; + }; + 63A0D987D61F6CDB9D1CE57B2AC88ADE /* Support Files */ = { + isa = PBXGroup; + children = ( + 7270B776073BDF7F886F410375A2468D /* sf-ios.modulemap */, + 32DCF4DE8312F64B0CF3AE04DD81FAD9 /* sf-ios-dummy.m */, + 4030261639065FB6E758E20B46AD84BC /* sf-ios-Info.plist */, + 4335711A79C8B9F2C44CCEC7DA2F7256 /* sf-ios-prefix.pch */, + C33A35A825DAC697493A517F8D23C455 /* sf-ios-umbrella.h */, + 65D7E8FDA268069E4DBE471FD4B51C43 /* sf-ios.debug.xcconfig */, + 61300EDB21C649EB201A2B745D3D2EE7 /* sf-ios.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/sf-ios"; + sourceTree = ""; + }; + 723A55B7C95F7B398E39638AC37039F4 /* sf-ios */ = { + isa = PBXGroup; + children = ( + DF664E3F9DAB8D9C8257C16A493BAA1E /* sf-ios-Bridging-Header.h */, + 3FFB31884F86F64238B17527FE10DB62 /* sf_ios.h */, + DD2D26A77DB958E7CEAEDEA102EB0B9C /* SFByteReader.h */, + 684EBC6DFA0FFDE2E145ADE8EE2CEF9D /* SFByteReader.m */, + 3A7924890AF51FC698FDC4BA555F8203 /* SFByteWriter.h */, + AF480DCB19D1E9B5BA62A83199AF81F8 /* SFByteWriter.m */, + E62B92847D5C6C4EE2059D7C20A2BF58 /* SFCentroidCurve.h */, + F9AC01D61B807E620F86FF04553A7E22 /* SFCentroidCurve.m */, + 7A1CFE976EEBFC3B285E36AAEF90C0DA /* SFCentroidPoint.h */, + D2BD9093CC836E72F46BAB2083FFAEEC /* SFCentroidPoint.m */, + 4F200FC096E28386D09EDFAEAFB92FE2 /* SFCentroidSurface.h */, + 20E9140136FCFC5180C5DB8560B389CE /* SFCentroidSurface.m */, + 59075292CE1938FB375C16B89BF274E7 /* SFCircularString.h */, + DCE023898F386905A91529F1767ACBCC /* SFCircularString.m */, + 9BF125EC77C10CFFE724AB465DBEF5E7 /* SFCompoundCurve.h */, + E3DF9B5CBF0D7628C48F436A93CFD1DE /* SFCompoundCurve.m */, + AE54A558ADF6D24D5B574F99C9DC4242 /* SFCurve.h */, + EA45EEA7958D8FBA57D574798993A122 /* SFCurve.m */, + 82E900BF27CD52A05EDC4212E2C1B5A0 /* SFCurvePolygon.h */, + E4BF99730F9B069C1683F0F653E57950 /* SFCurvePolygon.m */, + 951F07FBF3A71F6BF1BE5D46496C09B4 /* SFDegreesCentroid.h */, + E78DEACAED1651147C3138A3C387A819 /* SFDegreesCentroid.m */, + 4B893DB37D9F9BD4589F99C5E3099B42 /* SFEvent.h */, + B9A67935C386EE102ECA25199A7CA64F /* SFEvent.m */, + 9F6EB542086BD931C888EE2394148556 /* SFEventQueue.h */, + 35F014EC7FAFEDD1FD2BC06705152166 /* SFEventQueue.m */, + 0FF3776E7D2B4FB9DCCF8754FBBC0968 /* SFEventTypes.h */, + 34DB0CB350ADC3E8182E69C445536CD5 /* SFEventTypes.m */, + 8B452511DBDAF5420CBB798B10651D74 /* SFExtendedGeometryCollection.h */, + ED9A6DEDF060D707D58AE0AE9D2F5949 /* SFExtendedGeometryCollection.m */, + 7412B9AC933AB40511AC70B9B83E44C7 /* SFFiniteFilterTypes.h */, + 812AFFB5750766A63544908B43017FE7 /* SFFiniteFilterTypes.m */, + 7BC2C4FEAE7B1010D93F1747B4E6BB47 /* SFGeometry.h */, + F08EDF875F45F6F05DAA577FA13BD612 /* SFGeometry.m */, + 28621C8035DA87D89A8A2B187EF98A12 /* SFGeometryCollection.h */, + E2609AC25973D169691399F3034F8C45 /* SFGeometryCollection.m */, + 2DFF9DB321426B8017B1228290F3AAB5 /* SFGeometryConstants.h */, + 45EDE46C074CBF3E3C6844B4FD831B49 /* SFGeometryConstants.m */, + 0F5B469490FCAA1B343E671F023A4601 /* SFGeometryEnvelope.h */, + 84AEC61DCB8D681446EC274B37E177C7 /* SFGeometryEnvelope.m */, + B2B7CF69670153E3A5E66EDAFE73F986 /* SFGeometryEnvelopeBuilder.h */, + AE65D7763433AC19571DEB36D6C83382 /* SFGeometryEnvelopeBuilder.m */, + 18A7B13EE54A4BC21C570D2272B52641 /* SFGeometryFilter.h */, + BE4FE0A48BC1665780534BB195F72F06 /* SFGeometryPrinter.h */, + 92FF470E4F1B25D8F608830CA5349553 /* SFGeometryPrinter.m */, + 71813FA652DFA5A20023C050E554547F /* SFGeometryTypes.h */, + 3F9275398D56434E1B4E7F9AEF17F84A /* SFGeometryTypes.m */, + 400F91DA42E6FC7C22FE3F06D34AA353 /* SFGeometryUtils.h */, + 32323DCD7ED9B830CD0092ADA15048D9 /* SFGeometryUtils.m */, + CD338F8209C92757C6B886A7D5C12FD9 /* SFLine.h */, + 3A4D194D9A6DAE1A91AD99CE4929EE9D /* SFLine.m */, + CFB4CED1A185DF0BD9E8CB853E35D10A /* SFLinearRing.h */, + 4FFF5393EA951873D1A95226E5C54A29 /* SFLinearRing.m */, + F39EA9BF5EE5B05ACF23EE24D29895B3 /* SFLineString.h */, + 46FAD3DD8438C6C2AE7D2DBE9BBAAD91 /* SFLineString.m */, + 03943E94A1C99BFA9457B8F632CD7B01 /* SFMultiCurve.h */, + 77AB54852F23C634C09A6DEBEC793E4D /* SFMultiCurve.m */, + D3ACFE5C52409F1F3838413D0BE0A0ED /* SFMultiLineString.h */, + 290D43FF8A536D340A0768C91F6100C0 /* SFMultiLineString.m */, + 2E4DEEEDE538673CA7C5898930DF1107 /* SFMultiPoint.h */, + 2DC2B5D322035FCF210E33EF2A14FD88 /* SFMultiPoint.m */, + A1F34BA5218CED0EB4EC1ADC65FA96CB /* SFMultiPolygon.h */, + 2CAA0B3C0128A4A471AC3A01501CC604 /* SFMultiPolygon.m */, + B29C44830FBB834CBB0A1947FE188EFE /* SFMultiSurface.h */, + 1FDD7A8AF9BD4A6F04C55146B97B851E /* SFMultiSurface.m */, + BC518689A7A47FD476B1D6CE52A93481 /* SFPoint.h */, + AD95786446785A780D3D0B2BBBA6E805 /* SFPoint.m */, + B8E90925ACED35EF26688DC909BF9AF5 /* SFPointFiniteFilter.h */, + B10D2636A8F752C00B34BD04F83FF39E /* SFPointFiniteFilter.m */, + F15D2E1A619B2F2B360124EAC98D3051 /* SFPolygon.h */, + 564541973760DAF89844D15379F26DB9 /* SFPolygon.m */, + 125F8B13569BE402D8E2C259ADAAB66F /* SFPolyhedralSurface.h */, + F3EDF6D2E962047A3C2009AEAE795218 /* SFPolyhedralSurface.m */, + DC3BEB53F37F4E4A6E6881AEF5E5CD96 /* SFSegment.h */, + 0A8672C317E1B2F31B285ED1D844E8D7 /* SFSegment.m */, + 1113AEB5317A5C730AF2E5E9BE675A27 /* SFShamosHoey.h */, + 4D410E4F6B59F78F8AEF5F2BB42EB2F0 /* SFShamosHoey.m */, + AC1B528E9D3CF87CCECE5D5025B6B77F /* SFSurface.h */, + 891086E5D78592128EB4829E5ED1C607 /* SFSurface.m */, + 1C75A5D9330CC221D70D0D70068C2F74 /* SFSweepLine.h */, + 774DB00815D3CAB2F00CEE49CADA14AF /* SFSweepLine.m */, + 31932A4DAB4F160BFB79EBE8A8391471 /* SFTextReader.h */, + B3FDD43CE01C21257235D709E637CA23 /* SFTextReader.m */, + DD70F1CD97D9E83C30A00C26579A125A /* SFTIN.h */, + DEBA3DA768B7114FD90DE29E628D8502 /* SFTIN.m */, + D88EF2992992020D850AE6B957799B4D /* SFTriangle.h */, + 1B3EDB3F6C36DC0596E30D4B9C4B9077 /* SFTriangle.m */, + 63A0D987D61F6CDB9D1CE57B2AC88ADE /* Support Files */, + ); + name = "sf-ios"; + path = "sf-ios"; + sourceTree = ""; + }; + 75C797F28B5DEF94462D832C73756CC4 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + 55BB9E49B32063886EE0A4E31449AD47 /* Pods-TAKTracker */, + 487431FECFE54FC71ED5B8C251CCDC7B /* Pods-TAKTracker-TAKTrackerTests */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 7E5CB85025787D52ED52C39CD46D349D /* Resources */ = { + isa = PBXGroup; + children = ( + A6B717F198BFC1E490565769FCF09C8C /* mgrs.plist */, + ); + name = Resources; + sourceTree = ""; + }; + A604AFF07916E4C28E64106739ED0D27 /* color-ios */ = { + isa = PBXGroup; + children = ( + BDB1652DF414492116E57A6DCDFE5638 /* CLRColor.h */, + 7A6EE4E33BC33969C2E18DCE42A4AFBE /* CLRColor.m */, + 0BD7CF883331619E55A228A609D5B4FC /* CLRColorConstants.h */, + CFCD2C92AF6B4622C9CFC8ED1A1A1BB6 /* CLRColorConstants.m */, + C5B7341D5D21DEBB1E948B31E5483AEC /* CLRColorUtils.h */, + B671FDAAB743C4A7A52731BA988B470F /* CLRColorUtils.m */, + 6F14634AB5D2F308AED53764F7CF3110 /* color-ios-Bridging-Header.h */, + 271FE6CD6C70D881EC77AD64E8071CD8 /* color_ios.h */, + 5FB02F906F212F4182A69889F9F45CBD /* Support Files */, + ); + name = "color-ios"; + path = "color-ios"; + sourceTree = ""; + }; + AC0E7BF3FB86C37094AE26C0875BEFBA /* Support Files */ = { + isa = PBXGroup; + children = ( + C8FB3FFB026BA83BAD3A19C9728B7104 /* mgrs-ios.modulemap */, + F389AFCA8100D47A138EEFC50343EF98 /* mgrs-ios-dummy.m */, + 70361BBB0CD461A2B88827416F8B3D75 /* mgrs-ios-Info.plist */, + FBBAF7EC67C3701545D97F90DAF0181D /* mgrs-ios-prefix.pch */, + 907D7CCB83DA375467750C89CA1B8726 /* mgrs-ios-umbrella.h */, + 0F5CB11B2BADDF906FFAFA890F456CE2 /* mgrs-ios.debug.xcconfig */, + 2660C7AFBBC2D87AB2FE6D0563716923 /* mgrs-ios.release.xcconfig */, + BE4B520CD9BD34295645E90C1D7675ED /* ResourceBundle-mgrs-ios-mgrs-ios-Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/mgrs-ios"; + sourceTree = ""; + }; + CF1408CF629C7361332E53B88F7BD30C = { + isa = PBXGroup; + children = ( + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, + D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */, + 5942738BDCDEE7566D643B3CB79841B6 /* Pods */, + 5FA7FA848B7CA227A5B84BDF30D3E0F5 /* Products */, + 75C797F28B5DEF94462D832C73756CC4 /* Targets Support Files */, + ); + sourceTree = ""; + }; + D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 578452D2E740E91742655AC8F1636D1F /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 4057A75C8A4C0FE2C3D31A4125B774E4 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 6237D17F94DAFD71C873EF84725A63E5 /* Pods-TAKTracker-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 52A0504B8B0BE050528F200E506FDD95 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 64909F0D34050F9337AA5D9EBCB91866 /* sf-ios-Bridging-Header.h in Headers */, + 990A5FCE56D34701ED0B1F4FC5732286 /* sf-ios-umbrella.h in Headers */, + D2010CA20405CD2A3732AAA7BAA00FA0 /* sf_ios.h in Headers */, + 357C97B40448E6D0796FD6E50B3FC37D /* SFByteReader.h in Headers */, + 2529DBFC6D7F8A5C2223025BC04F19C7 /* SFByteWriter.h in Headers */, + A93701B9BD555583EFFFA7C8A4BBBC32 /* SFCentroidCurve.h in Headers */, + 7BDBE294B8E37DACFB2A3CC11E36B474 /* SFCentroidPoint.h in Headers */, + 40B0D84C70D2A91336BA9BE6812F1907 /* SFCentroidSurface.h in Headers */, + D3F13422D83C27C47FE24B2B7927DB34 /* SFCircularString.h in Headers */, + DDB3C0D281907A9677CDFD87A5579DBB /* SFCompoundCurve.h in Headers */, + 6B5A3FCF2A85991D83DE4B91C8EF94BB /* SFCurve.h in Headers */, + 5162CC563DB7C40556F7A3BD47A6D729 /* SFCurvePolygon.h in Headers */, + AD8C9C36F0AA8257A1C23D2547CCF8EE /* SFDegreesCentroid.h in Headers */, + A6046769D45D10FA4428712EA0D85881 /* SFEvent.h in Headers */, + 2393BAE200B3EEC1FA10FB24D06242C8 /* SFEventQueue.h in Headers */, + 18BFF2E239D0B1D9185EB96608E12D7E /* SFEventTypes.h in Headers */, + 3460722D8AB9B7B5492A2F71D52A2635 /* SFExtendedGeometryCollection.h in Headers */, + 9C7ABCDEDF00ADE6D09E5280E1949D96 /* SFFiniteFilterTypes.h in Headers */, + 7900FB4C393C1450079977D3C2415D57 /* SFGeometry.h in Headers */, + 21903FB8A17A7598FCBE8D2F4D1CA0BE /* SFGeometryCollection.h in Headers */, + 441868A71789DE750628E4049B68C1B5 /* SFGeometryConstants.h in Headers */, + D6E316C5261E3521DF26C41224CBEAAB /* SFGeometryEnvelope.h in Headers */, + A9953A9C364C5785061E35D13E1DDE9E /* SFGeometryEnvelopeBuilder.h in Headers */, + FB417D91B5E2AF28BE667B217E060A5C /* SFGeometryFilter.h in Headers */, + 8ABF748E99B2D156FBE63D67D56BD2D4 /* SFGeometryPrinter.h in Headers */, + C83F587DC28A1AB00D96D3A63F41E8CA /* SFGeometryTypes.h in Headers */, + 27805EB07D85C9E0D83B18CA0ADB2480 /* SFGeometryUtils.h in Headers */, + 985F593E1D8188ACCD22A09C30E1782E /* SFLine.h in Headers */, + 9A607F3DDB4BEA8548A2D427E1A3A408 /* SFLinearRing.h in Headers */, + CA70C6033B0236EA356CF545F6FBF902 /* SFLineString.h in Headers */, + E060AD3B694BEDAFA5B5395BC2D52805 /* SFMultiCurve.h in Headers */, + A5B5C387B6AC85CF40057BCCD1716C0D /* SFMultiLineString.h in Headers */, + 55B8CD797D15B06F6DEDE3942C531909 /* SFMultiPoint.h in Headers */, + C185114905B3BD1C7E3030807794FAF8 /* SFMultiPolygon.h in Headers */, + 2FD630B28BBEBA4BCBF16B2A4F0839BE /* SFMultiSurface.h in Headers */, + F05096E84B02ABA64A76FF3AC8482C45 /* SFPoint.h in Headers */, + D7BFE536C2B5007FDEBDCBDE23724038 /* SFPointFiniteFilter.h in Headers */, + 1EF5A466ACFC030D286EEC26D340A1C5 /* SFPolygon.h in Headers */, + CFD10A6078AE92707E4384B735A56A1E /* SFPolyhedralSurface.h in Headers */, + E12A603B4C1E9DD0C53E4DBEC19062AD /* SFSegment.h in Headers */, + EB718323DA2FB3B09B68405FBE2F2B0A /* SFShamosHoey.h in Headers */, + A0E521FEB9A172074CAFA62B36928BA1 /* SFSurface.h in Headers */, + 7D5233B65991E88DE0977460745DE72C /* SFSweepLine.h in Headers */, + A21A61C28C044618FE47ABFEE13775B2 /* SFTextReader.h in Headers */, + 8024C8311B04F3A5A45D3CF28D01DF45 /* SFTIN.h in Headers */, + C594ABC4AB985A512289A9036A83AE3F /* SFTriangle.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5E5C459FBCBC286333D4B05AADEAB6A3 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7AB45672E1B9BF48632144D30410BEE8 /* grid-ios-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6D18AF8FE1F54C23181291078980585B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 689B2DF51EECBC692E7C2507180E7696 /* CLRColor.h in Headers */, + 4FAEF057D06A2FE9452EC6402A646935 /* CLRColorConstants.h in Headers */, + 9A1CF5F77CBB50B95AB79D27214BF2FC /* CLRColorUtils.h in Headers */, + EF7FB19EC749C2AF91625156E43FDED4 /* color-ios-Bridging-Header.h in Headers */, + EF1C288D10C68E69DA5FCF9BFAB6F854 /* color-ios-umbrella.h in Headers */, + FBA0B6116F184AEE48111DCA56484F4F /* color_ios.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CB97EA8FA8A8BDA0F7CFF2CDC3BABE92 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + C1A99C38DE8AD8351521E2822380350D /* mgrs-ios-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D4EFA4D1CF2505801724D7B7E6DB1A78 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + DD65F2AE6A5A60EFFBB748D446FF7486 /* Pods-TAKTracker-TAKTrackerTests-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 3D3A419CC7A327DAABA72019D5CE9F57 /* sf-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = C5D498BD1D92FB2EB5EFE325F8024A20 /* Build configuration list for PBXNativeTarget "sf-ios" */; + buildPhases = ( + 52A0504B8B0BE050528F200E506FDD95 /* Headers */, + 6651D6A05B35BC947FDF89D906F66C34 /* Sources */, + C13B6A24A42C76F264E1B2425722B05F /* Frameworks */, + 330C9737A5F4F50B1441B85E4A9C8478 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "sf-ios"; + productName = sf_ios; + productReference = D57C1FAB77A663260850740EEB9C3590 /* sf-ios */; + productType = "com.apple.product-type.framework"; + }; + 4B6D9591FEA898A87D97798C55543161 /* Pods-TAKTracker */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0D30DAC03D7EDB95949FE36C616CAC65 /* Build configuration list for PBXNativeTarget "Pods-TAKTracker" */; + buildPhases = ( + 4057A75C8A4C0FE2C3D31A4125B774E4 /* Headers */, + 2DD9F6EF67BA6C7D1F62F8D42DD28EAD /* Sources */, + 3AFA87906F1B606FC83D0A13EF6ECC71 /* Frameworks */, + A7ECF257770467FB95080411A7FF620A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 7B10E22A5AAC19B211AEB7EFA3D3E7DF /* PBXTargetDependency */, + CE59983B29412F9519F0AA0AE5096F99 /* PBXTargetDependency */, + FEA965BD9FC2A559A091CDD47D636935 /* PBXTargetDependency */, + A0FC7DE45FFB888D6C98E322948D2370 /* PBXTargetDependency */, + ); + name = "Pods-TAKTracker"; + productName = Pods_TAKTracker; + productReference = C784F19CB8F1F6BFB2768B8D8C62D136 /* Pods-TAKTracker */; + productType = "com.apple.product-type.framework"; + }; + 577E91B04D12C328F76DD4B7C16DBAEF /* mgrs-ios-mgrs-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = C007DC12A477E284AF70FA16D7A76645 /* Build configuration list for PBXNativeTarget "mgrs-ios-mgrs-ios" */; + buildPhases = ( + E09348D9C1753CDFFC1DB8DD805D4EA9 /* Sources */, + E56CF42C1BFAECCD56E15B543F2F1364 /* Frameworks */, + F55FAD818918A0EC0FBCB1F8755B9A3E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "mgrs-ios-mgrs-ios"; + productName = "mgrs-ios"; + productReference = F3C55B46709D88246CAD4116FE38617D /* mgrs-ios-mgrs-ios */; + productType = "com.apple.product-type.bundle"; + }; + 5D942CA48BAB353546F6B788AC3EA195 /* color-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 00AD696AC94A97E80145F548E01C60F3 /* Build configuration list for PBXNativeTarget "color-ios" */; + buildPhases = ( + 6D18AF8FE1F54C23181291078980585B /* Headers */, + 8279E556FB47230EE33085B83D74CF4C /* Sources */, + 6308171C03AEF1CDA84E20E11290150A /* Frameworks */, + 19D8C2971D17447BD731219D87348310 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "color-ios"; + productName = color_ios; + productReference = 6701E1E7881E37B884FEEA9B3F803E0B /* color-ios */; + productType = "com.apple.product-type.framework"; + }; + 97F7D1D756E951FEF4A5FB093925DAA4 /* Pods-TAKTracker-TAKTrackerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 32F9D45FAFB6EB13958CF7588217BC2E /* Build configuration list for PBXNativeTarget "Pods-TAKTracker-TAKTrackerTests" */; + buildPhases = ( + D4EFA4D1CF2505801724D7B7E6DB1A78 /* Headers */, + AD0F788233EC4BB68CAFDE5FB64CBCC7 /* Sources */, + 0443C9B1523B9AE431B3BE4BBC474FBA /* Frameworks */, + 499A9A49B675CDAD53238DECFEDC57E7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + A3331FD8FF22ED4118C9313C4F3C0043 /* PBXTargetDependency */, + A4BC26DC65743B77ED8BE0E5BBA5CAD6 /* PBXTargetDependency */, + 814487F34492F5C5B72A6E9012EB9775 /* PBXTargetDependency */, + 43A30D3374287D05814D4EC9B10A2FAD /* PBXTargetDependency */, + ); + name = "Pods-TAKTracker-TAKTrackerTests"; + productName = Pods_TAKTracker_TAKTrackerTests; + productReference = 487DDF25A56AFBBDE95A6A50CD438336 /* Pods-TAKTracker-TAKTrackerTests */; + productType = "com.apple.product-type.framework"; + }; + F99C60B9711DB2529FC6C4FC9904B3F9 /* grid-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7B192E4F93DD72EAC4E2B74CB53EF40A /* Build configuration list for PBXNativeTarget "grid-ios" */; + buildPhases = ( + 5E5C459FBCBC286333D4B05AADEAB6A3 /* Headers */, + D4E6192BB99B53535D25211AF03EDDA2 /* Sources */, + C097081D1FF513514B88F3881164333E /* Frameworks */, + 95EE0D2B1261DD86C3C4BAC9ABA9EDDE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 6EB6667E11EA137C48B79BF3AFA5C274 /* PBXTargetDependency */, + F49F4CD05835AB2E295EA3E05CCFDF4B /* PBXTargetDependency */, + ); + name = "grid-ios"; + productName = grid_ios; + productReference = 7EE66363A245AC8A4B45D95E5CEC6B09 /* grid-ios */; + productType = "com.apple.product-type.framework"; + }; + FA341BB40DB010A6FF2E54DFC3D1E5D8 /* mgrs-ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = 50DCE2A6FA367D7E9B546A0504461FF5 /* Build configuration list for PBXNativeTarget "mgrs-ios" */; + buildPhases = ( + CB97EA8FA8A8BDA0F7CFF2CDC3BABE92 /* Headers */, + 30756DA618037CC18AD1198A4C438016 /* Sources */, + D8B41C70B6573A19AA0DF5D423643549 /* Frameworks */, + 5A43A87703E2F6D02B2F59253A9FDCAF /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 4EB511DF595EFECBE4DAF95CDCB6B388 /* PBXTargetDependency */, + 50FC18D97479F228C6CCC7F450B2778C /* PBXTargetDependency */, + ); + name = "mgrs-ios"; + productName = mgrs_ios; + productReference = C1D37DBF2B7B7BCE0213BC0468DA7AB5 /* mgrs-ios */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + BFDFE7DC352907FC980B868725387E98 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1500; + LastUpgradeCheck = 1500; + }; + buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + Base, + en, + ); + mainGroup = CF1408CF629C7361332E53B88F7BD30C; + productRefGroup = 5FA7FA848B7CA227A5B84BDF30D3E0F5 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 5D942CA48BAB353546F6B788AC3EA195 /* color-ios */, + F99C60B9711DB2529FC6C4FC9904B3F9 /* grid-ios */, + FA341BB40DB010A6FF2E54DFC3D1E5D8 /* mgrs-ios */, + 577E91B04D12C328F76DD4B7C16DBAEF /* mgrs-ios-mgrs-ios */, + 4B6D9591FEA898A87D97798C55543161 /* Pods-TAKTracker */, + 97F7D1D756E951FEF4A5FB093925DAA4 /* Pods-TAKTracker-TAKTrackerTests */, + 3D3A419CC7A327DAABA72019D5CE9F57 /* sf-ios */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 19D8C2971D17447BD731219D87348310 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 330C9737A5F4F50B1441B85E4A9C8478 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 499A9A49B675CDAD53238DECFEDC57E7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5A43A87703E2F6D02B2F59253A9FDCAF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4B8A895EECFCB0E14F31C9B854CA7283 /* mgrs-ios-mgrs-ios in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 95EE0D2B1261DD86C3C4BAC9ABA9EDDE /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A7ECF257770467FB95080411A7FF620A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F55FAD818918A0EC0FBCB1F8755B9A3E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A9CC986E40D14C54FE31268A4F77F7D5 /* mgrs.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2DD9F6EF67BA6C7D1F62F8D42DD28EAD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 54EAAB8901C3599E3BB17E356F1EC4BA /* Pods-TAKTracker-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 30756DA618037CC18AD1198A4C438016 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FF828B06B69B612AF17AE40C3149481C /* BandLetterRange.swift in Sources */, + 0D16C71CF738F3BBA2C63FEC24CBAE3F /* Grid.swift in Sources */, + 5F16E3EF1FAABDF6C5C1DDB451948919 /* GridLabel.swift in Sources */, + 4E9DB3A55799AD6A7BB6CABC2792DA9D /* GridLabeler.swift in Sources */, + 92AD7B6978B043A6D87647E147EE2763 /* GridRange.swift in Sources */, + 12C72C459546562A4C7A8D046B5BE963 /* Grids.swift in Sources */, + 504452CAC12585B620DE82B41AE2F0EF /* GridType.swift in Sources */, + 85033FED5CBFB7D24E7CAB85F76D7DED /* GridZone.swift in Sources */, + B9CE441CDCD318CB9A977B27705DE792 /* GridZones.swift in Sources */, + 5DEEDED84D1B4B01781E6DABA90EDF98 /* GZDLabeler.swift in Sources */, + 99D63002859B00ED49BE5D481965B751 /* LatitudeBand.swift in Sources */, + 071F303DFF627313B76DE65A777F15C1 /* LongitudinalStrip.swift in Sources */, + 8447B58BA06145AA077143850FFDDFD6 /* MGRS.swift in Sources */, + 7FA49CA3EDC298CA7C55C460F06B0DC2 /* mgrs-ios-dummy.m in Sources */, + 45FAE0AE275B0268A3A0AFF513BD46D1 /* MGRSConstants.swift in Sources */, + C58C3CBDFADC280064A3E6AC33A1BE85 /* MGRSLabeler.swift in Sources */, + B3D24A91D499AE8FA8686B61B67C8DE5 /* MGRSLine.swift in Sources */, + DDED62BD2C447F6C5E7297D20D697A1A /* MGRSProperties.swift in Sources */, + 58090A8C68FE54524677FD5B059D279B /* MGRSTileOverlay.swift in Sources */, + F74B1D2D126E49BB9B0FF8DA9CC05E63 /* MGRSUtils.swift in Sources */, + F84FCFCAC9BCAB72DD72486E6B8E7A68 /* UTM.swift in Sources */, + 067C7ED7510521BE277F755220E822C5 /* ZoneNumberRange.swift in Sources */, + E4FCEA16DE75F4A694D3726150FB3E93 /* ZoomGrids.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6651D6A05B35BC947FDF89D906F66C34 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 728724F5C466127FDB1028BDF3967D66 /* sf-ios-dummy.m in Sources */, + 0D613B084A281CFFE84AD258E78BCF46 /* SFByteReader.m in Sources */, + 75664AD0731FCA7F5CF05B0AF0C6E1EA /* SFByteWriter.m in Sources */, + FF53E26D8746E0EFEE73E7EBC06115C1 /* SFCentroidCurve.m in Sources */, + 7170630BAFBB1EDE838A1A12E85A76F8 /* SFCentroidPoint.m in Sources */, + AC01C60701C16C3FA2840CD916457A10 /* SFCentroidSurface.m in Sources */, + A7CE6C3CCF8202E05EF3F343B5FCE41C /* SFCircularString.m in Sources */, + B0A5D78F5B2F79AFE98D4AF98D8610E5 /* SFCompoundCurve.m in Sources */, + 43917DB945C7B0D7ADAD92DF8A1AE0D8 /* SFCurve.m in Sources */, + DD7720DA2C6F5945301B013F5939A9A7 /* SFCurvePolygon.m in Sources */, + 1D698A50DD3E699C98DBDB6069F55692 /* SFDegreesCentroid.m in Sources */, + 4D20A8913616CE13CCBF92EAE5CBA703 /* SFEvent.m in Sources */, + 0A7A071437788D2CD978AC14600164C4 /* SFEventQueue.m in Sources */, + A0CD1692DF3059ECF8AC5D1084B8FFD8 /* SFEventTypes.m in Sources */, + 334990EB900D463BE5872BBC3B5F3958 /* SFExtendedGeometryCollection.m in Sources */, + CB40FE6AC60EC5BB6FF4EAB06C112E87 /* SFFiniteFilterTypes.m in Sources */, + 1CE9DCE43EE4AD7049582C77ED9B8AA8 /* SFGeometry.m in Sources */, + 88C9C42049FF76699B4AEA2D808C9DF4 /* SFGeometryCollection.m in Sources */, + 11C8F47D1A8C14C2D7EBB896EDD5ABD0 /* SFGeometryConstants.m in Sources */, + 001F68F56A633058BF4BA7B66B76B71F /* SFGeometryEnvelope.m in Sources */, + 5C7B38DB5D67811CD288E23EC7E6AEE1 /* SFGeometryEnvelopeBuilder.m in Sources */, + F3357B9FCA92F8DAB22DD0FA79A561EC /* SFGeometryPrinter.m in Sources */, + 6BC65B2810FE7DB2E497A14CAED5C073 /* SFGeometryTypes.m in Sources */, + 345CA1488DECB422072705006D13346B /* SFGeometryUtils.m in Sources */, + C855782F17ECC25066916923DF7822D4 /* SFLine.m in Sources */, + 94125BE9C2D04C2400314FDCB37274EE /* SFLinearRing.m in Sources */, + C00DB75C81D8D19823B4E0BB955FE592 /* SFLineString.m in Sources */, + 77112F31BD9AE65246FE4854BCF0DA88 /* SFMultiCurve.m in Sources */, + 151C527DAC489E8572AC35ABC2906DD3 /* SFMultiLineString.m in Sources */, + 3641423CA329A8EE581EE79262B8A114 /* SFMultiPoint.m in Sources */, + 9DC9FC4ED00BD4E4E8B49CFD41484DDA /* SFMultiPolygon.m in Sources */, + 340A22AEEA4B642789E75D2D18E10799 /* SFMultiSurface.m in Sources */, + 6AAFEA4BDADEF8014A7D3DC9E6611F2C /* SFPoint.m in Sources */, + CD7F04E818114536D2C57D946B3C5DB3 /* SFPointFiniteFilter.m in Sources */, + D8DCE0CC793032CA3E70637A69047DC8 /* SFPolygon.m in Sources */, + 0E39041630EF2F1DBCFD440BA4382F37 /* SFPolyhedralSurface.m in Sources */, + 50276582786348FBA53DF53E1734ACBF /* SFSegment.m in Sources */, + 5C7E5B3EDE4E1B01D44A1A264E13DC41 /* SFShamosHoey.m in Sources */, + 4A916B1EC4FFB5029D417B3F8221C935 /* SFSurface.m in Sources */, + 14520EB15EE4C93038B8F8C08D801249 /* SFSweepLine.m in Sources */, + C5B5DCE9E4DD10638628100C1FE8A5C4 /* SFTextReader.m in Sources */, + F02E316A96C8263449A52ADE34EBF15A /* SFTIN.m in Sources */, + 1AC9C136DF9DC5C9A64F6ED3527450C6 /* SFTriangle.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8279E556FB47230EE33085B83D74CF4C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9199F3D813C5616AB348DC0D123B0A9A /* CLRColor.m in Sources */, + DF9D7D1FCFA243E6EFE52B9ADBAFF56D /* CLRColorConstants.m in Sources */, + AE7434CD15CBEFF4168F1B9A071887E2 /* CLRColorUtils.m in Sources */, + 0E48F269B264AC4DF3B3DC9E834251FC /* color-ios-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AD0F788233EC4BB68CAFDE5FB64CBCC7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7F7DD9882849C54605DED9DDB34F5782 /* Pods-TAKTracker-TAKTrackerTests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D4E6192BB99B53535D25211AF03EDDA2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7531B4F97700F1C84513A7A8B43C75FE /* BaseGrid.swift in Sources */, + 35A0D6930B1375D439168D1746877049 /* BaseGrids.swift in Sources */, + 04B3A6327E57113297E147F45AB86AC2 /* BaseZoomGrids.swift in Sources */, + 5E8C298257FC8FA288AB6E017CF94ADF /* Bounds.swift in Sources */, + D4A82FE97D097418A6D469327D543E5B /* grid-ios-dummy.m in Sources */, + D9A1DF495BF9773DD784205359712CC5 /* GridConstants.swift in Sources */, + 08A82D98A2958761B0C37502C499ECCC /* GridPoint.swift in Sources */, + CD58FCD440C3CB39746FC62196361E7C /* GridProperties.swift in Sources */, + 655B618AA7337F91593380D603986548 /* GridStyle.swift in Sources */, + B1BFDB9E4706D492A8052A8DCB2FBB3F /* GridTile.swift in Sources */, + 391601FB8693640EBE5D411023C746A9 /* GridUtils.swift in Sources */, + 06D18D87D8504AC2715A0863CCDAED96 /* Hemisphere.swift in Sources */, + F5DA2BD5458F7EA65CD2E599D35CC4F8 /* Label.swift in Sources */, + CA931BED8FFF97222F2E4C1DD002C117 /* Labeler.swift in Sources */, + EE12BDF6B07146DCE7D71A1FD9BB5C58 /* Line.swift in Sources */, + 5F657D10EC9C1F621FE145E6961CDBDA /* Pixel.swift in Sources */, + 4857891EB4E50C0313B47AAE82257B91 /* PixelRange.swift in Sources */, + 0A42D4949996376A528CC9DE5933FFED /* PropertyConstants.swift in Sources */, + 66AAA766D7293D6DE733D3C0DFD53472 /* TileDraw.swift in Sources */, + DE0812E35F28B6F0E1647226542ACC11 /* TileUtils.swift in Sources */, + 3CD803A89F48503EDFB120BF71FBE80E /* Unit.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E09348D9C1753CDFFC1DB8DD805D4EA9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 43A30D3374287D05814D4EC9B10A2FAD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "sf-ios"; + target = 3D3A419CC7A327DAABA72019D5CE9F57 /* sf-ios */; + targetProxy = 51E822EB846DD678032CF511C2D194D4 /* PBXContainerItemProxy */; + }; + 4EB511DF595EFECBE4DAF95CDCB6B388 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "grid-ios"; + target = F99C60B9711DB2529FC6C4FC9904B3F9 /* grid-ios */; + targetProxy = 416EBD680E4DC7D01C89A47357693AA7 /* PBXContainerItemProxy */; + }; + 50FC18D97479F228C6CCC7F450B2778C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "mgrs-ios-mgrs-ios"; + target = 577E91B04D12C328F76DD4B7C16DBAEF /* mgrs-ios-mgrs-ios */; + targetProxy = BC1A641CC3110E62E5DE83A0A7252F32 /* PBXContainerItemProxy */; + }; + 6EB6667E11EA137C48B79BF3AFA5C274 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "color-ios"; + target = 5D942CA48BAB353546F6B788AC3EA195 /* color-ios */; + targetProxy = D415627711DED532AAA0B6A36DCC5948 /* PBXContainerItemProxy */; + }; + 7B10E22A5AAC19B211AEB7EFA3D3E7DF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "color-ios"; + target = 5D942CA48BAB353546F6B788AC3EA195 /* color-ios */; + targetProxy = 14A5AAF358A1460F34DE9CCD243DBBA7 /* PBXContainerItemProxy */; + }; + 814487F34492F5C5B72A6E9012EB9775 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "mgrs-ios"; + target = FA341BB40DB010A6FF2E54DFC3D1E5D8 /* mgrs-ios */; + targetProxy = FC0BA8E95EAB6077B80B2BD277E70F20 /* PBXContainerItemProxy */; + }; + A0FC7DE45FFB888D6C98E322948D2370 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "sf-ios"; + target = 3D3A419CC7A327DAABA72019D5CE9F57 /* sf-ios */; + targetProxy = 93E2BBEF8CD4EB2D2B588892CB4A12AA /* PBXContainerItemProxy */; + }; + A3331FD8FF22ED4118C9313C4F3C0043 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "color-ios"; + target = 5D942CA48BAB353546F6B788AC3EA195 /* color-ios */; + targetProxy = B6A0CB8D262C7A709DAB014FD7B06778 /* PBXContainerItemProxy */; + }; + A4BC26DC65743B77ED8BE0E5BBA5CAD6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "grid-ios"; + target = F99C60B9711DB2529FC6C4FC9904B3F9 /* grid-ios */; + targetProxy = 27E0EDA9B6A89F8A568D38404519028B /* PBXContainerItemProxy */; + }; + CE59983B29412F9519F0AA0AE5096F99 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "grid-ios"; + target = F99C60B9711DB2529FC6C4FC9904B3F9 /* grid-ios */; + targetProxy = 802089AF3970F80C87B0F258B9AD5E12 /* PBXContainerItemProxy */; + }; + F49F4CD05835AB2E295EA3E05CCFDF4B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "sf-ios"; + target = 3D3A419CC7A327DAABA72019D5CE9F57 /* sf-ios */; + targetProxy = F174B54D03D29015D5379B9F2E91AC8B /* PBXContainerItemProxy */; + }; + FEA965BD9FC2A559A091CDD47D636935 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "mgrs-ios"; + target = FA341BB40DB010A6FF2E54DFC3D1E5D8 /* mgrs-ios */; + targetProxy = 62027A19ED0F1A46E0231A220C1FA062 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 058BC19F01515F675B67BBDB9BAED6AB /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0894E95C0890A27CB27EE722440C3E15 /* Pods-TAKTracker.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-TAKTracker/Pods-TAKTracker-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-TAKTracker/Pods-TAKTracker.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 07D3A460AEADBDD3FB639946FBF64422 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2660C7AFBBC2D87AB2FE6D0563716923 /* mgrs-ios.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/mgrs-ios/mgrs-ios-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/mgrs-ios/mgrs-ios-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/mgrs-ios/mgrs-ios.modulemap"; + PRODUCT_MODULE_NAME = mgrs_ios; + PRODUCT_NAME = mgrs_ios; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 121C10237A3BA5B60D86A56BB5B4DE4D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0F5CB11B2BADDF906FFAFA890F456CE2 /* mgrs-ios.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/mgrs-ios/mgrs-ios-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/mgrs-ios/mgrs-ios-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/mgrs-ios/mgrs-ios.modulemap"; + PRODUCT_MODULE_NAME = mgrs_ios; + PRODUCT_NAME = mgrs_ios; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 15CDB399EB6A6DD4F2699612A8FF2700 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 65D7E8FDA268069E4DBE471FD4B51C43 /* sf-ios.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/sf-ios/sf-ios-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/sf-ios/sf-ios-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/sf-ios/sf-ios.modulemap"; + PRODUCT_MODULE_NAME = sf_ios; + PRODUCT_NAME = sf_ios; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 17D6208215E2451594577DF432A57AA3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9D31CEE8BD52C5C0BD08FC7F3D9E9257 /* Pods-TAKTracker-TAKTrackerTests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 20972A24B48900AA1787DB57E9FE04AD /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2660C7AFBBC2D87AB2FE6D0563716923 /* mgrs-ios.release.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/mgrs-ios"; + IBSC_MODULE = mgrs_ios; + INFOPLIST_FILE = "Target Support Files/mgrs-ios/ResourceBundle-mgrs-ios-mgrs-ios-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = "mgrs-ios"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 45E34B1342CE39DF1DE9EFF8B4365D78 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AEDE3F2148291E06268235146C8D4F1B /* Pods-TAKTracker-TAKTrackerTests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 65933154FBBDD054A17F14FCBB87703E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D568030E05D091C56309AF39466B9771 /* color-ios.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/color-ios/color-ios-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/color-ios/color-ios-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/color-ios/color-ios.modulemap"; + PRODUCT_MODULE_NAME = color_ios; + PRODUCT_NAME = color_ios; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 7B6CF91ECDA707C852012550A3A8AE88 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0F5CB11B2BADDF906FFAFA890F456CE2 /* mgrs-ios.debug.xcconfig */; + buildSettings = { + CODE_SIGNING_ALLOWED = NO; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/mgrs-ios"; + IBSC_MODULE = mgrs_ios; + INFOPLIST_FILE = "Target Support Files/mgrs-ios/ResourceBundle-mgrs-ios-mgrs-ios-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + PRODUCT_NAME = "mgrs-ios"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + 8147F44FBE0512B52D8894A4B155EE47 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 500FF3361BF5F512BBC1567F56848F83 /* Pods-TAKTracker.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-TAKTracker/Pods-TAKTracker-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-TAKTracker/Pods-TAKTracker.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 90D4D09BCB6A4660E43ACBE9ECB6FE9A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + 9553C89E183877A5CB2F3C6801BEC129 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Release; + }; + AB801EB3D7B3F1C843153A4808FDAA38 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B6CD63F50A987FC9D3C394C510C654E5 /* color-ios.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/color-ios/color-ios-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/color-ios/color-ios-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/color-ios/color-ios.modulemap"; + PRODUCT_MODULE_NAME = color_ios; + PRODUCT_NAME = color_ios; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + B96F89FD9B49F4A9FECD637C773FF88A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 663C73DDDC517802F4DAE8E3BA5D2167 /* grid-ios.debug.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/grid-ios/grid-ios-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/grid-ios/grid-ios-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/grid-ios/grid-ios.modulemap"; + PRODUCT_MODULE_NAME = grid_ios; + PRODUCT_NAME = grid_ios; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + BED0DFD6B0B27004988071B7B398F902 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D5FCE36CEC5EB6ECBCC39E71F2E05AC4 /* grid-ios.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/grid-ios/grid-ios-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/grid-ios/grid-ios-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/grid-ios/grid-ios.modulemap"; + PRODUCT_MODULE_NAME = grid_ios; + PRODUCT_NAME = grid_ios; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + D60AB289726639A0FD8C8759B763EB8E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 61300EDB21C649EB201A2B745D3D2EE7 /* sf-ios.release.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/sf-ios/sf-ios-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/sf-ios/sf-ios-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/sf-ios/sf-ios.modulemap"; + PRODUCT_MODULE_NAME = sf_ios; + PRODUCT_NAME = sf_ios; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 00AD696AC94A97E80145F548E01C60F3 /* Build configuration list for PBXNativeTarget "color-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 65933154FBBDD054A17F14FCBB87703E /* Debug */, + AB801EB3D7B3F1C843153A4808FDAA38 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0D30DAC03D7EDB95949FE36C616CAC65 /* Build configuration list for PBXNativeTarget "Pods-TAKTracker" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 058BC19F01515F675B67BBDB9BAED6AB /* Debug */, + 8147F44FBE0512B52D8894A4B155EE47 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 32F9D45FAFB6EB13958CF7588217BC2E /* Build configuration list for PBXNativeTarget "Pods-TAKTracker-TAKTrackerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 17D6208215E2451594577DF432A57AA3 /* Debug */, + 45E34B1342CE39DF1DE9EFF8B4365D78 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 90D4D09BCB6A4660E43ACBE9ECB6FE9A /* Debug */, + 9553C89E183877A5CB2F3C6801BEC129 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 50DCE2A6FA367D7E9B546A0504461FF5 /* Build configuration list for PBXNativeTarget "mgrs-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 121C10237A3BA5B60D86A56BB5B4DE4D /* Debug */, + 07D3A460AEADBDD3FB639946FBF64422 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7B192E4F93DD72EAC4E2B74CB53EF40A /* Build configuration list for PBXNativeTarget "grid-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + B96F89FD9B49F4A9FECD637C773FF88A /* Debug */, + BED0DFD6B0B27004988071B7B398F902 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C007DC12A477E284AF70FA16D7A76645 /* Build configuration list for PBXNativeTarget "mgrs-ios-mgrs-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7B6CF91ECDA707C852012550A3A8AE88 /* Debug */, + 20972A24B48900AA1787DB57E9FE04AD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C5D498BD1D92FB2EB5EFE325F8024A20 /* Build configuration list for PBXNativeTarget "sf-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 15CDB399EB6A6DD4F2699612A8FF2700 /* Debug */, + D60AB289726639A0FD8C8759B763EB8E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; +} diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-Info.plist b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-Info.plist new file mode 100644 index 0000000..19cf209 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-acknowledgements.markdown b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-acknowledgements.markdown new file mode 100644 index 0000000..aec1c28 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-acknowledgements.markdown @@ -0,0 +1,103 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## color-ios + +MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## grid-ios + +MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## mgrs-ios + +MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## sf-ios + +The MIT License (MIT) + +Copyright (c) 2015 Bit Systems + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-acknowledgements.plist b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-acknowledgements.plist new file mode 100644 index 0000000..a0021d7 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-acknowledgements.plist @@ -0,0 +1,153 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + color-ios + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + grid-ios + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + mgrs-ios + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) + +Copyright (c) 2015 Bit Systems + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + sf-ios + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-dummy.m b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-dummy.m new file mode 100644 index 0000000..4931555 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_TAKTracker_TAKTrackerTests : NSObject +@end +@implementation PodsDummy_Pods_TAKTracker_TAKTrackerTests +@end diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Debug-input-files.xcfilelist b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Debug-input-files.xcfilelist new file mode 100644 index 0000000..bfd2f1c --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Debug-input-files.xcfilelist @@ -0,0 +1,5 @@ +${PODS_ROOT}/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks.sh +${BUILT_PRODUCTS_DIR}/color-ios/color_ios.framework +${BUILT_PRODUCTS_DIR}/grid-ios/grid_ios.framework +${BUILT_PRODUCTS_DIR}/mgrs-ios/mgrs_ios.framework +${BUILT_PRODUCTS_DIR}/sf-ios/sf_ios.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Debug-output-files.xcfilelist b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Debug-output-files.xcfilelist new file mode 100644 index 0000000..0f76ab6 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Debug-output-files.xcfilelist @@ -0,0 +1,4 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/color_ios.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/grid_ios.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/mgrs_ios.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sf_ios.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Release-input-files.xcfilelist b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Release-input-files.xcfilelist new file mode 100644 index 0000000..bfd2f1c --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Release-input-files.xcfilelist @@ -0,0 +1,5 @@ +${PODS_ROOT}/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks.sh +${BUILT_PRODUCTS_DIR}/color-ios/color_ios.framework +${BUILT_PRODUCTS_DIR}/grid-ios/grid_ios.framework +${BUILT_PRODUCTS_DIR}/mgrs-ios/mgrs_ios.framework +${BUILT_PRODUCTS_DIR}/sf-ios/sf_ios.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Release-output-files.xcfilelist b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Release-output-files.xcfilelist new file mode 100644 index 0000000..0f76ab6 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-Release-output-files.xcfilelist @@ -0,0 +1,4 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/color_ios.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/grid_ios.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/mgrs_ios.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sf_ios.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks.sh b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks.sh new file mode 100755 index 0000000..014fd22 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks.sh @@ -0,0 +1,192 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +BCSYMBOLMAP_DIR="BCSymbolMaps" + + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink -f "${source}")" + fi + + if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then + # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied + find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do + echo "Installing $f" + install_bcsymbolmap "$f" "$destination" + rm "$f" + done + rmdir "${source}/${BCSYMBOLMAP_DIR}" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + elif [ -L "${binary}" ]; then + echo "Destination binary is symlinked..." + dirname="$(dirname "${binary}")" + binary="${dirname}/$(readlink "${binary}")" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + warn_missing_arch=${2:-true} + if [ -r "$source" ]; then + # Copy the dSYM into the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .dSYM "$source")" + binary_name="$(ls "$source/Contents/Resources/DWARF")" + binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" + + # Strip invalid architectures from the dSYM. + if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then + strip_invalid_archs "$binary" "$warn_missing_arch" + fi + if [[ $STRIP_BINARY_RETVAL == 0 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + mkdir -p "${DWARF_DSYM_FOLDER_PATH}" + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" + fi + fi +} + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + warn_missing_arch=${2:-true} + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + if [[ "$warn_missing_arch" == "true" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + fi + STRIP_BINARY_RETVAL=1 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=0 +} + +# Copies the bcsymbolmap files of a vendored framework +install_bcsymbolmap() { + local bcsymbolmap_path="$1" + local destination="${BUILT_PRODUCTS_DIR}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/color-ios/color_ios.framework" + install_framework "${BUILT_PRODUCTS_DIR}/grid-ios/grid_ios.framework" + install_framework "${BUILT_PRODUCTS_DIR}/mgrs-ios/mgrs_ios.framework" + install_framework "${BUILT_PRODUCTS_DIR}/sf-ios/sf_ios.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/color-ios/color_ios.framework" + install_framework "${BUILT_PRODUCTS_DIR}/grid-ios/grid_ios.framework" + install_framework "${BUILT_PRODUCTS_DIR}/mgrs-ios/mgrs_ios.framework" + install_framework "${BUILT_PRODUCTS_DIR}/sf-ios/sf_ios.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-umbrella.h b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-umbrella.h new file mode 100644 index 0000000..794b3f8 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_TAKTracker_TAKTrackerTestsVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_TAKTracker_TAKTrackerTestsVersionString[]; + diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.debug.xcconfig b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.debug.xcconfig new file mode 100644 index 0000000..6add9c9 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.debug.xcconfig @@ -0,0 +1,15 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/color-ios" "${PODS_CONFIGURATION_BUILD_DIR}/grid-ios" "${PODS_CONFIGURATION_BUILD_DIR}/mgrs-ios" "${PODS_CONFIGURATION_BUILD_DIR}/sf-ios" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/color-ios/color_ios.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/grid-ios/grid_ios.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/mgrs-ios/mgrs_ios.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/sf-ios/sf_ios.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "color_ios" -framework "grid_ios" -framework "mgrs_ios" -framework "sf_ios" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.modulemap b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.modulemap new file mode 100644 index 0000000..71e92bf --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.modulemap @@ -0,0 +1,6 @@ +framework module Pods_TAKTracker_TAKTrackerTests { + umbrella header "Pods-TAKTracker-TAKTrackerTests-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.release.xcconfig b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.release.xcconfig new file mode 100644 index 0000000..6add9c9 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.release.xcconfig @@ -0,0 +1,15 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/color-ios" "${PODS_CONFIGURATION_BUILD_DIR}/grid-ios" "${PODS_CONFIGURATION_BUILD_DIR}/mgrs-ios" "${PODS_CONFIGURATION_BUILD_DIR}/sf-ios" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/color-ios/color_ios.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/grid-ios/grid_ios.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/mgrs-ios/mgrs_ios.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/sf-ios/sf_ios.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift "$(PLATFORM_DIR)/Developer/Library/Frameworks" '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "color_ios" -framework "grid_ios" -framework "mgrs_ios" -framework "sf_ios" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-Info.plist b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-Info.plist new file mode 100644 index 0000000..19cf209 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-acknowledgements.markdown b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-acknowledgements.markdown new file mode 100644 index 0000000..aec1c28 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-acknowledgements.markdown @@ -0,0 +1,103 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## color-ios + +MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## grid-ios + +MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## mgrs-ios + +MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## sf-ios + +The MIT License (MIT) + +Copyright (c) 2015 Bit Systems + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-acknowledgements.plist b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-acknowledgements.plist new file mode 100644 index 0000000..a0021d7 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-acknowledgements.plist @@ -0,0 +1,153 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + color-ios + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + grid-ios + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + mgrs-ios + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) + +Copyright (c) 2015 Bit Systems + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + sf-ios + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-dummy.m b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-dummy.m new file mode 100644 index 0000000..f020dc1 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_TAKTracker : NSObject +@end +@implementation PodsDummy_Pods_TAKTracker +@end diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Debug-input-files.xcfilelist b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Debug-input-files.xcfilelist new file mode 100644 index 0000000..b41158c --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Debug-input-files.xcfilelist @@ -0,0 +1,5 @@ +${PODS_ROOT}/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks.sh +${BUILT_PRODUCTS_DIR}/color-ios/color_ios.framework +${BUILT_PRODUCTS_DIR}/grid-ios/grid_ios.framework +${BUILT_PRODUCTS_DIR}/mgrs-ios/mgrs_ios.framework +${BUILT_PRODUCTS_DIR}/sf-ios/sf_ios.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Debug-output-files.xcfilelist b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Debug-output-files.xcfilelist new file mode 100644 index 0000000..0f76ab6 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Debug-output-files.xcfilelist @@ -0,0 +1,4 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/color_ios.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/grid_ios.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/mgrs_ios.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sf_ios.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Release-input-files.xcfilelist b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Release-input-files.xcfilelist new file mode 100644 index 0000000..b41158c --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Release-input-files.xcfilelist @@ -0,0 +1,5 @@ +${PODS_ROOT}/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks.sh +${BUILT_PRODUCTS_DIR}/color-ios/color_ios.framework +${BUILT_PRODUCTS_DIR}/grid-ios/grid_ios.framework +${BUILT_PRODUCTS_DIR}/mgrs-ios/mgrs_ios.framework +${BUILT_PRODUCTS_DIR}/sf-ios/sf_ios.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Release-output-files.xcfilelist b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Release-output-files.xcfilelist new file mode 100644 index 0000000..0f76ab6 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-Release-output-files.xcfilelist @@ -0,0 +1,4 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/color_ios.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/grid_ios.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/mgrs_ios.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sf_ios.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks.sh b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks.sh new file mode 100755 index 0000000..014fd22 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks.sh @@ -0,0 +1,192 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +BCSYMBOLMAP_DIR="BCSymbolMaps" + + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink -f "${source}")" + fi + + if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then + # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied + find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do + echo "Installing $f" + install_bcsymbolmap "$f" "$destination" + rm "$f" + done + rmdir "${source}/${BCSYMBOLMAP_DIR}" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + elif [ -L "${binary}" ]; then + echo "Destination binary is symlinked..." + dirname="$(dirname "${binary}")" + binary="${dirname}/$(readlink "${binary}")" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + warn_missing_arch=${2:-true} + if [ -r "$source" ]; then + # Copy the dSYM into the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .dSYM "$source")" + binary_name="$(ls "$source/Contents/Resources/DWARF")" + binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" + + # Strip invalid architectures from the dSYM. + if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then + strip_invalid_archs "$binary" "$warn_missing_arch" + fi + if [[ $STRIP_BINARY_RETVAL == 0 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + mkdir -p "${DWARF_DSYM_FOLDER_PATH}" + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" + fi + fi +} + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + warn_missing_arch=${2:-true} + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + if [[ "$warn_missing_arch" == "true" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + fi + STRIP_BINARY_RETVAL=1 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=0 +} + +# Copies the bcsymbolmap files of a vendored framework +install_bcsymbolmap() { + local bcsymbolmap_path="$1" + local destination="${BUILT_PRODUCTS_DIR}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/color-ios/color_ios.framework" + install_framework "${BUILT_PRODUCTS_DIR}/grid-ios/grid_ios.framework" + install_framework "${BUILT_PRODUCTS_DIR}/mgrs-ios/mgrs_ios.framework" + install_framework "${BUILT_PRODUCTS_DIR}/sf-ios/sf_ios.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/color-ios/color_ios.framework" + install_framework "${BUILT_PRODUCTS_DIR}/grid-ios/grid_ios.framework" + install_framework "${BUILT_PRODUCTS_DIR}/mgrs-ios/mgrs_ios.framework" + install_framework "${BUILT_PRODUCTS_DIR}/sf-ios/sf_ios.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-umbrella.h b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-umbrella.h new file mode 100644 index 0000000..c6e5e77 --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_TAKTrackerVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_TAKTrackerVersionString[]; + diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker.debug.xcconfig b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker.debug.xcconfig new file mode 100644 index 0000000..6f4059a --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker.debug.xcconfig @@ -0,0 +1,15 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/color-ios" "${PODS_CONFIGURATION_BUILD_DIR}/grid-ios" "${PODS_CONFIGURATION_BUILD_DIR}/mgrs-ios" "${PODS_CONFIGURATION_BUILD_DIR}/sf-ios" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/color-ios/color_ios.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/grid-ios/grid_ios.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/mgrs-ios/mgrs_ios.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/sf-ios/sf_ios.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "color_ios" -framework "grid_ios" -framework "mgrs_ios" -framework "sf_ios" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker.modulemap b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker.modulemap new file mode 100644 index 0000000..f8b182a --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker.modulemap @@ -0,0 +1,6 @@ +framework module Pods_TAKTracker { + umbrella header "Pods-TAKTracker-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker.release.xcconfig b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker.release.xcconfig new file mode 100644 index 0000000..6f4059a --- /dev/null +++ b/Pods/Target Support Files/Pods-TAKTracker/Pods-TAKTracker.release.xcconfig @@ -0,0 +1,15 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/color-ios" "${PODS_CONFIGURATION_BUILD_DIR}/grid-ios" "${PODS_CONFIGURATION_BUILD_DIR}/mgrs-ios" "${PODS_CONFIGURATION_BUILD_DIR}/sf-ios" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/color-ios/color_ios.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/grid-ios/grid_ios.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/mgrs-ios/mgrs_ios.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/sf-ios/sf_ios.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "color_ios" -framework "grid_ios" -framework "mgrs_ios" -framework "sf_ios" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/color-ios/color-ios-Info.plist b/Pods/Target Support Files/color-ios/color-ios-Info.plist new file mode 100644 index 0000000..7ffdf65 --- /dev/null +++ b/Pods/Target Support Files/color-ios/color-ios-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.1 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/color-ios/color-ios-dummy.m b/Pods/Target Support Files/color-ios/color-ios-dummy.m new file mode 100644 index 0000000..a480849 --- /dev/null +++ b/Pods/Target Support Files/color-ios/color-ios-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_color_ios : NSObject +@end +@implementation PodsDummy_color_ios +@end diff --git a/Pods/Target Support Files/color-ios/color-ios-prefix.pch b/Pods/Target Support Files/color-ios/color-ios-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/color-ios/color-ios-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/color-ios/color-ios-umbrella.h b/Pods/Target Support Files/color-ios/color-ios-umbrella.h new file mode 100644 index 0000000..be344f8 --- /dev/null +++ b/Pods/Target Support Files/color-ios/color-ios-umbrella.h @@ -0,0 +1,21 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "CLRColor.h" +#import "CLRColorConstants.h" +#import "CLRColorUtils.h" +#import "color-ios-Bridging-Header.h" +#import "color_ios.h" + +FOUNDATION_EXPORT double color_iosVersionNumber; +FOUNDATION_EXPORT const unsigned char color_iosVersionString[]; + diff --git a/Pods/Target Support Files/color-ios/color-ios.debug.xcconfig b/Pods/Target Support Files/color-ios/color-ios.debug.xcconfig new file mode 100644 index 0000000..58bce07 --- /dev/null +++ b/Pods/Target Support Files/color-ios/color-ios.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/color-ios +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "Foundation" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/color-ios +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/color-ios/color-ios.modulemap b/Pods/Target Support Files/color-ios/color-ios.modulemap new file mode 100644 index 0000000..c4ba415 --- /dev/null +++ b/Pods/Target Support Files/color-ios/color-ios.modulemap @@ -0,0 +1,6 @@ +framework module color_ios { + umbrella header "color-ios-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/color-ios/color-ios.release.xcconfig b/Pods/Target Support Files/color-ios/color-ios.release.xcconfig new file mode 100644 index 0000000..58bce07 --- /dev/null +++ b/Pods/Target Support Files/color-ios/color-ios.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/color-ios +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "Foundation" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/color-ios +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/grid-ios/grid-ios-Info.plist b/Pods/Target Support Files/grid-ios/grid-ios-Info.plist new file mode 100644 index 0000000..0b89d70 --- /dev/null +++ b/Pods/Target Support Files/grid-ios/grid-ios-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.5 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/grid-ios/grid-ios-dummy.m b/Pods/Target Support Files/grid-ios/grid-ios-dummy.m new file mode 100644 index 0000000..274fe50 --- /dev/null +++ b/Pods/Target Support Files/grid-ios/grid-ios-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_grid_ios : NSObject +@end +@implementation PodsDummy_grid_ios +@end diff --git a/Pods/Target Support Files/grid-ios/grid-ios-prefix.pch b/Pods/Target Support Files/grid-ios/grid-ios-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/grid-ios/grid-ios-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/grid-ios/grid-ios-umbrella.h b/Pods/Target Support Files/grid-ios/grid-ios-umbrella.h new file mode 100644 index 0000000..3573678 --- /dev/null +++ b/Pods/Target Support Files/grid-ios/grid-ios-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double grid_iosVersionNumber; +FOUNDATION_EXPORT const unsigned char grid_iosVersionString[]; + diff --git a/Pods/Target Support Files/grid-ios/grid-ios.debug.xcconfig b/Pods/Target Support Files/grid-ios/grid-ios.debug.xcconfig new file mode 100644 index 0000000..9eae350 --- /dev/null +++ b/Pods/Target Support Files/grid-ios/grid-ios.debug.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/grid-ios +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/color-ios" "${PODS_CONFIGURATION_BUILD_DIR}/sf-ios" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "color_ios" -framework "sf_ios" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/grid-ios +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/grid-ios/grid-ios.modulemap b/Pods/Target Support Files/grid-ios/grid-ios.modulemap new file mode 100644 index 0000000..1317966 --- /dev/null +++ b/Pods/Target Support Files/grid-ios/grid-ios.modulemap @@ -0,0 +1,6 @@ +framework module grid_ios { + umbrella header "grid-ios-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/grid-ios/grid-ios.release.xcconfig b/Pods/Target Support Files/grid-ios/grid-ios.release.xcconfig new file mode 100644 index 0000000..9eae350 --- /dev/null +++ b/Pods/Target Support Files/grid-ios/grid-ios.release.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/grid-ios +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/color-ios" "${PODS_CONFIGURATION_BUILD_DIR}/sf-ios" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "color_ios" -framework "sf_ios" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/grid-ios +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/mgrs-ios/ResourceBundle-mgrs-ios-mgrs-ios-Info.plist b/Pods/Target Support Files/mgrs-ios/ResourceBundle-mgrs-ios-mgrs-ios-Info.plist new file mode 100644 index 0000000..7db6f0c --- /dev/null +++ b/Pods/Target Support Files/mgrs-ios/ResourceBundle-mgrs-ios-mgrs-ios-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.1.4 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/mgrs-ios/mgrs-ios-Info.plist b/Pods/Target Support Files/mgrs-ios/mgrs-ios-Info.plist new file mode 100644 index 0000000..b53ea21 --- /dev/null +++ b/Pods/Target Support Files/mgrs-ios/mgrs-ios-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.1.4 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/mgrs-ios/mgrs-ios-dummy.m b/Pods/Target Support Files/mgrs-ios/mgrs-ios-dummy.m new file mode 100644 index 0000000..fa19f6f --- /dev/null +++ b/Pods/Target Support Files/mgrs-ios/mgrs-ios-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_mgrs_ios : NSObject +@end +@implementation PodsDummy_mgrs_ios +@end diff --git a/Pods/Target Support Files/mgrs-ios/mgrs-ios-prefix.pch b/Pods/Target Support Files/mgrs-ios/mgrs-ios-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/mgrs-ios/mgrs-ios-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/mgrs-ios/mgrs-ios-umbrella.h b/Pods/Target Support Files/mgrs-ios/mgrs-ios-umbrella.h new file mode 100644 index 0000000..6e69a83 --- /dev/null +++ b/Pods/Target Support Files/mgrs-ios/mgrs-ios-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double mgrs_iosVersionNumber; +FOUNDATION_EXPORT const unsigned char mgrs_iosVersionString[]; + diff --git a/Pods/Target Support Files/mgrs-ios/mgrs-ios.debug.xcconfig b/Pods/Target Support Files/mgrs-ios/mgrs-ios.debug.xcconfig new file mode 100644 index 0000000..16c544a --- /dev/null +++ b/Pods/Target Support Files/mgrs-ios/mgrs-ios.debug.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/mgrs-ios +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/color-ios" "${PODS_CONFIGURATION_BUILD_DIR}/grid-ios" "${PODS_CONFIGURATION_BUILD_DIR}/sf-ios" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "grid_ios" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/mgrs-ios +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/mgrs-ios/mgrs-ios.modulemap b/Pods/Target Support Files/mgrs-ios/mgrs-ios.modulemap new file mode 100644 index 0000000..7502849 --- /dev/null +++ b/Pods/Target Support Files/mgrs-ios/mgrs-ios.modulemap @@ -0,0 +1,6 @@ +framework module mgrs_ios { + umbrella header "mgrs-ios-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/mgrs-ios/mgrs-ios.release.xcconfig b/Pods/Target Support Files/mgrs-ios/mgrs-ios.release.xcconfig new file mode 100644 index 0000000..16c544a --- /dev/null +++ b/Pods/Target Support Files/mgrs-ios/mgrs-ios.release.xcconfig @@ -0,0 +1,16 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/mgrs-ios +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/color-ios" "${PODS_CONFIGURATION_BUILD_DIR}/grid-ios" "${PODS_CONFIGURATION_BUILD_DIR}/sf-ios" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "grid_ios" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/mgrs-ios +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/sf-ios/sf-ios-Info.plist b/Pods/Target Support Files/sf-ios/sf-ios-Info.plist new file mode 100644 index 0000000..c7cec0c --- /dev/null +++ b/Pods/Target Support Files/sf-ios/sf-ios-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + ${PODS_DEVELOPMENT_LANGUAGE} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 4.1.2 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/sf-ios/sf-ios-dummy.m b/Pods/Target Support Files/sf-ios/sf-ios-dummy.m new file mode 100644 index 0000000..9af3139 --- /dev/null +++ b/Pods/Target Support Files/sf-ios/sf-ios-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_sf_ios : NSObject +@end +@implementation PodsDummy_sf_ios +@end diff --git a/Pods/Target Support Files/sf-ios/sf-ios-prefix.pch b/Pods/Target Support Files/sf-ios/sf-ios-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/sf-ios/sf-ios-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/sf-ios/sf-ios-umbrella.h b/Pods/Target Support Files/sf-ios/sf-ios-umbrella.h new file mode 100644 index 0000000..ce62e76 --- /dev/null +++ b/Pods/Target Support Files/sf-ios/sf-ios-umbrella.h @@ -0,0 +1,61 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "SFExtendedGeometryCollection.h" +#import "sf-ios-Bridging-Header.h" +#import "SFCircularString.h" +#import "SFCompoundCurve.h" +#import "SFCurve.h" +#import "SFCurvePolygon.h" +#import "SFGeometry.h" +#import "SFGeometryCollection.h" +#import "SFGeometryEnvelope.h" +#import "SFGeometryTypes.h" +#import "SFLine.h" +#import "SFLinearRing.h" +#import "SFLineString.h" +#import "SFMultiCurve.h" +#import "SFMultiLineString.h" +#import "SFMultiPoint.h" +#import "SFMultiPolygon.h" +#import "SFMultiSurface.h" +#import "SFPoint.h" +#import "SFPolygon.h" +#import "SFPolyhedralSurface.h" +#import "SFSurface.h" +#import "SFTIN.h" +#import "SFTriangle.h" +#import "sf_ios.h" +#import "SFCentroidCurve.h" +#import "SFCentroidPoint.h" +#import "SFCentroidSurface.h" +#import "SFDegreesCentroid.h" +#import "SFFiniteFilterTypes.h" +#import "SFGeometryFilter.h" +#import "SFPointFiniteFilter.h" +#import "SFByteReader.h" +#import "SFByteWriter.h" +#import "SFGeometryConstants.h" +#import "SFGeometryEnvelopeBuilder.h" +#import "SFGeometryPrinter.h" +#import "SFGeometryUtils.h" +#import "SFTextReader.h" +#import "SFEvent.h" +#import "SFEventQueue.h" +#import "SFEventTypes.h" +#import "SFSegment.h" +#import "SFShamosHoey.h" +#import "SFSweepLine.h" + +FOUNDATION_EXPORT double sf_iosVersionNumber; +FOUNDATION_EXPORT const unsigned char sf_iosVersionString[]; + diff --git a/Pods/Target Support Files/sf-ios/sf-ios.debug.xcconfig b/Pods/Target Support Files/sf-ios/sf-ios.debug.xcconfig new file mode 100644 index 0000000..9fe24d2 --- /dev/null +++ b/Pods/Target Support Files/sf-ios/sf-ios.debug.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/sf-ios +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "Foundation" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/sf-ios +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/sf-ios/sf-ios.modulemap b/Pods/Target Support Files/sf-ios/sf-ios.modulemap new file mode 100644 index 0000000..7fb6fc6 --- /dev/null +++ b/Pods/Target Support Files/sf-ios/sf-ios.modulemap @@ -0,0 +1,6 @@ +framework module sf_ios { + umbrella header "sf-ios-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/sf-ios/sf-ios.release.xcconfig b/Pods/Target Support Files/sf-ios/sf-ios.release.xcconfig new file mode 100644 index 0000000..9fe24d2 --- /dev/null +++ b/Pods/Target Support Files/sf-ios/sf-ios.release.xcconfig @@ -0,0 +1,13 @@ +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/sf-ios +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "Foundation" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/sf-ios +PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/color-ios/LICENSE b/Pods/color-ios/LICENSE new file mode 100644 index 0000000..e71e681 --- /dev/null +++ b/Pods/color-ios/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Pods/color-ios/README.md b/Pods/color-ios/README.md new file mode 100644 index 0000000..5f9e32d --- /dev/null +++ b/Pods/color-ios/README.md @@ -0,0 +1,139 @@ +# Color iOS + +#### Color Lib #### + +The Color Library was developed at the [National Geospatial-Intelligence Agency (NGA)](http://www.nga.mil/) in collaboration with [BIT Systems](https://www.caci.com/bit-systems/). The government has "unlimited rights" and is releasing this software to increase the impact of government investments by providing developers with the opportunity to take things in new directions. The software use, modification, and distribution rights are stipulated within the [MIT license](http://choosealicense.com/licenses/mit/). + +### Pull Requests ### +If you'd like to contribute to this project, please make a pull request. We'll review the pull request and discuss the changes. All pull request contributions to this project will be released under the MIT license. + +Software source code previously released under an open source license and then modified by NGA staff is considered a "joint work" (see 17 USC § 101); it is partially copyrighted, partially public domain, and as a whole is protected by the copyrights of the non-government authors and must be released according to the terms of the original open source license. + +### About ### + +[Color](http://ngageoint.github.io/color-ios/) is an iOS Objective-C library providing color representation with support for hex, RBG, arithmetic RBG, HSL, and integer colors. + +### Usage ### + +View the latest [Appledoc](http://ngageoint.github.io/color-ios/docs/api/) + +```objectivec + +CLRColor *rgb = [CLRColor colorWithRed:154 andGreen:205 andBlue:50]; +CLRColor *rgba = [CLRColor colorWithRed:255 andGreen:165 andBlue:0 andAlpha:64]; +CLRColor *rgbOpacity = [CLRColor colorWithRed:255 andGreen:165 andBlue:0 andOpacity:0.25]; +CLRColor *arithmeticRGB = [CLRColor colorWithArithmeticRed:1.0 andGreen:0.64705882352 andBlue:0.0]; +CLRColor *arithmeticRGBOpacity = [CLRColor colorWithArithmeticRed:1.0 andGreen:0.64705882352 andBlue:0.0 andOpacity:0.25098039215]; +CLRColor *hex = [CLRColor colorWithHex:@"#BA55D3"]; +CLRColor *hexAlpha = [CLRColor colorWithHex:@"#D9FFFF00"]; +CLRColor *hexInteger = [CLRColor colorWithColor:0xFFC000]; +CLRColor *hexIntegerAlpha = [CLRColor colorWithColor:0x40FFA500]; +CLRColor *integer = [CLRColor colorWithColor:16711680]; +CLRColor *integerAlpha = [CLRColor colorWithColor:-12303292]; +CLRColor *hexSingles = [CLRColor colorWithHexRed:@"FF" andGreen:@"C0" andBlue:@"CB"]; +CLRColor *hexSinglesAlpha = [CLRColor colorWithHexRed:@"00" andGreen:@"00" andBlue:@"00" andAlpha:@"80"]; +CLRColor *hexSinglesOpacity = [CLRColor colorWithHexRed:@"FF" andGreen:@"A5" andBlue:@"00" andOpacity:0.25]; +CLRColor *hsl = [CLRColor colorWithHue:300.0 andSaturation:1.0 andLightness:0.2509804]; +CLRColor *hsla = [CLRColor colorWithHue:60.0 andSaturation:1.0 andLightness:0.5 andAlpha:0.85098039215]; +CLRColor *orangeAlpha = [CLRColor colorWithHex:CLR_COLOR_ORANGE andAlpha:120]; +CLRColor *orangeOpacity = [CLRColor colorWithHex:CLR_COLOR_ORANGE andOpacity:0.25]; + +CLRColor *color = [CLRColor blue]; +[color setAlpha:56]; +NSString *hexValue = [color colorHex]; +NSString *hexShorthand = [color colorHexShorthand]; +NSString *hexWithAlpha = [color colorHexWithAlpha]; +NSString *hexShorthandWithAlpha = [color colorHexShorthandWithAlpha]; +int integerValue = [color color]; +int integerAlphaValue = [color colorWithAlpha]; +int red = [color red]; +float greenArithmetic = color.greenArithmetic; +NSString *blueHex = [color blueHex]; +NSString *alphaHexShorthand = [color alphaHexShorthand]; +float opacity = color.opacity; +float *hslValue = [color hsl]; +float hue = [color hue]; +float saturation = [color saturation]; +float lightness = [color lightness]; + +``` + +### Build ### + +[![Build & Test](https://github.com/ngageoint/color-ios/workflows/Build%20&%20Test/badge.svg)](https://github.com/ngageoint/color-ios/actions/workflows/build-test.yml) + +Build this repository using Xcode and/or CocoaPods: + + pod install + +Open color-ios.xcworkspace in Xcode or build from command line: + + xcodebuild -workspace 'color-ios.xcworkspace' -scheme color-ios build + +Run tests from Xcode or from command line: + + xcodebuild test -workspace 'color-ios.xcworkspace' -scheme color-ios -destination 'platform=iOS Simulator,name=iPhone 14' + +### Include Library ### + +Include this repository by specifying it in a Podfile using a supported option. + +Pull from [CocoaPods](https://cocoapods.org/pods/color-ios): + + pod 'color-ios', '~> 1.0.1' + +Pull from GitHub: + + pod 'color-ios', :git => 'https://github.com/ngageoint/color-ios.git', :branch => 'master' + pod 'color-ios', :git => 'https://github.com/ngageoint/color-ios.git', :tag => '1.0.1' + +Include as local project: + + pod 'color-ios', :path => '../color-ios' + +### Swift ### + +To use from Swift, import the color-ios bridging header from the Swift project's bridging header + + #import "color-ios-Bridging-Header.h" + +```swift + +let rgb : CLRColor = CLRColor.init(red:154, andGreen:205, andBlue:50) +let rgba : CLRColor = CLRColor.init(red:255, andGreen:165, andBlue:0, andAlpha:64) +let rgbOpacity : CLRColor = CLRColor.init(red:255, andGreen:165, andBlue:0, andOpacity:0.25) +let arithmeticRGB : CLRColor = CLRColor.init(arithmeticRed:1.0, andGreen:0.64705882352, andBlue:0.0) +let arithmeticRGBOpacity : CLRColor = CLRColor.init(arithmeticRed:1.0, andGreen:0.64705882352, andBlue:0.0, andOpacity:0.25098039215) +let hex : CLRColor = CLRColor.init(hex:"#BA55D3") +let hexAlpha : CLRColor = CLRColor.init(hex:"#D9FFFF00") +let hexInteger : CLRColor = CLRColor.init(color:0xFFC000) +let hexIntegerAlpha : CLRColor = CLRColor.init(color:0x40FFA500) +let integer : CLRColor = CLRColor.init(color:16711680) +let integerAlpha : CLRColor = CLRColor.init(color:-12303292) +let hexSingles : CLRColor = CLRColor.init(hexRed:"FF", andGreen:"C0", andBlue:"CB") +let hexSinglesAlpha : CLRColor = CLRColor.init(hexRed:"00", andGreen:"00", andBlue:"00", andAlpha:"80") +let hexSinglesOpacity : CLRColor = CLRColor.init(hexRed:"FF", andGreen:"A5", andBlue:"00", andOpacity:0.25) +let hsl : CLRColor = CLRColor.init(hue:300.0, andSaturation:1.0, andLightness:0.2509804) +let hsla : CLRColor = CLRColor.init(hue:60.0, andSaturation:1.0, andLightness:0.5, andAlpha:0.85098039215) +let orangeAlpha : CLRColor = CLRColor.init(hex:CLR_COLOR_ORANGE, andAlpha:120) +let orangeOpacity : CLRColor = CLRColor.init(hex:CLR_COLOR_ORANGE, andOpacity:0.25) + +let color : CLRColor = CLRColor.blue() +color.setAlpha(56) +let hexValue : String = color.colorHex() +let hexShorthand : String = color.colorHexShorthand() +let hexWithAlpha : String = color.colorHexWithAlpha() +let hexShorthandWithAlpha : String = color.colorHexShorthandWithAlpha() +let integerValue : Int32 = color.color() +let integerAlphaValue : Int32 = color.colorWithAlpha() +let red : Int32 = color.red() +let greenArithmetic : Float = color.greenArithmetic +let blueHex : String = color.blueHex() +let alphaHexShorthand : String = color.alphaHexShorthand() +let opacity : Float = color.opacity +let hslValue : UnsafeMutablePointer = color.hsl() +let hue : Float = color.hue() +let saturation : Float = color.saturation() +let lightness : Float = color.lightness() + +``` diff --git a/Pods/color-ios/color-ios/CLRColor.h b/Pods/color-ios/color-ios/CLRColor.h new file mode 100644 index 0000000..b69e13c --- /dev/null +++ b/Pods/color-ios/color-ios/CLRColor.h @@ -0,0 +1,1026 @@ +// +// CLRColor.h +// color-ios +// +// Created by Brian Osborn on 7/18/22. +// Copyright © 2022 NGA. All rights reserved. +// + +#import + +/** + * Color representation with support for hex, RBG, arithmetic RBG, and integer + * colors + */ +@interface CLRColor : NSObject + +/** + * Red arithmetic color value + */ +@property (nonatomic) float redArithmetic; + +/** + * Green arithmetic color value + */ +@property (nonatomic) float greenArithmetic; + +/** + * Blue arithmetic color value + */ +@property (nonatomic) float blueArithmetic; + +/** + * Opacity arithmetic value + */ +@property (nonatomic) float opacity; + +/** + * Create a black color + * + * @return color + */ ++(CLRColor *) black; + +/** + * Create a blue color + * + * @return color + */ ++(CLRColor *) blue; + +/** + * Create a brown color + * + * @return color + */ ++(CLRColor *) brown; + +/** + * Create a cyan color + * + * @return color + */ ++(CLRColor *) cyan; + +/** + * Create a dark gray color + * + * @return color + */ ++(CLRColor *) darkGray; + +/** + * Create a gray color + * + * @return color + */ ++(CLRColor *) gray; + +/** + * Create a green color + * + * @return color + */ ++(CLRColor *) green; + +/** + * Create a light gray color + * + * @return color + */ ++(CLRColor *) lightGray; + +/** + * Create a magenta color + * + * @return color + */ ++(CLRColor *) magenta; + +/** + * Create an orange color + * + * @return color + */ ++(CLRColor *) orange; + +/** + * Create a pink color + * + * @return color + */ ++(CLRColor *) pink; + +/** + * Create a purple color + * + * @return color + */ ++(CLRColor *) purple; + +/** + * Create a red color + * + * @return color + */ ++(CLRColor *) red; + +/** + * Create a violet color + * + * @return color + */ ++(CLRColor *) violet; + +/** + * Create a white color + * + * @return color + */ ++(CLRColor *) white; + +/** + * Create a yellow color + * + * @return color + */ ++(CLRColor *) yellow; + +/** + * Create the color in hex + * + * @param color + * hex color in format #RRGGBB, RRGGBB, #RGB, RGB, #AARRGGBB, + * AARRGGBB, #ARGB, or ARGB + * + * @return color + */ ++(CLRColor *) colorWithHex: (NSString *) color; + +/** + * Create the color in hex with an opacity + * + * @param color + * hex color in format #RRGGBB, RRGGBB, #RGB, RGB, #AARRGGBB, + * AARRGGBB, #ARGB, or ARGB + * @param opacity + * opacity float inclusively between 0.0 and 1.0 + * + * @return color + */ ++(CLRColor *) colorWithHex: (NSString *) color andOpacity: (float) opacity; + +/** + * Create the color in hex with an alpha + * + * @param color + * hex color in format #RRGGBB, RRGGBB, #RGB, RGB, #AARRGGBB, + * AARRGGBB, #ARGB, or ARGB + * @param alpha + * alpha integer color inclusively between 0 and 255 + * + * @return color + */ ++(CLRColor *) colorWithHex: (NSString *) color andAlpha: (int) alpha; + +/** + * Create the color with individual hex colors + * + * @param red + * red hex color in format RR + * @param green + * green hex color in format GG + * @param blue + * blue hex color in format BB + * + * @return color + */ ++(CLRColor *) colorWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue; + +/** + * Create the color with individual hex colors and alpha + * + * @param red + * red hex color in format RR + * @param green + * green hex color in format GG + * @param blue + * blue hex color in format BB + * @param alpha + * alpha hex color in format AA + * + * @return color + */ ++(CLRColor *) colorWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andAlpha: (NSString *) alpha; + +/** + * Create the color with individual hex colors and opacity + * + * @param red + * red hex color in format RR + * @param green + * green hex color in format GG + * @param blue + * blue hex color in format BB + * @param opacity + * opacity float inclusively between 0.0 and 1.0 + * + * @return color + */ ++(CLRColor *) colorWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andOpacity: (float) opacity; + +/** + * Create the color with RGB values + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * + * @return color + */ ++(CLRColor *) colorWithRed: (int) red andGreen: (int) green andBlue: (int) blue; + +/** + * Create the color with RGBA values + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * @param alpha + * alpha integer color inclusively between 0 and 255 + * + * @return color + */ ++(CLRColor *) colorWithRed: (int) red andGreen: (int) green andBlue: (int) blue andAlpha: (int) alpha; + +/** + * Create the color with RGBA values + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * @param opacity + * opacity float inclusively between 0.0 and 1.0 + * + * @return color + */ ++(CLRColor *) colorWithRed: (int) red andGreen: (int) green andBlue: (int) blue andOpacity: (float) opacity; + +/** + * Create the color with arithmetic RGB values + * + * @param red + * red float color inclusively between 0.0 and 1.0 + * @param green + * green float color inclusively between 0.0 and 1.0 + * @param blue + * blue float color inclusively between 0.0 and 1.0 + * + * @return color + */ ++(CLRColor *) colorWithArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue; + +/** + * Create the color with arithmetic RGB values + * + * @param red + * red float color inclusively between 0.0 and 1.0 + * @param green + * green float color inclusively between 0.0 and 1.0 + * @param blue + * blue float color inclusively between 0.0 and 1.0 + * @param opacity + * opacity float inclusively between 0.0 and 1.0 + * + * @return color + */ ++(CLRColor *) colorWithArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue andOpacity: (float) opacity; + +/** + * Create the color with HSL (hue, saturation, lightness) or HSL (alpha) + * values + * + * @param hue + * hue + * @param saturation + * saturation + * @param lightness + * lightness + * + * @return color + */ ++(CLRColor *) colorWithHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness; + +/** + * Create the color with HSLA (hue, saturation, lightness, alpha) values + * + * @param hue + * hue + * @param saturation + * saturation + * @param lightness + * lightness + * @param alpha + * alpha inclusively between 0.0 and 1.0 + * + * @return color + */ ++(CLRColor *) colorWithHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness andAlpha: (float) alpha; + +/** + * Create the color as a single integer + * + * @param color + * color integer + * + * @return color + */ ++(CLRColor *) colorWithColor: (int) color; + +/** + * Create the color as a single unsigned integer + * + * @param color + * color unsigned integer + * + * @return color + */ ++(CLRColor *) colorWithUnsignedColor: (unsigned int) color; + +/** + * Default color initializer, opaque black + * + * @return new color + */ +-(instancetype) init; + +/** + * Create the color in hex + * + * @param color + * hex color in format #RRGGBB, RRGGBB, #RGB, RGB, #AARRGGBB, + * AARRGGBB, #ARGB, or ARGB + * + * @return new color + */ +-(instancetype) initWithHex: (NSString *) color; + +/** + * Create the color in hex with an opacity + * + * @param color + * hex color in format #RRGGBB, RRGGBB, #RGB, RGB, #AARRGGBB, + * AARRGGBB, #ARGB, or ARGB + * @param opacity + * opacity float inclusively between 0.0 and 1.0 + * + * @return new color + */ +-(instancetype) initWithHex: (NSString *) color andOpacity: (float) opacity; + +/** + * Create the color in hex with an alpha + * + * @param color + * hex color in format #RRGGBB, RRGGBB, #RGB, RGB, #AARRGGBB, + * AARRGGBB, #ARGB, or ARGB + * @param alpha + * alpha integer color inclusively between 0 and 255 + * + * @return new color + */ +-(instancetype) initWithHex: (NSString *) color andAlpha: (int) alpha; + +/** + * Create the color with individual hex colors + * + * @param red + * red hex color in format RR + * @param green + * green hex color in format GG + * @param blue + * blue hex color in format BB + * + * @return new color + */ +-(instancetype) initWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue; + +/** + * Create the color with individual hex colors and alpha + * + * @param red + * red hex color in format RR + * @param green + * green hex color in format GG + * @param blue + * blue hex color in format BB + * @param alpha + * alpha hex color in format AA + * + * @return new color + */ +-(instancetype) initWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andAlpha: (NSString *) alpha; + +/** + * Create the color with individual hex colors and opacity + * + * @param red + * red hex color in format RR + * @param green + * green hex color in format GG + * @param blue + * blue hex color in format BB + * @param opacity + * opacity float inclusively between 0.0 and 1.0 + * + * @return new color + */ +-(instancetype) initWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andOpacity: (float) opacity; + +/** + * Create the color with RGB values + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * + * @return new color + */ +-(instancetype) initWithRed: (int) red andGreen: (int) green andBlue: (int) blue; + +/** + * Create the color with RGBA values + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * @param alpha + * alpha integer color inclusively between 0 and 255 + * + * @return new color + */ +-(instancetype) initWithRed: (int) red andGreen: (int) green andBlue: (int) blue andAlpha: (int) alpha; + +/** + * Create the color with RGBA values + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * @param opacity + * opacity float inclusively between 0.0 and 1.0 + * + * @return new color + */ +-(instancetype) initWithRed: (int) red andGreen: (int) green andBlue: (int) blue andOpacity: (float) opacity; + +/** + * Create the color with arithmetic RGB values + * + * @param red + * red float color inclusively between 0.0 and 1.0 + * @param green + * green float color inclusively between 0.0 and 1.0 + * @param blue + * blue float color inclusively between 0.0 and 1.0 + * + * @return new color + */ +-(instancetype) initWithArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue; + +/** + * Create the color with arithmetic RGB values + * + * @param red + * red float color inclusively between 0.0 and 1.0 + * @param green + * green float color inclusively between 0.0 and 1.0 + * @param blue + * blue float color inclusively between 0.0 and 1.0 + * @param opacity + * opacity float inclusively between 0.0 and 1.0 + * + * @return new color + */ +-(instancetype) initWithArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue andOpacity: (float) opacity; + +/** + * Create the color with HSL (hue, saturation, lightness) or HSL (alpha) + * values + * + * @param hue + * hue + * @param saturation + * saturation + * @param lightness + * lightness + * + * @return new color + */ +-(instancetype) initWithHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness; + +/** + * Create the color with HSLA (hue, saturation, lightness, alpha) values + * + * @param hue + * hue + * @param saturation + * saturation + * @param lightness + * lightness + * @param alpha + * alpha inclusively between 0.0 and 1.0 + * + * @return new color + */ +-(instancetype) initWithHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness andAlpha: (float) alpha; + +/** + * Create the color as a single integer + * + * @param color + * color integer + * + * @return new color + */ +-(instancetype) initWithColor: (int) color; + +/** + * Create the color as a single unsigned integer + * + * @param color + * color unsigned integer + * + * @return new color + */ +-(instancetype) initWithUnsignedColor: (unsigned int) color; + +/** + * Copy Initialize + * + * @param color + * color to copy + * + * @return new color + */ +-(instancetype) initWithCLRColor: (CLRColor *) color; + +/** + * Set the color in hex + * + * @param color + * hex color in format #RRGGBB, RRGGBB, #RGB, RGB, #AARRGGBB, + * AARRGGBB, #ARGB, or ARGB + */ +-(void) setColorWithHex: (NSString *) color; + +/** + * Set the color in hex with an opacity + * + * @param color + * hex color in format #RRGGBB, RRGGBB, #RGB, RGB, #AARRGGBB, + * AARRGGBB, #ARGB, or ARGB + * @param opacity + * opacity float inclusively between 0.0 and 1.0 + */ +-(void) setColorWithHex: (NSString *) color andOpacity: (float) opacity; + +/** + * Set the color in hex with an alpha + * + * @param color + * hex color in format #RRGGBB, RRGGBB, #RGB, RGB, #AARRGGBB, + * AARRGGBB, #ARGB, or ARGB + * @param alpha + * alpha integer color inclusively between 0 and 255 + */ +-(void) setColorWithHex: (NSString *) color andAlpha: (int) alpha; + +/** + * Set the color with individual hex colors + * + * @param red + * red hex color in format RR + * @param green + * green hex color in format GG + * @param blue + * blue hex color in format BB + */ +-(void) setColorWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue; + +/** + * Set the color with individual hex colors and alpha + * + * @param red + * red hex color in format RR + * @param green + * green hex color in format GG + * @param blue + * blue hex color in format BB + * @param alpha + * alpha hex color in format AA + */ +-(void) setColorWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andAlpha: (NSString *) alpha; + +/** + * Set the color with individual hex colors and opacity + * + * @param red + * red hex color in format RR + * @param green + * green hex color in format GG + * @param blue + * blue hex color in format BB + * @param opacity + * opacity float inclusively between 0.0 and 1.0 + */ +-(void) setColorWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andOpacity: (float) opacity; + +/** + * Set the color with RGB values + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + */ +-(void) setColorWithRed: (int) red andGreen: (int) green andBlue: (int) blue; + +/** + * Set the color with RGBA values + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * @param alpha + * alpha integer color inclusively between 0 and 255 + */ +-(void) setColorWithRed: (int) red andGreen: (int) green andBlue: (int) blue andAlpha: (int) alpha; + +/** + * Set the color with RGBA values + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * @param opacity + * opacity float inclusively between 0.0 and 1.0 + */ +-(void) setColorWithRed: (int) red andGreen: (int) green andBlue: (int) blue andOpacity: (float) opacity; + +/** + * Set the color with arithmetic RGB values + * + * @param red + * red float color inclusively between 0.0 and 1.0 + * @param green + * green float color inclusively between 0.0 and 1.0 + * @param blue + * blue float color inclusively between 0.0 and 1.0 + */ +-(void) setColorWithArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue; + +/** + * Set the color with arithmetic RGB values + * + * @param red + * red float color inclusively between 0.0 and 1.0 + * @param green + * green float color inclusively between 0.0 and 1.0 + * @param blue + * blue float color inclusively between 0.0 and 1.0 + * @param opacity + * opacity float inclusively between 0.0 and 1.0 + */ +-(void) setColorWithArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue andOpacity: (float) opacity; + +/** + * Set the color with HSL (hue, saturation, lightness) values + * + * @param hue + * hue value inclusively between 0.0 and 360.0 + * @param saturation + * saturation inclusively between 0.0 and 1.0 + * @param lightness + * lightness inclusively between 0.0 and 1.0 + */ +-(void) setColorWithHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness; + +/** + * Set the color with HSLA (hue, saturation, lightness, alpha) values + * + * @param hue + * hue value inclusively between 0.0 and 360.0 + * @param saturation + * saturation inclusively between 0.0 and 1.0 + * @param lightness + * lightness inclusively between 0.0 and 1.0 + * @param alpha + * alpha inclusively between 0.0 and 1.0 + */ +-(void) setColorWithHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness andAlpha: (float) alpha; + +/** + * Set the color as a single integer + * + * @param color + * color integer + */ +-(void) setColor: (int) color; + +/** + * Set the color as a single unsigned integer + * + * @param color + * color unsigned integer + */ +-(void) setUnsignedColor: (unsigned int) color; + +/** + * Set the red color in hex + * + * @param red + * red hex color in format RR or R + */ +-(void) setRedHex: (NSString *) red; + +/** + * Set the green color in hex + * + * @param green + * green hex color in format GG or G + */ +-(void) setGreenHex: (NSString *) green; + +/** + * Set the blue color in hex + * + * @param blue + * blue hex color in format BB or B + */ +-(void) setBlueHex: (NSString *) blue; + +/** + * Set the alpha color in hex + * + * @param alpha + * alpha hex color in format AA or A + */ +-(void) setAlphaHex: (NSString *) alpha; + +/** + * Set the red color as an integer + * + * @param red + * red integer color inclusively between 0 and 255 + */ +-(void) setRed: (int) red; + +/** + * Set the green color as an integer + * + * @param green + * green integer color inclusively between 0 and 255 + */ +-(void) setGreen: (int) green; + +/** + * Set the blue color as an integer + * + * @param blue + * blue integer color inclusively between 0 and 255 + */ +-(void) setBlue: (int) blue; + +/** + * Set the alpha color as an integer + * + * @param alpha + * alpha integer color inclusively between 0 and 255 + */ +-(void) setAlpha: (int) alpha; + +/** + * Set the alpha color as an arithmetic float + * + * @param alpha + * alpha float color inclusively between 0.0 and 1.0 + */ +-(void) setAlphaArithmetic: (float) alpha; + +/** + * Check if the color is opaque (opacity or alpha of 1.0, 255, or x00) + * + * @return true if opaque + */ +-(BOOL) isOpaque; + +/** + * Get a UIColor from this color + * + * @return color + */ +-(UIColor *) uiColor; + +/** + * Get the color as a hex string + * + * @return hex color in the format #RRGGBB + */ +-(NSString *) colorHex; + +/** + * Get the color as a hex string with alpha + * + * @return hex color in the format #AARRGGBB + */ +-(NSString *) colorHexWithAlpha; + +/** + * Get the color as a hex string, shorthanded when possible + * + * @return hex color in the format #RGB or #RRGGBB + */ +-(NSString *) colorHexShorthand; + +/** + * Get the color as a hex string with alpha, shorthanded when possible + * + * @return hex color in the format #ARGB or #AARRGGBB + */ +-(NSString *) colorHexShorthandWithAlpha; + +/** + * Get the color as an integer + * + * @return integer color + */ +-(int) color; + +/** + * Get the color as an unsigned integer + * + * @return unsigned integer color + */ +-(unsigned int) unsignedColor; + +/** + * Get the color as an integer including the alpha + * + * @return integer color + */ +-(int) colorWithAlpha; + +/** + * Get the color as an unsigned integer including the alpha + * + * @return unsigned integer color + */ +-(unsigned int) unsignedColorWithAlpha; + +/** + * Get the red color in hex + * + * @return red hex color in format RR + */ +-(NSString *) redHex; + +/** + * Get the green color in hex + * + * @return green hex color in format GG + */ +-(NSString *) greenHex; + +/** + * Get the blue color in hex + * + * @return blue hex color in format BB + */ +-(NSString *) blueHex; + +/** + * Get the alpha color in hex + * + * @return alpha hex color in format AA + */ +-(NSString *) alphaHex; + +/** + * Get the red color in hex, shorthand when possible + * + * @return red hex color in format R or RR + */ +-(NSString *) redHexShorthand; + +/** + * Get the green color in hex, shorthand when possible + * + * @return green hex color in format G or GG + */ +-(NSString *) greenHexShorthand; + +/** + * Get the blue color in hex, shorthand when possible + * + * @return blue hex color in format B or BB + */ +-(NSString *) blueHexShorthand; + +/** + * Get the alpha color in hex, shorthand when possible + * + * @return alpha hex color in format A or AA + */ +-(NSString *) alphaHexShorthand; + +/** + * Get the red color as an integer + * + * @return red integer color inclusively between 0 and 255 + */ +-(int) red; + +/** + * Get the green color as an integer + * + * @return green integer color inclusively between 0 and 255 + */ +-(int) green; + +/** + * Get the blue color as an integer + * + * @return blue integer color inclusively between 0 and 255 + */ +-(int) blue; + +/** + * Get the alpha color as an integer + * + * @return alpha integer color inclusively between 0 and 255 + */ +-(int) alpha; + +/** + * Get the alpha color as an arithmetic float + * + * @return alpha float color inclusively between 0.0 and 1.0 + */ +-(float) alphaArithmetic; + +/** + * Get the HSL (hue, saturation, lightness) values + * + * @return HSL array where: 0 = hue, 1 = saturation, 2 = lightness + */ +-(float *) hsl; + +/** + * Get the HSL hue value + * + * @return hue value + */ +-(float) hue; + +/** + * Get the HSL saturation value + * + * @return saturation value + */ +-(float) saturation; + +/** + * Get the HSL lightness value + * + * @return lightness value + */ +-(float) lightness; + +@end diff --git a/Pods/color-ios/color-ios/CLRColor.m b/Pods/color-ios/color-ios/CLRColor.m new file mode 100644 index 0000000..5e1f458 --- /dev/null +++ b/Pods/color-ios/color-ios/CLRColor.m @@ -0,0 +1,537 @@ +// +// CLRColor.m +// color-ios +// +// Created by Brian Osborn on 7/18/22. +// Copyright © 2022 NGA. All rights reserved. +// + +#import "CLRColor.h" +#import "CLRColorUtils.h" +#import "CLRColorConstants.h" + +@implementation CLRColor + ++(CLRColor *) black{ + return [self colorWithHex:CLR_COLOR_BLACK]; +} + ++(CLRColor *) blue{ + return [self colorWithHex:CLR_COLOR_BLUE]; +} + ++(CLRColor *) brown{ + return [self colorWithHex:CLR_COLOR_BROWN]; +} + ++(CLRColor *) cyan{ + return [self colorWithHex:CLR_COLOR_CYAN]; +} + ++(CLRColor *) darkGray{ + return [self colorWithHex:CLR_COLOR_DKGRAY]; +} + ++(CLRColor *) gray{ + return [self colorWithHex:CLR_COLOR_GRAY]; +} + ++(CLRColor *) green{ + return [self colorWithHex:CLR_COLOR_GREEN]; +} + ++(CLRColor *) lightGray{ + return [self colorWithHex:CLR_COLOR_LTGRAY]; +} + ++(CLRColor *) magenta{ + return [self colorWithHex:CLR_COLOR_MAGENTA]; +} + ++(CLRColor *) orange{ + return [self colorWithHex:CLR_COLOR_ORANGE]; +} + ++(CLRColor *) pink{ + return [self colorWithHex:CLR_COLOR_PINK]; +} + ++(CLRColor *) purple{ + return [self colorWithHex:CLR_COLOR_PURPLE]; +} + ++(CLRColor *) red{ + return [self colorWithHex:CLR_COLOR_RED]; +} + ++(CLRColor *) violet{ + return [self colorWithHex:CLR_COLOR_VIOLET]; +} + ++(CLRColor *) white{ + return [self colorWithHex:CLR_COLOR_WHITE]; +} + ++(CLRColor *) yellow{ + return [self colorWithHex:CLR_COLOR_YELLOW]; +} + ++(CLRColor *) colorWithHex: (NSString *) color{ + return [[CLRColor alloc] initWithHex:color]; +} + ++(CLRColor *) colorWithHex: (NSString *) color andOpacity: (float) opacity{ + return [[CLRColor alloc] initWithHex:color andOpacity:opacity]; +} + ++(CLRColor *) colorWithHex: (NSString *) color andAlpha: (int) alpha{ + return [[CLRColor alloc] initWithHex:color andAlpha:alpha]; +} + ++(CLRColor *) colorWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue{ + return [[CLRColor alloc] initWithHexRed:red andGreen:green andBlue:blue]; +} + ++(CLRColor *) colorWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andAlpha: (NSString *) alpha{ + return [[CLRColor alloc] initWithHexRed:red andGreen:green andBlue:blue andAlpha:alpha]; +} + ++(CLRColor *) colorWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andOpacity: (float) opacity{ + return [[CLRColor alloc] initWithHexRed:red andGreen:green andBlue:blue andOpacity:opacity]; +} + ++(CLRColor *) colorWithRed: (int) red andGreen: (int) green andBlue: (int) blue{ + return [[CLRColor alloc] initWithRed:red andGreen:green andBlue:blue]; +} + ++(CLRColor *) colorWithRed: (int) red andGreen: (int) green andBlue: (int) blue andAlpha: (int) alpha{ + return [[CLRColor alloc] initWithRed:red andGreen:green andBlue:blue andAlpha:alpha]; +} + ++(CLRColor *) colorWithRed: (int) red andGreen: (int) green andBlue: (int) blue andOpacity: (float) opacity{ + return [[CLRColor alloc] initWithRed:red andGreen:green andBlue:blue andOpacity:opacity]; +} + ++(CLRColor *) colorWithArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue{ + return [[CLRColor alloc] initWithArithmeticRed:red andGreen:green andBlue:blue]; +} + ++(CLRColor *) colorWithArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue andOpacity: (float) opacity{ + return [[CLRColor alloc] initWithArithmeticRed:red andGreen:green andBlue:blue andOpacity:opacity]; +} + ++(CLRColor *) colorWithHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness{ + return [[CLRColor alloc] initWithHue:hue andSaturation:saturation andLightness:lightness]; +} + ++(CLRColor *) colorWithHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness andAlpha: (float) alpha{ + return [[CLRColor alloc] initWithHue:hue andSaturation:saturation andLightness:lightness andAlpha:alpha]; +} + ++(CLRColor *) colorWithColor: (int) color{ + return [[CLRColor alloc] initWithColor:color]; +} + ++(CLRColor *) colorWithUnsignedColor: (unsigned int) color{ + return [[CLRColor alloc] initWithUnsignedColor:color]; +} + +-(instancetype) init{ + self = [super init]; + if(self != nil){ + _redArithmetic = 0.0; + _greenArithmetic = 0.0; + _blueArithmetic = 0.0; + _opacity = 1.0; + } + return self; +} + +-(instancetype) initWithHex: (NSString *) color{ + self = [self init]; + if(self != nil){ + [self setColorWithHex:color]; + } + return self; +} + +-(instancetype) initWithHex: (NSString *) color andOpacity: (float) opacity{ + self = [self init]; + if(self != nil){ + [self setColorWithHex:color andOpacity:opacity]; + } + return self; +} + +-(instancetype) initWithHex: (NSString *) color andAlpha: (int) alpha{ + self = [self init]; + if(self != nil){ + [self setColorWithHex:color andAlpha:alpha]; + } + return self; +} + +-(instancetype) initWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue{ + self = [self init]; + if(self != nil){ + [self setColorWithHexRed:red andGreen:green andBlue:blue]; + } + return self; +} + +-(instancetype) initWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andAlpha: (NSString *) alpha{ + self = [self init]; + if(self != nil){ + [self setColorWithHexRed:red andGreen:green andBlue:blue andAlpha:alpha]; + } + return self; +} + +-(instancetype) initWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andOpacity: (float) opacity{ + self = [self init]; + if(self != nil){ + [self setColorWithHexRed:red andGreen:green andBlue:blue andOpacity:opacity]; + } + return self; +} + +-(instancetype) initWithRed: (int) red andGreen: (int) green andBlue: (int) blue{ + self = [self init]; + if(self != nil){ + [self setColorWithRed:red andGreen:green andBlue:blue]; + } + return self; +} + +-(instancetype) initWithRed: (int) red andGreen: (int) green andBlue: (int) blue andAlpha: (int) alpha{ + self = [self init]; + if(self != nil){ + [self setColorWithRed:red andGreen:green andBlue:blue andAlpha:alpha]; + } + return self; +} + +-(instancetype) initWithRed: (int) red andGreen: (int) green andBlue: (int) blue andOpacity: (float) opacity{ + self = [self init]; + if(self != nil){ + [self setColorWithRed:red andGreen:green andBlue:blue andOpacity:opacity]; + } + return self; +} + +-(instancetype) initWithArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue{ + self = [self init]; + if(self != nil){ + [self setColorWithArithmeticRed:red andGreen:green andBlue:blue]; + } + return self; +} + +-(instancetype) initWithArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue andOpacity: (float) opacity{ + self = [self init]; + if(self != nil){ + [self setColorWithArithmeticRed:red andGreen:green andBlue:blue andOpacity:opacity]; + } + return self; +} + +-(instancetype) initWithHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness{ + self = [self init]; + if(self != nil){ + [self setColorWithHue:hue andSaturation:saturation andLightness:lightness]; + } + return self; +} + +-(instancetype) initWithHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness andAlpha: (float) alpha{ + self = [self init]; + if(self != nil){ + [self setColorWithHue:hue andSaturation:saturation andLightness:lightness andAlpha:alpha]; + } + return self; +} + +-(instancetype) initWithColor: (int) color{ + self = [self init]; + if(self != nil){ + [self setColor:color]; + } + return self; +} + +-(instancetype) initWithUnsignedColor: (unsigned int) color{ + self = [self init]; + if(self != nil){ + [self setUnsignedColor:color]; + } + return self; +} + +-(instancetype) initWithCLRColor: (CLRColor *) color{ + self = [self init]; + if(self != nil){ + _redArithmetic = color.redArithmetic; + _greenArithmetic = color.greenArithmetic; + _blueArithmetic = color.blueArithmetic; + _opacity = color.opacity; + } + return self; +} + +-(void) setColorWithHex: (NSString *) color{ + [self setRedHex:[CLRColorUtils redHexFromHex:color]]; + [self setGreenHex:[CLRColorUtils greenHexFromHex:color]]; + [self setBlueHex:[CLRColorUtils blueHexFromHex:color]]; + NSString *alpha = [CLRColorUtils alphaHexFromHex:color]; + if(alpha != nil){ + [self setAlphaHex:alpha]; + } +} + +-(void) setColorWithHex: (NSString *) color andOpacity: (float) opacity{ + [self setColorWithHex:color]; + [self setOpacity:opacity]; +} + +-(void) setColorWithHex: (NSString *) color andAlpha: (int) alpha{ + [self setColorWithHex:color]; + [self setAlpha:alpha]; +} + +-(void) setColorWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue{ + [self setRedHex:red]; + [self setGreenHex:green]; + [self setBlueHex:blue]; +} + +-(void) setColorWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andAlpha: (NSString *) alpha{ + [self setColorWithHexRed:red andGreen:green andBlue:blue]; + [self setAlphaHex:alpha]; +} + +-(void) setColorWithHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andOpacity: (float) opacity{ + [self setColorWithHexRed:red andGreen:green andBlue:blue]; + [self setOpacity:opacity]; +} + +-(void) setColorWithRed: (int) red andGreen: (int) green andBlue: (int) blue{ + [self setRed:red]; + [self setGreen:green]; + [self setBlue:blue]; +} + +-(void) setColorWithRed: (int) red andGreen: (int) green andBlue: (int) blue andAlpha: (int) alpha{ + [self setColorWithRed:red andGreen:green andBlue:blue]; + [self setAlpha:alpha]; +} + +-(void) setColorWithRed: (int) red andGreen: (int) green andBlue: (int) blue andOpacity: (float) opacity{ + [self setColorWithRed:red andGreen:green andBlue:blue]; + [self setOpacity:opacity]; +} + +-(void) setColorWithArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue{ + [self setRedArithmetic:red]; + [self setGreenArithmetic:green]; + [self setBlueArithmetic:blue]; +} + +-(void) setColorWithArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue andOpacity: (float) opacity{ + [self setColorWithArithmeticRed:red andGreen:green andBlue:blue]; + [self setOpacity:opacity]; +} + +-(void) setColorWithHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness{ + float *arithmeticRGB = [CLRColorUtils toArithmeticRGBFromHue:hue andSaturation:saturation andLightness:lightness]; + [self setRedArithmetic:arithmeticRGB[0]]; + [self setGreenArithmetic:arithmeticRGB[1]]; + [self setBlueArithmetic:arithmeticRGB[2]]; +} + +-(void) setColorWithHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness andAlpha: (float) alpha{ + [self setColorWithHue:hue andSaturation:saturation andLightness:lightness]; + [self setAlphaArithmetic:alpha]; +} + +-(void) setColor: (int) color{ + [self setRed:[CLRColorUtils redFromColor:color]]; + [self setGreen:[CLRColorUtils greenFromColor:color]]; + [self setBlue:[CLRColorUtils blueFromColor:color]]; + if (color > 16777215 || color < 0) { + [self setAlpha:[CLRColorUtils alphaFromColor:color]]; + } +} + +-(void) setUnsignedColor: (unsigned int) color{ + [self setColor:color]; +} + +-(void) setRedHex: (NSString *) red{ + [self setRedArithmetic:[CLRColorUtils toArithmeticRGBFromHex:red]]; +} + +-(void) setGreenHex: (NSString *) green{ + [self setGreenArithmetic:[CLRColorUtils toArithmeticRGBFromHex:green]]; +} + +-(void) setBlueHex: (NSString *) blue{ + [self setBlueArithmetic:[CLRColorUtils toArithmeticRGBFromHex:blue]]; +} + +-(void) setAlphaHex: (NSString *) alpha{ + [self setAlphaArithmetic:[CLRColorUtils toArithmeticRGBFromHex:alpha]]; +} + +-(void) setRed: (int) red{ + [self setRedHex:[CLRColorUtils toHexFromRGB:red]]; +} + +-(void) setGreen: (int) green{ + [self setGreenHex:[CLRColorUtils toHexFromRGB:green]]; +} + +-(void) setBlue: (int) blue{ + [self setBlueHex:[CLRColorUtils toHexFromRGB:blue]]; +} + +-(void) setAlpha: (int) alpha{ + [self setOpacity:[CLRColorUtils toArithmeticRGBFromRGB:alpha]]; +} + +-(void) setRedArithmetic: (float) redArithmetic{ + [CLRColorUtils validateArithmeticRGB:redArithmetic]; + _redArithmetic = redArithmetic; +} + +-(void) setGreenArithmetic: (float) greenArithmetic{ + [CLRColorUtils validateArithmeticRGB:greenArithmetic]; + _greenArithmetic = greenArithmetic; +} + +-(void) setBlueArithmetic: (float) blueArithmetic{ + [CLRColorUtils validateArithmeticRGB:blueArithmetic]; + _blueArithmetic = blueArithmetic; +} + +-(void) setOpacity: (float) opacity{ + [CLRColorUtils validateArithmeticRGB:opacity]; + _opacity = opacity; +} + +-(void) setAlphaArithmetic: (float) alpha{ + [self setOpacity:alpha]; +} + +-(BOOL) isOpaque{ + return self.opacity == 1.0; +} + +-(UIColor *) uiColor{ + return [UIColor colorWithRed:[self redArithmetic] green:[self greenArithmetic] blue:[self blueArithmetic] alpha:[self alphaArithmetic]]; +} + +-(NSString *) colorHex{ + return [CLRColorUtils toColorFromHexRed:[self redHex] andGreen:[self greenHex] andBlue:[self blueHex]]; +} + +-(NSString *) colorHexWithAlpha{ + return [CLRColorUtils toColorWithAlphaFromHexRed:[self redHex] andGreen:[self greenHex] andBlue:[self blueHex] andAlpha:[self alphaHex]]; +} + +-(NSString *) colorHexShorthand{ + return [CLRColorUtils toColorShorthandFromHexRed:[self redHex] andGreen:[self greenHex] andBlue:[self blueHex]]; +} + +-(NSString *) colorHexShorthandWithAlpha{ + return [CLRColorUtils toColorShorthandWithAlphaFromHexRed:[self redHex] andGreen:[self greenHex] andBlue:[self blueHex] andAlpha:[self alphaHex]]; +} + +-(int) color{ + return [CLRColorUtils toColorFromRed:[self red] andGreen:[self green] andBlue:[self blue]]; +} + +-(unsigned int) unsignedColor{ + return [self color]; +} + +-(int) colorWithAlpha{ + return [CLRColorUtils toColorWithAlphaFromRed:[self red] andGreen:[self green] andBlue:[self blue] andAlpha:[self alpha]]; +} + +-(unsigned int) unsignedColorWithAlpha{ + return [self colorWithAlpha]; +} + +-(NSString *) redHex{ + return [CLRColorUtils toHexFromArithmeticRGB:self.redArithmetic]; +} + +-(NSString *) greenHex{ + return [CLRColorUtils toHexFromArithmeticRGB:self.greenArithmetic]; +} + +-(NSString *) blueHex{ + return [CLRColorUtils toHexFromArithmeticRGB:self.blueArithmetic]; +} + +-(NSString *) alphaHex{ + return [CLRColorUtils toHexFromArithmeticRGB:self.opacity]; +} + +-(NSString *) redHexShorthand{ + return [CLRColorUtils shorthandHexSingle:[self redHex]]; +} + +-(NSString *) greenHexShorthand{ + return [CLRColorUtils shorthandHexSingle:[self greenHex]]; +} + +-(NSString *) blueHexShorthand{ + return [CLRColorUtils shorthandHexSingle:[self blueHex]]; +} + +-(NSString *) alphaHexShorthand{ + return [CLRColorUtils shorthandHexSingle:[self alphaHex]]; +} + +-(int) red{ + return [CLRColorUtils toRGBFromArithmeticRGB:self.redArithmetic]; +} + +-(int) green{ + return [CLRColorUtils toRGBFromArithmeticRGB:self.greenArithmetic]; +} + +-(int) blue{ + return [CLRColorUtils toRGBFromArithmeticRGB:self.blueArithmetic]; +} + +-(int) alpha{ + return [CLRColorUtils toRGBFromArithmeticRGB:self.opacity]; +} + +-(float) alphaArithmetic{ + return _opacity; +} + +-(float *) hsl{ + return [CLRColorUtils toHSLFromArithmeticRed:self.redArithmetic andGreen:self.greenArithmetic andBlue:self.blueArithmetic]; +} + +-(float) hue{ + return [self hsl][0]; +} + +-(float) saturation{ + return [self hsl][1]; +} + +-(float) lightness{ + return [self hsl][2]; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [[CLRColor alloc] initWithCLRColor:self]; +} + +@end diff --git a/Pods/color-ios/color-ios/CLRColorConstants.h b/Pods/color-ios/color-ios/CLRColorConstants.h new file mode 100644 index 0000000..9df559a --- /dev/null +++ b/Pods/color-ios/color-ios/CLRColorConstants.h @@ -0,0 +1,30 @@ +// +// CLRColorConstants.h +// color-ios +// +// Created by Brian Osborn on 7/18/22. +// Copyright © 2022 NGA. All rights reserved. +// + +#import + +extern NSString * const CLR_COLOR_BLACK; +extern NSString * const CLR_COLOR_BLUE; +extern NSString * const CLR_COLOR_BROWN; +extern NSString * const CLR_COLOR_CYAN; +extern NSString * const CLR_COLOR_DKGRAY; +extern NSString * const CLR_COLOR_GRAY; +extern NSString * const CLR_COLOR_GREEN; +extern NSString * const CLR_COLOR_LTGRAY; +extern NSString * const CLR_COLOR_MAGENTA; +extern NSString * const CLR_COLOR_ORANGE; +extern NSString * const CLR_COLOR_PINK; +extern NSString * const CLR_COLOR_PURPLE; +extern NSString * const CLR_COLOR_RED; +extern NSString * const CLR_COLOR_VIOLET; +extern NSString * const CLR_COLOR_WHITE; +extern NSString * const CLR_COLOR_YELLOW; + +@interface CLRColorConstants : NSObject + +@end diff --git a/Pods/color-ios/color-ios/CLRColorConstants.m b/Pods/color-ios/color-ios/CLRColorConstants.m new file mode 100644 index 0000000..a78f64b --- /dev/null +++ b/Pods/color-ios/color-ios/CLRColorConstants.m @@ -0,0 +1,30 @@ +// +// CLRColorConstants.m +// color-ios +// +// Created by Brian Osborn on 7/18/22. +// Copyright © 2022 NGA. All rights reserved. +// + +#import "CLRColorConstants.h" + +NSString * const CLR_COLOR_BLACK = @"#000000"; +NSString * const CLR_COLOR_BLUE = @"#0000FF"; +NSString * const CLR_COLOR_BROWN = @"#A52A2A"; +NSString * const CLR_COLOR_CYAN = @"#00FFFF"; +NSString * const CLR_COLOR_DKGRAY = @"#444444"; +NSString * const CLR_COLOR_GRAY = @"#888888"; +NSString * const CLR_COLOR_GREEN = @"#00FF00"; +NSString * const CLR_COLOR_LTGRAY = @"#CCCCCC"; +NSString * const CLR_COLOR_MAGENTA = @"#FF00FF"; +NSString * const CLR_COLOR_ORANGE = @"#FFA500"; +NSString * const CLR_COLOR_PINK = @"#FFC0CB"; +NSString * const CLR_COLOR_PURPLE = @"#800080"; +NSString * const CLR_COLOR_RED = @"#FF0000"; +NSString * const CLR_COLOR_VIOLET = @"#EE82EE"; +NSString * const CLR_COLOR_WHITE = @"#FFFFFF"; +NSString * const CLR_COLOR_YELLOW = @"#FFFF00"; + +@implementation CLRColorConstants + +@end diff --git a/Pods/color-ios/color-ios/CLRColorUtils.h b/Pods/color-ios/color-ios/CLRColorUtils.h new file mode 100644 index 0000000..45ee674 --- /dev/null +++ b/Pods/color-ios/color-ios/CLRColorUtils.h @@ -0,0 +1,578 @@ +// +// CLRColorUtils.h +// color-ios +// +// Created by Brian Osborn on 7/18/22. +// Copyright © 2022 NGA. All rights reserved. +// + +#import + +/** + * Color utilities with support for hex, RBG, arithmetic RBG, and integer colors + */ +@interface CLRColorUtils : NSObject + +/** + * Convert the hex color values to a hex color + * + * @param red + * red hex color in format RR or R + * @param green + * green hex color in format GG or G + * @param blue + * blue hex color in format BB or B + * + * @return hex color in format #RRGGBB + */ ++(NSString *) toColorFromHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue; + +/** + * Convert the hex color values to a hex color, shorthanded when possible + * + * @param red + * red hex color in format RR or R + * @param green + * green hex color in format GG or G + * @param blue + * blue hex color in format BB or B + * + * @return hex color in format #RGB or #RRGGBB + */ ++(NSString *) toColorShorthandFromHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue; + +/** + * Convert the hex color values to a hex color including an opaque alpha + * value of FF + * + * @param red + * red hex color in format RR or R + * @param green + * green hex color in format GG or G + * @param blue + * blue hex color in format BB or B + * + * @return hex color in format #AARRGGBB + */ ++(NSString *) toColorWithAlphaFromHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue; + +/** + * Convert the hex color values to a hex color including an opaque alpha + * value of FF or F, shorthanded when possible + * + * @param red + * red hex color in format RR or R + * @param green + * green hex color in format GG or G + * @param blue + * blue hex color in format BB or B + * + * @return hex color in format #ARGB or #AARRGGBB + */ ++(NSString *) toColorShorthandWithAlphaFromHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue; + +/** + * Convert the hex color values to a hex color + * + * @param red + * red hex color in format RR or R + * @param green + * green hex color in format GG or G + * @param blue + * blue hex color in format BB or B + * @param alpha + * alpha hex color in format AA or A, null to not include alpha + * + * @return hex color in format #AARRGGBB or #RRGGBB + */ ++(NSString *) toColorWithAlphaFromHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andAlpha: (NSString *) alpha; + +/** + * Convert the hex color values to a hex color, shorthanded when possible + * + * @param red + * red hex color in format RR or R + * @param green + * green hex color in format GG or G + * @param blue + * blue hex color in format BB or B + * @param alpha + * alpha hex color in format AA or A, null to not include alpha + * + * @return hex color in format #ARGB, #RGB, #AARRGGBB, or #RRGGBB + */ ++(NSString *) toColorShorthandWithAlphaFromHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andAlpha: (NSString *) alpha; + +/** + * Convert the RBG values to a color integer + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * + * @return integer color + */ ++(int) toColorFromRed: (int) red andGreen: (int) green andBlue: (int) blue; + +/** + * Convert the RBG values to a color unsigned integer + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * + * @return unsigned integer color + */ ++(unsigned int) toUnsignedColorFromRed: (int) red andGreen: (int) green andBlue: (int) blue; + +/** + * Convert the RBG values to a color integer including an opaque alpha value + * of 255 + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * + * @return integer color + */ ++(int) toColorWithAlphaFromRed: (int) red andGreen: (int) green andBlue: (int) blue; + +/** + * Convert the RBG values to a color unsigned integer including an opaque alpha value + * of 255 + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * + * @return unsigned integer color + */ ++(unsigned int) toUnsignedColorWithAlphaFromRed: (int) red andGreen: (int) green andBlue: (int) blue; + +/** + * Convert the RBGA values to a color integer + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * @param alpha + * alpha integer color inclusively between 0 and 255, -1 to not + * include alpha + * + * @return integer color + */ ++(int) toColorWithAlphaFromRed: (int) red andGreen: (int) green andBlue: (int) blue andAlpha: (int) alpha; + +/** + * Convert the RBGA values to a color unsigned integer + * + * @param red + * red integer color inclusively between 0 and 255 + * @param green + * green integer color inclusively between 0 and 255 + * @param blue + * blue integer color inclusively between 0 and 255 + * @param alpha + * alpha integer color inclusively between 0 and 255, -1 to not + * include alpha + * + * @return unsigned integer color + */ ++(unsigned int) toUnsignedColorWithAlphaFromRed: (int) red andGreen: (int) green andBlue: (int) blue andAlpha: (int) alpha; + +/** + * Convert the RGB integer to a hex single color + * + * @param color + * integer color inclusively between 0 and 255 + * @return hex single color in format FF + */ ++(NSString *) toHexFromRGB: (int) color; + +/** + * Convert the arithmetic RGB float to a hex single color + * + * @param color + * float color inclusively between 0.0 and 1.0 + * @return hex single color in format FF + */ ++(NSString *) toHexFromArithmeticRGB: (float) color; + +/** + * Convert the hex single color to a RBG integer + * + * @param color + * hex single color in format FF or F + * + * @return integer color inclusively between 0 and 255 + */ ++(int) toRGBFromHex: (NSString *) color; + +/** + * Convert the arithmetic RGB float to a RBG integer + * + * @param color + * float color inclusively between 0.0 and 1.0 + * + * @return integer color inclusively between 0 and 255 + */ ++(int) toRGBFromArithmeticRGB: (float) color; + +/** + * Convert the hex single color to an arithmetic RBG float + * + * @param color + * hex single color in format FF or F + * @return float color inclusively between 0.0 and 1.0 + */ ++(float) toArithmeticRGBFromHex: (NSString *) color; + +/** + * Convert the RGB integer to an arithmetic RBG float + * + * @param color + * integer color inclusively between 0 and 255 + * @return float color inclusively between 0.0 and 1.0 + */ ++(float) toArithmeticRGBFromRGB: (int) color; + +/** + * Convert red, green, and blue arithmetic values to HSL (hue, saturation, + * lightness) values + * + * @param red + * red color inclusively between 0.0 and 1.0 + * @param green + * green color inclusively between 0.0 and 1.0 + * @param blue + * blue color inclusively between 0.0 and 1.0 + * @return HSL array where: 0 = hue, 1 = saturation, 2 = lightness + */ ++(float *) toHSLFromArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue; + +/** + * Convert red, green, and blue integer values to HSL (hue, saturation, + * lightness) values + * + * @param red + * red color inclusively between 0 and 255 + * @param green + * green color inclusively between 0 and 255 + * @param blue + * blue color inclusively between 0 and 255 + * @return HSL array where: 0 = hue, 1 = saturation, 2 = lightness + */ ++(float *) toHSLFromRed: (int) red andGreen: (int) green andBlue: (int) blue; + +/** + * Convert HSL (hue, saturation, and lightness) values to RGB arithmetic + * values + * + * @param hue + * hue value inclusively between 0.0 and 360.0 + * @param saturation + * saturation inclusively between 0.0 and 1.0 + * @param lightness + * lightness inclusively between 0.0 and 1.0 + * @return arithmetic RGB array where: 0 = red, 1 = green, 2 = blue + */ ++(float *) toArithmeticRGBFromHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness; + +/** + * Convert HSL (hue, saturation, and lightness) values to RGB integer values + * + * @param hue + * hue value inclusively between 0.0 and 360.0 + * @param saturation + * saturation inclusively between 0.0 and 1.0 + * @param lightness + * lightness inclusively between 0.0 and 1.0 + * @return RGB integer array where: 0 = red, 1 = green, 2 = blue + */ ++(int *) toRGBFromHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness; + +/** + * Get the hex red color from the hex string + * + * @param hex + * hex color + * @return hex red color in format RR + */ ++(NSString *) redHexFromHex: (NSString *) hex; + +/** + * Get the hex green color from the hex string + * + * @param hex + * hex color + * @return hex green color in format GG + */ ++(NSString *) greenHexFromHex: (NSString *) hex; + +/** + * Get the hex blue color from the hex string + * + * @param hex + * hex color + * @return hex blue color in format BB + */ ++(NSString *) blueHexFromHex: (NSString *) hex; + +/** + * Get the hex alpha color from the hex string if it exists + * + * @param hex + * hex color + * @return hex alpha color in format AA or null + */ ++(NSString *) alphaHexFromHex: (NSString *) hex; + +/** + * Get the red color from color integer + * + * @param color + * color integer + * @return red color + */ ++(int) redFromColor: (int) color; + +/** + * Get the red color from color unsigned integer + * + * @param color + * color unsigned integer + * @return red color + */ ++(int) redFromUnsignedColor: (unsigned int) color; + +/** + * Get the green color from color integer + * + * @param color + * color integer + * @return green color + */ ++(int) greenFromColor: (int) color; + +/** + * Get the green color from color unsigned integer + * + * @param color + * color unsigned integer + * @return green color + */ ++(int) greenFromUnsignedColor: (unsigned int) color; + +/** + * Get the blue color from color integer + * + * @param color + * color integer + * @return blue color + */ ++(int) blueFromColor: (int) color; + +/** + * Get the blue color from color unsigned integer + * + * @param color + * color unsigned integer + * @return blue color + */ ++(int) blueFromUnsignedColor: (unsigned int) color; + +/** + * Get the alpha color from color integer + * + * @param color + * color integer + * @return alpha color + */ ++(int) alphaFromColor: (int) color; + +/** + * Get the alpha color from color unsigned integer + * + * @param color + * color unsigned integer + * @return alpha color + */ ++(int) alphaFromUnsignedColor: (unsigned int) color; + +/** + * Shorthand the hex color if possible + * + * @param color + * hex color + * @return shorthand hex color or original value + */ ++(NSString *) shorthandHex: (NSString *) color; + +/** + * Expand the hex if it is in shorthand + * + * @param color + * hex color + * @return expanded hex color or original value + */ ++(NSString *) expandShorthandHex: (NSString *) color; + +/** + * Shorthand the hex single color if possible + * + * @param color + * hex single color + * @return shorthand hex color or original value + */ ++(NSString *) shorthandHexSingle: (NSString *) color; + +/** + * Expand the hex single if it is in shorthand + * + * @param color + * hex single color + * @return expanded hex color or original value + */ ++(NSString *) expandShorthandHexSingle: (NSString *) color; + +/** + * Check if the hex color value is valid + * + * @param color + * hex color + * @return true if valid + */ ++(BOOL) isValidHex: (NSString *) color; + +/** + * Validate the hex color value + * + * @param color + * hex color + */ ++(void) validateHex: (NSString *) color; + +/** + * Check if the hex single color value is valid + * + * @param color + * hex single color + * @return true if valid + */ ++(BOOL) isValidHexSingle: (NSString *) color; + +/** + * Validate the hex single color value + * + * @param color + * hex single color + */ ++(void) validateHexSingle: (NSString *) color; + +/** + * Check if the RBG integer color is valid, inclusively between 0 and 255 + * + * @param color + * decimal color + * @return true if valid + */ ++(BOOL) isValidRGB: (int) color; + +/** + * Validate the RBG integer color is inclusively between 0 and 255 + * + * @param color + * decimal color + */ ++(void) validateRGB: (int) color; + +/** + * Check if the arithmetic RGB float color is valid, inclusively between 0.0 + * and 1.0 + * + * @param color + * decimal color + * @return true if valid + */ ++(BOOL) isValidArithmeticRGB: (float) color; + +/** + * Validate the arithmetic RGB float color is inclusively between 0.0 and + * 1.0 + * + * @param color + * decimal color + */ ++(void) validateArithmeticRGB: (float) color; + +/** + * Check if the HSL hue float value is valid, inclusively between 0.0 and + * 360.0 + * + * @param hue + * hue value + * @return true if valid + */ ++(BOOL) isValidHue: (float) hue; + +/** + * Validate the HSL hue float value is inclusively between 0.0 and 360.0 + * + * @param hue + * hue value + */ ++(void) validateHue: (float) hue; + +/** + * Check if the HSL saturation float value is valid, inclusively between 0.0 + * and 1.0 + * + * @param saturation + * saturation value + * @return true if valid + */ ++(BOOL) isValidSaturation: (float) saturation; + +/** + * Validate the HSL saturation float value is inclusively between 0.0 and + * 1.0 + * + * @param saturation + * saturation value + */ ++(void) validateSaturation: (float) saturation; + +/** + * Check if the HSL lightness float value is valid, inclusively between 0.0 + * and 1.0 + * + * @param lightness + * lightness value + * @return true if valid + */ ++(BOOL) isValidLightness: (float) lightness; + +/** + * Validate the HSL lightness float value is inclusively between 0.0 and 1.0 + * + * @param lightness + * lightness value + */ ++(void) validateLightness: (float) lightness; + +@end diff --git a/Pods/color-ios/color-ios/CLRColorUtils.m b/Pods/color-ios/color-ios/CLRColorUtils.m new file mode 100644 index 0000000..8d8f406 --- /dev/null +++ b/Pods/color-ios/color-ios/CLRColorUtils.m @@ -0,0 +1,482 @@ +// +// CLRColorUtils.m +// color-ios +// +// Created by Brian Osborn on 7/18/22. +// Copyright © 2022 NGA. All rights reserved. +// + +#import "CLRColorUtils.h" + +NSString *const hexColorPattern = @"^#?(([0-9a-fA-F]{3}){1,2}|([0-9a-fA-F]{4}){1,2})$"; +NSString *const hexSingleColorPattern = @"^[0-9a-fA-F]{1,2}$"; + +@implementation CLRColorUtils + +static NSRegularExpression *hexColorExpression; +static NSRegularExpression *hexSingleColorExpression; + ++(void) initialize{ + if(hexColorExpression == nil){ + NSError *error = nil; + hexColorExpression = [NSRegularExpression regularExpressionWithPattern:hexColorPattern options:0 error:&error]; + if(error){ + [NSException raise:@"Hex Color Regular Expression" format:@"Failed to create hex color regular expression with error: %@", error]; + } + } + if(hexSingleColorExpression == nil){ + NSError *error = nil; + hexSingleColorExpression = [NSRegularExpression regularExpressionWithPattern:hexSingleColorPattern options:0 error:&error]; + if(error){ + [NSException raise:@"Hex Single Color Regular Expression" format:@"Failed to create hex single color regular expression with error: %@", error]; + } + } +} + ++(NSString *) toColorFromHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue{ + return [self toColorWithAlphaFromHexRed:red andGreen:green andBlue:blue andAlpha:nil]; +} + ++(NSString *) toColorShorthandFromHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue{ + return [self shorthandHex:[self toColorFromHexRed:red andGreen:green andBlue:blue]]; +} + ++(NSString *) toColorWithAlphaFromHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue{ + NSString *defaultAlpha = @"FF"; + if(red != nil && red.length > 0 && [[NSCharacterSet lowercaseLetterCharacterSet] characterIsMember:[red characterAtIndex:0]]){ + defaultAlpha = [defaultAlpha lowercaseString]; + } + return [self toColorWithAlphaFromHexRed:red andGreen:green andBlue:blue andAlpha:defaultAlpha]; +} + ++(NSString *) toColorShorthandWithAlphaFromHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue{ + return [self shorthandHex:[self toColorWithAlphaFromHexRed:red andGreen:green andBlue:blue]]; +} + ++(NSString *) toColorWithAlphaFromHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andAlpha: (NSString *) alpha{ + [self validateHexSingle:red]; + [self validateHexSingle:green]; + [self validateHexSingle:blue]; + NSMutableString *color = [NSMutableString stringWithString:@"#"]; + if(alpha != nil){ + [color appendString:[self expandShorthandHexSingle:alpha]]; + } + [color appendString:[self expandShorthandHexSingle:red]]; + [color appendString:[self expandShorthandHexSingle:green]]; + [color appendString:[self expandShorthandHexSingle:blue]]; + return color; +} + ++(NSString *) toColorShorthandWithAlphaFromHexRed: (NSString *) red andGreen: (NSString *) green andBlue: (NSString *) blue andAlpha: (NSString *) alpha{ + return [self shorthandHex:[self toColorWithAlphaFromHexRed:red andGreen:green andBlue:blue andAlpha:alpha]]; +} + ++(int) toColorFromRed: (int) red andGreen: (int) green andBlue: (int) blue{ + return [self toColorWithAlphaFromRed:red andGreen:green andBlue:blue andAlpha:-1]; +} + ++(unsigned int) toUnsignedColorFromRed: (int) red andGreen: (int) green andBlue: (int) blue{ + return (unsigned int) [self toColorFromRed:red andGreen:green andBlue:blue]; +} + ++(int) toColorWithAlphaFromRed: (int) red andGreen: (int) green andBlue: (int) blue{ + return [self toColorWithAlphaFromRed:red andGreen:green andBlue:blue andAlpha:255]; +} + ++(unsigned int) toUnsignedColorWithAlphaFromRed: (int) red andGreen: (int) green andBlue: (int) blue{ + return (unsigned int) [self toColorWithAlphaFromRed:red andGreen:green andBlue:blue]; +} + ++(int) toColorWithAlphaFromRed: (int) red andGreen: (int) green andBlue: (int) blue andAlpha: (int) alpha{ + [self validateRGB:red]; + [self validateRGB:green]; + [self validateRGB:blue]; + int color = (red & 0xff) << 16 | (green & 0xff) << 8 | (blue & 0xff); + if(alpha != -1){ + [self validateRGB:alpha]; + color = (alpha & 0xff) << 24 | color; + } + return color; +} + ++(unsigned int) toUnsignedColorWithAlphaFromRed: (int) red andGreen: (int) green andBlue: (int) blue andAlpha: (int) alpha{ + return (unsigned int) [self toColorWithAlphaFromRed:red andGreen:green andBlue:blue andAlpha:alpha]; +} + ++(NSString *) toHexFromRGB: (int) color{ + [self validateRGB:color]; + NSString *hex = [[NSString stringWithFormat:@"%x", color] uppercaseString]; + if(hex.length == 1){ + hex = [NSString stringWithFormat:@"0%@", hex]; + } + return hex; +} + ++(NSString *) toHexFromArithmeticRGB: (float) color{ + return [self toHexFromRGB:[self toRGBFromArithmeticRGB:color]]; +} + ++(int) toRGBFromHex: (NSString *) color{ + [self validateHexSingle:color]; + if(color.length == 1){ + color = [NSString stringWithFormat:@"%@%@", color, color]; + } + unsigned int rgb; + [[NSScanner scannerWithString:color] scanHexInt:&rgb]; + return rgb; +} + ++(int) toRGBFromArithmeticRGB: (float) color{ + [self validateArithmeticRGB:color]; + return (int)lroundf(255 * color); +} + ++(float) toArithmeticRGBFromHex: (NSString *) color{ + return [self toArithmeticRGBFromRGB:[self toRGBFromHex:color]]; +} + ++(float) toArithmeticRGBFromRGB: (int) color{ + [self validateRGB:color]; + return color / 255.0f; +} + ++(float *) toHSLFromArithmeticRed: (float) red andGreen: (float) green andBlue: (float) blue{ + + [self validateArithmeticRGB:red]; + [self validateArithmeticRGB:green]; + [self validateArithmeticRGB:blue]; + + float min = MIN(MIN(red, green), blue); + float max = MAX(MAX(red, green), blue); + + float range = max - min; + + float hue = 0.0f; + if (range > 0.0f) { + if (red >= green && red >= blue) { + hue = (green - blue) / range; + } else if (green >= blue) { + hue = 2 + (blue - red) / range; + } else { + hue = 4 + (red - green) / range; + } + } + + hue *= 60.0f; + if (hue < 0.0f) { + hue += 360.0f; + } + + float sum = min + max; + + float lightness = sum / 2.0f; + + float saturation; + if (min == max) { + saturation = 0.0f; + } else { + if (lightness < 0.5f) { + saturation = range / sum; + } else { + saturation = range / (2.0f - max - min); + } + } + + float *hsl = calloc(3, sizeof(float)); + hsl[0] = hue; + hsl[1] = saturation; + hsl[2] = lightness; + + return hsl; +} + ++(float *) toHSLFromRed: (int) red andGreen: (int) green andBlue: (int) blue{ + return [self toHSLFromArithmeticRed:[self toArithmeticRGBFromRGB:red] andGreen:[self toArithmeticRGBFromRGB:green] andBlue:[self toArithmeticRGBFromRGB:blue]]; +} + ++(float *) toArithmeticRGBFromHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness{ + + [self validateHue:hue]; + [self validateSaturation:saturation]; + [self validateLightness:lightness]; + + hue /= 60.0f; + float t2; + if (lightness <= 0.5f) { + t2 = lightness * (saturation + 1); + } else { + t2 = lightness + saturation - (lightness * saturation); + } + float t1 = lightness * 2.0f - t2; + + float red = [self hslConvertT1:t1 andT2:t2 andHue:hue + 2]; + float green = [self hslConvertT1:t1 andT2:t2 andHue:hue]; + float blue = [self hslConvertT1:t1 andT2:t2 andHue:hue - 2]; + + float *rgb = calloc(3, sizeof(float)); + rgb[0] = red; + rgb[1] = green; + rgb[2] = blue; + + return rgb; +} + ++(int *) toRGBFromHue: (float) hue andSaturation: (float) saturation andLightness: (float) lightness{ + float *arithmeticRGB = [self toArithmeticRGBFromHue:hue andSaturation:saturation andLightness:lightness]; + + int *rgb = calloc(3, sizeof(int)); + rgb[0] = [self toRGBFromArithmeticRGB:arithmeticRGB[0]]; + rgb[1] = [self toRGBFromArithmeticRGB:arithmeticRGB[1]]; + rgb[2] = [self toRGBFromArithmeticRGB:arithmeticRGB[2]]; + + return rgb; +} + +/** + * HSL convert helper method + * + * @param t1 + * t1 + * @param t2 + * t2 + * @param hue + * hue + * @return arithmetic RBG value + */ ++(float) hslConvertT1: (float) t1 andT2: (float) t2 andHue: (float) hue{ + float value; + if (hue < 0) { + hue += 6; + } + if (hue >= 6) { + hue -= 6; + } + if (hue < 1) { + value = (t2 - t1) * hue + t1; + } else if (hue < 3) { + value = t2; + } else if (hue < 4) { + value = (t2 - t1) * (4 - hue) + t1; + } else { + value = t1; + } + return value; +} + ++(NSString *) redHexFromHex: (NSString *) hex{ + return [self hexSingleFromHex:hex andColorIndex:0]; +} + ++(NSString *) greenHexFromHex: (NSString *) hex{ + return [self hexSingleFromHex:hex andColorIndex:1]; +} + ++(NSString *) blueHexFromHex: (NSString *) hex{ + return [self hexSingleFromHex:hex andColorIndex:2]; +} + ++(NSString *) alphaHexFromHex: (NSString *) hex{ + return [self hexSingleFromHex:hex andColorIndex:-1]; +} + +/** + * Get the hex single color + * + * @param hex + * hex color + * @param colorIndex + * red=0, green=1, blue=2, alpha=-1 + * @return hex single color in format FF or null + */ ++(NSString *) hexSingleFromHex: (NSString *) hex andColorIndex: (int) colorIndex{ + [self validateHex:hex]; + + if([hex hasPrefix:@"#"]){ + hex = [hex substringFromIndex:1]; + } + + int colorCharacters = 1; + int numColors = (int)hex.length; + if (numColors > 4) { + colorCharacters++; + numColors /= 2; + } + + NSString *color = nil; + if (colorIndex >= 0 || numColors > 3) { + if (numColors > 3) { + colorIndex++; + } + int startIndex = colorIndex; + if (colorCharacters > 1) { + startIndex *= 2; + } + color = [hex substringWithRange:NSMakeRange(startIndex, colorCharacters)]; + color = [self expandShorthandHexSingle:color]; + } + + return color; +} + ++(int) redFromColor: (int) color{ + return (color >> 16) & 0xff; +} + ++(int) redFromUnsignedColor: (unsigned int) color{ + return [self redFromColor:color]; +} + ++(int) greenFromColor: (int) color{ + return (color >> 8) & 0xff; +} + ++(int) greenFromUnsignedColor: (unsigned int) color{ + return [self greenFromColor:color]; +} + ++(int) blueFromColor: (int) color{ + return color & 0xff; +} + ++(int) blueFromUnsignedColor: (unsigned int) color{ + return [self blueFromColor:color]; +} + ++(int) alphaFromColor: (int) color{ + return (color >> 24) & 0xff; +} + ++(int) alphaFromUnsignedColor: (unsigned int) color{ + return [self alphaFromColor:color]; +} + ++(NSString *) shorthandHex: (NSString *) color{ + [self validateHex:color]; + if(color.length > 5){ + NSMutableString *shorthandColor = [NSMutableString string]; + int startIndex = 0; + if([color hasPrefix:@"#"]){ + [shorthandColor appendString:@"#"]; + startIndex++; + } + for (; startIndex < color.length; startIndex += 2) { + NSString *shorthand = [self shorthandHexSingle:[color substringWithRange:NSMakeRange(startIndex, 2)]]; + if(shorthand.length > 1){ + shorthandColor = nil; + break; + } + [shorthandColor appendString:shorthand]; + } + if(shorthandColor != nil){ + color = shorthandColor; + } + } + + return color; +} + ++(NSString *) expandShorthandHex: (NSString *) color{ + [self validateHex:color]; + if(color.length < 6){ + NSMutableString *expandColor = [NSMutableString string]; + int startIndex = 0; + if([color hasPrefix:@"#"]){ + [expandColor appendString:@"#"]; + startIndex++; + } + for (; startIndex < color.length; startIndex++) { + NSString *expand = [self expandShorthandHexSingle:[color substringWithRange:NSMakeRange(startIndex, 1)]]; + [expandColor appendString:expand]; + } + color = expandColor; + } + return color; +} + ++(NSString *) shorthandHexSingle: (NSString *) color{ + [self validateHexSingle:color]; + if(color.length > 1 && toupper([color characterAtIndex:0]) == toupper([color characterAtIndex:1])){ + color = [color substringToIndex:1]; + } + return color; +} + ++(NSString *) expandShorthandHexSingle: (NSString *) color{ + [self validateHexSingle:color]; + if (color.length == 1) { + color = [NSString stringWithFormat:@"%@%@", color, color]; + } + return color; +} + ++(BOOL) isValidHex: (NSString *) color{ + return color != nil && [hexColorExpression numberOfMatchesInString:color options:0 range:NSMakeRange(0, color.length)] == 1; +} + ++(void) validateHex: (NSString *) color{ + if(![self isValidHex:color]){ + [NSException raise:@"Invalid Hex" format:@"Hex color must be in format #RRGGBB, #RGB, #AARRGGBB, #ARGB, RRGGBB, RGB, AARRGGBB, or ARGB, invalid value: %@", color]; + } +} + ++(BOOL) isValidHexSingle: (NSString *) color{ + return color != nil && [hexSingleColorExpression numberOfMatchesInString:color options:0 range:NSMakeRange(0, color.length)] == 1; +} + ++(void) validateHexSingle: (NSString *) color{ + if(![self isValidHexSingle:color]){ + [NSException raise:@"Invalid Hex" format:@"Must be in format FF or F, invalid value: %@", color]; + } +} + ++(BOOL) isValidRGB: (int) color{ + return color >= 0 && color <= 255; +} + ++(void) validateRGB: (int) color{ + if (![self isValidRGB:color]){ + [NSException raise:@"Invalid RGB" format:@"Must be inclusively between 0 and 255, invalid value: %d", color]; + } +} + ++(BOOL) isValidArithmeticRGB: (float) color{ + return color >= 0.0 && color <= 1.0; +} + ++(void) validateArithmeticRGB: (float) color{ + if (![self isValidArithmeticRGB:color]){ + [NSException raise:@"Invalid Arithmetic RGB" format:@"Must be inclusively between 0.0 and 1.0, invalid value: %f", color]; + } +} + ++(BOOL) isValidHue: (float) hue{ + return hue >= 0.0 && hue <= 360.0; +} + ++(void) validateHue: (float) hue{ + if (![self isValidHue:hue]) { + [NSException raise:@"Invalid Hue" format:@"Must be inclusively between 0.0 and 360.0, invalid value: %f", hue]; + } +} + ++(BOOL) isValidSaturation: (float) saturation{ + return saturation >= 0.0 && saturation <= 1.0; +} + ++(void) validateSaturation: (float) saturation{ + if (![self isValidSaturation:saturation]) { + [NSException raise:@"Invalid Saturation" format:@"Must be inclusively between 0.0 and 1.0, invalid value: %f", saturation]; + } +} + ++(BOOL) isValidLightness: (float) lightness{ + return lightness >= 0.0 && lightness <= 1.0; +} + ++(void) validateLightness: (float) lightness{ + if (![self isValidLightness:lightness]) { + [NSException raise:@"Invalid Lightness" format:@"Must be inclusively between 0.0 and 1.0, invalid value: %f", lightness]; + } +} + +@end diff --git a/Pods/color-ios/color-ios/color-ios-Bridging-Header.h b/Pods/color-ios/color-ios/color-ios-Bridging-Header.h new file mode 100644 index 0000000..9477065 --- /dev/null +++ b/Pods/color-ios/color-ios/color-ios-Bridging-Header.h @@ -0,0 +1,17 @@ +// +// color-ios-Bridging-Header.h +// color-ios +// +// Created by Brian Osborn on 7/18/22. +// Copyright © 2022 NGA. All rights reserved. +// + +#ifndef color_ios_Bridging_Header_h +#define color_ios_Bridging_Header_h + +#import "color_ios.h" +#import "CLRColor.h" +#import "CLRColorConstants.h" +#import "CLRColorUtils.h" + +#endif /* color_ios_Bridging_Header_h */ diff --git a/Pods/color-ios/color-ios/color_ios.h b/Pods/color-ios/color-ios/color_ios.h new file mode 100644 index 0000000..4061c49 --- /dev/null +++ b/Pods/color-ios/color-ios/color_ios.h @@ -0,0 +1,13 @@ +// +// color-ios.h +// color-ios +// +// Created by Brian Osborn on 7/18/22. +// Copyright (c) 2022 NGA. All rights reserved. +// + +#ifndef color_ios_color_ios_h +#define color_ios_color_ios_h + + +#endif diff --git a/Pods/grid-ios/LICENSE b/Pods/grid-ios/LICENSE new file mode 100644 index 0000000..e71e681 --- /dev/null +++ b/Pods/grid-ios/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Pods/grid-ios/README.md b/Pods/grid-ios/README.md new file mode 100644 index 0000000..9fca682 --- /dev/null +++ b/Pods/grid-ios/README.md @@ -0,0 +1,72 @@ +# Grid iOS + +#### Grid Lib #### + +The Grid Library was developed at the [National Geospatial-Intelligence Agency (NGA)](http://www.nga.mil/) in collaboration with [BIT Systems](https://www.caci.com/bit-systems/). The government has "unlimited rights" and is releasing this software to increase the impact of government investments by providing developers with the opportunity to take things in new directions. The software use, modification, and distribution rights are stipulated within the [MIT license](http://choosealicense.com/licenses/mit/). + +### Pull Requests ### +If you'd like to contribute to this project, please make a pull request. We'll review the pull request and discuss the changes. All pull request contributions to this project will be released under the MIT license. + +Software source code previously released under an open source license and then modified by NGA staff is considered a "joint work" (see 17 USC § 101); it is partially copyrighted, partially public domain, and as a whole is protected by the copyrights of the non-government authors and must be released according to the terms of the original open source license. + +### About ### + +[Grid](http://ngageoint.github.io/grid-ios/) is a Swift library providing common geospatial reference system grid functionality. + +### Usage ### + +View the latest [Appledoc](http://ngageoint.github.io/grid-ios/docs/api/) + +#### Military Grid Reference System #### + +[MGRS](https://github.com/ngageoint/mgrs-ios) is a Swift library providing Military Grid Reference System functionality, a geocoordinate standard used by NATO militaries for locating points on Earth. + +#### Global Area Reference System #### + +[GARS](https://github.com/ngageoint/gars-ios) is a Swift library providing Global Area Reference System functionality, a standardized geospatial reference system for areas. + +#### Import #### + +```swift + +import grid_ios + +``` + +### Build ### + +[![Build & Test](https://github.com/ngageoint/grid-ios/workflows/Build%20&%20Test/badge.svg)](https://github.com/ngageoint/grid-ios/actions/workflows/build-test.yml) + +Build this repository using Xcode and/or CocoaPods: + + pod install + +Open grid-ios.xcworkspace in Xcode or build from command line: + + xcodebuild -workspace 'grid-ios.xcworkspace' -scheme grid-ios build + +Run tests from Xcode or from command line: + + xcodebuild test -workspace 'grid-ios.xcworkspace' -scheme grid-ios -destination 'platform=iOS Simulator,name=iPhone 14' + +### Include Library ### + +Include this repository by specifying it in a Podfile using a supported option. + +Pull from [CocoaPods](https://cocoapods.org/pods/grid-ios): + + pod 'grid-ios', '~> 1.0.5' + +Pull from GitHub: + + pod 'grid-ios', :git => 'https://github.com/ngageoint/grid-ios.git', :branch => 'master' + pod 'grid-ios', :git => 'https://github.com/ngageoint/grid-ios.git', :tag => '1.0.5' + +Include as local project: + + pod 'grid-ios', :path => '../grid-ios' + +### Remote Dependencies ### + +* [Simple Features](https://github.com/ngageoint/simple-features-ios) (The MIT License (MIT)) - Simple Features Lib +* [Color](https://github.com/ngageoint/color-ios) (The MIT License (MIT)) - Color Lib diff --git a/Pods/grid-ios/grid-ios/BaseGrid.swift b/Pods/grid-ios/grid-ios/BaseGrid.swift new file mode 100644 index 0000000..6a51666 --- /dev/null +++ b/Pods/grid-ios/grid-ios/BaseGrid.swift @@ -0,0 +1,205 @@ +// +// BaseGrid.swift +// grid-ios +// +// Created by Brian Osborn on 8/8/22. +// + +import Foundation +import color_ios + +/** + * Base Grid + */ +open class BaseGrid: Hashable, Comparable { + + /** + * Enabled grid + */ + public var enabled: Bool = true + + /** + * Minimum zoom level + */ + public var minZoom: Int = 0 + + /** + * Maximum zoom level + */ + public var maxZoom: Int? + + /** + * Minimum zoom level override for drawing grid lines + */ + private var _linesMinZoom: Int? + + /** + * Minimum zoom level override for drawing grid lines + */ + public var linesMinZoom: Int? { + get { + return _linesMinZoom != nil ? _linesMinZoom : minZoom + } + set { + _linesMinZoom = newValue + } + } + + /** + * Maximum zoom level override for drawing grid lines + */ + private var _linesMaxZoom: Int? + + /** + * Maximum zoom level override for drawing grid lines + */ + public var linesMaxZoom: Int? { + get { + return _linesMaxZoom != nil ? _linesMaxZoom : maxZoom + } + set { + _linesMaxZoom = newValue + } + } + + /** + * Grid line style + */ + public var style: GridStyle = GridStyle() + + /** + * Grid labeler + */ + open var labeler: Labeler? + + /** + * The grid line color + */ + public var color: UIColor? { + get { + return style.color + } + set { + style.color = newValue + } + } + + /** + * The grid line width + */ + public var width: Double { + get { + return style.width + } + set { + style.width = newValue + } + } + + /** + * Initialize + */ + public init() { + + } + + /** + * Has a maximum zoom level + * + * @return true if has a maximum, false if unbounded + */ + public func hasMaxZoom() -> Bool { + return maxZoom != nil + } + + /** + * Is the zoom level within the grid zoom range + * + * @param zoom + * zoom level + * @return true if within range + */ + public func isWithin(_ zoom: Int) -> Bool { + return zoom >= minZoom && (maxZoom == nil || zoom <= maxZoom!) + } + + /** + * Has a minimum zoom level override for drawing grid lines + * + * @return true if has a minimum, false if not overridden + */ + public func hasLinesMinZoom() -> Bool { + return _linesMinZoom != nil + } + + /** + * Has a maximum zoom level override for drawing grid lines + * + * @return true if has a maximum, false if not overridden + */ + public func hasLinesMaxZoom() -> Bool { + return _linesMaxZoom != nil + } + + /** + * Is the zoom level within the grid lines zoom range + * + * @param zoom + * zoom level + * @return true if within range + */ + public func isLinesWithin(_ zoom: Int) -> Bool { + return (_linesMinZoom == nil || zoom >= _linesMinZoom!) + && (_linesMaxZoom == nil || zoom <= _linesMaxZoom!) + } + + /** + * Has a grid labeler + * + * @return true if has a grid labeler + */ + public func hasLabeler() -> Bool { + return labeler != nil + } + + /** + * Is labeler zoom level within the grid zoom range + * + * @param zoom + * zoom level + * @return true if within range + */ + public func isLabelerWithin(_ zoom: Int) -> Bool { + return hasLabeler() && labeler!.enabled && labeler!.isWithin(zoom) + } + + /** + * Get the label grid edge buffer + * + * @return label buffer (greater than or equal to 0.0 and less than 0.5) + */ + public func labelBuffer() -> Double { + return hasLabeler() ? labeler!.buffer : 0.0 + } + + public static func == (lhs: BaseGrid, rhs: BaseGrid) -> Bool { + return lhs.equals(rhs) + } + + open func equals(_ grid: BaseGrid) -> Bool { + preconditionFailure("This method must be overridden") + } + + open func hash(into hasher: inout Hasher) { + + } + + public static func < (lhs: BaseGrid, rhs: BaseGrid) -> Bool { + return lhs.compare(rhs) + } + + open func compare(_ grid: BaseGrid) -> Bool { + preconditionFailure("This method must be overridden") + } + +} diff --git a/Pods/grid-ios/grid-ios/BaseGrids.swift b/Pods/grid-ios/grid-ios/BaseGrids.swift new file mode 100644 index 0000000..8456756 --- /dev/null +++ b/Pods/grid-ios/grid-ios/BaseGrids.swift @@ -0,0 +1,521 @@ +// +// BaseGrids.swift +// grid-ios +// +// Created by Brian Osborn on 8/8/22. +// + +import Foundation +import color_ios + +/** + * Grids + */ +open class BaseGrids { + + /** + * Grid properties + */ + public let properties: GridProperties + + /** + * Map between zoom levels and grids + */ + private var zoomGrids: [Int: BaseZoomGrids] = [:] + + /** + * Initialize + * + * @param properties + * grid properties + */ + public init(_ properties: GridProperties) { + self.properties = properties + } + + /** + * Get the default grid line width + * + * @return width + */ + open func defaultWidth() -> Double { + preconditionFailure("This method must be overridden") + } + + /** + * Get the grids + * + * @return grids + */ + open func grids() -> [BaseGrid] { + preconditionFailure("This method must be overridden") + } + + /** + * Create a new zoom grids + * + * @param zoom + * zoom level + * @return zoom grids + */ + open func newZoomGrids(_ zoom: Int) -> BaseZoomGrids { + preconditionFailure("This method must be overridden") + } + + /** + * Load the grid + * + * @param grid + * name + * @param gridKey + * grid name key + * @param enabled + * enable created grids + * @param labeler + * grid labeler + */ + public func loadGrid(_ grid: BaseGrid, _ gridKey: String, _ enabled: Bool?, _ labeler: Labeler?) { + + let gridKeyProperty = properties.combine(PropertyConstants.GRIDS, gridKey) + + var enabledValue = enabled + if enabledValue == nil { + enabledValue = properties.boolValue(gridKeyProperty, PropertyConstants.ENABLED, false) + if enabledValue == nil { + enabledValue = true + } + } + grid.enabled = enabledValue! + + var minZoom = properties.intValue(gridKeyProperty, PropertyConstants.MIN_ZOOM, false) + if minZoom == nil { + minZoom = 0 + } + grid.minZoom = minZoom! + + let maxZoom = properties.intValue(gridKeyProperty, PropertyConstants.MAX_ZOOM, false) + grid.maxZoom = maxZoom + + let linesProperty = properties.combine(gridKeyProperty, PropertyConstants.LINES) + + let linesMinZoom = properties.intValue(linesProperty, PropertyConstants.MIN_ZOOM, false) + grid.linesMinZoom = linesMinZoom + + let linesMaxZoom = properties.intValue(linesProperty, PropertyConstants.MAX_ZOOM, false) + grid.linesMaxZoom = linesMaxZoom + + let colorProperty = properties.value(gridKeyProperty, PropertyConstants.COLOR, false) + let color = colorProperty != nil ? CLRColor(hex: colorProperty).uiColor() : UIColor.black + grid.color = color + + var width = properties.doubleValue(gridKeyProperty, PropertyConstants.WIDTH, false) + if width == nil { + width = defaultWidth() + } + grid.width = width! + + if labeler != nil { + loadLabeler(labeler!, gridKey) + } + grid.labeler = labeler + + } + + /** + * Load the labeler + * + * @param labeler + * labeler + * @param gridKey + * grid name key + */ + public func loadLabeler(_ labeler: Labeler, _ gridKey: String) { + + let gridKeyProperty = properties.combine(PropertyConstants.GRIDS, gridKey) + let labelerProperty = properties.combine(gridKeyProperty, PropertyConstants.LABELER) + + let enabled = properties.boolValue(labelerProperty, PropertyConstants.ENABLED, false) + labeler.enabled = (enabled != nil) && enabled! + + let minZoom = properties.intValue(labelerProperty, PropertyConstants.MIN_ZOOM, false) + if minZoom != nil { + labeler.minZoom = minZoom! + } + + let maxZoom = properties.intValue(labelerProperty, PropertyConstants.MAX_ZOOM, false) + if maxZoom != nil { + labeler.maxZoom = maxZoom! + } + + let color = properties.value(labelerProperty, PropertyConstants.COLOR, false) + if color != nil { + labeler.color = CLRColor(hex: color).uiColor() + } + + let textSize = properties.doubleValue(labelerProperty, PropertyConstants.TEXT_SIZE, false) + if textSize != nil { + labeler.textSize = textSize! + } + + let buffer = properties.doubleValue(labelerProperty, PropertyConstants.BUFFER, false) + if buffer != nil { + labeler.buffer = buffer! + } + + } + + /** + * Load the grid style color + * + * @param gridKey + * grid name key + * @param gridKey2 + * second grid name key + * @return color + */ + public func loadGridStyleColor(_ gridKey: String, _ gridKey2: String) -> UIColor? { + + let gridKeyProperty = properties.combine(PropertyConstants.GRIDS, gridKey) + let gridKey2Property = properties.combine(gridKeyProperty, gridKey2) + + let colorProperty = properties.value(gridKey2Property, PropertyConstants.COLOR, false) + var color: UIColor? + if colorProperty != nil { + color = CLRColor(hex: colorProperty).uiColor() + } + return color + } + + /** + * Load the grid style width + * + * @param gridKey + * grid name key + * @param gridKey2 + * second grid name key + * @return width + */ + public func loadGridStyleWidth(_ gridKey: String, _ gridKey2: String) -> Double? { + + let gridKeyProperty = properties.combine(PropertyConstants.GRIDS, gridKey) + let gridKey2Property = properties.combine(gridKeyProperty, gridKey2) + + return properties.doubleValue(gridKey2Property, PropertyConstants.WIDTH, false) + } + + /** + * Get a combined grid style from the provided color, width, and grid + * + * @param color + * color + * @param width + * width + * @param grid + * grid + * @return grid style + */ + public func gridStyle(_ color: UIColor?, _ width: Double?, _ grid: BaseGrid) -> GridStyle { + + var colorValue = color + if colorValue == nil { + colorValue = grid.color + } + + var widthValue = width + if widthValue == nil || width == 0 { + widthValue = grid.width + } + + return GridStyle(colorValue, widthValue!) + } + + /** + * Create the zoom level grids + */ + public func createZoomGrids() { + for zoom in 0 ... GridConstants.MAX_MAP_ZOOM_LEVEL { + _ = createZoomGrids(zoom) + } + } + + /** + * Get the grids for the zoom level + * + * @param zoom + * zoom level + * @return grids + */ + open func grids(_ zoom: Int) -> BaseZoomGrids { + var grids = zoomGrids[zoom] + if grids == nil { + grids = createZoomGrids(zoom) + } + return grids! + } + + /** + * Create grids for the zoom level + * + * @param zoom + * zoom level + * @return grids + */ + private func createZoomGrids(_ zoom: Int) -> BaseZoomGrids { + let zoomLevelGrids = newZoomGrids(zoom) + for grid in grids() { + if grid.enabled && grid.isWithin(zoom) { + _ = zoomLevelGrids.addGrid(grid) + } + } + zoomGrids[zoom] = zoomLevelGrids + return zoomLevelGrids + } + + /** + * Enable grids + * + * @param grids + * grids + */ + public func enableGrids(_ grids: [BaseGrid]) { + for grid in grids { + enable(grid) + } + } + + /** + * Disable grids + * + * @param grids + * grids + */ + public func disableGrids(_ grids: [BaseGrid]) { + for grid in grids { + disable(grid) + } + } + + /** + * Enable the grid + * + * @param grid + * grid + */ + public func enable(_ grid: BaseGrid) { + + if !grid.enabled { + + grid.enabled = true + + let minZoom = grid.minZoom + var maxZoom = grid.maxZoom + if maxZoom == nil { + maxZoom = maxZoomLevel() + } + + for zoom in minZoom ... maxZoom! { + addGrid(grid, zoom) + } + + } + + } + + /** + * Disable the grid + * + * @param grid + * grid + */ + public func disable(_ grid: BaseGrid) { + + if grid.enabled { + + grid.enabled = false + + let minZoom = grid.minZoom + var maxZoom = grid.maxZoom + if maxZoom == nil { + maxZoom = maxZoomLevel() + } + + for zoom in minZoom ... maxZoom! { + removeGrid(grid, zoom) + } + + } + + } + + /** + * Get the sorted zoom levels + * + * @return zoom levels + */ + public func zoomLevels() -> [Int] { + return zoomGrids.keys.sorted() + } + + /** + * Get the min zoom level + * + * @return min zoom level + */ + public func minZoomLevel() -> Int { + return zoomLevels().first! + } + + /** + * Get the min zoom level + * + * @return min zoom level + */ + public func maxZoomLevel() -> Int { + return zoomLevels().last! + } + + /** + * Set the grid minimum zoom + * + * @param grid + * grid + * @param minZoom + * minimum zoom + */ + public func setMinZoom(_ grid: BaseGrid, _ minZoom: Int) { + var maxZoom = grid.maxZoom + if maxZoom != nil && maxZoom! < minZoom { + maxZoom = minZoom + } + setZoomRange(grid, minZoom, maxZoom) + } + + /** + * Set the grid maximum zoom + * + * @param grid + * grid + * @param maxZoom + * maximum zoom + */ + public func setMaxZoom(_ grid: BaseGrid, _ maxZoom: Int?) { + var minZoom = grid.minZoom + if maxZoom != nil && minZoom > maxZoom! { + minZoom = maxZoom! + } + setZoomRange(grid, minZoom, maxZoom) + } + + /** + * Set the grid zoom range + * + * @param grid + * grid + * @param minZoom + * minimum zoom + * @param maxZoom + * maximum zoom + */ + public func setZoomRange(_ grid: BaseGrid, _ minZoom: Int, _ maxZoom: Int?) { + + if maxZoom != nil && maxZoom! < minZoom { + preconditionFailure("Min zoom '\(minZoom)' can not be larger than max zoom '\(String(describing: maxZoom))\'") + } + + // All grids zoom range + let allGridsMin = minZoomLevel() + let allGridsMax = maxZoomLevel() + + // Existing grid zoom range + let gridMinZoom = grid.minZoom + let gridMaxZoom = grid.maxZoom == nil ? allGridsMax : min(grid.maxZoom!, allGridsMax) + + grid.minZoom = minZoom + grid.maxZoom = maxZoom + + let minZoomValue = max(minZoom, allGridsMin) + let maxZoomValue = maxZoom == nil ? allGridsMax : min(maxZoom!, allGridsMax) + + let minOverlap = max(minZoomValue, gridMinZoom) + let maxOverlap = min(maxZoomValue, gridMaxZoom) + + let overlaps = minOverlap <= maxOverlap + + if overlaps { + + let min = min(minZoomValue, gridMinZoom) + let max = max(maxZoomValue, gridMaxZoom) + + for zoom in min ... max { + + if zoom < minOverlap || zoom > maxOverlap { + + if zoom >= minZoomValue && zoom <= maxZoomValue { + addGrid(grid, zoom) + } else { + removeGrid(grid, zoom) + } + + } + + } + } else { + + for zoom in gridMinZoom ... gridMaxZoom { + removeGrid(grid, zoom) + } + + for zoom in minZoomValue ... maxZoomValue { + addGrid(grid, zoom) + } + + } + + } + + /** + * Add a grid to the zoom level + * + * @param grid + * grid + * @param zoom + * zoom level + */ + private func addGrid(_ grid: BaseGrid, _ zoom: Int) { + _ = zoomGrids[zoom]?.addGrid(grid) + } + + /** + * Remove a grid from the zoom level + * + * @param grid + * grid + * @param zoom + * zoom level + */ + private func removeGrid(_ grid: BaseGrid, _ zoom: Int) { + _ = zoomGrids[zoom]?.removeGrid(grid) + } + + /** + * Enable all grid labelers + */ + public func enableAllLabelers() { + for grid in grids() { + grid.labeler?.enabled = true + } + } + + /** + * Set all label grid edge buffers + * + * @param buffer + * label buffer (greater than or equal to 0.0 and less than 0.5) + */ + public func setAllLabelBuffers(_ buffer: Double) { + for grid in grids() { + grid.labeler?.buffer = buffer + } + } + +} diff --git a/Pods/grid-ios/grid-ios/BaseZoomGrids.swift b/Pods/grid-ios/grid-ios/BaseZoomGrids.swift new file mode 100644 index 0000000..4b604b8 --- /dev/null +++ b/Pods/grid-ios/grid-ios/BaseZoomGrids.swift @@ -0,0 +1,86 @@ +// +// BaseZoomGrids.swift +// grid-ios +// +// Created by Brian Osborn on 8/8/22. +// + +import Foundation + +/** + * Zoom Level Matching Grids + */ +open class BaseZoomGrids { + + /** + * Zoom level + */ + public let zoom: Int + + /** + * Grids + */ + private var _grids: Set = Set() + + /** + * Get the grids within the zoom level + * + * @return grids + */ + public var grids: [BaseGrid] { + get { + return _grids.sorted() + } + } + + /** + * Initialize + * + * @param zoom + * zoom level + */ + public init(_ zoom: Int) { + self.zoom = zoom + } + + /** + * Get the number of grids + * + * @return number of grids + */ + public func numGrids() -> Int { + return _grids.count + } + + /** + * Determine if the zoom level has grids + * + * @return true if has grids + */ + public func hasGrids() -> Bool { + return !_grids.isEmpty + } + + /** + * Add a grid + * + * @param grid + * grid + * @return true if added + */ + public func addGrid(_ grid: BaseGrid) -> Bool { + return _grids.insert(grid).inserted + } + + /** + * Remove the grid + * + * @param grid + * grid + * @return true if removed + */ + public func removeGrid(_ grid: BaseGrid) -> Bool { + return _grids.remove(grid) != nil + } + +} diff --git a/Pods/grid-ios/grid-ios/GridConstants.swift b/Pods/grid-ios/grid-ios/GridConstants.swift new file mode 100644 index 0000000..7e2d0f6 --- /dev/null +++ b/Pods/grid-ios/grid-ios/GridConstants.swift @@ -0,0 +1,76 @@ +// +// GridConstants.swift +// grid-ios +// +// Created by Brian Osborn on 8/4/22. +// + +import Foundation +import sf_ios + +/** + * Grid Constants + */ +public struct GridConstants { + + /** + * Minimum longitude + */ + public static let MIN_LON = -SF_WGS84_HALF_WORLD_LON_WIDTH + + /** + * Maximum longitude + */ + public static let MAX_LON = SF_WGS84_HALF_WORLD_LON_WIDTH + + /** + * Minimum latitude + */ + public static let MIN_LAT = -SF_WGS84_HALF_WORLD_LAT_HEIGHT + + /** + * Maximum latitude + */ + public static let MAX_LAT = SF_WGS84_HALF_WORLD_LAT_HEIGHT + + /** + * Omitted band letter 'I' + */ + public static let BAND_LETTER_OMIT_I: Character = "I" + + /** + * Omitted band letter 'O' + */ + public static let BAND_LETTER_OMIT_O: Character = "O" + + /** + * Max map zoom level + */ + public static let MAX_MAP_ZOOM_LEVEL = 21 + + /** + * North single character as a string + */ + public static let NORTH_CHAR = "N" + + /** + * South single character as a string + */ + public static let SOUTH_CHAR = "S" + + /** + * West single character as a string + */ + public static let WEST_CHAR = "W" + + /** + * East single character as a string + */ + public static let EAST_CHAR = "E" + + /** + * Mercator radius + */ + public static let MERCATOR_RADIUS = 85445659.44705395 + +} diff --git a/Pods/grid-ios/grid-ios/GridStyle.swift b/Pods/grid-ios/grid-ios/GridStyle.swift new file mode 100644 index 0000000..177f9a2 --- /dev/null +++ b/Pods/grid-ios/grid-ios/GridStyle.swift @@ -0,0 +1,46 @@ +// +// GridStyle.swift +// grid-ios +// +// Created by Brian Osborn on 8/5/22. +// + +import Foundation +import color_ios + +/** + * Grid Line Style + */ +public class GridStyle { + + /** + * Grid line color + */ + public var color: UIColor? + + /** + * Grid line width + */ + public var width: Double = 0 + + /** + * Initialize + */ + public init() { + + } + + /** + * Initialize + * + * @param color + * color + * @param width + * width + */ + public init(_ color: UIColor?, _ width: Double) { + self.color = color + self.width = width + } + +} diff --git a/Pods/grid-ios/grid-ios/GridUtils.swift b/Pods/grid-ios/grid-ios/GridUtils.swift new file mode 100644 index 0000000..064742b --- /dev/null +++ b/Pods/grid-ios/grid-ios/GridUtils.swift @@ -0,0 +1,375 @@ +// +// GridUtils.swift +// grid-ios +// +// Created by Brian Osborn on 8/4/22. +// + +import Foundation +import sf_ios + +/** + * Grid utilities + */ +public class GridUtils { + + /** + * Get the pixel where the point fits into the bounds + * + * @param width + * width + * @param height + * height + * @param bounds + * bounds + * @param point + * point + * @return pixel + */ + public static func pixel(_ width: Int, _ height: Int, _ bounds: Bounds, _ point: GridPoint) -> Pixel { + + let pointMeters = point.toMeters() + let boundsMeters = bounds.toMeters() + + let x = xPixel(width, boundsMeters, pointMeters.longitude) + let y = yPixel(height, boundsMeters, pointMeters.latitude) + return Pixel(x, y) + } + + /** + * Get the X pixel for where the longitude in meters fits into the bounds + * + * @param width + * width + * @param bounds + * bounds + * @param longitude + * longitude in meters + * @return x pixel + */ + public static func xPixel(_ width: Int, _ bounds: Bounds, _ longitude: Double) -> Float { + + let boundsMeters = bounds.toMeters() + + let boxWidth = boundsMeters.maxLongitude - boundsMeters.minLongitude + let offset = longitude - boundsMeters.minLongitude + let percentage = offset / boxWidth + let pixel = Float(percentage * Double(width)) + + return pixel + } + + /** + * Get the Y pixel for where the latitude in meters fits into the bounds + * + * @param height + * height + * @param bounds + * bounds + * @param latitude + * latitude + * @return y pixel + */ + public static func yPixel(_ height: Int, _ bounds: Bounds, _ latitude: Double) -> Float { + + let boundsMeters = bounds.toMeters() + + let boxHeight = boundsMeters.maxLatitude - boundsMeters.minLatitude + let offset = boundsMeters.maxLatitude - latitude + let percentage = offset / boxHeight + let pixel = Float(percentage * Double(height)) + + return pixel + } + + /** + * Get the tile bounds from the XYZ tile coordinates and zoom level + * + * @param x + * x coordinate + * @param y + * y coordinate + * @param zoom + * zoom level + * @return bounds + */ + public static func bounds(_ x: Int, _ y: Int, _ zoom: Int) -> Bounds { + + let tilesPerSide = tilesPerSide(zoom) + let tileSize = tileSize(tilesPerSide) + + let minLon = (-1 * SF_WEB_MERCATOR_HALF_WORLD_WIDTH) + (Double(x) * tileSize) + let minLat = SF_WEB_MERCATOR_HALF_WORLD_WIDTH - (Double(y + 1) * tileSize) + let maxLon = (-1 * SF_WEB_MERCATOR_HALF_WORLD_WIDTH) + (Double(x + 1) * tileSize) + let maxLat = SF_WEB_MERCATOR_HALF_WORLD_WIDTH - (Double(y) * tileSize) + + return Bounds.meters(minLon, minLat, maxLon, maxLat) + } + + /** + * Get the tiles per side, width and height, at the zoom level + * + * @param zoom + * zoom level + * @return tiles per side + */ + public static func tilesPerSide(_ zoom: Int) -> Int { + return Int(pow(2, Double(zoom))) + } + + /** + * Get the tile size in meters + * + * @param tilesPerSide + * tiles per side + * @return tile size + */ + public static func tileSize(_ tilesPerSide: Int) -> Double { + return (2 * SF_WEB_MERCATOR_HALF_WORLD_WIDTH) / Double(tilesPerSide) + } + + /** + * Get the zoom level of the bounds using the shortest bounds side length + * + * @param bounds + * bounds + * @return zoom level + */ + public static func zoomLevel(_ bounds: Bounds) -> Double { + let boundsMeters = bounds.toMeters() + let tileSize = min(boundsMeters.width, boundsMeters.height) + let tilesPerSide = 2 * SF_WEB_MERCATOR_HALF_WORLD_WIDTH / tileSize + return log(tilesPerSide) / log(2) + } + + /** + * Convert a coordinate from a unit to another unit + * + * @param fromUnit + * unit of provided coordinate + * @param longitude + * longitude + * @param latitude + * latitude + * @param toUnit + * desired unit + * @return point in unit + */ + public static func toUnit(_ fromUnit: Unit, _ longitude: Double, _ latitude: Double, _ toUnit: Unit) -> GridPoint { + var point: GridPoint + if fromUnit == toUnit { + point = GridPoint(longitude, latitude, toUnit) + } else { + point = self.toUnit(longitude, latitude, toUnit) + } + return point + } + + /** + * Convert a coordinate to the unit, assumes the coordinate is in the + * opposite unit + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param unit + * desired unit + * @return point in unit + */ + public static func toUnit(_ longitude: Double, _ latitude: Double, + _ unit: Unit) -> GridPoint { + var point: SFPoint + switch unit { + case .DEGREE: + point = SFGeometryUtils.metersToDegreesWith(x: longitude, andY: latitude) + case .METER: + point = SFGeometryUtils.degreesToMetersWith(x: longitude, andY: latitude) + } + return GridPoint(point, unit) + } + + /** + * Is the band letter an omitted letter + * GridConstants.BAND_LETTER_OMIT_I or + * GridConstants.BAND_LETTER_OMIT_O + * + * @param letter + * band letter + * @return true if omitted + */ + public static func isOmittedBandLetter(_ letter: Character) -> Bool { + return letter == GridConstants.BAND_LETTER_OMIT_I || letter == GridConstants.BAND_LETTER_OMIT_O + } + + /** + * Get the precision value before the value + * + * @param value + * value + * @param precision + * precision + * @return precision value + */ + public static func precisionBefore(_ value: Double, _ precision: Double) -> Double { + var before = 0.0 + if abs(value) >= precision { + before = value - ((value.truncatingRemainder(dividingBy: precision) + precision).truncatingRemainder(dividingBy: precision)) + } else if value < 0.0 { + before = -precision + } + return before + } + + /** + * Get the precision value after the value + * + * @param value + * value + * @param precision + * precision + * @return precision value + */ + public static func precisionAfter(_ value: Double, _ precision: Double) -> Double { + return precisionBefore(value + precision, precision) + } + + /** + * Get the point intersection between two lines + * + * @param line1 + * first line + * @param line2 + * second line + * @return intersection point or null if no intersection + */ + public static func intersection(_ line1: Line, _ line2: Line) -> GridPoint? { + return intersection(line1.point1, line1.point2, line2.point1, line2.point2) + } + + /** + * Get the point intersection between end points of two lines + * + * @param line1Point1 + * first point of the first line + * @param line1Point2 + * second point of the first line + * @param line2Point1 + * first point of the second line + * @param line2Point2 + * second point of the second line + * @return intersection point or null if no intersection + */ + public static func intersection(_ line1Point1: GridPoint, _ line1Point2: GridPoint, _ line2Point1: GridPoint, _ line2Point2: GridPoint) -> GridPoint? { + + var intersection: GridPoint? = nil + + let point: SFPoint? = SFGeometryUtils.intersectionBetweenLine1Point1(line1Point1.toMeters(), andLine1Point2: line1Point2.toMeters(), andLine2Point1: line2Point1.toMeters(), andLine2Point2: line2Point2.toMeters()) + + if point != nil { + intersection = GridPoint(point!, Unit.METER).toUnit(line1Point1.unit) + } + + return intersection + } + + /** + * Increment the ASCII character by one + * + * @param character + * starting character + * @return next character + */ + public static func incrementCharacter(_ character: Character) -> Character { + return incrementCharacter(character, 1) + } + + /** + * Decrement the ASCII character by one + * + * @param character + * starting character + * @return previous character + */ + public static func decrementCharacter(_ character: Character) -> Character { + return incrementCharacter(character, -1) + } + + /** + * Increment the ASCII character + * + * @param character + * starting character + * @param increment + * ASCII increment, positive or negative for decrement + * @return incremented character + */ + public static func incrementCharacter(_ character: Character, _ increment: Int) -> Character { + var characterValue = Int(character.asciiValue!) + characterValue += increment + return Character(UnicodeScalar(characterValue)!) + } + + /** + * Get the character at the index in a string + * + * @param value + * string value + * @param index + * character index + * @return character at index + */ + public static func charAt(_ value: String, _ index: Int) -> Character { + return value[value.index(value.startIndex, offsetBy: index)] + } + + /** + * Get the first index of the character in the string, or -1 if not contained + * + * @param value + * string value + * @param char + * character + * @return index of character or -1 + */ + public static func indexOf(_ value: String, _ char: Character) -> Int { + var index = -1 + let firstIndex = value.firstIndex(of: char) + if firstIndex != nil { + index = firstIndex!.utf16Offset(in: value) + } + return index + } + + /** + * Get a substring of the string value from the inclusive begin index to the exclusive end index + * + * @param value + * string value + * @param beginIndex + * begin index, inclusive + * @param endIndex + * end index, exclusive + * @return substring as a string + */ + public static func substring(_ value: String, _ beginIndex: Int, _ endIndex: Int) -> String { + let start = value.index(value.startIndex, offsetBy: beginIndex) + let end = value.index(value.startIndex, offsetBy: endIndex) + let range = start.. String { + return substring(value, beginIndex, value.count) + } + +} diff --git a/Pods/grid-ios/grid-ios/Hemisphere.swift b/Pods/grid-ios/grid-ios/Hemisphere.swift new file mode 100644 index 0000000..0685576 --- /dev/null +++ b/Pods/grid-ios/grid-ios/Hemisphere.swift @@ -0,0 +1,51 @@ +// +// Hemisphere.swift +// grid-ios +// +// Created by Brian Osborn on 8/5/22. +// + +import Foundation + +/** + * Hemisphere enumeration + */ +public enum Hemisphere: Int { + + /** + * Northern hemisphere + */ + case NORTH + + /** + * Southern hemisphere + */ + case SOUTH + + /** + * Get the hemisphere for the latitude + * + * @param latitude + * latitude + * @return hemisphere + */ + public static func from(_ latitude: Double) -> Hemisphere { + return latitude >= 0 ? Hemisphere.NORTH : Hemisphere.SOUTH + } + + /** + * Get the hemisphere for the point + * + * @param point + * point + * @return hemisphere + */ + public static func from(_ point: GridPoint) -> Hemisphere { + return from(point.latitude) + } + + var name: String { + get { return String(describing: self) } + } + +} diff --git a/Pods/grid-ios/grid-ios/Label.swift b/Pods/grid-ios/grid-ios/Label.swift new file mode 100644 index 0000000..303efa1 --- /dev/null +++ b/Pods/grid-ios/grid-ios/Label.swift @@ -0,0 +1,50 @@ +// +// Label.swift +// grid-ios +// +// Created by Brian Osborn on 8/5/22. +// + +import Foundation + +/** + * Grid Label + */ +open class Label { + + /** + * Name + */ + public var name: String + + /** + * Center point + */ + public var center: GridPoint + + /** + * Bounds + */ + public var bounds: Bounds + + /** + * Initialize + * + * @param width + * tile width + * @param height + * tile height + * @param x + * x coordinate + * @param y + * y coordinate + * @param zoom + * zoom level + */ + public init(_ name: String, _ center: GridPoint, _ bounds: Bounds) { + self.name = name + self.center = center + self.bounds = bounds + } + +} diff --git a/Pods/grid-ios/grid-ios/Labeler.swift b/Pods/grid-ios/grid-ios/Labeler.swift new file mode 100644 index 0000000..fbd2cff --- /dev/null +++ b/Pods/grid-ios/grid-ios/Labeler.swift @@ -0,0 +1,134 @@ +// +// Labeler.swift +// grid-ios +// +// Created by Brian Osborn on 8/5/22. +// + +import Foundation +import color_ios + +/** + * Grid Labeler + */ +open class Labeler { + + /** + * Enabled labeler + */ + public var enabled: Bool + + /** + * Minimum zoom level + */ + public var minZoom: Int + + /** + * Maximum zoom level + */ + public var maxZoom: Int? + + /** + * Label color + */ + public var color: UIColor? + + /** + * Label text size + */ + public var textSize: Double + + /** + * Grid edge buffer (greater than or equal to 0.0 and less than 0.5) + */ + public var buffer: Double { + willSet { + if newValue < 0.0 || newValue >= 0.5 { + preconditionFailure("Grid edge buffer must be >= 0 and < 0.5. buffer: \(newValue)") + } + } + } + + /** + * Initialize + * + * @param minZoom + * minimum zoom + * @param color + * label color + * @param textSize + * label text size + * @param buffer + * grid edge buffer (greater than or equal to 0.0 and less than + * 0.5) + */ + public convenience init(_ minZoom: Int, _ color: UIColor?, _ textSize: Double, _ buffer: Double) { + self.init(minZoom, nil, color, textSize, buffer) + } + + /** + * Initialize + * + * @param minZoom + * minimum zoom + * @param maxZoom + * maximum zoom + * @param color + * label color + * @param textSize + * label text size + * @param buffer + * grid edge buffer (greater than or equal to 0.0 and less than + * 0.5) + */ + public convenience init(_ minZoom: Int, _ maxZoom: Int?, _ color: UIColor?, _ textSize: Double, _ buffer: Double) { + self.init(true, minZoom, maxZoom, color, textSize, buffer) + } + + /** + * Initialize + * + * @param enabled + * enabled labeler + * @param minZoom + * minimum zoom + * @param maxZoom + * maximum zoom + * @param color + * label color + * @param textSize + * label text size + * @param buffer + * grid edge buffer (greater than or equal to 0.0 and less than + * 0.5) + */ + public init(_ enabled: Bool, _ minZoom: Int, _ maxZoom: Int?, _ color: UIColor?, _ textSize: Double, _ buffer: Double) { + self.enabled = enabled + self.minZoom = minZoom + self.maxZoom = maxZoom + self.color = color + self.textSize = textSize + self.buffer = buffer + } + + /** + * Has a maximum zoom level + * + * @return true if has a maximum, false if unbounded + */ + public func hasMaxZoom() -> Bool { + return maxZoom != nil + } + + /** + * Is the zoom level within the grid zoom range + * + * @param zoom + * zoom level + * @return true if within range + */ + public func isWithin(_ zoom: Int) -> Bool { + return zoom >= minZoom && (maxZoom == nil || zoom <= maxZoom!) + } + +} diff --git a/Pods/grid-ios/grid-ios/features/Bounds.swift b/Pods/grid-ios/grid-ios/features/Bounds.swift new file mode 100644 index 0000000..0bc6937 --- /dev/null +++ b/Pods/grid-ios/grid-ios/features/Bounds.swift @@ -0,0 +1,586 @@ +// +// Bounds.swift +// grid-ios +// +// Created by Brian Osborn on 8/3/22. +// + +import Foundation +import sf_ios + +/** + * Grid Bounds + */ +public class Bounds: SFGeometryEnvelope { + + /** + * Create bounds in degrees + * + * @param minLongitude + * min longitude + * @param minLatitude + * min latitude + * @param maxLongitude + * max longitude + * @param maxLatitude + * max latitude + * @return bounds + */ + public static func degrees(_ minLongitude: Double, _ minLatitude: Double, _ maxLongitude: Double, _ maxLatitude: Double) -> Bounds { + return Bounds(minLongitude, minLatitude, maxLongitude, maxLatitude, Unit.DEGREE) + } + + /** + * Create bounds in meters + * + * @param minLongitude + * min longitude + * @param minLatitude + * min latitude + * @param maxLongitude + * max longitude + * @param maxLatitude + * max latitude + * @return bounds + */ + public static func meters(_ minLongitude: Double, _ minLatitude: Double, _ maxLongitude: Double, _ maxLatitude: Double) -> Bounds { + return Bounds(minLongitude, minLatitude, maxLongitude, maxLatitude, Unit.METER) + } + + /** + * Unit + */ + public var unit: Unit + + /** + * The min longitude + */ + public var minLongitude: Double { + get { + return minX.doubleValue + } + set(minLongitude) { + setMinXValue(minLongitude) + } + } + + /** + * The min latitude + */ + public var minLatitude: Double { + get { + return minY.doubleValue + } + set(minLatitude) { + setMinYValue(minLatitude) + } + } + + /** + * The max longitude + */ + public var maxLongitude: Double { + get { + return maxX.doubleValue + } + set(maxLongitude) { + setMaxXValue(maxLongitude) + } + } + + /** + * The max latitude + */ + public var maxLatitude: Double { + get { + return maxY.doubleValue + } + set(maxLatitude) { + setMaxYValue(maxLatitude) + } + } + + /** + * The western longitude + * + * @return western longitude + */ + public var west: Double { + get { + return minLongitude + } + set(west) { + minLongitude = west + } + } + + /** + * The southern longitude + * + * @return southern longitude + */ + public var south: Double { + get { + return minLatitude + } + set(south) { + minLatitude = south + } + } + + /** + * The eastern longitude + * + * @return eastern longitude + */ + public var east: Double { + get { + return maxLongitude + } + set(east) { + maxLongitude = east + } + } + + /** + * The northern longitude + * + * @return northern longitude + */ + public var north: Double { + get { + return maxLatitude + } + set(north) { + maxLatitude = north + } + } + + /** + * The width + */ + public var width: Double { + get { + return xRange() + } + } + + /** + * The height + */ + public var height: Double { + get { + return yRange() + } + } + + /** + * The southwest coordinate + * + * @return southwest coordinate + */ + public var southwest: GridPoint { + get { + return GridPoint(minLongitude, minLatitude, unit) + } + } + + /** + * The northwest coordinate + * + * @return northwest coordinate + */ + public var northwest: GridPoint { + get { + return GridPoint(minLongitude, maxLatitude, unit) + } + } + + /** + * The southeast coordinate + * + * @return southeast coordinate + */ + public var southeast: GridPoint { + get { + return GridPoint(maxLongitude, minLatitude, unit) + } + } + + /** + * The northeast coordinate + * + * @return northeast coordinate + */ + public var northeast: GridPoint { + get { + return GridPoint(maxLongitude, maxLatitude, unit) + } + } + + /** + * Initialize + * + * @param minLongitude + * min longitude + * @param minLatitude + * min latitude + * @param maxLongitude + * max longitude + * @param maxLatitude + * max latitude + */ + public convenience init(_ minLongitude: Double, _ minLatitude: Double, _ maxLongitude: Double, _ maxLatitude: Double) { + self.init(minLongitude, minLatitude, maxLongitude, maxLatitude, Unit.DEGREE) + } + + /** + * Initialize + * + * @param minLongitude + * min longitude + * @param minLatitude + * min latitude + * @param maxLongitude + * max longitude + * @param maxLatitude + * max latitude + * @param unit + * unit + */ + public init(_ minLongitude: Double, _ minLatitude: Double, _ maxLongitude: Double, _ maxLatitude: Double, _ unit: Unit) { + self.unit = unit + super.init(minX: NSDecimalNumber.init(value: minLongitude), andMinY: NSDecimalNumber.init(value: minLatitude), andMinZ: nil, andMinM: nil, andMaxX: NSDecimalNumber.init(value: maxLongitude), andMaxY: NSDecimalNumber.init(value: maxLatitude), andMaxZ: nil, andMaxM: nil) + } + + /** + * Initialize + * + * @param southwest + * southwest corner + * @param northeast + * northeast corner + */ + public convenience init(_ southwest: GridPoint, _ northeast: GridPoint) { + self.init(southwest.longitude, southwest.latitude, northeast.longitude, northeast.latitude, southwest.unit) + + if !isUnit(northeast.unit) { + preconditionFailure("Points are in different units. southwest: \(String(describing: unit)), northeast: \(String(describing: northeast.unit))") + } + } + + /** + * Initialize + * + * @param point + * point to copy + */ + public convenience init(_ bounds: Bounds) { + self.init(bounds, bounds.unit) + } + + /** + * Initialize + * + * @param envelope + * geometry envelope + * @param unit + * unit + */ + public init(_ envelope: SFGeometryEnvelope, _ unit: Unit) { + self.unit = unit + super.init(minX: envelope.minX, andMinY: envelope.minY, andMinZ: envelope.minZ, andMinM: envelope.minM, andMaxX: envelope.maxX, andMaxY: envelope.maxY, andMaxZ: envelope.maxZ, andMaxM: envelope.maxM) + } + + /** + * Is in the provided unit type + * + * @param unit + * unit + * @return true if in the unit + */ + public func isUnit(_ unit: Unit) -> Bool { + return self.unit == unit + } + + /** + * Are bounds in degrees + * + * @return true if degrees + */ + public func isDegrees() -> Bool { + return isUnit(Unit.DEGREE) + } + + /** + * Are bounds in meters + * + * @return true if meters + */ + public func isMeters() -> Bool { + return isUnit(Unit.METER) + } + + /** + * Convert to the unit + * + * @param unit + * unit + * @return bounds in units, same bounds if equal units + */ + public func toUnit(_ unit: Unit) -> Bounds { + var bounds: Bounds + if isUnit(unit) { + bounds = self + } else { + let sw: GridPoint = southwest.toUnit(unit) + let ne: GridPoint = northeast.toUnit(unit) + bounds = Bounds(sw, ne) + } + return bounds + } + + /** + * Convert to degrees + * + * @return bounds in degrees, same bounds if already in degrees + */ + public func toDegrees() -> Bounds { + return toUnit(Unit.DEGREE) + } + + /** + * Convert to meters + * + * @return bounds in meters, same bounds if already in meters + */ + public func toMeters() -> Bounds { + return toUnit(Unit.METER) + } + + /** + * Get the centroid longitude + * + * @return centroid longitude + */ + public func centroidLongitude() -> Double { + return midX() + } + + /** + * Get the centroid latitude + * + * @return centroid latitude + */ + public func centroidLatitude() -> Double { + var centerLatitude: Double + if unit == Unit.DEGREE { + centerLatitude = centroid().latitude + } else { + centerLatitude = midY() + } + return centerLatitude + } + + public override func centroid() -> GridPoint { + var point: GridPoint + if unit == Unit.DEGREE { + point = toMeters().centroid().toDegrees() + } else { + point = GridPoint(super.centroid(), unit) + } + return point + } + + /** + * Create a new bounds as the overlapping between this bounds and the + * provided + * + * @param bounds + * bounds + * @return overlap bounds + */ + public func overlap(_ bounds: Bounds) -> Bounds? { + + var overlap: Bounds? + + let overlapEnvelope: SFGeometryEnvelope? = super.overlap(with: bounds.toUnit(unit), withAllowEmpty: true) + if overlapEnvelope != nil { + overlap = Bounds(overlapEnvelope!, unit) + } + + return overlap + } + + /** + * Create a new bounds as the union between this bounds and the provided + * + * @param bounds + * bounds + * @return union bounds + */ + public func union(_ bounds: Bounds) -> Bounds? { + + var union: Bounds? + + let unionEnvelope: SFGeometryEnvelope? = super.union(with: bounds.toUnit(unit)) + if unionEnvelope != nil { + union = Bounds(unionEnvelope!, unit) + } + + return union + } + + /** + * Get the western line + * + * @return west line + */ + public func westLine() -> Line { + return grid_ios.Line(northwest, southwest) + } + + /** + * Get the southern line + * + * @return south line + */ + public func southLine() -> Line { + return grid_ios.Line(southwest, southeast) + } + + /** + * Get the eastern line + * + * @return east line + */ + public func eastLine() -> Line { + return grid_ios.Line(southeast, northeast) + } + + /** + * Get the northern line + * + * @return north line + */ + public func northLine() -> Line { + return grid_ios.Line(northeast, northwest) + } + + /** + * Convert the bounds to be precision accurate minimally containing the + * bounds. Each bound is equal to or larger by the precision degree amount. + * + * @param precision + * precision in degrees + * @return precision bounds + */ + public func toPrecision(_ precision: Double) -> Bounds { + + let boundsDegrees = toDegrees() + + let minLon = GridUtils.precisionBefore(boundsDegrees.minLongitude, precision) + let minLat = GridUtils.precisionBefore(boundsDegrees.minLatitude, precision) + let maxLon = GridUtils.precisionAfter(boundsDegrees.maxLongitude, precision) + let maxLat = GridUtils.precisionAfter(boundsDegrees.maxLatitude, precision) + + return Bounds.degrees(minLon, minLat, maxLon, maxLat) + } + + /** + * Get the pixel range where the bounds fit into the tile + * + * @param tile + * tile + * @return pixel range + */ + public func pixelRange(_ tile: GridTile) -> PixelRange { + return pixelRange(tile.width, tile.height, tile.bounds) + } + + /** + * Get the pixel range where the bounds fit into the provided bounds + * + * @param width + * width + * @param height + * height + * @param bounds + * bounds + * @return pixel range + */ + public func pixelRange(_ width: Int, _ height: Int, _ bounds: Bounds) -> PixelRange { + let boundsMeters = bounds.toMeters() + let topLeft = GridUtils.pixel(width, height, boundsMeters, northwest) + let bottomRight = GridUtils.pixel(width, height, boundsMeters, southeast) + return PixelRange(topLeft, bottomRight) + } + + /** + * Get the four line bounds in meters + * + * @return lines + */ + public func lines() -> [Line] { + + let southwest = southwest + let northwest = northwest + let northeast = northeast + let southeast = southeast + + var lines: [Line] = [] + lines.append(Line(southwest, northwest)) + lines.append(Line(northwest, northeast)) + lines.append(Line(northeast, southeast)) + lines.append(Line(southeast, southwest)) + + return lines + } + + public override func mutableCopy(with zone: NSZone? = nil) -> Any { + return Bounds(self) + } + + public override func encode(with coder: NSCoder) { + coder.encode(unit.rawValue, forKey: "unit") + super.encode(with: coder) + } + + public required init?(coder: NSCoder) { + unit = Unit.init(rawValue: coder.decodeInteger(forKey: "unit"))! + super.init(coder: coder) + } + + public func isEqual(_ bounds: Bounds?) -> Bool { + if self == bounds { + return true + } + if bounds == nil { + return false + } + if !super.isEqual(bounds) { + return false + } + if unit != bounds?.unit { + return false + } + return true + } + + public override func isEqual(_ object: Any?) -> Bool { + + if !(object is Bounds) { + return false + } + + return isEqual(object as? Bounds) + } + + public override var hash: Int { + let prime = 31 + var result = super.hash + result = prime * result + unit.rawValue + return result + } + +} diff --git a/Pods/grid-ios/grid-ios/features/GridPoint.swift b/Pods/grid-ios/grid-ios/features/GridPoint.swift new file mode 100644 index 0000000..4715827 --- /dev/null +++ b/Pods/grid-ios/grid-ios/features/GridPoint.swift @@ -0,0 +1,327 @@ +// +// GridPoint.swift +// grid-ios +// +// Created by Brian Osborn on 8/3/22. +// + +import Foundation +import sf_ios +import MapKit + +/** + * Point + */ +public class GridPoint: SFPoint { + + /** + * Create a point in degrees + * + * @param longitude + * longitude in degrees + * @param latitude + * latitude in degrees + * @return point in degrees + */ + public static func degrees(_ longitude: Double, _ latitude: Double) -> GridPoint { + return GridPoint(longitude, latitude, Unit.DEGREE) + } + + /** + * Create a point in meters + * + * @param longitude + * longitude in meters + * @param latitude + * latitude in meters + * @return point in meters + */ + public static func meters(_ longitude: Double, _ latitude: Double) -> GridPoint { + return GridPoint(longitude, latitude, Unit.METER) + } + + /** + * Create a point from a coordinate in a unit to another unit + * + * @param fromUnit + * unit of provided coordinate + * @param longitude + * longitude + * @param latitude + * latitude + * @param toUnit + * desired unit + * @return point in unit + */ + public static func toUnit(_ fromUnit: Unit, _ longitude: Double, _ latitude: Double, _ toUnit: Unit) -> GridPoint { + return GridUtils.toUnit(fromUnit, longitude, latitude, toUnit) + } + + /** + * Create a point from a coordinate in an opposite unit to another unit + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param unit + * desired unit + * @return point in unit + */ + public static func toUnit(_ longitude: Double, _ latitude: Double, _ unit: Unit) -> GridPoint { + return GridUtils.toUnit(longitude, latitude, unit) + } + + /** + * Create a point converting the degrees coordinate to meters + * + * @param longitude + * longitude in degrees + * @param latitude + * latitude in degrees + * @return point in meters + */ + public static func degreesToMeters(_ longitude: Double, _ latitude: Double) -> GridPoint { + return toUnit(Unit.DEGREE, longitude, latitude, Unit.METER) + } + + /** + * Create a point converting the meters coordinate to degrees + * + * @param longitude + * longitude in meters + * @param latitude + * latitude in meters + * @return point in degrees + */ + public static func metersToDegrees(_ longitude: Double, _ latitude: Double) -> GridPoint { + return toUnit(Unit.METER, longitude, latitude, Unit.DEGREE) + } + + /** + * Unit + */ + public var unit: Unit + + /** + * The longitude + */ + public var longitude: Double { + get { + return x.doubleValue + } + set(longitude) { + setXValue(longitude) + } + } + + /** + * The latitude + */ + public var latitude: Double { + get { + return y.doubleValue + } + set(latitude) { + setYValue(latitude) + } + } + + /** + * Initialize, in DEGREE units + * + * @param longitude + * longitude + * @param latitude + * latitude + */ + public convenience init(_ longitude: Double, _ latitude: Double) { + self.init(longitude, latitude, Unit.DEGREE) + } + + /** + * Initialize + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param unit + * unit + */ + public init(_ longitude: Double, _ latitude: Double, _ unit: Unit) { + self.unit = unit + super.init(hasZ: false, andHasM: false, andX: NSDecimalNumber.init(value: longitude), andY: NSDecimalNumber.init(value: latitude)) + } + + /** + * Initialize + * + * @param point + * point to copy + */ + public convenience init(_ point: GridPoint) { + self.init(point, point.unit) + } + + /** + * Initialize + * + * @param point + * point to copy + * @param unit + * unit + */ + public init(_ point: SFPoint, _ unit: Unit) { + self.unit = unit + super.init(hasZ: point.hasZ, andHasM: point.hasM, andX: point.x, andY: point.y) + z = point.z + m = point.m + } + + /** + * Is in the provided unit type + * + * @param unit + * unit + * @return true if in the unit + */ + public func isUnit(_ unit: Unit) -> Bool { + return self.unit == unit + } + + /** + * Is this point in degrees + * + * @return true if degrees + */ + public func isDegrees() -> Bool { + return isUnit(Unit.DEGREE) + } + + /** + * Is this point in meters + * + * @return true if meters + */ + public func isMeters() -> Bool { + return isUnit(Unit.METER) + } + + /** + * Convert to the unit + * + * @param unit + * unit + * @return point in units, same point if equal units + */ + public func toUnit(_ unit: Unit) -> GridPoint { + var point: GridPoint + if isUnit(unit) { + point = self + } else { + point = GridUtils.toUnit(self.unit, longitude, latitude, unit) + } + return point + } + + /** + * Convert to degrees + * + * @return point in degrees, same point if already in degrees + */ + public func toDegrees() -> GridPoint { + return toUnit(Unit.DEGREE) + } + + /** + * Convert to meters + * + * @return point in meters, same point if already in meters + */ + public func toMeters() -> GridPoint { + return toUnit(Unit.METER) + } + + /** + * Get the pixel where the point fits into tile + * + * @param tile + * tile + * @return pixel + */ + public func pixel(_ tile: GridTile) -> Pixel { + return pixel(tile.width, tile.height, tile.bounds) + } + + /** + * Get the pixel where the point fits into the bounds + * + * @param width + * width + * @param height + * height + * @param bounds + * bounds + * @return pixel + */ + public func pixel(_ width: Int, _ height: Int, _ bounds: Bounds) -> Pixel { + return GridUtils.pixel(width, height, bounds, self) + } + + /** + * Convert to a location coordinate + * + * @return coordinate + */ + public func toCoordinate() -> CLLocationCoordinate2D { + return TileUtils.toCoordinate(self) + } + + public override func mutableCopy(with zone: NSZone? = nil) -> Any { + return GridPoint(self) + } + + public override func encode(with coder: NSCoder) { + coder.encode(unit.rawValue, forKey: "unit") + super.encode(with: coder) + } + + public required init?(coder: NSCoder) { + unit = Unit.init(rawValue: coder.decodeInteger(forKey: "unit"))! + super.init(coder: coder) + } + + public func isEqual(_ point: GridPoint?) -> Bool { + if self == point { + return true + } + if point == nil { + return false + } + if !super.isEqual(point) { + return false + } + if unit != point?.unit { + return false + } + return true + } + + public override func isEqual(_ object: Any?) -> Bool { + + if !(object is GridPoint) { + return false + } + + return isEqual(object as? GridPoint) + } + + public override var hash: Int { + let prime = 31 + var result = super.hash + result = prime * result + unit.rawValue + return result + } + +} diff --git a/Pods/grid-ios/grid-ios/features/Line.swift b/Pods/grid-ios/grid-ios/features/Line.swift new file mode 100644 index 0000000..e007bcc --- /dev/null +++ b/Pods/grid-ios/grid-ios/features/Line.swift @@ -0,0 +1,212 @@ +// +// Line.swift +// grid-ios +// +// Created by Brian Osborn on 8/4/22. +// + +import Foundation +import sf_ios + +/** + * Line between two points + */ +open class Line: SFLine { + + /** + * The first point + */ + public var point1: GridPoint { + get { + return startPoint() as! GridPoint + } + set(point1) { + setPoints(point1, point2) + } + } + + /** + * The second point + */ + public var point2: GridPoint { + get { + return endPoint() as! GridPoint + } + set(point2) { + setPoints(point1, point2) + } + } + + /** + * The unit + */ + public var unit: Unit { + get { + return point1.unit + } + } + + /** + * Initialize + * + * @param point1 + * first point + * @param point2 + * second point + */ + public init(_ point1: GridPoint, _ point2: GridPoint) { + super.init(type:SF_LINESTRING, andHasZ: false, andHasM: false) + setPoints(point1, point2) + } + + /** + * Initialize + * + * @param line + * line to copy + */ + public init(_ line: Line) { + super.init(type:SF_LINESTRING, andHasZ: line.hasZ, andHasM: line.hasM) + setPoints(line.point1, line.point2) + } + + /** + * Set the points + * + * @param point1 + * first point + * @param point2 + * second point + */ + public func setPoints(_ point1: GridPoint, _ point2: GridPoint) { + var linePoints: [GridPoint] = [] + linePoints.append(point1) + linePoints.append(point2) + points = NSMutableArray(array: linePoints) + validateUnits() + } + + /** + * Is in the provided unit type + * + * @param unit + * unit + * @return true if in the unit + */ + public func isUnit(_ unit: Unit) -> Bool { + return point1.isUnit(unit) + } + + /** + * Is this line in degrees + * + * @return true if degrees + */ + public func isDegrees() -> Bool { + return point1.isDegrees() + } + + /** + * Is this line in meters + * + * @return true if meters + */ + public func isMeters() -> Bool { + return point1.isMeters() + } + + /** + * Convert to the unit + * + * @param unit + * unit + * @return line in units, same line if equal units + */ + public func toUnit(_ unit: Unit) -> Line { + var line: Line + if isUnit(unit) { + line = self + } else { + line = mutableCopy() as! Line + line.setPoints(point1.toUnit(unit), point2.toUnit(unit)) + } + return line + } + + /** + * Convert to degrees + * + * @return line in degrees, same line if already in degrees + */ + public func toDegrees() -> Line { + return toUnit(Unit.DEGREE) + } + + /** + * Convert to meters + * + * @return line in meters, same line if already in meters + */ + public func toMeters() -> Line { + return toUnit(Unit.METER) + } + + /** + * Get the intersection between this line and the provided line + * + * @param line + * line + * @return intersection + */ + public func intersection(_ line: Line) -> GridPoint? { + return GridUtils.intersection(self, line) + } + + open override func mutableCopy(with zone: NSZone? = nil) -> Any { + return Line(self) + } + + open override func encode(with coder: NSCoder) { + super.encode(with: coder) + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + } + + public func isEqual(_ line: Line?) -> Bool { + if self == line { + return true + } + if line == nil { + return false + } + if !super.isEqual(line) { + return false + } + return true + } + + open override func isEqual(_ object: Any?) -> Bool { + + if !(object is Line) { + return false + } + + return isEqual(object as? Line) + } + + open override var hash: Int { + return super.hash + } + + /** + * Validate units are the same + */ + private func validateUnits() { + if !point1.isUnit(point2.unit) { + preconditionFailure("Points are in different units. point1: \(String(describing: point1.unit)), point2: \(String(describing: point2.unit)))") + } + } + +} diff --git a/Pods/grid-ios/grid-ios/features/Unit.swift b/Pods/grid-ios/grid-ios/features/Unit.swift new file mode 100644 index 0000000..594f4a9 --- /dev/null +++ b/Pods/grid-ios/grid-ios/features/Unit.swift @@ -0,0 +1,29 @@ +// +// Unit.swift +// grid-ios +// +// Created by Brian Osborn on 8/3/22. +// + +import Foundation + +/** + * Unit + */ +public enum Unit: Int { + + /** + * Degrees + */ + case DEGREE + + /** + * Meters + */ + case METER + + var name: String { + get { return String(describing: self) } + } + +} diff --git a/Pods/grid-ios/grid-ios/property/GridProperties.swift b/Pods/grid-ios/grid-ios/property/GridProperties.swift new file mode 100644 index 0000000..c11caef --- /dev/null +++ b/Pods/grid-ios/grid-ios/property/GridProperties.swift @@ -0,0 +1,341 @@ +// +// GridProperties.swift +// grid-ios +// +// Created by Brian Osborn on 8/5/22. +// + +import Foundation + +/** + * Grid property loader + */ +open class GridProperties { + + /** + * Properties + */ + public var properties: [String: Any] + + /** + * Initialize + * + * @param resourceClass resource class + * @param bundle bundle name + * @param name properties name + */ + public init(_ resourceClass: AnyClass, _ bundle: String, _ name: String) { + let dict: [String: Any]? + let propertiesPath = GridProperties.propertyListURL(resourceClass, bundle, name) + do { + let propertiesData = try Data(contentsOf: propertiesPath) + dict = try PropertyListSerialization.propertyList(from: propertiesData, options: [], format: nil) as? [String: Any] + } catch { + fatalError("Failed to load properties in bundle '\(bundle)' with name '\(name)'") + } + properties = dict! + } + + /** + * Combine the base property with the property to create a single combined property + * + * @param base base property + * @param property property + * + * @return string value + */ + public func combine(_ base: String, _ property: String) -> String { + return "\(base)\(PropertyConstants.PROPERTY_DIVIDER)\(property)" + } + + /** + * Get the string value of the property + * + * @param property property + * + * @return string value + */ + public func value(_ property: String) -> String { + return value(property, true)! + } + + /** + * Get the string value of the property with required option + * + * @param property property + * @param required true if required to exist + * + * @return string value + */ + public func value(_ property: String, _ required: Bool) -> String? { + let value: String? = properties[property] as? String + + if value == nil && required { + preconditionFailure("Required property not found: \(property)") + } + + return value + } + + /** + * Get the string value of the property combined with the base + * + * @param base base property + * @param property property + * + * @return string value + */ + public func value(_ base: String, _ property: String) -> String { + return value(base, property, true)! + } + + /** + * Get the string value of the property combined with the base with required option + * + * @param base base property + * @param property property + * @param required true if required to exist + * + * @return string value + */ + public func value(_ base: String, _ property: String, _ required: Bool) -> String? { + return value(combine(base, property), required) + } + + /** + * Get the int value of the property + * + * @param property property + * + * @return int value + */ + public func intValue(_ property: String) -> Int { + return intValue(property, true)! + } + + /** + * Get the int value of the property with required option + * + * @param property property + * @param required true if required to exist + * + * @return int value + */ + public func intValue(_ property: String, _ required: Bool) -> Int? { + var val: Int? + let stringValue: String? = value(property, required) + if stringValue != nil { + val = Int(stringValue!) + } + return val + } + + /** + * Get the int value of the property + * + * @param base base property + * @param property property + * + * @return int value + */ + public func intValue(_ base: String, _ property: String) -> Int { + return intValue(base, property, true)! + } + + /** + * Get the int value of the property with required option + * + * @param base base property + * @param property property + * @param required true if required to exist + * + * @return int value + */ + public func intValue(_ base: String, _ property: String, _ required: Bool) -> Int? { + return intValue(combine(base, property), required) + } + + /** + * Get the float value of the property + * + * @param property property + * + * @return float value + */ + public func floatValue(_ property: String) -> Float { + return floatValue(property, true)! + } + + /** + * Get the float value of the property with required option + * + * @param property property + * @param required true if required to exist + * + * @return float value + */ + public func floatValue(_ property: String, _ required: Bool) -> Float? { + var val: Float? + let stringValue: String? = value(property, required) + if stringValue != nil { + val = Float(stringValue!) + } + return val + } + + /** + * Get the float value of the property + * + * @param base base property + * @param property property + * + * @return float value + */ + public func floatValue(_ base: String, _ property: String) -> Float { + return floatValue(base, property, true)! + } + + /** + * Get the float value of the property with required option + * + * @param base base property + * @param property property + * @param required true if required to exist + * + * @return float value + */ + public func floatValue(_ base: String, _ property: String, _ required: Bool) -> Float? { + return floatValue(combine(base, property), required) + } + + /** + * Get the double value of the property + * + * @param property property + * + * @return double value + */ + public func doubleValue(_ property: String) -> Double { + return doubleValue(property, true)! + } + + /** + * Get the double value of the property with required option + * + * @param property property + * @param required true if required to exist + * + * @return double value + */ + public func doubleValue(_ property: String, _ required: Bool) -> Double? { + var val: Double? + let stringValue: String? = value(property, required) + if stringValue != nil { + val = Double(stringValue!) + } + return val + } + + /** + * Get the double value of the property + * + * @param base base property + * @param property property + * + * @return double value + */ + public func doubleValue(_ base: String, _ property: String) -> Double { + return doubleValue(base, property, true)! + } + + /** + * Get the double value of the property with required option + * + * @param base base property + * @param property property + * @param required true if required to exist + * + * @return double value + */ + public func doubleValue(_ base: String, _ property: String, _ required: Bool) -> Double? { + return doubleValue(combine(base, property), required) + } + + /** + * Get the bool value of the property + * + * @param property property + * + * @return bool value + */ + public func boolValue(_ property: String) -> Bool { + return boolValue(property, true)! + } + + /** + * Get the bool value of the property with required option + * + * @param property property + * @param required true if required to exist + * + * @return bool value + */ + public func boolValue(_ property: String, _ required: Bool) -> Bool? { + var val: Bool? + let stringValue: String? = value(property, required) + if stringValue != nil { + val = Bool(stringValue!) + } + return val + } + + /** + * Get the bool value of the property + * + * @param base base property + * @param property property + * + * @return bool value + */ + public func boolValue(_ base: String, _ property: String) -> Bool { + return boolValue(base, property, true)! + } + + /** + * Get the bool value of the property with required option + * + * @param base base property + * @param property property + * @param required true if required to exist + * + * @return bool value + */ + public func boolValue(_ base: String, _ property: String, _ required: Bool) -> Bool? { + return boolValue(combine(base, property), required) + } + + public static func propertyListURL(_ resourceClass: AnyClass, _ bundle: String, _ name: String) -> URL { + return resourceURL(resourceClass, bundle, name, PropertyConstants.PROPERTY_LIST_TYPE) + } + + public static func resourceURL(_ resourceClass: AnyClass, _ bundle: String, _ name: String, _ ext: String) -> URL { + + let resource = "\(bundle)/\(name)" + var resourceURL = Bundle.main.url(forResource: resource, withExtension: ext) + if resourceURL == nil { + resourceURL = Bundle(for: resourceClass).url(forResource: resource, withExtension: ext) + if resourceURL == nil { + resourceURL = Bundle(for: resourceClass).url(forResource: name, withExtension: ext) + if resourceURL == nil { + resourceURL = Bundle.main.url(forResource: name, withExtension: ext) + } + } + } + if resourceURL == nil { + fatalError("Failed to find resource '\(name)' with extension '\(ext)'") + } + + return resourceURL! + } + +} diff --git a/Pods/grid-ios/grid-ios/property/PropertyConstants.swift b/Pods/grid-ios/grid-ios/property/PropertyConstants.swift new file mode 100644 index 0000000..1b6849d --- /dev/null +++ b/Pods/grid-ios/grid-ios/property/PropertyConstants.swift @@ -0,0 +1,85 @@ +// +// PropertyConstants.swift +// grid-ios +// +// Created by Brian Osborn on 8/5/22. +// + +import Foundation + +/** + * Property Constants + */ +public struct PropertyConstants { + + /** + * Property list type + */ + public static let PROPERTY_LIST_TYPE = "plist" + + /** + * Property part divider + */ + public static let PROPERTY_DIVIDER = "." + + /** + * Grid + */ + public static let GRID = "grid" + + /** + * Labeler + */ + public static let LABELER = "labeler" + + /** + * Grids + */ + public static let GRIDS = "grids" + + /** + * Propagate + */ + public static let PROPAGATE = "propagate" + + /** + * Width + */ + public static let WIDTH = "width" + + /** + * Text Size + */ + public static let TEXT_SIZE = "text_size" + + /** + * Buffer + */ + public static let BUFFER = "buffer" + + /** + * Enabled + */ + public static let ENABLED = "enabled" + + /** + * Min Zoom + */ + public static let MIN_ZOOM = "min_zoom" + + /** + * Max Zoom + */ + public static let MAX_ZOOM = "max_zoom" + + /** + * Color + */ + public static let COLOR = "color" + + /** + * Lines + */ + public static let LINES = "lines" + +} diff --git a/Pods/grid-ios/grid-ios/tile/GridTile.swift b/Pods/grid-ios/grid-ios/tile/GridTile.swift new file mode 100644 index 0000000..e799d78 --- /dev/null +++ b/Pods/grid-ios/grid-ios/tile/GridTile.swift @@ -0,0 +1,171 @@ +// +// GridTile.swift +// grid-ios +// +// Created by Brian Osborn on 8/3/22. +// + +import Foundation + +/** + * Grid Tile + */ +public class GridTile { + + /** + * Tile width + */ + public var width: Int + + /** + * Tile height + */ + public var height: Int + + /** + * Grid Zoom level + */ + public var zoom: Int + + /** + * Bounds + */ + public var bounds: Bounds + + /** + * Initialize + * + * @param width + * tile width + * @param height + * tile height + * @param x + * x coordinate + * @param y + * y coordinate + * @param zoom + * zoom level + */ + public convenience init(_ width: Int, _ height: Int, _ x: Int, _ y: Int, _ zoom: Int) { + self.init(width, height, x, y, zoom, zoom) + } + + /** + * Initialize + * + * @param width + * tile width + * @param height + * tile height + * @param x + * x coordinate + * @param y + * y coordinate + * @param zoom + * zoom level + * @param gridZoom + * grid zoom level if different from the XYZ zoom level + */ + public init(_ width: Int, _ height: Int, _ x: Int, _ y: Int, _ zoom: Int, _ gridZoom: Int) { + self.width = width + self.height = height + self.zoom = gridZoom + self.bounds = GridUtils.bounds(x, y, zoom) + } + + /** + * Initialize + * + * @param width + * tile width + * @param height + * tile height + * @param bounds + * tile bounds + */ + public convenience init(_ width: Int, _ height: Int, _ bounds: Bounds) { + self.init(width, height, bounds, 0) + } + + /** + * Initialize + * + * @param width + * tile width + * @param height + * tile height + * @param bounds + * tile bounds + * @param gridZoomOffset + * grid zoom level offset from bounds determined zoom level + */ + public init(_ width: Int, _ height: Int, _ bounds: Bounds, _ gridZoomOffset: Int) { + self.width = width + self.height = height + self.bounds = bounds + self.zoom = Int(round(GridUtils.zoomLevel(bounds))) + gridZoomOffset + } + + /** + * Get the bounds in the units + * + * @param unit + * units + * @return bounds in units + */ + public func bounds(_ unit: Unit) -> Bounds { + return bounds.toUnit(unit) + } + + /** + * Get the bounds in degrees + * + * @return bounds in degrees + */ + public func boundsDegrees() -> Bounds { + return bounds(Unit.DEGREE) + } + + /** + * Get the bounds in meters + * + * @return bounds in meters + */ + public func boundsMeters() -> Bounds { + return bounds(Unit.METER) + } + + /** + * Get the point pixel location in the tile + * + * @param point + * point + * @return pixel + */ + public func pixel(_ point: GridPoint) -> Pixel { + return GridUtils.pixel(width, height, bounds, point) + } + + /** + * Get the longitude in meters x pixel location in the tile + * + * @param longitude + * longitude in meters + * @return x pixel + */ + public func xPixel(_ longitude: Double) -> Float { + return GridUtils.xPixel(width, bounds, longitude) + } + + /** + * Get the latitude (in meters) y pixel location in the tile + * + * @param latitude + * latitude in meters + * @return y pixel + */ + public func yPixel(_ latitude: Double) -> Float { + return GridUtils.yPixel(height, bounds, latitude) + } + +} diff --git a/Pods/grid-ios/grid-ios/tile/Pixel.swift b/Pods/grid-ios/grid-ios/tile/Pixel.swift new file mode 100644 index 0000000..7fc118d --- /dev/null +++ b/Pods/grid-ios/grid-ios/tile/Pixel.swift @@ -0,0 +1,38 @@ +// +// Pixel.swift +// grid-ios +// +// Created by Brian Osborn on 8/3/22. +// + +import Foundation + +/** + * Tile Pixel + */ +public class Pixel { + + /** + * X pixel + */ + public var x: Float + + /** + * Y pixel + */ + public var y: Float + + /** + * Initialize + * + * @param x + * x pixel + * @param y + * y pixel + */ + public init(_ x: Float, _ y: Float) { + self.x = x + self.y = y + } + +} diff --git a/Pods/grid-ios/grid-ios/tile/PixelRange.swift b/Pods/grid-ios/grid-ios/tile/PixelRange.swift new file mode 100644 index 0000000..3782566 --- /dev/null +++ b/Pods/grid-ios/grid-ios/tile/PixelRange.swift @@ -0,0 +1,148 @@ +// +// PixelRange.swift +// grid-ios +// +// Created by Brian Osborn on 8/3/22. +// + +import Foundation + +/** + * Pixel Range + */ +public class PixelRange { + + /** + * Top left pixel + */ + public var topLeft: Pixel + + /** + * Bottom right pixel + */ + public var bottomRight: Pixel + + /** + * Get the minimum x pixel + * + * @return minimum x pixel + */ + public var minX: Float { + get { + return topLeft.x + } + } + + /** + * Get the minimum y pixel + * + * @return minimum y pixel + */ + public var minY: Float { + get { + return topLeft.y + } + } + + /** + * Get the maximum x pixel + * + * @return maximum x pixel + */ + public var maxX: Float { + get { + return bottomRight.x + } + } + + /** + * Get the maximum y pixel + * + * @return maximum y pixel + */ + public var maxY: Float { + get { + return bottomRight.y + } + } + + /** + * Get the left pixel + * + * @return left pixel + */ + public var left: Float { + get { + return minX + } + } + + /** + * Get the top pixel + * + * @return top pixel + */ + public var top: Float { + get { + return minY + } + } + + /** + * Get the right pixel + * + * @return right pixel + */ + public var right: Float { + get { + return maxX + } + } + + /** + * Get the bottom pixel + * + * @return bottom pixel + */ + public var bottom: Float { + get { + return maxY + } + } + + /** + * Get the pixel width + * + * @return pixel width + */ + public var width: Float { + get { + return maxX - minX + } + } + + /** + * Get the pixel height + * + * @return pixel height + */ + public var height: Float { + get { + return maxY - minY + } + } + + /** + * Initialize + * + * @param topLeft + * top left pixel + * @param bottomRight + * bottom right pixel + */ + public init(_ topLeft: Pixel, _ bottomRight: Pixel) { + self.topLeft = topLeft + self.bottomRight = bottomRight + } + +} diff --git a/Pods/grid-ios/grid-ios/tile/TileDraw.swift b/Pods/grid-ios/grid-ios/tile/TileDraw.swift new file mode 100644 index 0000000..a1dcb70 --- /dev/null +++ b/Pods/grid-ios/grid-ios/tile/TileDraw.swift @@ -0,0 +1,124 @@ +// +// TileDraw.swift +// grid-ios +// +// Created by Brian Osborn on 8/17/22. +// + +import UIKit + +/** + * Tile draw utilities for lines and labels + */ +public class TileDraw { + + /** + * Draw the lines on the tile + * + * @param lines lines to draw + * @param tile tile + * @param grid grid + * @param context graphics context + */ + public static func drawLine(_ line: Line, _ tile: GridTile, _ width: Double, _ color: UIColor?, _ context: CGContext) { + + let path = CGMutablePath() + addLine(tile, path, line) + + let strokeColor = color ?? UIColor.black + + context.setLineWidth(width) + context.setStrokeColor(strokeColor.cgColor) + + context.addPath(path) + context.drawPath(using: CGPathDrawingMode.stroke) + + } + + /** + * Add the line to the path + * + * @param tile tile + * @param path line path + * @param line line to draw + */ + public static func addLine(_ tile: GridTile, _ path: CGMutablePath, _ line: Line) { + + let metersLine = line.toMeters() + let point1 = metersLine.point1 + let point2 = metersLine.point2 + + let pixel = point1.pixel(tile) + path.move(to: CGPoint(x: CGFloat(pixel.x), y: CGFloat(pixel.y))) + + let pixel2 = point2.pixel(tile) + path.addLine(to: CGPoint(x: CGFloat(pixel2.x), y: CGFloat(pixel2.y))) + + } + + /** + * Draw the labels on the tile + * + * @param labels labels to draw + * @param buffer grid zone edge buffer + * @param tile tile + * @param grid grid + */ + public static func drawLabels(_ labels: [Label], _ buffer: Double, _ tile: GridTile, _ grid: BaseGrid) { + + let labeler = grid.labeler! + + let textSize = labeler.textSize + let font = UIFont.systemFont(ofSize: CGFloat(textSize)) + + var color = labeler.color + if color == nil { + color = UIColor.black + } + + for label in labels { + drawLabel(label, buffer, tile, font, color!) + } + } + + /** + * Draw the label + * + * @param label label to draw + * @param buffer grid zone edge buffer + * @param tile tile + * @param font font + * @param color color + */ + public static func drawLabel(_ label: Label, _ buffer: Double, _ tile: GridTile, _ font: UIFont, _ color: UIColor) { + + let name = label.name + let nameString = name as NSString + + // Determine the text bounds + var textSize = nameString.size(withAttributes: [NSAttributedString.Key.font: font]) + textSize = CGSize(width: ceil(textSize.width), height: ceil(textSize.height)) + + // Determine the pixel width and height of the label grid zone to the tile + let pixelRange = label.bounds.pixelRange(tile) + + // Determine the maximum width and height a label in the grid should be + let gridPercentage = 1.0 - (2 * buffer) + let maxWidth = gridPercentage * Double(pixelRange.width) + let maxHeight = gridPercentage * Double(pixelRange.height) + + // If it fits, draw the label in the center of the grid zone + if textSize.width <= maxWidth && textSize.height <= maxHeight { + let centerPixel = label.center.pixel(tile) + let bounds = CGRect(x: CGFloat(centerPixel.x) - (textSize.width / 2.0), y: CGFloat(centerPixel.y) - (textSize.height / 2.0), width: textSize.width, height: textSize.height) + + let attributes = [ + NSAttributedString.Key.font: font, + NSAttributedString.Key.foregroundColor: color + ] + nameString.draw(in: bounds, withAttributes: attributes) + } + + } + +} diff --git a/Pods/grid-ios/grid-ios/tile/TileUtils.swift b/Pods/grid-ios/grid-ios/tile/TileUtils.swift new file mode 100644 index 0000000..517ad12 --- /dev/null +++ b/Pods/grid-ios/grid-ios/tile/TileUtils.swift @@ -0,0 +1,197 @@ +// +// TileUtils.swift +// grid-ios +// +// Created by Brian Osborn on 8/17/22. +// + +import MapKit +import sf_ios + +/** + * Tile Utils + */ +public class TileUtils { + + /** + * Displayed device-independent pixels + */ + public static let TILE_DP = 256 + + /** + * Tile pixels for default dpi tiles + */ + public static let TILE_PIXELS_DEFAULT = TILE_DP + + /** + * Tile pixels for high dpi tiles + */ + public static let TILE_PIXELS_HIGH = TILE_PIXELS_DEFAULT * 2 + + /** + * High density scale + */ + public static let SCALE_FACTOR_DEFAULT: Float = 2.0 + + /** + * Get the tile side (width and height) dimension based upon the screen resolution + * + * @return default tile length + */ + public static func tileLength() -> Int { + return tileLength(Float(UIScreen.main.nativeScale)) + } + + /** + * Get the tile side (width and height) dimension based upon the scale + * + * @param scale resolution scale + * @return default tile length + */ + public static func tileLength(_ scale: Float) -> Int { + let length: Int + if scale <= SCALE_FACTOR_DEFAULT { + length = TILE_PIXELS_DEFAULT + } else { + length = TILE_PIXELS_HIGH + } + return length + } + + /** + * Compress the image to byte data + * + * @param image image + * + * @return byte data + */ + public static func toData(_ image: UIImage?) -> Data? { + return image?.pngData() + } + + /** + * Convert a MapKit map point to a location coordinate + * + * @param point MK map point + * + * @return location coordinate + */ + public static func toCoordinate(_ point: MKMapPoint) -> CLLocationCoordinate2D { + return point.coordinate + } + + /** + * Convert a grid point to a location coordinate + * + * @param point grid point + * + * @return location coordinate + */ + public static func toCoordinate(_ point: GridPoint) -> CLLocationCoordinate2D { + let pointDegrees = point.toDegrees() + return CLLocationCoordinate2DMake(pointDegrees.latitude, pointDegrees.longitude) + } + + /** + * Convert a location coordinate to a MapKit map point + * + * @param coordinate location coordinate + * + * @return map point + */ + public static func toMapPoint(_ coordinate: CLLocationCoordinate2D) -> MKMapPoint { + return MKMapPoint(coordinate) + } + + /** + * Convert a grid point to a MapKit map point + * + * @param point grid point + * + * @return map point + */ + public static func toMapPoint(_ point: GridPoint) -> MKMapPoint { + return toMapPoint(toCoordinate(point)) + } + + /** + * Convert a location coordinate to a grid point + * + * @param coordinate location coordinate + * + * @return grid point + */ + public static func toGridPoint(_ coordinate: CLLocationCoordinate2D) -> GridPoint { + return GridPoint.degrees(coordinate.longitude, coordinate.latitude) + } + + /** + * Convert a MapKit map point to a grid point + * + * @param point MK map point + * + * @return grid point + */ + public static func toGridPoint(_ point: MKMapPoint) -> GridPoint { + return toGridPoint(toCoordinate(point)) + } + + /** + * Get the current zoom level of the map view + * + * @param mapView map view + * + * @return current zoom level + */ + public static func currentZoom(_ mapView: MKMapView) -> Double { + + let longitudeDelta = mapView.region.span.longitudeDelta + let width = mapView.bounds.size.width + let scale = longitudeDelta * GridConstants.MERCATOR_RADIUS * Double.pi / (SF_WGS84_HALF_WORLD_LON_WIDTH * width) + var zoom = Double(GridConstants.MAX_MAP_ZOOM_LEVEL) - log2(scale) + if zoom < 0 { + zoom = 0 + } + + return zoom + } + + /** + * Get the current rounded zoom level of the map view + * + * @param mapView map view + * + * @return current zoom level + */ + public static func currentRoundedZoom(_ mapView: MKMapView) -> Int { + return Int(round(currentZoom(mapView))) + } + + /** + * Get a coordinate region for the coordinate at the zoom level in the map view + * + * @param coordinate location coordinate + * @param zoom zoom level + * @param mapView map view + * + * @return coordinate region + */ + public static func coordinateRegion(_ coordinate: CLLocationCoordinate2D, _ zoom: Double, _ mapView: MKMapView) -> MKCoordinateRegion { + + let scale = pow(2, Double(GridConstants.MAX_MAP_ZOOM_LEVEL) - zoom) + + let width = mapView.bounds.size.width + let longitudeDelta = scale * SF_WGS84_HALF_WORLD_LON_WIDTH * width / (GridConstants.MERCATOR_RADIUS * Double.pi) + + let height = mapView.bounds.size.height + let latitudeDelta = scale * SF_WGS84_HALF_WORLD_LAT_HEIGHT * height / (GridConstants.MERCATOR_RADIUS * Double.pi) + + + let span = MKCoordinateSpan(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta) + + let region = MKCoordinateRegion(center: coordinate, span: span) + + return region + } + +} diff --git a/Pods/mgrs-ios/LICENSE b/Pods/mgrs-ios/LICENSE new file mode 100644 index 0000000..e71e681 --- /dev/null +++ b/Pods/mgrs-ios/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 National Geospatial-Intelligence Agency + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Pods/mgrs-ios/README.md b/Pods/mgrs-ios/README.md new file mode 100644 index 0000000..555187b --- /dev/null +++ b/Pods/mgrs-ios/README.md @@ -0,0 +1,245 @@ +# MGRS iOS + +#### Military Grid Reference System Lib #### + +The MGRS Library was developed at the [National Geospatial-Intelligence Agency (NGA)](http://www.nga.mil/) in collaboration with [BIT Systems](https://www.caci.com/bit-systems/). The government has "unlimited rights" and is releasing this software to increase the impact of government investments by providing developers with the opportunity to take things in new directions. The software use, modification, and distribution rights are stipulated within the [MIT license](http://choosealicense.com/licenses/mit/). + +### Pull Requests ### +If you'd like to contribute to this project, please make a pull request. We'll review the pull request and discuss the changes. All pull request contributions to this project will be released under the MIT license. + +Software source code previously released under an open source license and then modified by NGA staff is considered a "joint work" (see 17 USC § 101); it is partially copyrighted, partially public domain, and as a whole is protected by the copyrights of the non-government authors and must be released according to the terms of the original open source license. + +### About ### + +[MGRS](http://ngageoint.github.io/mgrs-ios/) is a Swift library providing Military Grid Reference System functionality, a geocoordinate standard used by NATO militaries for locating points on Earth. [MGRS App](https://github.com/ngageoint/mgrs-ios/tree/master/app) is a map implementation utilizing this library. + +### Usage ### + +View the latest [Appledoc](http://ngageoint.github.io/mgrs-ios/docs/api/) + +#### Import #### + +```swift + +import mgrs_ios + +``` + +#### Coordinates #### + +```swift + +let mgrs = MGRS.parse("33XVG74594359") +let point = mgrs.toPoint() +let pointMeters = point.toMeters() +let utm = mgrs.toUTM() +let utmCoordinate = utm.description +let point2 = utm.toPoint() + +let mgrs2 = MGRS.parse("33X VG 74596 43594") + +let latitude = 63.98862388 +let longitude = 29.06755082 +let point3 = GridPoint(longitude, latitude) +let mgrs3 = MGRS.from(point3) +let mgrsCoordinate = mgrs3.description +let mgrsGZD = mgrs3.coordinate(GridType.GZD) +let mgrs100k = mgrs3.coordinate(GridType.HUNDRED_KILOMETER) +let mgrs10k = mgrs3.coordinate(GridType.TEN_KILOMETER) +let mgrs1k = mgrs3.coordinate(GridType.KILOMETER) +let mgrs100m = mgrs3.coordinate(GridType.HUNDRED_METER) +let mgrs10m = mgrs3.coordinate(GridType.TEN_METER) +let mgrs1m = mgrs3.coordinate(GridType.METER) + +let utm2 = UTM.from(point3) +let mgrs4 = utm2.toMGRS() + +let utm3 = UTM.parse("18 N 585628 4511322") +let mgrs5 = utm3.toMGRS() + +``` + +#### Tile Overlay #### + +```swift + +// let mapView: MKMapView = ... + +// Tile size determined from display density +let tileOverlay = MGRSTileOverlay() + +// Manually specify tile size +let tileOverlay2 = MGRSTileOverlay(512, 512) + +// GZD only grid +let gzdTileOverlay = MGRSTileOverlay.createGZD() + +// Specified grids +let customTileOverlay = MGRSTileOverlay( + [GridType.GZD, GridType.HUNDRED_KILOMETER]) + +mapView.addOverlay(tileOverlay) + +``` + +#### Tile Overlay Options #### + +```swift + +let tileOverlay = MGRSTileOverlay() + +let x = 8 +let y = 12 +let zoom = 5 + +// Manually get a tile or draw the tile bitmap +let tile = tileOverlay.tile(x, y, zoom) +let tileImage = tileOverlay.drawTile(x, y, zoom) + +let latitude = 63.98862388 +let longitude = 29.06755082 +let locationCoordinate = CLLocationCoordinate2DMake(latitude, longitude) + +// MGRS Coordinates +let mgrs = tileOverlay.mgrs(locationCoordinate) +let coordinate = tileOverlay.coordinate(locationCoordinate) +let zoomCoordinate = tileOverlay.coordinate(locationCoordinate, zoom) + +let mgrsGZD = tileOverlay.coordinate(locationCoordinate, GridType.GZD) +let mgrs100k = tileOverlay.coordinate(locationCoordinate, GridType.HUNDRED_KILOMETER) +let mgrs10k = tileOverlay.coordinate(locationCoordinate, GridType.TEN_KILOMETER) +let mgrs1k = tileOverlay.coordinate(locationCoordinate, GridType.KILOMETER) +let mgrs100m = tileOverlay.coordinate(locationCoordinate, GridType.HUNDRED_METER) +let mgrs10m = tileOverlay.coordinate(locationCoordinate, GridType.TEN_METER) +let mgrs1m = tileOverlay.coordinate(locationCoordinate, GridType.METER) + +``` + +#### Custom Grids #### + +```swift + +let grids = Grids() + +grids.setColor(GridType.GZD, UIColor.red) +grids.setWidth(GridType.GZD, 5.0) + +grids.setLabelMinZoom(GridType.GZD, 3) +grids.setLabelMaxZoom(GridType.GZD, 8) +grids.setLabelTextSize(GridType.GZD, 32.0) + +grids.setMinZoom(GridType.HUNDRED_KILOMETER, 4) +grids.setMaxZoom(GridType.HUNDRED_KILOMETER, 8) +grids.setColor(GridType.HUNDRED_KILOMETER, UIColor.blue) + +grids.setLabelColor(GridType.HUNDRED_KILOMETER, UIColor.orange) +grids.setLabelBuffer(GridType.HUNDRED_KILOMETER, 0.1) + +grids.setColor([GridType.TEN_KILOMETER, GridType.KILOMETER, GridType.HUNDRED_METER, GridType.TEN_METER], UIColor.darkGray) + +grids.disable(GridType.METER) + +grids.enableLabeler(GridType.TEN_KILOMETER) + +let tileOverlay = MGRSTileOverlay(grids) + +``` + +#### Draw Tile Template #### + +```swift + +// let tile: GridTile = ... + +let grids = Grids() + +let zoomGrids = grids.grids(tile.zoom) +if zoomGrids.hasGrids() { + + let gridRange = GridZones.gridRange(tile.bounds) + + for grid in zoomGrids { + + // draw this grid for each zone + for zone in gridRange { + + let lines = grid.lines(tile, zone) + if lines != nil { + let pixelRange = zone.bounds.pixelRange(tile) + for line in lines! { + let pixel1 = line.point1.pixel(tile) + let pixel2 = line.point2.pixel(tile) + // Draw line + } + } + + let labels = grid.labels(tile, zone) + if labels != nil { + for label in labels! { + let pixelRange = label.bounds.pixelRange(tile) + let centerPixel = label.center.pixel(tile) + // Draw label + } + } + + } + } +} + +``` + +#### Objective-C #### + +```objectivec + +#import "mgrs_ios-Swift.h" + +``` + +```objectivec + +MKTileOverlay *tileOverlay = [[MGRSTileOverlay alloc] init]; +[mapView addOverlay:tileOverlay]; + +``` + +### Build ### + +[![Build & Test](https://github.com/ngageoint/mgrs-ios/workflows/Build%20&%20Test/badge.svg)](https://github.com/ngageoint/mgrs-ios/actions/workflows/build-test.yml) + +Build this repository using Xcode and/or CocoaPods: + + pod install + +Open mgrs-ios.xcworkspace in Xcode or build from command line: + + xcodebuild -workspace 'mgrs-ios.xcworkspace' -scheme mgrs-ios build + +Run tests from Xcode or from command line: + + xcodebuild test -workspace 'mgrs-ios.xcworkspace' -scheme mgrs-ios -destination 'platform=iOS Simulator,name=iPhone 14' + +### Include Library ### + +Include this repository by specifying it in a Podfile using a supported option. + +Pull from [CocoaPods](https://cocoapods.org/pods/mgrs-ios): + + pod 'mgrs-ios', '~> 1.1.4' + +Pull from GitHub: + + pod 'mgrs-ios', :git => 'https://github.com/ngageoint/mgrs-ios.git', :branch => 'master' + pod 'mgrs-ios', :git => 'https://github.com/ngageoint/mgrs-ios.git', :tag => '1.1.4' + +Include as local project: + + pod 'mgrs-ios', :path => '../mgrs-ios' + +### Remote Dependencies ### + +* [Grid](https://github.com/ngageoint/grid-ios) (The MIT License (MIT)) - Grid Library + +### MGRS App ### + +The [MGRS App](https://github.com/ngageoint/mgrs-ios/tree/master/app) provides a Military Grid Reference System map using this library. diff --git a/Pods/mgrs-ios/mgrs-ios/MGRS.swift b/Pods/mgrs-ios/mgrs-ios/MGRS.swift new file mode 100644 index 0000000..0e29a4e --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/MGRS.swift @@ -0,0 +1,916 @@ +// +// MGRS.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation +import grid_ios +import sf_ios +import MapKit + +/** + * Military Grid Reference System Coordinate + */ +public class MGRS: Hashable { + + /** + * 100km grid square column (‘e’) letters repeat every third zone + */ + private static let columnLetters: [String] = [ "ABCDEFGH", "JKLMNPQR", "STUVWXYZ" ] + + /** + * 100km grid square row (‘n’) letters repeat every other zone + */ + private static let rowLetters: [String] = [ "ABCDEFGHJKLMNPQRSTUV", "FGHJKLMNPQRSTUVABCDE" ] + + /** + * MGRS string pattern + */ + private static let mgrsPattern = "^(\\d{1,2})([C-HJ-NP-X])(?:([A-HJ-NP-Z][A-HJ-NP-V])((\\d{2}){0,5}))?$" + + /** + * MGRS regular expression + */ + private static let mgrsExpression = try! NSRegularExpression(pattern: mgrsPattern, options: .caseInsensitive) + + /** + * MGRS invalid string pattern (Svalbard) + */ + private static let mgrsInvalidPattern = "^3[246]X.*$" + + /** + * MGRS invalid regular expression (Svalbard) + */ + private static let mgrsInvalidExpression = try! NSRegularExpression(pattern: mgrsInvalidPattern, options: .caseInsensitive) + + /** + * Zone number + */ + public let zone: Int + + /** + * Band letter + */ + public let band: Character + + /** + * Column letter + */ + public let column: Character + + /** + * Row letter + */ + public let row: Character + + /** + * Easting + */ + public let easting: Int + + /** + * Northing + */ + public let northing: Int + + /** + * Initialize + * + * @param zone + * zone number + * @param band + * band letter + * @param column + * column letter + * @param row + * row letter + * @param easting + * easting + * @param northing + * northing + */ + public init(_ zone: Int, _ band: Character, _ column: Character, _ row: Character, _ easting: Int, _ northing: Int) { + self.zone = zone + self.band = band + self.column = column + self.row = row + self.easting = easting + self.northing = northing + } + + /** + * Initialize + * + * @param zone + * zone number + * @param band + * band letter + * @param column + * column letter + * @param row + * row letter + * @param easting + * easting + * @param northing + * northing + */ + public convenience init(_ zone: Int, _ band: Character, _ easting: Int, _ northing: Int) { + self.init(zone, band, MGRS.columnLetter(zone, Double(easting)), MGRS.rowLetter(zone, Double(northing)), easting, northing) + } + + /** + * Get the hemisphere + * + * @return hemisphere + */ + public func hemisphere() -> Hemisphere { + return MGRSUtils.hemisphere(band) + } + + /** + * Get the MGRS coordinate with one meter precision + * + * @return MGRS coordinate + */ + public func coordinate() -> String { + return coordinate(GridType.METER) + } + + /** + * Get the MGRS coordinate with specified grid precision + * + * @param type + * grid type precision + * @return MGRS coordinate + */ + public func coordinate(_ type: GridType?) -> String { + + var mgrs = String() + + if type != nil { + + mgrs = mgrs.appending(String(zone)) + mgrs = mgrs.appending(String(band)) + + if type != GridType.GZD { + + mgrs = mgrs.appending(String(column)) + mgrs = mgrs.appending(String(row)) + + if type != GridType.HUNDRED_KILOMETER { + + mgrs = mgrs.appending(eastingAndNorthing(type!)) + + } + + } + + } + + return mgrs + } + + /** + * Get the easting and northing concatenated value in the grid type + * precision + * + * @param type + * grid type precision + * @return easting and northing value + */ + public func eastingAndNorthing(_ type: GridType) -> String { + + let accuracy = 5 - Int(log10(Double(type.precision()))) + + let easting = String(format: "%05d", self.easting) + let northing = String(format: "%05d", self.northing) + + return String(easting.prefix(accuracy)) + String(northing.prefix(accuracy)) + } + + /** + * Get the MGRS coordinate with the accuracy number of digits in the easting + * and northing values. Accuracy must be inclusively between 0 + * (GridType.HUNDRED_KILOMETER) and 5 (GridType.METER). + * + * @param accuracy + * accuracy digits between 0 (inclusive) and 5 (inclusive) + * @return MGRS coordinate + */ + public func coordinate(_ accuracy: Int) -> String { + return coordinate(GridType.withAccuracy(accuracy)) + } + + /** + * Get the MGRS coordinate grid precision + * + * @return grid type precision + */ + public func precision() -> GridType { + return GridType.withAccuracy(accuracy()) + } + + /** + * Get the MGRS coordinate accuracy number of digits + * + * @return accuracy digits + */ + public func accuracy() -> Int { + + var accuracy = 5 + + var accuracyLevel = 10 + while accuracyLevel <= 100000 { + + if easting % accuracyLevel != 0 || northing % accuracyLevel != 0 { + break + } + accuracy -= 1 + + accuracyLevel *= 10 + } + + return accuracy + } + + /** + * Get the two letter column and row 100k designator + * + * @return the two letter column and row 100k designator + */ + public func columnRowId() -> String { + return String(column) + String(row) + } + + /** + * Get the GZD grid zone + * + * @return GZD grid zone + */ + public func gridZone() -> GridZone? { + return GridZones.gridZone(self) + } + + /** + * Convert to a point + * + * @return point + */ + public func toPoint() -> GridPoint { + return toUTM().toPoint() + } + + /** + * Convert to a location coordinate + * + * @return coordinate + */ + public func toCoordinate() -> CLLocationCoordinate2D { + return toPoint().toCoordinate() + } + + /** + * Convert to UTM coordinate + * + * @return UTM + */ + public func toUTM() -> UTM { + + let easting = utmEasting() + let northing = utmNorthing() + let hemisphere = hemisphere() + + return UTM(zone, hemisphere, easting, northing) + } + + /** + * Get the UTM easting + * + * @return UTM easting + */ + public func utmEasting() -> Double { + + // get easting specified by e100k + let columnLetters = MGRS.columnLetters(zone) + let columnIndex = GridUtils.indexOf(columnLetters, column) + 1 + // index+1 since A (index 0) -> 1*100e3, B (index 1) -> 2*100e3, etc. + let e100kNum = Double(columnIndex) * 100000.0 // e100k in meters + + return e100kNum + Double(easting) + } + + /** + * Get the UTM northing + * + * @return UTM northing + */ + public func utmNorthing() -> Double { + + // get northing specified by n100k + let rowLetters = MGRS.rowLetters(zone) + let rowIndex = GridUtils.indexOf(rowLetters, row) + let n100kNum = Double(rowIndex) * 100000.0 // n100k in meters + + // get latitude of (bottom of) band + let latBand = GridZones.southLatitude(band) + + // northing of bottom of band, extended to include entirety of + // bottommost 100km square + // (100km square boundaries are aligned with 100km UTM northing + // intervals) + + let latBandNorthing = UTM.from(GridPoint.degrees(0, latBand)).northing + let nBand = floor(latBandNorthing / 100000) * 100000 + + // 100km grid square row letters repeat every 2,000km north; add enough + // 2,000km blocks to get + // into required band + var n2M = 0 // northing of 2,000km block + while Double(n2M) + n100kNum + Double(northing) < nBand { + n2M += 2000000 + } + + return Double(n2M) + n100kNum + Double(northing) + } + + public var description: String { + return coordinate() + } + + public static func == (lhs: MGRS, rhs: MGRS) -> Bool { + return lhs.zone == rhs.zone + && lhs.band == rhs.band + && lhs.column == rhs.column + && lhs.row == rhs.row + && lhs.easting == rhs.easting + && lhs.northing == rhs.northing + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(zone) + hasher.combine(band) + hasher.combine(column) + hasher.combine(row) + hasher.combine(easting) + hasher.combine(northing) + } + + /** + * Return whether the given string is valid MGRS string + * + * @param mgrs + * potential MGRS string + * @return true if MGRS string is valid, false otherwise + */ + public static func isMGRS(_ mgrs: String) -> Bool { + let mgrsValue = removeSpaces(mgrs) + return mgrsExpression.matches(in: mgrsValue, range: NSMakeRange(0, mgrsValue.count)).count > 0 && mgrsInvalidExpression.matches(in: mgrsValue, range: NSMakeRange(0, mgrsValue.count)).count <= 0 + } + + /** + * Removed spaces from the value + * + * @param value + * value string + * @return value without spaces + */ + private static func removeSpaces(_ value: String) -> String { + return value.filter { !$0.isWhitespace } + } + + /** + * Encodes a point as a MGRS + * + * @param point + * point + * @return MGRS + */ + public static func from(_ point: GridPoint) -> MGRS { + + let pointDegrees = (point.mutableCopy() as! GridPoint).toDegrees() + + // Bound the latitude if needed + if pointDegrees.latitude < MGRSConstants.MIN_LAT { + pointDegrees.latitude = MGRSConstants.MIN_LAT + } else if pointDegrees.latitude > MGRSConstants.MAX_LAT { + pointDegrees.latitude = MGRSConstants.MAX_LAT + } + + // Normalize the longitude if needed + SFGeometryUtils.normalizeWGS84Geometry(pointDegrees) + + let utm = UTM.from(pointDegrees) + + let bandLetter = GridZones.bandLetter(pointDegrees.latitude) + + let columnLetter = columnLetter(utm) + + let rowLetter = rowLetter(utm) + + // truncate easting/northing to within 100km grid square + let easting = Int(utm.easting.truncatingRemainder(dividingBy: 100000)) + let northing = Int(utm.northing.truncatingRemainder(dividingBy: 100000)) + + return MGRS(utm.zone, bandLetter, columnLetter, rowLetter, + easting, northing) + } + + /** + * Encodes a coordinate as a MGRS + * + * @param coordinate + * coordinate + * @return MGRS + */ + public static func from(_ coordinate: CLLocationCoordinate2D) -> MGRS { + return from(coordinate.longitude, coordinate.latitude) + } + + /** + * Encodes a coordinate in degrees as a MGRS + * + * @param longitude + * longitude + * @param latitude + * latitude + * @return MGRS + */ + public static func from(_ longitude: Double, _ latitude: Double) -> MGRS { + return from(longitude, latitude, Unit.DEGREE) + } + + /** + * Encodes a coordinate in the unit as a MGRS + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param unit + * unit + * @return MGRS + */ + public static func from(_ longitude: Double, _ latitude: Double, _ unit: grid_ios.Unit) -> MGRS { + return from(GridPoint(longitude, latitude, unit)) + } + + /** + * Parse a MGRS string + * + * @param mgrs + * MGRS string + * @return MGRS + */ + public static func parse(_ mgrs: String) -> MGRS { + let mgrsNoSpaces = removeSpaces(mgrs) + let matches = mgrsExpression.matches(in: mgrsNoSpaces, range: NSMakeRange(0, mgrsNoSpaces.count)) + if matches.count <= 0 { + preconditionFailure("Invalid MGRS: \(mgrs)") + } + + let match = matches[0] + let mgrsString = mgrsNoSpaces as NSString + + let zone = Int(mgrsString.substring(with: match.range(at: 1)))! + let band = mgrsString.substring(with: match.range(at: 2)).uppercased().first! + + let gridZone = GridZones.gridZone(zone, band) + if gridZone == nil { + preconditionFailure("Invalid MGRS: \(mgrs)") + } + + var mgrsValue: MGRS + + let columnRowMatch = match.range(at: 3) + if columnRowMatch.length > 0 { + + var columnRow = mgrsString.substring(with: columnRowMatch) + + columnRow = columnRow.uppercased() + let column = GridUtils.charAt(columnRow, 0) + let row = GridUtils.charAt(columnRow, 1) + + // parse easting & northing + var easting = 0 + var northing = 0 + let locationMatch = match.range(at: 4) + if locationMatch.length > 0 { + + let location = mgrsString.substring(with: locationMatch) + + let precision = location.count / 2 + let multiplier = pow(10.0, 5.0 - Double(precision)) + easting = Int(Double(GridUtils.substring(location, 0, precision))! * multiplier) + northing = Int(Double(GridUtils.substring(location, precision))! * multiplier) + } + + mgrsValue = MGRS(zone, band, column, row, easting, northing) + + if locationMatch.length == 0 { + + let point = mgrsValue.toPoint().toDegrees() + let gridBounds = gridZone!.bounds + let gridSouthwest = gridBounds.southwest.toDegrees() + + let westBounds = point.longitude < gridSouthwest.longitude + let southBounds = point.latitude < gridSouthwest.latitude + + if westBounds || southBounds { + + if westBounds && southBounds { + let northeast = MGRS(zone, band, column, row, + GridType.HUNDRED_KILOMETER.precision(), + GridType.HUNDRED_KILOMETER.precision()) + .toPoint() + if gridBounds.contains(northeast) { + mgrsValue = from(gridSouthwest) + } + } else if westBounds { + let east = MGRS(zone, band, column, row, + GridType.HUNDRED_KILOMETER.precision(), + northing) + .toPoint() + if gridBounds.contains(east) { + let intersection = westernBoundsPoint(gridZone!, + point, east) + mgrsValue = from(intersection) + } + } else if southBounds { + let north = MGRS(zone, band, column, row, + easting, + GridType.HUNDRED_KILOMETER.precision()) + .toPoint() + if gridBounds.contains(north) { + let intersection = southernBoundsPoint( + gridZone!, point, north) + mgrsValue = from(intersection) + } + } + + } + + } + + } else { + mgrsValue = from(gridZone!.bounds.southwest) + } + + return mgrsValue + } + + /** + * Parse a MGRS string into a location coordinate + * + * @param mgrs + * MGRS string + * @return coordinate + */ + public static func parseToCoordinate(_ mgrs: String) -> CLLocationCoordinate2D { + var coordinate = kCLLocationCoordinate2DInvalid + if isMGRS(mgrs) { + coordinate = parse(mgrs).toCoordinate() + } + return coordinate + } + + /** + * Encodes a point as a MGRS coordinate with one meter precision + * + * @param point + * point + * @return MGRS coordinate + */ + public static func coordinate(_ point: GridPoint) -> String { + return from(point).coordinate() + } + + /** + * Encodes a point as a MGRS coordinate with specified grid precision + * + * @param point + * point + * @param type + * grid type precision + * @return MGRS coordinate + */ + public static func coordinate(_ point: GridPoint, _ type: GridType?) -> String { + return from(point).coordinate(type) + } + + /** + * Encodes a coordinate as a MGRS coordinate with one meter precision + * + * @param coordinate + * coordinate + * @return MGRS coordinate + */ + public static func coordinate(_ coordinate: CLLocationCoordinate2D) -> String { + return from(coordinate).coordinate() + } + + /** + * Encodes a coordinate as a MGRS coordinate with specified grid precision + * + * @param coordinate + * coordinate + * @param type + * grid type precision + * @return MGRS coordinate + */ + public static func coordinate(_ coordinate: CLLocationCoordinate2D, _ type: GridType?) -> String { + return from(coordinate).coordinate(type) + } + + /** + * Encodes a coordinate in degrees as a MGRS coordinate with one meter precision + * + * @param longitude + * longitude + * @param latitude + * latitude + * @return MGRS coordinate + */ + public static func coordinate(_ longitude: Double, _ latitude: Double) -> String { + return from(longitude, latitude).coordinate() + } + + /** + * Encodes a coordinate in degrees as a MGRS coordinate with specified grid precision + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param type + * grid type precision + * @return MGRS coordinate + */ + public static func coordinate(_ longitude: Double, _ latitude: Double, _ type: GridType?) -> String { + return from(longitude, latitude).coordinate(type) + } + + /** + * Encodes a coordinate in the unit as a MGRS coordinate with one meter precision + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param unit + * unit + * @return MGRS coordinate + */ + public static func coordinate(_ longitude: Double, _ latitude: Double, _ unit: grid_ios.Unit) -> String { + return from(longitude, latitude, unit).coordinate() + } + + /** + * Encodes a coordinate in the unit as a MGRS coordinate with specified grid precision + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param unit + * unit + * @param type + * grid type precision + * @return MGRS coordinate + */ + public static func coordinate(_ longitude: Double, _ latitude: Double, _ unit: grid_ios.Unit, _ type: GridType?) -> String { + return from(longitude, latitude, unit).coordinate(type) + } + + /** + * Get the point on the western grid zone bounds point between the western + * and eastern points + * + * @param gridZone + * grid zone + * @param west + * western point + * @param east + * eastern point + * @return western grid bounds point + */ + private static func westernBoundsPoint(_ gridZone: GridZone, _ west: GridPoint, + _ east: GridPoint) -> GridPoint { + + let eastUTM = UTM.from(east) + let northing = eastUTM.northing + + let zoneNumber = gridZone.number() + let hemisphere = gridZone.hemisphere() + + let line = Line(west, east) + let boundsLine = gridZone.bounds.westLine() + + let intersection = line.intersection(boundsLine)! + + // Intersection easting + let intersectionUTM = UTM.from(intersection, zoneNumber, hemisphere) + let intersectionEasting = intersectionUTM.easting + + // One meter precision just inside the bounds + let boundsEasting = ceil(intersectionEasting) + + // Higher precision point just inside of the bounds + let boundsPoint = UTM.point(zoneNumber, hemisphere, boundsEasting, + northing) + + boundsPoint.longitude = boundsLine.point1.longitude + + return boundsPoint + } + + /** + * Get the point on the southern grid zone bounds point between the southern + * and northern points + * + * @param gridZone + * grid zone + * @param south + * southern point + * @param north + * northern point + * @return southern grid bounds point + */ + private static func southernBoundsPoint(_ gridZone: GridZone, _ south: GridPoint, + _ north: GridPoint) -> GridPoint { + + let northUTM = UTM.from(north) + let easting = northUTM.easting + + let zoneNumber = gridZone.number() + let hemisphere = gridZone.hemisphere() + + let line = Line(south, north) + let boundsLine = gridZone.bounds.southLine() + + let intersection = line.intersection(boundsLine)! + + // Intersection northing + let intersectionUTM = UTM.from(intersection, zoneNumber, hemisphere) + let intersectionNorthing = intersectionUTM.northing + + // One meter precision just inside the bounds + let boundsNorthing = ceil(intersectionNorthing) + + // Higher precision point just inside of the bounds + let boundsPoint = UTM.point(zoneNumber, hemisphere, easting, + boundsNorthing) + + boundsPoint.latitude = boundsLine.point1.latitude + + return boundsPoint + } + + /** + * Parse the MGRS string for the precision + * + * @param mgrs + * MGRS string + * @return grid type precision + */ + public static func precision(_ mgrs: String) -> GridType { + let mgrsValue = removeSpaces(mgrs) + let matches = mgrsExpression.matches(in: mgrsValue, range: NSMakeRange(0, mgrsValue.count)) + if matches.count <= 0 { + preconditionFailure("Invalid MGRS: \(mgrs)") + } + + let match = matches[0] + + let precision: GridType + + if match.range(at: 3).length > 0 { + + let mgrsString = mgrsValue as NSString + + let locationMatch = match.range(at: 4) + if locationMatch.length > 0 { + let location = mgrsString.substring(with: locationMatch) + precision = GridType.withAccuracy(location.count / 2) + } else { + precision = GridType.HUNDRED_KILOMETER + } + + } else { + precision = GridType.GZD + } + + return precision + } + + /** + * Get the MGRS coordinate accuracy number of digits + * + * @param mgrs + * MGRS string + * @return accuracy digits + */ + public static func accuracy(_ mgrs: String) -> Int { + return precision(mgrs).accuracy() + } + + /** + * Get the two letter column and row 100k designator for a given UTM + * easting, northing and zone number value + * + * @param easting + * easting + * @param northing + * northing + * @param zoneNumber + * zone number + * @return the two letter column and row 100k designator + */ + public static func columnRowId(_ easting: Double, _ northing: Double, _ zoneNumber: Int) -> String { + + let columnLetter = columnLetter(zoneNumber, easting) + + let rowLetter = rowLetter(zoneNumber, northing) + + return String(columnLetter) + String(rowLetter) + } + + /** + * Get the column letter from the UTM + * + * @param utm + * UTM + * @return column letter + */ + public static func columnLetter(_ utm: UTM) -> Character { + return columnLetter(utm.zone, utm.easting) + } + + /** + * Get the column letter from the zone number and easting + * + * @param zoneNumber + * zone number + * @param easting + * easting + * @return column letter + */ + public static func columnLetter(_ zoneNumber: Int, _ easting: Double) -> Character { + // columns in zone 1 are A-H, zone 2 J-R, zone 3 S-Z, then repeating + // every 3rd zone + let column = Int(floor(easting / 100000)) + let columnLetters = columnLetters(zoneNumber) + return GridUtils.charAt(columnLetters, column - 1) + } + + /** + * Get the row letter from the UTM + * + * @param utm + * UTM + * @return row letter + */ + public static func rowLetter(_ utm: UTM) -> Character { + return rowLetter(utm.zone, utm.northing) + } + + /** + * Get the row letter from the zone number and northing + * + * @param zoneNumber + * zone number + * @param northing + * northing + * @return row letter + */ + public static func rowLetter(_ zoneNumber: Int, _ northing: Double) -> Character { + // rows in even zones are A-V, in odd zones are F-E + let row = Int(floor(northing / 100000)) % 20 + let rowLetters = rowLetters(zoneNumber) + return GridUtils.charAt(rowLetters, row) + } + + /** + * Get the column letters for the zone number + * + * @param zoneNumber + * zone number + * @return column letters + */ + private static func columnLetters(_ zoneNumber: Int) -> String { + return columnLetters[columnLetters.index(columnLetters.startIndex, offsetBy: (zoneNumber - 1) % 3)] + } + + /** + * Get the row letters for the zone number + * + * @param zoneNumber + * zone number + * @return row letters + */ + private static func rowLetters(_ zoneNumber: Int) -> String { + return rowLetters[rowLetters.index(rowLetters.startIndex, offsetBy: (zoneNumber - 1) % 2)] + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/MGRSConstants.swift b/Pods/mgrs-ios/mgrs-ios/MGRSConstants.swift new file mode 100644 index 0000000..22b959a --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/MGRSConstants.swift @@ -0,0 +1,121 @@ +// +// MGRSConstants.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation +import grid_ios + +/** + * Military Grid Reference System Constants + */ +public struct MGRSConstants { + + /** + * Minimum longitude + */ + public static let MIN_LON = GridConstants.MIN_LON + + /** + * Maximum longitude + */ + public static let MAX_LON = GridConstants.MAX_LON + + /** + * Minimum latitude + */ + public static let MIN_LAT = -80.0 + + /** + * Maximum latitude + */ + public static let MAX_LAT = 84.0 + + /** + * Minimum grid zone number + */ + public static let MIN_ZONE_NUMBER = 1 + + /** + * Maximum grid zone number + */ + public static let MAX_ZONE_NUMBER = 60 + + /** + * Grid zone width + */ + public static let ZONE_WIDTH = 6.0 + + /** + * Minimum grid band letter + */ + public static let MIN_BAND_LETTER: Character = "C" + + /** + * Maximum grid band letter + */ + public static let MAX_BAND_LETTER: Character = "X" + + /** + * Number of bands + */ + public static let NUM_BANDS = 20 + + /** + * Grid band height for all by but the MAX_BAND_LETTER + */ + public static let BAND_HEIGHT = 8.0 + + /** + * Grid band height for the MAX_BAND_LETTER + */ + public static let MAX_BAND_HEIGHT = 12.0 + + /** + * Last southern hemisphere band letter + */ + public static let BAND_LETTER_SOUTH: Character = "M" + + /** + * First northern hemisphere band letter + */ + public static let BAND_LETTER_NORTH: Character = "N" + + /** + * Min zone number in Svalbard grid zones + */ + public static let MIN_SVALBARD_ZONE_NUMBER = 31 + + /** + * Max zone number in Svalbard grid zones + */ + public static let MAX_SVALBARD_ZONE_NUMBER = 37 + + /** + * Band letter in Svalbard grid zones + */ + public static let SVALBARD_BAND_LETTER = MAX_BAND_LETTER + + /** + * Min zone number in Norway grid zones + */ + public static let MIN_NORWAY_ZONE_NUMBER = 31 + + /** + * Max zone number in Norway grid zones + */ + public static let MAX_NORWAY_ZONE_NUMBER = 32 + + /** + * Band letter in Norway grid zones + */ + public static let NORWAY_BAND_LETTER: Character = "V" + + /** + * Grid zoom display offset from XYZ tile zoom levels + */ + public static let ZOOM_OFFSET = -1 + +} diff --git a/Pods/mgrs-ios/mgrs-ios/MGRSUtils.swift b/Pods/mgrs-ios/mgrs-ios/MGRSUtils.swift new file mode 100644 index 0000000..980ce2c --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/MGRSUtils.swift @@ -0,0 +1,102 @@ +// +// MGRSUtils.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation +import grid_ios + +/** + * Military Grid Reference System utilities + */ +public class MGRSUtils { + + /** + * Validate the zone number + * + * @param number + * zone number + */ + public static func validateZoneNumber(_ number: Int) { + if number < MGRSConstants.MIN_ZONE_NUMBER + || number > MGRSConstants.MAX_ZONE_NUMBER { + preconditionFailure("Illegal zone number (expected \(MGRSConstants.MIN_ZONE_NUMBER) - \(MGRSConstants.MAX_ZONE_NUMBER)): \(number)") + } + } + + /** + * Validate the band letter + * + * @param letter + * band letter + */ + public static func validateBandLetter(_ letter: Character) { + if letter < MGRSConstants.MIN_BAND_LETTER + || letter > MGRSConstants.MAX_BAND_LETTER + || GridUtils.isOmittedBandLetter(letter) { + preconditionFailure("Illegal band letter (CDEFGHJKLMNPQRSTUVWX): \(letter)") + } + } + + /** + * Get the next band letter + * + * @param letter + * band letter + * @return next band letter, 'Y' (MGRSConstants.MAX_BAND_LETTER + 1) + * if no next bands + */ + public static func nextBandLetter(_ letter: Character) -> Character { + validateBandLetter(letter) + var letterValue = GridUtils.incrementCharacter(letter) + if GridUtils.isOmittedBandLetter(letterValue) { + letterValue = GridUtils.incrementCharacter(letterValue) + } + return letterValue + } + + /** + * Get the previous band letter + * + * @param letter + * band letter + * @return previous band letter, 'B' (MGRSConstants.MIN_BAND_LETTER + * - 1) if no previous bands + */ + public static func previousBandLetter(_ letter: Character) -> Character { + validateBandLetter(letter) + var letterValue = GridUtils.decrementCharacter(letter) + if GridUtils.isOmittedBandLetter(letterValue) { + letterValue = GridUtils.decrementCharacter(letterValue) + } + return letterValue + } + + /** + * Get the label name + * + * @param zoneNumber + * zone number + * @param bandLetter + * band letter + * @return name + */ + public static func labelName(_ zoneNumber: Int, _ bandLetter: Character) -> String { + return String(zoneNumber) + String(bandLetter) + } + + /** + * Get the hemisphere from the band letter + * + * @param bandLetter + * band letter + * @return hemisphere + */ + public static func hemisphere(_ bandLetter: Character) -> Hemisphere { + return bandLetter < MGRSConstants.BAND_LETTER_NORTH ? Hemisphere.SOUTH + : Hemisphere.NORTH + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/features/MGRSLine.swift b/Pods/mgrs-ios/mgrs-ios/features/MGRSLine.swift new file mode 100644 index 0000000..8a04b8a --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/features/MGRSLine.swift @@ -0,0 +1,137 @@ +// +// MGRSLine.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation +import grid_ios + +/** + * Line between two points + */ +public class MGRSLine: Line { + + /** + * Grid type the line represents if any + */ + public var gridType: GridType? + + /** + * Initialize + * + * @param point1 + * first point + * @param point2 + * second point + */ + public override init(_ point1: GridPoint, _ point2: GridPoint) { + super.init(point1, point2) + } + + /** + * Initialize + * + * @param point1 + * first point + * @param point2 + * second point + * @param gridType + * line grid type + */ + public convenience init(_ point1: GridPoint, _ point2: GridPoint, _ gridType: GridType?) { + self.init(point1, point2) + self.gridType = gridType + } + + /** + * Initialize + * + * @param line + * line to copy + */ + public override init(_ line: Line) { + super.init(line) + } + + /** + * Initialize + * + * @param line + * line to copy + * @param gridType + * line grid type + */ + public convenience init(_ line: Line, _ gridType: GridType?) { + self.init(line) + self.gridType = gridType + } + + /** + * Initialize + * + * @param gridLine + * line to copy + */ + public convenience init(_ gridLine: MGRSLine) { + self.init(gridLine, gridLine.gridType) + } + + /** + * Check if the line has a grid type + * + * @return true if has grid type + */ + public func hasGridType() -> Bool { + return gridType != nil + } + + public override func mutableCopy(with zone: NSZone? = nil) -> Any { + return MGRSLine(self) + } + + public override func encode(with coder: NSCoder) { + let gridValue = gridType != nil ? gridType?.rawValue : -1 + coder.encode(gridValue, forKey: "gridType") + super.encode(with: coder) + } + + public required init?(coder: NSCoder) { + let gridValue = coder.decodeInteger(forKey: "gridType") + if gridValue >= 0 { + gridType = GridType.init(rawValue: gridValue) + } + super.init(coder: coder) + } + + public func isEqual(_ gridLine: MGRSLine?) -> Bool { + if self == gridLine { + return true + } + if gridLine == nil { + return false + } + if !super.isEqual(gridLine) { + return false + } + return true + } + + public override func isEqual(_ object: Any?) -> Bool { + + if !(object is MGRSLine) { + return false + } + + return isEqual(object as? MGRSLine) + } + + public override var hash: Int { + let prime = 31 + var result = super.hash + result = prime * result + ((gridType == nil) ? -1 : gridType!.rawValue) + return result + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/grid/Grid.swift b/Pods/mgrs-ios/mgrs-ios/grid/Grid.swift new file mode 100644 index 0000000..176be1c --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/grid/Grid.swift @@ -0,0 +1,305 @@ +// +// Grid.swift +// mgrs-ios +// +// Created by Brian Osborn on 9/2/22. +// + +import Foundation +import grid_ios +import color_ios + +/** + * Grid + */ +public class Grid: BaseGrid { + + /** + * Default line width + */ + public static let DEFAULT_WIDTH = MGRSProperties.instance.doubleValue(PropertyConstants.GRID, PropertyConstants.WIDTH) + + /** + * Grid type + */ + public let type: GridType + + /** + * Grid line styles + */ + private var styles: [GridType: GridStyle] = [:] + + /** + * Initialize + * + * @param type + * grid type + */ + public init(_ type: GridType) { + self.type = type + } + + /** + * Is the provided grid type + * + * @param type + * grid type + * @return true if the type + */ + public func isType(_ type: GridType) -> Bool { + return self.type == type + } + + /** + * Get the precision in meters + * + * @return precision meters + */ + public func precision() -> Int { + return type.precision() + } + + /** + * Get the grid type precision line style for the grid type + * + * @param gridType + * grid type + * @return grid type line style + */ + public func style(_ gridType: GridType) -> GridStyle? { + let style: GridStyle? + if gridType == type { + style = self.style + } else { + style = styles[gridType] + } + return style + } + + /** + * Get the grid type line style for the grid type or create it + * + * @param gridType + * grid type + * @return grid type line style + */ + private func getOrCreateStyle(_ gridType: GridType) -> GridStyle { + var style = style(gridType) + if style == nil { + style = GridStyle() + setStyle(gridType, style!) + } + return style! + } + + /** + * Set the grid type precision line style + * + * @param gridType + * grid type + * @param style + * grid line style + */ + public func setStyle(_ gridType: GridType, _ style: GridStyle?) { + if gridType.precision() < precision() { + preconditionFailure("Grid can not define a style for a higher precision grid type. Type: \(type), Style Type: \(gridType)") + } + let gridStyle = style != nil ? style! : GridStyle() + if gridType == type { + self.style = gridStyle + } else { + styles[gridType] = gridStyle + } + } + + /** + * Clear the propagated grid type precision styles + */ + public func clearPrecisionStyles() { + styles.removeAll() + } + + /** + * Get the grid type precision line color + * + * @param gridType + * grid type + * @return grid type line color + */ + public func color(_ gridType: GridType) -> UIColor? { + var color: UIColor? = nil + let style = style(gridType) + if style != nil { + color = style!.color + } + if color == nil { + color = self.color + } + return color + } + + /** + * Set the grid type precision line color + * + * @param gridType + * grid type + * @param color + * grid line color + */ + public func setColor(_ gridType: GridType, _ color: UIColor) { + getOrCreateStyle(gridType).color = color + } + + /** + * Get the grid type precision line width + * + * @param gridType + * grid type + * @return grid type line width + */ + public func width(_ gridType: GridType) -> Double { + var width = 0.0 + let style = style(gridType) + if style != nil { + width = style!.width + } + if width == 0 { + width = self.width + } + return width + } + + /** + * Set the grid type precision line width + * + * @param gridType + * grid type + * @param width + * grid line width + */ + public func setWidth(_ gridType: GridType, _ width: Double) { + getOrCreateStyle(gridType).width = width + } + + /** + * Get the grid labeler + * + * @return grid labeler + */ + public func labeler() -> GridLabeler? { + return labeler as? GridLabeler + } + + /** + * Set the grid labeler + * + * @param labeler + * grid labeler + */ + public func setLabeler(_ labeler: GridLabeler?) { + self.labeler = labeler + } + + /** + * Get the lines for the tile and zone + * + * @param tile + * tile + * @param zone + * grid zone + * @return lines + */ + public func lines(_ tile: GridTile, _ zone: GridZone) -> [MGRSLine]? { + return lines(tile.zoom, tile.bounds, zone) + } + + /** + * Get the lines for the zoom, tile bounds, and zone + * + * @param zoom + * zoom level + * @param tileBounds + * tile bounds + * @param zone + * grid zone + * @return lines + */ + public func lines(_ zoom: Int, _ tileBounds: Bounds, _ zone: GridZone) -> [MGRSLine]? { + var gridLines: [MGRSLine]? = nil + if isLinesWithin(zoom) { + gridLines = lines(tileBounds, zone) + } + return gridLines + } + + /** + * Get the lines for the tile bounds and zone + * + * @param tileBounds + * tile bounds + * @param zone + * grid zone + * @return lines + */ + public func lines(_ tileBounds: Bounds, _ zone: GridZone) -> [MGRSLine]? { + return zone.lines(tileBounds, type) + } + + /** + * Get the labels for the tile and zone + * + * @param tile + * tile + * @param zone + * grid zone + * @return labels + */ + public func labels(_ tile: GridTile, _ zone: GridZone) -> [GridLabel]? { + return labels(tile.zoom, tile.bounds, zone) + } + + /** + * Get the labels for the zoom, tile bounds, and zone + * + * @param zoom + * zoom level + * @param tileBounds + * tile bounds + * @param zone + * grid zone + * @return labels + */ + public func labels(_ zoom: Int, _ tileBounds: Bounds, _ zone: GridZone) -> [GridLabel]? { + var labels: [GridLabel]? = nil + if isLabelerWithin(zoom) { + labels = labeler()!.labels(tileBounds, type, zone) + } + return labels + } + + public override func equals(_ grid: BaseGrid) -> Bool { + return type == (grid as! Grid).type + } + + public override func hash(into hasher: inout Hasher) { + hasher.combine(type) + } + + public override func compare(_ grid: BaseGrid) -> Bool { + return precisionCompare() <= (grid as! Grid).precisionCompare() + } + + /** + * Get the precision in meters + * + * @return precision meters + */ + public func precisionCompare() -> Int { + var precision = precision() + if precision <= GridType.GZD.precision() { + precision = Int.max + } + return precision + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/grid/GridLabel.swift b/Pods/mgrs-ios/mgrs-ios/grid/GridLabel.swift new file mode 100644 index 0000000..4d3e952 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/grid/GridLabel.swift @@ -0,0 +1,46 @@ +// +// GridLabel.swift +// mgrs-ios +// +// Created by Brian Osborn on 9/2/22. +// + +import Foundation +import grid_ios + +/** + * MGRS Grid Label + */ +public class GridLabel: Label { + + /** + * Grid type + */ + public var gridType: GridType + + /** + * MGRS coordinate + */ + public var coordinate: MGRS + + /** + * Initialize + * + * @param name + * name + * @param center + * center point + * @param bounds + * bounds + * @param gridType + * grid type + * @param coordinate + * MGRS coordinate + */ + public init(_ name: String, _ center: GridPoint, _ bounds: Bounds, _ gridType: GridType, _ coordinate: MGRS) { + self.gridType = gridType + self.coordinate = coordinate + super.init(name, center, bounds) + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/grid/GridLabeler.swift b/Pods/mgrs-ios/mgrs-ios/grid/GridLabeler.swift new file mode 100644 index 0000000..0727baa --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/grid/GridLabeler.swift @@ -0,0 +1,196 @@ +// +// GridLabeler.swift +// mgrs-ios +// +// Created by Brian Osborn on 9/2/22. +// + +import Foundation +import grid_ios +import color_ios + +/** + * Grid labeler + */ +public class GridLabeler: Labeler { + + /** + * Default text size + */ + public static let DEFAULT_TEXT_SIZE = MGRSProperties.instance.doubleValue(PropertyConstants.LABELER, PropertyConstants.TEXT_SIZE) + + /** + * Default buffer size + */ + public static let DEFAULT_BUFFER = MGRSProperties.instance.doubleValue(PropertyConstants.LABELER, PropertyConstants.BUFFER) + + /** + * Initialize + */ + public init() { + super.init(true, 0, nil, UIColor.black, GridLabeler.DEFAULT_TEXT_SIZE, GridLabeler.DEFAULT_BUFFER) + } + + /** + * Initialize + * + * @param minZoom + * minimum zoom + * @param color + * label color + */ + public convenience init(_ minZoom: Int, _ color: UIColor) { + self.init(minZoom, color, GridLabeler.DEFAULT_TEXT_SIZE) + } + + /** + * Initialize + * + * @param minZoom + * minimum zoom + * @param color + * label color + * @param textSize + * label text size + */ + public convenience init(_ minZoom: Int, _ color: UIColor, _ textSize: Double) { + self.init(minZoom, color, textSize, GridLabeler.DEFAULT_BUFFER) + } + + /** + * Initialize + * + * @param minZoom + * minimum zoom + * @param color + * label color + * @param textSize + * label text size + * @param buffer + * grid edge buffer (greater than or equal to 0.0 and less than + * 0.5) + */ + public init(_ minZoom: Int, _ color: UIColor, _ textSize: Double, _ buffer: Double) { + super.init(true, minZoom, nil, color, textSize, buffer) + } + + /** + * Initialize + * + * @param minZoom + * minimum zoom + * @param maxZoom + * maximum zoom + * @param color + * label color + */ + public convenience init(_ minZoom: Int, _ maxZoom: Int?, _ color: UIColor) { + self.init(minZoom, maxZoom, color, GridLabeler.DEFAULT_TEXT_SIZE) + } + + /** + * Initialize + * + * @param minZoom + * minimum zoom + * @param maxZoom + * maximum zoom + * @param color + * label color + * @param textSize + * label text size + */ + public convenience init(_ minZoom: Int, _ maxZoom: Int?, _ color: UIColor, _ textSize: Double) { + self.init(minZoom, maxZoom, color, textSize, GridLabeler.DEFAULT_BUFFER) + } + + /** + * Initialize + * + * @param minZoom + * minimum zoom + * @param maxZoom + * maximum zoom + * @param color + * label color + * @param textSize + * label text size + * @param buffer + * grid edge buffer (greater than or equal to 0.0 and less than + * 0.5) + */ + public init(_ minZoom: Int, _ maxZoom: Int?, _ color: UIColor, _ textSize: Double, _ buffer: Double) { + super.init(true, minZoom, maxZoom, color, textSize, buffer) + } + + /** + * Initialize + * + * @param enabled + * enabled labeler + * @param minZoom + * minimum zoom + * @param maxZoom + * maximum zoom + * @param color + * label color + */ + public convenience init(_ enabled: Bool, _ minZoom: Int, _ maxZoom: Int?, _ color: UIColor) { + self.init(enabled, minZoom, maxZoom, color, GridLabeler.DEFAULT_TEXT_SIZE) + } + + /** + * Initialize + * + * @param enabled + * enabled labeler + * @param minZoom + * minimum zoom + * @param maxZoom + * maximum zoom + * @param color + * label color + * @param textSize + * label text size + */ + public convenience init(_ enabled: Bool, _ minZoom: Int, _ maxZoom: Int?, _ color: UIColor, _ textSize: Double) { + self.init(enabled, minZoom, maxZoom, color, textSize, GridLabeler.DEFAULT_BUFFER) + } + + /** + * Initialize + * + * @param enabled + * enabled labeler + * @param minZoom + * minimum zoom + * @param maxZoom + * maximum zoom + * @param color + * label color + * @param textSize + * label text size + * @param buffer + * grid edge buffer (greater than or equal to 0.0 and less than + * 0.5) + */ + public init(_ enabled: Bool, _ minZoom: Int, _ maxZoom: Int?, _ color: UIColor, _ textSize: Double, _ buffer: Double) { + super.init(enabled, minZoom, maxZoom, color, textSize, buffer) + } + + /** + * Get labels for the bounds + * + * @param tileBounds + * tile bounds + * @param gridType + * grid type + * @param zone + * grid zone + * @return labels + */ + public func labels(_ tileBounds: Bounds, _ gridType: GridType, _ zone: GridZone) -> [GridLabel]? { + preconditionFailure("This method must be overridden") + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/grid/GridType.swift b/Pods/mgrs-ios/mgrs-ios/grid/GridType.swift new file mode 100644 index 0000000..387c200 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/grid/GridType.swift @@ -0,0 +1,157 @@ +// +// GridType.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation + +/** + * Grid type enumeration + */ +public enum GridType: Int, CaseIterable { + + /** + * Grid Zone Designator + */ + case GZD + + /** + * Hundred Kilometer + */ + case HUNDRED_KILOMETER + + /** + * Ten Kilometer + */ + case TEN_KILOMETER + + /** + * Kilometer + */ + case KILOMETER + + /** + * Hundred Meter + */ + case HUNDRED_METER + + /** + * Ten Meter + */ + case TEN_METER + + /** + * Meter + */ + case METER + + /** + * Grid precision in meters + * + * @return precision meters + */ + public func precision() -> Int { + let precision: Int + switch self { + case .GZD: + precision = 0 + case .HUNDRED_KILOMETER: + precision = 100000 + case .TEN_KILOMETER: + precision = 10000 + case .KILOMETER: + precision = 1000 + case .HUNDRED_METER: + precision = 100 + case .TEN_METER: + precision = 10 + case .METER: + precision = 1 + } + return precision + } + + /** + * Get the Grid Type accuracy number of digits in the easting and northing + * values + * + * @return accuracy digits + */ + public func accuracy() -> Int { + return max(rawValue - 1, 0) + } + + /** + * Get the Grid Type with the accuracy number of digits in the easting and + * northing values. Accuracy must be inclusively between 0 + * (GridType.HUNDRED_KILOMETER) and 5 (GridType.METER). + * + * @param accuracy + * accuracy digits between 0 (inclusive) and 5 (inclusive) + * @return grid type + */ + public static func withAccuracy(_ accuracy: Int) -> GridType { + if accuracy < 0 || accuracy > 5 { + preconditionFailure("Grid Type accuracy digits must be >= 0 and <= 5. accuracy digits: \(accuracy)") + } + return self.allCases[accuracy + 1] + } + + /** + * Get the precision of the value in meters based upon trailing 0's + * + * @param value + * value in meters + * @return precision grid type + */ + public static func precision(_ value: Double) -> GridType { + let precision: GridType + if value.truncatingRemainder(dividingBy: Double(HUNDRED_KILOMETER.precision())) == 0 { + precision = HUNDRED_KILOMETER + } else if value.truncatingRemainder(dividingBy: Double(TEN_KILOMETER.precision())) == 0 { + precision = TEN_KILOMETER + } else if value.truncatingRemainder(dividingBy: Double(KILOMETER.precision())) == 0 { + precision = KILOMETER + } else if value.truncatingRemainder(dividingBy: Double(HUNDRED_METER.precision())) == 0 { + precision = HUNDRED_METER + } else if value.truncatingRemainder(dividingBy: Double(TEN_METER.precision())) == 0 { + precision = TEN_METER + } else { + precision = METER + } + return precision + } + + /** + * Get the less precise (larger precision value) grid types + * + * @param type + * grid type + * @return grid types less precise + */ + public static func lessPrecise(_ type: GridType) -> [GridType] { + let cases = self.allCases + let index = cases.firstIndex(of: type) + return Array(cases.prefix(upTo: index!)) + } + + /** + * Get the more precise (smaller precision value) grid types + * + * @param type + * grid type + * @return grid types more precise + */ + public static func morePrecise(_ type: GridType) -> [GridType] { + let cases = self.allCases + let index = cases.firstIndex(of: type) + return Array(cases.suffix(from: index! + 1)) + } + + var name: String { + get { return String(describing: self) } + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/grid/Grids.swift b/Pods/mgrs-ios/mgrs-ios/grid/Grids.swift new file mode 100644 index 0000000..24055b3 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/grid/Grids.swift @@ -0,0 +1,1004 @@ +// +// Grids.swift +// mgrs-ios +// +// Created by Brian Osborn on 9/2/22. +// + +import Foundation +import grid_ios + +/** + * Grids + */ +public class Grids: BaseGrids { + + /** + * Grid zoom display offset from XYZ tile zoom levels, defaulted to MGRSConstants.ZOOM_OFFSET + */ + public var zoomOffset = MGRSConstants.ZOOM_OFFSET + + /** + * Grids + */ + private var typeGrids: [GridType: Grid] = [:] + + /** + * Create only Grid Zone Designator grids + * + * @return grids + */ + public static func createGZD() -> Grids { + return Grids([GridType.GZD]) + } + + /** + * Initialize, all grid types enabled per property configurations + */ + public init() { + super.init(MGRSProperties.instance) + createGrids() + createZoomGrids() + } + + /** + * Initialize + * + * @param types + * grid types to enable + */ + public init(_ types: [GridType]) { + super.init(MGRSProperties.instance) + + createGrids(false) + + for type in types { + grid(type).enabled = true + } + + createZoomGrids() + } + + /** + * Get the default grid line width + * + * @return width + */ + public override func defaultWidth() -> Double { + return Grid.DEFAULT_WIDTH + } + + /** + * Get the grids + * + * @return grids + */ + public override func grids() -> [BaseGrid] { + return Array(typeGrids.values) + } + + /** + * Create a new grid, override to create a specialized grid + * + * @param type + * grid type + * @return grid + */ + public func newGrid(_ type: GridType) -> Grid { + return Grid(type) + } + + /** + * Create a new zoom grids + * + * @param zoom + * zoom level + * @return zoom grids + */ + public override func newZoomGrids(_ zoom: Int) -> BaseZoomGrids { + return ZoomGrids(zoom) + } + + public override func grids(_ zoom: Int) -> ZoomGrids { + return super.grids(zoom) as! ZoomGrids + } + + /** + * Create the grids + */ + private func createGrids() { + createGrids(nil) + } + + /** + * Create the grids + * + * @param enabled + * enable created grids + */ + private func createGrids(_ enabled: Bool?) { + + let propagate = properties.boolValue(PropertyConstants.GRIDS, PropertyConstants.PROPAGATE, false) + var styles: [GridType: GridStyle]? = nil + if propagate != nil && propagate! { + styles = [:] + } + + createGrid(GridType.GZD, &styles, enabled, GZDLabeler()) + createGrid(GridType.HUNDRED_KILOMETER, &styles, enabled, MGRSLabeler()) + createGrid(GridType.TEN_KILOMETER, &styles, enabled, MGRSLabeler()) + createGrid(GridType.KILOMETER, &styles, enabled, MGRSLabeler()) + createGrid(GridType.HUNDRED_METER, &styles, enabled, MGRSLabeler()) + createGrid(GridType.TEN_METER, &styles, enabled, MGRSLabeler()) + createGrid(GridType.METER, &styles, enabled, MGRSLabeler()) + + } + + /** + * Create the grid + * + * @param type + * grid type + * @param styles + * propagate grid styles + * @param enabled + * enable created grids + * @param labeler + * grid labeler + */ + private func createGrid(_ type: GridType, _ styles: inout [GridType: GridStyle]?, _ enabled: Bool?, _ labeler: GridLabeler?) { + + let grid = newGrid(type) + + let gridKey = type.name.lowercased() + + loadGrid(grid, gridKey, enabled, labeler) + + if styles != nil { + styles![type] = GridStyle(grid.color, grid.width) + } + + loadGridStyles(grid, &styles, gridKey) + + typeGrids[type] = grid + } + + /** + * Load grid styles within a higher precision grid + * + * @param grid + * grid + * @param styles + * propagate grid styles + * @param gridKey + * grid key + */ + private func loadGridStyles(_ grid: Grid, _ styles: inout [GridType: GridStyle]?, _ gridKey: String) { + + let precision = grid.precision() + if precision < GridType.HUNDRED_KILOMETER.precision() { + loadGridStyle(grid, &styles, gridKey, GridType.HUNDRED_KILOMETER) + } + if precision < GridType.TEN_KILOMETER.precision() { + loadGridStyle(grid, &styles, gridKey, GridType.TEN_KILOMETER) + } + if precision < GridType.KILOMETER.precision() { + loadGridStyle(grid, &styles, gridKey, GridType.KILOMETER) + } + if precision < GridType.HUNDRED_METER.precision() { + loadGridStyle(grid, &styles, gridKey, GridType.HUNDRED_METER) + } + if precision < GridType.TEN_METER.precision() { + loadGridStyle(grid, &styles, gridKey, GridType.TEN_METER) + } + + } + + /** + * Load a grid style within a higher precision grid + * + * @param grid + * grid + * @param styles + * propagate grid styles + * @param gridKey + * grid key + * @param gridType + * style grid type + */ + private func loadGridStyle(_ grid: Grid, _ styles: inout [GridType: GridStyle]?, _ gridKey: String, _ gridType: GridType) { + + let gridKey2 = gridType.name.lowercased() + + var color = loadGridStyleColor(gridKey, gridKey2) + var width = loadGridStyleWidth(gridKey, gridKey2) + + if (color == nil || width == nil) && styles != nil { + let style = styles![gridType] + if style != nil { + if color == nil { + let styleColor = style!.color + if styleColor != nil { + color = styleColor!.copy() as? UIColor + } + } + if width == nil { + width = style?.width + } + } + } + + if color != nil || width != nil { + + let style = gridStyle(color, width, grid) + grid.setStyle(gridType, style) + + if styles != nil { + styles![gridType] = style + } + } + + } + + /** + * Get the grid + * + * @param type + * grid type + * @return grid + */ + public func grid(_ type: GridType) -> Grid { + return typeGrids[type]! + } + + /** + * Get the grid precision for the zoom level + * + * @param zoom + * zoom level + * @return grid type precision + */ + + public func precision(_ zoom: Int) -> GridType? { + return grids(zoom).precision() + } + + /** + * Set the active grid types + * + * @param types + * grid types + */ + public func setGrids(_ types: [GridType]) { + var disable = Set(GridType.allCases) + for gridType in types { + enable(gridType) + disable.remove(gridType) + } + disableTypes(Array(disable)) + } + + /** + * Set the active grids + * + * @param grids + * grids + */ + public func setGrids(_ grids: [Grid]) { + var disable = Set(GridType.allCases) + for grid in grids { + enable(grid) + disable.remove(grid.type) + } + disableTypes(Array(disable)) + } + + /** + * Enable grid types + * + * @param types + * grid types + */ + public func enableTypes(_ types: [GridType]) { + for type in types { + enable(type) + } + } + + /** + * Disable grid types + * + * @param types + * grid types + */ + public func disableTypes(_ types: [GridType]) { + for type in types { + disable(type) + } + } + + /** + * Is the grid type enabled + * + * @param type + * grid type + * @return true if enabled + */ + public func isEnabled(_ type: GridType) -> Bool { + return grid(type).enabled + } + + /** + * Enable the grid type + * + * @param type + * grid type + */ + public func enable(_ type: GridType) { + enable(grid(type)) + } + + /** + * Disable the grid type + * + * @param type + * grid type + */ + public func disable(_ type: GridType) { + disable(grid(type)) + } + + /** + * Set the grid minimum zoom + * + * @param type + * grid type + * @param minZoom + * minimum zoom + */ + public func setMinZoom(_ type: GridType, _ minZoom: Int) { + setMinZoom(grid(type), minZoom) + } + + /** + * Set the grid maximum zoom + * + * @param type + * grid type + * @param maxZoom + * maximum zoom + */ + public func setMaxZoom(_ type: GridType, _ maxZoom: Int?) { + setMaxZoom(grid(type), maxZoom) + } + + /** + * Set the grid zoom range + * + * @param type + * grid type + * @param minZoom + * minimum zoom + * @param maxZoom + * maximum zoom + */ + public func setZoomRange(_ type: GridType, _ minZoom: Int, _ maxZoom: Int?) { + setZoomRange(grid(type), minZoom, maxZoom) + } + + /** + * Set the grid minimum level override for drawing grid lines + * + * @param type + * grid type + * @param minZoom + * minimum zoom level or null to remove + */ + public func setLinesMinZoom(_ type: GridType, _ minZoom: Int?) { + grid(type).linesMinZoom = minZoom + } + + /** + * Set the grid maximum level override for drawing grid lines + * + * @param type + * grid type + * @param maxZoom + * maximum zoom level or null to remove + */ + public func setLinesMaxZoom(_ type: GridType, _ maxZoom: Int?) { + grid(type).linesMaxZoom = maxZoom + } + + /** + * Set all grid line colors + * + * @param color + * grid line color + */ + public func setAllColors(_ color: UIColor) { + setColor(GridType.allCases, color) + } + + /** + * Set the grid line color for the grid types + * + * @param types + * grid types + * @param color + * grid line color + */ + public func setColor(_ types: [GridType], _ color: UIColor) { + for type in types { + setColor(type, color) + } + } + + /** + * Set the grid line color for the grid type + * + * @param type + * grid type + * @param color + * grid line color + */ + public func setColor(_ type: GridType, _ color: UIColor) { + grid(type).color = color + } + + /** + * Set all grid line widths + * + * @param width + * grid line width + */ + public func setAllWidths(_ width: Double) { + setWidth(GridType.allCases, width) + } + + /** + * Set the grid line width for the grid types + * + * @param types + * grid types + * @param width + * grid line width + */ + public func setWidth(_ types: [GridType], _ width: Double) { + for type in types { + setWidth(type, width) + } + } + + /** + * Set the grid line width for the grid type + * + * @param type + * grid type + * @param width + * grid line width + */ + public func setWidth(_ type: GridType, _ width: Double) { + grid(type).width = width + } + + /** + * Delete propagated styles + */ + public func deletePropagatedStyles() { + deletePropagatedStyles(GridType.allCases) + } + + /** + * Delete propagated styles for the grid types + * + * @param types + * grid types + */ + public func deletePropagatedStyles(_ types: [GridType]) { + for type in types { + deletePropagatedStyles(type) + } + } + + /** + * Delete propagated styles for the grid type + * + * @param type + * grid type + */ + public func deletePropagatedStyles(_ type: GridType) { + grid(type).clearPrecisionStyles() + } + + /** + * Set the grid type precision line color for the grid types + * + * @param types + * grid types + * @param precisionType + * precision grid type + * @param color + * grid line color + */ + public func setColor(_ types: [GridType], _ precisionType: GridType, _ color: UIColor) { + for type in types { + setColor(type, precisionType, color) + } + } + + /** + * Set the grid type precision line colors for the grid type + * + * @param type + * grid type + * @param precisionTypes + * precision grid types + * @param color + * grid line color + */ + public func setColor(_ type: GridType, _ precisionTypes: [GridType], _ color: UIColor) { + for precisionType in precisionTypes { + setColor(type, precisionType, color) + } + } + + /** + * Set the grid type precision line color for the grid type + * + * @param type + * grid type + * @param precisionType + * precision grid type + * @param color + * grid line color + */ + public func setColor(_ type: GridType, _ precisionType: GridType, _ color: UIColor) { + grid(type).setColor(precisionType, color) + } + + /** + * Set the grid type precision line width for the grid types + * + * @param types + * grid types + * @param precisionType + * precision grid type + * @param width + * grid line width + */ + public func setWidth(_ types: [GridType], _ precisionType: GridType, _ width: Double) { + for type in types { + setWidth(type, precisionType, width) + } + } + + /** + * Set the grid type precision line widths for the grid type + * + * @param type + * grid type + * @param precisionTypes + * precision grid types + * @param width + * grid line width + */ + public func setWidth(_ type: GridType, _ precisionTypes: [GridType], _ width: Double) { + for precisionType in precisionTypes { + setWidth(type, precisionType, width) + } + } + + /** + * Set the grid type precision line width for the grid type + * + * @param type + * grid type + * @param precisionType + * precision grid type + * @param width + * grid line width + */ + public func setWidth(_ type: GridType, _ precisionType: GridType, _ width: Double) { + grid(type).setWidth(precisionType, width) + } + + /** + * Get the labeler for the grid type + * + * @param type + * grid type + * @return labeler or null + */ + public func labeler(_ type: GridType) -> GridLabeler? { + return grid(type).labeler() + } + + /** + * Has a labeler for the grid type + * + * @param type + * grid type + * @return true if has labeler + */ + public func hasLabeler(_ type: GridType) -> Bool { + return grid(type).hasLabeler() + } + + /** + * Set the labeler for the grid type + * + * @param type + * grid type + * @param labeler + * labeler + */ + public func setLabeler(_ type: GridType, _ labeler: GridLabeler) { + grid(type).setLabeler(labeler) + } + + /** + * Disable all grid labelers + */ + public func disableAllLabelers() { + disableLabelers(GridType.allCases) + } + + /** + * Enable the labelers for the grid types + * + * @param types + * grid types + */ + public func enableLabelers(_ types: [GridType]) { + for type in types { + enableLabeler(type) + } + } + + /** + * Disable the labelers for the grid types + * + * @param types + * grid types + */ + public func disableLabelers(_ types: [GridType]) { + for type in types { + disableLabeler(type) + } + } + + /** + * Is a labeler enabled for the grid type + * + * @param type + * grid type + * @return true if labeler enabled + */ + public func isLabelerEnabled(_ type: GridType) -> Bool { + let labeler = labeler(type) + return labeler != nil && labeler!.enabled + } + + /** + * Enable the grid type labeler + * + * @param type + * grid type + */ + public func enableLabeler(_ type: GridType) { + requiredLabeler(type).enabled = true + } + + /** + * Disable the grid type labeler + * + * @param type + * grid type + */ + public func disableLabeler(_ type: GridType) { + let labeler = labeler(type) + if labeler != nil { + labeler!.enabled = false + } + } + + /** + * Get the labeler for the grid type + * + * @param type + * grid type + * @return labeler or null + */ + private func requiredLabeler(_ type: GridType) -> GridLabeler { + let labeler = labeler(type) + if labeler == nil { + preconditionFailure("Grid type does not have a labeler: \(type)") + } + return labeler! + } + + /** + * Set the grid minimum zoom + * + * @param type + * grid type + * @param minZoom + * minimum zoom + */ + public func setLabelMinZoom(_ type: GridType, _ minZoom: Int) { + let labeler = requiredLabeler(type) + labeler.minZoom = minZoom + let maxZoom = labeler.maxZoom + if maxZoom != nil && maxZoom! < minZoom { + labeler.maxZoom = minZoom + } + } + + /** + * Set the grid maximum zoom + * + * @param type + * grid type + * @param maxZoom + * maximum zoom + */ + public func setLabelMaxZoom(_ type: GridType, _ maxZoom: Int?) { + let labeler = requiredLabeler(type) + labeler.maxZoom = maxZoom + if maxZoom != nil && labeler.minZoom > maxZoom! { + labeler.minZoom = maxZoom! + } + } + + /** + * Set the grid zoom range + * + * @param type + * grid type + * @param minZoom + * minimum zoom + * @param maxZoom + * maximum zoom + */ + public func setLabelZoomRange(_ type: GridType, _ minZoom: Int, _ maxZoom: Int?) { + let labeler = requiredLabeler(type) + if maxZoom != nil && maxZoom! < minZoom { + preconditionFailure("Min zoom '\(minZoom)' can not be larger than max zoom '\(maxZoom!)'") + } + labeler.minZoom = minZoom + labeler.maxZoom = maxZoom + } + + /** + * Set the label grid edge buffer for the grid types + * + * @param types + * grid types + * @param buffer + * label buffer (greater than or equal to 0.0 and less than 0.5) + */ + public func setLabelBuffer(_ types: [GridType], _ buffer: Double) { + for type in types { + setLabelBuffer(type, buffer) + } + } + + /** + * Get the label grid edge buffer + * + * @param type + * grid type + * @return label buffer (greater than or equal to 0.0 and less than 0.5) + */ + public func getLabelBuffer(_ type: GridType) -> Double { + return grid(type).labelBuffer() + } + + /** + * Set the label grid edge buffer + * + * @param type + * grid type + * @param buffer + * label buffer (greater than or equal to 0.0 and less than 0.5) + */ + public func setLabelBuffer(_ type: GridType, _ buffer: Double) { + requiredLabeler(type).buffer = buffer + } + + /** + * Set all label colors + * + * @param color + * label color + */ + public func setAllLabelColors(_ color: UIColor) { + for grid in typeGrids.values { + if grid.hasLabeler() { + setLabelColor(grid.type, color) + } + } + } + + /** + * Set the label color for the grid types + * + * @param types + * grid types + * @param color + * label color + */ + public func setLabelColor(_ types: [GridType], _ color: UIColor) { + for type in types { + setLabelColor(type, color) + } + } + + /** + * Set the label color + * + * @param type + * grid type + * @param color + * label color + */ + public func setLabelColor(_ type: GridType, _ color: UIColor) { + requiredLabeler(type).color = color + } + + /** + * Set all label text sizes + * + * @param textSize + * label text size + */ + public func setAllLabelTextSizes(_ textSize: Double) { + for grid in typeGrids.values { + if grid.hasLabeler() { + setLabelTextSize(grid.type, textSize) + } + } + } + + /** + * Set the label text size for the grid types + * + * @param types + * grid types + * @param textSize + * label text size + */ + public func setLabelTextSize(_ types: [GridType], _ textSize: Double) { + for type in types { + setLabelTextSize(type, textSize) + } + } + + /** + * Set the label text size + * + * @param type + * grid type + * @param textSize + * label text size + */ + public func setLabelTextSize(_ type: GridType, _ textSize: Double) { + requiredLabeler(type).textSize = textSize + } + + /** + * Draw a tile with the dimensions and XYZ coordinate + * + * @param tileWidth tile width + * @param tileHeight tile height + * @param x x coordinate + * @param y y coordinate + * @param zoom zoom level + * @return image tile + */ + public func drawTile(_ tileWidth: Int, _ tileHeight: Int, _ x: Int, _ y: Int, _ zoom: Int) -> UIImage? { + var image: UIImage? = nil + let gridZoom = zoom + zoomOffset + let zoomGrids = grids(gridZoom) + if zoomGrids.hasGrids() { + image = drawTile(GridTile(tileWidth, tileHeight, x, y, zoom, gridZoom), zoomGrids) + } + return image + } + + /** + * Draw a tile with the dimensions and bounds + * + * @param tileWidth tile width + * @param tileHeight tile height + * @param bounds bounds + * @return image tile + */ + public func drawTile(_ tileWidth: Int, _ tileHeight: Int, _ bounds: Bounds) -> UIImage? { + return drawTile(GridTile(tileWidth, tileHeight, bounds)) + } + + /** + * Draw the tile + * + * @param gridTile tile + * @return image tile + */ + public func drawTile(_ gridTile: GridTile) -> UIImage? { + var image: UIImage? = nil + let zoomGrids = grids(gridTile.zoom) + if zoomGrids.hasGrids() { + image = drawTile(gridTile, zoomGrids) + } + return image + } + + /** + * Draw the tile + * + * @param gridTile tile + * @param zoomGrids zoom grids + * @return image tile + */ + private func drawTile(_ gridTile: GridTile, _ zoomGrids: ZoomGrids) -> UIImage? { + + UIGraphicsBeginImageContext(CGSize(width: CGFloat(gridTile.width), height: CGFloat(gridTile.height))) + let context = UIGraphicsGetCurrentContext()! + + let gridRange = GridZones.gridRange(gridTile.bounds) + + for grid in zoomGrids { + + // draw this grid for each zone + for zone in gridRange { + + let lines = grid.lines(gridTile, zone) + if lines != nil { + Grids.drawLines(lines!, gridTile, grid, zone, context) + } + + let labels = grid.labels(gridTile, zone) + if labels != nil { + TileDraw.drawLabels(labels!, grid.labelBuffer(), gridTile, grid) + } + + } + } + + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return image + } + + /** + * Draw the lines on the tile + * + * @param lines lines to draw + * @param tile tile + * @param grid grid + * @param zone grid zone + * @param context graphics context + */ + public static func drawLines(_ lines: [MGRSLine], _ tile: GridTile, _ grid: Grid, _ zone: GridZone, _ context: CGContext) { + + let pixelRange = zone.bounds.pixelRange(tile) + + context.saveGState() + context.clip(to: CGRect(x: CGFloat(pixelRange.left), y: CGFloat(pixelRange.top), width: CGFloat(pixelRange.width), height: CGFloat(pixelRange.height))) + + for line in lines { + + let gridType = line.gridType != nil ? line.gridType! : grid.type + let width = grid.width(gridType) + let color = grid.color(gridType) + + TileDraw.drawLine(line, tile, width, color, context) + + } + + context.restoreGState() + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/grid/MGRSLabeler.swift b/Pods/mgrs-ios/mgrs-ios/grid/MGRSLabeler.swift new file mode 100644 index 0000000..582e796 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/grid/MGRSLabeler.swift @@ -0,0 +1,103 @@ +// +// MGRSLabeler.swift +// mgrs-ios +// +// Created by Brian Osborn on 9/2/22. +// + +import Foundation +import grid_ios + +/** + * MGRS grid labeler + */ +public class MGRSLabeler: GridLabeler { + + public override func labels(_ tileBounds: Bounds, _ gridType: GridType, _ zone: GridZone) -> [GridLabel]? { + + var labels: [GridLabel]? = nil + + let drawBounds = zone.drawBounds(tileBounds, gridType) + + if drawBounds != nil { + + labels = [] + + let precision = Double(gridType.precision()) + + for easting in stride(from: drawBounds!.minLongitude, through: drawBounds!.maxLongitude, by: precision) { + for northing in stride(from: drawBounds!.minLatitude, through: drawBounds!.maxLatitude, by: precision) { + + let gridLabel = label(gridType, zone, easting, northing) + if gridLabel != nil { + labels!.append(gridLabel!) + } + + } + } + + } + + return labels + } + + /** + * Get the grid zone label + * + * @param gridType + * grid type + * @param easting + * easting + * @param northing + * northing + * @return labels + */ + private func label(_ gridType: GridType, _ zone: GridZone, _ easting: Double, + _ northing: Double) -> GridLabel? { + + var label: GridLabel? = nil + + let precision = Double(gridType.precision()) + let bounds = zone.bounds + let zoneNumber = zone.number() + let hemisphere = zone.hemisphere() + + let northwest = UTM.point(zoneNumber, hemisphere, easting, + northing + precision) + let southwest = UTM.point(zoneNumber, hemisphere, easting, northing) + let southeast = UTM.point(zoneNumber, hemisphere, easting + precision, + northing) + let northeast = UTM.point(zoneNumber, hemisphere, easting + precision, + northing + precision) + + var minLatitude = max(southwest.latitude, southeast.latitude) + minLatitude = max(minLatitude, bounds.minLatitude) + var maxLatitude = min(northwest.latitude, northeast.latitude) + maxLatitude = min(maxLatitude, bounds.maxLatitude) + + var minLongitude = max(southwest.longitude, northwest.longitude) + minLongitude = max(minLongitude, bounds.minLongitude) + var maxLongitude = min(southeast.longitude, northeast.longitude) + maxLongitude = min(maxLongitude, bounds.maxLongitude) + + if minLongitude <= maxLongitude && minLatitude <= maxLatitude { + + let labelBounds = Bounds.degrees(minLongitude, minLatitude, + maxLongitude, maxLatitude) + let center = labelBounds.centroid() + + let mgrs = MGRS.from(center) + var id: String + if gridType == GridType.HUNDRED_KILOMETER { + id = mgrs.columnRowId() + } else { + id = mgrs.eastingAndNorthing(gridType) + } + + label = GridLabel(id, center, labelBounds, gridType, mgrs) + } + + return label + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/grid/ZoomGrids.swift b/Pods/mgrs-ios/mgrs-ios/grid/ZoomGrids.swift new file mode 100644 index 0000000..a1a379c --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/grid/ZoomGrids.swift @@ -0,0 +1,34 @@ +// +// ZoomGrids.swift +// mgrs-ios +// +// Created by Brian Osborn on 9/2/22. +// + +import Foundation +import grid_ios + +/** + * Zoom Level Matching Grids + */ +public class ZoomGrids: BaseZoomGrids, Sequence { + + /** + * Get the grid type precision + * + * @return grid type precision + */ + public func precision() -> GridType? { + var type: GridType? = nil + if hasGrids() { + type = (grids.first as! Grid).type + } + return type + } + + public func makeIterator() -> IndexingIterator<[Grid]> { + let value: [Grid] = grids.map { $0 as! Grid } + return value.makeIterator() + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/gzd/BandLetterRange.swift b/Pods/mgrs-ios/mgrs-ios/gzd/BandLetterRange.swift new file mode 100644 index 0000000..e71bf4e --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/gzd/BandLetterRange.swift @@ -0,0 +1,88 @@ +// +// BandLetterRange.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation + +/** + * Band Letter Range + */ +public class BandLetterRange: Sequence { + + /** + * Southern band letter + */ + public var south: Character + + /** + * Northern band letter + */ + public var north: Character + + /** + * Initialize, full range + */ + public convenience init() { + self.init(MGRSConstants.MIN_BAND_LETTER, MGRSConstants.MAX_BAND_LETTER) + } + + /** + * Initialize + * + * @param south + * southern band letter + * @param north + * northern band letter + */ + public init(_ south: Character, _ north: Character) { + self.south = south + self.north = north + } + + /** + * Get the southern latitude + * + * @return latitude + */ + public func southLatitude() -> Double { + return GridZones.latitudeBand(south).south + } + + /** + * Get the northern latitude + * + * @return latitude + */ + public func northLatitude() -> Double { + return GridZones.latitudeBand(north).north + } + + public func makeIterator() -> BandLetterRangeIterator { + return BandLetterRangeIterator(self) + } + +} + +public struct BandLetterRangeIterator: IteratorProtocol { + + var letter: Character + let north: Character + + init(_ range: BandLetterRange) { + self.letter = range.south + self.north = range.north + } + + public mutating func next() -> Character? { + var value: Character? = nil + if letter <= north { + value = letter + letter = MGRSUtils.nextBandLetter(letter) + } + return value + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/gzd/GZDLabeler.swift b/Pods/mgrs-ios/mgrs-ios/gzd/GZDLabeler.swift new file mode 100644 index 0000000..8cb5c67 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/gzd/GZDLabeler.swift @@ -0,0 +1,24 @@ +// +// GZDLabeler.swift +// mgrs-ios +// +// Created by Brian Osborn on 9/2/22. +// + +import Foundation +import grid_ios + +/** + * Grid Zone Designator labeler + */ +public class GZDLabeler: GridLabeler { + + public override func labels(_ tileBounds: Bounds, _ gridType: GridType, _ zone: GridZone) -> [GridLabel]? { + var labels = [GridLabel]() + let bounds = zone.bounds + let center = bounds.centroid() + labels.append(GridLabel(zone.name(), center, bounds, gridType, MGRS.from(center))) + return labels + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/gzd/GridRange.swift b/Pods/mgrs-ios/mgrs-ios/gzd/GridRange.swift new file mode 100644 index 0000000..42e4b01 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/gzd/GridRange.swift @@ -0,0 +1,149 @@ +// +// GridRange.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation +import grid_ios + +/** + * Grid Range + */ +public class GridRange: Sequence { + + /** + * Zone Number Range + */ + public var zoneNumberRange: ZoneNumberRange + + /** + * Band Letter Range + */ + public var bandLetterRange: BandLetterRange + + /** + * Initialize, full range + */ + public init() { + self.zoneNumberRange = ZoneNumberRange() + self.bandLetterRange = BandLetterRange() + } + + /** + * Initialize + * + * @param bandNumberRange + * band number range + * @param bandLettersRange + * band letters range + */ + public init(_ zoneNumberRange: ZoneNumberRange, _ bandLetterRange: BandLetterRange) { + self.zoneNumberRange = zoneNumberRange + self.bandLetterRange = bandLetterRange + } + + /** + * Get the grid range bounds + * + * @return bounds + */ + public func bounds() -> Bounds { + + let west = zoneNumberRange.westLongitude() + let south = bandLetterRange.southLatitude() + let east = zoneNumberRange.eastLongitude() + let north = bandLetterRange.northLatitude() + + return Bounds.degrees(west, south, east, north) + } + + public func makeIterator() -> GridRangeIterator { + return GridRangeIterator(self) + } + +} + +public struct GridRangeIterator: IteratorProtocol { + + let minZoneNumber: Int + let maxZoneNumber: Int + let minBandLetter: Character + let maxBandLetter: Character + var zoneNumber: Int + var bandLetter: Character + var gridZone: GridZone? + var additional: [GridZone] = [] + + init(_ range: GridRange) { + minZoneNumber = range.zoneNumberRange.west + maxZoneNumber = range.zoneNumberRange.east + minBandLetter = range.bandLetterRange.south + maxBandLetter = range.bandLetterRange.north + zoneNumber = minZoneNumber + bandLetter = minBandLetter + } + + public mutating func next() -> GridZone? { + var gridZone: GridZone? = nil + + while gridZone == nil && zoneNumber <= maxZoneNumber { + + gridZone = GridZones.gridZone(zoneNumber, bandLetter) + + // Handle special case grid gaps (Svalbard) + if gridZone == nil { + + // Retrieve the western grid if on the left edge + if zoneNumber == minZoneNumber { + additional.append(GridZones.gridZone(zoneNumber - 1, bandLetter)!) + } + + // Expand to the eastern grid if on the right edge + if zoneNumber == maxZoneNumber { + additional.append(GridZones.gridZone(zoneNumber + 1, bandLetter)!) + } + + } else { + + // Handle special case grid zone expansions (Norway) + let expand = gridZone!.stripExpand() + if expand != 0 { + if expand > 0 { + for expandZone in stride(from: zoneNumber + expand, to: zoneNumber, by: -1) { + if expandZone > maxZoneNumber { + additional.append(GridZones.gridZone(expandZone, bandLetter)!) + } else { + break + } + } + } else { + for expandZone in zoneNumber + expand ..< zoneNumber { + if expandZone < minZoneNumber { + additional.append(GridZones.gridZone(expandZone, bandLetter)!) + } else { + break + } + } + } + } + + } + + bandLetter = MGRSUtils.nextBandLetter(bandLetter) + if bandLetter > maxBandLetter { + zoneNumber += 1 + bandLetter = minBandLetter + } + + } + + if gridZone == nil && additional.count > 0 { + gridZone = additional.removeFirst() + } + + return gridZone + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/gzd/GridZone.swift b/Pods/mgrs-ios/mgrs-ios/gzd/GridZone.swift new file mode 100644 index 0000000..b8eb092 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/gzd/GridZone.swift @@ -0,0 +1,329 @@ +// +// GridZone.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation +import grid_ios + +/** + * Grid Zone + */ +public class GridZone { + + /** + * Longitudinal strip + */ + public let strip: LongitudinalStrip + + /** + * Latitude band + */ + public let band: LatitudeBand + + /** + * Bounds + */ + public let bounds: Bounds + + /** + * Constructor + * + * @param strip + * longitudinal strip + * @param band + * latitude band + */ + public init(_ strip: LongitudinalStrip, _ band: LatitudeBand) { + self.strip = strip + self.band = band + self.bounds = Bounds.degrees(strip.west, band.south, strip.east, band.north) + } + + /** + * Get the zone number + * + * @return zone number + */ + public func number() -> Int { + return strip.number + } + + /** + * Get the band letter + * + * @return band letter + */ + public func letter() -> Character { + return band.letter + } + + /** + * Get the hemisphere + * + * @return hemisphere + */ + public func hemisphere() -> Hemisphere { + return band.hemisphere + } + + /** + * Get the label name + * + * @return name + */ + public func name() -> String { + return MGRSUtils.labelName(number(), letter()) + } + + /** + * Is the provided bounds within the zone bounds + * + * @param bounds + * bounds + * @return true if within bounds + */ + public func isWithin(_ bounds: Bounds) -> Bool { + let boundsUnit = bounds.toUnit(self.bounds.unit) + return self.bounds.south <= boundsUnit.north + && self.bounds.north >= boundsUnit.south + && self.bounds.west <= boundsUnit.east + && self.bounds.east >= boundsUnit.west + } + + /** + * Get the longitudinal strip expansion, number of additional neighbors to + * iterate over in combination with this strip + * + * @return longitudinal strip neighbor iteration expansion + */ + public func stripExpand() -> Int { + return strip.expand + } + + /** + * Get the grid zone lines + * + * @param gridType + * grid type + * @return lines + */ + public func lines(_ gridType: GridType) -> [MGRSLine]? { + return lines(bounds, gridType) + } + + /** + * Get the grid zone lines + * + * @param tileBounds + * tile bounds + * @param gridType + * grid type + * @return lines + */ + public func lines(_ tileBounds: Bounds, _ gridType: GridType) -> [MGRSLine]? { + + var lines: [MGRSLine]? = nil + + if gridType == GridType.GZD { + // if precision is 0, draw the zone bounds + lines = [] + for line in bounds.lines() { + lines?.append(MGRSLine(line, GridType.GZD)) + } + } else { + + let drawBounds = drawBounds(tileBounds, gridType) + + if drawBounds != nil { + + lines = [] + + let precision = Double(gridType.precision()) + let zoneNumber = number() + let hemisphere = hemisphere() + let minLon = bounds.minLongitude + let maxLon = bounds.maxLongitude + + var easting = drawBounds!.minLongitude + while easting < drawBounds!.maxLongitude { + + let eastingPrecision = GridType.precision(easting) + + var northing = drawBounds!.minLatitude + while northing < drawBounds!.maxLatitude { + + let northingPrecision = GridType.precision(northing) + + var southwest = UTM.point(zoneNumber, hemisphere, + easting, northing) + let northwest = UTM.point(zoneNumber, hemisphere, + easting, northing + precision) + var southeast = UTM.point(zoneNumber, hemisphere, + easting + precision, northing) + + // For points outside the tile grid longitude bounds, + // get a bound just outside the bounds + if precision > 1 { + if southwest.longitude < minLon { + southwest = westBoundsPoint(easting, + northing, southwest, southeast) + } else if southeast.longitude > maxLon { + southeast = eastBoundsPoint(easting, + northing, southwest, southeast) + } + } + + // Vertical line + lines?.append(MGRSLine(southwest, northwest, eastingPrecision)) + + // Horizontal line + lines?.append(MGRSLine(southwest, southeast, northingPrecision)) + + northing += precision + } + + easting += precision + } + + } + + } + + return lines + } + + /** + * Get a point west of the horizontal bounds at one meter precision + * + * @param easting + * easting value + * @param northing + * northing value + * @param west + * west point + * @param east + * east point + * @return higher precision point + */ + private func westBoundsPoint(_ easting: Double, _ northing: Double, + _ west: GridPoint, _ east: GridPoint) -> GridPoint { + return boundsPoint(easting, northing, west, east, false) + } + + /** + * Get a point east of the horizontal bounds at one meter precision + * + * @param easting + * easting value + * @param northing + * northing value + * @param west + * west point + * @param east + * east point + * @return higher precision point + */ + private func eastBoundsPoint(_ easting: Double, _ northing: Double, + _ west: GridPoint, _ east: GridPoint) -> GridPoint { + return boundsPoint(easting, northing, west, east, true) + } + + /** + * Get a point outside of the horizontal bounds at one meter precision + * + * @param easting + * easting value + * @param northing + * northing value + * @param west + * west point + * @param east + * east point + * @param eastern + * true if east of the eastern bounds, false if west of the + * western bounds + * @return higher precision point + */ + private func boundsPoint(_ easting: Double, _ northing: Double, _ west: GridPoint, + _ east: GridPoint, _ eastern: Bool) -> GridPoint { + + let line = Line(west, east) + + let boundsLine = eastern ? bounds.eastLine() : bounds.westLine() + + let zoneNumber = number() + let hemisphere = hemisphere() + + // Intersection between the horizontal line and vertical bounds line + let intersection = line.intersection(boundsLine) + + // Intersection easting + let intersectionUTM = UTM.from(intersection!, zoneNumber, hemisphere) + let intersectionEasting = intersectionUTM.easting + + // One meter precision just outside the bounds + var boundsEasting = intersectionEasting - easting + if eastern { + boundsEasting = ceil(boundsEasting) + } else { + boundsEasting = floor(boundsEasting) + } + + // Higher precision point just outside of the bounds + let boundsPoint = UTM.point(zoneNumber, hemisphere, + easting + boundsEasting, northing) + + return boundsPoint + } + + /** + * Get the draw bounds of easting and northing in meters + * + * @param tileBounds + * tile bounds + * @param gridType + * grid type + * @return draw bounds or null + */ + public func drawBounds(_ tileBounds: Bounds, _ gridType: GridType) -> Bounds? { + + var drawBounds: Bounds? = nil + + let tileBoundsOverlap = tileBounds.toDegrees().overlap(bounds) + + if tileBoundsOverlap != nil && !tileBoundsOverlap!.isEmpty() { + + let zoneNumber = number() + let hemisphere = hemisphere() + + let upperLeftUTM = UTM.from(tileBoundsOverlap!.northwest, zoneNumber, + hemisphere) + let lowerLeftUTM = UTM.from(tileBoundsOverlap!.southwest, zoneNumber, + hemisphere) + let lowerRightUTM = UTM.from(tileBoundsOverlap!.southeast, zoneNumber, + hemisphere) + let upperRightUTM = UTM.from(tileBoundsOverlap!.northeast, zoneNumber, + hemisphere) + + let precision = Double(gridType.precision()) + let leftEasting = floor(min(upperLeftUTM.easting, lowerLeftUTM.easting) + / precision) * precision + let lowerNorthing = floor(min(lowerLeftUTM.northing, lowerRightUTM.northing) + / precision) * precision + let rightEasting = ceil(max(lowerRightUTM.easting, upperRightUTM.easting) + / precision) * precision + let upperNorthing = ceil(max(upperRightUTM.northing, upperLeftUTM.northing) + / precision) * precision + + drawBounds = Bounds.meters(leftEasting, lowerNorthing, rightEasting, + upperNorthing) + + } + + return drawBounds + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/gzd/GridZones.swift b/Pods/mgrs-ios/mgrs-ios/gzd/GridZones.swift new file mode 100644 index 0000000..449cac0 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/gzd/GridZones.swift @@ -0,0 +1,592 @@ +// +// GridZones.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/24/22. +// + +import Foundation +import grid_ios + +/** + * Grid Zones, Longitudinal Strips, and Latitude Bands + */ +public class GridZones { + + /** + * Longitudinal Strips + */ + public static var strips: [Int: LongitudinalStrip] = [:] + + /** + * Latitude Bands + */ + public static var bands: [Character: LatitudeBand] = [:] + + /** + * Grid Zones + */ + public static var gridZones: [Int: [Character: GridZone]] = [:] + + private static var initialized = false + + private static let lock = NSLock() + + private static func initGridZones() { + lock.lock() + if !initialized { + initialize() + initialized = true + } + lock.unlock() + } + + private static func initialize() { + + // Create longitudinal strips + let numberRange = ZoneNumberRange() + for zoneNumber in numberRange { + let longitude = MGRSConstants.MIN_LON + + (Double(zoneNumber - 1) * MGRSConstants.ZONE_WIDTH) + let strip = LongitudinalStrip(zoneNumber, + longitude, longitude + MGRSConstants.ZONE_WIDTH) + strips[strip.number] = strip + } + + // Create latitude bands + var latitude = MGRSConstants.MIN_LAT + let letterRange = BandLetterRange() + for bandLetter in letterRange { + let min = latitude + if bandLetter == MGRSConstants.MAX_BAND_LETTER { + latitude += MGRSConstants.MAX_BAND_HEIGHT + } else { + latitude += MGRSConstants.BAND_HEIGHT + } + bands[bandLetter] = LatitudeBand(bandLetter, min, latitude) + } + + // Create grid zones + for strip in strips.values { + + let zoneNumber = strip.number + + var stripGridZones: [Character: GridZone] = [:] + for band in bands.values { + + let bandLetter = band.letter + + var gridZoneStrip: LongitudinalStrip? = strip + + if isSvalbard(zoneNumber, bandLetter) { + gridZoneStrip = svalbardStrip(strip) + } else if isNorway(zoneNumber, bandLetter) { + gridZoneStrip = norwayStrip(strip) + } + + if gridZoneStrip != nil { + stripGridZones[bandLetter] = GridZone(gridZoneStrip!, band) + } + + } + gridZones[zoneNumber] = stripGridZones + } + + } + + /** + * Get the longitudinal strip by zone number + * + * @param zoneNumber + * zone number + * @return longitudinal strip + */ + public static func longitudinalStrip(_ zoneNumber: Int) -> LongitudinalStrip { + MGRSUtils.validateZoneNumber(zoneNumber) + if !initialized { + initGridZones() + } + return strips[zoneNumber]! + } + + /** + * Get the west longitude in degrees of the zone number + * + * @param zoneNumber + * zone number + * @return longitude in degrees + */ + public static func westLongitude(_ zoneNumber: Int) -> Double { + return longitudinalStrip(zoneNumber).west + } + + /** + * Get the east longitude in degrees of the zone number + * + * @param zoneNumber + * zone number + * @return longitude in degrees + */ + public static func eastLongitude(_ zoneNumber: Int) -> Double { + return longitudinalStrip(zoneNumber).east + } + + /** + * Get the latitude band by band letter + * + * @param bandLetter + * band letter + * @return latitude band + */ + public static func latitudeBand(_ bandLetter: Character) -> LatitudeBand { + MGRSUtils.validateBandLetter(bandLetter) + if !initialized { + initGridZones() + } + return bands[bandLetter]! + } + + /** + * Get the south latitude in degrees of the band letter + * + * @param bandLetter + * band letter + * @return latitude in degrees + */ + public static func southLatitude(_ bandLetter: Character) -> Double { + return latitudeBand(bandLetter).south + } + + /** + * Get the north latitude in degrees of the band letter + * + * @param bandLetter + * band letter + * @return latitude in degrees + */ + public static func northLatitude(_ bandLetter: Character) -> Double { + return latitudeBand(bandLetter).north + } + + /** + * Get the zones within the bounds + * + * @param bounds + * bounds + * @return grid zones + */ + public static func zones(_ bounds: Bounds) -> [GridZone] { + + var zones: [GridZone] = [] + + let range = gridRange(bounds) + for zone in range { + zones.append(zone) + } + + return zones + } + + /** + * Get the grid zone by zone number and band letter + * + * @param zoneNumber + * zone number + * @param bandLetter + * band letter + * @return grid zone + */ + public static func gridZone(_ zoneNumber: Int, _ bandLetter: Character) -> GridZone? { + MGRSUtils.validateZoneNumber(zoneNumber) + MGRSUtils.validateBandLetter(bandLetter) + if !initialized { + initGridZones() + } + return gridZones[zoneNumber]![bandLetter] + } + + /** + * Get the grid zone by MGRS + * + * @param mgrs + * mgrs coordinate + * @return grid zone + */ + public static func gridZone(_ mgrs: MGRS) -> GridZone? { + return gridZone(mgrs.zone, mgrs.band) + } + + /** + * Get a grid range from the bounds + * + * @param bounds + * bounds + * @return grid range + */ + public static func gridRange(_ bounds: Bounds) -> GridRange { + let boundsDegrees = bounds.toDegrees() + let zoneRange = zoneNumberRange(boundsDegrees) + let bandRange = bandLetterRange(boundsDegrees) + return GridRange(zoneRange, bandRange) + } + + /** + * Get a zone number range between the western and eastern bounds + * + * @param bounds + * bounds + * @return zone number range + */ + public static func zoneNumberRange(_ bounds: Bounds) -> ZoneNumberRange { + let boundsDegrees = bounds.toDegrees() + return zoneNumberRange(boundsDegrees.west, boundsDegrees.east) + } + + /** + * Get a zone number range between the western and eastern longitudes + * + * @param west + * western longitude in degrees + * @param east + * eastern longitude in degrees + * @return zone number range + */ + public static func zoneNumberRange(_ west: Double, _ east: Double) -> ZoneNumberRange { + let westZone = zoneNumber(west, false) + let eastZone = zoneNumber(east, true) + return ZoneNumberRange(westZone, eastZone) + } + + /** + * Get the zone number of the point + * + * @param point + * point + * @return zone number + */ + public static func zoneNumber(_ point: GridPoint) -> Int { + let pointDegrees = point.toDegrees() + return zoneNumber(pointDegrees.longitude, pointDegrees.latitude) + } + + /** + * Get the zone number of the longitude and latitude + * + * @param longitude + * longitude + * @param latitude + * latitude + * @return zone number + */ + public static func zoneNumber(_ longitude: Double, _ latitude: Double) -> Int { + var zoneNum = zoneNumber(longitude) + let svalbardZone = isSvalbardZone(zoneNum) + let norwayZone = isNorwayZone(zoneNum) + if svalbardZone || norwayZone { + let bandLetter = bandLetter(latitude) + if svalbardZone && isSvalbardLetter(bandLetter) { + zoneNum = self.svalbardZone(longitude) + } else if norwayZone && isNorwayLetter(bandLetter) { + zoneNum = self.norwayZone(longitude) + } + } + return zoneNum + } + + /** + * Get the zone number of the longitude (degrees between + * MGRSConstants.MIN_LON and MGRSConstants.MAX_LON). Eastern + * zone number on borders. + * + * @param longitude + * longitude in degrees + * @return zone number + */ + public static func zoneNumber(_ longitude: Double) -> Int { + return zoneNumber(longitude, true) + } + + /** + * Get the zone number of the longitude (degrees between + * MGRSConstants.MIN_LON and MGRSConstants.MAX_LON) + * + * @param longitude + * longitude in degrees + * @param eastern + * true for eastern number on edges, false for western + * @return zone number + */ + public static func zoneNumber(_ longitude: Double, _ eastern: Bool) -> Int { + + var longitudeValue = longitude + + // Normalize the longitude if needed + if longitudeValue < MGRSConstants.MIN_LON + || longitudeValue > MGRSConstants.MAX_LON { + longitudeValue = (longitudeValue - MGRSConstants.MIN_LON) + .truncatingRemainder(dividingBy: 2 * MGRSConstants.MAX_LON) + + MGRSConstants.MIN_LON + } + + // Determine the zone + let zoneValue = (longitudeValue - MGRSConstants.MIN_LON) + / MGRSConstants.ZONE_WIDTH + var zoneNumber = 1 + Int(zoneValue) + + // Handle western edge cases and 180.0 + if !eastern { + if zoneNumber > 1 && zoneValue.truncatingRemainder(dividingBy: 1.0) == 0.0 { + zoneNumber -= 1 + } + } else if zoneNumber > MGRSConstants.MAX_ZONE_NUMBER { + zoneNumber -= 1 + } + + return zoneNumber + } + + /** + * Get a band letter range between the southern and northern bounds + * + * @param bounds + * bounds + * @return band letter range + */ + public static func bandLetterRange(_ bounds: Bounds) -> BandLetterRange { + let boundsDegrees = bounds.toDegrees() + return bandLetterRange(boundsDegrees.south, boundsDegrees.north) + } + + /** + * Get a band letter range between the southern and northern latitudes in + * degrees + * + * @param south + * southern latitude in degrees + * @param north + * northern latitude in degrees + * @return band letter range + */ + public static func bandLetterRange(_ south: Double, _ north: Double) -> BandLetterRange { + let southLetter = bandLetter(south, false) + let northLetter = bandLetter(north, true) + return BandLetterRange(southLetter, northLetter) + } + + /** + * Get the band letter of the latitude (degrees between + * MGRSConstants.MIN_LAT and MGRSConstants.MAX_LAT). + * Northern band letter on borders. + * + * @param latitude + * latitude in degrees + * @return band letter + */ + public static func bandLetter(_ latitude: Double) -> Character { + return bandLetter(latitude, true) + } + + /** + * Get the band letter of the latitude (degrees between + * MGRSConstants.MIN_LAT and MGRSConstants.MAX_LAT) + * + * @param latitude + * latitude in degrees + * @param northern + * true for northern band on edges, false for southern + * @return band letter + */ + public static func bandLetter(_ latitude: Double, _ northern: Bool) -> Character { + + var latitudeValue = latitude + + // Bound the latitude if needed + if latitudeValue < MGRSConstants.MIN_LAT { + latitudeValue = MGRSConstants.MIN_LAT + } else if latitudeValue > MGRSConstants.MAX_LAT { + latitudeValue = MGRSConstants.MAX_LAT + } + + let bandValue = (latitudeValue - MGRSConstants.MIN_LAT) + / MGRSConstants.BAND_HEIGHT + var bands = Int(bandValue) + + // Handle 80.0 to 84.0 and southern edge cases + if bands >= MGRSConstants.NUM_BANDS { + bands -= 1 + } else if !northern && bands > 0 && bandValue.truncatingRemainder(dividingBy: 1.0) == 0.0 { + bands -= 1 + } + + // Handle skipped 'I' and 'O' letters + if bands > 10 { + bands += 2 + } else if bands > 5 { + bands += 1 + } + + return GridUtils.incrementCharacter(MGRSConstants.MIN_BAND_LETTER, bands) + } + + /** + * Is the zone number and band letter a Svalbard GZD (31X - 37X) + * + * @param zoneNumber + * zone number + * @param bandLetter + * band letter + * @return true if a Svalbard GZD + */ + public static func isSvalbard(_ zoneNumber: Int, _ bandLetter: Character) -> Bool { + return isSvalbardLetter(bandLetter) && isSvalbardZone(zoneNumber) + } + + /** + * Is the band letter a Svalbard GZD (X) + * + * @param bandLetter + * band letter + * @return true if a Svalbard GZD + */ + public static func isSvalbardLetter(_ bandLetter: Character) -> Bool { + return bandLetter == MGRSConstants.SVALBARD_BAND_LETTER + } + + /** + * Is the zone number a Svalbard GZD (31 - 37) + * + * @param zoneNumber + * zone number + * @return true if a Svalbard GZD + */ + public static func isSvalbardZone(_ zoneNumber: Int) -> Bool { + return zoneNumber >= MGRSConstants.MIN_SVALBARD_ZONE_NUMBER + && zoneNumber <= MGRSConstants.MAX_SVALBARD_ZONE_NUMBER + } + + /** + * Get the Svalbard longitudinal strip from the strip + * + * @param strip + * longitudinal strip + * @return Svalbard strip or null for empty strips + */ + private static func svalbardStrip(_ strip: LongitudinalStrip) -> LongitudinalStrip? { + + var svalbardStrip: LongitudinalStrip? = nil + + let number = strip.number + if number % 2 == 1 { + var west = strip.west + var east = strip.east + let halfWidth = (east - west) / 2.0 + if number > 31 { + west -= halfWidth + } + if number < 37 { + east += halfWidth + } + svalbardStrip = LongitudinalStrip(number, west, east) + } + + return svalbardStrip + } + + /** + * Get the Svalbard zone number from the longitude + * + * @param longitude + * longitude + * @return zone number + */ + private static func svalbardZone(_ longitude: Double) -> Int { + let minimumLongitude = westLongitude( + MGRSConstants.MIN_SVALBARD_ZONE_NUMBER) + let zoneValue = Double(MGRSConstants.MIN_SVALBARD_ZONE_NUMBER) + + ((longitude - minimumLongitude) / MGRSConstants.ZONE_WIDTH) + var zone = Int(round(zoneValue)) + if zone % 2 == 0 { + zone -= 1 + } + return zone + } + + /** + * Is the zone number and band letter a Norway GZD (31V or 32V) + * + * @param zoneNumber + * zone number + * @param bandLetter + * band letter + * @return true if a Norway GZD + */ + private static func isNorway(_ zoneNumber: Int, _ bandLetter: Character) -> Bool { + return isNorwayLetter(bandLetter) && isNorwayZone(zoneNumber) + } + + /** + * Is the band letter a Norway GZD (V) + * + * @param bandLetter + * band letter + * @return true if a Norway GZD band letter + */ + private static func isNorwayLetter(_ bandLetter: Character) -> Bool { + return bandLetter == MGRSConstants.NORWAY_BAND_LETTER + } + + /** + * Is the zone number a Norway GZD (31 or 32) + * + * @param zoneNumber + * zone number + * @return true if a Norway GZD zone number + */ + private static func isNorwayZone(_ zoneNumber: Int) -> Bool { + return zoneNumber >= MGRSConstants.MIN_NORWAY_ZONE_NUMBER + && zoneNumber <= MGRSConstants.MAX_NORWAY_ZONE_NUMBER + } + + /** + * Get the Norway longitudinal strip from the strip + * + * @param strip + * longitudinal strip + * @return Norway strip + */ + private static func norwayStrip(_ strip: LongitudinalStrip) -> LongitudinalStrip { + + let number = strip.number + var west = strip.west + var east = strip.east + let halfWidth = (east - west) / 2.0 + + var expand = 0 + if number == MGRSConstants.MIN_NORWAY_ZONE_NUMBER { + east -= halfWidth + expand += 1 + } else if number == MGRSConstants.MAX_NORWAY_ZONE_NUMBER { + west -= halfWidth + } + + return LongitudinalStrip(number, west, east, expand) + } + + /** + * Get the Norway zone number from the longitude + * + * @param longitude + * longitude + * @return zone number + */ + private static func norwayZone(_ longitude: Double) -> Int { + let minimumLongitude = westLongitude( + MGRSConstants.MIN_NORWAY_ZONE_NUMBER) + var zone = MGRSConstants.MIN_NORWAY_ZONE_NUMBER + if longitude >= minimumLongitude + (MGRSConstants.ZONE_WIDTH / 2.0) { + zone += 1 + } + return zone + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/gzd/LatitudeBand.swift b/Pods/mgrs-ios/mgrs-ios/gzd/LatitudeBand.swift new file mode 100644 index 0000000..c7f5f48 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/gzd/LatitudeBand.swift @@ -0,0 +1,63 @@ +// +// LatitudeBand.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation +import grid_ios + +/** + * Latitude (horizontal) band + */ +public class LatitudeBand { + + private var _letter: Character + + /** + * Band letter + */ + public var letter: Character { + get { + return _letter + } + set { + _letter = newValue + hemisphere = MGRSUtils.hemisphere(letter) + } + } + + /** + * Southern latitude + */ + public var south: Double + + /** + * Northern latitude + */ + public var north: Double + + /** + * Hemisphere + */ + public var hemisphere: Hemisphere + + /** + * Initialize + * + * @param letter + * band letter + * @param south + * southern latitude + * @param north + * northern latitude + */ + public init(_ letter: Character, _ south: Double, _ north: Double) { + _letter = letter + self.south = south + self.north = north + hemisphere = MGRSUtils.hemisphere(letter) + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/gzd/LongitudinalStrip.swift b/Pods/mgrs-ios/mgrs-ios/gzd/LongitudinalStrip.swift new file mode 100644 index 0000000..44c254f --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/gzd/LongitudinalStrip.swift @@ -0,0 +1,68 @@ +// +// LongitudinalStrip.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation + +/** + * Longitudinal (vertical) strip + */ +public class LongitudinalStrip { + + /** + * Zone number + */ + public var number: Int + + /** + * Western longitude + */ + public var west: Double + + /** + * Eastern longitude + */ + public var east: Double + + /** + * Expansion for range iterations over neighboring strips + */ + public var expand: Int + + /** + * Initialize + * + * @param number + * zone number + * @param west + * western longitude + * @param east + * eastern longitude + */ + public convenience init(_ number: Int, _ west: Double, _ east: Double) { + self.init(number, west, east, 0) + } + + /** + * Initialize + * + * @param number + * zone number + * @param west + * western longitude + * @param east + * eastern longitude + * @param expand + * expansion for range iterations over neighboring strips + */ + public init(_ number: Int, _ west: Double, _ east: Double, _ expand: Int) { + self.number = number + self.west = west + self.east = east + self.expand = expand + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/gzd/ZoneNumberRange.swift b/Pods/mgrs-ios/mgrs-ios/gzd/ZoneNumberRange.swift new file mode 100644 index 0000000..8779897 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/gzd/ZoneNumberRange.swift @@ -0,0 +1,88 @@ +// +// ZoneNumberRange.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation + +/** + * Zone Number Range + */ +public class ZoneNumberRange: Sequence { + + /** + * Western zone number + */ + public var west: Int + + /** + * Eastern zone number + */ + public var east: Int + + /** + * Initialize, full range + */ + public convenience init() { + self.init(MGRSConstants.MIN_ZONE_NUMBER, MGRSConstants.MAX_ZONE_NUMBER) + } + + /** + * Initialize + * + * @param west + * western zone number + * @param east + * eastern zone number + */ + public init(_ west: Int, _ east: Int) { + self.west = west + self.east = east + } + + /** + * Get the western longitude + * + * @return longitude + */ + public func westLongitude() -> Double { + return GridZones.longitudinalStrip(west).west + } + + /** + * Get the eastern longitude + * + * @return longitude + */ + public func eastLongitude() -> Double { + return GridZones.longitudinalStrip(east).east + } + + public func makeIterator() -> ZoneNumberRangeIterator { + return ZoneNumberRangeIterator(self) + } + +} + +public struct ZoneNumberRangeIterator: IteratorProtocol { + + var number: Int + var east: Int + + init(_ range: ZoneNumberRange) { + self.number = range.west + self.east = range.east + } + + public mutating func next() -> Int? { + var value: Int? = nil + if number <= east { + value = number + number += 1 + } + return value + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/mgrs.plist b/Pods/mgrs-ios/mgrs-ios/mgrs.plist new file mode 100644 index 0000000..79eca2e --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/mgrs.plist @@ -0,0 +1,160 @@ + + + + + grid.width + 2.0 + labeler.text_size + 35.0 + labeler.buffer + 0.05 + grids.gzd.enabled + true + grids.gzd.min_zoom + 0 + grids.gzd.max_zoom + + grids.gzd.color + EF5350 + grids.gzd.width + 2.0 + grids.gzd.labeler.enabled + true + grids.gzd.labeler.min_zoom + 4 + grids.gzd.labeler.max_zoom + + grids.gzd.labeler.color + EF5350 + grids.gzd.labeler.text_size + 24.0 + grids.gzd.labeler.buffer + 0.05 + grids.propagate + true + grids.hundred_kilometer.enabled + true + grids.hundred_kilometer.min_zoom + 5 + grids.hundred_kilometer.max_zoom + + grids.hundred_kilometer.lines.min_zoom + + grids.hundred_kilometer.lines.max_zoom + 8 + grids.hundred_kilometer.color + 3D8C40 + grids.hundred_kilometer.width + 2.0 + grids.hundred_kilometer.labeler.enabled + true + grids.hundred_kilometer.labeler.min_zoom + 6 + grids.hundred_kilometer.labeler.max_zoom + + grids.hundred_kilometer.labeler.color + 3D8C40 + grids.hundred_kilometer.labeler.text_size + 24.0 + grids.hundred_kilometer.labeler.buffer + 0.05 + grids.ten_kilometer.enabled + true + grids.ten_kilometer.min_zoom + 9 + grids.ten_kilometer.max_zoom + 11 + grids.ten_kilometer.color + 888888 + grids.ten_kilometer.width + 2.0 + grids.ten_kilometer.labeler.enabled + false + grids.ten_kilometer.labeler.min_zoom + 10 + grids.ten_kilometer.labeler.max_zoom + 11 + grids.ten_kilometer.labeler.color + 888888 + grids.ten_kilometer.labeler.text_size + 24.0 + grids.ten_kilometer.labeler.buffer + 0.05 + grids.kilometer.enabled + true + grids.kilometer.min_zoom + 12 + grids.kilometer.max_zoom + 14 + grids.kilometer.color + 888888 + grids.kilometer.width + 2.0 + grids.kilometer.labeler.enabled + false + grids.kilometer.labeler.min_zoom + 13 + grids.kilometer.labeler.max_zoom + 14 + grids.kilometer.labeler.color + 888888 + grids.kilometer.labeler.text_size + 24.0 + grids.kilometer.labeler.buffer + 0.05 + grids.hundred_meter.enabled + true + grids.hundred_meter.min_zoom + 15 + grids.hundred_meter.max_zoom + 17 + grids.hundred_meter.color + 888888 + grids.hundred_meter.width + 2.0 + grids.hundred_meter.labeler.enabled + false + grids.hundred_meter.labeler.min_zoom + 16 + grids.hundred_meter.labeler.max_zoom + 17 + grids.hundred_meter.labeler.color + 888888 + grids.hundred_meter.labeler.text_size + 24.0 + grids.hundred_meter.labeler.buffer + 0.05 + grids.ten_meter.enabled + true + grids.ten_meter.min_zoom + 18 + grids.ten_meter.max_zoom + 20 + grids.ten_meter.color + 888888 + grids.ten_meter.width + 2.0 + grids.ten_meter.labeler.enabled + false + grids.ten_meter.labeler.min_zoom + 19 + grids.ten_meter.labeler.max_zoom + 20 + grids.ten_meter.labeler.color + 888888 + grids.ten_meter.labeler.text_size + 24.0 + grids.ten_meter.labeler.buffer + 0.05 + grids.meter.enabled + true + grids.meter.min_zoom + 21 + grids.meter.max_zoom + + grids.meter.color + 888888 + grids.meter.width + 2.0 + + diff --git a/Pods/mgrs-ios/mgrs-ios/property/MGRSProperties.swift b/Pods/mgrs-ios/mgrs-ios/property/MGRSProperties.swift new file mode 100644 index 0000000..055da15 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/property/MGRSProperties.swift @@ -0,0 +1,37 @@ +// +// MGRSProperties.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation +import grid_ios + +/** + * MGRS property loader + */ +public class MGRSProperties: GridProperties { + + /** + * Bundle Name + */ + public static let BUNDLE_NAME = "mgrs-ios.bundle" + + /** + * Properties Name + */ + public static let PROPERTIES_NAME = "mgrs" + + /** + * Singleton instance + */ + private static let _instance = MGRSProperties(MGRSProperties.self, BUNDLE_NAME, PROPERTIES_NAME) + + public static var instance: MGRSProperties { + get { + return _instance + } + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/tile/MGRSTileOverlay.swift b/Pods/mgrs-ios/mgrs-ios/tile/MGRSTileOverlay.swift new file mode 100644 index 0000000..e32fbb7 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/tile/MGRSTileOverlay.swift @@ -0,0 +1,354 @@ +// +// MGRSTileOverlay.swift +// mgrs-ios +// +// Created by Brian Osborn on 9/2/22. +// + +import MapKit +import grid_ios + +/** + * MGRS Tile Overlay + */ +public class MGRSTileOverlay: MKTileOverlay { + + /** + * Tile width + */ + public var tileWidth: Int + + /** + * Tile height + */ + public var tileHeight: Int + + /** + * Grids + */ + public var grids: Grids + + /** + * Create a tile provider with Grid Zone Designator grids + * + * @return tile provider + */ + public static func createGZD() -> MGRSTileOverlay { + return createGZD(TileUtils.tileLength()) + } + + /** + * Create a tile provider with Grid Zone Designator grids + * + * @param tileLength tile length + * @return tile provider + */ + public static func createGZD(_ tileLength: Int) -> MGRSTileOverlay { + return createGZD(tileLength, tileLength) + } + + /** + * Create a tile provider with Grid Zone Designator grids + * + * @param tileWidth tile width + * @param tileHeight tile height + * @return tile provider + */ + public static func createGZD(_ tileWidth: Int, _ tileHeight: Int) -> MGRSTileOverlay { + return MGRSTileOverlay(tileWidth, tileHeight, Grids.createGZD()) + } + + /** + * Initialize + * + * @param context app context + */ + public init() { + let tileLength = TileUtils.tileLength() + self.tileWidth = tileLength + self.tileHeight = tileLength + self.grids = Grids() + super.init(urlTemplate: nil) + } + + /** + * Initialize + * + * @param types grids types to enable + */ + public init(_ types: [GridType]) { + let tileLength = TileUtils.tileLength() + self.tileWidth = tileLength + self.tileHeight = tileLength + self.grids = Grids(types) + super.init(urlTemplate: nil) + } + + /** + * Initialize + * + * @param grids grids + */ + public init(_ grids: Grids) { + let tileLength = TileUtils.tileLength() + self.tileWidth = tileLength + self.tileHeight = tileLength + self.grids = grids + super.init(urlTemplate: nil) + } + + /** + * Initialize + * + * @param tileLength tile width and height + */ + public init(_ tileLength: Int) { + self.tileWidth = tileLength + self.tileHeight = tileLength + self.grids = Grids() + super.init(urlTemplate: nil) + } + + /** + * Initialize + * + * @param tileLength tile width and height + * @param types grids types to enable + */ + public init(_ tileLength: Int, _ types: [GridType]) { + self.tileWidth = tileLength + self.tileHeight = tileLength + self.grids = Grids(types) + super.init(urlTemplate: nil) + } + + /** + * Initialize + * + * @param tileLength tile width and height + * @param grids grids + */ + public init(_ tileLength: Int, _ grids: Grids) { + self.tileWidth = tileLength + self.tileHeight = tileLength + self.grids = grids + super.init(urlTemplate: nil) + } + + /** + * Initialize + * + * @param tileWidth tile width + * @param tileHeight tile height + */ + public init(_ tileWidth: Int, _ tileHeight: Int) { + self.tileWidth = tileWidth + self.tileHeight = tileHeight + self.grids = Grids() + super.init(urlTemplate: nil) + } + + /** + * Initialize + * + * @param tileWidth tile width + * @param tileHeight tile height + * @param types grids types to enable + */ + public init(_ tileWidth: Int, _ tileHeight: Int, _ types: [GridType]) { + self.tileWidth = tileWidth + self.tileHeight = tileHeight + self.grids = Grids(types) + super.init(urlTemplate: nil) + } + + /** + * Initialize + * + * @param tileWidth tile width + * @param tileHeight tile height + * @param grids grids + */ + public init(_ tileWidth: Int, _ tileHeight: Int, _ grids: Grids) { + self.tileWidth = tileWidth + self.tileHeight = tileHeight + self.grids = grids + super.init(urlTemplate: nil) + } + + public override func url(forTilePath path: MKTileOverlayPath) -> URL { + return URL(fileURLWithPath: "") + } + + public override func loadTile(at path: MKTileOverlayPath, result: @escaping (Data?, Error?) -> Void) { + + DispatchQueue.global(qos: .userInitiated).async { [self] in + + var tileData: Data? = tile(path.x, path.y, path.z) + + if tileData == nil { + tileData = Data() + } + result(tileData, nil) + + } + + } + + /** + * Get the grid + * + * @param type grid type + * @return grid + */ + public func grid(_ type: GridType) -> Grid { + return grids.grid(type) + } + + /** + * Get the Global Area Reference System coordinate for the location coordinate in five + * minute precision + * + * @param coordinate location + * @return MGRS coordinate + */ + public func coordinate(_ coordinate: CLLocationCoordinate2D) -> String { + return mgrs(coordinate).coordinate() + } + + /** + * Get the Global Area Reference System coordinate for the MapKit map point in five + * minute precision + * + * @param point MapKit map point + * @return MGRS coordinate + */ + public func coordinate(_ point: MKMapPoint) -> String { + return coordinate(TileUtils.toCoordinate(point)) + } + + /** + * Get the Global Area Reference System coordinate for the location coordinate in the + * zoom level precision + * + * @param coordinate location + * @param zoom zoom level precision + * @return MGRS coordinate + */ + public func coordinate(_ coordinate: CLLocationCoordinate2D, _ zoom: Int) -> String { + return self.coordinate(coordinate, precision(zoom)) + } + + /** + * Get the Global Area Reference System coordinate for the MapKit map point in the + * zoom level precision + * + * @param point MapKit map point + * @param zoom zoom level precision + * @return MGRS coordinate + */ + public func coordinate(_ point: MKMapPoint, _ zoom: Int) -> String { + return coordinate(TileUtils.toCoordinate(point), zoom) + } + + /** + * Get the Global Area Reference System coordinate for the location coordinate in the + * grid type precision + * + * @param coordinate location + * @param type grid type precision + * @return MGRS coordinate + */ + public func coordinate(_ coordinate: CLLocationCoordinate2D, _ type: GridType?) -> String { + return mgrs(coordinate).coordinate(type) + } + + /** + * Get the Global Area Reference System coordinate for the MapKit map point in the + * grid type precision + * + * @param point MapKit map point + * @param type grid type precision + * @return MGRS coordinate + */ + public func coordinate(_ point: MKMapPoint, _ type: GridType?) -> String { + return coordinate(TileUtils.toCoordinate(point), type) + } + + /** + * Get the Global Area Reference System for the location coordinate + * + * @param coordinate location + * @return MGRS + */ + public func mgrs(_ coordinate: CLLocationCoordinate2D) -> MGRS { + return MGRS.from(coordinate) + } + + /** + * Get the Global Area Reference System for the MapKit map point + * + * @param point MapKit map point + * @return MGRS + */ + public func mgrs(_ point: MKMapPoint) -> MGRS { + return mgrs(TileUtils.toCoordinate(point)) + } + + /** + * Parse a MGRS string + * + * @param mgrs + * MGRS string + * @return MGRS + */ + public static func parse(_ mgrs: String) -> MGRS { + return MGRS.parse(mgrs) + } + + /** + * Parse a MGRS string into a location coordinate + * + * @param mgrs + * MGRS string + * @return coordinate + */ + public static func parseToCoordinate(_ mgrs: String) -> CLLocationCoordinate2D { + return MGRS.parseToCoordinate(mgrs) + } + + /** + * Get the grid precision for the zoom level + * + * @param zoom zoom level + * @return grid type precision + */ + public func precision(_ zoom: Int) -> GridType? { + return grids.precision(zoom) + } + + /** + * Get the tile + * + * @param x x coordinate + * @param y y coordinate + * @param zoom zoom level + * @return image + */ + public func tile(_ x: Int, _ y: Int, _ zoom: Int) -> Data? { + return TileUtils.toData(drawTile(x, y, zoom)) + } + + /** + * Draw the tile + * + * @param x x coordinate + * @param y y coordinate + * @param zoom zoom level + * @return image + */ + public func drawTile(_ x: Int, _ y: Int, _ zoom: Int) -> UIImage? { + return grids.drawTile(tileWidth, tileHeight, x, y, zoom) + } + +} diff --git a/Pods/mgrs-ios/mgrs-ios/utm/UTM.swift b/Pods/mgrs-ios/mgrs-ios/utm/UTM.swift new file mode 100644 index 0000000..dafa5a1 --- /dev/null +++ b/Pods/mgrs-ios/mgrs-ios/utm/UTM.swift @@ -0,0 +1,509 @@ +// +// UTM.swift +// mgrs-ios +// +// Created by Brian Osborn on 8/23/22. +// + +import Foundation +import grid_ios +import MapKit + +/** + * Universal Transverse Mercator Projection + */ +public class UTM { + + /** + * Zone number + */ + public let zone: Int + + /** + * Hemisphere + */ + public let hemisphere: Hemisphere + + /** + * Easting + */ + public let easting: Double + + /** + * Northing + */ + public let northing: Double + + /** + * UTM string pattern + */ + private static let utmPattern = "^(\\d{1,2})\\s*([N|S])\\s*(\\d+\\.?\\d*)\\s*(\\d+\\.?\\d*)$" + + /** + * UTM regular expression + */ + private static let utmExpression = try! NSRegularExpression(pattern: utmPattern, options: .caseInsensitive) + + /** + * Create a point from the UTM attributes + * + * @param zone + * zone number + * @param hemisphere + * hemisphere + * @param easting + * easting + * @param northing + * northing + * @return point + */ + public static func point(_ zone: Int, _ hemisphere: Hemisphere, _ easting: Double, _ northing: Double) -> GridPoint { + return UTM(zone, hemisphere, easting, northing).toPoint() + } + + /** + * Initialize + * + * @param zone + * zone number + * @param hemisphere + * hemisphere + * @param easting + * easting + * @param northing + * northing + */ + public init(_ zone: Int, _ hemisphere: Hemisphere, _ easting: Double, _ northing: Double) { + self.zone = zone + self.hemisphere = hemisphere + self.easting = easting + self.northing = northing + } + + /** + * Convert to a point + * + * @return point + */ + public func toPoint() -> GridPoint { + + var north = northing + if hemisphere == Hemisphere.SOUTH { + // Remove 10,000,000 meter offset used for southern hemisphere + north -= 10000000.0 + } + + var latitude = (north/6366197.724/0.9996+(1+0.006739496742*pow(cos(north/6366197.724/0.9996),2)-0.006739496742*sin(north/6366197.724/0.9996)*cos(north/6366197.724/0.9996)*(atan(cos(atan(( exp((easting - 500000) / (0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*pow((easting - 500000) / (0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2)))),2)/2*pow(cos(north/6366197.724/0.9996),2)/3))-exp(-(easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2))))*( 1 - 0.006739496742*pow((easting - 500000) / (0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2)))),2)/2*pow(cos(north/6366197.724/0.9996),2)/3)))/2/cos((north-0.9996*6399593.625*(north/6366197.724/0.9996-0.006739496742*3/4*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+pow(0.006739496742*3/4,2)*5/3*(3*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996 )/2)+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2))/4-pow(0.006739496742*3/4,3)*35/27*(5*(3*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2))/4+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2)*pow(cos(north/6366197.724/0.9996),2))/3))/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*pow((easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2)))),2)/2*pow(cos(north/6366197.724/0.9996),2))+north/6366197.724/0.9996)))*tan((north-0.9996*6399593.625*(north/6366197.724/0.9996 - 0.006739496742*3/4*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+pow(0.006739496742*3/4,2)*5/3*(3*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+sin(2*north/6366197.724/0.9996 )*pow(cos(north/6366197.724/0.9996),2))/4-pow(0.006739496742*3/4,3)*35/27*(5*(3*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2))/4+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2)*pow(cos(north/6366197.724/0.9996),2))/3))/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*pow((easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2)))),2)/2*pow(cos(north/6366197.724/0.9996),2))+north/6366197.724/0.9996))-north/6366197.724/0.9996)*3/2)*(atan(cos(atan((exp((easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*pow((easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2)))),2)/2*pow(cos(north/6366197.724/0.9996),2)/3))-exp(-(easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*pow((easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2)))),2)/2*pow(cos(north/6366197.724/0.9996),2)/3)))/2/cos((north-0.9996*6399593.625*(north/6366197.724/0.9996-0.006739496742*3/4*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+pow(0.006739496742*3/4,2)*5/3*(3*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2))/4-pow(0.006739496742*3/4,3)*35/27*(5*(3*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2))/4+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2)*pow(cos(north/6366197.724/0.9996),2))/3))/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*pow((easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2)))),2)/2*pow(cos(north/6366197.724/0.9996),2))+north/6366197.724/0.9996)))*tan((north-0.9996*6399593.625*(north/6366197.724/0.9996-0.006739496742*3/4*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+pow(0.006739496742*3/4,2)*5/3*(3*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2))/4-pow(0.006739496742*3/4,3)*35/27*(5*(3*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2))/4+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2)*pow(cos(north/6366197.724/0.9996),2))/3))/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*pow((easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2)))),2)/2*pow(cos(north/6366197.724/0.9996),2))+north/6366197.724/0.9996))-north/6366197.724/0.9996))*180/Double.pi + latitude = round(latitude * 10000000) + latitude = latitude / 10000000 + + var longitude = atan((exp((easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*pow((easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2)))),2)/2*pow(cos(north/6366197.724/0.9996),2)/3))-exp(-(easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*pow((easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2)))),2)/2*pow(cos(north/6366197.724/0.9996),2)/3)))/2/cos((north-0.9996*6399593.625*( north/6366197.724/0.9996-0.006739496742*3/4*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+pow(0.006739496742*3/4,2)*5/3*(3*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2))/4-pow(0.006739496742*3/4,3)*35/27*(5*(3*(north/6366197.724/0.9996+sin(2*north/6366197.724/0.9996)/2)+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2))/4+sin(2*north/6366197.724/0.9996)*pow(cos(north/6366197.724/0.9996),2)*pow(cos(north/6366197.724/0.9996),2))/3)) / (0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*pow((easting-500000)/(0.9996*6399593.625/sqrt((1+0.006739496742*pow(cos(north/6366197.724/0.9996),2)))),2)/2*pow(cos(north/6366197.724/0.9996),2))+north/6366197.724/0.9996))*180/Double.pi+Double(zone)*6-183 + longitude = round(longitude * 10000000) + longitude = longitude / 10000000 + + return GridPoint.degrees(longitude, latitude) + } + + /** + * Convert to a MGRS coordinate + * + * @return MGRS + */ + public func toMGRS() -> MGRS { + return MGRS.from(toPoint()) + } + + /** + * Convert to a location coordinate + * + * @return coordinate + */ + public func toCoordinate() -> CLLocationCoordinate2D { + return toPoint().toCoordinate() + } + + /** + * Format to a UTM string + * + * @return UTM string + */ + public func format() -> String { + + let formatter = NumberFormatter() + formatter.numberStyle = .decimal + formatter.maximumFractionDigits = 2 + formatter.usesGroupingSeparator = false + + return String(format: "%02d", zone) + + " " + + (hemisphere == Hemisphere.NORTH ? GridConstants.NORTH_CHAR : GridConstants.SOUTH_CHAR) + + " " + + formatter.string(from: easting as NSNumber)! + + " " + + formatter.string(from: northing as NSNumber)! + } + + public var description: String { + return format() + } + + /** + * Return whether the given string is valid UTM string + * + * @param utm + * potential UTM string + * @return true if UTM string is valid, false otherwise + */ + public static func isUTM(_ utm: String) -> Bool { + return utmExpression.matches(in: utm, range: NSMakeRange(0, utm.count)).count > 0 + } + + /** + * Parse a UTM value (Zone N|S Easting Northing) + * + * @param utm + * UTM value + * @return UTM + */ + public static func parse(_ utm: String) -> UTM { + let matches = utmExpression.matches(in: utm, range: NSMakeRange(0, utm.count)) + if matches.count <= 0 { + preconditionFailure("Invalid UTM: \(utm)") + } + + let match = matches[0] + let utmString = utm as NSString + + let zone = Int(utmString.substring(with: match.range(at: 1)))! + let hemisphere = utmString.substring(with: match.range(at: 2)).caseInsensitiveCompare(GridConstants.NORTH_CHAR) == .orderedSame ? Hemisphere.NORTH : Hemisphere.SOUTH + let easting = Double(utmString.substring(with: match.range(at: 3)))! + let northing = Double(utmString.substring(with: match.range(at: 4)))! + + return UTM(zone, hemisphere, easting, northing) + } + + /** + * Parse a UTM value (Zone N|S Easting Northing) into a location coordinate + * + * @param utm + * UTM value + * @return coordinate + */ + public static func parseToCoordinate(_ utm: String) -> CLLocationCoordinate2D { + var coordinate = kCLLocationCoordinate2DInvalid + if isUTM(utm) { + coordinate = parse(utm).toCoordinate() + } + return coordinate + } + + /** + * Create from a point + * + * @param point + * point + * @return UTM + */ + public static func from(_ point: GridPoint) -> UTM { + return from(point, GridZones.zoneNumber(point)) + } + + /** + * Create from a point and zone number + * + * @param point + * point + * @param zone + * zone number + * @return UTM + */ + public static func from(_ point: GridPoint, _ zone: Int) -> UTM { + return from(point, zone, Hemisphere.from(point)) + } + + /** + * Create from a coordinate, zone number, and hemisphere + * + * @param point + * coordinate + * @param zone + * zone number + * @param hemisphere + * hemisphere + * @return UTM + */ + public static func from(_ point: GridPoint, _ zone: Int, _ hemisphere: Hemisphere) -> UTM { + + let pointDegrees = point.toDegrees() + + let latitude = pointDegrees.latitude + let longitude = pointDegrees.longitude + + var easting = 0.5 * log((1+cos(latitude*Double.pi/180)*sin(longitude*Double.pi/180-(6*Double(zone)-183)*Double.pi/180))/(1-cos(latitude*Double.pi/180)*sin(longitude*Double.pi/180-(6*Double(zone)-183)*Double.pi/180)))*0.9996*6399593.62/pow((1+pow(0.0820944379, 2)*pow(cos(latitude*Double.pi/180), 2)), 0.5)*(1+pow(0.0820944379,2)/2*pow((0.5*log((1+cos(latitude*Double.pi/180)*sin(longitude*Double.pi/180-(6*Double(zone)-183)*Double.pi/180))/(1-cos(latitude*Double.pi/180)*sin(longitude*Double.pi/180-(6*Double(zone)-183)*Double.pi/180)))),2)*pow(cos(latitude*Double.pi/180),2)/3)+500000 + easting = round(easting * 100) * 0.01 + + var northing = (atan(tan(latitude*Double.pi/180)/cos((longitude*Double.pi/180-(6*Double(zone)-183)*Double.pi/180)))-latitude*Double.pi/180)*0.9996*6399593.625/sqrt(1+0.006739496742*pow(cos(latitude*Double.pi/180),2))*(1+0.006739496742/2*pow(0.5*log((1+cos(latitude*Double.pi/180)*sin((longitude*Double.pi/180-(6*Double(zone)-183)*Double.pi/180)))/(1-cos(latitude*Double.pi/180)*sin((longitude*Double.pi/180-(6*Double(zone)-183)*Double.pi/180)))),2)*pow(cos(latitude*Double.pi/180),2))+0.9996*6399593.625*(latitude*Double.pi/180-0.005054622556*(latitude*Double.pi/180+sin(2*latitude*Double.pi/180)/2)+4.258201531e-05*(3*(latitude*Double.pi/180+sin(2*latitude*Double.pi/180)/2)+sin(2*latitude*Double.pi/180)*pow(cos(latitude*Double.pi/180),2))/4-1.674057895e-07*(5*(3*(latitude*Double.pi/180+sin(2*latitude*Double.pi/180)/2)+sin(2*latitude*Double.pi/180)*pow(cos(latitude*Double.pi/180),2))/4+sin(2*latitude*Double.pi/180)*pow(cos(latitude*Double.pi/180),2)*pow(cos(latitude*Double.pi/180),2))/3) + + if hemisphere == Hemisphere.SOUTH { + northing = northing + 10000000 + } + + northing = round(northing * 100) * 0.01 + + return UTM(zone, hemisphere, easting, northing) + } + + /** + * Create from a coordinate + * + * @param coordinate + * coordinate + * @return UTM + */ + public static func from(_ coordinate: CLLocationCoordinate2D) -> UTM { + return from(coordinate.longitude, coordinate.latitude) + } + + /** + * Create from a coordinate in degrees + * + * @param longitude + * longitude + * @param latitude + * latitude + * @return UTM + */ + public static func from(_ longitude: Double, _ latitude: Double) -> UTM { + return from(longitude, latitude, Unit.DEGREE) + } + + /** + * Create from a coordinate in the unit + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param unit + * unit + * @return UTM + */ + public static func from(_ longitude: Double, _ latitude: Double, _ unit: grid_ios.Unit) -> UTM { + return from(GridPoint(longitude, latitude, unit)) + } + + /** + * Create from a coordinate in degrees and zone number + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param zone + * zone number + * @return UTM + */ + public static func from(_ longitude: Double, _ latitude: Double, _ zone: Int) -> UTM { + return from(longitude, latitude, Unit.DEGREE, zone) + } + + /** + * Create from a coordinate in the unit and zone number + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param unit + * unit + * @param zone + * zone number + * @return UTM + */ + public static func from(_ longitude: Double, _ latitude: Double, _ unit: grid_ios.Unit, _ zone: Int) -> UTM { + return from(GridPoint(longitude, latitude, unit), zone) + } + + /** + * Create from a coordinate in degrees, zone number, and hemisphere + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param zone + * zone number + * @param hemisphere + * hemisphere + * @return UTM + */ + public static func from(_ longitude: Double, _ latitude: Double, _ zone: Int, _ hemisphere: Hemisphere) -> UTM { + return from(longitude, latitude, Unit.DEGREE, zone, hemisphere) + } + + /** + * Create from a coordinate in the unit, zone number, and hemisphere + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param unit + * unit + * @param zone + * zone number + * @param hemisphere + * hemisphere + * @return UTM + */ + public static func from(_ longitude: Double, _ latitude: Double, _ unit: grid_ios.Unit, _ zone: Int, _ hemisphere: Hemisphere) -> UTM { + return from(GridPoint(longitude, latitude, unit), zone, hemisphere) + } + + /** + * Format to a UTM string from a point + * + * @param point + * point + * @return UTM string + */ + public static func format(_ point: GridPoint) -> String { + return from(point).format() + } + + /** + * Format to a UTM string from a point and zone number + * + * @param point + * point + * @param zone + * zone number + * @return UTM string + */ + public static func format(_ point: GridPoint, _ zone: Int) -> String { + return from(point, zone).format() + } + + /** + * Format to a UTM string from a coordinate, zone number, and hemisphere + * + * @param point + * coordinate + * @param zone + * zone number + * @param hemisphere + * hemisphere + * @return UTM string + */ + public static func format(_ point: GridPoint, _ zone: Int, _ hemisphere: Hemisphere) -> String { + return from(point, zone, hemisphere).format() + } + + /** + * Format to a UTM string from a coordinate + * + * @param coordinate + * coordinate + * @return UTM string + */ + public static func format(_ coordinate: CLLocationCoordinate2D) -> String { + return from(coordinate).format() + } + + /** + * Format to a UTM string from a coordinate in degrees + * + * @param longitude + * longitude + * @param latitude + * latitude + * @return UTM string + */ + public static func format(_ longitude: Double, _ latitude: Double) -> String { + return from(longitude, latitude).format() + } + + /** + * Format to a UTM string from a coordinate in the unit + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param unit + * unit + * @return UTM string + */ + public static func format(_ longitude: Double, _ latitude: Double, _ unit: grid_ios.Unit) -> String { + return from(longitude, latitude, unit).format() + } + + /** + * Format to a UTM string from a coordinate in degrees and zone number + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param zone + * zone number + * @return UTM string + */ + public static func format(_ longitude: Double, _ latitude: Double, _ zone: Int) -> String { + return from(longitude, latitude, zone).format() + } + + /** + * Format to a UTM string from a coordinate in the unit and zone number + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param unit + * unit + * @param zone + * zone number + * @return UTM string + */ + public static func format(_ longitude: Double, _ latitude: Double, _ unit: grid_ios.Unit, _ zone: Int) -> String { + return from(longitude, latitude, unit, zone).format() + } + + /** + * Format to a UTM string from a coordinate in degrees, zone number, and hemisphere + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param zone + * zone number + * @param hemisphere + * hemisphere + * @return UTM string + */ + public static func format(_ longitude: Double, _ latitude: Double, _ zone: Int, _ hemisphere: Hemisphere) -> String { + return from(longitude, latitude, zone, hemisphere).format() + } + + /** + * Format to a UTM string from a coordinate in the unit, zone number, and hemisphere + * + * @param longitude + * longitude + * @param latitude + * latitude + * @param unit + * unit + * @param zone + * zone number + * @param hemisphere + * hemisphere + * @return UTM string + */ + public static func format(_ longitude: Double, _ latitude: Double, _ unit: grid_ios.Unit, _ zone: Int, _ hemisphere: Hemisphere) -> String { + return from(longitude, latitude, unit, zone, hemisphere).format() + } + +} diff --git a/Pods/sf-ios/LICENSE b/Pods/sf-ios/LICENSE new file mode 100644 index 0000000..713780d --- /dev/null +++ b/Pods/sf-ios/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Bit Systems + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Pods/sf-ios/README.md b/Pods/sf-ios/README.md new file mode 100644 index 0000000..1914274 --- /dev/null +++ b/Pods/sf-ios/README.md @@ -0,0 +1,59 @@ +# Simple Features iOS + +#### Simple Features Lib #### + +The Simple Features Libraries were developed at the [National Geospatial-Intelligence Agency (NGA)](http://www.nga.mil/) in collaboration with [BIT Systems](https://www.caci.com/bit-systems/). The government has "unlimited rights" and is releasing this software to increase the impact of government investments by providing developers with the opportunity to take things in new directions. The software use, modification, and distribution rights are stipulated within the [MIT license](http://choosealicense.com/licenses/mit/). + +### Pull Requests ### +If you'd like to contribute to this project, please make a pull request. We'll review the pull request and discuss the changes. All pull request contributions to this project will be released under the MIT license. + +Software source code previously released under an open source license and then modified by NGA staff is considered a "joint work" (see 17 USC § 101); it is partially copyrighted, partially public domain, and as a whole is protected by the copyrights of the non-government authors and must be released according to the terms of the original open source license. + +### About ### + +[Simple Features](http://ngageoint.github.io/simple-features-ios/) is an iOS library of geometry objects and utilities based upon the [OGC Simple Feature Access](http://www.opengeospatial.org/standards/sfa) standard. + +### Simple Feature Conversion Libraries ### + +* [simple-features-wkb-ios](https://github.com/ngageoint/simple-features-wkb-ios) - Well-Known Binary +* [simple-features-wkt-ios](https://github.com/ngageoint/simple-features-wkt-ios) - Well-Known Text +* [simple-features-geojson-ios](https://github.com/ngageoint/simple-features-geojson-ios) - GeoJSON +* [simple-features-proj-ios](https://github.com/ngageoint/simple-features-proj-ios) - Projection + +### Usage ### + +View the latest [Appledoc](http://ngageoint.github.io/simple-features-ios/docs/api/) + +### Build ### + +[![Build & Test](https://github.com/ngageoint/simple-features-ios/workflows/Build%20&%20Test/badge.svg)](https://github.com/ngageoint/simple-features-ios/actions/workflows/build-test.yml) + +Build this repository using Xcode and/or CocoaPods: + + pod repo update + pod install + +Open sf-ios.xcworkspace in Xcode or build from command line: + + xcodebuild -workspace 'sf-ios.xcworkspace' -scheme sf-ios build + +Run tests from Xcode or from command line: + + xcodebuild test -workspace 'sf-ios.xcworkspace' -scheme sf-ios -destination 'platform=iOS Simulator,name=iPhone 14' + +### Include Library ### + +Include this repository by specifying it in a Podfile using a supported option. + +Pull from [CocoaPods](https://cocoapods.org/pods/sf-ios): + + pod 'sf-ios', '~> 4.1.2' + +Pull from GitHub: + + pod 'sf-ios', :git => 'https://github.com/ngageoint/simple-features-ios.git', :branch => 'master' + pod 'sf-ios', :git => 'https://github.com/ngageoint/simple-features-ios.git', :tag => '4.1.2' + +Include as local project: + + pod 'sf-ios', :path => '../simple-features-ios' diff --git a/Pods/sf-ios/sf-ios/SFCircularString.h b/Pods/sf-ios/sf-ios/SFCircularString.h new file mode 100644 index 0000000..056956c --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFCircularString.h @@ -0,0 +1,88 @@ +// +// SFCircularString.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFLineString.h" + +/** + * Circular String, Curve sub type + */ +@interface SFCircularString : SFLineString + +/** + * Create + * + * @return new circular string + */ ++(SFCircularString *) circularString; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new circular string + */ ++(SFCircularString *) circularStringWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param points + * list of points + * + * @return new circular string + */ ++(SFCircularString *) circularStringWithPoints: (NSMutableArray *) points; + +/** + * Create + * + * @param circularString circular string + * + * @return new circular string + */ ++(SFCircularString *) circularStringWithCircularString: (SFCircularString *) circularString; + +/** + * Initialize + * + * @return new circular string + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new circular string + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param points + * list of points + * + * @return new circular string + */ +-(instancetype) initWithPoints: (NSMutableArray *) points; + +/** + * Initialize + * + * @param circularString circular string + * + * @return new circular string + */ +-(instancetype) initWithCircularString: (SFCircularString *) circularString; + +@end diff --git a/Pods/sf-ios/sf-ios/SFCircularString.m b/Pods/sf-ios/sf-ios/SFCircularString.m new file mode 100644 index 0000000..45e5f55 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFCircularString.m @@ -0,0 +1,62 @@ +// +// SFCircularString.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFCircularString.h" +#import "SFGeometryUtils.h" + +@implementation SFCircularString + ++(SFCircularString *) circularString{ + return [[SFCircularString alloc] init]; +} + ++(SFCircularString *) circularStringWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFCircularString alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFCircularString *) circularStringWithPoints: (NSMutableArray *) points{ + return [[SFCircularString alloc] initWithPoints:points]; +} + ++(SFCircularString *) circularStringWithCircularString: (SFCircularString *) circularString{ + return [[SFCircularString alloc] initWithCircularString:circularString]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:SF_CIRCULARSTRING andHasZ:hasZ andHasM:hasM]; + return self; +} + +-(instancetype) initWithPoints: (NSMutableArray *) points{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:points] andHasM:[SFGeometryUtils hasM:points]]; + if(self != nil){ + [self setPoints:points]; + } + return self; +} + +-(instancetype) initWithCircularString: (SFCircularString *) circularString{ + self = [self initWithHasZ:circularString.hasZ andHasM:circularString.hasM]; + if(self != nil){ + for(SFPoint *point in circularString.points){ + [self addPoint:[point mutableCopy]]; + } + } + return self; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFCircularString circularStringWithCircularString:self]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFCompoundCurve.h b/Pods/sf-ios/sf-ios/SFCompoundCurve.h new file mode 100644 index 0000000..da4341b --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFCompoundCurve.h @@ -0,0 +1,146 @@ +// +// SFCompoundCurve.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFLineString.h" + +/** + * Compound Curve, Curve sub type + */ +@interface SFCompoundCurve : SFCurve + +/** + * Array of line strings + */ +@property (nonatomic, strong) NSMutableArray *lineStrings; + +/** + * Create + * + * @return new compound curve + */ ++(SFCompoundCurve *) compoundCurve; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new compound curve + */ ++(SFCompoundCurve *) compoundCurveWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param lineStrings + * list of line strings + * + * @return new compound curve + */ ++(SFCompoundCurve *) compoundCurveWithLineStrings: (NSMutableArray *) lineStrings; + +/** + * Create + * + * @param lineString + * line string + * + * @return new compound curve + */ ++(SFCompoundCurve *) compoundCurveWithLineString: (SFLineString *) lineString; + +/** + * Create + * + * @param compoundCurve + * compound curve + * + * @return new compound curve + */ ++(SFCompoundCurve *) compoundCurveWithCompoundCurve: (SFCompoundCurve *) compoundCurve; + +/** + * Initialize + * + * @return new compound curve + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new compound curve + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param lineStrings + * list of line strings + * + * @return new compound curve + */ +-(instancetype) initWithLineStrings: (NSMutableArray *) lineStrings; + +/** + * Initialize + * + * @param lineString + * line string + * + * @return new compound curve + */ +-(instancetype) initWithLineString: (SFLineString *) lineString; + +/** + * Initialize + * + * @param compoundCurve + * compound curve + * + * @return new compound curve + */ +-(instancetype) initWithCompoundCurve: (SFCompoundCurve *) compoundCurve; + +/** + * Add a line string + * + * @param lineString line string + */ +-(void) addLineString: (SFLineString *) lineString; + +/** + * Add line strings + * + * @param lineStrings + * line strings + */ +-(void) addLineStrings: (NSArray *) lineStrings; + +/** + * Get the number of line strings + * + * @return line string count + */ +-(int) numLineStrings; + +/** + * Returns the Nth line string + * + * @param n + * nth line string to return + * @return line string + */ +-(SFLineString *) lineStringAtIndex: (int) n; + +@end diff --git a/Pods/sf-ios/sf-ios/SFCompoundCurve.m b/Pods/sf-ios/sf-ios/SFCompoundCurve.m new file mode 100644 index 0000000..40f2e2c --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFCompoundCurve.m @@ -0,0 +1,185 @@ +// +// SFCompoundCurve.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFCompoundCurve.h" +#import "SFShamosHoey.h" +#import "SFGeometryUtils.h" + +@implementation SFCompoundCurve + ++(SFCompoundCurve *) compoundCurve{ + return [[SFCompoundCurve alloc] init]; +} + ++(SFCompoundCurve *) compoundCurveWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFCompoundCurve alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFCompoundCurve *) compoundCurveWithLineStrings: (NSMutableArray *) lineStrings{ + return [[SFCompoundCurve alloc] initWithLineStrings:lineStrings]; +} + ++(SFCompoundCurve *) compoundCurveWithLineString: (SFLineString *) lineString{ + return [[SFCompoundCurve alloc] initWithLineString:lineString]; +} + ++(SFCompoundCurve *) compoundCurveWithCompoundCurve: (SFCompoundCurve *) compoundCurve{ + return [[SFCompoundCurve alloc] initWithCompoundCurve:compoundCurve]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:SF_COMPOUNDCURVE andHasZ:hasZ andHasM:hasM]; + if(self != nil){ + self.lineStrings = [NSMutableArray array]; + } + return self; +} + +-(instancetype) initWithLineStrings: (NSMutableArray *) lineStrings{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:lineStrings] andHasM:[SFGeometryUtils hasM:lineStrings]]; + if(self != nil){ + [self setLineStrings:lineStrings]; + } + return self; +} + +-(instancetype) initWithLineString: (SFLineString *) lineString{ + self = [self initWithHasZ:lineString.hasZ andHasM:lineString.hasM]; + if(self != nil){ + [self addLineString:lineString]; + } + return self; +} + +-(instancetype) initWithCompoundCurve: (SFCompoundCurve *) compoundCurve{ + self = [self initWithHasZ:compoundCurve.hasZ andHasM:compoundCurve.hasM]; + if(self != nil){ + for(SFLineString *lineString in compoundCurve.lineStrings){ + [self addLineString:[lineString mutableCopy]]; + } + } + return self; +} + +-(void) addLineString: (SFLineString *) lineString{ + [self.lineStrings addObject:lineString]; + [self updateZM:lineString]; +} + +-(void) addLineStrings: (NSArray *) lineStrings{ + for(SFLineString *lineString in lineStrings){ + [self addLineString:lineString]; + } +} + +-(int) numLineStrings{ + return (int)self.lineStrings.count; +} + +-(SFLineString *) lineStringAtIndex: (int) n{ + return [self.lineStrings objectAtIndex:n]; +} + +-(SFPoint *) startPoint{ + SFPoint *startPoint = nil; + if (![self isEmpty]) { + for (SFLineString *lineString in self.lineStrings) { + if (![lineString isEmpty]) { + startPoint = [lineString startPoint]; + break; + } + } + } + return startPoint; +} + +-(SFPoint *) endPoint{ + SFPoint *endPoint = nil; + if (![self isEmpty]) { + for (int i = (int)self.lineStrings.count - 1; i >= 0; i--) { + SFLineString *lineString = [self.lineStrings objectAtIndex:i]; + if (![lineString isEmpty]) { + endPoint = [lineString endPoint]; + break; + } + } + } + return endPoint; +} + +-(BOOL) isEmpty{ + return self.lineStrings.count == 0; +} + +-(BOOL) isSimple{ + return [SFShamosHoey simplePolygonRings:self.lineStrings]; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFCompoundCurve compoundCurveWithCompoundCurve:self]; +} + ++ (BOOL) supportsSecureCoding { + return YES; +} + +- (void) encodeWithCoder:(NSCoder *)encoder { + [super encodeWithCoder:encoder]; + + [encoder encodeObject:self.lineStrings forKey:@"lineStrings"]; +} + +- (id) initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + _lineStrings = [decoder decodeObjectOfClasses:[NSSet setWithObjects:[NSMutableArray class], [SFLineString class], nil] forKey:@"lineStrings"]; + } + return self; +} + +- (BOOL)isEqualToCompoundCurve:(SFCompoundCurve *)compoundCurve { + if (self == compoundCurve) + return YES; + if (compoundCurve == nil) + return NO; + if (![super isEqual:compoundCurve]) + return NO; + if (self.lineStrings == nil) { + if (compoundCurve.lineStrings != nil) + return NO; + } else if (![self.lineStrings isEqual:compoundCurve.lineStrings]) + return NO; + return YES; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[SFCompoundCurve class]]) { + return NO; + } + + return [self isEqualToCompoundCurve:(SFCompoundCurve *)object]; +} + +- (NSUInteger)hash { + NSUInteger prime = 31; + NSUInteger result = [super hash]; + result = prime * result + + ((self.lineStrings == nil) ? 0 : [self.lineStrings hash]); + return result; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFCurve.h b/Pods/sf-ios/sf-ios/SFCurve.h new file mode 100644 index 0000000..7681878 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFCurve.h @@ -0,0 +1,59 @@ +// +// SFCurve.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFPoint.h" + +/** + * The base type for all 1-dimensional geometry types. A 1-dimensional geometry + * is a geometry that has a length, but no area. A curve is considered simple if + * it does not intersect itself (except at the start and end point). A curve is + * considered closed its start and end point are coincident. A simple, closed + * curve is called a ring. + */ +@interface SFCurve : SFGeometry + +/** + * Initialize + * + * @param geometryType geometry type + * @param hasZ has z values + * @param hasM has m values + * + * @return new curve + */ +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Get the start Point of this Curve + * + * @return start point + */ +-(SFPoint *) startPoint; + +/** + * Get the end Point of this Curve + * + * @return end point + */ +-(SFPoint *) endPoint; + +/** + * Determine if this Curve is closed (start point = end point) + * + * @return true if closed + */ +-(BOOL) isClosed; + +/** + * Determine if this Curve is a ring (closed and simple) + * + * @return true if a ring + */ +-(BOOL) isRing; + +@end diff --git a/Pods/sf-ios/sf-ios/SFCurve.m b/Pods/sf-ios/sf-ios/SFCurve.m new file mode 100644 index 0000000..2199efb --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFCurve.m @@ -0,0 +1,36 @@ +// +// SFCurve.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFCurve.h" + +@implementation SFCurve + +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:geometryType andHasZ:hasZ andHasM:hasM]; + return self; +} + +-(SFPoint *) startPoint{ + [NSException raise:@"Abstract" format:@"Can not determine start point of abstract curve"]; + return nil; +} + +-(SFPoint *) endPoint{ + [NSException raise:@"Abstract" format:@"Can not determine end point of abstract curve"]; + return nil; +} + +-(BOOL) isClosed{ + return ![self isEmpty] && [[self startPoint] isEqual:[self endPoint]]; +} + +-(BOOL) isRing{ + return [self isClosed] && [self isSimple]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFCurvePolygon.h b/Pods/sf-ios/sf-ios/SFCurvePolygon.h new file mode 100644 index 0000000..5dc5050 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFCurvePolygon.h @@ -0,0 +1,183 @@ +// +// SFCurvePolygon.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFSurface.h" +#import "SFCurve.h" + +/** + * A planar surface defined by an exterior ring and zero or more interior ring. + * Each ring is defined by a Curve instance. + */ +@interface SFCurvePolygon : SFSurface + +/** + * Array of rings + */ +@property (nonatomic, strong) NSMutableArray *rings; + +/** + * Create + * + * @return new curve polygon + */ ++(SFCurvePolygon *) curvePolygon; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new curve polygon + */ ++(SFCurvePolygon *) curvePolygonWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param rings + * list of rings + * + * @return new curve polygon + */ ++(SFCurvePolygon *) curvePolygonWithRings: (NSMutableArray *) rings; + +/** + * Create + * + * @param ring + * ring + * + * @return new curve polygon + */ ++(SFCurvePolygon *) curvePolygonWithRing: (SFCurve *) ring; + +/** + * Create + * + * @param curvePolygon + * curve polygon + * + * @return new curve polygon + */ ++(SFCurvePolygon *) curvePolygonWithCurvePolygon: (SFCurvePolygon *) curvePolygon; + +/** + * Initialize + * + * @return new curve polygon + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new curve polygon + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param rings + * list of rings + * + * @return new curve polygon + */ +-(instancetype) initWithRings: (NSMutableArray *) rings; + +/** + * Initialize + * + * @param ring + * ring + * + * @return new curve polygon + */ +-(instancetype) initWithRing: (SFCurve *) ring; + +/** + * Initialize + * + * @param geometryType geometry type + * @param hasZ has z values + * @param hasM has m values + * + * @return new curve polygon + */ +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param curvePolygon + * curve polygon + * + * @return new curve polygon + */ +-(instancetype) initWithCurvePolygon: (SFCurvePolygon *) curvePolygon; + +/** + * Add a ring + * + * @param ring curve ring + */ +-(void) addRing: (SFCurve *) ring; + +/** + * Add rings + * + * @param rings + * rings + */ +-(void) addRings: (NSArray *) rings; + +/** + * Get the number of rings + * + * @return ring count + */ +-(int) numRings; + +/** + * Returns the Nth ring where the exterior ring is at 0, interior rings + * begin at 1 + * + * @param n + * nth ring to return + * @return ring + */ +-(SFCurve *) ringAtIndex: (int) n; + +/** + * Get the exterior ring + * + * @return exterior ring + */ +-(SFCurve *) exteriorRing; + +/** + * Get the number of interior rings + * + * @return number of interior rings + */ +-(int) numInteriorRings; + +/** + * Returns the Nth interior ring for this Polygon + * + * @param n + * interior ring number + * @return interior ring + */ +-(SFCurve *) interiorRingAtIndex: (int) n; + +@end diff --git a/Pods/sf-ios/sf-ios/SFCurvePolygon.m b/Pods/sf-ios/sf-ios/SFCurvePolygon.m new file mode 100644 index 0000000..8166ce1 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFCurvePolygon.m @@ -0,0 +1,174 @@ +// +// SFCurvePolygon.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFCurvePolygon.h" +#import "SFGeometryUtils.h" + +@implementation SFCurvePolygon + ++(SFCurvePolygon *) curvePolygon{ + return [[SFCurvePolygon alloc] init]; +} + ++(SFCurvePolygon *) curvePolygonWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFCurvePolygon alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFCurvePolygon *) curvePolygonWithRings: (NSMutableArray *) rings{ + return [[SFCurvePolygon alloc] initWithRings:rings]; +} + ++(SFCurvePolygon *) curvePolygonWithRing: (SFCurve *) ring{ + return [[SFCurvePolygon alloc] initWithRing:ring]; +} + ++(SFCurvePolygon *) curvePolygonWithCurvePolygon: (SFCurvePolygon *) curvePolygon{ + return [[SFCurvePolygon alloc] initWithCurvePolygon:curvePolygon]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [self initWithType:SF_CURVEPOLYGON andHasZ:hasZ andHasM:hasM]; +} + +-(instancetype) initWithRings: (NSMutableArray *) rings{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:rings] andHasM:[SFGeometryUtils hasM:rings]]; + if(self != nil){ + [self setRings:rings]; + } + return self; +} + +-(instancetype) initWithRing: (SFCurve *) ring{ + self = [self initWithHasZ:ring.hasZ andHasM:ring.hasM]; + if(self != nil){ + [self addRing:ring]; + } + return self; +} + +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:geometryType andHasZ:hasZ andHasM:hasM]; + if(self != nil){ + self.rings = [NSMutableArray array]; + } + return self; +} + +-(instancetype) initWithCurvePolygon: (SFCurvePolygon *) curvePolygon{ + self = [self initWithHasZ:curvePolygon.hasZ andHasM:curvePolygon.hasM]; + if(self != nil){ + for(SFCurve *ring in curvePolygon.rings){ + [self addRing:[ring mutableCopy]]; + } + } + return self; +} + +-(void) addRing: (SFCurve *) ring{ + [self.rings addObject:ring]; + [self updateZM:ring]; +} + +-(void) addRings: (NSArray *) rings{ + for(SFCurve *ring in rings){ + [self addRing:ring]; + } +} + +-(int) numRings{ + return (int) self.rings.count; +} + +-(SFCurve *) ringAtIndex: (int) n{ + return [self.rings objectAtIndex:n]; +} + +-(SFCurve *) exteriorRing{ + return [self.rings objectAtIndex:0]; +} + +-(int) numInteriorRings{ + return (int)self.rings.count - 1; +} + +-(SFCurve *) interiorRingAtIndex: (int) n{ + return [self.rings objectAtIndex:n + 1]; +} + +-(BOOL) isEmpty{ + return self.rings.count == 0; +} + +-(BOOL) isSimple{ + [NSException raise:@"Unsupported" format:@"Is Simple not implemented for Curve Polygon"]; + return NO; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFCurvePolygon curvePolygonWithCurvePolygon:self]; +} + ++ (BOOL) supportsSecureCoding { + return YES; +} + +- (void) encodeWithCoder:(NSCoder *)encoder { + [super encodeWithCoder:encoder]; + + [encoder encodeObject:self.rings forKey:@"rings"]; +} + +- (id) initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + _rings = [decoder decodeObjectOfClasses:[NSSet setWithObjects:[NSMutableArray class], [SFCurve class], nil] forKey:@"rings"]; + } + return self; +} + +- (BOOL)isEqualToCurvePolygon:(SFCurvePolygon *)curvePolygon { + if (self == curvePolygon) + return YES; + if (curvePolygon == nil) + return NO; + if (![super isEqual:curvePolygon]) + return NO; + if (self.rings == nil) { + if (curvePolygon.rings != nil) + return NO; + } else if (![self.rings isEqual:curvePolygon.rings]) + return NO; + return YES; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[SFCurvePolygon class]]) { + return NO; + } + + return [self isEqualToCurvePolygon:(SFCurvePolygon *)object]; +} + +- (NSUInteger)hash { + NSUInteger prime = 31; + NSUInteger result = [super hash]; + result = prime * result + + ((self.rings == nil) ? 0 : [self.rings hash]); + return result; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFGeometry.h b/Pods/sf-ios/sf-ios/SFGeometry.h new file mode 100644 index 0000000..cebab71 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFGeometry.h @@ -0,0 +1,124 @@ +// +// SFGeometry.h +// sf-ios +// +// Created by Brian Osborn on 6/1/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometryTypes.h" +#import "SFGeometryEnvelope.h" + +@class SFPoint; + +/** + * The root of the geometry type hierarchy + */ +@interface SFGeometry : NSObject + +/** + * Geometry type + */ +@property (nonatomic) enum SFGeometryType geometryType; + +/** + * Has Z values + */ +@property (nonatomic) BOOL hasZ; + +/** + * Has M values + */ +@property (nonatomic) BOOL hasM; + +/** + * Initialize + * + * @param geometryType geometry type + * @param hasZ has z values + * @param hasM has m values + * + * @return new geometry + */ +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Does the geometry have z coordinates + * + * @return true if has z coordinates + */ +-(BOOL) is3D; + +/** + * Does the geometry have m coordinates. + * + * @return true if has m coordinates + */ +-(BOOL) isMeasured; + +/** + * Get the minimum bounding box for this Geometry + * + * @return geometry envelope + */ +-(SFGeometryEnvelope *) envelope; + +/** + * Expand the envelope with the minimum bounding box for this Geometry + * + * @param envelope + * geometry envelope to expand + */ +-(void) expandEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Get the inherent dimension (0, 1, or 2) for this Geometry + * + * @return dimension + */ +-(int) dimension; + +/** + * Get the mathematical centroid point of a 2 dimensional representation of + * the Geometry (balancing point of a 2d cutout of the geometry). Only the x + * and y coordinate of the resulting point are calculated and populated. The + * resulting SFPoint.z and SFPoint.m values will always be nil. + * + * @return centroid point + */ +-(SFPoint *) centroid; + +/** + * Get the geographic centroid point of a 2 dimensional representation of + * the degree unit Geometry. Only the x and y coordinate of the resulting + * point are calculated and populated. The resulting SFPoint.z and + * SFPoint.m values will always be nil. + * + * @return centroid point + */ +-(SFPoint *) degreesCentroid; + +/** + * Is the Geometry empty + * + * @return true if empty + */ +-(BOOL) isEmpty; + +/** + * Determine if this Geometry has no anomalous geometric points, such as + * self intersection or self tangency + * + * @return true if simple + */ +-(BOOL) isSimple; + +/** + * Update currently false hasZ and hasM values using the provided geometry + * + * @param geometry + * geometry + */ +-(void) updateZM: (SFGeometry *) geometry; + +@end diff --git a/Pods/sf-ios/sf-ios/SFGeometry.m b/Pods/sf-ios/sf-ios/SFGeometry.m new file mode 100644 index 0000000..a594000 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFGeometry.m @@ -0,0 +1,132 @@ +// +// SFGeometry.m +// sf-ios +// +// Created by Brian Osborn on 6/1/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometry.h" +#import "SFGeometryEnvelopeBuilder.h" +#import "SFGeometryUtils.h" + +@implementation SFGeometry + +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super init]; + if(self != nil){ + self.geometryType = geometryType; + self.hasZ = hasZ; + self.hasM = hasM; + } + return self; +} + +-(BOOL) is3D{ + return _hasZ; +} + +-(BOOL) isMeasured{ + return _hasM; +} + +-(SFGeometryEnvelope *) envelope{ + return [SFGeometryEnvelopeBuilder buildEnvelopeWithGeometry:self]; +} + +-(void) expandEnvelope: (SFGeometryEnvelope *) envelope{ + [SFGeometryEnvelopeBuilder buildEnvelope:envelope andGeometry:self]; +} + +-(int) dimension{ + return [SFGeometryUtils dimensionOfGeometry:self]; +} + +-(SFPoint *) centroid{ + return [SFGeometryUtils centroidOfGeometry:self]; +} + +-(SFPoint *) degreesCentroid{ + return [SFGeometryUtils degreesCentroidOfGeometry:self]; +} + +-(BOOL) isEmpty{ + [NSException raise:@"Abstract" format:@"Can not determine if abstract geometry is empty"]; + return NO; +} + +-(BOOL) isSimple{ + [NSException raise:@"Abstract" format:@"Can not determine if abstract geometry is simple"]; + return NO; +} + +-(void) updateZM: (SFGeometry *) geometry{ + if(!_hasZ){ + [self setHasZ:geometry.hasZ]; + } + if(!_hasM){ + [self setHasM:geometry.hasM]; + } +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + [NSException raise:@"Abstract" format:@"Can not copy abstract geometry"]; + return nil; +} + ++ (BOOL) supportsSecureCoding { + return YES; +} + +- (void) encodeWithCoder:(NSCoder *)encoder { + [encoder encodeInt:(int)self.geometryType forKey:@"geometryType"]; + [encoder encodeBool:self.hasZ forKey:@"hasZ"]; + [encoder encodeBool:self.hasM forKey:@"hasM"]; +} + +- (id) initWithCoder:(NSCoder *)decoder { + self = [super init]; + if (self) { + _geometryType = (enum SFGeometryType)[decoder decodeIntForKey:@"geometryType"]; + _hasZ = [decoder decodeBoolForKey:@"hasZ"]; + _hasM = [decoder decodeBoolForKey:@"hasM"]; + } + return self; +} + +- (BOOL)isEqualToGeometry:(SFGeometry *)geometry { + if (self == geometry) + return YES; + if (geometry == nil) + return NO; + if (self.geometryType != geometry.geometryType) + return NO; + if (self.hasM != geometry.hasM) + return NO; + if (self.hasZ != geometry.hasZ) + return NO; + return YES; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[SFGeometry class]]) { + return NO; + } + + return [self isEqualToGeometry:(SFGeometry *)object]; +} + +- (NSUInteger)hash { + NSUInteger prime = 31; + NSUInteger result = 1; + result = prime * result + (int)self.geometryType; + result = prime * result + (self.hasM ? 1231 : 1237); + result = prime * result + (self.hasZ ? 1231 : 1237); + return result; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFGeometryCollection.h b/Pods/sf-ios/sf-ios/SFGeometryCollection.h new file mode 100644 index 0000000..4760ba0 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFGeometryCollection.h @@ -0,0 +1,261 @@ +// +// SFGeometryCollection.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometry.h" + +@class SFMultiPoint; +@class SFMultiLineString; +@class SFMultiPolygon; +@class SFMultiCurve; +@class SFMultiSurface; + +/** + * A collection of zero or more Geometry instances. + */ +@interface SFGeometryCollection : SFGeometry + +/** + * Array of geometries + */ +@property (nonatomic, strong) NSMutableArray *geometries; + +/** + * Create + * + * @return new geometry collection + */ ++(SFGeometryCollection *) geometryCollection; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new geometry collection + */ ++(SFGeometryCollection *) geometryCollectionWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param geometries + * list of geometries + * + * @return new geometry collection + */ ++(SFGeometryCollection *) geometryCollectionWithGeometries: (NSMutableArray *) geometries; + +/** + * Create + * + * @param geometry + * geometry + * + * @return new geometry collection + */ ++(SFGeometryCollection *) geometryCollectionWithGeometry: (SFGeometry *) geometry; + +/** + * Create + * + * @param geometryCollection + * geometry ollection + * + * @return new geometry collection + */ ++(SFGeometryCollection *) geometryCollectionWithGeometryCollection: (SFGeometryCollection *) geometryCollection; + +/** + * Initialize + * + * @return new geometry collection + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new geometry collection + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param geometries + * list of geometries + * + * @return new geometry collection + */ +-(instancetype) initWithGeometries: (NSMutableArray *) geometries; + +/** + * Initialize + * + * @param geometry + * geometry + * + * @return new geometry collection + */ +-(instancetype) initWithGeometry: (SFGeometry *) geometry; + +/** + * Initialize + * + * @param geometryType geometry type + * @param hasZ has z values + * @param hasM has m values + * + * @return new geometry collection + */ +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param geometryCollection + * geometry ollection + * + * @return new geometry collection + */ +-(instancetype) initWithGeometryCollection: (SFGeometryCollection *) geometryCollection; + +/** + * Add geometry + * + * @param geometry geometry + */ +-(void) addGeometry: (SFGeometry *) geometry; + +/** + * Add geometries + * + * @param geometries + * geometries + */ +-(void) addGeometries: (NSArray *) geometries; + +/** + * Get the number of geometries + * + * @return geometry count + */ +-(int) numGeometries; + +/** + * Returns the Nth geometry + * + * @param n + * nth geometry to return + * @return geometry + */ +-(SFGeometry *) geometryAtIndex: (int) n; + +/** + * Get the collection type by evaluating the geometries + * + * @return collection geometry type, one of: + * MULTIPOINT, + * MULTILINESTRING, + * MULTIPOLYGON, + * MULTICURVE, + * MULTISURFACE, + * GEOMETRYCOLLECTION + */ +-(enum SFGeometryType) collectionType; + +/** + * Determine if this geometry collection is a MultiPoint instance or + * contains only Point geometries + * + * @return true if a multi point or contains only points + */ +-(BOOL) isMultiPoint; + +/** + * Get as a MultiPoint, either the current instance or newly created + * from the Point geometries + * + * @return multi point + */ +-(SFMultiPoint *) asMultiPoint; + +/** + * Determine if this geometry collection is a MultiLineString + * instance or contains only LineString geometries + * + * @return true if a multi line string or contains only line strings + */ +-(BOOL) isMultiLineString; + +/** + * Get as a MultiLineString, either the current instance or newly + * created from the LineString geometries + * + * @return multi line string + */ +-(SFMultiLineString *) asMultiLineString; + +/** + * Determine if this geometry collection is a MultiPolygon instance + * or contains only Polygon geometries + * + * @return true if a multi polygon or contains only polygons + */ +-(BOOL) isMultiPolygon; + +/** + * Get as a MultiPolygon, either the current instance or newly + * created from the Polygon geometries + * + * @return multi polygon + */ +-(SFMultiPolygon *) asMultiPolygon; + +/** + * Determine if this geometry collection contains only Curve + * geometries + * + * @return true if contains only curves + */ +-(BOOL) isMultiCurve; + +/** + * Get as a Multi Curve, a Curve typed Geometry Collection + * + * @return multi curve + */ +-(SFGeometryCollection *) asMultiCurve; + +/** + * Determine if this geometry collection contains only Surface + * geometries + * + * @return true if contains only surfaces + */ +-(BOOL) isMultiSurface; + +/** + * Get as a Multi Surface, a Surface typed Geometry Collection + * + * @return multi surface + */ +-(SFGeometryCollection *) asMultiSurface; + +/** + * Get as a top level Geometry Collection + * + * @return geometry collection + */ +-(SFGeometryCollection *) asGeometryCollection; + +@end diff --git a/Pods/sf-ios/sf-ios/SFGeometryCollection.m b/Pods/sf-ios/sf-ios/SFGeometryCollection.m new file mode 100644 index 0000000..3f25872 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFGeometryCollection.m @@ -0,0 +1,308 @@ +// +// SFGeometryCollection.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometryUtils.h" +#import "SFMultiLineString.h" +#import "SFMultiPolygon.h" + +@implementation SFGeometryCollection + ++(SFGeometryCollection *) geometryCollection{ + return [[SFGeometryCollection alloc] init]; +} + ++(SFGeometryCollection *) geometryCollectionWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFGeometryCollection alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFGeometryCollection *) geometryCollectionWithGeometries: (NSMutableArray *) geometries{ + return [[SFGeometryCollection alloc] initWithGeometries:geometries]; +} + ++(SFGeometryCollection *) geometryCollectionWithGeometry: (SFGeometry *) geometry{ + return [[SFGeometryCollection alloc] initWithGeometry:geometry]; +} + ++(SFGeometryCollection *) geometryCollectionWithGeometryCollection: (SFGeometryCollection *) geometryCollection{ + return [[SFGeometryCollection alloc] initWithGeometryCollection:geometryCollection]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [self initWithType:SF_GEOMETRYCOLLECTION andHasZ:hasZ andHasM:hasM]; +} + +-(instancetype) initWithGeometries: (NSMutableArray *) geometries{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:geometries] andHasM:[SFGeometryUtils hasM:geometries]]; + if(self != nil){ + [self setGeometries:geometries]; + } + return self; +} + +-(instancetype) initWithGeometry: (SFGeometry *) geometry{ + self = [self initWithHasZ:geometry.hasZ andHasM:geometry.hasM]; + if(self != nil){ + [self addGeometry:geometry]; + } + return self; +} + +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:geometryType andHasZ:hasZ andHasM:hasM]; + if(self != nil){ + self.geometries = [NSMutableArray array]; + } + return self; +} + +-(instancetype) initWithGeometryCollection: (SFGeometryCollection *) geometryCollection{ + self = [self initWithHasZ:geometryCollection.hasZ andHasM:geometryCollection.hasM]; + if(self != nil){ + for(SFGeometry *geometry in geometryCollection.geometries){ + [self addGeometry:[geometry mutableCopy]]; + } + } + return self; +} + +-(void) addGeometry: (SFGeometry *) geometry{ + [self.geometries addObject:geometry]; + [self updateZM:geometry]; +} + +-(void) addGeometries: (NSArray *) geometries{ + for(SFGeometry *geometry in geometries){ + [self addGeometry:geometry]; + } +} + +-(int) numGeometries{ + return (int)self.geometries.count; +} + +-(SFGeometry *) geometryAtIndex: (int) n{ + return [self.geometries objectAtIndex:n]; +} + +-(enum SFGeometryType) collectionType{ + + enum SFGeometryType geometryType = [self geometryType]; + + switch (geometryType) { + case SF_MULTIPOINT: + case SF_MULTILINESTRING: + case SF_MULTIPOLYGON: + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + if([self isMultiPoint]){ + geometryType = SF_MULTIPOINT; + }else if([self isMultiLineString]){ + geometryType = SF_MULTILINESTRING; + }else if([self isMultiPolygon]){ + geometryType = SF_MULTIPOLYGON; + }else if([self isMultiCurve]){ + geometryType = SF_MULTICURVE; + }else if([self isMultiSurface]){ + geometryType = SF_MULTISURFACE; + } + break; + default: + [NSException raise:@"Unexpected" format:@"Unexpected Geometry Collection Type: %u", geometryType]; + } + + return geometryType; +} + +-(BOOL) isMultiPoint{ + BOOL isMultiPoint = [self isKindOfClass:[SFMultiPoint class]]; + if (!isMultiPoint) { + isMultiPoint = [self isCollectionOfType:[SFPoint class]]; + } + return isMultiPoint; +} + +-(SFMultiPoint *) asMultiPoint{ + SFMultiPoint *multiPoint; + if([self isKindOfClass:[SFMultiPoint class]]){ + multiPoint = (SFMultiPoint *) self; + }else{ + multiPoint = [SFMultiPoint multiPointWithPoints:(NSMutableArray *)self.geometries]; + } + return multiPoint; +} + +-(BOOL) isMultiLineString{ + BOOL isMultiLineString = [self isKindOfClass:[SFMultiLineString class]]; + if (!isMultiLineString) { + isMultiLineString = [self isCollectionOfType:[SFLineString class]]; + } + return isMultiLineString; +} + +-(SFMultiLineString *) asMultiLineString{ + SFMultiLineString *multiLineString; + if([self isKindOfClass:[SFMultiLineString class]]){ + multiLineString = (SFMultiLineString*) self; + }else{ + multiLineString = [SFMultiLineString multiLineStringWithLineStrings:(NSMutableArray *)self.geometries]; + } + return multiLineString; +} + +-(BOOL) isMultiPolygon{ + BOOL isMultiPolygon = [self isKindOfClass:[SFMultiPolygon class]]; + if (!isMultiPolygon) { + isMultiPolygon = [self isCollectionOfType:[SFPolygon class]]; + } + return isMultiPolygon; +} + +-(SFMultiPolygon *) asMultiPolygon{ + SFMultiPolygon *multiPolygon; + if([self isKindOfClass:[SFMultiPolygon class]]){ + multiPolygon = (SFMultiPolygon*) self; + }else{ + multiPolygon = [SFMultiPolygon multiPolygonWithPolygons:(NSMutableArray *)self.geometries]; + } + return multiPolygon; +} + +-(BOOL) isMultiCurve{ + BOOL isMultiCurve = [self isKindOfClass:[SFMultiLineString class]]; + if (!isMultiCurve) { + isMultiCurve = [self isCollectionOfType:[SFCurve class]]; + } + return isMultiCurve; +} + +-(SFGeometryCollection *) asMultiCurve{ + SFGeometryCollection *multiCurve; + if ([self isKindOfClass:[SFMultiLineString class]]) { + multiCurve = [SFGeometryCollection geometryCollectionWithGeometries:self.geometries]; + } else { + multiCurve = self; + } + return multiCurve; +} + +-(BOOL) isMultiSurface{ + BOOL isMultiSurface = [self isKindOfClass:[SFMultiPolygon class]]; + if (!isMultiSurface) { + isMultiSurface = [self isCollectionOfType:[SFSurface class]]; + } + return isMultiSurface; +} + +-(SFGeometryCollection *) asMultiSurface{ + SFGeometryCollection *multiSurface; + if ([self isKindOfClass:[SFMultiPolygon class]]) { + multiSurface = [SFGeometryCollection geometryCollectionWithGeometries:self.geometries]; + } else { + multiSurface = self; + } + return multiSurface; +} + +-(SFGeometryCollection *) asGeometryCollection{ + SFGeometryCollection *geometryCollection; + if([[self class] isMemberOfClass:[SFGeometryCollection class]]){ + geometryCollection = self; + } else { + geometryCollection = [SFGeometryCollection geometryCollectionWithGeometries:self.geometries]; + } + return geometryCollection; +} + +-(BOOL) isCollectionOfType: (Class) type{ + + BOOL isType = YES; + + for(SFGeometry *geometry in self.geometries){ + if(![geometry isKindOfClass:type]){ + isType = NO; + break; + } + } + + return isType; +} + +-(BOOL) isEmpty{ + return self.geometries.count == 0; +} + +-(BOOL) isSimple{ + [NSException raise:@"Unsupported" format:@"Is Simple not implemented for Geometry Collection"]; + return NO; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFGeometryCollection geometryCollectionWithGeometryCollection:self]; +} + ++ (BOOL) supportsSecureCoding { + return YES; +} + +- (void) encodeWithCoder:(NSCoder *)encoder { + [super encodeWithCoder:encoder]; + + [encoder encodeObject:self.geometries forKey:@"geometries"]; +} + +- (id) initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + _geometries = [decoder decodeObjectOfClasses:[NSSet setWithObjects:[NSMutableArray class], [SFGeometry class], nil] forKey:@"geometries"]; + } + return self; +} + +- (BOOL)isEqualToGeometryCollection:(SFGeometryCollection *)geometryCollection { + if (self == geometryCollection) + return YES; + if (geometryCollection == nil) + return NO; + if (![super isEqual:geometryCollection]) + return NO; + if (self.geometries == nil) { + if (geometryCollection.geometries != nil) + return NO; + } else if (![self.geometries isEqual:geometryCollection.geometries]) + return NO; + return YES; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[SFGeometryCollection class]]) { + return NO; + } + + return [self isEqualToGeometryCollection:(SFGeometryCollection *)object]; +} + +- (NSUInteger)hash { + NSUInteger prime = 31; + NSUInteger result = [super hash]; + result = prime * result + + ((self.geometries == nil) ? 0 : [self.geometries hash]); + return result; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFGeometryEnvelope.h b/Pods/sf-ios/sf-ios/SFGeometryEnvelope.h new file mode 100644 index 0000000..a746d09 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFGeometryEnvelope.h @@ -0,0 +1,635 @@ +// +// SFGeometryEnvelope.h +// sf-ios +// +// Created by Brian Osborn on 6/1/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import + +@class SFPoint; +@class SFLine; +@class SFGeometry; + +/** + * Geometry envelope containing x and y range with optional z and m range + */ +@interface SFGeometryEnvelope : NSObject + +/** + * X coordinate range + */ +@property (nonatomic, strong) NSDecimalNumber *minX; +@property (nonatomic, strong) NSDecimalNumber *maxX; + +/** + * Y coordinate range + */ +@property (nonatomic, strong) NSDecimalNumber *minY; +@property (nonatomic, strong) NSDecimalNumber *maxY; + +/** + * Has Z value and Z coordinate range + */ +@property (nonatomic) BOOL hasZ; +@property (nonatomic, strong) NSDecimalNumber *minZ; +@property (nonatomic, strong) NSDecimalNumber *maxZ; + +/** + * Has M value and M coordinate range + */ +@property (nonatomic) BOOL hasM; +@property (nonatomic, strong) NSDecimalNumber *minM; +@property (nonatomic, strong) NSDecimalNumber *maxM; + +/** + * Create with no z or m + * + * @return new geometry envelope + */ ++(SFGeometryEnvelope *) envelope; + +/** + * Create with the has z and m values + * + * @param hasZ geometry has z + * @param hasM geometry has m + * + * @return new geometry envelope + */ ++(SFGeometryEnvelope *) envelopeWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create with number range + * + * @param minX minimum x + * @param minY minimum y + * @param maxX maximum x + * @param maxY maximum y + * + * @return new geometry envelope + */ ++(SFGeometryEnvelope *) envelopeWithMinX: (NSDecimalNumber *) minX + andMinY: (NSDecimalNumber *) minY + andMaxX: (NSDecimalNumber *) maxX + andMaxY: (NSDecimalNumber *) maxY; + +/** + * Create with double range + * + * @param minX minimum x + * @param minY minimum y + * @param maxX maximum x + * @param maxY maximum y + * + * @return new geometry envelope + */ ++(SFGeometryEnvelope *) envelopeWithMinXValue: (double) minX + andMinYValue: (double) minY + andMaxXValue: (double) maxX + andMaxYValue: (double) maxY; + +/** + * Create with number range + * + * @param minX minimum x + * @param minY minimum y + * @param minZ minimum z + * @param maxX maximum x + * @param maxY maximum y + * @param maxZ maximum z + * + * @return new geometry envelope + */ ++(SFGeometryEnvelope *) envelopeWithMinX: (NSDecimalNumber *) minX + andMinY: (NSDecimalNumber *) minY + andMinZ: (NSDecimalNumber *) minZ + andMaxX: (NSDecimalNumber *) maxX + andMaxY: (NSDecimalNumber *) maxY + andMaxZ: (NSDecimalNumber *) maxZ; + +/** + * Create with double range + * + * @param minX minimum x + * @param minY minimum y + * @param minZ minimum z + * @param maxX maximum x + * @param maxY maximum y + * @param maxZ maximum z + * + * @return new geometry envelope + */ ++(SFGeometryEnvelope *) envelopeWithMinXValue: (double) minX + andMinYValue: (double) minY + andMinZValue: (double) minZ + andMaxXValue: (double) maxX + andMaxYValue: (double) maxY + andMaxZValue: (double) maxZ; + +/** + * Create with number range + * + * @param minX minimum x + * @param minY minimum y + * @param minZ minimum z + * @param minM minimum m + * @param maxX maximum x + * @param maxY maximum y + * @param maxZ maximum z + * @param maxM maximum m + * + * @return new geometry envelope + */ ++(SFGeometryEnvelope *) envelopeWithMinX: (NSDecimalNumber *) minX + andMinY: (NSDecimalNumber *) minY + andMinZ: (NSDecimalNumber *) minZ + andMinM: (NSDecimalNumber *) minM + andMaxX: (NSDecimalNumber *) maxX + andMaxY: (NSDecimalNumber *) maxY + andMaxZ: (NSDecimalNumber *) maxZ + andMaxM: (NSDecimalNumber *) maxM; + +/** + * Create with double range + * + * @param minX minimum x + * @param minY minimum y + * @param minZ minimum z + * @param minM minimum m + * @param maxX maximum x + * @param maxY maximum y + * @param maxZ maximum z + * @param maxM maximum m + * + * @return new geometry envelope + */ ++(SFGeometryEnvelope *) envelopeWithMinXValue: (double) minX + andMinYValue: (double) minY + andMinZValue: (double) minZ + andMinMValue: (double) minM + andMaxXValue: (double) maxX + andMaxYValue: (double) maxY + andMaxZValue: (double) maxZ + andMaxMValue: (double) maxM; + +/** + * Create + * + * @param geometryEnvelope geometry envelope + * + * @return new geometry envelope + */ ++(SFGeometryEnvelope *) geometryEnvelopeWithGeometryEnvelope: (SFGeometryEnvelope *) geometryEnvelope; + +/** + * Initialize with no z or m + * + * @return new geometry envelope + */ +-(instancetype) init; + +/** + * Initialize with the has z and m values + * + * @param hasZ geometry has z + * @param hasM geometry has m + * + * @return new geometry envelope + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize with number range + * + * @param minX minimum x + * @param minY minimum y + * @param maxX maximum x + * @param maxY maximum y + * + * @return new geometry envelope + */ +-(instancetype) initWithMinX: (NSDecimalNumber *) minX + andMinY: (NSDecimalNumber *) minY + andMaxX: (NSDecimalNumber *) maxX + andMaxY: (NSDecimalNumber *) maxY; + +/** + * Initialize with double range + * + * @param minX minimum x + * @param minY minimum y + * @param maxX maximum x + * @param maxY maximum y + * + * @return new geometry envelope + */ +-(instancetype) initWithMinXValue: (double) minX + andMinYValue: (double) minY + andMaxXValue: (double) maxX + andMaxYValue: (double) maxY; + +/** + * Initialize with number range + * + * @param minX minimum x + * @param minY minimum y + * @param minZ minimum z + * @param maxX maximum x + * @param maxY maximum y + * @param maxZ maximum z + * + * @return new geometry envelope + */ +-(instancetype) initWithMinX: (NSDecimalNumber *) minX + andMinY: (NSDecimalNumber *) minY + andMinZ: (NSDecimalNumber *) minZ + andMaxX: (NSDecimalNumber *) maxX + andMaxY: (NSDecimalNumber *) maxY + andMaxZ: (NSDecimalNumber *) maxZ; + +/** + * Initialize with double range + * + * @param minX minimum x + * @param minY minimum y + * @param minZ minimum z + * @param maxX maximum x + * @param maxY maximum y + * @param maxZ maximum z + * + * @return new geometry envelope + */ +-(instancetype) initWithMinXValue: (double) minX + andMinYValue: (double) minY + andMinZValue: (double) minZ + andMaxXValue: (double) maxX + andMaxYValue: (double) maxY + andMaxZValue: (double) maxZ; + +/** + * Initialize with number range + * + * @param minX minimum x + * @param minY minimum y + * @param minZ minimum z + * @param minM minimum m + * @param maxX maximum x + * @param maxY maximum y + * @param maxZ maximum z + * @param maxM maximum m + * + * @return new geometry envelope + */ +-(instancetype) initWithMinX: (NSDecimalNumber *) minX + andMinY: (NSDecimalNumber *) minY + andMinZ: (NSDecimalNumber *) minZ + andMinM: (NSDecimalNumber *) minM + andMaxX: (NSDecimalNumber *) maxX + andMaxY: (NSDecimalNumber *) maxY + andMaxZ: (NSDecimalNumber *) maxZ + andMaxM: (NSDecimalNumber *) maxM; + +/** + * Initialize with double range + * + * @param minX minimum x + * @param minY minimum y + * @param minZ minimum z + * @param minM minimum m + * @param maxX maximum x + * @param maxY maximum y + * @param maxZ maximum z + * @param maxM maximum m + * + * @return new geometry envelope + */ +-(instancetype) initWithMinXValue: (double) minX + andMinYValue: (double) minY + andMinZValue: (double) minZ + andMinMValue: (double) minM + andMaxXValue: (double) maxX + andMaxYValue: (double) maxY + andMaxZValue: (double) maxZ + andMaxMValue: (double) maxM; + +/** + * Initialize + * + * @param geometryEnvelope geometry envelope + * + * @return new geometry envelope + */ +-(instancetype) initWithGeometryEnvelope: (SFGeometryEnvelope *) geometryEnvelope; + +/** + * Set the min x value + * + * @param x x coordinate + */ +-(void) setMinXValue: (double) x; + +/** + * Set the max x value + * + * @param x x coordinate + */ +-(void) setMaxXValue: (double) x; + +/** + * Set the min y value + * + * @param y y coordinate + */ +-(void) setMinYValue: (double) y; + +/** + * Set the max y value + * + * @param y y coordinate + */ +-(void) setMaxYValue: (double) y; + +/** + * Set the min z value + * + * @param z z coordinate + */ +-(void) setMinZValue: (double) z; + +/** + * Set the max z value + * + * @param z z coordinate + */ +-(void) setMaxZValue: (double) z; + +/** + * Set the min m value + * + * @param m m coordinate + */ +-(void) setMinMValue: (double) m; + +/** + * Set the max m value + * + * @param m m coordinate + */ +-(void) setMaxMValue: (double) m; + +/** + * True if has Z coordinates + * + * @return has z + */ +-(BOOL) is3D; + +/** + * True if has M measurements + * + * @return has m + */ +-(BOOL) isMeasured; + +/** + * Get the x range + * + * @return x range + */ +-(double) xRange; + +/** + * Get the y range + * + * @return y range + */ +-(double) yRange; + +/** + * Get the z range + * + * @return z range + */ +-(NSDecimalNumber *) zRange; + +/** + * Get the m range + * + * @return m range + */ +-(NSDecimalNumber *) mRange; + +/** + * Determine if the envelope is of a single point + * + * @return true if a single point bounds + */ +-(BOOL) isPoint; + +/** + * Get the top left point + * + * @return top left point + */ +-(SFPoint *) topLeft; + +/** + * Get the bottom left point + * + * @return bottom left point + */ +-(SFPoint *) bottomLeft; + +/** + * Get the bottom right point + * + * @return bottom right point + */ +-(SFPoint *) bottomRight; + +/** + * Get the top right point + * + * @return top right point + */ +-(SFPoint *) topRight; + +/** + * Get the left line + * + * @return left line + */ +-(SFLine *) left; + +/** + * Get the bottom line + * + * @return bottom line + */ +-(SFLine *) bottom; + +/** + * Get the right line + * + * @return right line + */ +-(SFLine *) right; + +/** + * Get the top line + * + * @return top line + */ +-(SFLine *) top; + +/** + * Get the envelope mid x + * + * @return mid x + */ +-(double) midX; + +/** + * Get the envelope mid y + * + * @return mid y + */ +-(double) midY; + +/** + * Get the envelope centroid point + * + * @return centroid point + */ +-(SFPoint *) centroid; + +/** + * Determine if the envelope is empty + * + * @return true if empty + */ +-(BOOL) isEmpty; + +/** + * Determine if intersects with the provided envelope + * + * @param envelope + * geometry envelope + * @return true if intersects + */ +-(BOOL) intersectsWithEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Determine if intersects with the provided envelope + * + * @param envelope + * geometry envelope + * @param allowEmpty + * allow empty ranges when determining intersection + * @return true if intersects + */ +-(BOOL) intersectsWithEnvelope: (SFGeometryEnvelope *) envelope withAllowEmpty: (BOOL) allowEmpty; + +/** + * Get the overlapping geometry envelope with the provided envelope + * + * @param envelope + * geometry envelope + * @return geometry envelope + */ +-(SFGeometryEnvelope *) overlapWithEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Get the overlapping geometry envelope with the provided envelope + * + * @param envelope + * geometry envelope + * @param allowEmpty + * allow empty ranges when determining overlap + * @return geometry envelope + */ +-(SFGeometryEnvelope *) overlapWithEnvelope: (SFGeometryEnvelope *) envelope withAllowEmpty: (BOOL) allowEmpty; + +/** + * Get the union geometry envelope combined with the provided envelope + * + * @param envelope + * geometry envelope + * @return geometry envelope + */ +-(SFGeometryEnvelope *) unionWithEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Determine if contains the point + * + * @param point + * point + * @return true if contains + */ +-(BOOL) containsPoint: (SFPoint *) point; + +/** + * Determine if contains the point + * + * @param point + * point + * @param epsilon + * epsilon equality tolerance + * @return true if contains + */ +-(BOOL) containsPoint: (SFPoint *) point withEpsilon: (double) epsilon; + +/** + * Determine if contains the coordinate + * + * @param x + * x value + * @param y + * y value + * @return true if contains + */ +-(BOOL) containsX: (double) x andY: (double) y; + +/** + * Determine if contains the coordinate + * + * @param x + * x value + * @param y + * y value + * @param epsilon + * epsilon equality tolerance + * @return true if contains + */ +-(BOOL) containsX: (double) x andY: (double) y withEpsilon: (double) epsilon; + +/** + * Determine if inclusively contains the provided envelope + * + * @param envelope + * geometry envelope + * @return true if contains + */ +-(BOOL) containsEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Determine if inclusively contains the provided envelope + * + * @param envelope + * geometry envelope + * @param epsilon + * epsilon equality tolerance + * @return true if contains + */ +-(BOOL) containsEnvelope: (SFGeometryEnvelope *) envelope withEpsilon: (double) epsilon; + +/** + * Build a geometry representation of the geometry envelope + * + * @return geometry, polygon or point + */ +-(SFGeometry *) buildGeometry; + +@end diff --git a/Pods/sf-ios/sf-ios/SFGeometryEnvelope.m b/Pods/sf-ios/sf-ios/SFGeometryEnvelope.m new file mode 100644 index 0000000..2b64bb9 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFGeometryEnvelope.m @@ -0,0 +1,491 @@ +// +// SFGeometryEnvelope.m +// sf-ios +// +// Created by Brian Osborn on 6/1/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometryEnvelope.h" +#import "SFLine.h" +#import "SFGeometryEnvelopeBuilder.h" + +@implementation SFGeometryEnvelope + ++(SFGeometryEnvelope *) envelope{ + return [[SFGeometryEnvelope alloc] init]; +} + ++(SFGeometryEnvelope *) envelopeWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFGeometryEnvelope alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFGeometryEnvelope *) envelopeWithMinX: (NSDecimalNumber *) minX + andMinY: (NSDecimalNumber *) minY + andMaxX: (NSDecimalNumber *) maxX + andMaxY: (NSDecimalNumber *) maxY{ + return [[SFGeometryEnvelope alloc] initWithMinX:minX andMinY:minY andMaxX:maxX andMaxY:maxY]; +} + ++(SFGeometryEnvelope *) envelopeWithMinXValue: (double) minX + andMinYValue: (double) minY + andMaxXValue: (double) maxX + andMaxYValue: (double) maxY{ + return [[SFGeometryEnvelope alloc] initWithMinXValue:minX andMinYValue:minY andMaxXValue:maxX andMaxYValue:maxY]; +} + ++(SFGeometryEnvelope *) envelopeWithMinX: (NSDecimalNumber *) minX + andMinY: (NSDecimalNumber *) minY + andMinZ: (NSDecimalNumber *) minZ + andMaxX: (NSDecimalNumber *) maxX + andMaxY: (NSDecimalNumber *) maxY + andMaxZ: (NSDecimalNumber *) maxZ{ + return [[SFGeometryEnvelope alloc] initWithMinX:minX andMinY:minY andMinZ:minZ andMaxX:maxX andMaxY:maxY andMaxZ:maxZ]; +} + ++(SFGeometryEnvelope *) envelopeWithMinXValue: (double) minX + andMinYValue: (double) minY + andMinZValue: (double) minZ + andMaxXValue: (double) maxX + andMaxYValue: (double) maxY + andMaxZValue: (double) maxZ{ + return [[SFGeometryEnvelope alloc] initWithMinXValue:minX andMinYValue:minY andMinZValue:minZ andMaxXValue:maxX andMaxYValue:maxY andMaxZValue:maxZ]; +} + ++(SFGeometryEnvelope *) envelopeWithMinX: (NSDecimalNumber *) minX + andMinY: (NSDecimalNumber *) minY + andMinZ: (NSDecimalNumber *) minZ + andMinM: (NSDecimalNumber *) minM + andMaxX: (NSDecimalNumber *) maxX + andMaxY: (NSDecimalNumber *) maxY + andMaxZ: (NSDecimalNumber *) maxZ + andMaxM: (NSDecimalNumber *) maxM{ + return [[SFGeometryEnvelope alloc] initWithMinX:minX andMinY:minY andMinZ:minZ andMinM:minM andMaxX:maxX andMaxY:maxY andMaxZ:maxZ andMaxM:maxM]; +} + ++(SFGeometryEnvelope *) envelopeWithMinXValue: (double) minX + andMinYValue: (double) minY + andMinZValue: (double) minZ + andMinMValue: (double) minM + andMaxXValue: (double) maxX + andMaxYValue: (double) maxY + andMaxZValue: (double) maxZ + andMaxMValue: (double) maxM{ + return [[SFGeometryEnvelope alloc] initWithMinXValue:minX andMinYValue:minY andMinZValue:minZ andMinMValue:minM andMaxXValue:maxX andMaxYValue:maxY andMaxZValue:maxZ andMaxMValue:maxM]; +} + ++(SFGeometryEnvelope *) geometryEnvelopeWithGeometryEnvelope: (SFGeometryEnvelope *) geometryEnvelope{ + return [[SFGeometryEnvelope alloc] initWithGeometryEnvelope:geometryEnvelope]; +} + +-(instancetype) init{ + return [self initWithHasZ:false andHasM:false]; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super init]; + if(self != nil){ + self.hasZ = hasZ; + self.hasM = hasM; + } + return self; +} + +-(instancetype) initWithMinX: (NSDecimalNumber *) minX + andMinY: (NSDecimalNumber *) minY + andMaxX: (NSDecimalNumber *) maxX + andMaxY: (NSDecimalNumber *) maxY{ + return [self initWithMinX:minX andMinY:minY andMinZ:nil andMinM:nil andMaxX:maxX andMaxY:maxY andMaxZ:nil andMaxM:nil]; +} + +-(instancetype) initWithMinXValue: (double) minX + andMinYValue: (double) minY + andMaxXValue: (double) maxX + andMaxYValue: (double) maxY{ + return [self initWithMinX:[[NSDecimalNumber alloc] initWithDouble:minX] + andMinY:[[NSDecimalNumber alloc] initWithDouble:minY] + andMaxX:[[NSDecimalNumber alloc] initWithDouble:maxX] + andMaxY:[[NSDecimalNumber alloc] initWithDouble:maxY]]; +} + +-(instancetype) initWithMinX: (NSDecimalNumber *) minX + andMinY: (NSDecimalNumber *) minY + andMinZ: (NSDecimalNumber *) minZ + andMaxX: (NSDecimalNumber *) maxX + andMaxY: (NSDecimalNumber *) maxY + andMaxZ: (NSDecimalNumber *) maxZ{ + return [self initWithMinX:minX andMinY:minY andMinZ:minZ andMinM:nil andMaxX:maxX andMaxY:maxY andMaxZ:maxZ andMaxM:nil]; +} + +-(instancetype) initWithMinXValue: (double) minX + andMinYValue: (double) minY + andMinZValue: (double) minZ + andMaxXValue: (double) maxX + andMaxYValue: (double) maxY + andMaxZValue: (double) maxZ{ + return [self initWithMinX:[[NSDecimalNumber alloc] initWithDouble:minX] + andMinY:[[NSDecimalNumber alloc] initWithDouble:minY] + andMinZ:[[NSDecimalNumber alloc] initWithDouble:minZ] + andMaxX:[[NSDecimalNumber alloc] initWithDouble:maxX] + andMaxY:[[NSDecimalNumber alloc] initWithDouble:maxY] + andMaxZ:[[NSDecimalNumber alloc] initWithDouble:maxZ]]; +} + +-(instancetype) initWithMinX: (NSDecimalNumber *) minX + andMinY: (NSDecimalNumber *) minY + andMinZ: (NSDecimalNumber *) minZ + andMinM: (NSDecimalNumber *) minM + andMaxX: (NSDecimalNumber *) maxX + andMaxY: (NSDecimalNumber *) maxY + andMaxZ: (NSDecimalNumber *) maxZ + andMaxM: (NSDecimalNumber *) maxM{ + self = [super init]; + if(self != nil){ + self.minX = minX; + self.minY = minY; + self.minZ = minZ; + self.minM = minM; + self.maxX = maxX; + self.maxY = maxY; + self.maxZ = maxZ; + self.maxM = maxM; + self.hasZ = minZ != nil || maxZ != nil; + self.hasM = minM != nil || maxM != nil; + } + return self; +} + +-(instancetype) initWithMinXValue: (double) minX + andMinYValue: (double) minY + andMinZValue: (double) minZ + andMinMValue: (double) minM + andMaxXValue: (double) maxX + andMaxYValue: (double) maxY + andMaxZValue: (double) maxZ + andMaxMValue: (double) maxM{ + return [self initWithMinX:[[NSDecimalNumber alloc] initWithDouble:minX] + andMinY:[[NSDecimalNumber alloc] initWithDouble:minY] + andMinZ:[[NSDecimalNumber alloc] initWithDouble:minZ] + andMinM:[[NSDecimalNumber alloc] initWithDouble:minM] + andMaxX:[[NSDecimalNumber alloc] initWithDouble:maxX] + andMaxY:[[NSDecimalNumber alloc] initWithDouble:maxY] + andMaxZ:[[NSDecimalNumber alloc] initWithDouble:maxZ] + andMaxM:[[NSDecimalNumber alloc] initWithDouble:maxM]]; +} + +-(instancetype) initWithGeometryEnvelope: (SFGeometryEnvelope *) geometryEnvelope{ + self = [self initWithMinX:geometryEnvelope.minX andMinY:geometryEnvelope.minY andMinZ:geometryEnvelope.minZ andMinM:geometryEnvelope.minM andMaxX:geometryEnvelope.maxX andMaxY:geometryEnvelope.maxY andMaxZ:geometryEnvelope.maxZ andMaxM:geometryEnvelope.maxM]; + return self; +} + +-(void) setMinXValue: (double) x{ + [self setMinX:[[NSDecimalNumber alloc] initWithDouble:x]]; +} + +-(void) setMaxXValue: (double) x{ + [self setMaxX:[[NSDecimalNumber alloc] initWithDouble:x]]; +} + +-(void) setMinYValue: (double) y{ + [self setMinY:[[NSDecimalNumber alloc] initWithDouble:y]]; +} + +-(void) setMaxYValue: (double) y{ + [self setMaxY:[[NSDecimalNumber alloc] initWithDouble:y]]; +} + +-(void) setMinZValue: (double) z{ + [self setMinZ:[[NSDecimalNumber alloc] initWithDouble:z]]; +} + +-(void) setMaxZValue: (double) z{ + [self setMaxZ:[[NSDecimalNumber alloc] initWithDouble:z]]; +} + +-(void) setMinMValue: (double) m{ + [self setMinM:[[NSDecimalNumber alloc] initWithDouble:m]]; +} + +-(void) setMaxMValue: (double) m{ + [self setMaxM:[[NSDecimalNumber alloc] initWithDouble:m]]; +} + +-(BOOL) is3D{ + return _hasZ; +} + +-(BOOL) isMeasured{ + return _hasM; +} + +-(double) xRange{ + return [_maxX doubleValue] - [_minX doubleValue]; +} + +-(double) yRange{ + return [_maxY doubleValue] - [_minY doubleValue]; +} + +-(NSDecimalNumber *) zRange{ + NSDecimalNumber *range = nil; + if(_minZ != nil && _maxZ != nil){ + range = [_maxZ decimalNumberBySubtracting:_minZ]; + } + return range; +} + +-(NSDecimalNumber *) mRange{ + NSDecimalNumber *range = nil; + if(_minM != nil && _maxM != nil){ + range = [_maxM decimalNumberBySubtracting:_minM]; + } + return range; +} + +-(BOOL) isPoint{ + return [_minX compare:_maxX] == NSOrderedSame && [_minY compare:_maxY] == NSOrderedSame; +} + +-(SFPoint *) topLeft{ + return [SFPoint pointWithX:_minX andY:_maxY]; +} + +-(SFPoint *) bottomLeft{ + return [SFPoint pointWithX:_minX andY:_minY]; +} + +-(SFPoint *) bottomRight{ + return [SFPoint pointWithX:_maxX andY:_minY]; +} + +-(SFPoint *) topRight{ + return [SFPoint pointWithX:_maxX andY:_maxY]; +} + +-(SFLine *) left{ + return [SFLine lineWithPoint1:[self topLeft] andPoint2:[self bottomLeft]]; +} + +-(SFLine *) bottom{ + return [SFLine lineWithPoint1:[self bottomLeft] andPoint2:[self bottomRight]]; +} + +-(SFLine *) right{ + return [SFLine lineWithPoint1:[self bottomRight] andPoint2:[self topRight]]; +} + +-(SFLine *) top{ + return [SFLine lineWithPoint1:[self topRight] andPoint2:[self topLeft]]; +} + +-(double) midX{ + return ([_minX doubleValue] + [_maxX doubleValue]) / 2.0; +} + +-(double) midY{ + return ([_minY doubleValue] + [_maxY doubleValue]) / 2.0; +} + +-(SFPoint *) centroid{ + return [SFPoint pointWithXValue:[self midX] andYValue:[self midY]]; +} + +-(BOOL) isEmpty{ + return [self xRange] <= 0.0 || [self yRange] <= 0.0; +} + +-(BOOL) intersectsWithEnvelope: (SFGeometryEnvelope *) envelope{ + return [self overlapWithEnvelope:envelope] != nil; +} + +-(BOOL) intersectsWithEnvelope: (SFGeometryEnvelope *) envelope withAllowEmpty: (BOOL) allowEmpty{ + return [self overlapWithEnvelope:envelope withAllowEmpty:allowEmpty] != nil; +} + +-(SFGeometryEnvelope *) overlapWithEnvelope: (SFGeometryEnvelope *) envelope{ + return [self overlapWithEnvelope:envelope withAllowEmpty:NO]; +} + +-(SFGeometryEnvelope *) overlapWithEnvelope: (SFGeometryEnvelope *) envelope withAllowEmpty: (BOOL) allowEmpty{ + + double minX = MAX([self.minX doubleValue], [envelope.minX doubleValue]); + double maxX = MIN([self.maxX doubleValue], [envelope.maxX doubleValue]); + double minY = MAX([self.minY doubleValue], [envelope.minY doubleValue]); + double maxY = MIN([self.maxY doubleValue], [envelope.maxY doubleValue]); + + SFGeometryEnvelope *overlap = nil; + + if((minX < maxX && minY < maxY) || (allowEmpty && minX <= maxX && minY <= maxY)){ + overlap = [SFGeometryEnvelope envelopeWithMinXValue:minX andMinYValue:minY andMaxXValue:maxX andMaxYValue:maxY]; + } + + return overlap; +} + +-(SFGeometryEnvelope *) unionWithEnvelope: (SFGeometryEnvelope *) envelope{ + + double minX = MIN([self.minX doubleValue], [envelope.minX doubleValue]); + double maxX = MAX([self.maxX doubleValue], [envelope.maxX doubleValue]); + double minY = MIN([self.minY doubleValue], [envelope.minY doubleValue]); + double maxY = MAX([self.maxY doubleValue], [envelope.maxY doubleValue]); + + SFGeometryEnvelope *unionEnvelope = nil; + + if(minX < maxX && minY < maxY){ + unionEnvelope = [SFGeometryEnvelope envelopeWithMinXValue:minX andMinYValue:minY andMaxXValue:maxX andMaxYValue:maxY]; + } + + return unionEnvelope; +} + +-(BOOL) containsPoint: (SFPoint *) point{ + return [self containsPoint:point withEpsilon:0.0]; +} + +-(BOOL) containsPoint: (SFPoint *) point withEpsilon: (double) epsilon{ + return [self containsX:[point.x doubleValue] andY:[point.y doubleValue] withEpsilon:epsilon]; +} + +-(BOOL) containsX: (double) x andY: (double) y{ + return [self containsX:x andY:y withEpsilon:0.0]; +} + +-(BOOL) containsX: (double) x andY: (double) y withEpsilon: (double) epsilon{ + return x >= [_minX doubleValue] - epsilon && x <= [_maxX doubleValue] + epsilon + && y >= [_minY doubleValue] - epsilon && y <= [_maxY doubleValue] + epsilon; +} + +-(BOOL) containsEnvelope: (SFGeometryEnvelope *) envelope{ + return [self containsEnvelope:envelope withEpsilon:0.0]; +} + +-(BOOL) containsEnvelope: (SFGeometryEnvelope *) envelope withEpsilon: (double) epsilon{ + return [_minX doubleValue] - epsilon <= [envelope.minX doubleValue] + && [_maxX doubleValue] + epsilon >= [envelope.maxX doubleValue] + && [_minY doubleValue] - epsilon <= [envelope.minY doubleValue] + && [_maxY doubleValue] + epsilon >= [envelope.maxY doubleValue]; +} + +-(SFGeometry *) buildGeometry{ + return [SFGeometryEnvelopeBuilder buildGeometryWithEnvelope:self]; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFGeometryEnvelope geometryEnvelopeWithGeometryEnvelope:self]; +} + ++ (BOOL) supportsSecureCoding { + return YES; +} + +- (void) encodeWithCoder:(NSCoder *)encoder { + [encoder encodeObject:self.minX forKey:@"minX"]; + [encoder encodeObject:self.maxX forKey:@"maxX"]; + [encoder encodeObject:self.minY forKey:@"minY"]; + [encoder encodeObject:self.maxY forKey:@"maxY"]; + [encoder encodeObject:self.minZ forKey:@"minZ"]; + [encoder encodeObject:self.maxZ forKey:@"maxZ"]; + [encoder encodeObject:self.minM forKey:@"minM"]; + [encoder encodeObject:self.maxM forKey:@"maxM"]; +} + +- (id) initWithCoder:(NSCoder *)decoder { + self = [super init]; + if (self) { + _minX = [decoder decodeObjectOfClass:[NSDecimalNumber class] forKey:@"minX"]; + _maxX = [decoder decodeObjectOfClass:[NSDecimalNumber class] forKey:@"maxX"]; + _minY = [decoder decodeObjectOfClass:[NSDecimalNumber class] forKey:@"minY"]; + _maxY = [decoder decodeObjectOfClass:[NSDecimalNumber class] forKey:@"maxY"]; + _minZ = [decoder decodeObjectOfClass:[NSDecimalNumber class] forKey:@"minZ"]; + _maxZ = [decoder decodeObjectOfClass:[NSDecimalNumber class] forKey:@"maxZ"]; + _minM = [decoder decodeObjectOfClass:[NSDecimalNumber class] forKey:@"minM"]; + _maxM = [decoder decodeObjectOfClass:[NSDecimalNumber class] forKey:@"maxM"]; + } + return self; +} + +- (BOOL)isEqualToGeometryEnvelope:(SFGeometryEnvelope *)geometryEnvelope { + if (self == geometryEnvelope) + return YES; + if (geometryEnvelope == nil) + return NO; + if(self.maxM == nil){ + if(geometryEnvelope.maxM != nil) + return NO; + }else if(![self.maxM isEqual:geometryEnvelope.maxM]){ + return NO; + } + if(self.maxX == nil){ + if(geometryEnvelope.maxX != nil) + return NO; + }else if(![self.maxX isEqual:geometryEnvelope.maxX]){ + return NO; + } + if(self.maxY == nil){ + if(geometryEnvelope.maxY != nil) + return NO; + }else if(![self.maxY isEqual:geometryEnvelope.maxY]){ + return NO; + } + if(self.maxZ == nil){ + if(geometryEnvelope.maxZ != nil) + return NO; + }else if(![self.maxZ isEqual:geometryEnvelope.maxZ]){ + return NO; + } + if(self.minM == nil){ + if(geometryEnvelope.minM != nil) + return NO; + }else if(![self.minM isEqual:geometryEnvelope.minM]){ + return NO; + } + if(self.minX == nil){ + if(geometryEnvelope.minX != nil) + return NO; + }else if(![self.minX isEqual:geometryEnvelope.minX]){ + return NO; + } + if(self.minY == nil){ + if(geometryEnvelope.minY != nil) + return NO; + }else if(![self.minY isEqual:geometryEnvelope.minY]){ + return NO; + } + if(self.minZ == nil){ + if(geometryEnvelope.minZ != nil) + return NO; + }else if(![self.minZ isEqual:geometryEnvelope.minZ]){ + return NO; + } + return YES; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[SFGeometryEnvelope class]]) { + return NO; + } + + return [self isEqualToGeometryEnvelope:(SFGeometryEnvelope *)object]; +} + +- (NSUInteger)hash { + NSUInteger prime = 31; + NSUInteger result = 1; + result = prime * result + (self.hasM ? 1231 : 1237); + result = prime * result + (self.hasZ ? 1231 : 1237); + result = prime * result + ((self.maxM == nil) ? 0 : [self.maxM hash]); + result = prime * result + ((self.maxX == nil) ? 0 : [self.maxX hash]); + result = prime * result + ((self.maxY == nil) ? 0 : [self.maxY hash]); + result = prime * result + ((self.maxZ == nil) ? 0 : [self.maxZ hash]); + result = prime * result + ((self.minM == nil) ? 0 : [self.minM hash]); + result = prime * result + ((self.minX == nil) ? 0 : [self.minX hash]); + result = prime * result + ((self.minY == nil) ? 0 : [self.minY hash]); + result = prime * result + ((self.minZ == nil) ? 0 : [self.minZ hash]); + return result; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFGeometryTypes.h b/Pods/sf-ios/sf-ios/SFGeometryTypes.h new file mode 100644 index 0000000..78fa499 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFGeometryTypes.h @@ -0,0 +1,79 @@ +// +// SFGeometryTypes.h +// sf-ios +// +// Created by Brian Osborn on 5/26/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import + +/** + * Geometry Type enumeration + */ +enum SFGeometryType{ + SF_GEOMETRY = 0, + SF_POINT, + SF_LINESTRING, + SF_POLYGON, + SF_MULTIPOINT, + SF_MULTILINESTRING, + SF_MULTIPOLYGON, + SF_GEOMETRYCOLLECTION, + SF_CIRCULARSTRING, + SF_COMPOUNDCURVE, + SF_CURVEPOLYGON, + SF_MULTICURVE, + SF_MULTISURFACE, + SF_CURVE, + SF_SURFACE, + SF_POLYHEDRALSURFACE, + SF_TIN, + SF_TRIANGLE, + SF_NONE +}; + +/** + * Geometry type names + */ +extern NSString * const SF_GEOMETRY_NAME; +extern NSString * const SF_POINT_NAME; +extern NSString * const SF_LINESTRING_NAME; +extern NSString * const SF_POLYGON_NAME; +extern NSString * const SF_MULTIPOINT_NAME; +extern NSString * const SF_MULTILINESTRING_NAME; +extern NSString * const SF_MULTIPOLYGON_NAME; +extern NSString * const SF_GEOMETRYCOLLECTION_NAME; +extern NSString * const SF_CIRCULARSTRING_NAME; +extern NSString * const SF_COMPOUNDCURVE_NAME; +extern NSString * const SF_CURVEPOLYGON_NAME; +extern NSString * const SF_MULTICURVE_NAME; +extern NSString * const SF_MULTISURFACE_NAME; +extern NSString * const SF_CURVE_NAME; +extern NSString * const SF_SURFACE_NAME; +extern NSString * const SF_POLYHEDRALSURFACE_NAME; +extern NSString * const SF_TIN_NAME; +extern NSString * const SF_TRIANGLE_NAME; +extern NSString * const SF_NONE_NAME; + +@interface SFGeometryTypes : NSObject + +/** + * Get the name of the geometry type + * + * @param geometryType geometry type enum + * + * @return geometry type name + */ ++(NSString *) name: (enum SFGeometryType) geometryType; + +/** + * Get the geometry type of the name + * + * @param name geometry type name + * + * @return geometry type + */ ++(enum SFGeometryType) fromName: (NSString *) name; + +@end diff --git a/Pods/sf-ios/sf-ios/SFGeometryTypes.m b/Pods/sf-ios/sf-ios/SFGeometryTypes.m new file mode 100644 index 0000000..febd691 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFGeometryTypes.m @@ -0,0 +1,135 @@ +// +// SFGeometryTypes.m +// sf-ios +// +// Created by Brian Osborn on 5/26/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometryTypes.h" + +NSString * const SF_GEOMETRY_NAME = @"GEOMETRY"; +NSString * const SF_POINT_NAME = @"POINT"; +NSString * const SF_LINESTRING_NAME = @"LINESTRING"; +NSString * const SF_POLYGON_NAME = @"POLYGON"; +NSString * const SF_MULTIPOINT_NAME = @"MULTIPOINT"; +NSString * const SF_MULTILINESTRING_NAME = @"MULTILINESTRING"; +NSString * const SF_MULTIPOLYGON_NAME = @"MULTIPOLYGON"; +NSString * const SF_GEOMETRYCOLLECTION_NAME = @"GEOMETRYCOLLECTION"; +NSString * const SF_CIRCULARSTRING_NAME = @"CIRCULARSTRING"; +NSString * const SF_COMPOUNDCURVE_NAME = @"COMPOUNDCURVE"; +NSString * const SF_CURVEPOLYGON_NAME = @"CURVEPOLYGON"; +NSString * const SF_MULTICURVE_NAME = @"MULTICURVE"; +NSString * const SF_MULTISURFACE_NAME = @"MULTISURFACE"; +NSString * const SF_CURVE_NAME = @"CURVE"; +NSString * const SF_SURFACE_NAME = @"SURFACE"; +NSString * const SF_POLYHEDRALSURFACE_NAME = @"POLYHEDRALSURFACE"; +NSString * const SF_TIN_NAME = @"TIN"; +NSString * const SF_TRIANGLE_NAME = @"TRIANGLE"; +NSString * const SF_NONE_NAME = @"NONE"; + +@implementation SFGeometryTypes + ++(NSString *) name: (enum SFGeometryType) geometryType{ + NSString *name = nil; + + switch(geometryType){ + case SF_GEOMETRY: + name = SF_GEOMETRY_NAME; + break; + case SF_POINT: + name = SF_POINT_NAME; + break; + case SF_LINESTRING: + name = SF_LINESTRING_NAME; + break; + case SF_POLYGON: + name = SF_POLYGON_NAME; + break; + case SF_MULTIPOINT: + name = SF_MULTIPOINT_NAME; + break; + case SF_MULTILINESTRING: + name = SF_MULTILINESTRING_NAME; + break; + case SF_MULTIPOLYGON: + name = SF_MULTIPOLYGON_NAME; + break; + case SF_GEOMETRYCOLLECTION: + name = SF_GEOMETRYCOLLECTION_NAME; + break; + case SF_CIRCULARSTRING: + name = SF_CIRCULARSTRING_NAME; + break; + case SF_COMPOUNDCURVE: + name = SF_COMPOUNDCURVE_NAME; + break; + case SF_CURVEPOLYGON: + name = SF_CURVEPOLYGON_NAME; + break; + case SF_MULTICURVE: + name = SF_MULTICURVE_NAME; + break; + case SF_MULTISURFACE: + name = SF_MULTISURFACE_NAME; + break; + case SF_CURVE: + name = SF_CURVE_NAME; + break; + case SF_SURFACE: + name = SF_SURFACE_NAME; + break; + case SF_POLYHEDRALSURFACE: + name = SF_POLYHEDRALSURFACE_NAME; + break; + case SF_TIN: + name = SF_TIN_NAME; + break; + case SF_TRIANGLE: + name = SF_TRIANGLE_NAME; + break; + case SF_NONE: + name = SF_NONE_NAME; + break; + } + + return name; +} + ++(enum SFGeometryType) fromName: (NSString *) name{ + enum SFGeometryType value = SF_NONE; + + if(name != nil){ + name = [name uppercaseString]; + NSDictionary *types = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInteger:SF_GEOMETRY], SF_GEOMETRY_NAME, + [NSNumber numberWithInteger:SF_POINT], SF_POINT_NAME, + [NSNumber numberWithInteger:SF_LINESTRING], SF_LINESTRING_NAME, + [NSNumber numberWithInteger:SF_POLYGON], SF_POLYGON_NAME, + [NSNumber numberWithInteger:SF_MULTIPOINT], SF_MULTIPOINT_NAME, + [NSNumber numberWithInteger:SF_MULTILINESTRING], SF_MULTILINESTRING_NAME, + [NSNumber numberWithInteger:SF_MULTIPOLYGON], SF_MULTIPOLYGON_NAME, + [NSNumber numberWithInteger:SF_GEOMETRYCOLLECTION], SF_GEOMETRYCOLLECTION_NAME, + [NSNumber numberWithInteger:SF_CIRCULARSTRING], SF_CIRCULARSTRING_NAME, + [NSNumber numberWithInteger:SF_COMPOUNDCURVE], SF_COMPOUNDCURVE_NAME, + [NSNumber numberWithInteger:SF_CURVEPOLYGON], SF_CURVEPOLYGON_NAME, + [NSNumber numberWithInteger:SF_MULTICURVE], SF_MULTICURVE_NAME, + [NSNumber numberWithInteger:SF_MULTISURFACE], SF_MULTISURFACE_NAME, + [NSNumber numberWithInteger:SF_CURVE], SF_CURVE_NAME, + [NSNumber numberWithInteger:SF_SURFACE], SF_SURFACE_NAME, + [NSNumber numberWithInteger:SF_POLYHEDRALSURFACE], SF_POLYHEDRALSURFACE_NAME, + [NSNumber numberWithInteger:SF_TIN], SF_TIN_NAME, + [NSNumber numberWithInteger:SF_TRIANGLE], SF_TRIANGLE_NAME, + [NSNumber numberWithInteger:SF_NONE], SF_NONE_NAME, + nil + ]; + NSNumber *enumValue = [types objectForKey:name]; + if(enumValue != nil){ + value = (enum SFGeometryType)[enumValue intValue]; + } + } + + return value; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFLine.h b/Pods/sf-ios/sf-ios/SFLine.h new file mode 100644 index 0000000..747c09a --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFLine.h @@ -0,0 +1,108 @@ +// +// SFLine.h +// sf-ios +// +// Created by Brian Osborn on 4/25/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFLineString.h" + +/** + * A LineString with exactly 2 Points. + */ +@interface SFLine : SFLineString + +/** + * Create + * + * @return new line + */ ++(SFLine *) line; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new line + */ ++(SFLine *) lineWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param points + * list of points + * + * @return new line + */ ++(SFLine *) lineWithPoints: (NSMutableArray *) points; + +/** + * Create + * + * @param point1 first point + * @param point2 second point + * + * @return new line + */ ++(SFLine *) lineWithPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2; + +/** + * Create + * + * @param line line + * + * @return new line + */ ++(SFLine *) lineWithLine: (SFLine *) line; + +/** + * Initialize + * + * @return new line + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new line + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param points + * list of points + * + * @return new line + */ +-(instancetype) initWithPoints: (NSMutableArray *) points; + +/** + * Initialize + * + * @param point1 first point + * @param point2 second point + * + * @return new line + */ +-(instancetype) initWithPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2; + +/** + * Initialize + * + * @param line line + * + * @return new line + */ +-(instancetype) initWithLine: (SFLine *) line; + +@end diff --git a/Pods/sf-ios/sf-ios/SFLine.m b/Pods/sf-ios/sf-ios/SFLine.m new file mode 100644 index 0000000..9f8226a --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFLine.m @@ -0,0 +1,81 @@ +// +// SFLine.m +// sf-ios +// +// Created by Brian Osborn on 4/25/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFLine.h" +#import "SFGeometryUtils.h" + +@implementation SFLine + ++(SFLine *) line{ + return [[SFLine alloc] init]; +} + ++(SFLine *) lineWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFLine alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFLine *) lineWithPoints: (NSMutableArray *) points{ + return [[SFLine alloc] initWithPoints:points]; +} + ++(SFLine *) lineWithPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2{ + return [[SFLine alloc] initWithPoint1:point1 andPoint2:point2]; +} + ++(SFLine *) lineWithLine: (SFLine *) line{ + return [[SFLine alloc] initWithLine:line]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [super initWithHasZ:hasZ andHasM:hasM]; +} + +-(instancetype) initWithPoints: (NSMutableArray *) points{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:points] andHasM:[SFGeometryUtils hasM:points]]; + if(self != nil){ + [self setPoints:points]; + } + return self; +} + +-(instancetype) initWithPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2{ + self = [self initWithHasZ:point1.hasZ || point2.hasZ andHasM:point1.hasM || point2.hasM]; + if(self != nil){ + [self addPoint:point1]; + [self addPoint:point2]; + } + return self; +} + +-(instancetype) initWithLine: (SFLine *) line{ + self = [self initWithHasZ:line.hasZ andHasM:line.hasM]; + if(self != nil){ + for(SFPoint *point in line.points){ + [self addPoint:[point mutableCopy]]; + } + } + return self; +} + +-(void) setPoints:(NSMutableArray *)points{ + [super setPoints:points]; + if(![self isEmpty] && [self numPoints] != 2){ + [NSException raise:@"Invalid Line" format:@"A line must have exactly 2 points."]; + } +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFLine lineWithLine:self]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFLineString.h b/Pods/sf-ios/sf-ios/SFLineString.h new file mode 100644 index 0000000..773d2fa --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFLineString.h @@ -0,0 +1,137 @@ +// +// SFLineString.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFCurve.h" + +/** + * A Curve that connects two or more points in space. + */ +@interface SFLineString : SFCurve + +/** + * Array of points + */ +@property (nonatomic, strong) NSMutableArray *points; + +/** + * Create + * + * @return new line string + */ ++(SFLineString *) lineString; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new line string + */ ++(SFLineString *) lineStringWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param points + * list of points + * + * @return new line string + */ ++(SFLineString *) lineStringWithPoints: (NSMutableArray *) points; + +/** + * Create + * + * @param lineString + * line string + * + * @return new line string + */ ++(SFLineString *) lineStringWithLineString: (SFLineString *) lineString; + +/** + * Initialize + * + * @return new line string + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new line string + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param points + * list of points + * + * @return new line string + */ +-(instancetype) initWithPoints: (NSMutableArray *) points; + +/** + * Initialize + * + * @param geometryType geometry type + * @param hasZ has z values + * @param hasM has m values + * + * @return new line string + */ +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param lineString + * line string + * + * @return new line string + */ +-(instancetype) initWithLineString: (SFLineString *) lineString; + +/** + * Add a point + * + * @param point point + */ +-(void) addPoint: (SFPoint *) point; + +/** + * Add points + * + * @param points + * points + */ +-(void) addPoints: (NSArray *) points; + +/** + * Get the number of points + * + * @return point count + */ +-(int) numPoints; + +/** + * Returns the Nth point + * + * @param n + * nth point to return + * @return point + */ +-(SFPoint *) pointAtIndex: (int) n; + +@end diff --git a/Pods/sf-ios/sf-ios/SFLineString.m b/Pods/sf-ios/sf-ios/SFLineString.m new file mode 100644 index 0000000..0028303 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFLineString.m @@ -0,0 +1,166 @@ +// +// SFLineString.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFLineString.h" +#import "SFShamosHoey.h" +#import "SFGeometryUtils.h" + +@implementation SFLineString + ++(SFLineString *) lineString{ + return [[SFLineString alloc] init]; +} + ++(SFLineString *) lineStringWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFLineString alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFLineString *) lineStringWithPoints: (NSMutableArray *) points{ + return [[SFLineString alloc] initWithPoints:points]; +} + ++(SFLineString *) lineStringWithLineString: (SFLineString *) lineString{ + return [[SFLineString alloc] initWithLineString:lineString]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [self initWithType:SF_LINESTRING andHasZ:hasZ andHasM:hasM]; +} + +-(instancetype) initWithPoints: (NSMutableArray *) points{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:points] andHasM:[SFGeometryUtils hasM:points]]; + if(self != nil){ + [self setPoints:points]; + } + return self; +} + +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:geometryType andHasZ:hasZ andHasM:hasM]; + if(self != nil){ + self.points = [NSMutableArray array]; + } + return self; +} + +-(instancetype) initWithLineString: (SFLineString *) lineString{ + self = [self initWithHasZ:lineString.hasZ andHasM:lineString.hasM]; + if(self != nil){ + for(SFPoint *point in lineString.points){ + [self addPoint:[point mutableCopy]]; + } + } + return self; +} + +-(void) addPoint: (SFPoint *) point{ + [self.points addObject:point]; + [self updateZM:point]; +} + +-(void) addPoints: (NSArray *) points{ + for(SFPoint *point in points){ + [self addPoint:point]; + } +} + +-(int) numPoints{ + return (int)self.points.count; +} + +-(SFPoint *) pointAtIndex: (int) n{ + return [self.points objectAtIndex:n]; +} + +-(SFPoint *) startPoint{ + SFPoint *startPoint = nil; + if (![self isEmpty]) { + startPoint = [self.points objectAtIndex:0]; + } + return startPoint; +} + +-(SFPoint *) endPoint{ + SFPoint *endPoint = nil; + if (![self isEmpty]) { + endPoint = [self.points objectAtIndex:self.points.count - 1]; + } + return endPoint; +} + +-(BOOL) isEmpty{ + return self.points.count == 0; +} + +-(BOOL) isSimple{ + return [SFShamosHoey simplePolygonPoints:self.points]; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFLineString lineStringWithLineString:self]; +} + ++ (BOOL) supportsSecureCoding { + return YES; +} + +- (void) encodeWithCoder:(NSCoder *)encoder { + [super encodeWithCoder:encoder]; + + [encoder encodeObject:self.points forKey:@"points"]; +} + +- (id) initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + _points = [decoder decodeObjectOfClasses:[NSSet setWithObjects:[NSMutableArray class], [SFPoint class], nil] forKey:@"points"]; + } + return self; +} + +- (BOOL)isEqualToLineString:(SFLineString *)lineString { + if (self == lineString) + return YES; + if (lineString == nil) + return NO; + if (![super isEqual:lineString]) + return NO; + if (self.points == nil) { + if (lineString.points != nil) + return NO; + } else if (![self.points isEqual:lineString.points]) + return NO; + return YES; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[SFLineString class]]) { + return NO; + } + + return [self isEqualToLineString:(SFLineString *)object]; +} + +- (NSUInteger)hash { + NSUInteger prime = 31; + NSUInteger result = [super hash]; + result = prime * result + + ((self.points == nil) ? 0 : [self.points hash]); + return result; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFLinearRing.h b/Pods/sf-ios/sf-ios/SFLinearRing.h new file mode 100644 index 0000000..eec2b47 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFLinearRing.h @@ -0,0 +1,90 @@ +// +// SFLinearRing.h +// sf-ios +// +// Created by Brian Osborn on 4/25/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFLineString.h" + +/** + * A LineString that is both closed and simple. + */ +@interface SFLinearRing : SFLineString + +/** + * Create + * + * @return new linear ring + */ ++(SFLinearRing *) linearRing; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new linear ring + */ ++(SFLinearRing *) linearRingWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param points + * list of points + * + * @return new linear ring + */ ++(SFLinearRing *) linearRingWithPoints: (NSMutableArray *) points; + +/** + * Create + * + * @param linearRing + * linear ring + * + * @return new linear ring + */ ++(SFLinearRing *) linearRingWithLinearRing: (SFLinearRing *) linearRing; + +/** + * Initialize + * + * @return new linear ring + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new linear ring + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param points + * list of points + * + * @return new linear ring + */ +-(instancetype) initWithPoints: (NSMutableArray *) points; + +/** + * Initialize + * + * @param linearRing + * linear ring + * + * @return new linear ring + */ +-(instancetype) initWithLinearRing: (SFLinearRing *) linearRing; + +@end diff --git a/Pods/sf-ios/sf-ios/SFLinearRing.m b/Pods/sf-ios/sf-ios/SFLinearRing.m new file mode 100644 index 0000000..b0fe4d4 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFLinearRing.m @@ -0,0 +1,73 @@ +// +// SFLinearRing.m +// sf-ios +// +// Created by Brian Osborn on 4/25/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFLinearRing.h" +#import "SFGeometryUtils.h" + +@implementation SFLinearRing + ++(SFLinearRing *) linearRing{ + return [[SFLinearRing alloc] init]; +} + ++(SFLinearRing *) linearRingWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFLinearRing alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFLinearRing *) linearRingWithPoints: (NSMutableArray *) points{ + return [[SFLinearRing alloc] initWithPoints:points]; +} + ++(SFLinearRing *) linearRingWithLinearRing: (SFLinearRing *) linearRing{ + return [[SFLinearRing alloc] initWithLinearRing:linearRing]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [super initWithHasZ:hasZ andHasM:hasM]; +} + +-(instancetype) initWithPoints: (NSMutableArray *) points{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:points] andHasM:[SFGeometryUtils hasM:points]]; + if(self != nil){ + [self setPoints:points]; + } + return self; +} + +-(instancetype) initWithLinearRing: (SFLinearRing *) linearRing{ + self = [self initWithHasZ:linearRing.hasZ andHasM:linearRing.hasM]; + if(self != nil){ + for(SFPoint *point in linearRing.points){ + [self addPoint:[point mutableCopy]]; + } + } + return self; +} + +-(void) setPoints:(NSMutableArray *)points{ + [super setPoints:points]; + if(![self isEmpty]){ + if(![self isClosed]){ + [self addPoint:[points objectAtIndex:0]]; + } + if([self numPoints] < 4){ + [NSException raise:@"Invalid Linear Ring" format:@"A closed linear ring must have at least four points."]; + } + } +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFLinearRing linearRingWithLinearRing:self]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFMultiCurve.h b/Pods/sf-ios/sf-ios/SFMultiCurve.h new file mode 100644 index 0000000..27aa16f --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFMultiCurve.h @@ -0,0 +1,82 @@ +// +// SFMultiCurve.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometryCollection.h" +#import "SFCurve.h" + +/** + * A restricted form of GeometryCollection where each Geometry in the collection + * must be of type Curve. + */ +@interface SFMultiCurve : SFGeometryCollection + +/** + * Initialize + * + * @param geometryType geometry type + * @param hasZ has z values + * @param hasM has m values + * + * @return new multi curve + */ +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Get the curves + * + * @return curves + */ +-(NSMutableArray *) curves; + +/** + * Set the curves + * + * @param curves curves + */ +-(void) setCurves: (NSMutableArray *) curves; + +/** + * Add a curve + * + * @param curve curve + */ +-(void) addCurve: (SFCurve *) curve; + +/** + * Add curves + * + * @param curves + * curves + */ +-(void) addCurves: (NSArray *) curves; + +/** + * Get the number of curves + * + * @return curve count + */ +-(int) numCurves; + +/** + * Returns the Nth curve + * + * @param n + * nth curve to return + * @return curve + */ +-(SFCurve *) curveAtIndex: (int) n; + +/** + * Determine if this Multi Curve is closed for each Curve (start point = end + * point) + * + * @return true if closed + */ +-(BOOL) isClosed; + +@end diff --git a/Pods/sf-ios/sf-ios/SFMultiCurve.m b/Pods/sf-ios/sf-ios/SFMultiCurve.m new file mode 100644 index 0000000..ab16908 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFMultiCurve.m @@ -0,0 +1,53 @@ +// +// SFMultiCurve.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFMultiCurve.h" + +@implementation SFMultiCurve + +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:geometryType andHasZ:hasZ andHasM:hasM]; + return self; +} + +-(NSMutableArray *) curves{ + return (NSMutableArray *)[self geometries]; +} + +-(void) setCurves: (NSMutableArray *) curves{ + [self setGeometries:(NSMutableArray *)curves]; +} + +-(void) addCurve: (SFCurve *) curve{ + [self addGeometry:curve]; +} + +-(void) addCurves: (NSArray *) curves{ + return [self addGeometries:curves]; +} + +-(int) numCurves{ + return [self numGeometries]; +} + +-(SFCurve *) curveAtIndex: (int) n{ + return (SFCurve *)[self geometryAtIndex:n]; +} + +-(BOOL) isClosed{ + BOOL closed = YES; + for (SFCurve *curve in self.geometries) { + if (![curve isClosed]) { + closed = NO; + break; + } + } + return closed; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFMultiLineString.h b/Pods/sf-ios/sf-ios/SFMultiLineString.h new file mode 100644 index 0000000..823094a --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFMultiLineString.h @@ -0,0 +1,157 @@ +// +// SFMultiLineString.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFMultiCurve.h" +#import "SFLineString.h" + +/** + * A restricted form of MultiCurve where each Curve in the collection must be of + * type LineString. + */ +@interface SFMultiLineString : SFMultiCurve + +/** + * Create + * + * @return new multi line string + */ ++(SFMultiLineString *) multiLineString; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new multi line string + */ ++(SFMultiLineString *) multiLineStringWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param lineStrings + * list of line strings + * + * @return new multi line string + */ ++(SFMultiLineString *) multiLineStringWithLineStrings: (NSMutableArray *) lineStrings; + +/** + * Create + * + * @param lineString + * line string + * + * @return new multi line string + */ ++(SFMultiLineString *) multiLineStringWithLineString: (SFLineString *) lineString; + +/** + * Create + * + * @param multiLineString + * multi line string + * + * @return new multi line string + */ ++(SFMultiLineString *) multiLineStringWithMultiLineString: (SFMultiLineString *) multiLineString; + +/** + * Initialize + * + * @return new multi line string + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new multi line string + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param lineStrings + * list of line strings + * + * @return new multi line string + */ +-(instancetype) initWithLineStrings: (NSMutableArray *) lineStrings; + +/** + * Initialize + * + * @param lineString + * line string + * + * @return new multi line string + */ +-(instancetype) initWithLineString: (SFLineString *) lineString; + +/** + * Initialize + * + * @param multiLineString + * multi line string + * + * @return new multi line string + */ +-(instancetype) initWithMultiLineString: (SFMultiLineString *) multiLineString; + +/** + * Get the line strings + * + * @return line strings + */ +-(NSMutableArray *) lineStrings; + +/** + * Set the line strings + * + * @param lineStrings line strings + */ +-(void) setLineStrings: (NSMutableArray *) lineStrings; + +/** + * Add a line string + * + * @param lineString line string + */ +-(void) addLineString: (SFLineString *) lineString; + +/** + * Add line strings + * + * @param lineStrings + * line strings + */ +-(void) addLineStrings: (NSArray *) lineStrings; + +/** + * Get the number of line strings + * + * @return line string count + */ +-(int) numLineStrings; + +/** + * Returns the Nth line string + * + * @param n + * nth line string to return + * @return line string + */ +-(SFLineString *) lineStringAtIndex: (int) n; + +@end diff --git a/Pods/sf-ios/sf-ios/SFMultiLineString.m b/Pods/sf-ios/sf-ios/SFMultiLineString.m new file mode 100644 index 0000000..f6b8937 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFMultiLineString.m @@ -0,0 +1,98 @@ +// +// SFMultiLineString.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFMultiLineString.h" +#import "SFGeometryUtils.h" + +@implementation SFMultiLineString + ++(SFMultiLineString *) multiLineString{ + return [[SFMultiLineString alloc] init]; +} + ++(SFMultiLineString *) multiLineStringWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFMultiLineString alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFMultiLineString *) multiLineStringWithLineStrings: (NSMutableArray *) lineStrings{ + return [[SFMultiLineString alloc] initWithLineStrings:lineStrings]; +} + ++(SFMultiLineString *) multiLineStringWithLineString: (SFLineString *) lineString{ + return [[SFMultiLineString alloc] initWithLineString:lineString]; +} + ++(SFMultiLineString *) multiLineStringWithMultiLineString: (SFMultiLineString *) multiLineString{ + return [[SFMultiLineString alloc] initWithMultiLineString:multiLineString]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:SF_MULTILINESTRING andHasZ:hasZ andHasM:hasM]; + return self; +} + +-(instancetype) initWithLineStrings: (NSMutableArray *) lineStrings{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:lineStrings] andHasM:[SFGeometryUtils hasM:lineStrings]]; + if(self != nil){ + [self setLineStrings:lineStrings]; + } + return self; +} + +-(instancetype) initWithLineString: (SFLineString *) lineString{ + self = [self initWithHasZ:lineString.hasZ andHasM:lineString.hasM]; + if(self != nil){ + [self addLineString:lineString]; + } + return self; +} + +-(instancetype) initWithMultiLineString: (SFMultiLineString *) multiLineString{ + self = [self initWithHasZ:multiLineString.hasZ andHasM:multiLineString.hasM]; + if(self != nil){ + for(SFLineString *lineString in multiLineString.geometries){ + [self addLineString:[lineString mutableCopy]]; + } + } + return self; +} + +-(NSMutableArray *) lineStrings{ + return (NSMutableArray *)[self curves]; +} + +-(void) setLineStrings: (NSMutableArray *) lineStrings{ + [self setCurves:(NSMutableArray *)lineStrings]; +} + +-(void) addLineString: (SFLineString *) lineString{ + [self addCurve:lineString]; +} + +-(void) addLineStrings: (NSArray *) lineStrings{ + [self addCurves:lineStrings]; +} + +-(int) numLineStrings{ + return [self numCurves]; +} + +-(SFLineString *) lineStringAtIndex: (int) n{ + return (SFLineString *)[self curveAtIndex:n]; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFMultiLineString multiLineStringWithMultiLineString:self]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFMultiPoint.h b/Pods/sf-ios/sf-ios/SFMultiPoint.h new file mode 100644 index 0000000..1315ebd --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFMultiPoint.h @@ -0,0 +1,156 @@ +// +// SFMultiPoint.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometryCollection.h" + +/** + * A restricted form of GeometryCollection where each Geometry in the collection + * must be of type Point. + */ +@interface SFMultiPoint : SFGeometryCollection + +/** + * Create + * + * @return new multi point + */ ++(SFMultiPoint *) multiPoint; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new multi point + */ ++(SFMultiPoint *) multiPointWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param points + * list of points + * + * @return new multi point + */ ++(SFMultiPoint *) multiPointWithPoints: (NSMutableArray *) points; + +/** + * Create + * + * @param point + * point + * + * @return new multi point + */ ++(SFMultiPoint *) multiPointWithPoint: (SFPoint *) point; + +/** + * Create + * + * @param multiPoint + * multi point + * + * @return new multi point + */ ++(SFMultiPoint *) multiPointWithMultiPoint: (SFMultiPoint *) multiPoint; + +/** + * Initialize + * + * @return new multi point + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new multi point + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param points + * list of points + * + * @return new multi point + */ +-(instancetype) initWithPoints: (NSMutableArray *) points; + +/** + * Initialize + * + * @param point + * point + * + * @return new multi point + */ +-(instancetype) initWithPoint: (SFPoint *) point; + +/** + * Initialize + * + * @param multiPoint + * multi point + * + * @return new multi point + */ +-(instancetype) initWithMultiPoint: (SFMultiPoint *) multiPoint; + +/** + * Get the points + * + * @return points + */ +-(NSMutableArray *) points; + +/** + * Set the points + * + * @param points points + */ +-(void) setPoints: (NSMutableArray *) points; + +/** + * Add a point + * + * @param point point + */ +-(void) addPoint: (SFPoint *) point; + +/** + * Add points + * + * @param points + * points + */ +-(void) addPoints: (NSArray *) points; + +/** + * Get the number of points + * + * @return point count + */ +-(int) numPoints; + +/** + * Returns the Nth point + * + * @param n + * nth point to return + * @return point + */ +-(SFPoint *) pointAtIndex: (int) n; + +@end diff --git a/Pods/sf-ios/sf-ios/SFMultiPoint.m b/Pods/sf-ios/sf-ios/SFMultiPoint.m new file mode 100644 index 0000000..7aa03f7 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFMultiPoint.m @@ -0,0 +1,103 @@ +// +// SFMultiPoint.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFMultiPoint.h" +#import "SFGeometryUtils.h" + +@implementation SFMultiPoint + ++(SFMultiPoint *) multiPoint{ + return [[SFMultiPoint alloc] init]; +} + ++(SFMultiPoint *) multiPointWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFMultiPoint alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFMultiPoint *) multiPointWithPoints: (NSMutableArray *) points{ + return [[SFMultiPoint alloc] initWithPoints:points]; +} + ++(SFMultiPoint *) multiPointWithPoint: (SFPoint *) point{ + return [[SFMultiPoint alloc] initWithPoint:point]; +} + ++(SFMultiPoint *) multiPointWithMultiPoint: (SFMultiPoint *) multiPoint{ + return [[SFMultiPoint alloc] initWithMultiPoint:multiPoint]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:SF_MULTIPOINT andHasZ:hasZ andHasM:hasM]; + return self; +} + +-(instancetype) initWithPoints: (NSMutableArray *) points{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:points] andHasM:[SFGeometryUtils hasM:points]]; + if(self != nil){ + [self setPoints:points]; + } + return self; +} + +-(instancetype) initWithPoint: (SFPoint *) point{ + self = [self initWithHasZ:point.hasZ andHasM:point.hasM]; + if(self != nil){ + [self addPoint:point]; + } + return self; +} + +-(instancetype) initWithMultiPoint: (SFMultiPoint *) multiPoint{ + self = [self initWithHasZ:multiPoint.hasZ andHasM:multiPoint.hasM]; + if(self != nil){ + for(SFPoint *point in multiPoint.geometries){ + [self addPoint:[point mutableCopy]]; + } + } + return self; +} + +-(NSMutableArray *) points{ + return (NSMutableArray *)[self geometries]; +} + +-(void) setPoints: (NSMutableArray *) points{ + [self setGeometries:(NSMutableArray *)points]; +} + +-(void) addPoint: (SFPoint *) point{ + [self addGeometry:point]; +} + +-(void) addPoints: (NSArray *) points{ + [self addGeometries:points]; +} + +-(int) numPoints{ + return [self numGeometries]; +} + +-(SFPoint *) pointAtIndex: (int) n{ + return (SFPoint *)[self geometryAtIndex:n]; +} + +-(BOOL) isSimple{ + NSSet *points = [NSSet setWithArray:[self points]]; + return points.count == [self numPoints]; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFMultiPoint multiPointWithMultiPoint:self]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFMultiPolygon.h b/Pods/sf-ios/sf-ios/SFMultiPolygon.h new file mode 100644 index 0000000..1607cc9 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFMultiPolygon.h @@ -0,0 +1,157 @@ +// +// SFMultiPolygon.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFMultiSurface.h" +#import "SFPolygon.h" + +/** + * A restricted form of MultiSurface where each Surface in the collection must + * be of type Polygon. + */ +@interface SFMultiPolygon : SFMultiSurface + +/** + * Create + * + * @return new multi polygon + */ ++(SFMultiPolygon *) multiPolygon; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new multi polygon + */ ++(SFMultiPolygon *) multiPolygonWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param polygons + * list of polygons + * + * @return new multi polygon + */ ++(SFMultiPolygon *) multiPolygonWithPolygons: (NSMutableArray *) polygons; + +/** + * Create + * + * @param polygon + * polygon + * + * @return new multi polygon + */ ++(SFMultiPolygon *) multiPolygonWithPolygon: (SFPolygon *) polygon; + +/** + * Create + * + * @param multiPolygon + * multi polygon + * + * @return new multi polygon + */ ++(SFMultiPolygon *) multiPolygonWithMultiPolygon: (SFMultiPolygon *) multiPolygon; + +/** + * Initialize + * + * @return new multi polygon + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new multi polygon + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param polygons + * list of polygons + * + * @return new multi polygon + */ +-(instancetype) initWithPolygons: (NSMutableArray *) polygons; + +/** + * Initialize + * + * @param polygon + * polygon + * + * @return new multi polygon + */ +-(instancetype) initWithPolygon: (SFPolygon *) polygon; + +/** + * Initialize + * + * @param multiPolygon + * multi polygon + * + * @return new multi polygon + */ +-(instancetype) initWithMultiPolygon: (SFMultiPolygon *) multiPolygon; + +/** + * Get the polygons + * + * @return polygons + */ +-(NSMutableArray *) polygons; + +/** + * Set the polygons + * + * @param polygons polygons + */ +-(void) setPolygons: (NSMutableArray *) polygons; + +/** + * Add a polygon + * + * @param polygon polygon + */ +-(void) addPolygon: (SFPolygon *) polygon; + +/** + * Add polygons + * + * @param polygons + * polygons + */ +-(void) addPolygons: (NSArray *) polygons; + +/** + * Get the number of polygons + * + * @return polygon count + */ +-(int) numPolygons; + +/** + * Returns the Nth polygon + * + * @param n + * nth polygon to return + * @return polygon + */ +-(SFPolygon *) polygonAtIndex: (int) n; + +@end diff --git a/Pods/sf-ios/sf-ios/SFMultiPolygon.m b/Pods/sf-ios/sf-ios/SFMultiPolygon.m new file mode 100644 index 0000000..6af1d51 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFMultiPolygon.m @@ -0,0 +1,98 @@ +// +// SFMultiPolygon.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFMultiPolygon.h" +#import "SFGeometryUtils.h" + +@implementation SFMultiPolygon + ++(SFMultiPolygon *) multiPolygon{ + return [[SFMultiPolygon alloc] init]; +} + ++(SFMultiPolygon *) multiPolygonWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFMultiPolygon alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFMultiPolygon *) multiPolygonWithPolygons: (NSMutableArray *) polygons{ + return [[SFMultiPolygon alloc] initWithPolygons:polygons]; +} + ++(SFMultiPolygon *) multiPolygonWithPolygon: (SFPolygon *) polygon{ + return [[SFMultiPolygon alloc] initWithPolygon:polygon]; +} + ++(SFMultiPolygon *) multiPolygonWithMultiPolygon: (SFMultiPolygon *) multiPolygon{ + return [[SFMultiPolygon alloc] initWithMultiPolygon:multiPolygon]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:SF_MULTIPOLYGON andHasZ:hasZ andHasM:hasM]; + return self; +} + +-(instancetype) initWithPolygons: (NSMutableArray *) polygons{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:polygons] andHasM:[SFGeometryUtils hasM:polygons]]; + if(self != nil){ + [self setPolygons:polygons]; + } + return self; +} + +-(instancetype) initWithPolygon: (SFPolygon *) polygon{ + self = [self initWithHasZ:polygon.hasZ andHasM:polygon.hasM]; + if(self != nil){ + [self addPolygon:polygon]; + } + return self; +} + +-(instancetype) initWithMultiPolygon: (SFMultiPolygon *) multiPolygon{ + self = [self initWithHasZ:multiPolygon.hasZ andHasM:multiPolygon.hasM]; + if(self != nil){ + for(SFPolygon *polygon in multiPolygon.geometries){ + [multiPolygon addPolygon:[polygon mutableCopy]]; + } + } + return self; +} + +-(NSMutableArray *) polygons{ + return (NSMutableArray *)[self surfaces]; +} + +-(void) setPolygons: (NSMutableArray *) polygons{ + [self setSurfaces:(NSMutableArray *)polygons]; +} + +-(void) addPolygon: (SFPolygon *) polygon{ + [self addSurface:polygon]; +} + +-(void) addPolygons: (NSArray *) polygons{ + [self addSurfaces:polygons]; +} + +-(int) numPolygons{ + return [self numSurfaces]; +} + +-(SFPolygon *) polygonAtIndex: (int) n{ + return (SFPolygon *)[self surfaceAtIndex:n]; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFMultiPolygon multiPolygonWithMultiPolygon:self]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFMultiSurface.h b/Pods/sf-ios/sf-ios/SFMultiSurface.h new file mode 100644 index 0000000..3173c10 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFMultiSurface.h @@ -0,0 +1,74 @@ +// +// SFMultiSurface.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometryCollection.h" +#import "SFSurface.h" + +/** + * A restricted form of GeometryCollection where each Geometry in the collection + * must be of type Surface. + */ +@interface SFMultiSurface : SFGeometryCollection + +/** + * Initialize + * + * @param geometryType geometry type + * @param hasZ has z values + * @param hasM has m values + * + * @return new multi surface + */ +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Get the surfaces + * + * @return surfaces + */ +-(NSMutableArray *) surfaces; + +/** + * Set the surfaces + * + * @param surfaces surfaces + */ +-(void) setSurfaces: (NSMutableArray *) surfaces; + +/** + * Add a surface + * + * @param surface surface + */ +-(void) addSurface: (SFSurface *) surface; + +/** + * Add surfaces + * + * @param surfaces + * surfaces + */ +-(void) addSurfaces: (NSArray *) surfaces; + +/** + * Get the number of surfaces + * + * @return surface count + */ +-(int) numSurfaces; + +/** + * Returns the Nth surface + * + * @param n + * nth surface to return + * @return surface + */ +-(SFSurface *) surfaceAtIndex: (int) n; + +@end diff --git a/Pods/sf-ios/sf-ios/SFMultiSurface.m b/Pods/sf-ios/sf-ios/SFMultiSurface.m new file mode 100644 index 0000000..86a01fc --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFMultiSurface.m @@ -0,0 +1,42 @@ +// +// SFMultiSurface.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFMultiSurface.h" + +@implementation SFMultiSurface + +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:geometryType andHasZ:hasZ andHasM:hasM]; + return self; +} + +-(NSMutableArray *) surfaces{ + return (NSMutableArray *)[self geometries]; +} + +-(void) setSurfaces: (NSMutableArray *) surfaces{ + [self setGeometries:(NSMutableArray *)surfaces]; +} + +-(void) addSurface: (SFSurface *) surface{ + [self addGeometry:surface]; +} + +-(void) addSurfaces: (NSArray *) surfaces{ + return [self addGeometries:surfaces]; +} + +-(int) numSurfaces{ + return [self numGeometries]; +} + +-(SFSurface *) surfaceAtIndex: (int) n{ + return (SFSurface *)[self geometryAtIndex:n]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFPoint.h b/Pods/sf-ios/sf-ios/SFPoint.h new file mode 100644 index 0000000..1bfb043 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFPoint.h @@ -0,0 +1,350 @@ +// +// SFPoint.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometry.h" + +/** + * A single location in space. Each point has an X and Y coordinate. A point MAY + * optionally also have a Z and/or an M value. + */ +@interface SFPoint : SFGeometry + +/** + * X coordinate + */ +@property (nonatomic, strong) NSDecimalNumber *x; + +/** + * Y coordinate + */ +@property (nonatomic, strong) NSDecimalNumber *y; + +/** + * Z coordinate + */ +@property (nonatomic, strong) NSDecimalNumber *z; + +/** + * M coordinate + */ +@property (nonatomic, strong) NSDecimalNumber *m; + +/** + * Create + * + * @return new point + */ ++(SFPoint *) point; + +/** + * Create + * + * @param x x coordinate + * @param y y coordinate + * + * @return new point + */ ++(SFPoint *) pointWithXValue: (double) x andYValue: (double) y; + +/** + * Create + * + * @param x x coordinate + * @param y y coordinate + * + * @return new point + */ ++(SFPoint *) pointWithX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y; + +/** + * Create + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * + * @return new point + */ ++(SFPoint *) pointWithX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y andZ: (NSDecimalNumber *) z; + +/** + * Create + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * + * @return new point + */ ++(SFPoint *) pointWithXValue: (double) x andYValue: (double) y andZ: (NSDecimalNumber *) z; + +/** + * Create + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * + * @return new point + */ ++(SFPoint *) pointWithXValue: (double) x andYValue: (double) y andZValue: (double) z; + +/** + * Create + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * @param m m coordinate + * + * @return new point + */ ++(SFPoint *) pointWithX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y andZ: (NSDecimalNumber *) z andM: (NSDecimalNumber *) m; + +/** + * Create + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * @param m m coordinate + * + * @return new point + */ ++(SFPoint *) pointWithXValue: (double) x andYValue: (double) y andZ: (NSDecimalNumber *) z andM: (NSDecimalNumber *) m; + +/** + * Create + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * @param m m coordinate + * + * @return new point + */ ++(SFPoint *) pointWithXValue: (double) x andYValue: (double) y andZValue: (double) z andMValue: (double) m; + +/** + * Create + * + * @param hasZ has z coordinate + * @param hasM has m coordinate + * @param x x coordinate + * @param y y coordinate + * + * @return new point + */ ++(SFPoint *) pointWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM andX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y; + +/** + * Create + * + * @param hasZ has z coordinate + * @param hasM has m coordinate + * @param x x coordinate + * @param y y coordinate + * + * @return new point + */ ++(SFPoint *) pointWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM andXValue: (double) x andYValue: (double) y; + +/** + * Create + * + * @param point point + * + * @return new point + */ ++(SFPoint *) pointWithPoint: (SFPoint *) point; + +/** + * Initialize + * + * @return new point + */ +-(instancetype) init; + +/** + * Initialize + * + * @param x x coordinate + * @param y y coordinate + * + * @return new point + */ +-(instancetype) initWithXValue: (double) x andYValue: (double) y; + +/** + * Initialize + * + * @param x x coordinate + * @param y y coordinate + * + * @return new point + */ +-(instancetype) initWithX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y; + +/** + * Initialize + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * + * @return new point + */ +-(instancetype) initWithX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y andZ: (NSDecimalNumber *) z; + +/** + * Initialize + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * + * @return new point + */ +-(instancetype) initWithXValue: (double) x andYValue: (double) y andZ: (NSDecimalNumber *) z; + +/** + * Initialize + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * + * @return new point + */ +-(instancetype) initWithXValue: (double) x andYValue: (double) y andZValue: (double) z; + +/** + * Initialize + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * @param m m coordinate + * + * @return new point + */ +-(instancetype) initWithX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y andZ: (NSDecimalNumber *) z andM: (NSDecimalNumber *) m; + +/** + * Initialize + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * @param m m coordinate + * + * @return new point + */ +-(instancetype) initWithXValue: (double) x andYValue: (double) y andZ: (NSDecimalNumber *) z andM: (NSDecimalNumber *) m; + +/** + * Initialize + * + * @param x x coordinate + * @param y y coordinate + * @param z z coordinate + * @param m m coordinate + * + * @return new point + */ +-(instancetype) initWithXValue: (double) x andYValue: (double) y andZValue: (double) z andMValue: (double) m; + +/** + * Initialize + * + * @param hasZ has z coordinate + * @param hasM has m coordinate + * @param x x coordinate + * @param y y coordinate + * + * @return new point + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM andX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y; + +/** + * Initialize + * + * @param hasZ has z coordinate + * @param hasM has m coordinate + * @param x x coordinate + * @param y y coordinate + * + * @return new point + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM andXValue: (double) x andYValue: (double) y; + +/** + * Initialize + * + * @param point point + * + * @return new point + */ +-(instancetype) initWithPoint: (SFPoint *) point; + +/** + * Set the x value + * + * @param x x coordinate + */ +-(void) setXValue: (double) x; + +/** + * Set the y value + * + * @param y y coordinate + */ +-(void) setYValue: (double) y; + +/** + * Set the z value + * + * @param z z coordinate + */ +-(void) setZValue: (double) z; + +/** + * Set the m value + * + * @param m m coordinate + */ +-(void) setMValue: (double) m; + +/** + * Indicates if x values are equal + * + * @param point + * point to compare + * @return true if x is equal + */ +-(BOOL) isEqualXToPoint: (SFPoint *) point; + +/** + * Indicates if y values are equal + * + * @param point + * point to compare + * @return true if y is equal + */ +-(BOOL) isEqualYToPoint: (SFPoint *) point; + +/** + * Indicates if x and y values are equal + * + * @param point + * point to compare + * @return true if x and y are equal + */ +-(BOOL) isEqualXYToPoint: (SFPoint *) point; + +@end diff --git a/Pods/sf-ios/sf-ios/SFPoint.m b/Pods/sf-ios/sf-ios/SFPoint.m new file mode 100644 index 0000000..b06310b --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFPoint.m @@ -0,0 +1,259 @@ +// +// SFPoint.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFPoint.h" + +@implementation SFPoint + ++(SFPoint *) point{ + return [[SFPoint alloc] init]; +} + ++(SFPoint *) pointWithXValue: (double) x andYValue: (double) y{ + return [[SFPoint alloc] initWithXValue:x andYValue:y]; +} + ++(SFPoint *) pointWithX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y{ + return [[SFPoint alloc] initWithX:x andY:y]; +} + ++(SFPoint *) pointWithX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y andZ: (NSDecimalNumber *) z{ + return [[SFPoint alloc] initWithX:x andY:y andZ:z]; +} + ++(SFPoint *) pointWithXValue: (double) x andYValue: (double) y andZ: (NSDecimalNumber *) z{ + return [[SFPoint alloc] initWithXValue:x andYValue:y andZ:z]; +} + ++(SFPoint *) pointWithXValue: (double) x andYValue: (double) y andZValue: (double) z{ + return [[SFPoint alloc] initWithXValue:x andYValue:y andZValue:z]; +} + ++(SFPoint *) pointWithX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y andZ: (NSDecimalNumber *) z andM: (NSDecimalNumber *) m{ + return [[SFPoint alloc] initWithX:x andY:y andZ:z andM:m]; +} + ++(SFPoint *) pointWithXValue: (double) x andYValue: (double) y andZ: (NSDecimalNumber *) z andM: (NSDecimalNumber *) m{ + return [[SFPoint alloc] initWithXValue:x andYValue:y andZ:z andM:m]; +} + ++(SFPoint *) pointWithXValue: (double) x andYValue: (double) y andZValue: (double) z andMValue: (double) m{ + return [[SFPoint alloc] initWithXValue:x andYValue:y andZValue:z andMValue:m]; +} + ++(SFPoint *) pointWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM andX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y{ + return [[SFPoint alloc] initWithHasZ:hasZ andHasM:hasM andX:x andY:y]; +} + ++(SFPoint *) pointWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM andXValue: (double) x andYValue: (double) y{ + return [[SFPoint alloc] initWithHasZ:hasZ andHasM:hasM andXValue:x andYValue:y]; +} + ++(SFPoint *) pointWithPoint: (SFPoint *) point{ + return [[SFPoint alloc] initWithPoint:point]; +} + +-(instancetype) init{ + return [self initWithXValue:0.0 andYValue:0.0]; +} + +-(instancetype) initWithXValue: (double) x andYValue: (double) y{ + return [self initWithX:[[NSDecimalNumber alloc] initWithDouble:x] andY:[[NSDecimalNumber alloc] initWithDouble:y]]; +} + +-(instancetype) initWithX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y{ + return [self initWithHasZ:false andHasM:false andX:x andY:y]; +} + +-(instancetype) initWithX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y andZ: (NSDecimalNumber *) z{ + return [self initWithX:x andY:y andZ:z andM:nil]; +} + +-(instancetype) initWithXValue: (double) x andYValue: (double) y andZ: (NSDecimalNumber *) z{ + return [self initWithXValue:x andYValue:y andZ:z andM:nil]; +} + +-(instancetype) initWithXValue: (double) x andYValue: (double) y andZValue: (double) z{ + return [self initWithXValue:x andYValue:y andZ:[[NSDecimalNumber alloc] initWithDouble:z]]; +} + +-(instancetype) initWithX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y andZ: (NSDecimalNumber *) z andM: (NSDecimalNumber *) m{ + self = [super initWithType:SF_POINT andHasZ:z != nil andHasM:m != nil]; + if(self != nil){ + self.x = x; + self.y = y; + self.z = z; + self.m = m; + } + return self; +} + +-(instancetype) initWithXValue: (double) x andYValue: (double) y andZ: (NSDecimalNumber *) z andM: (NSDecimalNumber *) m{ + return [self initWithX:[[NSDecimalNumber alloc] initWithDouble:x] andY:[[NSDecimalNumber alloc] initWithDouble:y] andZ:z andM:m]; +} + +-(instancetype) initWithXValue: (double) x andYValue: (double) y andZValue: (double) z andMValue: (double) m{ + return [self initWithXValue:x andYValue:y andZ:[[NSDecimalNumber alloc] initWithDouble:z] andM:[[NSDecimalNumber alloc] initWithDouble:m]]; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM andX: (NSDecimalNumber *) x andY: (NSDecimalNumber *) y{ + self = [super initWithType:SF_POINT andHasZ:hasZ andHasM:hasM]; + if(self != nil){ + self.x = x; + self.y = y; + } + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM andXValue: (double) x andYValue: (double) y{ + return [self initWithHasZ:hasZ andHasM:hasM andX:[[NSDecimalNumber alloc] initWithDouble:x] andY:[[NSDecimalNumber alloc] initWithDouble:y]]; +} + +-(instancetype) initWithPoint: (SFPoint *) point{ + self = [self initWithHasZ:point.hasZ andHasM:point.hasM andX:point.x andY:point.y]; + if(self != nil){ + _z = point.z; + _m = point.m; + } + return self; +} + +-(void) setZ: (NSDecimalNumber *) z{ + _z = z; + [self setHasZ:z != nil]; +} + +-(void) setM: (NSDecimalNumber *) m{ + _m = m; + [self setHasM:m != nil]; +} + +-(void) setXValue: (double) x{ + self.x = [[NSDecimalNumber alloc] initWithDouble:x]; +} + +-(void) setYValue: (double) y{ + self.y = [[NSDecimalNumber alloc] initWithDouble:y]; +} + +-(void) setZValue: (double) z{ + self.z = [[NSDecimalNumber alloc] initWithDouble:z]; +} + +-(void) setMValue: (double) m{ + self.m = [[NSDecimalNumber alloc] initWithDouble:m]; +} + +-(BOOL) isEqualXToPoint: (SFPoint *) point{ + BOOL equal; + if(self.x == nil){ + equal = point.x == nil; + }else{ + equal = [self.x isEqual:point.x]; + } + return equal; +} + +-(BOOL) isEqualYToPoint: (SFPoint *) point{ + BOOL equal; + if(self.y == nil){ + equal = point.y == nil; + }else{ + equal = [self.y isEqual:point.y]; + } + return equal; +} + +-(BOOL) isEqualXYToPoint: (SFPoint *) point{ + return [self isEqualXToPoint:point] && [self isEqualYToPoint:point]; +} + +-(BOOL) isEmpty{ + return NO; +} + +-(BOOL) isSimple{ + return YES; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFPoint pointWithPoint:self]; +} + ++ (BOOL) supportsSecureCoding { + return YES; +} + +- (void) encodeWithCoder:(NSCoder *)encoder { + [super encodeWithCoder:encoder]; + + [encoder encodeObject:self.x forKey:@"x"]; + [encoder encodeObject:self.y forKey:@"y"]; + [encoder encodeObject:self.z forKey:@"z"]; + [encoder encodeObject:self.m forKey:@"m"]; +} + +- (id) initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + _x = [decoder decodeObjectOfClass:[NSDecimalNumber class] forKey:@"x"]; + _y = [decoder decodeObjectOfClass:[NSDecimalNumber class] forKey:@"y"]; + _z = [decoder decodeObjectOfClass:[NSDecimalNumber class] forKey:@"z"]; + _m = [decoder decodeObjectOfClass:[NSDecimalNumber class] forKey:@"m"]; + } + return self; +} + +- (BOOL)isEqualToPoint:(SFPoint *)point { + if (self == point) + return YES; + if (point == nil) + return NO; + if (![super isEqual:point]) + return NO; + if(self.m == nil){ + if(point.m != nil) + return NO; + }else if(![self.m isEqual:point.m]){ + return NO; + } + if(![self isEqualXYToPoint:point]){ + return NO; + } + if(self.z == nil){ + if(point.z != nil) + return NO; + }else if(![self.z isEqual:point.z]){ + return NO; + } + return YES; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[SFPoint class]]) { + return NO; + } + + return [self isEqualToPoint:(SFPoint *)object]; +} + +- (NSUInteger)hash { + NSUInteger prime = 31; + NSUInteger result = [super hash]; + result = prime * result + ((self.m == nil) ? 0 : [self.m hash]); + result = prime * result + ((self.x == nil) ? 0 : [self.x hash]); + result = prime * result + ((self.y == nil) ? 0 : [self.y hash]); + result = prime * result + ((self.z == nil) ? 0 : [self.z hash]); + return result; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFPolygon.h b/Pods/sf-ios/sf-ios/SFPolygon.h new file mode 100644 index 0000000..c1a772d --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFPolygon.h @@ -0,0 +1,164 @@ +// +// SFPolygon.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFCurvePolygon.h" +#import "SFLineString.h" + +/** + * A restricted form of CurvePolygon where each ring is defined as a simple, + * closed LineString. + */ +@interface SFPolygon : SFCurvePolygon + +/** + * Create + * + * @return new polygon + */ ++(SFPolygon *) polygon; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new polygon + */ ++(SFPolygon *) polygonWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param rings + * list of rings + * + * @return new polygon + */ ++(SFPolygon *) polygonWithRings: (NSMutableArray *) rings; + +/** + * Create + * + * @param ring + * ring + * + * @return new polygon + */ ++(SFPolygon *) polygonWithRing: (SFLineString *) ring; + +/** + * Create + * + * @param polygon + * polygon + * + * @return new polygon + */ ++(SFPolygon *) polygonWithPolygon: (SFPolygon *) polygon; + +/** + * Initialize + * + * @return new polygon + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new polygon + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param rings + * list of rings + * + * @return new polygon + */ +-(instancetype) initWithRings: (NSMutableArray *) rings; + +/** + * Initialize + * + * @param ring + * ring + * + * @return new polygon + */ +-(instancetype) initWithRing: (SFLineString *) ring; + +/** + * Initialize + * + * @param geometryType geometry type + * @param hasZ has z values + * @param hasM has m values + * + * @return new polygon + */ +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param polygon + * polygon + * + * @return new polygon + */ +-(instancetype) initWithPolygon: (SFPolygon *) polygon; + +/** + * Get the line string rings + * + * @return line string rings + */ +-(NSMutableArray *) lineStrings; + +/** + * Set the line string rings + * + * @param rings + * line string rings + */ +-(void) setRings: (NSMutableArray *) rings; + +/** + * Returns the Nth ring where the exterior ring is at 0, interior rings + * begin at 1 + * + * @param n + * nth ring to return + * @return ring + */ +-(SFLineString *) ringAtIndex: (int) n; + +/** + * Get the exterior ring + * + * @return exterior ring + */ +-(SFLineString *) exteriorRing; + +/** + * Returns the Nth interior ring for this Polygon + * + * @param n + * interior ring number + * @return interior ring + */ +-(SFLineString *) interiorRingAtIndex: (int) n; + +@end diff --git a/Pods/sf-ios/sf-ios/SFPolygon.m b/Pods/sf-ios/sf-ios/SFPolygon.m new file mode 100644 index 0000000..6204d7b --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFPolygon.m @@ -0,0 +1,103 @@ +// +// SFPolygon.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFPolygon.h" +#import "SFShamosHoey.h" +#import "SFGeometryUtils.h" + +@implementation SFPolygon + ++(SFPolygon *) polygon{ + return [[SFPolygon alloc] init]; +} + ++(SFPolygon *) polygonWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFPolygon alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFPolygon *) polygonWithRings: (NSMutableArray *) rings{ + return [[SFPolygon alloc] initWithRings:rings]; +} + ++(SFPolygon *) polygonWithRing: (SFLineString *) ring{ + return [[SFPolygon alloc] initWithRing:ring]; +} + ++(SFPolygon *) polygonWithPolygon: (SFPolygon *) polygon{ + return [[SFPolygon alloc] initWithPolygon:polygon]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [self initWithType:SF_POLYGON andHasZ:hasZ andHasM:hasM]; +} + +-(instancetype) initWithRings: (NSMutableArray *) rings{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:rings] andHasM:[SFGeometryUtils hasM:rings]]; + if(self != nil){ + [self setRings:rings]; + } + return self; +} + +-(instancetype) initWithRing: (SFLineString *) ring{ + self = [self initWithHasZ:ring.hasZ andHasM:ring.hasM]; + if(self != nil){ + [self addRing:ring]; + } + return self; +} + +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:geometryType andHasZ:hasZ andHasM:hasM]; + return self; +} + +-(instancetype) initWithPolygon: (SFPolygon *) polygon{ + self = [self initWithHasZ:polygon.hasZ andHasM:polygon.hasM]; + if(self != nil){ + for(SFLineString *ring in polygon.rings){ + [self addRing:[ring mutableCopy]]; + } + } + return self; +} + +-(NSMutableArray *) lineStrings{ + return (NSMutableArray *) self.rings; +} + +-(void) setRings: (NSMutableArray *) rings{ + [super setRings:(NSMutableArray *)rings]; +} + +-(SFLineString *) ringAtIndex: (int) n{ + return (SFLineString *)[super ringAtIndex:n]; +} + +-(SFLineString *) exteriorRing{ + return (SFLineString *)[super exteriorRing]; +} + +-(SFLineString *) interiorRingAtIndex: (int) n{ + return (SFLineString *)[super interiorRingAtIndex:n]; +} + +-(BOOL) isSimple{ + return [SFShamosHoey simplePolygon:self]; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFPolygon polygonWithPolygon:self]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFPolyhedralSurface.h b/Pods/sf-ios/sf-ios/SFPolyhedralSurface.h new file mode 100644 index 0000000..0f94cae --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFPolyhedralSurface.h @@ -0,0 +1,205 @@ +// +// SFPolyhedralSurface.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFSurface.h" +#import "SFPolygon.h" + +/** + * Contiguous collection of polygons which share common boundary segments. + */ +@interface SFPolyhedralSurface : SFSurface + +/** + * Array of polygons + */ +@property (nonatomic, strong) NSMutableArray *polygons; + +/** + * Create + * + * @return new polyhedral surface + */ ++(SFPolyhedralSurface *) polyhedralSurface; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new polyhedral surface + */ ++(SFPolyhedralSurface *) polyhedralSurfaceWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param polygons + * list of polygons + * + * @return new polyhedral surface + */ ++(SFPolyhedralSurface *) polyhedralSurfaceWithPolygons: (NSMutableArray *) polygons; + +/** + * Create + * + * @param polygon + * polygon + * + * @return new polyhedral surface + */ ++(SFPolyhedralSurface *) polyhedralSurfaceWithPolygon: (SFPolygon *) polygon; + +/** + * Create + * + * @param polyhedralSurface + * polyhedral surface + * + * @return new polyhedral surface + */ ++(SFPolyhedralSurface *) polyhedralSurfaceWithPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface; + +/** + * Initialize + * + * @return new polyhedral surface + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new polyhedral surface + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param polygons + * list of polygons + * + * @return new polyhedral surface + */ +-(instancetype) initWithPolygons: (NSMutableArray *) polygons; + +/** + * Initialize + * + * @param polygon + * polygon + * + * @return new polyhedral surface + */ +-(instancetype) initWithPolygon: (SFPolygon *) polygon; + +/** + * Initialize + * + * @param geometryType geometry type + * @param hasZ has z values + * @param hasM has m values + * + * @return new polyhedral surface + */ +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param polyhedralSurface + * polyhedral surface + * + * @return new polyhedral surface + */ +-(instancetype) initWithPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface; + +/** + * Get patches + * + * @return patches + */ +-(NSMutableArray *) patches; + +/** + * Set patches + * + * @param patches + * patches + */ +-(void) setPatches: (NSMutableArray *) patches; + +/** + * Add a polygon + * + * @param polygon polygon + */ +-(void) addPolygon: (SFPolygon *) polygon; + +/** + * Add patch + * + * @param patch + * patch + */ +-(void) addPatch: (SFPolygon *) patch; + +/** + * Add polygons + * + * @param polygons + * polygons + */ +-(void) addPolygons: (NSArray *) polygons; + +/** + * Add patches + * + * @param patches + * patches + */ +-(void) addPatches: (NSArray *) patches; + +/** + * Get the number of polygons + * + * @return polygon count + */ +-(int) numPolygons; + +/** + * Get the number of patches + * + * @return patch count + */ +-(int) numPatches; + +/** + * Get the Nth polygon + * + * @param n + * nth polygon to return + * @return polygon + */ +-(SFPolygon *) polygonAtIndex: (int) n; + +/** + * Get the Nth polygon patch + * + * @param n + * nth polygon patch to return + * @return polygon patch + */ +-(SFPolygon *) patchAtIndex: (int) n; + +@end diff --git a/Pods/sf-ios/sf-ios/SFPolyhedralSurface.m b/Pods/sf-ios/sf-ios/SFPolyhedralSurface.m new file mode 100644 index 0000000..934ebe4 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFPolyhedralSurface.m @@ -0,0 +1,186 @@ +// +// SFPolyhedralSurface.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFPolyhedralSurface.h" +#import "SFGeometryUtils.h" + +@implementation SFPolyhedralSurface + ++(SFPolyhedralSurface *) polyhedralSurface{ + return [[SFPolyhedralSurface alloc] init]; +} + ++(SFPolyhedralSurface *) polyhedralSurfaceWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFPolyhedralSurface alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFPolyhedralSurface *) polyhedralSurfaceWithPolygons: (NSMutableArray *) polygons{ + return [[SFPolyhedralSurface alloc] initWithPolygons:polygons]; +} + ++(SFPolyhedralSurface *) polyhedralSurfaceWithPolygon: (SFPolygon *) polygon{ + return [[SFPolyhedralSurface alloc] initWithPolygon:polygon]; +} + ++(SFPolyhedralSurface *) polyhedralSurfaceWithPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface{ + return [[SFPolyhedralSurface alloc] initWithPolyhedralSurface:polyhedralSurface]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [self initWithType:SF_POLYHEDRALSURFACE andHasZ:hasZ andHasM:hasM]; +} + +-(instancetype) initWithPolygons: (NSMutableArray *) polygons{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:polygons] andHasM:[SFGeometryUtils hasM:polygons]]; + if(self != nil){ + [self setPolygons:polygons]; + } + return self; +} + +-(instancetype) initWithPolygon: (SFPolygon *) polygon{ + self = [self initWithHasZ:polygon.hasZ andHasM:polygon.hasM]; + if(self != nil){ + [self addPolygon:polygon]; + } + return self; +} + +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:geometryType andHasZ:hasZ andHasM:hasM]; + if(self != nil){ + self.polygons = [NSMutableArray array]; + } + return self; +} + +-(instancetype) initWithPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface{ + self = [self initWithHasZ:polyhedralSurface.hasZ andHasM:polyhedralSurface.hasM]; + if(self != nil){ + for(SFPolygon *polygon in polyhedralSurface.polygons){ + [self addPolygon:[polygon mutableCopy]]; + } + } + return self; +} + +-(NSMutableArray *) patches{ + return [self polygons]; +} + +-(void) setPatches: (NSMutableArray *) patches{ + [self setPolygons:patches]; +} + +-(void) addPolygon: (SFPolygon *) polygon{ + [self.polygons addObject:polygon]; + [self updateZM:polygon]; +} + +-(void) addPatch: (SFPolygon *) patch{ + [self addPolygon:patch]; +} + +-(void) addPolygons: (NSArray *) polygons{ + for(SFPolygon *polygon in polygons){ + [self addPolygon:polygon]; + } +} + +-(void) addPatches: (NSArray *) patches{ + [self addPolygons:patches]; +} + +-(int) numPolygons{ + return (int)self.polygons.count; +} + +-(int) numPatches{ + return [self numPolygons]; +} + +-(SFPolygon *) polygonAtIndex: (int) n{ + return [self.polygons objectAtIndex:n]; +} + +-(SFPolygon *) patchAtIndex: (int) n{ + return [self polygonAtIndex:n]; +} + +-(BOOL) isEmpty{ + return self.polygons.count == 0; +} + +-(BOOL) isSimple{ + [NSException raise:@"Unsupported" format:@"Is Simple not implemented for Polyhedral Surface"]; + return NO; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFPolyhedralSurface polyhedralSurfaceWithPolyhedralSurface:self]; +} + ++ (BOOL) supportsSecureCoding { + return YES; +} + +- (void) encodeWithCoder:(NSCoder *)encoder { + [super encodeWithCoder:encoder]; + + [encoder encodeObject:self.polygons forKey:@"polygons"]; +} + +- (id) initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + _polygons = [decoder decodeObjectOfClasses:[NSSet setWithObjects:[NSMutableArray class], [SFPolygon class], nil] forKey:@"polygons"]; + } + return self; +} + +- (BOOL)isEqualToPolyhedralSurface:(SFPolyhedralSurface *)polyhedralSurface { + if (self == polyhedralSurface) + return YES; + if (polyhedralSurface == nil) + return NO; + if (![super isEqual:polyhedralSurface]) + return NO; + if (self.polygons == nil) { + if (polyhedralSurface.polygons != nil) + return NO; + } else if (![self.polygons isEqual:polyhedralSurface.polygons]) + return NO; + return YES; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[SFPolyhedralSurface class]]) { + return NO; + } + + return [self isEqualToPolyhedralSurface:(SFPolyhedralSurface *)object]; +} + +- (NSUInteger)hash { + NSUInteger prime = 31; + NSUInteger result = [super hash]; + result = prime * result + + ((self.polygons == nil) ? 0 : [self.polygons hash]); + return result; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFSurface.h b/Pods/sf-ios/sf-ios/SFSurface.h new file mode 100644 index 0000000..1b53be2 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFSurface.h @@ -0,0 +1,28 @@ +// +// SFSurface.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometry.h" + +/** + * The base type for all 2-dimensional geometry types. A 2-dimensional geometry + * is a geometry that has an area. + */ +@interface SFSurface : SFGeometry + +/** + * Initialize + * + * @param geometryType geometry type + * @param hasZ has z values + * @param hasM has m values + * + * @return new surface + */ +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +@end diff --git a/Pods/sf-ios/sf-ios/SFSurface.m b/Pods/sf-ios/sf-ios/SFSurface.m new file mode 100644 index 0000000..6663d51 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFSurface.m @@ -0,0 +1,18 @@ +// +// SFSurface.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFSurface.h" + +@implementation SFSurface + +-(instancetype) initWithType: (enum SFGeometryType) geometryType andHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:geometryType andHasZ:hasZ andHasM:hasM]; + return self; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFTIN.h b/Pods/sf-ios/sf-ios/SFTIN.h new file mode 100644 index 0000000..56f11b7 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFTIN.h @@ -0,0 +1,111 @@ +// +// SFTIN.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFPolyhedralSurface.h" + +/** + * A tetrahedron (4 triangular faces), corner at the origin and each unit + * coordinate digit. + */ +@interface SFTIN : SFPolyhedralSurface + +/** + * Create + * + * @return new tin + */ ++(SFTIN *) tin; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new tin + */ ++(SFTIN *) tinWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param polygons + * list of polygons + * + * @return new tin + */ ++(SFTIN *) tinWithPolygons: (NSMutableArray *) polygons; + +/** + * Create + * + * @param polygon + * polygon + * + * @return new tin + */ ++(SFTIN *) tinWithPolygon: (SFPolygon *) polygon; + +/** + * Create + * + * @param tin + * tin + * + * @return new tin + */ ++(SFTIN *) tinWithTIN: (SFTIN *) tin; + +/** + * Initialize + * + * @return new tin + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new tin + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param polygons + * list of polygons + * + * @return new tin + */ +-(instancetype) initWithPolygons: (NSMutableArray *) polygons; + +/** + * Initialize + * + * @param polygon + * polygon + * + * @return new tin + */ +-(instancetype) initWithPolygon: (SFPolygon *) polygon; + +/** + * Initialize + * + * @param tin + * tin + * + * @return new tin + */ +-(instancetype) initWithTIN: (SFTIN *) tin; + +@end diff --git a/Pods/sf-ios/sf-ios/SFTIN.m b/Pods/sf-ios/sf-ios/SFTIN.m new file mode 100644 index 0000000..9abe6a7 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFTIN.m @@ -0,0 +1,74 @@ +// +// SFTIN.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFTIN.h" +#import "SFGeometryUtils.h" + +@implementation SFTIN + ++(SFTIN *) tin{ + return [[SFTIN alloc] init]; +} + ++(SFTIN *) tinWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFTIN alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFTIN *) tinWithPolygons: (NSMutableArray *) polygons{ + return [[SFTIN alloc] initWithPolygons:polygons]; +} + ++(SFTIN *) tinWithPolygon: (SFPolygon *) polygon{ + return [[SFTIN alloc] initWithPolygon:polygon]; +} + ++(SFTIN *) tinWithTIN: (SFTIN *) tin{ + return [[SFTIN alloc] initWithTIN:tin]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:SF_TIN andHasZ:hasZ andHasM:hasM]; + return self; +} + +-(instancetype) initWithPolygons: (NSMutableArray *) polygons{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:polygons] andHasM:[SFGeometryUtils hasM:polygons]]; + if(self != nil){ + [self setPolygons:polygons]; + } + return self; +} + +-(instancetype) initWithPolygon: (SFPolygon *) polygon{ + self = [self initWithHasZ:polygon.hasZ andHasM:polygon.hasM]; + if(self != nil){ + [self addPolygon:polygon]; + } + return self; +} + +-(instancetype) initWithTIN: (SFTIN *) tin{ + self = [self initWithHasZ:tin.hasZ andHasM:tin.hasM]; + if(self != nil){ + for(SFPolygon *polygon in tin.polygons){ + [self addPolygon:[polygon mutableCopy]]; + } + } + return self; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFTIN tinWithTIN:self]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/SFTriangle.h b/Pods/sf-ios/sf-ios/SFTriangle.h new file mode 100644 index 0000000..e0037b5 --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFTriangle.h @@ -0,0 +1,110 @@ +// +// SFTriangle.h +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFPolygon.h" + +/** + * Triangle + */ +@interface SFTriangle : SFPolygon + +/** + * Create + * + * @return new triangle + */ ++(SFTriangle *) triangle; + +/** + * Create + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new triangle + */ ++(SFTriangle *) triangleWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Create + * + * @param rings + * list of rings + * + * @return new triangle + */ ++(SFTriangle *) triangleWithRings: (NSMutableArray *) rings; + +/** + * Create + * + * @param ring + * ring + * + * @return new triangle + */ ++(SFTriangle *) triangleWithRing: (SFLineString *) ring; + +/** + * Create + * + * @param triangle + * triangle + * + * @return new triangle + */ ++(SFTriangle *) triangleWithTriangle: (SFTriangle *) triangle; + +/** + * Initialize + * + * @return new triangle + */ +-(instancetype) init; + +/** + * Initialize + * + * @param hasZ has z values + * @param hasM has m values + * + * @return new triangle + */ +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM; + +/** + * Initialize + * + * @param rings + * list of rings + * + * @return new triangle + */ +-(instancetype) initWithRings: (NSMutableArray *) rings; + +/** + * Initialize + * + * @param ring + * ring + * + * @return new triangle + */ +-(instancetype) initWithRing: (SFLineString *) ring; + +/** + * Initialize + * + * @param triangle + * triangle + * + * @return new triangle + */ +-(instancetype) initWithTriangle: (SFTriangle *) triangle; + +@end diff --git a/Pods/sf-ios/sf-ios/SFTriangle.m b/Pods/sf-ios/sf-ios/SFTriangle.m new file mode 100644 index 0000000..6d7ffda --- /dev/null +++ b/Pods/sf-ios/sf-ios/SFTriangle.m @@ -0,0 +1,74 @@ +// +// SFTriangle.m +// sf-ios +// +// Created by Brian Osborn on 6/2/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFTriangle.h" +#import "SFGeometryUtils.h" + +@implementation SFTriangle + ++(SFTriangle *) triangle{ + return [[SFTriangle alloc] init]; +} + ++(SFTriangle *) triangleWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + return [[SFTriangle alloc] initWithHasZ:hasZ andHasM:hasM]; +} + ++(SFTriangle *) triangleWithRings: (NSMutableArray *) rings{ + return [[SFTriangle alloc] initWithRings:rings]; +} + ++(SFTriangle *) triangleWithRing: (SFLineString *) ring{ + return [[SFTriangle alloc] initWithRing:ring]; +} + ++(SFTriangle *) triangleWithTriangle: (SFTriangle *) triangle{ + return [[SFTriangle alloc] initWithTriangle:triangle]; +} + +-(instancetype) init{ + self = [self initWithHasZ:false andHasM:false]; + return self; +} + +-(instancetype) initWithHasZ: (BOOL) hasZ andHasM: (BOOL) hasM{ + self = [super initWithType:SF_TRIANGLE andHasZ:hasZ andHasM:hasM]; + return self; +} + +-(instancetype) initWithRings: (NSMutableArray *) rings{ + self = [self initWithHasZ:[SFGeometryUtils hasZ:rings] andHasM:[SFGeometryUtils hasM:rings]]; + if(self != nil){ + [self setRings:rings]; + } + return self; +} + +-(instancetype) initWithRing: (SFLineString *) ring{ + self = [self initWithHasZ:ring.hasZ andHasM:ring.hasM]; + if(self != nil){ + [self addRing:ring]; + } + return self; +} + +-(instancetype) initWithTriangle: (SFTriangle *) triangle{ + self = [self initWithHasZ:triangle.hasZ andHasM:triangle.hasM]; + if(self != nil){ + for(SFLineString *ring in triangle.rings){ + [self addRing:[ring mutableCopy]]; + } + } + return self; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFTriangle triangleWithTriangle:self]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/extended/SFExtendedGeometryCollection.h b/Pods/sf-ios/sf-ios/extended/SFExtendedGeometryCollection.h new file mode 100644 index 0000000..2a40ea7 --- /dev/null +++ b/Pods/sf-ios/sf-ios/extended/SFExtendedGeometryCollection.h @@ -0,0 +1,62 @@ +// +// SFExtendedGeometryCollection.h +// sf-ios +// +// Created by Brian Osborn on 4/25/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFGeometryCollection.h" + +/** + * Extended Geometry Collection providing abstract geometry collection type + * support + */ +@interface SFExtendedGeometryCollection : SFGeometryCollection + +/** + * Create + * + * @param geometryCollection + * geometry collection + * + * @return new extended geometry collection + */ ++(SFExtendedGeometryCollection *) extendedGeometryCollectionWithGeometryCollection: (SFGeometryCollection *) geometryCollection; + +/** + * Create + * + * @param extendedGeometryCollection + * extended geometry collection + * + * @return new extended geometry collection + */ ++(SFExtendedGeometryCollection *) extendedGeometryCollectionWithExtendedGeometryCollection: (SFExtendedGeometryCollection *) extendedGeometryCollection; + +/** + * Initialize + * + * @param geometryCollection + * geometry collection + * + * @return new extended geometry collection + */ +-(instancetype) initWithGeometryCollection: (SFGeometryCollection *) geometryCollection; + +/** + * Initialize + * + * @param extendedGeometryCollection + * extended geometry collection + * + * @return new extended geometry collection + */ +-(instancetype) initWithExtendedGeometryCollection: (SFExtendedGeometryCollection *) extendedGeometryCollection; + +/** + * Update the extended geometry type based upon the contained geometries + */ +-(void) updateGeometryType; + +@end diff --git a/Pods/sf-ios/sf-ios/extended/SFExtendedGeometryCollection.m b/Pods/sf-ios/sf-ios/extended/SFExtendedGeometryCollection.m new file mode 100644 index 0000000..a0e2449 --- /dev/null +++ b/Pods/sf-ios/sf-ios/extended/SFExtendedGeometryCollection.m @@ -0,0 +1,128 @@ +// +// SFExtendedGeometryCollection.m +// sf-ios +// +// Created by Brian Osborn on 4/25/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFExtendedGeometryCollection.h" + +@interface SFExtendedGeometryCollection() + +/** + * Extended geometry collection geometry type + */ +@property (nonatomic) enum SFGeometryType extendedGeometryType; + +@end + +@implementation SFExtendedGeometryCollection + ++(SFExtendedGeometryCollection *) extendedGeometryCollectionWithGeometryCollection: (SFGeometryCollection *) geometryCollection{ + return [[SFExtendedGeometryCollection alloc] initWithGeometryCollection:geometryCollection]; +} + ++(SFExtendedGeometryCollection *) extendedGeometryCollectionWithExtendedGeometryCollection: (SFExtendedGeometryCollection *) extendedGeometryCollection{ + return [[SFExtendedGeometryCollection alloc] initWithExtendedGeometryCollection:extendedGeometryCollection]; +} + +-(instancetype) initWithGeometryCollection: (SFGeometryCollection *) geometryCollection{ + self = [super initWithType:SF_GEOMETRYCOLLECTION andHasZ:geometryCollection.hasZ andHasM:geometryCollection.hasM]; + if(self != nil){ + [self setGeometries:geometryCollection.geometries]; + self.extendedGeometryType = SF_GEOMETRYCOLLECTION; + [self updateGeometryType]; + } + return self; +} + +-(instancetype) initWithExtendedGeometryCollection: (SFExtendedGeometryCollection *) extendedGeometryCollection{ + SFGeometryCollection *geometryCollection = [SFGeometryCollection geometryCollectionWithHasZ:extendedGeometryCollection.hasZ andHasM:extendedGeometryCollection.hasM]; + for(SFGeometry *geometry in extendedGeometryCollection.geometries){ + [geometryCollection addGeometry:[geometry mutableCopy]]; + } + self = [self initWithGeometryCollection:geometryCollection]; + return self; +} + +-(void) updateGeometryType{ + enum SFGeometryType geometryType = [self collectionType]; + switch (geometryType) { + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + break; + case SF_MULTIPOINT: + geometryType = SF_GEOMETRYCOLLECTION; + break; + case SF_MULTILINESTRING: + geometryType = SF_MULTICURVE; + break; + case SF_MULTIPOLYGON: + geometryType = SF_MULTISURFACE; + break; + default: + [NSException raise:@"Unsupported" format:@"Unsupported extended geometry collection geometry type: %u", geometryType]; + } + self.extendedGeometryType = geometryType; +} + +-(enum SFGeometryType) geometryType{ + return self.extendedGeometryType; +} + +-(id) mutableCopyWithZone: (NSZone *) zone{ + return [SFExtendedGeometryCollection extendedGeometryCollectionWithExtendedGeometryCollection:self]; +} + ++ (BOOL) supportsSecureCoding { + return YES; +} + +- (void) encodeWithCoder:(NSCoder *)encoder { + [super encodeWithCoder:encoder]; + + [encoder encodeInt:(int)self.extendedGeometryType forKey:@"extendedGeometryType"]; +} + +- (id) initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (self) { + _extendedGeometryType = (enum SFGeometryType)[decoder decodeIntForKey:@"extendedGeometryType"]; + } + return self; +} + +- (BOOL)isEqualToExtendedGeometryCollection:(SFExtendedGeometryCollection *)extendedGeometryCollection { + if (self == extendedGeometryCollection) + return YES; + if (extendedGeometryCollection == nil) + return NO; + if (![super isEqual:extendedGeometryCollection]) + return NO; + if (self.extendedGeometryType != extendedGeometryCollection.extendedGeometryType) + return NO; + return YES; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[SFExtendedGeometryCollection class]]) { + return NO; + } + + return [self isEqualToExtendedGeometryCollection:(SFExtendedGeometryCollection *)object]; +} + +- (NSUInteger)hash { + NSUInteger prime = 31; + NSUInteger result = [super hash]; + result = prime * result + (int)self.extendedGeometryType; + return result; +} + +@end diff --git a/Pods/sf-ios/sf-ios/sf-ios-Bridging-Header.h b/Pods/sf-ios/sf-ios/sf-ios-Bridging-Header.h new file mode 100644 index 0000000..fccac76 --- /dev/null +++ b/Pods/sf-ios/sf-ios/sf-ios-Bridging-Header.h @@ -0,0 +1,57 @@ +// +// sf-ios-Bridging-Header.h +// sf-ios +// +// Created by Brian Osborn on 11/23/15. +// Copyright © 2015 NGA. All rights reserved. +// + +#ifndef sf_ios_Bridging_Header_h +#define sf_ios_Bridging_Header_h + +#import "sf_ios.h" +#import "SFCircularString.h" +#import "SFCompoundCurve.h" +#import "SFCurve.h" +#import "SFCurvePolygon.h" +#import "SFGeometry.h" +#import "SFGeometryCollection.h" +#import "SFGeometryEnvelope.h" +#import "SFGeometryTypes.h" +#import "SFLine.h" +#import "SFLinearRing.h" +#import "SFLineString.h" +#import "SFMultiCurve.h" +#import "SFMultiLineString.h" +#import "SFMultiPoint.h" +#import "SFMultiPolygon.h" +#import "SFMultiSurface.h" +#import "SFPoint.h" +#import "SFPolygon.h" +#import "SFPolyhedralSurface.h" +#import "SFSurface.h" +#import "SFTIN.h" +#import "SFTriangle.h" +#import "SFExtendedGeometryCollection.h" +#import "SFByteReader.h" +#import "SFByteWriter.h" +#import "SFGeometryEnvelopeBuilder.h" +#import "SFGeometryPrinter.h" +#import "SFGeometryUtils.h" +#import "SFCentroidPoint.h" +#import "SFCentroidCurve.h" +#import "SFCentroidSurface.h" +#import "SFEvent.h" +#import "SFEventQueue.h" +#import "SFEventTypes.h" +#import "SFSegment.h" +#import "SFShamosHoey.h" +#import "SFSweepLine.h" +#import "SFFiniteFilterTypes.h" +#import "SFGeometryFilter.h" +#import "SFPointFiniteFilter.h" +#import "SFTextReader.h" +#import "SFDegreesCentroid.h" +#import "SFGeometryConstants.h" + +#endif /* sf_ios_Bridging_Header_h */ diff --git a/Pods/sf-ios/sf-ios/sf_ios.h b/Pods/sf-ios/sf-ios/sf_ios.h new file mode 100644 index 0000000..a5643ed --- /dev/null +++ b/Pods/sf-ios/sf-ios/sf_ios.h @@ -0,0 +1,13 @@ +// +// sf-ios.h +// sf-ios +// +// Created by Brian Osborn on 9/1/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#ifndef sf_ios_sf_ios_h +#define sf_ios_sf_ios_h + + +#endif diff --git a/Pods/sf-ios/sf-ios/util/SFByteReader.h b/Pods/sf-ios/sf-ios/util/SFByteReader.h new file mode 100644 index 0000000..7e9fb9c --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFByteReader.h @@ -0,0 +1,94 @@ +// +// SFByteReader.h +// sf-ios +// +// Created by Brian Osborn on 5/28/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import + +/** + * Default read byte order + */ +static CFByteOrder DEFAULT_READ_BYTE_ORDER = CFByteOrderBigEndian; + +/** + * Read through byte data + */ +@interface SFByteReader : NSObject + +/** + * Next byte index to read + */ +@property int nextByte; + +/** + * Bytes to read + */ +@property (nonatomic, strong) NSData *bytes; + +/** + * Byte order used to read, little or big endian + */ +@property (nonatomic) CFByteOrder byteOrder; + +/** + * Initialize + * + * @param bytes byte data + * + * @return new byte reader + */ +-(instancetype) initWithData: (NSData *) bytes; + +/** + * Initialize + * + * @param bytes byte data + * @param byteOrder byte order + * + * @return new byte reader + */ +-(instancetype) initWithData: (NSData *) bytes andByteOrder: (CFByteOrder) byteOrder; + +/** + * Read a String from the provided number of bytes + * + * @param num number of bytes to read + * + * @return string value + */ +-(NSString *) readString: (int) num; + +/** + * Read a single byte + * + * @return byte + */ +-(NSNumber *) readByte; + +/** + * Read Data with the provided number of bytes + * + * @param num number of bytes to read + * + * @return data value + */ +-(NSData *) readData: (int) num; + +/** + * Read an integer (4 bytes) + * + * @return integer + */ +-(NSNumber *) readInt; + +/** + * Read a double (8 bytes) + * + * @return double + */ +-(NSDecimalNumber *) readDouble; + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFByteReader.m b/Pods/sf-ios/sf-ios/util/SFByteReader.m new file mode 100644 index 0000000..eb3b55c --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFByteReader.m @@ -0,0 +1,98 @@ +// +// SFByteReader.m +// sf-ios +// +// Created by Brian Osborn on 5/28/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFByteReader.h" + +@implementation SFByteReader + +-(instancetype) initWithData: (NSData *) bytes{ + self = [self initWithData:bytes andByteOrder:DEFAULT_READ_BYTE_ORDER]; + return self; +} + +-(instancetype) initWithData: (NSData *) bytes andByteOrder: (CFByteOrder) byteOrder{ + self = [super init]; + if(self != nil){ + self.bytes = bytes; + self.nextByte = 0; + self.byteOrder = byteOrder; + } + return self; +} + +-(NSString *) readString: (int) num{ + char *buffer = (char *)malloc(sizeof(char) * (num +1)); + int rangeStart = self.nextByte; + [self.bytes getBytes:buffer range:NSMakeRange(rangeStart, num)]; + buffer[num] = '\0'; + NSString *value = [NSString stringWithUTF8String:buffer]; + self.nextByte += num; + free(buffer); + return value; +} + +-(NSNumber *) readByte{ + char *buffer = (char *)malloc(sizeof(char)); + int rangeStart = self.nextByte; + [self.bytes getBytes:buffer range:NSMakeRange(rangeStart, 1)]; + uint8_t value = *(uint8_t*)buffer; + self.nextByte++; + free(buffer); + return [NSNumber numberWithInt:value]; +} + +-(NSData *) readData: (int) num{ + int rangeStart = self.nextByte; + NSData *data = [self.bytes subdataWithRange:NSMakeRange(rangeStart, num)]; + self.nextByte += num; + return data; +} + +-(NSNumber *) readInt{ + char *buffer = (char *)malloc(sizeof(char) * 4); + int rangeStart = self.nextByte; + [self.bytes getBytes:buffer range:NSMakeRange(rangeStart, 4)]; + + uint32_t result = *(uint32_t*)buffer; + + if(self.byteOrder == CFByteOrderBigEndian){ + result = CFSwapInt32BigToHost(result); + }else{ + result = CFSwapInt32LittleToHost(result); + } + + self.nextByte += 4; + free(buffer); + + return [NSNumber numberWithInt:result]; +} + +-(NSDecimalNumber *) readDouble{ + char *buffer = (char *)malloc(sizeof(char) * 8); + int rangeStart = self.nextByte; + [self.bytes getBytes:buffer range:NSMakeRange(rangeStart, 8)]; + + union DoubleSwap { + double v; + uint64_t sv; + } result; + result.sv = *(uint64_t*)buffer; + + if(self.byteOrder == CFByteOrderBigEndian){ + result.sv = CFSwapInt64BigToHost(result.sv); + }else{ + result.sv = CFSwapInt64LittleToHost(result.sv); + } + + self.nextByte += 8; + free(buffer); + + return [[NSDecimalNumber alloc] initWithDouble:result.v]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFByteWriter.h b/Pods/sf-ios/sf-ios/util/SFByteWriter.h new file mode 100644 index 0000000..5ca02bc --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFByteWriter.h @@ -0,0 +1,106 @@ +// +// SFByteWriter.h +// sf-ios +// +// Created by Brian Osborn on 5/28/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import + +/** + * Default write byte order + */ +static CFByteOrder DEFAULT_WRITE_BYTE_ORDER = CFByteOrderBigEndian; + +/** + * Write byte data + */ +@interface SFByteWriter : NSObject + +/** + * Next byte index to write + */ +@property int nextByte; + +/** + * Output stream to write bytes to + */ +@property (nonatomic, strong) NSOutputStream *os; + +/** + * Byte order used to write, little or big endian + */ +@property (nonatomic) CFByteOrder byteOrder; + +/** + * Initialize + * + * @return new byte writer + */ +-(instancetype) init; + +/** + * Initialize + * + * @param byteOrder byte order + * + * @return new byte writer + */ +-(instancetype) initWithByteOrder: (CFByteOrder) byteOrder; + +/** + * Close the byte writer + */ +-(void) close; + +/** + * Get the written byte data + * + * @return byte data + */ +-(NSData *) data; + +/** + * Get the current size in bytes written + * + * @return bytes written + */ +-(int) size; + +/** + * Write a string + * + * @param value string + */ +-(void) writeString: (NSString *) value; + +/** + * Write a byte + * + * @param value byte + */ +-(void) writeByte: (NSNumber *) value; + +/** + * Write data + * + * @param data data + */ +-(void) writeData: (NSData *) data; + +/** + * Write an integer + * + * @param value integer + */ +-(void) writeInt: (NSNumber *) value; + +/** + * Write a double + * + * @param value double + */ +-(void) writeDouble: (NSDecimalNumber *) value; + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFByteWriter.m b/Pods/sf-ios/sf-ios/util/SFByteWriter.m new file mode 100644 index 0000000..3075c14 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFByteWriter.m @@ -0,0 +1,93 @@ +// +// SFByteWriter.m +// sf-ios +// +// Created by Brian Osborn on 5/28/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFByteWriter.h" + +@implementation SFByteWriter + +-(instancetype) init{ + self = [self initWithByteOrder:DEFAULT_WRITE_BYTE_ORDER]; + return self; +} + +-(instancetype) initWithByteOrder: (CFByteOrder) byteOrder{ + self = [super init]; + if(self != nil){ + self.nextByte = 0; + self.os = [[NSOutputStream alloc] initToMemory]; + [self.os open]; + self.byteOrder = byteOrder; + } + return self; +} + +-(void) close{ + [self.os close]; +} + +-(NSData *) data{ + return [self.os propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; +} + +-(int) size{ + return self.nextByte; +} + +-(void) writeString: (NSString *) value{ + NSData *data = [[NSData alloc] initWithData:[value dataUsingEncoding:NSUTF8StringEncoding]]; + [self.os write:[data bytes] maxLength:[value length]]; + self.nextByte += (int)[value length]; +} + +-(void) writeByte: (NSNumber *) value{ + uint8_t byte = [value intValue]; + NSData *data = [NSData dataWithBytes:&byte length:1]; + [self.os write:[data bytes] maxLength:1]; + self.nextByte++; +} + +-(void) writeData: (NSData *) data{ + [self.os write:[data bytes] maxLength:data.length]; + self.nextByte += (int)data.length; +} + +-(void) writeInt: (NSNumber *) value{ + + uint32_t v = [value intValue]; + + if(self.byteOrder == CFByteOrderBigEndian){ + v = CFSwapInt32HostToBig(v); + }else{ + v = CFSwapInt32HostToLittle(v); + } + + NSData *data = [NSData dataWithBytes:&v length:4]; + [self.os write:[data bytes] maxLength:4]; + self.nextByte += 4; +} + +-(void) writeDouble: (NSDecimalNumber *) value{ + + union DoubleSwap { + double v; + uint64_t sv; + } result; + result.v = [value doubleValue]; + + if(self.byteOrder == CFByteOrderBigEndian){ + result.sv = CFSwapInt64HostToBig(result.sv); + }else{ + result.sv = CFSwapInt64HostToLittle(result.sv); + } + + NSData *data = [NSData dataWithBytes:&result.sv length:8]; + [self.os write:[data bytes] maxLength:8]; + self.nextByte += 8; +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFGeometryConstants.h b/Pods/sf-ios/sf-ios/util/SFGeometryConstants.h new file mode 100644 index 0000000..e5bb54c --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFGeometryConstants.h @@ -0,0 +1,83 @@ +// +// SFGeometryConstants.h +// sf-ios +// +// Created by Brian Osborn on 7/25/22. +// Copyright © 2022 NGA. All rights reserved. +// + +#import + +/** + * Default epsilon for point in or on line tolerance + */ +extern double const SF_DEFAULT_LINE_EPSILON; + +/** + * Default epsilon for point equality + */ +extern double const SF_DEFAULT_EQUAL_EPSILON; + +/** + * Web Mercator Latitude Range + */ +extern double const SF_WEB_MERCATOR_MAX_LAT_RANGE; + +/** + * Web Mercator Latitude Range + */ +extern double const SF_WEB_MERCATOR_MIN_LAT_RANGE; + +/** + * Half the world distance in either direction + */ +extern double const SF_WEB_MERCATOR_HALF_WORLD_WIDTH; + +/** + * Half the world longitude width for WGS84 + */ +extern double const SF_WGS84_HALF_WORLD_LON_WIDTH; + +/** + * Half the world latitude height for WGS84 + */ +extern double const SF_WGS84_HALF_WORLD_LAT_HEIGHT; + +/** + * Minimum latitude degrees value convertible to meters + */ +extern double const SF_DEGREES_TO_METERS_MIN_LAT; + +/** + * Absolute north bearing in degrees + */ +extern double const SF_BEARING_NORTH; + +/** + * Absolute east bearing in degrees + */ +extern double const SF_BEARING_EAST; + +/** + * Absolute south bearing in degrees + */ +extern double const SF_BEARING_SOUTH; + +/** + * Absolute west bearing degrees + */ +extern double const SF_BEARING_WEST; + +/** + * Radians to Degrees conversion + */ +extern double const SF_RADIANS_TO_DEGREES; + +/** + * Degrees to Radians conversion + */ +extern double const SF_DEGREES_TO_RADIANS; + +@interface SFGeometryConstants : NSObject + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFGeometryConstants.m b/Pods/sf-ios/sf-ios/util/SFGeometryConstants.m new file mode 100644 index 0000000..2bbd916 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFGeometryConstants.m @@ -0,0 +1,28 @@ +// +// SFGeometryConstants.m +// sf-ios +// +// Created by Brian Osborn on 7/25/22. +// Copyright © 2022 NGA. All rights reserved. +// + +#import "SFGeometryConstants.h" + +double const SF_DEFAULT_LINE_EPSILON = 0.000000000000001; +double const SF_DEFAULT_EQUAL_EPSILON = 0.00000001; +double const SF_WEB_MERCATOR_MAX_LAT_RANGE = 85.0511287798066; +double const SF_WEB_MERCATOR_MIN_LAT_RANGE = -85.05112877980659; +double const SF_WEB_MERCATOR_HALF_WORLD_WIDTH = 20037508.342789244; +double const SF_WGS84_HALF_WORLD_LON_WIDTH = 180.0; +double const SF_WGS84_HALF_WORLD_LAT_HEIGHT = 90.0; +double const SF_DEGREES_TO_METERS_MIN_LAT = -89.99999999999999; +double const SF_BEARING_NORTH = 0.0; +double const SF_BEARING_EAST = 90.0; +double const SF_BEARING_SOUTH = 180.0; +double const SF_BEARING_WEST = 270.0; +double const SF_RADIANS_TO_DEGREES = 180.0 / M_PI; +double const SF_DEGREES_TO_RADIANS = M_PI / 180.0; + +@implementation SFGeometryConstants + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFGeometryEnvelopeBuilder.h b/Pods/sf-ios/sf-ios/util/SFGeometryEnvelopeBuilder.h new file mode 100644 index 0000000..7261319 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFGeometryEnvelopeBuilder.h @@ -0,0 +1,43 @@ +// +// SFGeometryEnvelopeBuilder.h +// sf-ios +// +// Created by Brian Osborn on 6/1/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometryEnvelope.h" + +/** + * Builds an envelope from a Geometry + */ +@interface SFGeometryEnvelopeBuilder : NSObject + +/** + * Build geometry envelope with geometry + * + * @param geometry geometry to build envelope from + * + * @return geometry envelope + */ ++(SFGeometryEnvelope *) buildEnvelopeWithGeometry: (SFGeometry *) geometry; + +/** + * Expand existing geometry envelope with a geometry + * + * @param envelope geometry envelope to expand + * @param geometry geometry to build envelope from + */ ++(void) buildEnvelope: (SFGeometryEnvelope *) envelope andGeometry: (SFGeometry *) geometry; + +/** + * Build a geometry representation of the geometry envelope + * + * @param envelope + * geometry envelope + * + * @return geometry, polygon or point + */ ++(SFGeometry *) buildGeometryWithEnvelope: (SFGeometryEnvelope *) envelope; + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFGeometryEnvelopeBuilder.m b/Pods/sf-ios/sf-ios/util/SFGeometryEnvelopeBuilder.m new file mode 100644 index 0000000..3a1dd8d --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFGeometryEnvelopeBuilder.m @@ -0,0 +1,235 @@ +// +// SFGeometryEnvelopeBuilder.m +// sf-ios +// +// Created by Brian Osborn on 6/1/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometryEnvelopeBuilder.h" +#import "SFMultiPoint.h" +#import "SFMultiLineString.h" +#import "SFMultiPolygon.h" +#import "SFCircularString.h" +#import "SFCompoundCurve.h" +#import "SFTIN.h" +#import "SFTriangle.h" + +@implementation SFGeometryEnvelopeBuilder + ++(SFGeometryEnvelope *) buildEnvelopeWithGeometry: (SFGeometry *) geometry{ + + SFGeometryEnvelope *envelope = [SFGeometryEnvelope envelope]; + + [self buildEnvelope:envelope andGeometry:geometry]; + + if(envelope.minX == nil || envelope.maxX == nil + || envelope.minY == nil || envelope.maxY == nil){ + envelope = nil; + } + + return envelope; +} + ++(void) buildEnvelope: (SFGeometryEnvelope *) envelope andGeometry: (SFGeometry *) geometry{ + + enum SFGeometryType geometryType = geometry.geometryType; + switch (geometryType) { + case SF_POINT: + [self addPoint:(SFPoint *)geometry andEnvelope:envelope]; + break; + case SF_LINESTRING: + [self addLineString:(SFLineString *)geometry andEnvelope:envelope]; + break; + case SF_POLYGON: + [self addPolygon:(SFPolygon *)geometry andEnvelope:envelope]; + break; + case SF_MULTIPOINT: + [self addMultiPoint:(SFMultiPoint *)geometry andEnvelope:envelope]; + break; + case SF_MULTILINESTRING: + [self addMultiLineString:(SFMultiLineString *)geometry andEnvelope:envelope]; + break; + case SF_MULTIPOLYGON: + [self addMultiPolygon:(SFMultiPolygon *)geometry andEnvelope:envelope]; + break; + case SF_CIRCULARSTRING: + [self addLineString:(SFCircularString *)geometry andEnvelope:envelope]; + break; + case SF_COMPOUNDCURVE: + [self addCompoundCurve:(SFCompoundCurve *)geometry andEnvelope:envelope]; + break; + case SF_CURVEPOLYGON: + [self addCurvePolygon:(SFCurvePolygon *)geometry andEnvelope:envelope]; + break; + case SF_POLYHEDRALSURFACE: + [self addPolyhedralSurface:(SFPolyhedralSurface *)geometry andEnvelope:envelope]; + break; + case SF_TIN: + [self addPolyhedralSurface:(SFTIN *)geometry andEnvelope:envelope]; + break; + case SF_TRIANGLE: + [self addPolygon:(SFTriangle *)geometry andEnvelope:envelope]; + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + { + [self updateHasZandMWithEnvelope:envelope andGeometry:geometry]; + SFGeometryCollection *geomCollection = (SFGeometryCollection *) geometry; + for (SFGeometry *subGeometry in geomCollection.geometries) { + [self buildEnvelope:envelope andGeometry:subGeometry]; + } + } + break; + default: + break; + + } + +} + ++(void) updateHasZandMWithEnvelope: (SFGeometryEnvelope *) envelope andGeometry: (SFGeometry *) geometry{ + if(!envelope.hasZ && geometry.hasZ){ + [envelope setHasZ:true]; + } + if(!envelope.hasM && geometry.hasM){ + [envelope setHasM:true]; + } +} + ++(void) addPoint: (SFPoint *) point andEnvelope: (SFGeometryEnvelope *) envelope{ + + [self updateHasZandMWithEnvelope:envelope andGeometry:point]; + + NSDecimalNumber *x = point.x; + NSDecimalNumber *y = point.y; + if(envelope.minX == nil || [x compare:envelope.minX] == NSOrderedAscending){ + [envelope setMinX:x]; + } + if(envelope.maxX == nil || [x compare:envelope.maxX] == NSOrderedDescending){ + [envelope setMaxX:x]; + } + if(envelope.minY == nil || [y compare:envelope.minY] == NSOrderedAscending){ + [envelope setMinY:y]; + } + if(envelope.maxY == nil || [y compare:envelope.maxY] == NSOrderedDescending){ + [envelope setMaxY:y]; + } + if (point.hasZ) { + NSDecimalNumber *z = point.z; + if (z != nil) { + if (envelope.minZ == nil || [z compare:envelope.minZ] == NSOrderedAscending) { + [envelope setMinZ:z]; + } + if (envelope.maxZ == nil || [z compare:envelope.maxZ] == NSOrderedDescending) { + [envelope setMaxZ:z]; + } + } + } + if (point.hasM) { + NSDecimalNumber *m = point.m; + if (m != nil) { + if (envelope.minM == nil || [m compare:envelope.minM] == NSOrderedAscending) { + [envelope setMinM:m]; + } + if (envelope.maxM == nil || [m compare:envelope.maxM] == NSOrderedDescending) { + [envelope setMaxM:m]; + } + } + } +} + ++(void) addMultiPoint: (SFMultiPoint *) multiPoint andEnvelope: (SFGeometryEnvelope *) envelope{ + + [self updateHasZandMWithEnvelope:envelope andGeometry:multiPoint]; + + NSArray *points = [multiPoint points]; + for(SFPoint *point in points){ + [self addPoint:point andEnvelope:envelope]; + } +} + ++(void) addLineString: (SFLineString *) lineString andEnvelope: (SFGeometryEnvelope *) envelope{ + + [self updateHasZandMWithEnvelope:envelope andGeometry:lineString]; + + for(SFPoint *point in lineString.points){ + [self addPoint:point andEnvelope:envelope]; + } +} + ++(void) addMultiLineString: (SFMultiLineString *) multiLineString andEnvelope: (SFGeometryEnvelope *) envelope{ + + [self updateHasZandMWithEnvelope:envelope andGeometry:multiLineString]; + + NSArray *lineStrings = [multiLineString lineStrings]; + for(SFLineString *lineString in lineStrings){ + [self addLineString:lineString andEnvelope:envelope]; + } +} + ++(void) addPolygon: (SFPolygon *) polygon andEnvelope: (SFGeometryEnvelope *) envelope{ + + [self updateHasZandMWithEnvelope:envelope andGeometry:polygon]; + + for(SFLineString *ring in polygon.rings){ + [self addLineString:ring andEnvelope:envelope]; + } +} + ++(void) addMultiPolygon: (SFMultiPolygon *) multiPolygon andEnvelope: (SFGeometryEnvelope *) envelope{ + + [self updateHasZandMWithEnvelope:envelope andGeometry:multiPolygon]; + + NSArray *polygons = [multiPolygon polygons]; + for(SFPolygon *polygon in polygons){ + [self addPolygon:polygon andEnvelope:envelope]; + } +} + ++(void) addCompoundCurve: (SFCompoundCurve *) compoundCurve andEnvelope: (SFGeometryEnvelope *) envelope{ + + [self updateHasZandMWithEnvelope:envelope andGeometry:compoundCurve]; + + for(SFLineString *lineString in compoundCurve.lineStrings){ + [self addLineString:lineString andEnvelope:envelope]; + } +} + ++(void) addCurvePolygon: (SFCurvePolygon *) curvePolygon andEnvelope: (SFGeometryEnvelope *) envelope{ + + [self updateHasZandMWithEnvelope:envelope andGeometry:curvePolygon]; + + for(SFCurve *ring in curvePolygon.rings){ + [self buildEnvelope:envelope andGeometry:ring]; + } +} + ++(void) addPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface andEnvelope: (SFGeometryEnvelope *) envelope{ + + [self updateHasZandMWithEnvelope:envelope andGeometry:polyhedralSurface]; + + for(SFPolygon *polygon in polyhedralSurface.polygons){ + [self addPolygon:polygon andEnvelope:envelope]; + } +} + ++(SFGeometry *) buildGeometryWithEnvelope: (SFGeometryEnvelope *) envelope{ + SFGeometry *geometry = nil; + if([envelope isPoint]){ + geometry = [SFPoint pointWithX:envelope.minX andY:envelope.minY]; + }else{ + SFPolygon *polygon = [SFPolygon polygon]; + SFLineString *ring = [SFLineString lineString]; + [ring addPoint:[SFPoint pointWithX:envelope.minX andY:envelope.minY]]; + [ring addPoint:[SFPoint pointWithX:envelope.maxX andY:envelope.minY]]; + [ring addPoint:[SFPoint pointWithX:envelope.maxX andY:envelope.maxY]]; + [ring addPoint:[SFPoint pointWithX:envelope.minX andY:envelope.maxY]]; + [polygon addRing:ring]; + geometry = polygon; + } + return geometry; +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFGeometryPrinter.h b/Pods/sf-ios/sf-ios/util/SFGeometryPrinter.h new file mode 100644 index 0000000..92f4dc1 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFGeometryPrinter.h @@ -0,0 +1,25 @@ +// +// SFGeometryPrinter.h +// sf-ios +// +// Created by Brian Osborn on 6/1/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometry.h" + +/** + * String representation of a Geometry + */ +@interface SFGeometryPrinter : NSObject + +/** + * Get Geometry information as a String + * + * @param geometry geometry + * + * @return geometry string + */ ++(NSString *) geometryString: (SFGeometry *) geometry; + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFGeometryPrinter.m b/Pods/sf-ios/sf-ios/util/SFGeometryPrinter.m new file mode 100644 index 0000000..378b2f4 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFGeometryPrinter.m @@ -0,0 +1,185 @@ +// +// SFGeometryPrinter.m +// sf-ios +// +// Created by Brian Osborn on 6/1/15. +// Copyright (c) 2015 NGA. All rights reserved. +// + +#import "SFGeometryPrinter.h" +#import "SFMultiPoint.h" +#import "SFMultiLineString.h" +#import "SFMultiPolygon.h" +#import "SFCircularString.h" +#import "SFCompoundCurve.h" +#import "SFTIN.h" +#import "SFTriangle.h" + +@implementation SFGeometryPrinter + ++(NSString *) geometryString: (SFGeometry *) geometry{ + + NSMutableString *message = [NSMutableString string]; + + enum SFGeometryType geometryType = geometry.geometryType; + switch (geometryType) { + case SF_POINT: + [self addPoint:(SFPoint *)geometry toMessage:message]; + break; + case SF_LINESTRING: + [self addLineString:(SFLineString *)geometry toMessage:message]; + break; + case SF_POLYGON: + [self addPolygon:(SFPolygon *)geometry toMessage:message]; + break; + case SF_MULTIPOINT: + [self addMultiPoint:(SFMultiPoint *)geometry toMessage:message]; + break; + case SF_MULTILINESTRING: + [self addMultiLineString:(SFMultiLineString *)geometry toMessage:message]; + break; + case SF_MULTIPOLYGON: + [self addMultiPolygon:(SFMultiPolygon *)geometry toMessage:message]; + break; + case SF_CIRCULARSTRING: + [self addLineString:(SFCircularString *)geometry toMessage:message]; + break; + case SF_COMPOUNDCURVE: + [self addCompoundCurve:(SFCompoundCurve *)geometry toMessage:message]; + break; + case SF_CURVEPOLYGON: + [self addCurvePolygon:(SFCurvePolygon *)geometry toMessage:message]; + break; + case SF_POLYHEDRALSURFACE: + [self addPolyhedralSurface:(SFPolyhedralSurface *)geometry toMessage:message]; + break; + case SF_TIN: + [self addPolyhedralSurface:(SFTIN *)geometry toMessage:message]; + break; + case SF_TRIANGLE: + [self addPolygon:(SFTriangle *)geometry toMessage:message]; + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + { + SFGeometryCollection *geomCollection = (SFGeometryCollection *) geometry; + [message appendFormat:@"Geometries: %d", [geomCollection numGeometries]]; + NSArray *geometries = geomCollection.geometries; + for(int i = 0; i < geometries.count; i++){ + SFGeometry *subGeometry = [geometries objectAtIndex:i]; + [message appendString:@"\n\n"]; + [message appendFormat:@"Geometry %d", (i+1)]; + [message appendString:@"\n"]; + [message appendFormat:@"%@", [SFGeometryTypes name:subGeometry.geometryType]]; + [message appendString:@"\n"]; + [message appendString:[self geometryString:subGeometry]]; + } + } + break; + default: + break; + + } + + return message; +} + ++(void) addPoint: (SFPoint *) point toMessage: (NSMutableString *) message{ + [message appendFormat:@"Latitude: %@", point.y]; + [message appendFormat:@"\nLongitude: %@", point.x]; +} + ++(void) addMultiPoint: (SFMultiPoint *) multiPoint toMessage: (NSMutableString *) message{ + [message appendFormat:@"Points: %d", [multiPoint numPoints]]; + NSArray *points = [multiPoint points]; + for(int i = 0; i < points.count; i++){ + SFPoint *point = [points objectAtIndex:i]; + [message appendString:@"\n\n"]; + [message appendFormat:@"Point %d", (i+1)]; + [message appendString:@"\n"]; + [self addPoint:point toMessage:message]; + } +} + ++(void) addLineString: (SFLineString *) lineString toMessage: (NSMutableString *) message{ + [message appendFormat:@"Points: %d", [lineString numPoints]]; + for(SFPoint *point in lineString.points){ + [message appendString:@"\n\n"]; + [self addPoint:point toMessage:message]; + } +} + ++(void) addMultiLineString: (SFMultiLineString *) multiLineString toMessage: (NSMutableString *) message{ + [message appendFormat:@"LineStrings: %d", [multiLineString numLineStrings]]; + NSArray *lineStrings = [multiLineString lineStrings]; + for(int i = 0; i < lineStrings.count; i++){ + SFLineString *lineString = [lineStrings objectAtIndex:i]; + [message appendString:@"\n\n"]; + [message appendFormat:@"LineString %d", (i+1)]; + [message appendString:@"\n"]; + [self addLineString:lineString toMessage:message]; + } +} + ++(void) addPolygon: (SFPolygon *) polygon toMessage: (NSMutableString *) message{ + [message appendFormat:@"Rings: %d", [polygon numRings]]; + for(int i = 0; i < polygon.rings.count; i++){ + SFLineString *ring = [polygon ringAtIndex:i]; + [message appendString:@"\n\n"]; + if(i > 0){ + [message appendFormat:@"Hole %d", i]; + [message appendString:@"\n"]; + } + [self addLineString:ring toMessage:message]; + } +} + ++(void) addMultiPolygon: (SFMultiPolygon *) multiPolygon toMessage: (NSMutableString *) message{ + [message appendFormat:@"Polygons: %d", [multiPolygon numPolygons]]; + NSArray *polygons = [multiPolygon polygons]; + for(int i = 0; i < polygons.count; i++){ + SFPolygon *polygon = [polygons objectAtIndex:i]; + [message appendString:@"\n\n"]; + [message appendFormat:@"Polygon %d", (i+1)]; + [message appendString:@"\n"]; + [self addPolygon:polygon toMessage:message]; + } +} + ++(void) addCompoundCurve: (SFCompoundCurve *) compoundCurve toMessage: (NSMutableString *) message{ + [message appendFormat:@"LineStrings: %d", [compoundCurve numLineStrings]]; + for(int i = 0; i < compoundCurve.lineStrings.count; i++){ + SFLineString *lineString = [compoundCurve.lineStrings objectAtIndex:i]; + [message appendString:@"\n\n"]; + [message appendFormat:@"LineString %d", (i+1)]; + [message appendString:@"\n"]; + [self addLineString:lineString toMessage:message]; + } +} + ++(void) addCurvePolygon: (SFCurvePolygon *) curvePolygon toMessage: (NSMutableString *) message{ + [message appendFormat:@"Rings: %d", [curvePolygon numRings]]; + for(int i = 0; i < curvePolygon.rings.count; i++){ + SFCurve *ring = [curvePolygon.rings objectAtIndex:i]; + [message appendString:@"\n\n"]; + if(i > 0){ + [message appendFormat:@"Hole %d", i]; + [message appendString:@"\n"]; + } + [message appendString:[self geometryString:ring]]; + } +} + ++(void) addPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface toMessage: (NSMutableString *) message{ + [message appendFormat:@"Polygons: %d", [polyhedralSurface numPolygons]]; + for(int i = 0; i < polyhedralSurface.polygons.count; i++){ + SFPolygon *polygon = [polyhedralSurface.polygons objectAtIndex:i]; + [message appendString:@"\n\n"]; + [message appendFormat:@"Polygon %d", (i+1)]; + [message appendString:@"\n"]; + [self addPolygon:polygon toMessage:message]; + } +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFGeometryUtils.h b/Pods/sf-ios/sf-ios/util/SFGeometryUtils.h new file mode 100644 index 0000000..b185467 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFGeometryUtils.h @@ -0,0 +1,1229 @@ +// +// SFGeometryUtils.h +// sf-ios +// +// Created by Brian Osborn on 4/14/17. +// Copyright © 2017 NGA. All rights reserved. +// + +#import "SFLine.h" +#import "SFMultiPoint.h" +#import "SFCircularString.h" +#import "SFCompoundCurve.h" +#import "SFTIN.h" +#import "SFTriangle.h" + +/** + * Utilities for Geometry objects + */ +@interface SFGeometryUtils : NSObject + +/** + * Get the dimension of the Geometry, 0 for points, 1 for curves, 2 for + * surfaces. If a collection, the largest dimension is returned. + * + * @param geometry + * geometry object + * @return dimension (0, 1, or 2) + */ ++(int) dimensionOfGeometry: (SFGeometry *) geometry; + +/** + * Get the Pythagorean theorem distance between two points + * + * @param point1 + * point 1 + * @param point2 + * point 2 + * @return distance + */ ++(double) distanceBetweenPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2; + +/** + * Get the Pythagorean theorem distance between the line end points + * + * @param line + * line + * @return distance + */ ++(double) distanceOfLine: (SFLine *) line; + +/** + * Get the bearing heading in degrees between two points in degrees + * + * @param point1 + * point 1 + * @param point2 + * point 2 + * @return bearing angle in degrees between 0 and 360 + */ ++(double) bearingBetweenPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2; + +/** + * Get the bearing heading in degrees between line end points in degrees + * + * @param line + * line + * @return bearing angle in degrees between 0 inclusively and 360 + * exclusively + */ ++(double) bearingOfLine: (SFLine *) line; + +/** + * Determine if the bearing is in any north direction + * + * @param bearing + * bearing angle in degrees + * @return true if north bearing + */ ++(BOOL) isNorthBearing: (double) bearing; + +/** + * Determine if the bearing is in any east direction + * + * @param bearing + * bearing angle in degrees + * @return true if east bearing + */ ++(BOOL) isEastBearing: (double) bearing; + +/** + * Determine if the bearing is in any south direction + * + * @param bearing + * bearing angle in degrees + * @return true if south bearing + */ ++(BOOL) isSouthBearing: (double) bearing; + +/** + * Determine if the bearing is in any west direction + * + * @param bearing + * bearing angle in degrees + * @return true if west bearing + */ ++(BOOL) isWestBearing: (double) bearing; + +/** + * Convert degrees to radians + * + * @param degrees + * degrees + * @return radians + */ ++(double) degreesToRadians: (double) degrees; + +/** + * Convert radians to degrees + * + * @param radians + * radians + * @return degrees + */ ++(double) radiansToDegrees: (double) radians; + +/** + * Get the centroid point of a 2 dimensional representation of the Geometry + * (balancing point of a 2d cutout of the geometry). Only the x and y + * coordinate of the resulting point are calculated and populated. The + * resulting SFPoint.z and SFPoint.m values will always be nil. + * + * @param geometry + * geometry object + * @return centroid point + */ ++(SFPoint *) centroidOfGeometry: (SFGeometry *) geometry; + +/** + * Get the geographic centroid point of a 2 dimensional representation of + * the degree unit Geometry. Only the x and y coordinate of the resulting + * point are calculated and populated. The resulting SFPoint.z and + * SFPoint.m values will always be nil. + * + * @param geometry + * geometry object + * @return centroid point + */ ++(SFPoint *) degreesCentroidOfGeometry: (SFGeometry *) geometry; + +/** + * Minimize the WGS84 geometry using the shortest x distance between each + * connected set of points. Resulting x values will be in the range: -540.0 + * <= x <= 540.0 + * + * @param geometry + * geometry + */ ++(void) minimizeWGS84Geometry: (SFGeometry *) geometry; + +/** + * Minimize the Web Mercator geometry using the shortest x distance between + * each connected set of points. Resulting x values will be in the range: + * -60112525.028367732 <= x <= 60112525.028367732 + * + * @param geometry + * geometry + */ ++(void) minimizeWebMercatorGeometry: (SFGeometry *) geometry; + +/** + * Minimize the geometry using the shortest x distance between each + * connected set of points. The resulting geometry point x values will be in + * the range: (3 * min value <= x <= 3 * max value + * + * Example: For WGS84 provide a max x of + * SF_WGS84_HALF_WORLD_LON_WIDTH. Resulting x values + * will be in the range: -540.0 <= x <= 540.0 + * + * Example: For web mercator provide a world width of + * SF_WEB_MERCATOR_HALF_WORLD_WIDTH. Resulting x + * values will be in the range: -60112525.028367732 <= x <= + * 60112525.028367732 + * + * @param geometry + * geometry + * @param maxX + * max positive x value in the geometry projection + */ ++(void) minimizeGeometry: (SFGeometry *) geometry withMaxX: (double) maxX; + +/** + * Normalize the WGS84 geometry using the shortest x distance between each + * connected set of points. Resulting x values will be in the range: -180.0 + * <= x <= 180.0 + * + * @param geometry + * geometry + */ ++(void) normalizeWGS84Geometry: (SFGeometry *) geometry; + +/** + * Normalize the Web Mercator geometry using the shortest x distance between + * each connected set of points. Resulting x values will be in the range: + * -20037508.342789244 <= x <= 20037508.342789244 + * + * @param geometry + * geometry + */ ++(void) normalizeWebMercatorGeometry: (SFGeometry *) geometry; + +/** + * Normalize the geometry so all points outside of the min and max value + * range are adjusted to fall within the range. + * + * Example: For WGS84 provide a max x of + * SF_WGS84_HALF_WORLD_LON_WIDTH. Resulting x values + * will be in the range: -180.0 <= x <= 180.0 + * + * Example: For web mercator provide a world width of + * SF_WEB_MERCATOR_HALF_WORLD_WIDTH. Resulting x + * values will be in the range: -20037508.342789244 <= x <= + * 20037508.342789244 + * + * @param geometry + * geometry + * @param maxX + * max positive x value in the geometry projection + */ ++(void) normalizeGeometry: (SFGeometry *) geometry withMaxX: (double) maxX; + +/** + * Simplify the ordered points (representing a line, polygon, etc) using the Douglas Peucker algorithm + * to create a similar curve with fewer points. Points should be in a meters unit type projection. + * The tolerance is the minimum tolerated distance between consecutive points. + * + * @param points + * geometry points + * @param tolerance + * minimum tolerance in meters for consecutive points + * @return simplified points + */ ++ (NSArray *) simplifyPoints: (NSArray *) points withTolerance : (double) tolerance; + +/** + * Calculate the perpendicular distance between the point and the line represented by the start and end points. + * Points should be in a meters unit type projection. + * + * @param point + * point + * @param lineStart + * point representing the line start + * @param lineEnd + * point representing the line end + * @return distance in meters + */ ++ (double) perpendicularDistanceBetweenPoint: (SFPoint *) point lineStart: (SFPoint *) lineStart lineEnd: (SFPoint *) lineEnd; + +/** + * Check if the point is in the polygon + * + * @param point + * point + * @param polygon + * polygon + * @return true if in the polygon + */ ++(BOOL) point: (SFPoint *) point inPolygon: (SFPolygon *) polygon; + +/** + * Check if the point is in the polygon + * + * @param point + * point + * @param polygon + * polygon + * @param epsilon + * epsilon line tolerance + * @return true if in the polygon + */ ++(BOOL) point: (SFPoint *) point inPolygon: (SFPolygon *) polygon withEpsilon: (double) epsilon; + +/** + * Check if the point is in the polygon ring + * + * @param point + * point + * @param ring + * polygon ring + * @return true if in the polygon + */ ++(BOOL) point: (SFPoint *) point inPolygonRing: (SFLineString *) ring; + +/** + * Check if the point is in the polygon ring + * + * @param point + * point + * @param ring + * polygon ring + * @param epsilon + * epsilon line tolerance + * @return true if in the polygon + */ ++(BOOL) point: (SFPoint *) point inPolygonRing: (SFLineString *) ring withEpsilon: (double) epsilon; + +/** + * Check if the point is in the polygon points + * + * @param point + * point + * @param points + * polygon points + * @return true if in the polygon + */ ++(BOOL) point: (SFPoint *) point inPolygonPoints: (NSArray *) points; + +/** + * Check if the point is in the polygon points + * + * @param point + * point + * @param points + * polygon points + * @param epsilon + * epsilon line tolerance + * @return true if in the polygon + */ ++(BOOL) point: (SFPoint *) point inPolygonPoints: (NSArray *) points withEpsilon: (double) epsilon; + +/** + * Check if the point is on the polygon edge + * + * @param point + * point + * @param polygon + * polygon + * @return true if on the polygon edge + */ ++(BOOL) point: (SFPoint *) point onPolygonEdge: (SFPolygon *) polygon; + +/** + * Check if the point is on the polygon edge + * + * @param point + * point + * @param polygon + * polygon + * @param epsilon + * epsilon line tolerance + * @return true if on the polygon edge + */ ++(BOOL) point: (SFPoint *) point onPolygonEdge: (SFPolygon *) polygon withEpsilon: (double) epsilon; + +/** + * Check if the point is on the polygon ring edge + * + * @param point + * point + * @param ring + * polygon ring + * @return true if on the polygon edge + */ ++(BOOL) point: (SFPoint *) point onPolygonRingEdge: (SFLineString *) ring; + +/** + * Check if the point is on the polygon ring edge + * + * @param point + * point + * @param ring + * polygon ring + * @param epsilon + * epsilon line tolerance + * @return true if on the polygon edge + */ ++(BOOL) point: (SFPoint *) point onPolygonRingEdge: (SFLineString *) ring withEpsilon: (double) epsilon; + +/** + * Check if the point is on the polygon ring edge points + * + * @param point + * point + * @param points + * polygon points + * @return true if on the polygon edge + */ ++(BOOL) point: (SFPoint *) point onPolygonPointsEdge: (NSArray *) points; + +/** + * Check if the point is on the polygon ring edge points + * + * @param point + * point + * @param points + * polygon points + * @param epsilon + * epsilon line tolerance + * @return true if on the polygon edge + */ ++(BOOL) point: (SFPoint *) point onPolygonPointsEdge: (NSArray *) points withEpsilon: (double) epsilon; + +/** + * Check if the polygon outer ring is explicitly closed, where the first and + * last point are the same + * + * @param polygon + * polygon + * @return true if the first and last points are the same + */ ++(BOOL) closedPolygon: (SFPolygon *) polygon; + +/** + * Check if the polygon ring is explicitly closed, where the first and last + * point are the same + * + * @param ring + * polygon ring + * @return true if the first and last points are the same + */ ++(BOOL) closedPolygonRing: (SFLineString *) ring; + +/** + * Check if the polygon ring points are explicitly closed, where the first + * and last point are the same + * + * @param points + * polygon ring points + * @return true if the first and last points are the same + */ ++(BOOL) closedPolygonPoints: (NSArray *) points; + +/** + * Check if the point is on the line + * + * @param point + * point + * @param line + * line + * @return true if on the line + */ ++(BOOL) point: (SFPoint *) point onLine: (SFLineString *) line; + +/** + * Check if the point is on the line + * + * @param point + * point + * @param line + * line + * @param epsilon + * epsilon line tolerance + * @return true if on the line + */ ++(BOOL) point: (SFPoint *) point onLine: (SFLineString *) line withEpsilon: (double) epsilon; + +/** + * Check if the point is on the line represented by the points + * + * @param point + * point + * @param points + * line points + * @return true if on the line + */ ++(BOOL) point: (SFPoint *) point onLinePoints: (NSArray *) points; + +/** + * Check if the point is on the line represented by the points + * + * @param point + * point + * @param points + * line points + * @param epsilon + * epsilon line tolerance + * @return true if on the line + */ ++(BOOL) point: (SFPoint *) point onLinePoints: (NSArray *) points withEpsilon: (double) epsilon; + +/** + * Check if the point is on the path between point 1 and point 2 + * + * @param point + * point + * @param point1 + * path point 1 + * @param point2 + * path point 2 + * @return true if on the path + */ ++(BOOL) point: (SFPoint *) point onPathPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2; + +/** + * Check if the point is on the path between point 1 and point 2 + * + * @param point + * point + * @param point1 + * path point 1 + * @param point2 + * path point 2 + * @param epsilon + * epsilon line tolerance + * @return true if on the path + */ ++(BOOL) point: (SFPoint *) point onPathPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2 withEpsilon: (double) epsilon; + +/** + * Get the point intersection between two lines + * + * @param line1 + * first line + * @param line2 + * second line + * @return intersection point or null if no intersection + */ ++(SFPoint *) intersectionBetweenLine1: (SFLine *) line1 andLine2: (SFLine *) line2; + +/** + * Get the point intersection between end points of two lines + * + * @param line1Point1 + * first point of the first line + * @param line1Point2 + * second point of the first line + * @param line2Point1 + * first point of the second line + * @param line2Point2 + * second point of the second line + * @return intersection point or null if no intersection + */ ++(SFPoint *) intersectionBetweenLine1Point1: (SFPoint *) line1Point1 andLine1Point2: (SFPoint *) line1Point2 andLine2Point1: (SFPoint *) line2Point1 andLine2Point2: (SFPoint *) line2Point2; + +/** + * Convert a geometry in degrees to a geometry in meters + * + * @param geometry + * geometry in degrees + * @return geometry in meters + */ ++(SFGeometry *) degreesToMetersWithGeometry: (SFGeometry *) geometry; + +/** + * Convert a point in degrees to a point in meters + * + * @param point + * point in degrees + * @return point in meters + */ ++(SFPoint *) degreesToMetersWithPoint: (SFPoint *) point; + +/** + * Convert a coordinate in degrees to a point in meters + * + * @param x + * x value in degrees + * @param y + * y value in degrees + * @return point in meters + */ ++(SFPoint *) degreesToMetersWithX: (double) x andY: (double) y; + +/** + * Convert a multi point in degrees to a multi point in meters + * + * @param multiPoint + * multi point in degrees + * @return multi point in meters + */ ++(SFMultiPoint *) degreesToMetersWithMultiPoint: (SFMultiPoint *) multiPoint; + +/** + * Convert a line string in degrees to a line string in meters + * + * @param lineString + * line string in degrees + * @return line string in meters + */ ++(SFLineString *) degreesToMetersWithLineString: (SFLineString *) lineString; + +/** + * Convert a line in degrees to a line in meters + * + * @param line + * line in degrees + * @return line in meters + */ ++(SFLine *) degreesToMetersWithLine: (SFLine *) line; + +/** + * Convert a multi line string in degrees to a multi line string in meters + * + * @param multiLineString + * multi line string in degrees + * @return multi line string in meters + */ ++(SFMultiLineString *) degreesToMetersWithMultiLineString: (SFMultiLineString *) multiLineString; + +/** + * Convert a polygon in degrees to a polygon in meters + * + * @param polygon + * polygon in degrees + * @return polygon in meters + */ ++(SFPolygon *) degreesToMetersWithPolygon: (SFPolygon *) polygon; + +/** + * Convert a multi polygon in degrees to a multi polygon in meters + * + * @param multiPolygon + * multi polygon in degrees + * @return multi polygon in meters + */ ++(SFMultiPolygon *) degreesToMetersWithMultiPolygon: (SFMultiPolygon *) multiPolygon; + +/** + * Convert a circular string in degrees to a circular string in meters + * + * @param circularString + * circular string in degrees + * @return circular string in meters + */ ++(SFCircularString *) degreesToMetersWithCircularString: (SFCircularString *) circularString; + +/** + * Convert a compound curve in degrees to a compound curve in meters + * + * @param compoundCurve + * compound curve in degrees + * @return compound curve in meters + */ ++(SFCompoundCurve *) degreesToMetersWithCompoundCurve: (SFCompoundCurve *) compoundCurve; + +/** + * Convert a curve polygon in degrees to a curve polygon in meters + * + * @param curvePolygon + * curve polygon in degrees + * @return curve polygon in meters + */ ++(SFCurvePolygon *) degreesToMetersWithCurvePolygon: (SFCurvePolygon *) curvePolygon; + +/** + * Convert a polyhedral surface in degrees to a polyhedral surface in meters + * + * @param polyhedralSurface + * polyhedral surface in degrees + * @return polyhedral surface in meters + */ ++(SFPolyhedralSurface *) degreesToMetersWithPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface; + +/** + * Convert a TIN in degrees to a TIN in meters + * + * @param tin + * TIN in degrees + * @return TIN in meters + */ ++(SFTIN *) degreesToMetersWithTIN: (SFTIN *) tin; + +/** + * Convert a triangle in degrees to a triangle in meters + * + * @param triangle + * triangle in degrees + * @return triangle in meters + */ ++(SFTriangle *) degreesToMetersWithTriangle: (SFTriangle *) triangle; + +/** + * Convert a geometry in meters to a geometry in degrees + * + * @param geometry + * geometry in meters + * @return geometry in degrees + */ ++(SFGeometry *) metersToDegreesWithGeometry: (SFGeometry *) geometry; + +/** + * Convert a point in meters to a point in degrees + * + * @param point + * point in meters + * @return point in degrees + */ ++(SFPoint *) metersToDegreesWithPoint: (SFPoint *) point; + +/** + * Convert a coordinate in meters to a point in degrees + * + * @param x + * x value in meters + * @param y + * y value in meters + * @return point in degrees + */ ++(SFPoint *) metersToDegreesWithX: (double) x andY: (double) y; + +/** + * Convert a multi point in meters to a multi point in degrees + * + * @param multiPoint + * multi point in meters + * @return multi point in degrees + */ ++(SFMultiPoint *) metersToDegreesWithMultiPoint: (SFMultiPoint *) multiPoint; + +/** + * Convert a line string in meters to a line string in degrees + * + * @param lineString + * line string in meters + * @return line string in degrees + */ ++(SFLineString *) metersToDegreesWithLineString: (SFLineString *) lineString; + +/** + * Convert a line in meters to a line in degrees + * + * @param line + * line in meters + * @return line in degrees + */ ++(SFLine *) metersToDegreesWithLine: (SFLine *) line; + +/** + * Convert a multi line string in meters to a multi line string in degrees + * + * @param multiLineString + * multi line string in meters + * @return multi line string in degrees + */ ++(SFMultiLineString *) metersToDegreesWithMultiLineString: (SFMultiLineString *) multiLineString; + +/** + * Convert a polygon in meters to a polygon in degrees + * + * @param polygon + * polygon in meters + * @return polygon in degrees + */ ++(SFPolygon *) metersToDegreesWithPolygon: (SFPolygon *) polygon; + +/** + * Convert a multi polygon in meters to a multi polygon in degrees + * + * @param multiPolygon + * multi polygon in meters + * @return multi polygon in degrees + */ ++(SFMultiPolygon *) metersToDegreesWithMultiPolygon: (SFMultiPolygon *) multiPolygon; + +/** + * Convert a circular string in meters to a circular string in degrees + * + * @param circularString + * circular string in meters + * @return circular string in degrees + */ ++(SFCircularString *) metersToDegreesWithCircularString: (SFCircularString *) circularString; + +/** + * Convert a compound curve in meters to a compound curve in degrees + * + * @param compoundCurve + * compound curve in meters + * @return compound curve in degrees + */ ++(SFCompoundCurve *) metersToDegreesWithCompoundCurve: (SFCompoundCurve *) compoundCurve; + +/** + * Convert a curve polygon in meters to a curve polygon in degrees + * + * @param curvePolygon + * curve polygon in meters + * @return curve polygon in degrees + */ ++(SFCurvePolygon *) metersToDegreesWithCurvePolygon: (SFCurvePolygon *) curvePolygon; + +/** + * Convert a polyhedral surface in meters to a polyhedral surface in degrees + * + * @param polyhedralSurface + * polyhedral surface in meters + * @return polyhedral surface in degrees + */ ++(SFPolyhedralSurface *) metersToDegreesWithPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface; + +/** + * Convert a TIN in meters to a TIN in degrees + * + * @param tin + * TIN in meters + * @return TIN in degrees + */ ++(SFTIN *) metersToDegreesWithTIN: (SFTIN *) tin; + +/** + * Convert a triangle in meters to a triangle in degrees + * + * @param triangle + * triangle in meters + * @return triangle in degrees + */ ++(SFTriangle *) metersToDegreesWithTriangle: (SFTriangle *) triangle; + +/** + * Get a WGS84 bounded geometry envelope + * + * @return geometry envelope + */ ++(SFGeometryEnvelope *) wgs84Envelope; + +/** + * Get a WGS84 bounded geometry envelope used for projection transformations + * (degrees to meters) + * + * @return geometry envelope + */ ++(SFGeometryEnvelope *) wgs84TransformableEnvelope; + +/** + * Get a Web Mercator bounded geometry envelope + * + * @return geometry envelope + */ ++(SFGeometryEnvelope *) webMercatorEnvelope; + +/** + * Get a WGS84 geometry envelope with Web Mercator bounds + * + * @return geometry envelope + */ ++(SFGeometryEnvelope *) wgs84EnvelopeWithWebMercator; + +/** + * Crop the geometry in meters by web mercator world bounds. Cropping + * removes points outside the envelope and creates new points on the line + * intersections with the envelope. + * + * @param geometry + * geometry in meters + * @return cropped geometry in meters or null + */ ++(SFGeometry *) cropWebMercatorGeometry: (SFGeometry *) geometry; + +/** + * Crop the geometry in meters by the envelope bounds in meters. Cropping + * removes points outside the envelope and creates new points on the line + * intersections with the envelope. + * + * @param geometry + * geometry in meters + * @param envelope + * envelope in meters + * @return cropped geometry in meters or null + */ ++(SFGeometry *) cropGeometry: (SFGeometry *) geometry withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the point by the envelope bounds. + * + * @param point + * point + * @param envelope + * envelope + * @return cropped point or null + */ ++(SFPoint *) cropPoint: (SFPoint *) point withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the list of consecutive points in meters by the envelope bounds in + * meters. Cropping removes points outside the envelope and creates new + * points on the line intersections with the envelope. + * + * @param points + * consecutive points + * @param envelope + * envelope in meters + * @return cropped points in meters or null + */ ++(NSMutableArray *) cropPoints: (NSArray *) points withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the multi point by the envelope bounds. + * + * @param multiPoint + * multi point + * @param envelope + * envelope + * @return cropped multi point or null + */ ++(SFMultiPoint *) cropMultiPoint: (SFMultiPoint *) multiPoint withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the line string in meters by the envelope bounds in meters. Cropping + * removes points outside the envelope and creates new points on the line + * intersections with the envelope. + * + * @param lineString + * line string in meters + * @param envelope + * envelope in meters + * @return cropped line string in meters or null + */ ++(SFLineString *) cropLineString: (SFLineString *) lineString withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the line in meters by the envelope bounds in meters. Cropping + * removes points outside the envelope and creates new points on the line + * intersections with the envelope. + * + * @param line + * line in meters + * @param envelope + * envelope in meters + * @return cropped line in meters or null + */ ++(SFLine *) cropLine: (SFLine *) line withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the multi line string in meters by the envelope bounds in meters. + * Cropping removes points outside the envelope and creates new points on + * the line intersections with the envelope. + * + * @param multiLineString + * multi line string in meters + * @param envelope + * envelope in meters + * @return cropped multi line string in meters or null + */ ++(SFMultiLineString *) cropMultiLineString: (SFMultiLineString *) multiLineString withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the polygon in meters by the envelope bounds in meters. Cropping + * removes points outside the envelope and creates new points on the line + * intersections with the envelope. + * + * @param polygon + * polygon in meters + * @param envelope + * envelope in meters + * @return cropped polygon in meters or null + */ ++(SFPolygon *) cropPolygon: (SFPolygon *) polygon withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the multi polygon in meters by the envelope bounds in meters. + * Cropping removes points outside the envelope and creates new points on + * the line intersections with the envelope. + * + * @param multiPolygon + * multi polygon in meters + * @param envelope + * envelope in meters + * @return cropped multi polygon in meters or null + */ ++(SFMultiPolygon *) cropMultiPolygon: (SFMultiPolygon *) multiPolygon withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the circular string in meters by the envelope bounds in meters. + * Cropping removes points outside the envelope and creates new points on + * the line intersections with the envelope. + * + * @param circularString + * circular string in meters + * @param envelope + * envelope in meters + * @return cropped circular string in meters or null + */ ++(SFCircularString *) cropCircularString: (SFCircularString *) circularString withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the compound curve in meters by the envelope bounds in meters. + * Cropping removes points outside the envelope and creates new points on + * the line intersections with the envelope. + * + * @param compoundCurve + * compound curve in meters + * @param envelope + * envelope in meters + * @return cropped compound curve in meters or null + */ ++(SFCompoundCurve *) cropCompoundCurve: (SFCompoundCurve *) compoundCurve withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the curve polygon in meters by the envelope bounds in meters. + * Cropping removes points outside the envelope and creates new points on + * the line intersections with the envelope. + * + * @param curvePolygon + * curve polygon in meters + * @param envelope + * envelope in meters + * @return cropped curve polygon in meters or null + */ ++(SFCurvePolygon *) cropCurvePolygon: (SFCurvePolygon *) curvePolygon withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the polyhedral surface in meters by the envelope bounds in meters. + * Cropping removes points outside the envelope and creates new points on + * the line intersections with the envelope. + * + * @param polyhedralSurface + * polyhedral surface in meters + * @param envelope + * envelope in meters + * @return cropped polyhedral surface in meters or null + */ ++(SFPolyhedralSurface *) cropPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the TIN in meters by the envelope bounds in meters. Cropping removes + * points outside the envelope and creates new points on the line + * intersections with the envelope. + * + * @param tin + * TIN in meters + * @param envelope + * envelope in meters + * @return cropped TIN in meters or null + */ ++(SFTIN *) cropTIN: (SFTIN *) tin withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Crop the triangle in meters by the envelope bounds in meters. Cropping + * removes points outside the envelope and creates new points on the line + * intersections with the envelope. + * + * @param triangle + * triangle in meters + * @param envelope + * envelope in meters + * @return cropped triangle in meters or null + */ ++(SFTriangle *) cropTriangle: (SFTriangle *) triangle withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Determine if the points are equal within the default tolerance of + * SF_DEFAULT_EQUAL_EPSILON. For exact equality, use SFPoint.isEqual(id). + * + * @param point1 + * point 1 + * @param point2 + * point 2 + * @return true if equal + */ ++(BOOL) isEqualWithPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2; + +/** + * Determine if the points are equal within the tolerance. For exact + * equality, use SFPoint.isEqual(id). + * + * @param point1 + * point 1 + * @param point2 + * point 2 + * @param epsilon + * epsilon equality tolerance + * @return true if equal + */ ++(BOOL) isEqualWithPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2 andEpsilon: (double) epsilon; + +/** + * Determine if the envelope contains the point within the default tolerance + * of SF_DEFAULT_EQUAL_EPSILON. For exact equality, + * use SFGeometryEnvelope.containsPoint(SFPoint). + * + * @param envelope + * envelope + * @param point + * point + * @return true if contains + */ ++(BOOL) containsPoint: (SFPoint *) point withinEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Determine if envelope 1 contains the envelope 2 within the default + * tolerance of SF_DEFAULT_EQUAL_EPSILON. For exact + * equality, use SFGeometryEnvelope.containsEnvelope(SFGeometryEnvelope). + * + * @param envelope1 + * envelope 1 + * @param envelope2 + * envelope 2 + * @return true if contains + */ ++(BOOL) containsEnvelope: (SFGeometryEnvelope *) envelope2 withinEnvelope: (SFGeometryEnvelope *) envelope1; + +/** + * Bound all points in the geometry to be within WGS84 limits. + * + * To perform a geometry crop using line intersections, see + * degreesToMetersWithGeometry(SFGeometry) and + * cropGeometry(SFGeometry)withEnvelope:(SFGeometryEnvelope). + * + * @param geometry + * geometry + */ ++(void) boundWGS84Geometry: (SFGeometry *) geometry; + +/** + * Bound all points in the geometry to be within WGS84 projection + * transformable (degrees to meters) limits. + * + * To perform a geometry crop using line intersections, see + * degreesToMetersWithGeometry(SFGeometry) and + * cropGeometry(SFGeometry)withEnvelope:(SFGeometryEnvelope). + * + * @param geometry + * geometry + */ ++(void) boundWGS84TransformableGeometry: (SFGeometry *) geometry; + +/** + * Bound all points in the geometry to be within Web Mercator limits. + * + * To perform a geometry crop using line intersections, see + * cropWebMercatorGeometry(SFGeometry). + * + * @param geometry + * geometry + */ ++(void) boundWebMercatorGeometry: (SFGeometry *) geometry; + +/** + * Bound all points in the WGS84 geometry to be within degree Web Mercator + * limits. + * + * To perform a geometry crop using line intersections, see + * degreesToMetersWithGeometry(SFGeometry) and + * cropWebMercatorGeometry(SFGeometry). + * + * @param geometry + * geometry + */ ++(void) boundWGS84WithWebMercatorGeometry: (SFGeometry *) geometry; + +/** + * Bound all points in the geometry to be within the geometry envelope. + * Point x and y values are bounded by the min and max envelope values. + * + * To perform a geometry crop using line intersections, see + * cropGeometry(SFGeometry)withEnvelope:(SFGeometryEnvelope) (requires geometry in meters). + * + * @param geometry + * geometry + * @param envelope + * geometry envelope + */ ++(void) boundGeometry: (SFGeometry *) geometry withEnvelope: (SFGeometryEnvelope *) envelope; + +/** + * Determine if the geometries contain a Z value + * + * @param geometries + * list of geometries + * @return true if has z + */ ++(BOOL) hasZ: (NSArray *) geometries; + +/** + * Determine if the geometries contain a M value + * + * @param geometries + * list of geometries + * @return true if has m + */ ++(BOOL) hasM: (NSArray *) geometries; + +/** + * Get the parent type hierarchy of the provided geometry type starting with + * the immediate parent. If the argument is GEOMETRY, an empty list is + * returned, else the final type in the list will be GEOMETRY. + * + * @param geometryType + * geometry type + * @return list of increasing parent types + */ ++(NSArray *) parentHierarchyOfType: (enum SFGeometryType) geometryType; + +/** + * Get the parent Geometry Type of the provided geometry type + * + * @param geometryType + * geometry type + * @return parent geometry type or null if argument is GEOMETRY (no parent + * type) + */ ++(enum SFGeometryType) parentTypeOfType: (enum SFGeometryType) geometryType; + +/** + * Get the child type hierarchy of the provided geometry type. + * + * @param geometryType + * geometry type + * @return child type hierarchy, null if no children + */ ++(NSDictionary *) childHierarchyOfType: (enum SFGeometryType) geometryType; + +/** + * Get the immediate child Geometry Types of the provided geometry type + * + * @param geometryType + * geometry type + * @return child geometry types, empty list if no child types + */ ++(NSArray *) childTypesOfType: (enum SFGeometryType) geometryType; + +/** + * Encode the geometry to data + * + * @param geometry + * geometry + * @return encoded dta + */ ++(NSData *) encodeGeometry: (SFGeometry *) geometry; + +/** + * Decode the data into a geometry + * + * @param data + * encoded data + * @return geometry + */ ++(SFGeometry *) decodeGeometry: (NSData *) data; + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFGeometryUtils.m b/Pods/sf-ios/sf-ios/util/SFGeometryUtils.m new file mode 100644 index 0000000..698c1ff --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFGeometryUtils.m @@ -0,0 +1,1832 @@ +// +// SFGeometryUtils.m +// sf-ios +// +// Created by Brian Osborn on 4/14/17. +// Copyright © 2017 NGA. All rights reserved. +// + +#import "SFGeometryUtils.h" +#import "SFCentroidPoint.h" +#import "SFCentroidCurve.h" +#import "SFCentroidSurface.h" +#import "SFMultiLineString.h" +#import "SFMultiPolygon.h" +#import "SFDegreesCentroid.h" +#import "SFGeometryConstants.h" + +@implementation SFGeometryUtils + ++(int) dimensionOfGeometry: (SFGeometry *) geometry{ + + int dimension = -1; + + enum SFGeometryType geometryType = geometry.geometryType; + switch (geometryType) { + case SF_POINT: + case SF_MULTIPOINT: + dimension = 0; + break; + case SF_LINESTRING: + case SF_MULTILINESTRING: + case SF_CIRCULARSTRING: + case SF_COMPOUNDCURVE: + dimension = 1; + break; + case SF_POLYGON: + case SF_CURVEPOLYGON: + case SF_MULTIPOLYGON: + case SF_POLYHEDRALSURFACE: + case SF_TIN: + case SF_TRIANGLE: + dimension = 2; + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + { + SFGeometryCollection *geomCollection = (SFGeometryCollection *) geometry; + for (SFGeometry *subGeometry in geomCollection.geometries) { + dimension = MAX(dimension, [self dimensionOfGeometry:subGeometry]); + } + } + break; + default: + [NSException raise:@"Geometry Not Supported" format:@"Unsupported Geometry Type: %d", geometryType]; + } + + return dimension; +} + ++(double) distanceBetweenPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2{ + double diffX = [point1.x doubleValue] - [point2.x doubleValue]; + double diffY = [point1.y doubleValue] - [point2.y doubleValue]; + return sqrt(diffX * diffX + diffY * diffY); +} + ++(double) distanceOfLine: (SFLine *) line{ + return [self distanceBetweenPoint1:[line startPoint] andPoint2:[line endPoint]]; +} + ++(double) bearingBetweenPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2{ + double y1 = [self degreesToRadians:[point1.y doubleValue]]; + double y2 = [self degreesToRadians:[point2.y doubleValue]]; + double xDiff = [self degreesToRadians:[point2.x doubleValue] - [point1.x doubleValue]]; + double y = sin(xDiff) * cos(y2); + double x = cos(y1) * sin(y2) - sin(y1) * cos(y2) * cos(xDiff); + return fmod([self radiansToDegrees:atan2(y, x)] + 360, 360); +} + ++(double) bearingOfLine: (SFLine *) line{ + return [self bearingBetweenPoint1:[line startPoint] andPoint2:[line endPoint]]; +} + ++(BOOL) isNorthBearing: (double) bearing{ + bearing = fmod(bearing, 360.0); + return bearing < SF_BEARING_EAST || bearing > SF_BEARING_WEST; +} + ++(BOOL) isEastBearing: (double) bearing{ + bearing = fmod(bearing, 360.0); + return bearing > SF_BEARING_NORTH && bearing < SF_BEARING_SOUTH; +} + ++(BOOL) isSouthBearing: (double) bearing{ + bearing = fmod(bearing, 360.0); + return bearing > SF_BEARING_EAST && bearing < SF_BEARING_WEST; +} + ++(BOOL) isWestBearing: (double) bearing{ + return fmod(bearing, 360.0) > SF_BEARING_SOUTH; +} + ++(double) degreesToRadians: (double) degrees{ + return degrees * SF_DEGREES_TO_RADIANS; +} + ++(double) radiansToDegrees: (double) radians{ + return radians * SF_RADIANS_TO_DEGREES; +} + ++(SFPoint *) centroidOfGeometry: (SFGeometry *) geometry{ + SFPoint *centroid = nil; + int dimension = [self dimensionOfGeometry:geometry]; + switch (dimension) { + case 0: + { + SFCentroidPoint *point = [[SFCentroidPoint alloc] initWithGeometry: geometry]; + centroid = [point centroid]; + } + break; + case 1: + { + SFCentroidCurve *curve = [[SFCentroidCurve alloc] initWithGeometry: geometry]; + centroid = [curve centroid]; + } + break; + case 2: + { + SFCentroidSurface *surface = [[SFCentroidSurface alloc] initWithGeometry: geometry]; + centroid = [surface centroid]; + } + break; + } + return centroid; +} + ++(SFPoint *) degreesCentroidOfGeometry: (SFGeometry *) geometry{ + return [SFDegreesCentroid centroidOfGeometry:geometry]; +} + ++(void) minimizeWGS84Geometry: (SFGeometry *) geometry{ + [self minimizeGeometry:geometry withMaxX:SF_WGS84_HALF_WORLD_LON_WIDTH]; +} + ++(void) minimizeWebMercatorGeometry: (SFGeometry *) geometry{ + [self minimizeGeometry:geometry withMaxX:SF_WEB_MERCATOR_HALF_WORLD_WIDTH]; +} + ++(void) minimizeGeometry: (SFGeometry *) geometry withMaxX: (double) maxX{ + + enum SFGeometryType geometryType = geometry.geometryType; + switch (geometryType) { + case SF_LINESTRING: + [self minimizeLineString:(SFLineString *)geometry withMaxX:maxX]; + break; + case SF_POLYGON: + [self minimizePolygon:(SFPolygon *)geometry withMaxX:maxX]; + break; + case SF_MULTILINESTRING: + [self minimizeMultiLineString:(SFMultiLineString *)geometry withMaxX:maxX]; + break; + case SF_MULTIPOLYGON: + [self minimizeMultiPolygon:(SFMultiPolygon *)geometry withMaxX:maxX]; + break; + case SF_CIRCULARSTRING: + [self minimizeLineString:(SFCircularString *)geometry withMaxX:maxX]; + break; + case SF_COMPOUNDCURVE: + [self minimizeCompoundCurve:(SFCompoundCurve *)geometry withMaxX:maxX]; + break; + case SF_CURVEPOLYGON: + [self minimizeCurvePolygon:(SFCurvePolygon *)geometry withMaxX:maxX]; + break; + case SF_POLYHEDRALSURFACE: + [self minimizePolyhedralSurface:(SFPolyhedralSurface *)geometry withMaxX:maxX]; + break; + case SF_TIN: + [self minimizePolyhedralSurface:(SFTIN *)geometry withMaxX:maxX]; + break; + case SF_TRIANGLE: + [self minimizePolygon:(SFTriangle *)geometry withMaxX:maxX]; + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + { + SFGeometryCollection *geomCollection = (SFGeometryCollection *) geometry; + for (SFGeometry *subGeometry in geomCollection.geometries) { + [self minimizeGeometry:subGeometry withMaxX:maxX]; + } + } + break; + default: + break; + + } + +} + ++(void) minimizeLineString: (SFLineString *) lineString withMaxX: (double) maxX{ + + NSMutableArray *points = lineString.points; + if(points.count > 1){ + SFPoint *point = [points objectAtIndex:0]; + for(int i = 1; i < points.count; i++){ + SFPoint *nextPoint = [points objectAtIndex:i]; + if([point.x doubleValue] < [nextPoint.x doubleValue]){ + if([nextPoint.x doubleValue] - [point.x doubleValue] > [point.x doubleValue] - [nextPoint.x doubleValue] + (maxX * 2.0)){ + [nextPoint setX:[nextPoint.x decimalNumberBySubtracting:[[NSDecimalNumber alloc] initWithDouble: maxX * 2.0]]]; + } + }else if([point.x doubleValue] > [nextPoint.x doubleValue]){ + if([point.x doubleValue] - [nextPoint.x doubleValue] > [nextPoint.x doubleValue] - [point.x doubleValue] + (maxX * 2.0)){ + [nextPoint setX:[nextPoint.x decimalNumberByAdding:[[NSDecimalNumber alloc] initWithDouble: maxX * 2.0]]]; + } + } + } + } +} + ++(void) minimizeMultiLineString: (SFMultiLineString *) multiLineString withMaxX: (double) maxX{ + + NSArray *lineStrings = [multiLineString lineStrings]; + for(SFLineString *lineString in lineStrings){ + [self minimizeLineString:lineString withMaxX:maxX]; + } +} + ++(void) minimizePolygon: (SFPolygon *) polygon withMaxX: (double) maxX{ + + for(SFLineString *ring in polygon.rings){ + [self minimizeLineString:ring withMaxX:maxX]; + } +} + ++(void) minimizeMultiPolygon: (SFMultiPolygon *) multiPolygon withMaxX: (double) maxX{ + + NSArray *polygons = [multiPolygon polygons]; + for(SFPolygon *polygon in polygons){ + [self minimizePolygon:polygon withMaxX:maxX]; + } +} + ++(void) minimizeCompoundCurve: (SFCompoundCurve *) compoundCurve withMaxX: (double) maxX{ + + for(SFLineString *lineString in compoundCurve.lineStrings){ + [self minimizeLineString:lineString withMaxX:maxX]; + } +} + ++(void) minimizeCurvePolygon: (SFCurvePolygon *) curvePolygon withMaxX: (double) maxX{ + + for(SFCurve *ring in curvePolygon.rings){ + [self minimizeGeometry:ring withMaxX:maxX]; + } +} + ++(void) minimizePolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface withMaxX: (double) maxX{ + + for(SFPolygon *polygon in polyhedralSurface.polygons){ + [self minimizePolygon:polygon withMaxX:maxX]; + } +} + ++(void) normalizeWGS84Geometry: (SFGeometry *) geometry{ + [self normalizeGeometry:geometry withMaxX:SF_WGS84_HALF_WORLD_LON_WIDTH]; +} + ++(void) normalizeWebMercatorGeometry: (SFGeometry *) geometry{ + [self normalizeGeometry:geometry withMaxX:SF_WEB_MERCATOR_HALF_WORLD_WIDTH]; +} + ++(void) normalizeGeometry: (SFGeometry *) geometry withMaxX: (double) maxX{ + + enum SFGeometryType geometryType = geometry.geometryType; + switch (geometryType) { + case SF_POINT: + [self normalizePoint:(SFPoint *)geometry withMaxX:maxX]; + break; + case SF_LINESTRING: + [self normalizeLineString:(SFLineString *)geometry withMaxX:maxX]; + break; + case SF_POLYGON: + [self normalizePolygon:(SFPolygon *)geometry withMaxX:maxX]; + break; + case SF_MULTIPOINT: + [self normalizeMultiPoint:(SFMultiPoint *)geometry withMaxX:maxX]; + break; + case SF_MULTILINESTRING: + [self normalizeMultiLineString:(SFMultiLineString *)geometry withMaxX:maxX]; + break; + case SF_MULTIPOLYGON: + [self normalizeMultiPolygon:(SFMultiPolygon *)geometry withMaxX:maxX]; + break; + case SF_CIRCULARSTRING: + [self normalizeLineString:(SFCircularString *)geometry withMaxX:maxX]; + break; + case SF_COMPOUNDCURVE: + [self normalizeCompoundCurve:(SFCompoundCurve *)geometry withMaxX:maxX]; + break; + case SF_CURVEPOLYGON: + [self normalizeCurvePolygon:(SFCurvePolygon *)geometry withMaxX:maxX]; + break; + case SF_POLYHEDRALSURFACE: + [self normalizePolyhedralSurface:(SFPolyhedralSurface *)geometry withMaxX:maxX]; + break; + case SF_TIN: + [self normalizePolyhedralSurface:(SFTIN *)geometry withMaxX:maxX]; + break; + case SF_TRIANGLE: + [self normalizePolygon:(SFTriangle *)geometry withMaxX:maxX]; + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + { + SFGeometryCollection *geomCollection = (SFGeometryCollection *) geometry; + for (SFGeometry *subGeometry in geomCollection.geometries) { + [self normalizeGeometry:subGeometry withMaxX:maxX]; + } + } + break; + default: + break; + + } + +} + ++(void) normalizePoint: (SFPoint *) point withMaxX: (double) maxX{ + [point setX:[[NSDecimalNumber alloc] initWithDouble:[self normalizeX:[point.x doubleValue] withMaxX:maxX]]]; +} + ++(double) normalizeX: (double) x withMaxX: (double) maxX{ + if(x < -maxX){ + x = x + (maxX * 2.0); + }else if (x > maxX){ + x = x - (maxX * 2.0); + } + return x; +} + ++(void) normalizeMultiPoint: (SFMultiPoint *) multiPoint withMaxX: (double) maxX{ + + NSArray *points = [multiPoint points]; + for(SFPoint *point in points){ + [self normalizePoint:point withMaxX:maxX]; + } +} + ++(void) normalizeLineString: (SFLineString *) lineString withMaxX: (double) maxX{ + + for(SFPoint *point in lineString.points){ + [self normalizePoint:point withMaxX:maxX]; + } +} + ++(void) normalizeMultiLineString: (SFMultiLineString *) multiLineString withMaxX: (double) maxX{ + + NSArray *lineStrings = [multiLineString lineStrings]; + for(SFLineString *lineString in lineStrings){ + [self normalizeLineString:lineString withMaxX:maxX]; + } +} + ++(void) normalizePolygon: (SFPolygon *) polygon withMaxX: (double) maxX{ + + for(SFLineString *ring in polygon.rings){ + [self normalizeLineString:ring withMaxX:maxX]; + } +} + ++(void) normalizeMultiPolygon: (SFMultiPolygon *) multiPolygon withMaxX: (double) maxX{ + + NSArray *polygons = [multiPolygon polygons]; + for(SFPolygon *polygon in polygons){ + [self normalizePolygon:polygon withMaxX:maxX]; + } +} + ++(void) normalizeCompoundCurve: (SFCompoundCurve *) compoundCurve withMaxX: (double) maxX{ + + for(SFLineString *lineString in compoundCurve.lineStrings){ + [self normalizeLineString:lineString withMaxX:maxX]; + } +} + ++(void) normalizeCurvePolygon: (SFCurvePolygon *) curvePolygon withMaxX: (double) maxX{ + + for(SFCurve *ring in curvePolygon.rings){ + [self normalizeGeometry:ring withMaxX:maxX]; + } +} + ++(void) normalizePolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface withMaxX: (double) maxX{ + + for(SFPolygon *polygon in polyhedralSurface.polygons){ + [self normalizePolygon:polygon withMaxX:maxX]; + } +} + ++ (NSArray *) simplifyPoints: (NSArray *) points withTolerance : (double) tolerance{ + return [self simplifyPoints:points withTolerance:tolerance andStartIndex:0 andEndIndex:(int)[points count]-1]; +} + ++(NSArray *) simplifyPoints: (NSArray *) points withTolerance: (double) tolerance andStartIndex: (int) startIndex andEndIndex: (int) endIndex { + + NSArray *result = nil; + + double dmax = 0.0; + int index = 0; + + SFPoint *startPoint = [points objectAtIndex:startIndex]; + SFPoint *endPoint = [points objectAtIndex:endIndex]; + + for (int i = startIndex + 1; i < endIndex; i++) { + SFPoint *point = [points objectAtIndex:i]; + + double d = [SFGeometryUtils perpendicularDistanceBetweenPoint:point lineStart:startPoint lineEnd:endPoint]; + + if (d > dmax) { + index = i; + dmax = d; + } + } + + if (dmax > tolerance) { + + NSArray *recResults1 = [self simplifyPoints:points withTolerance:tolerance andStartIndex:startIndex andEndIndex:index]; + NSArray *recResults2 = [self simplifyPoints:points withTolerance:tolerance andStartIndex:index andEndIndex:endIndex]; + + result = [recResults1 subarrayWithRange:NSMakeRange(0, recResults1.count - 1)]; + result = [result arrayByAddingObjectsFromArray:recResults2]; + + }else{ + result = [NSArray arrayWithObjects:startPoint, endPoint, nil]; + } + + return result; +} + ++(double) perpendicularDistanceBetweenPoint: (SFPoint *) point lineStart: (SFPoint *) lineStart lineEnd: (SFPoint *) lineEnd { + + double x = [point.x doubleValue]; + double y = [point.y doubleValue]; + double startX = [lineStart.x doubleValue]; + double startY = [lineStart.y doubleValue]; + double endX = [lineEnd.x doubleValue]; + double endY = [lineEnd.y doubleValue]; + + double vX = endX - startX; + double vY = endY - startY; + double wX = x - startX; + double wY = y - startY; + double c1 = wX * vX + wY * vY; + double c2 = vX * vX + vY * vY; + + double x2; + double y2; + if(c1 <=0){ + x2 = startX; + y2 = startY; + }else if(c2 <= c1){ + x2 = endX; + y2 = endY; + }else{ + double b = c1 / c2; + x2 = startX + b * vX; + y2 = startY + b * vY; + } + + double distance = sqrt(pow(x2 - x, 2) + pow(y2 - y, 2)); + + return distance; +} + ++(BOOL) point: (SFPoint *) point inPolygon: (SFPolygon *) polygon{ + return [self point:point inPolygon:polygon withEpsilon:SF_DEFAULT_LINE_EPSILON]; +} + ++(BOOL) point: (SFPoint *) point inPolygon: (SFPolygon *) polygon withEpsilon: (double) epsilon{ + + BOOL contains = NO; + NSArray *rings = polygon.rings; + if(rings.count > 0){ + contains = [self point:point inPolygonRing:[rings objectAtIndex:0] withEpsilon:epsilon]; + if(contains){ + // Check the holes + for(int i = 1; i < rings.count; i++){ + if([self point:point inPolygonRing:[rings objectAtIndex:i] withEpsilon:epsilon]){ + contains = NO; + break; + } + } + } + } + + return contains; +} + ++(BOOL) point: (SFPoint *) point inPolygonRing: (SFLineString *) ring{ + return [self point:point inPolygonRing:ring withEpsilon:SF_DEFAULT_LINE_EPSILON]; +} + ++(BOOL) point: (SFPoint *) point inPolygonRing: (SFLineString *) ring withEpsilon: (double) epsilon{ + return [self point:point inPolygonPoints:ring.points withEpsilon:epsilon]; +} + ++(BOOL) point: (SFPoint *) point inPolygonPoints: (NSArray *) points{ + return [self point:point inPolygonPoints:points withEpsilon:SF_DEFAULT_LINE_EPSILON]; +} + ++(BOOL) point: (SFPoint *) point inPolygonPoints: (NSArray *) points withEpsilon: (double) epsilon{ + + BOOL contains = NO; + + int i = 0; + int j = (int)points.count - 1; + if([self closedPolygonPoints:points]){ + j = i++; + } + + for(; i < points.count; j = i++){ + SFPoint *point1 = [points objectAtIndex:i]; + SFPoint *point2 = [points objectAtIndex:j]; + + double px = [point.x doubleValue]; + double py = [point.y doubleValue]; + + double p1x = [point1.x doubleValue]; + double p1y = [point1.y doubleValue]; + + // Shortcut check if polygon contains the point within tolerance + if(fabs(p1x - px) <= epsilon && fabs(p1y - py) <= epsilon){ + contains = YES; + break; + } + + double p2x = [point2.x doubleValue]; + double p2y = [point2.y doubleValue]; + + if(((p1y > py) != (p2y > py)) + && (px < (p2x - p1x) * (py - p1y) / (p2y - p1y) + p1x)){ + contains = !contains; + } + } + + if(!contains){ + // Check the polygon edges + contains = [self point:point onPolygonPointsEdge:points]; + } + + return contains; +} + ++(BOOL) point: (SFPoint *) point onPolygonEdge: (SFPolygon *) polygon{ + return [self point:point onPolygonEdge:polygon withEpsilon:SF_DEFAULT_LINE_EPSILON]; +} + ++(BOOL) point: (SFPoint *) point onPolygonEdge: (SFPolygon *) polygon withEpsilon: (double) epsilon{ + return [polygon numRings] > 0 && [self point:point onPolygonRingEdge:[polygon ringAtIndex:0] withEpsilon:epsilon]; +} + ++(BOOL) point: (SFPoint *) point onPolygonRingEdge: (SFLineString *) ring{ + return [self point:point onPolygonRingEdge:ring withEpsilon:SF_DEFAULT_LINE_EPSILON]; +} + ++(BOOL) point: (SFPoint *) point onPolygonRingEdge: (SFLineString *) ring withEpsilon: (double) epsilon{ + return [self point:point onPolygonPointsEdge:ring.points withEpsilon:epsilon]; +} + ++(BOOL) point: (SFPoint *) point onPolygonPointsEdge: (NSArray *) points{ + return [self point:point onPolygonPointsEdge:points withEpsilon:SF_DEFAULT_LINE_EPSILON]; +} + ++(BOOL) point: (SFPoint *) point onPolygonPointsEdge: (NSArray *) points withEpsilon: (double) epsilon{ + return [self point:point onPath:points withEpsilon:epsilon andCircular:![self closedPolygonPoints:points]]; +} + ++(BOOL) closedPolygon: (SFPolygon *) polygon{ + return [polygon numRings] > 0 && [self closedPolygonRing:[polygon ringAtIndex:0]]; +} + ++(BOOL) closedPolygonRing: (SFLineString *) ring{ + return [self closedPolygonPoints:ring.points]; +} + ++(BOOL) closedPolygonPoints: (NSArray *) points{ + BOOL closed = NO; + if(points.count > 0){ + SFPoint *first = [points objectAtIndex:0]; + SFPoint *last = [points objectAtIndex:points.count - 1]; + closed = [first.x compare:last.x] == NSOrderedSame && [first.y compare:last.y] == NSOrderedSame; + } + return closed; +} + ++(BOOL) point: (SFPoint *) point onLine: (SFLineString *) line{ + return [self point:point onLine:line withEpsilon:SF_DEFAULT_LINE_EPSILON]; +} + ++(BOOL) point: (SFPoint *) point onLine: (SFLineString *) line withEpsilon: (double) epsilon{ + return [self point:point onLinePoints:line.points withEpsilon:epsilon]; +} + ++(BOOL) point: (SFPoint *) point onLinePoints: (NSArray *) points{ + return [self point:point onLinePoints:points withEpsilon:SF_DEFAULT_LINE_EPSILON]; +} + ++(BOOL) point: (SFPoint *) point onLinePoints: (NSArray *) points withEpsilon: (double) epsilon{ + return [self point:point onPath:points withEpsilon:epsilon andCircular:NO]; +} + ++(BOOL) point: (SFPoint *) point onPathPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2{ + return [self point:point onPathPoint1:point1 andPoint2:point2 withEpsilon:SF_DEFAULT_LINE_EPSILON]; +} + ++(BOOL) point: (SFPoint *) point onPathPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2 withEpsilon: (double) epsilon{ + + BOOL contains = NO; + + double px = [point.x doubleValue]; + double py = [point.y doubleValue]; + double p1x = [point1.x doubleValue]; + double p1y = [point1.y doubleValue]; + double p2x = [point2.x doubleValue]; + double p2y = [point2.y doubleValue]; + + double x21 = p2x - p1x; + double y21 = p2y - p1y; + double xP1 = px - p1x; + double yP1 = py - p1y; + + double dp = xP1 * x21 + yP1 * y21; + if(dp >= 0.0){ + + double lengthP1 = xP1 * xP1 + yP1 * yP1; + double length21 = x21 * x21 + y21 * y21; + + if(lengthP1 <= length21){ + contains = fabs(dp * dp - lengthP1 * length21) <= epsilon; + } + } + + return contains; +} + ++(BOOL) point: (SFPoint *) point onPath: (NSArray *) points withEpsilon: (double) epsilon andCircular: (BOOL) circular{ + + BOOL onPath = NO; + + int i = 0; + int j = (int)points.count - 1; + if(!circular){ + j = i++; + } + + for(; i < points.count; j= i++){ + SFPoint *point1 = [points objectAtIndex:i]; + SFPoint *point2 = [points objectAtIndex:j]; + if([self point:point onPathPoint1:point1 andPoint2:point2 withEpsilon:epsilon]){ + onPath = YES; + break; + } + } + + return onPath; +} + ++(SFPoint *) intersectionBetweenLine1: (SFLine *) line1 andLine2: (SFLine *) line2{ + return [self intersectionBetweenLine1Point1:[line1 startPoint] andLine1Point2:[line1 endPoint] andLine2Point1:[line2 startPoint] andLine2Point2:[line2 endPoint]]; +} + ++(SFPoint *) intersectionBetweenLine1Point1: (SFPoint *) line1Point1 andLine1Point2: (SFPoint *) line1Point2 andLine2Point1: (SFPoint *) line2Point1 andLine2Point2: (SFPoint *) line2Point2{ + + SFPoint *intersection = nil; + + double a1 = [line1Point2.y doubleValue] - [line1Point1.y doubleValue]; + double b1 = [line1Point1.x doubleValue] - [line1Point2.x doubleValue]; + double c1 = a1 * [line1Point1.x doubleValue] + b1 * [line1Point1.y doubleValue]; + + double a2 = [line2Point2.y doubleValue] - [line2Point1.y doubleValue]; + double b2 = [line2Point1.x doubleValue] - [line2Point2.x doubleValue]; + double c2 = a2 * [line2Point1.x doubleValue] + b2 * [line2Point1.y doubleValue]; + + double determinant = a1 * b2 - a2 * b1; + + if (determinant != 0) { + double x = (b2 * c1 - b1 * c2) / determinant; + double y = (a1 * c2 - a2 * c1) / determinant; + intersection = [SFPoint pointWithXValue:x andYValue:y]; + } + + return intersection; +} + ++(SFGeometry *) degreesToMetersWithGeometry: (SFGeometry *) geometry{ + + SFGeometry *meters = nil; + + switch (geometry.geometryType) { + case SF_POINT: + meters = [self degreesToMetersWithPoint:(SFPoint *) geometry]; + break; + case SF_LINESTRING: + meters = [self degreesToMetersWithLineString:(SFLineString *) geometry]; + break; + case SF_POLYGON: + meters = [self degreesToMetersWithPolygon:(SFPolygon *) geometry]; + break; + case SF_MULTIPOINT: + meters = [self degreesToMetersWithMultiPoint:(SFMultiPoint *) geometry]; + break; + case SF_MULTILINESTRING: + meters = [self degreesToMetersWithMultiLineString:(SFMultiLineString *) geometry]; + break; + case SF_MULTIPOLYGON: + meters = [self degreesToMetersWithMultiPolygon:(SFMultiPolygon *) geometry]; + break; + case SF_CIRCULARSTRING: + meters = [self degreesToMetersWithCircularString:(SFCircularString *) geometry]; + break; + case SF_COMPOUNDCURVE: + meters = [self degreesToMetersWithCompoundCurve:(SFCompoundCurve *) geometry]; + break; + case SF_CURVEPOLYGON: + meters = [self degreesToMetersWithCurvePolygon:(SFCurvePolygon *) geometry]; + break; + case SF_POLYHEDRALSURFACE: + meters = [self degreesToMetersWithPolyhedralSurface:(SFPolyhedralSurface *) geometry]; + break; + case SF_TIN: + meters = [self degreesToMetersWithTIN:(SFTIN *) geometry]; + break; + case SF_TRIANGLE: + meters = [self degreesToMetersWithTriangle:(SFTriangle *) geometry]; + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + { + SFGeometryCollection *metersCollection = [SFGeometryCollection geometryCollection]; + SFGeometryCollection *geomCollection = (SFGeometryCollection *) geometry; + for (SFGeometry *subGeometry in geomCollection.geometries) { + [metersCollection addGeometry:[self degreesToMetersWithGeometry:subGeometry]]; + } + meters = metersCollection; + } + break; + default: + break; + + } + + return meters; +} + ++(SFPoint *) degreesToMetersWithPoint: (SFPoint *) point{ + SFPoint *value = [self degreesToMetersWithX:[point.x doubleValue] andY:[point.y doubleValue]]; + [value setZ:point.z]; + [value setM:point.m]; + return value; +} + ++(SFPoint *) degreesToMetersWithX: (double) x andY: (double) y{ + x = [self normalizeX:x withMaxX:SF_WGS84_HALF_WORLD_LON_WIDTH]; + y = MIN(y, SF_WGS84_HALF_WORLD_LAT_HEIGHT); + y = MAX(y, SF_DEGREES_TO_METERS_MIN_LAT); + double xValue = x * SF_WEB_MERCATOR_HALF_WORLD_WIDTH + / SF_WGS84_HALF_WORLD_LON_WIDTH; + double yValue = log(tan( + (SF_WGS84_HALF_WORLD_LAT_HEIGHT + y) * M_PI + / (2 * SF_WGS84_HALF_WORLD_LON_WIDTH))) + / (M_PI / SF_WGS84_HALF_WORLD_LON_WIDTH); + yValue = yValue * SF_WEB_MERCATOR_HALF_WORLD_WIDTH + / SF_WGS84_HALF_WORLD_LON_WIDTH; + return [SFPoint pointWithXValue:xValue andYValue:yValue]; +} + ++(SFMultiPoint *) degreesToMetersWithMultiPoint: (SFMultiPoint *) multiPoint{ + SFMultiPoint *meters = [SFMultiPoint multiPointWithHasZ:multiPoint.hasZ andHasM:multiPoint.hasM]; + for(SFPoint *point in [multiPoint points]){ + [meters addPoint:[self degreesToMetersWithPoint:point]]; + } + return meters; +} + ++(SFLineString *) degreesToMetersWithLineString: (SFLineString *) lineString{ + SFLineString *meters = [SFLineString lineStringWithHasZ:lineString.hasZ andHasM:lineString.hasM]; + for(SFPoint *point in [lineString points]){ + [meters addPoint:[self degreesToMetersWithPoint:point]]; + } + return meters; +} + ++(SFLine *) degreesToMetersWithLine: (SFLine *) line{ + SFLine *meters = [SFLine lineWithHasZ:line.hasZ andHasM:line.hasM]; + for(SFPoint *point in [line points]){ + [meters addPoint:[self degreesToMetersWithPoint:point]]; + } + return meters; +} + ++(SFMultiLineString *) degreesToMetersWithMultiLineString: (SFMultiLineString *) multiLineString{ + SFMultiLineString *meters = [SFMultiLineString multiLineStringWithHasZ:multiLineString.hasZ andHasM:multiLineString.hasM]; + for(SFLineString *lineString in [multiLineString lineStrings]){ + [meters addLineString:[self degreesToMetersWithLineString:lineString]]; + } + return meters; +} + ++(SFPolygon *) degreesToMetersWithPolygon: (SFPolygon *) polygon{ + SFPolygon *meters = [SFPolygon polygonWithHasZ:polygon.hasZ andHasM:polygon.hasM]; + for(SFLineString *ring in [polygon rings]){ + [meters addRing:[self degreesToMetersWithLineString:ring]]; + } + return meters; +} + ++(SFMultiPolygon *) degreesToMetersWithMultiPolygon: (SFMultiPolygon *) multiPolygon{ + SFMultiPolygon *meters = [SFMultiPolygon multiPolygonWithHasZ:multiPolygon.hasZ andHasM:multiPolygon.hasM]; + for(SFPolygon *polygon in [multiPolygon polygons]){ + [meters addPolygon:[self degreesToMetersWithPolygon:polygon]]; + } + return meters; +} + ++(SFCircularString *) degreesToMetersWithCircularString: (SFCircularString *) circularString{ + SFCircularString *meters = [SFCircularString circularStringWithHasZ:circularString.hasZ andHasM:circularString.hasM]; + for(SFPoint *point in [circularString points]){ + [meters addPoint:[self degreesToMetersWithPoint:point]]; + } + return meters; +} + ++(SFCompoundCurve *) degreesToMetersWithCompoundCurve: (SFCompoundCurve *) compoundCurve{ + SFCompoundCurve *meters = [SFCompoundCurve compoundCurveWithHasZ:compoundCurve.hasZ andHasM:compoundCurve.hasM]; + for(SFLineString *lineString in [compoundCurve lineStrings]){ + [meters addLineString:[self degreesToMetersWithLineString:lineString]]; + } + return meters; +} + ++(SFCurvePolygon *) degreesToMetersWithCurvePolygon: (SFCurvePolygon *) curvePolygon{ + SFCurvePolygon *meters = [SFCurvePolygon curvePolygonWithHasZ:curvePolygon.hasZ andHasM:curvePolygon.hasM]; + for(SFCurve *ring in [curvePolygon rings]){ + [meters addRing:(SFCurve *)[self degreesToMetersWithGeometry:ring]]; + } + return meters; +} + ++(SFPolyhedralSurface *) degreesToMetersWithPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface{ + SFPolyhedralSurface *meters = [SFPolyhedralSurface polyhedralSurfaceWithHasZ:polyhedralSurface.hasZ andHasM:polyhedralSurface.hasM]; + for(SFPolygon *polygon in [polyhedralSurface polygons]){ + [meters addPolygon:[self degreesToMetersWithPolygon:polygon]]; + } + return meters; +} + ++(SFTIN *) degreesToMetersWithTIN: (SFTIN *) tin{ + SFTIN *meters = [SFTIN tinWithHasZ:tin.hasZ andHasM:tin.hasM]; + for(SFPolygon *polygon in [tin polygons]){ + [meters addPolygon:[self degreesToMetersWithPolygon:polygon]]; + } + return meters; +} + ++(SFTriangle *) degreesToMetersWithTriangle: (SFTriangle *) triangle{ + SFTriangle *meters = [SFTriangle triangleWithHasZ:triangle.hasZ andHasM:triangle.hasM]; + for(SFLineString *ring in [triangle rings]){ + [meters addRing:[self degreesToMetersWithLineString:ring]]; + } + return meters; +} + ++(SFGeometry *) metersToDegreesWithGeometry: (SFGeometry *) geometry{ + + SFGeometry *degrees = nil; + + switch (geometry.geometryType) { + case SF_POINT: + degrees = [self metersToDegreesWithPoint:(SFPoint *) geometry]; + break; + case SF_LINESTRING: + degrees = [self metersToDegreesWithLineString:(SFLineString *) geometry]; + break; + case SF_POLYGON: + degrees = [self metersToDegreesWithPolygon:(SFPolygon *) geometry]; + break; + case SF_MULTIPOINT: + degrees = [self metersToDegreesWithMultiPoint:(SFMultiPoint *) geometry]; + break; + case SF_MULTILINESTRING: + degrees = [self metersToDegreesWithMultiLineString:(SFMultiLineString *) geometry]; + break; + case SF_MULTIPOLYGON: + degrees = [self metersToDegreesWithMultiPolygon:(SFMultiPolygon *) geometry]; + break; + case SF_CIRCULARSTRING: + degrees = [self metersToDegreesWithCircularString:(SFCircularString *) geometry]; + break; + case SF_COMPOUNDCURVE: + degrees = [self metersToDegreesWithCompoundCurve:(SFCompoundCurve *) geometry]; + break; + case SF_CURVEPOLYGON: + degrees = [self metersToDegreesWithCurvePolygon:(SFCurvePolygon *) geometry]; + break; + case SF_POLYHEDRALSURFACE: + degrees = [self metersToDegreesWithPolyhedralSurface:(SFPolyhedralSurface *) geometry]; + break; + case SF_TIN: + degrees = [self metersToDegreesWithTIN:(SFTIN *) geometry]; + break; + case SF_TRIANGLE: + degrees = [self metersToDegreesWithTriangle:(SFTriangle *) geometry]; + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + { + SFGeometryCollection *degreesCollection = [SFGeometryCollection geometryCollection]; + SFGeometryCollection *geomCollection = (SFGeometryCollection *) geometry; + for (SFGeometry *subGeometry in geomCollection.geometries) { + [degreesCollection addGeometry:[self metersToDegreesWithGeometry:subGeometry]]; + } + degrees = degreesCollection; + } + break; + default: + break; + + } + + return degrees; +} + ++(SFPoint *) metersToDegreesWithPoint: (SFPoint *) point{ + SFPoint *value = [self metersToDegreesWithX:[point.x doubleValue] andY:[point.y doubleValue]]; + [value setZ:point.z]; + [value setM:point.m]; + return value; +} + ++(SFPoint *) metersToDegreesWithX: (double) x andY: (double) y{ + double xValue = x * SF_WGS84_HALF_WORLD_LON_WIDTH + / SF_WEB_MERCATOR_HALF_WORLD_WIDTH; + double yValue = y * SF_WGS84_HALF_WORLD_LON_WIDTH + / SF_WEB_MERCATOR_HALF_WORLD_WIDTH; + yValue = atan(exp(yValue + * (M_PI / SF_WGS84_HALF_WORLD_LON_WIDTH))) + / M_PI * (2 * SF_WGS84_HALF_WORLD_LON_WIDTH) + - SF_WGS84_HALF_WORLD_LAT_HEIGHT; + return [SFPoint pointWithXValue:xValue andYValue:yValue]; +} + ++(SFMultiPoint *) metersToDegreesWithMultiPoint: (SFMultiPoint *) multiPoint{ + SFMultiPoint *degrees = [SFMultiPoint multiPointWithHasZ:multiPoint.hasZ andHasM:multiPoint.hasM]; + for(SFPoint *point in [multiPoint points]){ + [degrees addPoint:[self metersToDegreesWithPoint:point]]; + } + return degrees; +} + ++(SFLineString *) metersToDegreesWithLineString: (SFLineString *) lineString{ + SFLineString *degrees = [SFLineString lineStringWithHasZ:lineString.hasZ andHasM:lineString.hasM]; + for(SFPoint *point in lineString.points){ + [degrees addPoint:[self metersToDegreesWithPoint:point]]; + } + return degrees; +} + ++(SFLine *) metersToDegreesWithLine: (SFLine *) line{ + SFLine *degrees = [SFLine lineWithHasZ:line.hasZ andHasM:line.hasM]; + for(SFPoint *point in line.points){ + [degrees addPoint:[self metersToDegreesWithPoint:point]]; + } + return degrees; +} + ++(SFMultiLineString *) metersToDegreesWithMultiLineString: (SFMultiLineString *) multiLineString{ + SFMultiLineString *degrees = [SFMultiLineString multiLineStringWithHasZ:multiLineString.hasZ andHasM:multiLineString.hasM]; + for(SFLineString *lineString in [multiLineString lineStrings]){ + [degrees addLineString:[self metersToDegreesWithLineString:lineString]]; + } + return degrees; +} + ++(SFPolygon *) metersToDegreesWithPolygon: (SFPolygon *) polygon{ + SFPolygon *degrees = [SFPolygon polygonWithHasZ:polygon.hasZ andHasM:polygon.hasM]; + for(SFLineString *ring in polygon.rings){ + [degrees addRing:[self metersToDegreesWithLineString:ring]]; + } + return degrees; +} + ++(SFMultiPolygon *) metersToDegreesWithMultiPolygon: (SFMultiPolygon *) multiPolygon{ + SFMultiPolygon *degrees = [SFMultiPolygon multiPolygonWithHasZ:multiPolygon.hasZ andHasM:multiPolygon.hasM]; + for(SFPolygon *polygon in [multiPolygon polygons]){ + [degrees addPolygon:[self metersToDegreesWithPolygon:polygon]]; + } + return degrees; +} + ++(SFCircularString *) metersToDegreesWithCircularString: (SFCircularString *) circularString{ + SFCircularString *degrees = [SFCircularString circularStringWithHasZ:circularString.hasZ andHasM:circularString.hasM]; + for(SFPoint *point in circularString.points){ + [degrees addPoint:[self metersToDegreesWithPoint:point]]; + } + return degrees; +} + ++(SFCompoundCurve *) metersToDegreesWithCompoundCurve: (SFCompoundCurve *) compoundCurve{ + SFCompoundCurve *degrees = [SFCompoundCurve compoundCurveWithHasZ:compoundCurve.hasZ andHasM:compoundCurve.hasM]; + for(SFLineString *lineString in compoundCurve.lineStrings){ + [degrees addLineString:[self metersToDegreesWithLineString:lineString]]; + } + return degrees; +} + ++(SFCurvePolygon *) metersToDegreesWithCurvePolygon: (SFCurvePolygon *) curvePolygon{ + SFCurvePolygon *degrees = [SFCurvePolygon curvePolygonWithHasZ:curvePolygon.hasZ andHasM:curvePolygon.hasM]; + for(SFCurve *ring in curvePolygon.rings){ + [degrees addRing:(SFCurve *) [self metersToDegreesWithGeometry:ring]]; + } + return degrees; +} + ++(SFPolyhedralSurface *) metersToDegreesWithPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface{ + SFPolyhedralSurface *degrees = [SFPolyhedralSurface polyhedralSurfaceWithHasZ:polyhedralSurface.hasZ andHasM:polyhedralSurface.hasM]; + for(SFPolygon *polygon in polyhedralSurface.polygons){ + [degrees addPolygon:[self metersToDegreesWithPolygon:polygon]]; + } + return degrees; +} + ++(SFTIN *) metersToDegreesWithTIN: (SFTIN *) tin{ + SFTIN *degrees = [SFTIN tinWithHasZ:tin.hasZ andHasM:tin.hasM]; + for(SFPolygon *polygon in tin.polygons){ + [degrees addPolygon:[self metersToDegreesWithPolygon:polygon]]; + } + return degrees; +} + ++(SFTriangle *) metersToDegreesWithTriangle: (SFTriangle *) triangle{ + SFTriangle *degrees = [SFTriangle triangleWithHasZ:triangle.hasZ andHasM:triangle.hasM]; + for(SFLineString *ring in triangle.rings){ + [degrees addRing:[self metersToDegreesWithLineString:ring]]; + } + return degrees; +} + ++(SFGeometryEnvelope *) wgs84Envelope{ + return [SFGeometryEnvelope envelopeWithMinXValue:-SF_WGS84_HALF_WORLD_LON_WIDTH andMinYValue:-SF_WGS84_HALF_WORLD_LAT_HEIGHT andMaxXValue:SF_WGS84_HALF_WORLD_LON_WIDTH andMaxYValue:SF_WGS84_HALF_WORLD_LAT_HEIGHT]; +} + ++(SFGeometryEnvelope *) wgs84TransformableEnvelope{ + return [SFGeometryEnvelope envelopeWithMinXValue:-SF_WGS84_HALF_WORLD_LON_WIDTH andMinYValue:SF_DEGREES_TO_METERS_MIN_LAT andMaxXValue:SF_WGS84_HALF_WORLD_LON_WIDTH andMaxYValue:SF_WGS84_HALF_WORLD_LAT_HEIGHT]; +} + ++(SFGeometryEnvelope *) webMercatorEnvelope{ + return [SFGeometryEnvelope envelopeWithMinXValue:-SF_WEB_MERCATOR_HALF_WORLD_WIDTH andMinYValue:-SF_WEB_MERCATOR_HALF_WORLD_WIDTH andMaxXValue:SF_WEB_MERCATOR_HALF_WORLD_WIDTH andMaxYValue:SF_WEB_MERCATOR_HALF_WORLD_WIDTH]; +} + ++(SFGeometryEnvelope *) wgs84EnvelopeWithWebMercator{ + return [SFGeometryEnvelope envelopeWithMinXValue:-SF_WGS84_HALF_WORLD_LON_WIDTH andMinYValue:SF_WEB_MERCATOR_MIN_LAT_RANGE andMaxXValue:SF_WGS84_HALF_WORLD_LON_WIDTH andMaxYValue:SF_WEB_MERCATOR_MAX_LAT_RANGE]; +} + ++(SFGeometry *) cropWebMercatorGeometry: (SFGeometry *) geometry{ + return [self cropGeometry:geometry withEnvelope:[self webMercatorEnvelope]]; +} + ++(SFGeometry *) cropGeometry: (SFGeometry *) geometry withEnvelope: (SFGeometryEnvelope *) envelope{ + + SFGeometry *crop = nil; + + if([self containsEnvelope:geometry.envelope withinEnvelope:envelope]){ + crop = geometry; + }else{ + + switch (geometry.geometryType) { + case SF_POINT: + crop = [self cropPoint:(SFPoint *) geometry withEnvelope:envelope]; + break; + case SF_LINESTRING: + crop = [self cropLineString:(SFLineString *) geometry withEnvelope:envelope]; + break; + case SF_POLYGON: + crop = [self cropPolygon:(SFPolygon *) geometry withEnvelope:envelope]; + break; + case SF_MULTIPOINT: + crop = [self cropMultiPoint:(SFMultiPoint *) geometry withEnvelope:envelope]; + break; + case SF_MULTILINESTRING: + crop = [self cropMultiLineString:(SFMultiLineString *) geometry withEnvelope:envelope]; + break; + case SF_MULTIPOLYGON: + crop = [self cropMultiPolygon:(SFMultiPolygon *) geometry withEnvelope:envelope]; + break; + case SF_CIRCULARSTRING: + crop = [self cropCircularString:(SFCircularString *) geometry withEnvelope:envelope]; + break; + case SF_COMPOUNDCURVE: + crop = [self cropCompoundCurve:(SFCompoundCurve *) geometry withEnvelope:envelope]; + break; + case SF_CURVEPOLYGON: + crop = [self cropCurvePolygon:(SFCurvePolygon *) geometry withEnvelope:envelope]; + break; + case SF_POLYHEDRALSURFACE: + crop = [self cropPolyhedralSurface:(SFPolyhedralSurface *) geometry withEnvelope:envelope]; + break; + case SF_TIN: + crop = [self cropTIN:(SFTIN *) geometry withEnvelope:envelope]; + break; + case SF_TRIANGLE: + crop = [self cropTriangle:(SFTriangle *) geometry withEnvelope:envelope]; + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + { + SFGeometryCollection *cropCollection = [SFGeometryCollection geometryCollection]; + SFGeometryCollection *geomCollection = (SFGeometryCollection *) geometry; + for (SFGeometry *subGeometry in geomCollection.geometries) { + [cropCollection addGeometry:[self cropGeometry:subGeometry withEnvelope:envelope]]; + } + crop = cropCollection; + } + break; + default: + break; + + } + } + + return crop; +} + ++(SFPoint *) cropPoint: (SFPoint *) point withEnvelope: (SFGeometryEnvelope *) envelope{ + SFPoint *crop = nil; + if([self containsPoint:point withinEnvelope:envelope]){ + crop = [point mutableCopy]; + } + return crop; +} + ++(NSMutableArray *) cropPoints: (NSArray *) points withEnvelope: (SFGeometryEnvelope *) envelope{ + + NSMutableArray *crop = [NSMutableArray array]; + + SFLine *left = [envelope left]; + SFLine *bottom = [envelope bottom]; + SFLine *right = [envelope right]; + SFLine *top = [envelope top]; + + SFPoint *previousPoint = nil; + BOOL previousContains = NO; + for(SFPoint *point in points){ + BOOL contains = [self containsPoint:point withinEnvelope:envelope]; + + if(previousPoint != nil && (!contains || !previousContains)){ + + SFLine *line = [SFLine lineWithPoint1:previousPoint andPoint2:point]; + double bearing = [self bearingOfLine:[self metersToDegreesWithLine:line]]; + + BOOL westBearing = [self isWestBearing:bearing]; + BOOL eastBearing = [self isEastBearing:bearing]; + BOOL southBearing = [self isSouthBearing:bearing]; + BOOL northBearing = [self isNorthBearing:bearing]; + + SFLine *vertLine = nil; + if([point.x doubleValue] > [envelope.maxX doubleValue]){ + if(eastBearing){ + vertLine = right; + } + }else if([point.x doubleValue] < [envelope.minX doubleValue]){ + if(westBearing){ + vertLine = left; + } + }else if(eastBearing){ + vertLine = left; + }else if(westBearing){ + vertLine = right; + } + + SFLine *horizLine = nil; + if([point.y doubleValue] > [envelope.maxY doubleValue]){ + if(northBearing){ + horizLine = top; + } + }else if([point.y doubleValue] < [envelope.minY doubleValue]){ + if(southBearing){ + horizLine = bottom; + } + }else if(northBearing){ + horizLine = bottom; + }else if(southBearing){ + horizLine = top; + } + + SFPoint *vertIntersection = nil; + if(vertLine != nil){ + vertIntersection = [self intersectionBetweenLine1:line andLine2:vertLine]; + if(vertIntersection != nil && ![self containsPoint:vertIntersection withinEnvelope:envelope]){ + vertIntersection = nil; + } + } + + SFPoint *horizIntersection = nil; + if(horizLine != nil){ + horizIntersection = [self intersectionBetweenLine1:line andLine2:horizLine]; + if(horizIntersection != nil && ![self containsPoint:horizIntersection withinEnvelope:envelope]){ + horizIntersection = nil; + } + } + + SFPoint *intersection1 = nil; + SFPoint *intersection2 = nil; + if(vertIntersection != nil && horizIntersection != nil){ + double vertDistance = [self distanceBetweenPoint1:previousPoint andPoint2:vertIntersection]; + double horizDistance = [self distanceBetweenPoint1:previousPoint andPoint2:horizIntersection]; + if(vertDistance <= horizDistance){ + intersection1 = vertIntersection; + intersection2 = horizIntersection; + }else{ + intersection1 = horizIntersection; + intersection2 = vertIntersection; + } + }else if(vertIntersection != nil){ + intersection1 = vertIntersection; + }else{ + intersection1 = horizIntersection; + } + + if(intersection1 != nil && ![self isEqualWithPoint1:intersection1 andPoint2:point] && ![self isEqualWithPoint1:intersection1 andPoint2:previousPoint]){ + + [crop addObject:intersection1]; + + if(!contains && !previousContains && intersection2 != nil && ![self isEqualWithPoint1:intersection2 andPoint2:intersection1]){ + [crop addObject:intersection2]; + } + } + + } + + if(contains){ + [crop addObject:point]; + } + + previousPoint = point; + previousContains = contains; + } + + if(crop.count == 0){ + crop = nil; + }else if(crop.count > 1){ + + if([[points firstObject] isEqual:[points lastObject]] && ![[crop firstObject] isEqual:[crop lastObject]] ){ + [crop addObject:[[crop firstObject] mutableCopy]]; + } + + if(crop.count > 2){ + + NSMutableArray *simplified = [NSMutableArray array]; + [simplified addObject:[crop firstObject]]; + for(int i = 1; i < crop.count - 1; i++){ + SFPoint *previous = [simplified lastObject]; + SFPoint *point = [crop objectAtIndex:i]; + SFPoint *next = [crop objectAtIndex:i + 1]; + if(![self point:point onPathPoint1:previous andPoint2:next]){ + [simplified addObject:point]; + } + } + [simplified addObject:[crop lastObject]]; + crop = simplified; + + } + + } + + return crop; +} + ++(SFMultiPoint *) cropMultiPoint: (SFMultiPoint *) multiPoint withEnvelope: (SFGeometryEnvelope *) envelope{ + SFMultiPoint *crop = nil; + NSMutableArray *cropPoints = [NSMutableArray array]; + for(SFPoint *point in [multiPoint points]){ + SFPoint *cropPoint = [self cropPoint:point withEnvelope:envelope]; + if(cropPoint != nil){ + [cropPoints addObject:cropPoint]; + } + } + if(cropPoints.count != 0){ + crop = [SFMultiPoint multiPointWithHasZ:multiPoint.hasZ andHasM:multiPoint.hasM]; + [crop setPoints:cropPoints]; + } + return crop; +} + ++(SFLineString *) cropLineString: (SFLineString *) lineString withEnvelope: (SFGeometryEnvelope *) envelope{ + SFLineString *crop = nil; + NSMutableArray *cropPoints = [self cropPoints:lineString.points withEnvelope:envelope]; + if(cropPoints != nil){ + crop = [SFLineString lineStringWithHasZ:lineString.hasZ andHasM:lineString.hasM]; + [crop setPoints:cropPoints]; + } + return crop; +} + ++(SFLine *) cropLine: (SFLine *) line withEnvelope: (SFGeometryEnvelope *) envelope{ + SFLine *crop = nil; + NSMutableArray *cropPoints = [self cropPoints:line.points withEnvelope:envelope]; + if(cropPoints != nil){ + crop = [SFLine lineWithHasZ:line.hasZ andHasM:line.hasM]; + [crop setPoints:cropPoints]; + } + return crop; +} + ++(SFMultiLineString *) cropMultiLineString: (SFMultiLineString *) multiLineString withEnvelope: (SFGeometryEnvelope *) envelope{ + SFMultiLineString *crop = nil; + NSMutableArray *cropLineStrings = [NSMutableArray array]; + for(SFLineString *lineString in [multiLineString lineStrings]){ + SFLineString *cropLineString = [self cropLineString:lineString withEnvelope:envelope]; + if(cropLineString != nil){ + [cropLineStrings addObject:cropLineString]; + } + } + if(cropLineStrings.count != 0){ + crop = [SFMultiLineString multiLineStringWithHasZ:multiLineString.hasZ andHasM:multiLineString.hasM]; + [crop setLineStrings:cropLineStrings]; + } + return crop; +} + ++(SFPolygon *) cropPolygon: (SFPolygon *) polygon withEnvelope: (SFGeometryEnvelope *) envelope{ + SFPolygon *crop = nil; + NSMutableArray *cropRings = [NSMutableArray array]; + for(SFLineString *ring in polygon.rings){ + NSMutableArray *points = ring.points; + if(![ring isClosed]){ + [points addObject:[[points firstObject] mutableCopy]]; + } + NSMutableArray *cropPoints = [self cropPoints:points withEnvelope:envelope]; + if(cropPoints != nil){ + SFLineString *cropRing = [SFLineString lineStringWithHasZ:ring.hasZ andHasM:ring.hasM]; + [cropRing setPoints:cropPoints]; + [cropRings addObject:cropRing]; + } + } + if(cropRings.count != 0){ + crop = [SFPolygon polygonWithHasZ:polygon.hasZ andHasM:polygon.hasM]; + [crop setRings:cropRings]; + } + return crop; +} + ++(SFMultiPolygon *) cropMultiPolygon: (SFMultiPolygon *) multiPolygon withEnvelope: (SFGeometryEnvelope *) envelope{ + SFMultiPolygon *crop = nil; + NSMutableArray *cropPolygons = [NSMutableArray array]; + for(SFPolygon *polygon in [multiPolygon polygons]){ + SFPolygon *cropPolygon = [self cropPolygon:polygon withEnvelope:envelope]; + if(cropPolygon != nil){ + [cropPolygons addObject:cropPolygon]; + } + } + if(cropPolygons.count != 0){ + crop = [SFMultiPolygon multiPolygonWithHasZ:multiPolygon.hasZ andHasM:multiPolygon.hasM]; + [crop setPolygons:cropPolygons]; + } + return crop; +} + ++(SFCircularString *) cropCircularString: (SFCircularString *) circularString withEnvelope: (SFGeometryEnvelope *) envelope{ + SFCircularString *crop = nil; + NSMutableArray *cropPoints = [self cropPoints:circularString.points withEnvelope:envelope]; + if(cropPoints != nil){ + crop = [SFCircularString circularStringWithHasZ:circularString.hasZ andHasM:circularString.hasM]; + [crop setPoints:cropPoints]; + } + return crop; +} + ++(SFCompoundCurve *) cropCompoundCurve: (SFCompoundCurve *) compoundCurve withEnvelope: (SFGeometryEnvelope *) envelope{ + SFCompoundCurve *crop = nil; + NSMutableArray *cropLineStrings = [NSMutableArray array]; + for(SFLineString *lineString in compoundCurve.lineStrings){ + SFLineString *cropLineString = [self cropLineString:lineString withEnvelope:envelope]; + if(cropLineString != nil){ + [cropLineStrings addObject:cropLineString]; + } + } + if(cropLineStrings.count != 0){ + crop = [SFCompoundCurve compoundCurveWithHasZ:compoundCurve.hasZ andHasM:compoundCurve.hasM]; + [crop setLineStrings:cropLineStrings]; + } + return crop; +} + ++(SFCurvePolygon *) cropCurvePolygon: (SFCurvePolygon *) curvePolygon withEnvelope: (SFGeometryEnvelope *) envelope{ + SFCurvePolygon *crop = nil; + NSMutableArray *cropRings = [NSMutableArray array]; + for(SFCurve *ring in curvePolygon.rings){ + SFGeometry *cropRing = [self cropGeometry:ring withEnvelope:envelope]; + if(cropRing != nil){ + [cropRings addObject:(SFCurve *) cropRing]; + } + } + if(cropRings.count != 0){ + crop = [SFCurvePolygon curvePolygonWithHasZ:curvePolygon.hasZ andHasM:curvePolygon.hasM]; + [crop setRings:cropRings]; + } + return crop; +} + ++(SFPolyhedralSurface *) cropPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface withEnvelope: (SFGeometryEnvelope *) envelope{ + SFPolyhedralSurface *crop = nil; + NSMutableArray *cropPolygons = [NSMutableArray array]; + for(SFPolygon *polygon in polyhedralSurface.polygons){ + SFPolygon *cropPolygon = [self cropPolygon:polygon withEnvelope:envelope]; + if(cropPolygon != nil){ + [cropPolygons addObject:cropPolygon]; + } + } + if(cropPolygons.count != 0){ + crop = [SFPolyhedralSurface polyhedralSurfaceWithHasZ:polyhedralSurface.hasZ andHasM:polyhedralSurface.hasM]; + [crop setPolygons:cropPolygons]; + } + return crop; +} + ++(SFTIN *) cropTIN: (SFTIN *) tin withEnvelope: (SFGeometryEnvelope *) envelope{ + SFTIN *crop = nil; + NSMutableArray *cropPolygons = [NSMutableArray array]; + for(SFPolygon *polygon in tin.polygons){ + SFPolygon *cropPolygon = [self cropPolygon:polygon withEnvelope:envelope]; + if(cropPolygon != nil){ + [cropPolygons addObject:cropPolygon]; + } + } + if(cropPolygons.count != 0){ + crop = [SFTIN tinWithHasZ:tin.hasZ andHasM:tin.hasM]; + [crop setPolygons:cropPolygons]; + } + return crop; +} + ++(SFTriangle *) cropTriangle: (SFTriangle *) triangle withEnvelope: (SFGeometryEnvelope *) envelope{ + SFTriangle *crop = nil; + NSMutableArray *cropRings = [NSMutableArray array]; + for(SFLineString *ring in triangle.rings){ + NSMutableArray *points = ring.points; + if(![ring isClosed]){ + [points addObject:[[points firstObject] mutableCopy]]; + } + NSMutableArray *cropPoints = [self cropPoints:points withEnvelope:envelope]; + if(cropPoints != nil){ + SFLineString *cropRing = [SFLineString lineStringWithHasZ:ring.hasZ andHasM:ring.hasM]; + [cropRing setPoints:cropPoints]; + [cropRings addObject:cropRing]; + } + } + if(cropRings.count != 0){ + crop = [SFTriangle triangleWithHasZ:triangle.hasZ andHasM:triangle.hasM]; + [crop setRings:cropRings]; + } + return crop; +} + ++(BOOL) isEqualWithPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2{ + return [self isEqualWithPoint1:point1 andPoint2:point2 andEpsilon:SF_DEFAULT_EQUAL_EPSILON]; +} + ++(BOOL) isEqualWithPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2 andEpsilon: (double) epsilon{ + BOOL equal = fabs([point1.x doubleValue] - [point2.x doubleValue]) <= epsilon && fabs([point1.y doubleValue] - [point2.y doubleValue]) <= epsilon && point1.hasZ == point2.hasZ && point1.hasM == point2.hasM; + if(equal){ + if(point1.hasZ){ + equal = fabs([point1.z doubleValue] - [point2.z doubleValue]) <= epsilon; + } + if(equal && point1.hasM){ + equal = fabs([point1.m doubleValue] - [point2.m doubleValue]) <= epsilon; + } + } + return equal; +} + ++(BOOL) containsPoint: (SFPoint *) point withinEnvelope: (SFGeometryEnvelope *) envelope{ + return [envelope containsPoint:point withEpsilon:SF_DEFAULT_EQUAL_EPSILON]; +} + ++(BOOL) containsEnvelope: (SFGeometryEnvelope *) envelope2 withinEnvelope: (SFGeometryEnvelope *) envelope1{ + return [envelope1 containsEnvelope:envelope2 withEpsilon:SF_DEFAULT_EQUAL_EPSILON]; +} + ++(void) boundWGS84Geometry: (SFGeometry *) geometry{ + [self boundGeometry:geometry withEnvelope:[self wgs84Envelope]]; +} + ++(void) boundWGS84TransformableGeometry: (SFGeometry *) geometry{ + [self boundGeometry:geometry withEnvelope:[self wgs84TransformableEnvelope]]; +} + ++(void) boundWebMercatorGeometry: (SFGeometry *) geometry{ + [self boundGeometry:geometry withEnvelope:[self webMercatorEnvelope]]; +} + ++(void) boundWGS84WithWebMercatorGeometry: (SFGeometry *) geometry{ + [self boundGeometry:geometry withEnvelope:[self wgs84EnvelopeWithWebMercator]]; +} + ++(void) boundGeometry: (SFGeometry *) geometry withEnvelope: (SFGeometryEnvelope *) envelope{ + + enum SFGeometryType geometryType = geometry.geometryType; + switch (geometryType) { + case SF_POINT: + [self boundPoint:(SFPoint *)geometry withEnvelope:envelope]; + break; + case SF_LINESTRING: + [self boundLineString:(SFLineString *)geometry withEnvelope:envelope]; + break; + case SF_POLYGON: + [self boundPolygon:(SFPolygon *)geometry withEnvelope:envelope]; + break; + case SF_MULTIPOINT: + [self boundMultiPoint:(SFMultiPoint *)geometry withEnvelope:envelope]; + break; + case SF_MULTILINESTRING: + [self boundMultiLineString:(SFMultiLineString *)geometry withEnvelope:envelope]; + break; + case SF_MULTIPOLYGON: + [self boundMultiPolygon:(SFMultiPolygon *)geometry withEnvelope:envelope]; + break; + case SF_CIRCULARSTRING: + [self boundLineString:(SFCircularString *)geometry withEnvelope:envelope]; + break; + case SF_COMPOUNDCURVE: + [self boundCompoundCurve:(SFCompoundCurve *)geometry withEnvelope:envelope]; + break; + case SF_CURVEPOLYGON: + [self boundCurvePolygon:(SFCurvePolygon *)geometry withEnvelope:envelope]; + break; + case SF_POLYHEDRALSURFACE: + [self boundPolyhedralSurface:(SFPolyhedralSurface *)geometry withEnvelope:envelope]; + break; + case SF_TIN: + [self boundPolyhedralSurface:(SFTIN *)geometry withEnvelope:envelope]; + break; + case SF_TRIANGLE: + [self boundPolygon:(SFTriangle *)geometry withEnvelope:envelope]; + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + { + SFGeometryCollection *geomCollection = (SFGeometryCollection *) geometry; + for (SFGeometry *subGeometry in geomCollection.geometries) { + [self boundGeometry:subGeometry withEnvelope:envelope]; + } + } + break; + default: + break; + + } + +} + ++(void) boundPoint: (SFPoint *) point withEnvelope: (SFGeometryEnvelope *) envelope{ + double x = [point.x doubleValue]; + double y = [point.y doubleValue]; + if(x < [envelope.minX doubleValue]){ + [point setX:envelope.minX]; + }else if(x > [envelope.maxX doubleValue]){ + [point setX:envelope.maxX]; + } + if(y < [envelope.minY doubleValue]){ + [point setY:envelope.minY]; + }else if(y > [envelope.maxY doubleValue]){ + [point setY:envelope.maxY]; + } +} + ++(void) boundMultiPoint: (SFMultiPoint *) multiPoint withEnvelope: (SFGeometryEnvelope *) envelope{ + for(SFPoint *point in [multiPoint points]){ + [self boundPoint:point withEnvelope:envelope]; + } +} + ++(void) boundLineString: (SFLineString *) lineString withEnvelope: (SFGeometryEnvelope *) envelope{ + for(SFPoint *point in lineString.points){ + [self boundPoint:point withEnvelope:envelope]; + } +} + ++(void) boundMultiLineString: (SFMultiLineString *) multiLineString withEnvelope: (SFGeometryEnvelope *) envelope{ + for(SFLineString *lineString in [multiLineString lineStrings]){ + [self boundLineString:lineString withEnvelope:envelope]; + } +} + ++(void) boundPolygon: (SFPolygon *) polygon withEnvelope: (SFGeometryEnvelope *) envelope{ + for(SFLineString *ring in polygon.rings){ + [self boundLineString:ring withEnvelope:envelope]; + } +} + ++(void) boundMultiPolygon: (SFMultiPolygon *) multiPolygon withEnvelope: (SFGeometryEnvelope *) envelope{ + for(SFPolygon *polygon in [multiPolygon polygons]){ + [self boundPolygon:polygon withEnvelope:envelope]; + } +} + ++(void) boundCompoundCurve: (SFCompoundCurve *) compoundCurve withEnvelope: (SFGeometryEnvelope *) envelope{ + for(SFLineString *lineString in compoundCurve.lineStrings){ + [self boundLineString:lineString withEnvelope:envelope]; + } +} + ++(void) boundCurvePolygon: (SFCurvePolygon *) curvePolygon withEnvelope: (SFGeometryEnvelope *) envelope{ + for(SFCurve *ring in curvePolygon.rings){ + [self boundGeometry:ring withEnvelope:envelope]; + } +} + ++(void) boundPolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface withEnvelope: (SFGeometryEnvelope *) envelope{ + for(SFPolygon *polygon in polyhedralSurface.polygons){ + [self boundPolygon:polygon withEnvelope:envelope]; + } +} + ++(BOOL) hasZ: (NSArray *) geometries{ + BOOL hasZ = NO; + for (SFGeometry *geometry in geometries) { + if ([geometry hasZ]) { + hasZ = YES; + break; + } + } + return hasZ; +} + ++(BOOL) hasM: (NSArray *) geometries{ + BOOL hasM = NO; + for (SFGeometry *geometry in geometries) { + if ([geometry hasM]) { + hasM = YES; + break; + } + } + return hasM; +} + ++(NSArray *) parentHierarchyOfType: (enum SFGeometryType) geometryType{ + + NSMutableArray *hierarchy = [NSMutableArray array]; + + enum SFGeometryType parentType = [self parentTypeOfType:geometryType]; + while(parentType != SF_NONE && parentType >= 0){ + [hierarchy addObject:[NSNumber numberWithInt:parentType]]; + parentType = [self parentTypeOfType:parentType]; + } + + return hierarchy; +} + ++(enum SFGeometryType) parentTypeOfType: (enum SFGeometryType) geometryType{ + + enum SFGeometryType parentType = SF_NONE; + + switch(geometryType){ + + case SF_GEOMETRY: + break; + case SF_POINT: + parentType = SF_GEOMETRY; + break; + case SF_LINESTRING: + parentType = SF_CURVE; + break; + case SF_POLYGON: + parentType = SF_CURVEPOLYGON; + break; + case SF_MULTIPOINT: + parentType = SF_GEOMETRYCOLLECTION; + break; + case SF_MULTILINESTRING: + parentType = SF_MULTICURVE; + break; + case SF_MULTIPOLYGON: + parentType = SF_MULTISURFACE; + break; + case SF_GEOMETRYCOLLECTION: + parentType = SF_GEOMETRY; + break; + case SF_CIRCULARSTRING: + parentType = SF_LINESTRING; + break; + case SF_COMPOUNDCURVE: + parentType = SF_CURVE; + break; + case SF_CURVEPOLYGON: + parentType = SF_SURFACE; + break; + case SF_MULTICURVE: + parentType = SF_GEOMETRYCOLLECTION; + break; + case SF_MULTISURFACE: + parentType = SF_GEOMETRYCOLLECTION; + break; + case SF_CURVE: + parentType = SF_GEOMETRY; + break; + case SF_SURFACE: + parentType = SF_GEOMETRY; + break; + case SF_POLYHEDRALSURFACE: + parentType = SF_SURFACE; + break; + case SF_TIN: + parentType = SF_POLYHEDRALSURFACE; + break; + case SF_TRIANGLE: + parentType = SF_POLYGON; + break; + default: + [NSException raise:@"Geometry Type Not Supported" format:@"Geomery Type is not supported: %@", [SFGeometryTypes name:geometryType]]; + } + + return parentType; +} + + ++(NSDictionary *) childHierarchyOfType: (enum SFGeometryType) geometryType{ + + NSMutableDictionary *hierarchy = [NSMutableDictionary dictionary]; + + NSArray *childTypes = [self childTypesOfType:geometryType]; + + if(childTypes.count > 0){ + + for(NSNumber *childTypeNumber in childTypes){ + enum SFGeometryType childType = [childTypeNumber intValue]; + [hierarchy setObject:[self childHierarchyOfType:childType] forKey:childTypeNumber]; + } + } + + return hierarchy; +} + ++(NSArray *) childTypesOfType: (enum SFGeometryType) geometryType{ + + NSMutableArray *childTypes = [NSMutableArray array]; + + switch (geometryType) { + + case SF_GEOMETRY: + [childTypes addObject:[NSNumber numberWithInt:SF_POINT]]; + [childTypes addObject:[NSNumber numberWithInt:SF_GEOMETRYCOLLECTION]]; + [childTypes addObject:[NSNumber numberWithInt:SF_CURVE]]; + [childTypes addObject:[NSNumber numberWithInt:SF_SURFACE]]; + break; + case SF_POINT: + break; + case SF_LINESTRING: + [childTypes addObject:[NSNumber numberWithInt:SF_CIRCULARSTRING]]; + break; + case SF_POLYGON: + [childTypes addObject:[NSNumber numberWithInt:SF_TRIANGLE]]; + break; + case SF_MULTIPOINT: + break; + case SF_MULTILINESTRING: + break; + case SF_MULTIPOLYGON: + break; + case SF_GEOMETRYCOLLECTION: + [childTypes addObject:[NSNumber numberWithInt:SF_MULTIPOINT]]; + [childTypes addObject:[NSNumber numberWithInt:SF_MULTICURVE]]; + [childTypes addObject:[NSNumber numberWithInt:SF_MULTISURFACE]]; + break; + case SF_CIRCULARSTRING: + break; + case SF_COMPOUNDCURVE: + break; + case SF_CURVEPOLYGON: + [childTypes addObject:[NSNumber numberWithInt:SF_POLYGON]]; + break; + case SF_MULTICURVE: + [childTypes addObject:[NSNumber numberWithInt:SF_MULTILINESTRING]]; + break; + case SF_MULTISURFACE: + [childTypes addObject:[NSNumber numberWithInt:SF_MULTIPOLYGON]]; + break; + case SF_CURVE: + [childTypes addObject:[NSNumber numberWithInt:SF_LINESTRING]]; + [childTypes addObject:[NSNumber numberWithInt:SF_COMPOUNDCURVE]]; + break; + case SF_SURFACE: + [childTypes addObject:[NSNumber numberWithInt:SF_CURVEPOLYGON]]; + [childTypes addObject:[NSNumber numberWithInt:SF_POLYHEDRALSURFACE]]; + break; + case SF_POLYHEDRALSURFACE: + [childTypes addObject:[NSNumber numberWithInt:SF_TIN]]; + break; + case SF_TIN: + break; + case SF_TRIANGLE: + break; + default: + [NSException raise:@"Geometry Type Not Supported" format:@"Geomery Type is not supported: %@", [SFGeometryTypes name:geometryType]]; + } + + return childTypes; +} + ++(NSData *) encodeGeometry: (SFGeometry *) geometry{ + NSError *error = nil; + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:geometry requiringSecureCoding:YES error:&error]; + if(error != nil){ + [NSException raise:@"Encode Geometry" format:@"Failed to encode geometry with error: %@", error]; + } + return data; +} + ++(SFGeometry *) decodeGeometry: (NSData *) data{ + NSError *error = nil; + SFGeometry *geometry = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFGeometry class] fromData:data error:&error]; + if(error != nil){ + [NSException raise:@"Decode Geometry" format:@"Failed to decode geometry with error: %@", error]; + } + return geometry; +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFTextReader.h b/Pods/sf-ios/sf-ios/util/SFTextReader.h new file mode 100644 index 0000000..64b7418 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFTextReader.h @@ -0,0 +1,55 @@ +// +// SFTextReader.h +// sf-ios +// +// Created by Brian Osborn on 8/3/20. +// Copyright © 2020 NGA. All rights reserved. +// + +#import + +/** + *Read through text string + */ +@interface SFTextReader : NSObject + +/** + * Initialize + * + * @param text text + * + * @return new text reader + */ +-(instancetype) initWithText: (NSString *) text; + +/** + * Get the text + * + * @return text + */ +-(NSString *) text; + +/** + * Read the next token. Ignores whitespace until a non whitespace character + * is encountered. Returns a contiguous block of token characters ( [a-z] | + * [A-Z] | [0-9] | - | . | + ) or a non whitespace single character. + * + * @return token + */ +-(NSString *) readToken; + +/** + * Peek at the next token without reading past it + * + * @return next token + */ +-(NSString *) peekToken; + +/** + * Read a double + * + * @return double + */ +-(double) readDouble; + +@end diff --git a/Pods/sf-ios/sf-ios/util/SFTextReader.m b/Pods/sf-ios/sf-ios/util/SFTextReader.m new file mode 100644 index 0000000..46fa06e --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/SFTextReader.m @@ -0,0 +1,134 @@ +// +// SFTextReader.m +// sf-ios +// +// Created by Brian Osborn on 8/3/20. +// Copyright © 2020 NGA. All rights reserved. +// + +#import "SFTextReader.h" + +@interface SFTextReader() + +/** + * Text + */ +@property (nonatomic, strong) NSString *text; + +/** + * Next token cache for peeks + */ +@property (nonatomic, strong) NSString *nextToken; + +/** + * Next character number cache for between token caching + */ +@property (nonatomic) int nextCharacterNum; + +@end + +@implementation SFTextReader + +-(instancetype) initWithText: (NSString *) text{ + self = [super init]; + if(self != nil){ + self.text = text; + self.nextCharacterNum = 0; + } + return self; +} + +-(NSString *) text{ + return _text; +} + +-(NSString *) readToken{ + + NSString *token = nil; + + // Get the next token, cached or read + if (_nextToken != nil) { + token = _nextToken; + _nextToken = nil; + } else { + + NSMutableString *buildToken = nil; + + // Continue while characters are left + while (_nextCharacterNum < _text.length) { + + unichar character = [_text characterAtIndex:_nextCharacterNum]; + + // Check if not the first character in the token + if (buildToken != nil) { + + // Append token characters + if ([self isTokenCharacter:character]) { + [buildToken appendFormat:@"%C", character]; + } else { + break; + } + + } else if (![NSCharacterSet.whitespaceAndNewlineCharacterSet characterIsMember:character]) { + + // First non whitespace character in the token + buildToken = [NSMutableString stringWithFormat:@"%C", character]; + + // Complete token if a single character token + if(![self isTokenCharacter:character]){ + _nextCharacterNum++; + break; + } + + } + + // Continue to the next character + _nextCharacterNum++; + } + + if (buildToken != nil) { + token = buildToken; + } + + } + return token; +} + +-(NSString *) peekToken{ + if (_nextToken == nil) { + _nextToken = [self readToken]; + } + return _nextToken; +} + +-(double) readDouble{ + NSString *token = [self readToken]; + if (token == nil) { + [NSException raise:@"Expected Double" format:@"Failed to read expected double value"]; + } + double value; + if([token caseInsensitiveCompare:@"NaN"] == NSOrderedSame){ + value = NAN; + }else if([token caseInsensitiveCompare:@"infinity"] == NSOrderedSame){ + value = INFINITY; + }else if([token caseInsensitiveCompare:@"-infinity"] == NSOrderedSame){ + value = -INFINITY; + }else{ + value = [token doubleValue]; + } + return value; +} + +/** + * Check if the character is a contiguous block token character: ( [a-z] | + * [A-Z] | [0-9] | - | . | + ) + * + * @param c character + * @return true if token character + */ +-(BOOL) isTokenCharacter: (unichar) c{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9') || c == '-' || c == '.' || c == '+'; +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/centroid/SFCentroidCurve.h b/Pods/sf-ios/sf-ios/util/centroid/SFCentroidCurve.h new file mode 100644 index 0000000..b4917dc --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/centroid/SFCentroidCurve.h @@ -0,0 +1,49 @@ +// +// SFCentroidCurve.h +// sf-ios +// +// Created by Brian Osborn on 4/14/17. +// Copyright © 2017 NGA. All rights reserved. +// + +#import "SFPoint.h" + +/** + * Calculate the centroid from curve based geometries. Implementation based on + * the JTS (Java Topology Suite) CentroidLine. + */ +@interface SFCentroidCurve : NSObject + +/** + * Initialize + * + * @return new instance + */ +-(instancetype) init; + +/** + * Initialize + * + * @param geometry + * geometry to add + * @return new instance + */ +-(instancetype) initWithGeometry: (SFGeometry *) geometry; + +/** + * Add a curve based dimension 1 geometry to the centroid total. Ignores + * dimension 0 geometries. + * + * @param geometry + * geometry + */ +-(void) addGeometry: (SFGeometry *) geometry; + +/** + * Get the centroid point + * + * @return centroid point + */ +-(SFPoint *) centroid; + +@end diff --git a/Pods/sf-ios/sf-ios/util/centroid/SFCentroidCurve.m b/Pods/sf-ios/sf-ios/util/centroid/SFCentroidCurve.m new file mode 100644 index 0000000..5ed3ab5 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/centroid/SFCentroidCurve.m @@ -0,0 +1,124 @@ +// +// SFCentroidCurve.m +// sf-ios +// +// Created by Brian Osborn on 4/14/17. +// Copyright © 2017 NGA. All rights reserved. +// + +#import "SFCentroidCurve.h" +#import "SFGeometryUtils.h" +#import "SFMultiLineString.h" + +@interface SFCentroidCurve() + +/** + * Sum of curve point locations + */ +@property (nonatomic, strong) SFPoint *sum; + +/** + * Total length of curves + */ +@property (nonatomic) double totalLength; + +@end + +@implementation SFCentroidCurve + +-(instancetype) init{ + return [self initWithGeometry:nil]; +} + +-(instancetype) initWithGeometry: (SFGeometry *) geometry{ + self = [super init]; + if(self != nil){ + self.sum = [SFPoint point]; + self.totalLength = 0; + [self addGeometry:geometry]; + } + return self; +} + +-(void) addGeometry: (SFGeometry *) geometry{ + enum SFGeometryType geometryType = geometry.geometryType; + switch (geometryType) { + case SF_LINESTRING: + case SF_CIRCULARSTRING: + [self addLineString:(SFLineString *)geometry]; + break; + case SF_MULTILINESTRING: + [self addLineStrings:[((SFMultiLineString *)geometry) lineStrings]]; + break; + case SF_COMPOUNDCURVE: + [self addLineStrings:((SFCompoundCurve *)geometry).lineStrings]; + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + { + SFGeometryCollection *geomCollection = (SFGeometryCollection *) geometry; + for (SFGeometry *subGeometry in geomCollection.geometries) { + [self addGeometry:subGeometry]; + } + + } + break; + case SF_POINT: + case SF_MULTIPOINT: + // Doesn't contribute to curve dimension + break; + default: + [NSException raise:@"Geometry Not Supported" format:@"Unsupported Geometry Type: %d", geometryType]; + } +} + +/** + * Add line strings to the centroid total + * + * @param lineStrings + * line strings + */ +-(void) addLineStrings: (NSArray *) lineStrings{ + for(SFLineString *lineString in lineStrings){ + [self addLineString:lineString]; + } +} + +/** + * Add a line string to the centroid total + * + * @param lineString + * line string + */ +-(void) addLineString: (SFLineString *) lineString{ + [self addPoints:lineString.points]; +} + +/** + * Add points to the centroid total + * + * @param points + * points + */ +-(void) addPoints: (NSArray *) points{ + for(int i = 0; i < points.count - 1; i++){ + SFPoint *point = [points objectAtIndex:i]; + SFPoint *nextPoint = [points objectAtIndex:i + 1]; + + double length = [SFGeometryUtils distanceBetweenPoint1:point andPoint2:nextPoint]; + self.totalLength += length; + + double midX = ([point.x doubleValue] + [nextPoint.x doubleValue]) / 2; + [self.sum setX:[self.sum.x decimalNumberByAdding:[[NSDecimalNumber alloc] initWithDouble:length * midX]]]; + double midY = ([point.y doubleValue] + [nextPoint.y doubleValue]) / 2; + [self.sum setY:[self.sum.y decimalNumberByAdding:[[NSDecimalNumber alloc] initWithDouble:length * midY]]]; + } +} + +-(SFPoint *) centroid{ + SFPoint *centroid = [SFPoint pointWithXValue:([self.sum.x doubleValue] / self.totalLength) andYValue:([self.sum.y doubleValue] / self.totalLength)]; + return centroid; +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/centroid/SFCentroidPoint.h b/Pods/sf-ios/sf-ios/util/centroid/SFCentroidPoint.h new file mode 100644 index 0000000..60dacb1 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/centroid/SFCentroidPoint.h @@ -0,0 +1,48 @@ +// +// SFCentroidPoint.h +// sf-ios +// +// Created by Brian Osborn on 4/14/17. +// Copyright © 2017 NGA. All rights reserved. +// + +#import "SFPoint.h" + +/** + * Calculate the centroid from point based geometries. Implementation based on + * the JTS (Java Topology Suite) CentroidPoint. + */ +@interface SFCentroidPoint : NSObject + +/** + * Initialize + * + * @return new instance + */ +-(instancetype) init; + +/** + * Initialize + * + * @param geometry + * geometry to add + * @return new instance + */ +-(instancetype) initWithGeometry: (SFGeometry *) geometry; + +/** + * Add a point based dimension 0 geometry to the centroid total + * + * @param geometry + * geometry + */ +-(void) addGeometry: (SFGeometry *) geometry; + +/** + * Get the centroid point + * + * @return centroid point + */ +-(SFPoint *) centroid; + +@end diff --git a/Pods/sf-ios/sf-ios/util/centroid/SFCentroidPoint.m b/Pods/sf-ios/sf-ios/util/centroid/SFCentroidPoint.m new file mode 100644 index 0000000..48320b4 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/centroid/SFCentroidPoint.m @@ -0,0 +1,89 @@ +// +// SFCentroidPoint.m +// sf-ios +// +// Created by Brian Osborn on 4/14/17. +// Copyright © 2017 NGA. All rights reserved. +// + +#import "SFCentroidPoint.h" +#import "SFMultiPoint.h" + +@interface SFCentroidPoint() + +/** + * Point count + */ +@property (nonatomic) int count; + +/** + * Sum of point locations + */ +@property (nonatomic, strong) SFPoint *sum; + +@end + +@implementation SFCentroidPoint + +-(instancetype) init{ + return [self initWithGeometry:nil]; +} + +-(instancetype) initWithGeometry: (SFGeometry *) geometry{ + self = [super init]; + if(self != nil){ + self.count = 0; + self.sum = [SFPoint point]; + [self addGeometry:geometry]; + } + return self; +} + +-(void) addGeometry: (SFGeometry *) geometry{ + enum SFGeometryType geometryType = geometry.geometryType; + switch (geometryType) { + case SF_POINT: + [self addPoint:(SFPoint *)geometry]; + break; + case SF_MULTIPOINT: + { + SFMultiPoint *multiPoint = (SFMultiPoint *) geometry; + for(SFPoint *point in [multiPoint points]){ + [self addPoint:point]; + } + } + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + { + SFGeometryCollection *geomCollection = (SFGeometryCollection *) geometry; + for (SFGeometry *subGeometry in geomCollection.geometries) { + [self addGeometry:subGeometry]; + } + + } + break; + default: + [NSException raise:@"Geometry Not Supported" format:@"Unsupported Geometry Type: %d", geometryType]; + } +} + +/** + * Add a point to the centroid total + * + * @param point + * point + */ +-(void) addPoint: (SFPoint *) point{ + self.count++; + [self.sum setX:[self.sum.x decimalNumberByAdding:point.x]]; + [self.sum setY:[self.sum.y decimalNumberByAdding:point.y]]; +} + +-(SFPoint *) centroid{ + SFPoint *centroid = [SFPoint pointWithXValue:([self.sum.x doubleValue] / self.count) andYValue:([self.sum.y doubleValue] / self.count)]; + return centroid; +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/centroid/SFCentroidSurface.h b/Pods/sf-ios/sf-ios/util/centroid/SFCentroidSurface.h new file mode 100644 index 0000000..0949ad3 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/centroid/SFCentroidSurface.h @@ -0,0 +1,49 @@ +// +// SFCentroidSurface.h +// sf-ios +// +// Created by Brian Osborn on 4/14/17. +// Copyright © 2017 NGA. All rights reserved. +// + +#import "SFPoint.h" + +/** + * Calculate the centroid from surface based geometries. Implementation based on + * the JTS (Java Topology Suite) CentroidArea. + */ +@interface SFCentroidSurface : NSObject + +/** + * Initialize + * + * @return new instance + */ +-(instancetype) init; + +/** + * Initialize + * + * @param geometry + * geometry to add + * @return new instance + */ +-(instancetype) initWithGeometry: (SFGeometry *) geometry; + +/** + * Add a surface based dimension 2 geometry to the centroid total. Ignores + * dimension 0 and 1 geometries. + * + * @param geometry + * geometry + */ +-(void) addGeometry: (SFGeometry *) geometry; + +/** + * Get the centroid point + * + * @return centroid point + */ +-(SFPoint *) centroid; + +@end diff --git a/Pods/sf-ios/sf-ios/util/centroid/SFCentroidSurface.m b/Pods/sf-ios/sf-ios/util/centroid/SFCentroidSurface.m new file mode 100644 index 0000000..8e5e5d1 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/centroid/SFCentroidSurface.m @@ -0,0 +1,273 @@ +// +// SFCentroidSurface.m +// sf-ios +// +// Created by Brian Osborn on 4/14/17. +// Copyright © 2017 NGA. All rights reserved. +// + +#import "SFCentroidSurface.h" +#import "SFMultiPolygon.h" +#import "SFGeometryUtils.h" + +@interface SFCentroidSurface() + +/** + * Base point for triangles + */ +@property (nonatomic, strong) SFPoint *base; + +/** + * Area sum + */ +@property (nonatomic) double area; + +/** + * Sum of surface point locations + */ +@property (nonatomic, strong) SFPoint *sum; + +@end + +@implementation SFCentroidSurface + +-(instancetype) init{ + return [self initWithGeometry:nil]; +} + +-(instancetype) initWithGeometry: (SFGeometry *) geometry{ + self = [super init]; + if(self != nil){ + self.area = 0; + self.sum = [SFPoint point]; + [self addGeometry:geometry]; + } + return self; +} + +-(void) addGeometry: (SFGeometry *) geometry{ + enum SFGeometryType geometryType = geometry.geometryType; + switch (geometryType) { + case SF_POLYGON: + case SF_TRIANGLE: + [self addPolygon:(SFPolygon *) geometry]; + break; + case SF_MULTIPOLYGON: + [self addPolygons:[((SFMultiPolygon *)geometry) polygons]]; + break; + case SF_CURVEPOLYGON: + [self addCurvePolygon:(SFCurvePolygon *) geometry]; + break; + case SF_POLYHEDRALSURFACE: + case SF_TIN: + [self addPolygons:((SFPolyhedralSurface *)geometry).polygons]; + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTICURVE: + case SF_MULTISURFACE: + { + SFGeometryCollection *geomCollection = (SFGeometryCollection *) geometry; + for (SFGeometry *subGeometry in geomCollection.geometries) { + [self addGeometry:subGeometry]; + } + + } + break; + case SF_POINT: + case SF_MULTIPOINT: + case SF_LINESTRING: + case SF_CIRCULARSTRING: + case SF_MULTILINESTRING: + case SF_COMPOUNDCURVE: + // Doesn't contribute to surface dimension + break; + default: + [NSException raise:@"Geometry Not Supported" format:@"Unsupported Geometry Type: %d", geometryType]; + } +} + +/** + * Add polygons to the centroid total + * + * @param polygons + * polygons + */ +-(void) addPolygons: (NSArray *) polygons{ + for(SFPolygon *polygon in polygons){ + [self addPolygon:polygon]; + } +} + +/** + * Add a polygon to the centroid total + * + * @param polygon + * polygon + */ +-(void) addPolygon: (SFPolygon *) polygon{ + NSArray *rings = polygon.rings; + [self addLineString:[rings objectAtIndex:0]]; + for(int i = 1; i < rings.count; i++){ + [self addHoleLineString: [rings objectAtIndex: i]]; + } +} + +/** + * Add a curve polygon to the centroid total + * + * @param curvePolygon + * curve polygon + */ +-(void) addCurvePolygon: (SFCurvePolygon *) curvePolygon{ + + NSArray *rings = curvePolygon.rings; + + SFCurve *curve = [rings objectAtIndex:0]; + enum SFGeometryType curveGeometryType = curve.geometryType; + switch(curveGeometryType){ + case SF_COMPOUNDCURVE: + { + SFCompoundCurve *compoundCurve = (SFCompoundCurve *) curve; + for(SFLineString *lineString in compoundCurve.lineStrings){ + [self addLineString:lineString]; + } + break; + } + case SF_LINESTRING: + case SF_CIRCULARSTRING: + [self addLineString:(SFLineString *)curve]; + break; + default: + [NSException raise:@"Curve Type" format:@"Unexpected Curve Type: %d", curveGeometryType]; + } + + for(int i = 1; i < rings.count; i++){ + SFCurve *curveHole = [rings objectAtIndex:i]; + enum SFGeometryType curveHoleGeometryType = curveHole.geometryType; + switch(curveHoleGeometryType){ + case SF_COMPOUNDCURVE: + { + SFCompoundCurve *compoundCurveHole = (SFCompoundCurve *) curveHole; + for(SFLineString *lineStringHole in compoundCurveHole.lineStrings){ + [self addHoleLineString:lineStringHole]; + } + break; + } + case SF_LINESTRING: + case SF_CIRCULARSTRING: + [self addHoleLineString:(SFLineString *)curveHole]; + break; + default: + [NSException raise:@"Curve Type" format:@"Unexpected Curve Type: %d", curveHoleGeometryType]; + } + } +} + +/** + * Add a line string to the centroid total + * + * @param lineString + * line string + */ +-(void) addLineString: (SFLineString *) lineString{ + [self addWithPositive:true andLineString:lineString]; +} + +/** + * Add a line string hole to subtract from the centroid total + * + * @param lineString + * line string + */ +-(void) addHoleLineString: (SFLineString *) lineString{ + [self addWithPositive:false andLineString:lineString]; +} + +/** + * Add or subtract a line string to or from the centroid total + * + * @param positive + * true if an addition, false if a subtraction + * @param lineString + * line string + */ +-(void) addWithPositive: (BOOL) positive andLineString: (SFLineString *) lineString{ + NSArray *points = lineString.points; + SFPoint *firstPoint = [points objectAtIndex:0]; + if(self.base == nil){ + self.base = firstPoint; + } + for(int i = 0; i < points.count - 1; i++){ + SFPoint *point = [points objectAtIndex:i]; + SFPoint *nextPoint = [points objectAtIndex:i + 1]; + [self addTriangleWithPositive:positive andPoint1:self.base andPoint2:point andPoint3:nextPoint]; + } + SFPoint *lastPoint = [points objectAtIndex:points.count - 1]; + if([firstPoint.x doubleValue] != [lastPoint.x doubleValue] || [firstPoint.y doubleValue] != [lastPoint.y doubleValue]){ + [self addTriangleWithPositive:positive andPoint1:self.base andPoint2:lastPoint andPoint3:firstPoint]; + } +} + +/** + * Add or subtract a triangle of points to or from the centroid total + * + * @param positive + * true if an addition, false if a subtraction + * @param point1 + * point 1 + * @param point2 + * point 2 + * @param point3 + * point 3 + */ +-(void) addTriangleWithPositive: (BOOL) positive andPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2 andPoint3: (SFPoint *) point3{ + double sign = (positive) ? 1.0 : -1.0; + SFPoint *triangleCenter3 = [self centroid3WithPoint1:point1 andPoint2:point2 andPoint3:point3]; + double area2 = [self area2WithPoint1:point1 andPoint2:point2 andPoint3:point3]; + [self.sum setX:[self.sum.x decimalNumberByAdding:[[NSDecimalNumber alloc] initWithDouble:sign * area2 * [triangleCenter3.x doubleValue]]]]; + [self.sum setY:[self.sum.y decimalNumberByAdding:[[NSDecimalNumber alloc] initWithDouble:sign * area2 * [triangleCenter3.y doubleValue]]]]; + self.area += sign * area2; +} + +/** + * Calculate three times the centroid of the point triangle + * + * @param point1 + * point 1 + * @param point2 + * point 2 + * @param point3 + * point 3 + * @return 3 times centroid point + */ +-(SFPoint *) centroid3WithPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2 andPoint3: (SFPoint *) point3{ + double x = [point1.x doubleValue] + [point2.x doubleValue] + [point3.x doubleValue]; + double y = [point1.y doubleValue] + [point2.y doubleValue] + [point3.y doubleValue]; + SFPoint *point = [SFPoint pointWithXValue:x andYValue:y]; + return point; +} + +/** + * Calculate twice the area of the point triangle + * + * @param point1 + * point 1 + * @param point2 + * point 2 + * @param point3 + * point 3 + * @return 2 times triangle area + */ +-(double) area2WithPoint1: (SFPoint *) point1 andPoint2: (SFPoint *) point2 andPoint3: (SFPoint *) point3{ + return ([point2.x doubleValue] - [point1.x doubleValue]) + * ([point3.y doubleValue] - [point1.y doubleValue]) + - ([point3.x doubleValue] - [point1.x doubleValue]) + * ([point2.y doubleValue] - [point1.y doubleValue]); +} + +-(SFPoint *) centroid{ + SFPoint *centroid = [SFPoint pointWithXValue:([self.sum.x doubleValue] / 3 / self.area) andYValue:([self.sum.y doubleValue] / 3 / self.area)]; + return centroid; +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/centroid/SFDegreesCentroid.h b/Pods/sf-ios/sf-ios/util/centroid/SFDegreesCentroid.h new file mode 100644 index 0000000..4cdf94e --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/centroid/SFDegreesCentroid.h @@ -0,0 +1,41 @@ +// +// SFDegreesCentroid.h +// sf-ios +// +// Created by Brian Osborn on 2/9/22. +// Copyright © 2022 NGA. All rights reserved. +// + +#import "SFPoint.h" + +/** + * Centroid calculations for geometries in degrees + */ +@interface SFDegreesCentroid : NSObject + +/** + * Get the degree geometry centroid + * + * @param geometry + * geometry + * @return centroid point + */ ++(SFPoint *) centroidOfGeometry: (SFGeometry *) geometry; + +/** + * Initialize + * + * @param geometry + * geometry + * @return new instance + */ +-(instancetype) initWithGeometry: (SFGeometry *) geometry; + +/** + * Get the centroid point + * + * @return centroid point + */ +-(SFPoint *) centroid; + +@end diff --git a/Pods/sf-ios/sf-ios/util/centroid/SFDegreesCentroid.m b/Pods/sf-ios/sf-ios/util/centroid/SFDegreesCentroid.m new file mode 100644 index 0000000..79a8a7e --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/centroid/SFDegreesCentroid.m @@ -0,0 +1,239 @@ +// +// SFDegreesCentroid.m +// sf-ios +// +// Created by Brian Osborn on 2/9/22. +// Copyright © 2022 NGA. All rights reserved. +// + +#import "SFDegreesCentroid.h" +#import "SFGeometryUtils.h" + +@interface SFDegreesCentroid() + +/** + * Geometry + */ +@property (nonatomic, strong) SFGeometry *geometry; + +/** + * Number of points + */ +@property (nonatomic) int points; + +/** + * x sum + */ +@property (nonatomic) double x; + +/** + * y sum + */ +@property (nonatomic) double y; + +/** + * z sum + */ +@property (nonatomic) double z; + +@end + +@implementation SFDegreesCentroid + ++(SFPoint *) centroidOfGeometry: (SFGeometry *) geometry{ + return [[SFDegreesCentroid alloc] initWithGeometry:geometry].centroid; +} + +-(instancetype) initWithGeometry: (SFGeometry *) geometry{ + self = [super init]; + if(self != nil){ + self.geometry = geometry; + } + return self; +} + +-(SFPoint *) centroid{ + + SFPoint *centroid = nil; + + if(_geometry.geometryType == SF_POINT){ + centroid = (SFPoint *) _geometry; + }else{ + + [self calculate:_geometry]; + + _x = _x / _points; + _y = _y / _points; + _z = _z / _points; + + double centroidLongitude = atan2(_y, _x); + double centroidLatitude = atan2(_z, sqrt(_x * _x + _y * _y)); + + centroid = [SFPoint pointWithXValue:[SFGeometryUtils radiansToDegrees:centroidLongitude] andYValue:[SFGeometryUtils radiansToDegrees:centroidLatitude]]; + } + + return centroid; +} + +/** + * Add to the centroid calculation for the Geometry + * + * @param geometry + * Geometry + */ +-(void) calculate: (SFGeometry *) geometry{ + + enum SFGeometryType geometryType = geometry.geometryType; + + switch (geometryType) { + + case SF_GEOMETRY: + [NSException raise:@"Unexpected Geometry Type" format:@"Unexpected Geometry Type of %@ which is abstract", [SFGeometryTypes name:geometryType]]; + case SF_POINT: + [self calculatePoint:(SFPoint *) geometry]; + break; + case SF_LINESTRING: + case SF_CIRCULARSTRING: + [self calculateLineString:(SFLineString *) geometry]; + break; + case SF_POLYGON: + case SF_TRIANGLE: + [self calculatePolygon:(SFPolygon *) geometry]; + break; + case SF_GEOMETRYCOLLECTION: + case SF_MULTIPOINT: + case SF_MULTICURVE: + case SF_MULTILINESTRING: + case SF_MULTISURFACE: + case SF_MULTIPOLYGON: + [self calculateGeometryCollection:(SFGeometryCollection *) geometry]; + break; + case SF_COMPOUNDCURVE: + [self calculateCompoundCurve:(SFCompoundCurve *) geometry]; + break; + case SF_CURVEPOLYGON: + [self calculateCurvePolygon:(SFCurvePolygon *) geometry]; + break; + case SF_CURVE: + [NSException raise:@"Unexpected Geometry Type" format:@"Unexpected Geometry Type of %@ which is abstract", [SFGeometryTypes name:geometryType]]; + case SF_SURFACE: + [NSException raise:@"Unexpected Geometry Type" format:@"Unexpected Geometry Type of %@ which is abstract", [SFGeometryTypes name:geometryType]]; + case SF_POLYHEDRALSURFACE: + case SF_TIN: + [self calculatePolyhedralSurface:(SFPolyhedralSurface *) geometry]; + break; + default: + [NSException raise:@"Geometry Type" format:@"Geometry Type not supported: %@", [SFGeometryTypes name:geometryType]]; + break; + + } +} + +/** + * Add to the centroid calculation for the Point + * + * @param point + * Point + */ +-(void) calculatePoint: (SFPoint *) point{ + double latitude = [SFGeometryUtils degreesToRadians:[point.y doubleValue]]; + double longitude = [SFGeometryUtils degreesToRadians:[point.x doubleValue]]; + double cosLatitude = cos(latitude); + _x += cosLatitude * cos(longitude); + _y += cosLatitude * sin(longitude); + _z += sin(latitude); + _points++; +} + +/** + * Add to the centroid calculation for the Line String + * + * @param lineString + * Line String + */ +-(void) calculateLineString: (SFLineString *) lineString{ + + for(SFPoint *point in lineString.points){ + [self calculatePoint:point]; + } + +} + +/** + * Add to the centroid calculation for the Polygon + * + * @param polygon + * Polygon + */ +-(void) calculatePolygon: (SFPolygon *) polygon{ + + if([polygon numRings] > 0){ + SFLineString *exteriorRing = [polygon exteriorRing]; + int numPoints = [exteriorRing numPoints]; + if([SFGeometryUtils closedPolygonRing:exteriorRing]){ + numPoints--; + } + for(int i = 0; i < numPoints; i++){ + [self calculatePoint:[exteriorRing pointAtIndex:i]]; + } + } + +} + +/** + * Add to the centroid calculation for the Geometry Collection + * + * @param geometryCollection + * Geometry Collection + */ +-(void) calculateGeometryCollection: (SFGeometryCollection *) geometryCollection{ + + for(SFGeometry *geometry in geometryCollection.geometries){ + [self calculate:geometry]; + } + +} + +/** + * Add to the centroid calculation for the Compound Curve + * + * @param compoundCurve + * Compound Curve + */ +-(void) calculateCompoundCurve: (SFCompoundCurve *) compoundCurve{ + + for(SFLineString *lineString in compoundCurve.lineStrings){ + [self calculateLineString:lineString]; + } + +} + +/** + * Add to the centroid calculation for the Curve Polygon + * + * @param curvePolygon + * Curve Polygon + */ +-(void) calculateCurvePolygon: (SFCurvePolygon *) curvePolygon{ + + for(SFCurve *ring in curvePolygon.rings){ + [self calculate:ring]; + } + +} + +/** + * Add to the centroid calculation for the Polyhedral Surface + * + * @param polyhedralSurface + * Polyhedral Surface + */ +-(void) calculatePolyhedralSurface: (SFPolyhedralSurface *) polyhedralSurface{ + + for(SFPolygon *polygon in polyhedralSurface.polygons){ + [self calculatePolygon:polygon]; + } + +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/filter/SFFiniteFilterTypes.h b/Pods/sf-ios/sf-ios/util/filter/SFFiniteFilterTypes.h new file mode 100644 index 0000000..99c1388 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/filter/SFFiniteFilterTypes.h @@ -0,0 +1,23 @@ +// +// SFFiniteFilterTypes.h +// sf-ios +// +// Created by Brian Osborn on 7/21/20. +// Copyright © 2020 NGA. All rights reserved. +// + +#import + +/** + * Finite Filter Type, including finite values and optionally one of either + * infinite or NaN values + */ +enum SFFiniteFilterType{ + SF_FF_FINITE = 0, + SF_FF_FINITE_AND_INFINITE, + SF_FF_FINITE_AND_NAN +}; + +@interface SFFiniteFilterTypes : NSObject + +@end diff --git a/Pods/sf-ios/sf-ios/util/filter/SFFiniteFilterTypes.m b/Pods/sf-ios/sf-ios/util/filter/SFFiniteFilterTypes.m new file mode 100644 index 0000000..67c0aa0 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/filter/SFFiniteFilterTypes.m @@ -0,0 +1,13 @@ +// +// SFFiniteFilterTypes.m +// sf-ios +// +// Created by Brian Osborn on 7/21/20. +// Copyright © 2020 NGA. All rights reserved. +// + +#import "SFFiniteFilterTypes.h" + +@implementation SFFiniteFilterTypes + +@end diff --git a/Pods/sf-ios/sf-ios/util/filter/SFGeometryFilter.h b/Pods/sf-ios/sf-ios/util/filter/SFGeometryFilter.h new file mode 100644 index 0000000..5fc728d --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/filter/SFGeometryFilter.h @@ -0,0 +1,34 @@ +// +// SFGeometryFilter.h +// sf-ios +// +// Created by Brian Osborn on 7/21/20. +// Copyright © 2020 NGA. All rights reserved. +// + +#ifndef sf_ios_SFGeometryFilter_h +#define sf_ios_SFGeometryFilter_h + +#import "SFGeometry.h" + +/** + * Geometry Filter to filter included geometries and modify them during + * construction + */ +@protocol SFGeometryFilter + +/** + * Filter the geometry + * + * @param geometry + * geometry, may be modified + * @param containingType + * geometry type of the geometry containing this geometry + * element, null if geometry is top level + * @return true if passes filter and geometry should be included + */ +-(BOOL) filterGeometry: (SFGeometry *) geometry inType: (enum SFGeometryType) containingType; + +@end + +#endif diff --git a/Pods/sf-ios/sf-ios/util/filter/SFPointFiniteFilter.h b/Pods/sf-ios/sf-ios/util/filter/SFPointFiniteFilter.h new file mode 100644 index 0000000..599b4c4 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/filter/SFPointFiniteFilter.h @@ -0,0 +1,108 @@ +// +// SFPointFiniteFilter.h +// sf-ios +// +// Created by Brian Osborn on 7/21/20. +// Copyright © 2020 NGA. All rights reserved. +// + +#import "SFGeometryFilter.h" +#import "SFFiniteFilterTypes.h" + +/** + * Point filter for finite checks on x and y properties, optionally filter on z + * and m properties and non finite values (NaN or infinity) + */ +@interface SFPointFiniteFilter : NSObject + +/** + * Finite Filter type + */ +@property (nonatomic) enum SFFiniteFilterType type; + +/** + * Include z values in filtering + */ +@property (nonatomic) BOOL filterZ; + +/** + * Include m values in filtering + */ +@property (nonatomic) BOOL filterM; + +/** + * Initialize, filter on x and y, allowing only finite values + * + * @return new point finite filter + */ +-(instancetype) init; + +/** + * Initialize, filter on x and y + * + * @param type finite filter type + * + * @return new point finite filter + */ +-(instancetype) initWithType: (enum SFFiniteFilterType) type; + +/** + * Initialize, filter on x, y, and optionally z + * + * @param type finite filter type + * @param filterZ filter z values mode + * + * @return new point finite filter + */ +-(instancetype) initWithType: (enum SFFiniteFilterType) type andZ: (BOOL) filterZ; + +/** + * Initialize, filter on x, y, and optionally m + * + * @param type finite filter type + * @param filterM filter m values mode + * + * @return new point finite filter + */ +-(instancetype) initWithType: (enum SFFiniteFilterType) type andM: (BOOL) filterM; + +/** + * Initialize, filter on x, y, and optionally z and m + * + * @param type finite filter type + * @param filterZ filter z values mode + * @param filterM filter m values mode + * + * @return new point finite filter + */ +-(instancetype) initWithType: (enum SFFiniteFilterType) type andZ: (BOOL) filterZ andM: (BOOL) filterM; + +/** + * Initialize, filter on x, y, and optionally z + * + * @param filterZ filter z values mode + * + * @return new point finite filter + */ +-(instancetype) initWithZ: (BOOL) filterZ; + +/** + * Initialize, filter on x, y, and optionally m + * + * @param filterM filter m values mode + * + * @return new point finite filter + */ +-(instancetype) initWithM: (BOOL) filterM; + +/** + * Initialize, filter on x, y, and optionally z and m + * + * @param filterZ filter z values mode + * @param filterM filter m values mode + * + * @return new point finite filter + */ +-(instancetype) initWithZ: (BOOL) filterZ andM: (BOOL) filterM; + +@end diff --git a/Pods/sf-ios/sf-ios/util/filter/SFPointFiniteFilter.m b/Pods/sf-ios/sf-ios/util/filter/SFPointFiniteFilter.m new file mode 100644 index 0000000..094b598 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/filter/SFPointFiniteFilter.m @@ -0,0 +1,132 @@ +// +// SFPointFiniteFilter.m +// sf-ios +// +// Created by Brian Osborn on 7/21/20. +// Copyright © 2020 NGA. All rights reserved. +// + +#import "SFPointFiniteFilter.h" +#import "SFPoint.h" + +@implementation SFPointFiniteFilter + +-(instancetype) init{ + self = [self initWithType:SF_FF_FINITE]; + return self; +} + +-(instancetype) initWithType: (enum SFFiniteFilterType) type{ + self = [self initWithType:type andZ:NO andM:NO]; + return self; +} + +-(instancetype) initWithType: (enum SFFiniteFilterType) type andZ: (BOOL) filterZ{ + self = [self initWithType:type andZ:filterZ andM:NO]; + return self; +} + +-(instancetype) initWithType: (enum SFFiniteFilterType) type andM: (BOOL) filterM{ + self = [self initWithType:type andZ:NO andM:filterM]; + return self; +} + +-(instancetype) initWithType: (enum SFFiniteFilterType) type andZ: (BOOL) filterZ andM: (BOOL) filterM{ + self = [super self]; + if(self){ + _type = type; + _filterZ = filterZ; + _filterM = filterM; + } + return self; +} + +-(instancetype) initWithZ: (BOOL) filterZ{ + self = [self initWithZ:filterZ andM:NO]; + return self; +} + +-(instancetype) initWithM: (BOOL) filterM{ + self = [self initWithZ:NO andM:filterM]; + return self; +} + +-(instancetype) initWithZ: (BOOL) filterZ andM: (BOOL) filterM{ + self = [self initWithType:SF_FF_FINITE andZ:filterZ andM:filterM]; + return self; +} + +-(BOOL) filterGeometry: (SFGeometry *) geometry inType: (enum SFGeometryType) containingType{ + return geometry.geometryType != SF_POINT || ![geometry isKindOfClass:[SFPoint class]] || [self filterPoint:(SFPoint *)geometry]; +} + +/** + * Filter the point + * + * @param point + * point + * @return true if passes filter and point should be included + */ +-(BOOL) filterPoint: (SFPoint *) point{ + return [self filterNumber:point.x] && [self filterNumber:point.y] && [self filterZWithPoint:point] && [self filterMWithPoint:point]; +} + +/** + * Filter the double value + * + * @param value + * double value + * @return true if passes + */ +-(BOOL) filterDouble: (double) value{ + BOOL passes = NO; + switch (_type) { + case SF_FF_FINITE: + passes = isfinite(value); + break; + case SF_FF_FINITE_AND_INFINITE: + passes = !isnan(value); + break; + case SF_FF_FINITE_AND_NAN: + passes = !isinf(value); + break; + default: + [NSException raise:@"Unsupported" format:@"Unsupported filter type: %u", _type]; + } + return passes; +} + +/** + * Filter the Z value + * + * @param point + * point + * @return true if passes + */ +-(BOOL) filterZWithPoint: (SFPoint *) point{ + return !_filterZ || !point.hasZ || [self filterNumber:point.z]; +} + +/** + * Filter the M value + * + * @param point + * point + * @return true if passes + */ +-(BOOL) filterMWithPoint: (SFPoint *) point{ + return !_filterM || !point.hasM || [self filterNumber:point.m]; +} + +/** + * Filter the number value + * + * @param value + * number value + * @return true if passes + */ +-(BOOL) filterNumber: (NSDecimalNumber *) value{ + return value == nil || [self filterDouble:[value doubleValue]]; +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/sweep/SFEvent.h b/Pods/sf-ios/sf-ios/util/sweep/SFEvent.h new file mode 100644 index 0000000..f96310e --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/sweep/SFEvent.h @@ -0,0 +1,70 @@ +// +// SFEvent.h +// sf-ios +// +// Created by Brian Osborn on 1/11/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFPoint.h" +#import "SFEventTypes.h" + +/** + * Event element + */ +@interface SFEvent : NSObject + +/** + * Initialize + * + * @param edge + * edge number + * @param ring + * ring number + * @param point + * point + * @param type + * event type + * @return event + */ +-(instancetype) initWithEdge: (int) edge + andRing: (int) ring + andPoint: (SFPoint *) point + andType: (enum SFEventType) type; + +/** + * Get the edge + * + * @return edge number + */ +-(int) edge; + +/** + * Get the polygon ring number + * + * @return polygon ring number + */ +-(int) ring; + +/** + * Get the polygon point + * + * @return polygon point + */ +-(SFPoint *) point; + +/** + * Get the event type + * + * @return event type + */ +-(enum SFEventType) type; + +/** + * Sort the events + * + * @return sorted events + */ ++(NSArray *) sort: (NSArray *) events; + +@end diff --git a/Pods/sf-ios/sf-ios/util/sweep/SFEvent.m b/Pods/sf-ios/sf-ios/util/sweep/SFEvent.m new file mode 100644 index 0000000..5506a86 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/sweep/SFEvent.m @@ -0,0 +1,78 @@ +// +// SFEvent.m +// sf-ios +// +// Created by Brian Osborn on 1/11/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFEvent.h" +#import "SFSweepLine.h" + +@interface SFEvent() + +/** + * Edge number + */ +@property (nonatomic) int edge; + +/** + * Polygon ring number + */ +@property (nonatomic) int ring; + +/** + * Polygon point + */ +@property (nonatomic, strong) SFPoint *point; + +/** + * Event type, left or right point + */ +@property (nonatomic) enum SFEventType type; + +@end + +@implementation SFEvent + +-(instancetype) initWithEdge: (int) edge + andRing: (int) ring + andPoint: (SFPoint *) point + andType: (enum SFEventType) type{ + self = [super init]; + if(self != nil){ + self.edge = edge; + self.ring = ring; + self.point = point; + self.type = type; + } + return self; +} + +-(int) edge{ + return _edge; +} + +-(int) ring{ + return _ring; +} + +-(SFPoint *) point{ + return _point; +} + +-(enum SFEventType) type{ + return _type; +} + +- (NSComparisonResult) compare: (SFEvent *) event{ + return [SFSweepLine xyOrderWithPoint:self.point andPoint:event.point]; +} + ++(NSArray *) sort: (NSArray *) events{ + NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES]; + NSArray *sorted = [events sortedArrayUsingDescriptors:@[sort]]; + return sorted; +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/sweep/SFEventQueue.h b/Pods/sf-ios/sf-ios/util/sweep/SFEventQueue.h new file mode 100644 index 0000000..640e165 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/sweep/SFEventQueue.h @@ -0,0 +1,42 @@ +// +// SFEventQueue.h +// sf-ios +// +// Created by Brian Osborn on 1/12/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFLineString.h" +#import "SFEvent.h" + +/** + * Event queue for processing events + */ +@interface SFEventQueue : NSObject + +/** + * Initialize + * + * @param ring + * polygon ring + * @return event queue + */ +-(instancetype) initWithRing: (SFLineString *) ring; + +/** + * Initialize + * + * @param rings + * polygon rings + * @return event queue + */ +-(instancetype) initWithRings: (NSArray *) rings; + +/** + * Get the events + * + * @return events + */ +-(NSArray *) events; + +@end diff --git a/Pods/sf-ios/sf-ios/util/sweep/SFEventQueue.m b/Pods/sf-ios/sf-ios/util/sweep/SFEventQueue.m new file mode 100644 index 0000000..c229c59 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/sweep/SFEventQueue.m @@ -0,0 +1,67 @@ +// +// SFEventQueue.m +// sf-ios +// +// Created by Brian Osborn on 1/12/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFEventQueue.h" +#import "SFSweepLine.h" + +@interface SFEventQueue() + +@property (nonatomic, strong) NSArray *events; + +@end + +@implementation SFEventQueue + +-(instancetype) initWithRing: (SFLineString *) ring{ + return [self initWithRings:[NSArray arrayWithObjects:ring, nil]]; +} + +-(instancetype) initWithRings: (NSArray *) rings{ + self = [super init]; + if(self != nil){ + NSMutableArray *buildEvents = [NSMutableArray array]; + for(int i = 0; i < rings.count; i++){ + SFLineString *ring = [rings objectAtIndex:i]; + [self addRing:ring withIndex:i toEvents:buildEvents]; + } + self.events = [SFEvent sort:buildEvents]; + } + return self; +} + +-(void) addRing: (SFLineString *) ring withIndex: (int) ringIndex toEvents: (NSMutableArray *) events{ + + NSArray *points = ring.points; + + for (int i = 0; i < points.count; i++) { + + SFPoint *point1 = [points objectAtIndex:i]; + SFPoint *point2 = [points objectAtIndex:(i + 1) % points.count]; + + enum SFEventType type1 = SF_ET_RIGHT; + enum SFEventType type2 = SF_ET_LEFT; + if([SFSweepLine xyOrderWithPoint:point1 andPoint:point2] == NSOrderedAscending){ + type1 = SF_ET_LEFT; + type2 = SF_ET_RIGHT; + } + + SFEvent *endpoint1 = [[SFEvent alloc] initWithEdge:i andRing:ringIndex andPoint:point1 andType:type1]; + SFEvent *endpoint2 = [[SFEvent alloc] initWithEdge:i andRing:ringIndex andPoint:point2 andType:type2]; + + [events addObject:endpoint1]; + [events addObject:endpoint2]; + + } + +} + +-(NSArray *) events{ + return _events; +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/sweep/SFEventTypes.h b/Pods/sf-ios/sf-ios/util/sweep/SFEventTypes.h new file mode 100644 index 0000000..f3ce86a --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/sweep/SFEventTypes.h @@ -0,0 +1,21 @@ +// +// SFEventTypes.h +// sf-ios +// +// Created by Brian Osborn on 1/11/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import + +/** + * Event type of the point direction + */ +enum SFEventType{ + SF_ET_LEFT = 0, + SF_ET_RIGHT +}; + +@interface SFEventTypes : NSObject + +@end diff --git a/Pods/sf-ios/sf-ios/util/sweep/SFEventTypes.m b/Pods/sf-ios/sf-ios/util/sweep/SFEventTypes.m new file mode 100644 index 0000000..e1e832d --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/sweep/SFEventTypes.m @@ -0,0 +1,13 @@ +// +// SFEventType.m +// sf-ios +// +// Created by Brian Osborn on 1/11/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFEventTypes.h" + +@implementation SFEventTypes + +@end diff --git a/Pods/sf-ios/sf-ios/util/sweep/SFSegment.h b/Pods/sf-ios/sf-ios/util/sweep/SFSegment.h new file mode 100644 index 0000000..e45fa90 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/sweep/SFSegment.h @@ -0,0 +1,72 @@ +// +// SFSegment.h +// sf-ios +// +// Created by Brian Osborn on 1/12/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFPoint.h" + +/** + * Line segment of an edge between two points + */ +@interface SFSegment : NSObject + +/** + * Segment above + */ +@property (nonatomic, strong) SFSegment *above; + +/** + * Segment below + */ +@property (nonatomic, strong) SFSegment *below; + +/** + * Initialize + * + * @param edge + * edge number + * @param ring + * ring number + * @param leftPoint + * left point + * @param rightPoint + * right point + * @return segment + */ +-(instancetype) initWithEdge: (int) edge + andRing: (int) ring + andLeftPoint: (SFPoint *) leftPoint + andRightPoint: (SFPoint *) rightPoint; + +/** + * Get the edge number + * + * @return edge number + */ +-(int) edge; + +/** + * Get the polygon ring number + * + * @return polygon ring number + */ +-(int) ring; + +/** + * Get the left point + * + * @return left point + */ +-(SFPoint *) leftPoint; + +/** + * Get the right point + * + * @return right point + */ +-(SFPoint *) rightPoint; + +@end diff --git a/Pods/sf-ios/sf-ios/util/sweep/SFSegment.m b/Pods/sf-ios/sf-ios/util/sweep/SFSegment.m new file mode 100644 index 0000000..f5b9a25 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/sweep/SFSegment.m @@ -0,0 +1,67 @@ +// +// SFSegment.m +// sf-ios +// +// Created by Brian Osborn on 1/12/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFSegment.h" + +@interface SFSegment() + +/** + * Edge number + */ +@property (nonatomic) int edge; + +/** + * Polygon ring number + */ +@property (nonatomic) int ring; + +/** + * Left point + */ +@property (nonatomic, strong) SFPoint *leftPoint; + +/** + * Right point + */ +@property (nonatomic, strong) SFPoint *rightPoint; + +@end + +@implementation SFSegment + +-(instancetype) initWithEdge: (int) edge + andRing: (int) ring + andLeftPoint: (SFPoint *) leftPoint + andRightPoint: (SFPoint *) rightPoint{ + self = [super init]; + if(self != nil){ + self.edge = edge; + self.ring = ring; + self.leftPoint = leftPoint; + self.rightPoint = rightPoint; + } + return self; +} + +-(int) edge{ + return _edge; +} + +-(int) ring{ + return _ring; +} + +-(SFPoint *) leftPoint{ + return _leftPoint; +} + +-(SFPoint *) rightPoint{ + return _rightPoint; +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/sweep/SFShamosHoey.h b/Pods/sf-ios/sf-ios/util/sweep/SFShamosHoey.h new file mode 100644 index 0000000..2ad37b2 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/sweep/SFShamosHoey.h @@ -0,0 +1,72 @@ +// +// SFShamosHoey.h +// sf-ios +// +// Created by Brian Osborn on 1/12/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFPolygon.h" + +/** + * Shamos-Hoey simple polygon detection + * + * Based upon C++ implementation: + * http://geomalgorithms.com/a09-_intersect-3.html + * + * C++ implementation license: + * + * Copyright 2001 softSurfer, 2012 Dan Sunday This code may be freely used and + * modified for any purpose providing that this copyright notice is included + * with it. SoftSurfer makes no warranty for this code, and cannot be held + * liable for any real or imagined damage resulting from its use. Users of this + * code must verify correctness for their application. + */ +@interface SFShamosHoey : NSObject + +/** + * Determine if the polygon is simple + * + * @param polygon + * polygon + * @return true if simple, false if intersects + */ ++(BOOL) simplePolygon: (SFPolygon *) polygon; + +/** + * Determine if the polygon points are simple + * + * @param points + * polygon as points + * @return true if simple, false if intersects + */ ++(BOOL) simplePolygonPoints: (NSArray *) points; + +/** + * Determine if the polygon point rings are simple + * + * @param pointRings + * polygon point rings + * @return true if simple, false if intersects + */ ++(BOOL) simplePolygonRingPoints: (NSArray*> *) pointRings; + +/** + * Determine if the polygon line string ring is simple + * + * @param ring + * polygon ring as a line string + * @return true if simple, false if intersects + */ ++(BOOL) simplePolygonRing: (SFLineString *) ring; + +/** + * Determine if the polygon rings are simple + * + * @param rings + * polygon rings + * @return true if simple, false if intersects + */ ++(BOOL) simplePolygonRings: (NSArray *) rings; + +@end diff --git a/Pods/sf-ios/sf-ios/util/sweep/SFShamosHoey.m b/Pods/sf-ios/sf-ios/util/sweep/SFShamosHoey.m new file mode 100644 index 0000000..4af111f --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/sweep/SFShamosHoey.m @@ -0,0 +1,142 @@ +// +// SFShamosHoey.m +// sf-ios +// +// Created by Brian Osborn on 1/12/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFShamosHoey.h" +#import "SFGeometryUtils.h" +#import "SFEventQueue.h" +#import "SFSweepLine.h" + +@implementation SFShamosHoey + ++(BOOL) simplePolygon: (SFPolygon *) polygon{ + return [self simplePolygonRings:[polygon lineStrings]]; +} + ++(BOOL) simplePolygonPoints: (NSArray *) points{ + SFLineString *ring = [SFLineString lineString]; + [ring.points addObjectsFromArray:points]; + return [self simplePolygonRing:ring]; +} + ++(BOOL) simplePolygonRingPoints: (NSArray*> *) pointRings{ + NSMutableArray *rings = [NSMutableArray array]; + for(NSArray *points in pointRings){ + SFLineString *ring = [SFLineString lineString]; + [ring.points addObjectsFromArray:points]; + [rings addObject:ring]; + } + return [self simplePolygonRings:rings]; +} + ++(BOOL) simplePolygonRing: (SFLineString *) ring{ + NSMutableArray *rings = [NSMutableArray array]; + [rings addObject:ring]; + return [self simplePolygonRings:rings]; +} + ++(BOOL) simplePolygonRings: (NSArray *) rings{ + + BOOL simple = rings.count > 0; + + NSMutableArray *ringCopies = [NSMutableArray array]; + for(int i = 0; i < rings.count; i++){ + + SFLineString *ring = [rings objectAtIndex:i]; + + // Copy the ring + SFLineString *ringCopy = [SFLineString lineString]; + [ringCopy.points addObjectsFromArray:ring.points]; + [ringCopies addObject:ringCopy]; + + // Remove the last point when identical to the first + NSMutableArray *ringCopyPoints = ringCopy.points; + if(ringCopyPoints.count >= 3){ + SFPoint *first = [ringCopyPoints objectAtIndex:0]; + SFPoint *last = [ringCopyPoints objectAtIndex:ringCopyPoints.count - 1]; + if([first isEqualXYToPoint:last]){ + [ringCopyPoints removeObjectAtIndex:ringCopyPoints.count - 1]; + } + } + + // Verify enough ring points + if (ringCopyPoints.count < 3) { + simple = NO; + break; + } + + // Check for duplicate points (thus connecting more than two edges + // and not simple) + NSMutableDictionary *> *pointValues = [NSMutableDictionary dictionary]; + for(SFPoint *point in ringCopyPoints){ + NSDecimalNumber *x = point.x; + NSDecimalNumber *y = point.y; + NSMutableSet *xValues = [pointValues objectForKey:x]; + if(xValues == nil){ + xValues = [NSMutableSet set]; + [xValues addObject:y]; + [pointValues setObject:xValues forKey:x]; + }else if(![xValues containsObject:y]){ + [xValues addObject:y]; + }else{ + simple = NO; + break; + } + } + + // Check holes to make sure the first point is in the polygon + if (i > 0) { + SFPoint *firstPoint = [ringCopyPoints objectAtIndex:0]; + if(![SFGeometryUtils point:firstPoint inPolygonRing:[rings objectAtIndex:0]]){ + simple = NO; + break; + } + // Make sure the hole first points are not inside of one another + for (int j = 1; j < i; j++) { + NSArray *holePoints = [rings objectAtIndex:j].points; + if([SFGeometryUtils point:firstPoint inPolygonPoints:holePoints] + || [SFGeometryUtils point:[holePoints objectAtIndex:0] inPolygonPoints:ringCopyPoints]){ + simple = NO; + break; + } + } + if (!simple) { + break; + } + } + } + + // If valid polygon rings + if (simple) { + + SFEventQueue *eventQueue = [[SFEventQueue alloc] initWithRings:ringCopies]; + SFSweepLine *sweepLine = [[SFSweepLine alloc] initWithRings:ringCopies]; + + for (SFEvent *event in eventQueue.events) { + if(event.type == SF_ET_LEFT){ + SFSegment *segment = [sweepLine addEvent:event]; + if([sweepLine intersectWithSegment:segment andSegment:segment.above] + || [sweepLine intersectWithSegment:segment andSegment:segment.below]){ + simple = NO; + break; + } + } else { + SFSegment *segment = [sweepLine findEvent:event]; + if([sweepLine intersectWithSegment:segment.above andSegment:segment.below]){ + simple = NO; + break; + } + [sweepLine removeSegment:segment]; + } + } + } + + return simple; + +} + +@end diff --git a/Pods/sf-ios/sf-ios/util/sweep/SFSweepLine.h b/Pods/sf-ios/sf-ios/util/sweep/SFSweepLine.h new file mode 100644 index 0000000..1c04839 --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/sweep/SFSweepLine.h @@ -0,0 +1,75 @@ +// +// SFSweepLine.h +// sf-ios +// +// Created by Brian Osborn on 1/12/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFSegment.h" +#import "SFEvent.h" +#import "SFLineString.h" + +/** + * Sweep Line algorithm + */ +@interface SFSweepLine : NSObject + +/** + * Initialize + * + * @param rings + * polygon rings + * @return sweep line + */ +-(instancetype) initWithRings: (NSArray *) rings; + +/** + * Add the event to the sweep line + * + * @param event + * event + * @return added segment + */ +-(SFSegment *) addEvent: (SFEvent *) event; + +/** + * Find the existing event segment + * + * @param event + * event + * @return segment + */ +-(SFSegment *) findEvent: (SFEvent *) event; + +/** + * Determine if the two segments intersect + * + * @param segment1 + * segment 1 + * @param segment2 + * segment 2 + * @return true if intersection, false if not + */ +-(BOOL) intersectWithSegment: (SFSegment *) segment1 andSegment: (SFSegment *) segment2; + +/** + * Remove the segment from the sweep line + * + * @param segment + * segment + */ +-(void) removeSegment: (SFSegment *) segment; + +/** + * XY order of two points + * + * @param point1 + * point 1 + * @param point2 + * point 2 + * @return NSOrderedDescending if p1 > p2, NSOrderedAscending if p1 < p2, NSOrderedSame if equal + */ ++(NSComparisonResult) xyOrderWithPoint: (SFPoint *) point1 andPoint: (SFPoint *) point2; + +@end diff --git a/Pods/sf-ios/sf-ios/util/sweep/SFSweepLine.m b/Pods/sf-ios/sf-ios/util/sweep/SFSweepLine.m new file mode 100644 index 0000000..cf41d1e --- /dev/null +++ b/Pods/sf-ios/sf-ios/util/sweep/SFSweepLine.m @@ -0,0 +1,305 @@ +// +// SFSweepLine.m +// sf-ios +// +// Created by Brian Osborn on 1/12/18. +// Copyright © 2018 NGA. All rights reserved. +// + +#import "SFSweepLine.h" + +@interface SFSweepLine() + +/** + * Polygon rings + */ +@property (nonatomic, strong) NSArray *rings; + +/** + * Tree of segments sorted by above-below order + * TODO performance could be improved with a Red-Black or AVL tree + */ +@property NSMutableOrderedSet *tree; + +/** + * Mapping between ring, edges, and segments + */ +@property NSMutableDictionary *> *segments; + +@end + +@implementation SFSweepLine + +-(instancetype) initWithRings: (NSArray *) rings{ + self = [super init]; + if(self != nil){ + self.rings = rings; + self.tree = [[NSMutableOrderedSet alloc] init]; + self.segments = [NSMutableDictionary dictionary]; + } + return self; +} + +-(SFSegment *) addEvent: (SFEvent *) event{ + + SFSegment *segment = [self createSegmentForEvent:event]; + + // Add to the tree + int insertLocation = [self locationOfSegment:segment]; + [self.tree insertObject:segment atIndex:insertLocation]; + + // Update the above and below pointers + SFSegment *next = [self higherSegment:insertLocation]; + SFSegment *previous = [self lowerSegment:insertLocation]; + if (next != nil) { + segment.above = next; + next.below = segment; + } + if (previous != nil) { + segment.below = previous; + previous.above = segment; + } + + // Add to the segments map + NSNumber *ringNumber = [NSNumber numberWithInt:segment.ring]; + NSMutableDictionary *edgeDictionary = [self.segments objectForKey:ringNumber]; + if (edgeDictionary == nil) { + edgeDictionary = [NSMutableDictionary dictionary]; + [self.segments setObject:edgeDictionary forKey:ringNumber]; + } + [edgeDictionary setObject:segment forKey:[NSNumber numberWithInt:segment.edge]]; + + return segment; +} + +/** + * Get the location where the segment should be inserted or is located + * + * @param segment + * segment + * @return index location + */ +-(int) locationOfSegment: (SFSegment *) segment{ + + NSUInteger insertLocation = [self.tree indexOfObject:segment inSortedRange:NSMakeRange(0, self.tree.count) options:NSBinarySearchingInsertionIndex usingComparator:^NSComparisonResult(SFSegment *segment1, SFSegment *segment2){ + + NSComparisonResult compare = NSOrderedSame; + + if(segment1 != segment2){ + + SFPoint *lp1 = [segment1 leftPoint]; + SFPoint *rp1 = [segment1 rightPoint]; + SFPoint *lp2 = [segment2 leftPoint]; + SFPoint *rp2 = [segment2 rightPoint]; + + if([lp1.x doubleValue] <= [lp2.x doubleValue]){ + double s = [SFSweepLine isPoint:lp2 leftOfSegment:segment1]; + if(s != 0){ + compare = [self comparison:s > 0]; + }else{ + if([lp1 isEqualXToPoint:rp1]){ // Vertical line + compare = [self comparison:[lp1.y doubleValue] < [lp2.y doubleValue]]; + }else{ + compare = [self comparison:[SFSweepLine isPoint:rp2 leftOfSegment:segment1] > 0]; + } + } + }else{ + double s = [SFSweepLine isPoint:lp1 leftOfSegment:segment2]; + if(s != 0){ + compare = [self comparison:s < 0]; + }else{ + compare = [self comparison:[SFSweepLine isPoint:rp1 leftOfSegment:segment2] < 0]; + } + } + + } + + return compare; + }]; + + return (int)insertLocation; +} + +-(NSComparisonResult) comparison: (BOOL) left{ + return left ? NSOrderedAscending : NSOrderedDescending; +} + +/** + * Get the segment lower than the location + * + * @param location + * segment location + * @return lower segment + */ +-(SFSegment *) lowerSegment: (int) location{ + SFSegment *lower = nil; + if(location > 0){ + lower = [self.tree objectAtIndex:location - 1]; + } + return lower; +} + +/** + * Get the segment higher than the location + * + * @param location + * segment location + * @return higher segment + */ +-(SFSegment *) higherSegment: (int) location{ + SFSegment *higher = nil; + if(location + 1 < self.tree.count){ + higher = [self.tree objectAtIndex:location + 1]; + } + return higher; +} + +/** + * Create a segment from the event + * + * @param event + * event + * @return segment + */ +-(SFSegment *) createSegmentForEvent: (SFEvent *) event{ + + int edgeNumber = event.edge; + int ringNumber = event.ring; + + SFLineString *ring = [self.rings objectAtIndex:ringNumber]; + NSArray *points = ring.points; + + SFPoint *point1 = [points objectAtIndex:edgeNumber]; + SFPoint *point2 = [points objectAtIndex:(edgeNumber + 1) % points.count]; + + SFPoint *left = nil; + SFPoint *right = nil; + if([SFSweepLine xyOrderWithPoint:point1 andPoint:point2] == NSOrderedAscending){ + left = point1; + right = point2; + } else { + right = point1; + left = point2; + } + + SFSegment *segment = [[SFSegment alloc] initWithEdge:edgeNumber andRing:ringNumber andLeftPoint:left andRightPoint:right]; + + return segment; +} + +-(SFSegment *) findEvent: (SFEvent *) event{ + return [[self.segments objectForKey:[NSNumber numberWithInt:event.ring]] objectForKey:[NSNumber numberWithInt:event.edge]]; +} + +-(BOOL) intersectWithSegment: (SFSegment *) segment1 andSegment: (SFSegment *) segment2{ + + BOOL intersect = NO; + + if (segment1 != nil && segment2 != nil) { + + int ring1 = segment1.ring; + int ring2 = segment2.ring; + + BOOL consecutive = ring1 == ring2; + if (consecutive) { + int edge1 = segment1.edge; + int edge2 = segment2.edge; + int ringPoints = [[self.rings objectAtIndex:ring1] numPoints]; + consecutive = (edge1 + 1) % ringPoints == edge2 + || edge1 == (edge2 + 1) % ringPoints; + } + + if (!consecutive) { + + double left = [SFSweepLine isPoint:segment2.leftPoint leftOfSegment:segment1]; + double right = [SFSweepLine isPoint:segment2.rightPoint leftOfSegment:segment1]; + + if (left * right <= 0) { + + left = [SFSweepLine isPoint:segment1.leftPoint leftOfSegment:segment2]; + right = [SFSweepLine isPoint:segment1.rightPoint leftOfSegment:segment2]; + + if (left * right <= 0) { + intersect = YES; + } + } + } + } + + return intersect; +} + +-(void) removeSegment: (SFSegment *) segment{ + + BOOL removed = NO; + + int location = [self locationOfSegment:segment]; + if(location < self.tree.count){ + SFSegment *treeSegment = [self.tree objectAtIndex:location]; + if([treeSegment isEqual:segment]){ + [self.tree removeObjectAtIndex:location]; + removed = YES; + } + } + + if (removed) { + + SFSegment *above = segment.above; + SFSegment *below = segment.below; + if (above != nil) { + above.below = below; + } + if (below != nil) { + below.above = above; + } + + [[self.segments objectForKey:[NSNumber numberWithInt:segment.ring]] removeObjectForKey:[NSNumber numberWithInt:segment.edge]]; + } +} + ++(NSComparisonResult) xyOrderWithPoint: (SFPoint *) point1 andPoint: (SFPoint *) point2{ + NSComparisonResult value = NSOrderedSame; + if ([point1.x doubleValue] > [point2.x doubleValue]) { + value = NSOrderedDescending; + } else if ([point1.x doubleValue] < [point2.x doubleValue]) { + value = NSOrderedAscending; + } else if ([point1.y doubleValue] > [point2.y doubleValue]) { + value = NSOrderedDescending; + } else if ([point1.y doubleValue] < [point2.y doubleValue]) { + value = NSOrderedAscending; + } + return value; +} + +/** + * Check where the point is (left, on, right) relative to the line segment + * + * @param point + * point + * @param segment + * segment + * @return > 0 if left, 0 if on, < 0 if right + */ ++(double) isPoint: (SFPoint *) point leftOfSegment: (SFSegment *) segment{ + return [self isPoint:point leftOfPoint1:segment.leftPoint toPoint2:segment.rightPoint]; +} + +/** + * Check where point is (left, on, right) relative to the line from point 1 to point 2 + * + * @param point + * point + * @param point1 + * point 1 + * @param point2 + * point 2 + * @return > 0 if left, 0 if on, < 0 if right + */ ++(double) isPoint: (SFPoint *) point leftOfPoint1: (SFPoint *) point1 toPoint2: (SFPoint *) point2{ + return ([point2.x doubleValue] - [point1.x doubleValue]) + * ([point.y doubleValue] - [point1.y doubleValue]) + - ([point.x doubleValue] - [point1.x doubleValue]) + * ([point2.y doubleValue] - [point1.y doubleValue]); +} + +@end diff --git a/README.md b/README.md index 42e1ff8..ae594f7 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,12 @@ TAK Tracker is a update-only version of [TAK](https://www.tak.gov) for Apple Devices. It is designed to be quick to deploy and easy to use for teams to give to users who just need location tracked. The app is configured to send both broadcast and to a TAK Server directly, and is being to developed to support all of the features from the Android TAK Tracker. -Below is a portion of the roadmap being tracked. It is _highly_ likely that this project will end up spawing a separate iOS TAK app since TAK Tracker is supposed to be very lightweight. So if something isn't working or you don't see something on the list below, please use [GitHub Issues](https://github.com/flighttactics/TAKTracker/issues) to let us know about it if it isn't already being tracked there. +Below is a portion of the roadmap being tracked. If something isn't working or you don't see something on the list below, please use [GitHub Issues](https://github.com/flighttactics/TAKTracker/issues) to let us know about it (if it isn't already being tracked there) and we'll route it either to this project or to [SwiftTAK](https://github.com/flighttactics/SwiftTAK) depending on where the issue/feature is. -If you are interested in integrating this into your own product or want a custom iOS/Android/etc TAK app, plugins or features, let us know by contacting foyc at flighttactics dot com or visiting [Flight Tactics](https://www.flighttactics.com) +If you are interested in integrating this into your own product or want a custom iOS/Android/etc TAK app, plugins or features, let us know by contacting opensource at flighttactics dot com or visiting [Flight Tactics](https://www.flighttactics.com) ## Current TAK Tracker Parity Feature Status in rough priority / sequence: -- [ ] [Toggle Coordinates between DMS and MGRS](https://github.com/flighttactics/TAKTracker/issues/8) - [ ] [Group/Channel Support](https://github.com/flighttactics/TAKTracker/issues/14) - [ ] [Protobuf Support](https://github.com/flighttactics/TAKTracker/issues/9) - [ ] [TAK Chat](https://github.com/flighttactics/TAKTracker/issues/12) @@ -17,10 +16,11 @@ If you are interested in integrating this into your own product or want a custom - [ ] [Show Compass Accuracy](https://github.com/flighttactics/TAKTracker/issues/7) - [ ] [App notifications when connection lost](https://github.com/flighttactics/TAKTracker/issues/13) - [ ] [Allow user to toggle background update indicator](https://github.com/flighttactics/TAKTracker/issues/17) -- [X] [Allow setting the Team/Role](https://github.com/flighttactics/TAKTracker/issues/10) -- [X] [Emergency Beacon](https://github.com/flighttactics/TAKTracker/issues/11) -- [X] [Have compass / heading recognize landscape mode](https://github.com/flighttactics/TAKTracker/issues/16) -- [X] Better messages and logging about the state of parsing the packages and data connections +- [X] ~[Toggle Coordinates between DMS and MGRS](https://github.com/flighttactics/TAKTracker/issues/8)~ +- [X] ~[Allow setting the Team/Role](https://github.com/flighttactics/TAKTracker/issues/10)~ +- [X] ~[Emergency Beacon](https://github.com/flighttactics/TAKTracker/issues/11)~ +- [X] ~[Have compass / heading recognize landscape mode](https://github.com/flighttactics/TAKTracker/issues/16)~ +- [X] ~Better messages and logging about the state of parsing the packages and data connections~ - [X] ~[Allow map to be scrolled without resetting](https://github.com/flighttactics/TAKTracker/issues/1)~ - [X] ~Certificate Enrollment for connecting to server~ - [X] ~Toggle Compass and Speed Units by tapping the numbers~ @@ -57,4 +57,5 @@ Unless required by applicable law or agreed to in writing, software distributed Commercial Use support licenses are available - please contact opensource@flighttactics.com for more information. This app uses the following Open Source libraries: -- [SwiftTAK](https://github.com/flighttactics/swifttak) +- [SwiftTAK](https://github.com/flighttactics/swifttak) under the Apache License, Version 2.0 +- [mgrs-ios](https://github.com/ngageoint/mgrs-ios) under the MIT License diff --git a/TAKTracker.xcodeproj/project.pbxproj b/TAKTracker.xcodeproj/project.pbxproj index 1d21e00..5547792 100644 --- a/TAKTracker.xcodeproj/project.pbxproj +++ b/TAKTracker.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 479B8B617AB264363ABCD93B /* Pods_TAKTracker_TAKTrackerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEFD401A913144B7229D2781 /* Pods_TAKTracker_TAKTrackerTests.framework */; }; A508213F2AB3D19B00E0CBD8 /* TAKCAConfigResponseParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = A508213E2AB3D19B00E0CBD8 /* TAKCAConfigResponseParser.swift */; }; A50C5F5B2A5F92FF001E52E6 /* SettingsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50C5F5A2A5F92FF001E52E6 /* SettingsStore.swift */; }; A50C5F5D2A601CF0001E52E6 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50C5F5C2A601CF0001E52E6 /* SettingsView.swift */; }; @@ -60,6 +61,7 @@ A5FB4E8B2AACF2830034966D /* itak-do-foyc.zip in Resources */ = {isa = PBXBuildFile; fileRef = A5FB4E862AACF2820034966D /* itak-do-foyc.zip */; }; A5FB4E8C2AACF2830034966D /* foyc.p12 in Resources */ = {isa = PBXBuildFile; fileRef = A5FB4E872AACF2830034966D /* foyc.p12 */; }; A5FB4E8E2AACF2A20034966D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A5FB4E8D2AACF2A10034966D /* Assets.xcassets */; }; + B6C8997D4C1B298C733111DC /* Pods_TAKTracker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0840B3A75D0239E21ADEA2E7 /* Pods_TAKTracker.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -80,6 +82,10 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 0840B3A75D0239E21ADEA2E7 /* Pods_TAKTracker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TAKTracker.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 0CD85BD73504580BC32FA239 /* Pods-TAKTracker-TAKTrackerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TAKTracker-TAKTrackerTests.debug.xcconfig"; path = "Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.debug.xcconfig"; sourceTree = ""; }; + 4B2EC40D21C80BEBE05D29F8 /* Pods-TAKTracker.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TAKTracker.debug.xcconfig"; path = "Target Support Files/Pods-TAKTracker/Pods-TAKTracker.debug.xcconfig"; sourceTree = ""; }; + 94A6A10561B512E86B0E9DC2 /* Pods-TAKTracker.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TAKTracker.release.xcconfig"; path = "Target Support Files/Pods-TAKTracker/Pods-TAKTracker.release.xcconfig"; sourceTree = ""; }; A508213E2AB3D19B00E0CBD8 /* TAKCAConfigResponseParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TAKCAConfigResponseParser.swift; sourceTree = ""; }; A50C5F5A2A5F92FF001E52E6 /* SettingsStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsStore.swift; sourceTree = ""; }; A50C5F5C2A601CF0001E52E6 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; @@ -129,6 +135,8 @@ A5FB4E862AACF2820034966D /* itak-do-foyc.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = "itak-do-foyc.zip"; sourceTree = ""; }; A5FB4E872AACF2830034966D /* foyc.p12 */ = {isa = PBXFileReference; lastKnownFileType = file; path = foyc.p12; sourceTree = ""; }; A5FB4E8D2AACF2A10034966D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + CEFD401A913144B7229D2781 /* Pods_TAKTracker_TAKTrackerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TAKTracker_TAKTrackerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E7150D9B3F41CFFF2C34C4A3 /* Pods-TAKTracker-TAKTrackerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TAKTracker-TAKTrackerTests.release.xcconfig"; path = "Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -138,6 +146,7 @@ files = ( A57BA53B2AB8DB3800452D85 /* SwiftTAK in Frameworks */, A5FB4E622A8FDF430034966D /* X509 in Frameworks */, + B6C8997D4C1B298C733111DC /* Pods_TAKTracker.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -145,6 +154,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 479B8B617AB264363ABCD93B /* Pods_TAKTracker_TAKTrackerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -158,6 +168,15 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 085BD5615028DC7C36297967 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 0840B3A75D0239E21ADEA2E7 /* Pods_TAKTracker.framework */, + CEFD401A913144B7229D2781 /* Pods_TAKTracker_TAKTrackerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; A55ABF432ABDBF7600195AB7 /* SettingsScreens */ = { isa = PBXGroup; children = ( @@ -183,6 +202,8 @@ A5D8D38D2A53B0FB002F0E3E /* TAKTrackerTests */, A5D8D3972A53B0FB002F0E3E /* TAKTrackerUITests */, A5D8D37B2A53B0F9002F0E3E /* Products */, + B7B57F813DDA55B613DBA70B /* Pods */, + 085BD5615028DC7C36297967 /* Frameworks */, ); sourceTree = ""; }; @@ -317,6 +338,17 @@ path = "Test Files"; sourceTree = ""; }; + B7B57F813DDA55B613DBA70B /* Pods */ = { + isa = PBXGroup; + children = ( + 4B2EC40D21C80BEBE05D29F8 /* Pods-TAKTracker.debug.xcconfig */, + 94A6A10561B512E86B0E9DC2 /* Pods-TAKTracker.release.xcconfig */, + 0CD85BD73504580BC32FA239 /* Pods-TAKTracker-TAKTrackerTests.debug.xcconfig */, + E7150D9B3F41CFFF2C34C4A3 /* Pods-TAKTracker-TAKTrackerTests.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -324,9 +356,11 @@ isa = PBXNativeTarget; buildConfigurationList = A5D8D39E2A53B0FB002F0E3E /* Build configuration list for PBXNativeTarget "TAKTracker" */; buildPhases = ( + 764FA0D86787F8AAAE7F1B0D /* [CP] Check Pods Manifest.lock */, A5D8D3762A53B0F9002F0E3E /* Sources */, A5D8D3772A53B0F9002F0E3E /* Frameworks */, A5D8D3782A53B0F9002F0E3E /* Resources */, + CCCAF8052769F0D0661730AA /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -345,9 +379,11 @@ isa = PBXNativeTarget; buildConfigurationList = A5D8D3A12A53B0FB002F0E3E /* Build configuration list for PBXNativeTarget "TAKTrackerTests" */; buildPhases = ( + 4F091DA11E97FA41B7E18FCD /* [CP] Check Pods Manifest.lock */, A5D8D3862A53B0FA002F0E3E /* Sources */, A5D8D3872A53B0FA002F0E3E /* Frameworks */, A5D8D3882A53B0FA002F0E3E /* Resources */, + 1BC6F84570B200F9E37EC8D9 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -457,6 +493,87 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 1BC6F84570B200F9E37EC8D9 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TAKTracker-TAKTrackerTests/Pods-TAKTracker-TAKTrackerTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 4F091DA11E97FA41B7E18FCD /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-TAKTracker-TAKTrackerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 764FA0D86787F8AAAE7F1B0D /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-TAKTracker-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + CCCAF8052769F0D0661730AA /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TAKTracker/Pods-TAKTracker-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ A5D8D3762A53B0F9002F0E3E /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -657,6 +774,7 @@ }; A5D8D39F2A53B0FB002F0E3E /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 4B2EC40D21C80BEBE05D29F8 /* Pods-TAKTracker.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -667,6 +785,7 @@ DEVELOPMENT_ASSET_PATHS = "TAKTracker/Preview\\ Content"; DEVELOPMENT_TEAM = 5LZ5HR44P3; ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "TAKTracker-Info.plist"; INFOPLIST_KEY_CFBundleDisplayName = "TAK Tracker"; @@ -694,6 +813,7 @@ }; A5D8D3A02A53B0FB002F0E3E /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 94A6A10561B512E86B0E9DC2 /* Pods-TAKTracker.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -704,6 +824,7 @@ DEVELOPMENT_ASSET_PATHS = "TAKTracker/Preview\\ Content"; DEVELOPMENT_TEAM = 5LZ5HR44P3; ENABLE_PREVIEWS = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "TAKTracker-Info.plist"; INFOPLIST_KEY_CFBundleDisplayName = "TAK Tracker"; @@ -731,12 +852,14 @@ }; A5D8D3A22A53B0FB002F0E3E /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 0CD85BD73504580BC32FA239 /* Pods-TAKTracker-TAKTrackerTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 53; DEVELOPMENT_TEAM = 5LZ5HR44P3; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.4; MARKETING_VERSION = 1.0; @@ -751,12 +874,14 @@ }; A5D8D3A32A53B0FB002F0E3E /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = E7150D9B3F41CFFF2C34C4A3 /* Pods-TAKTracker-TAKTrackerTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 53; DEVELOPMENT_TEAM = 5LZ5HR44P3; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.4; MARKETING_VERSION = 1.0; diff --git a/TAKTracker.xcworkspace/contents.xcworkspacedata b/TAKTracker.xcworkspace/contents.xcworkspacedata index 15297ca..e1c2eaa 100644 --- a/TAKTracker.xcworkspace/contents.xcworkspacedata +++ b/TAKTracker.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/TAKTracker/Screens/MainScreen.swift b/TAKTracker/Screens/MainScreen.swift index 18b0b07..96e179b 100644 --- a/TAKTracker/Screens/MainScreen.swift +++ b/TAKTracker/Screens/MainScreen.swift @@ -69,7 +69,7 @@ struct DisplayUIState { switch(currentLocationUnit) { case .DMS: return "DMS" case .Decimal: return "Decimal" - //case .MGRS: return "MGRS" + case .MGRS: return "MGRS" } } @@ -103,6 +103,12 @@ struct DisplayUIState { lineTitle: "Lon", lineContents: Converter.LatLonToDecimal(latitude: location.coordinate.longitude) )) + case .MGRS: + let mgrsString = Converter.LatLongToMGRS(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude) + display.addLine(line: CoordinateDisplayLine( + lineContents: mgrsString + )) + } return display @@ -278,6 +284,7 @@ struct MainScreen: View { Spacer() Text(line.lineContents) } else { + Spacer() Text(line.lineContents).padding(.leading, 5) } Spacer() diff --git a/TAKTracker/Utilities/Converter.swift b/TAKTracker/Utilities/Converter.swift index aa78569..c33a7d3 100644 --- a/TAKTracker/Utilities/Converter.swift +++ b/TAKTracker/Utilities/Converter.swift @@ -7,6 +7,7 @@ import Foundation import MapKit +import mgrs_ios enum SpeedUnit { case MetersPerSecond @@ -17,7 +18,7 @@ enum SpeedUnit { enum LocationUnit { case DMS - //case MGRS + case MGRS case Decimal } @@ -47,8 +48,11 @@ struct UnitOrder { case LocationUnit.Decimal: return LocationUnit.DMS case LocationUnit.DMS: + return LocationUnit.MGRS + case LocationUnit.MGRS: return LocationUnit.Decimal } + } static func nextDirectionUnit(unit:DirectionUnit) -> DirectionUnit { @@ -93,7 +97,12 @@ class Converter { } static func LatLongToMGRS(latitude: Double, longitude: Double) -> String { - return "" + let mgrsPoint = MGRS.from(longitude, latitude) + let accuracy = 5 - Int(log10(Double(GridType.METER.precision()))) + let easting = String(format: "%05d", mgrsPoint.easting) + let northing = String(format: "%05d", mgrsPoint.northing) + + return "\(mgrsPoint.zone)\(mgrsPoint.band) \(mgrsPoint.column)\(mgrsPoint.row) \(String(easting.prefix(accuracy))) \(String(northing.prefix(accuracy)))" } static func LatLonToDMS(latitude: Double) -> String { diff --git a/TAKTrackerTests/ConverterTests.swift b/TAKTrackerTests/ConverterTests.swift index 9eba182..ed04708 100644 --- a/TAKTrackerTests/ConverterTests.swift +++ b/TAKTrackerTests/ConverterTests.swift @@ -28,13 +28,13 @@ final class ConverterTests: TAKTrackerTestCase { return CLLocation(coordinate: mockLocationCoordinate, altitude: mockDistance, horizontalAccuracy: mockAccuracy, verticalAccuracy: mockAccuracy, course: mockDirection, speed: mockSpeedMetersPerSecond, timestamp: Date()) } -// func testLatLongToMGRS() { -// let expected = "18S UJ 26938 05973" -// let coordinate = mockLocationCoordinate() -// let latitude = coordinate.latitude as Double -// let longitude = coordinate.longitude as Double -// XCTAssertEqual(expected, Converter.LatLongToMGRS(latitude: latitude, longitude: longitude)) -// } + func testLatLongToMGRS() { + let expected = "18S UJ 26938 05973" + let coordinate = mockLocationCoordinate() + let latitude = coordinate.latitude as Double + let longitude = coordinate.longitude as Double + XCTAssertEqual(expected, Converter.LatLongToMGRS(latitude: latitude, longitude: longitude)) + } func testLatitudeToDMS() { let latitude = mockLocationCoordinate().latitude as Double @@ -66,23 +66,20 @@ final class ConverterTests: TAKTrackerTestCase { XCTAssertEqual("67", Converter.convertToSpeedUnit(unit: SpeedUnit.MilesPerHour, location: location)) } - func testTogglingDMStoDecimal() { - XCTAssertEqual(LocationUnit.Decimal, UnitOrder.nextLocationUnit(unit: LocationUnit.DMS)) + //DMS -> MGRS -> Decimal + + func testTogglingDMStoMGRS() { + XCTAssertEqual(LocationUnit.MGRS, UnitOrder.nextLocationUnit(unit: LocationUnit.DMS)) + } + + func testTogglingMGRStoDecimal() { + XCTAssertEqual(LocationUnit.Decimal, UnitOrder.nextLocationUnit(unit: LocationUnit.MGRS)) } func testTogglingDecimaltoDMS() { XCTAssertEqual(LocationUnit.DMS, UnitOrder.nextLocationUnit(unit: LocationUnit.Decimal)) } - -// func testTogglingDMStoMGRS() { -// XCTAssertEqual(LocationUnit.MGRS, UnitOrder.nextLocationUnit(unit: LocationUnit.DMS)) -// } -// -// func testTogglingMGRStoDMS() { -// XCTAssertEqual(LocationUnit.DMS, UnitOrder.nextLocationUnit(unit: LocationUnit.MGRS)) -// } - func testTogglingMNtoTN() { XCTAssertEqual(DirectionUnit.TN, UnitOrder.nextDirectionUnit(unit: DirectionUnit.MN)) }