diff --git a/Data/Baseline/Examples/Projections/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt b/Data/Baseline/Examples/Projections/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt index 3b7575f0e55760da3a6ab94c9e422684a4f56896..bef7d330228075214cc9660493b3c27b572df4f1 100644 --- a/Data/Baseline/Examples/Projections/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt +++ b/Data/Baseline/Examples/Projections/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt @@ -1,205 +1,2 @@ -Image (0x1a6f470) - RTTI typeinfo: otb::Image - Reference Count: 2 - Modified Time: 141 - Debug: Off - Object Name: - Observers: - none - Source: (0x1a6f820) - Source output name: Primary - Release Data: Off - Data Released: False - Global Release Data: Off - PipelineMTime: 138 - UpdateMTime: 0 - RealTimeStamp: 0.0000000000 seconds - LargestPossibleRegion: - Dimension: 2 - Index: [0, 0] - Size: [3000, 3000] - BufferedRegion: - Dimension: 2 - Index: [0, 0] - Size: [0, 0] - RequestedRegion: - Dimension: 2 - Index: [0, 0] - Size: [3000, 3000] - Spacing: [1.0000000000, 1.0000000000] - Origin: [0.5000000000, 0.5000000000] - Direction: -1.0000000000 0.0000000000 -0.0000000000 1.0000000000 - - IndexToPointMatrix: -1.0000000000 0.0000000000 -0.0000000000 1.0000000000 - - PointToIndexMatrix: -1.0000000000 0.0000000000 -0.0000000000 1.0000000000 - - Inverse Direction: -1.0000000000 0.0000000000 -0.0000000000 1.0000000000 - - PixelContainer: - ImportImageContainer (0x1a6f650) - RTTI typeinfo: itk::ImportImageContainer - Reference Count: 1 - Modified Time: 18 - Debug: Off - Object Name: - Observers: - none - Pointer: 0 - Container manages memory: true - Size: 0 - Capacity: 0 - ---> DataType = 0 - ---> DriverLongName = CEOS Image - ---> DriverShortName = CEOS - ---> LowerLeftCorner[0] = 0.0000000000 - ---> LowerLeftCorner[1] = 3000.0000000000 - ---> LowerRightCorner[0] = 3000.0000000000 - ---> LowerRightCorner[1] = 3000.0000000000 - ---> OSSIMKeywordlist - Ossim Keyword list: - adjustment_0.adj_param_0.center: 0 -adjustment_0.adj_param_0.description: intrack_offset -adjustment_0.adj_param_0.lock_flag: 0 -adjustment_0.adj_param_0.parameter: 0 -adjustment_0.adj_param_0.sigma: 50 -adjustment_0.adj_param_0.units: pixel -adjustment_0.adj_param_1.center: 0 -adjustment_0.adj_param_1.description: crtrack_offset -adjustment_0.adj_param_1.lock_flag: 0 -adjustment_0.adj_param_1.parameter: 0 -adjustment_0.adj_param_1.sigma: 50 -adjustment_0.adj_param_1.units: pixel -adjustment_0.adj_param_2.center: 0 -adjustment_0.adj_param_2.description: intrack_scale -adjustment_0.adj_param_2.lock_flag: 0 -adjustment_0.adj_param_2.parameter: 0 -adjustment_0.adj_param_2.sigma: 50 -adjustment_0.adj_param_2.units: unknown -adjustment_0.adj_param_3.center: 0 -adjustment_0.adj_param_3.description: crtrack_scale -adjustment_0.adj_param_3.lock_flag: 0 -adjustment_0.adj_param_3.parameter: 0 -adjustment_0.adj_param_3.sigma: 50 -adjustment_0.adj_param_3.units: unknown -adjustment_0.adj_param_4.center: 0 -adjustment_0.adj_param_4.description: map_rotation -adjustment_0.adj_param_4.lock_flag: 0 -adjustment_0.adj_param_4.parameter: 0 -adjustment_0.adj_param_4.sigma: 0.1 -adjustment_0.adj_param_4.units: degrees -adjustment_0.description: Initial adjustment -adjustment_0.dirty_flag: 0 -adjustment_0.number_of_params: 5 -current_adjustment: 0 -height_off: 0 -height_scale: 4.5035996273705e+15 -lat_off: -43.13823715 -lat_scale: 1 -line_den_coeff_0: 1 -line_den_coeff_1: 2.43189701059228 -line_den_coeff_10: 0 -line_den_coeff_11: 0.427993733624612 -line_den_coeff_12: 0.211112963392964 -line_den_coeff_13: 0 -line_den_coeff_14: 0.367481099808053 -line_den_coeff_15: -0.393242099048278 -line_den_coeff_16: 0 -line_den_coeff_17: 0 -line_den_coeff_18: 0 -line_den_coeff_19: 0 -line_den_coeff_2: 4.20166177009252 -line_den_coeff_3: 0 -line_den_coeff_4: -0.160493581744926 -line_den_coeff_5: 0 -line_den_coeff_6: 0 -line_den_coeff_7: -0.269037030636058 -line_den_coeff_8: -0.667969530867681 -line_den_coeff_9: 0 -line_num_coeff_0: 0.240525444509033 -line_num_coeff_1: -3.13682519152775 -line_num_coeff_10: 5.05780223817459e-15 -line_num_coeff_11: 0.695793592435728 -line_num_coeff_12: 2.82251754264863 -line_num_coeff_13: 1.34538684327756e-15 -line_num_coeff_14: 0.463079410620594 -line_num_coeff_15: 0.222379206138169 -line_num_coeff_16: -3.76392327824494e-39 -line_num_coeff_17: -2.98517180447189e-40 -line_num_coeff_18: -1.34473504680247e-40 -line_num_coeff_19: 0 -line_num_coeff_2: 0.346548655180022 -line_num_coeff_3: -3.6731478667714e-15 -line_num_coeff_4: -17.3762105306822 -line_num_coeff_5: -1.18563642519605e-12 -line_num_coeff_6: -4.59667104442646e-13 -line_num_coeff_7: -9.24949285654521 -line_num_coeff_8: -2.94080878691262 -line_num_coeff_9: 9.75220202913922e-14 -line_off: 1500.5 -line_scale: 1454.5 -long_off: -22.88265985 -long_scale: 1 -number_of_adjustments: 1 -polynomial_format: B -samp_den_coeff_0: 1 -samp_den_coeff_1: 10.2569493509116 -samp_den_coeff_10: 0 -samp_den_coeff_11: 1.5540812085977 -samp_den_coeff_12: 1.0328092004279 -samp_den_coeff_13: 0 -samp_den_coeff_14: -1.32560471731861 -samp_den_coeff_15: -0.109971870820347 -samp_den_coeff_16: 0 -samp_den_coeff_17: 0 -samp_den_coeff_18: 0 -samp_den_coeff_19: 0 -samp_den_coeff_2: -0.673329431520661 -samp_den_coeff_3: 0 -samp_den_coeff_4: -0.0898098294659881 -samp_den_coeff_5: 0 -samp_den_coeff_6: 0 -samp_den_coeff_7: -1.01273131687892 -samp_den_coeff_8: 1.63658544331894 -samp_den_coeff_9: 0 -samp_num_coeff_0: -0.0293896997028787 -samp_num_coeff_1: -1.06364616725089 -samp_num_coeff_10: 2.51292516596346e-13 -samp_num_coeff_11: -0.130988460347871 -samp_num_coeff_12: 0.715080909979046 -samp_num_coeff_13: -5.44410980146769e-15 -samp_num_coeff_14: -3.40023401886119 -samp_num_coeff_15: 4.06427430084709 -samp_num_coeff_16: 3.7210399260609e-16 -samp_num_coeff_17: -8.27988733245361e-26 -samp_num_coeff_18: 0 -samp_num_coeff_19: 0 -samp_num_coeff_2: 2.74938094322821 -samp_num_coeff_3: -5.80757287997929e-10 -samp_num_coeff_4: 28.4971056225152 -samp_num_coeff_5: -9.75802000107915e-11 -samp_num_coeff_6: 5.79346199894214e-11 -samp_num_coeff_7: -8.00166234441079 -samp_num_coeff_8: -1.68546715570593 -samp_num_coeff_9: -1.50596504636281e-13 -samp_off: 1477.5 -samp_scale: 1406.5 -type: ossimRpcProjection - ---> ResolutionFactor = 0 - ---> SubDatasetIndex = 0 - ---> TileHintX = 3000 - ---> TileHintY = 1 - ---> UpperLeftCorner[0] = 0.0000000000 - ---> UpperLeftCorner[1] = 0.0000000000 - ---> UpperRightCorner[0] = 3000.0000000000 - ---> UpperRightCorner[1] = 0.0000000000 - -Residual ground error: 2.8481201293 +{"LineOffset": "2224.5", "SampleOffset": "2224.5", "LatOffset": "43.6089", "LonOffset": "1.42524", "HeightOffset": "0", "LineScale": "225.5", "SampleScale": "225.5", "LatScale": "1", "LonScale": "1", "HeightScale": "1", "LineNum": [ "0.00176507", "0.469826", "-182.989", "-3.97557e-14", "0.000167599", "-4.11403e-23", "4.64211e-36", "-0.000132256", "-0.00299522", "0", "0", "4.13719e-05", "-2.66116e-05", "0", "-0.00378323", "-0.0039722", "0", "0", "0", "0", ], "LineDen": [ "1", "0.116648", "-0.795797", "0", "-0.0017625", "0", "0", "-0.692057", "-0.725159", "0", "0", "4.24205e-06", "-1.2217e-05", "0", "-1.62292e-05", "-1.11751e-05", "0", "0", "0", "0", ], "SampleNum": [ "-4.03023e-05", "140.123", "0.720549", "-3.96237e-14", "-0.000307018", "-6.10744e-25", "3.08505e-39", "7.06292e-05", "0.000393857", "0", "0", "0.00514045", "0.00169871", "0", "3.04772e-06", "3.05975e-05", "0", "0", "0", "0", ], "SampleDen": [ "1", "-0.0140652", "0.0561119", "0", "-0.00165428", "0", "0", "-0.720295", "-0.238046", "0", "0", "-2.11567e-07", "-2.527e-06", "0", "1.28729e-06", "7.08213e-06", "0", "0", "0", "0", ], } +Residual ground error: 1.2432282311 diff --git a/Data/Baseline/Examples/Projections/vectorDataProjectionExample.1.dbf b/Data/Baseline/Examples/Projections/vectorDataProjectionExample.1.dbf index 64a213d3b909d440533d1d625e62bbedad41a6c8..e7f27172e0b8ffa5e842e26f5ce0be21069a1f29 100644 --- a/Data/Baseline/Examples/Projections/vectorDataProjectionExample.1.dbf +++ b/Data/Baseline/Examples/Projections/vectorDataProjectionExample.1.dbf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:42f1f66a4385e2b36d7b909e51dbba6c6449093d06b6a2f1ca8f36f841388b06 +oid sha256:28db43ed7ef45f04ebcdcac271ce838a1d2667e8db78e1c9365d8d3465a42fd2 size 1708 diff --git a/Data/Baseline/Examples/Projections/vectorDataProjectionExample.1.shp b/Data/Baseline/Examples/Projections/vectorDataProjectionExample.1.shp index 0500f6fad6c289a7b5a16cb250eae3b5b6975d1c..49986967cb5d494cc197ee8ff871c4bf5693d09f 100644 --- a/Data/Baseline/Examples/Projections/vectorDataProjectionExample.1.shp +++ b/Data/Baseline/Examples/Projections/vectorDataProjectionExample.1.shp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b2ceb97f018187a48821b228f3ee73fd162614cf2d7e809580df69ebdfb95955 +oid sha256:945bcb8fc61dec6192a806fcf153755254039ea97802fc10c5926261f6087cea size 5108 diff --git a/Data/Baseline/Examples/Projections/vectorDataProjectionExample.1.shx b/Data/Baseline/Examples/Projections/vectorDataProjectionExample.1.shx index 96318910bc498b9962a95f3265777954d8499f1d..193d063a11040801ccc83bcafe9ea85e2a27212b 100644 --- a/Data/Baseline/Examples/Projections/vectorDataProjectionExample.1.shx +++ b/Data/Baseline/Examples/Projections/vectorDataProjectionExample.1.shx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a50f2a7d39fb606fe3b4105d1a5f363a12f5199879679abc8ee7290ec9629222 +oid sha256:2f48d605a5612f5cf8782e1352d46fa17075b077cef366aeec83136753acd3d7 size 180 diff --git a/Data/Baseline/Examples/Projections/vectorDataProjectionExample.dbf b/Data/Baseline/Examples/Projections/vectorDataProjectionExample.dbf index 18614b7873aec2e5909b6608121c0f100109f5ef..46752c69e57a28ac6e772fd24ffec773f24ca95a 100644 --- a/Data/Baseline/Examples/Projections/vectorDataProjectionExample.dbf +++ b/Data/Baseline/Examples/Projections/vectorDataProjectionExample.dbf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e6650bf5852cbdcf63f2f5f423a6bb835d40580346bb24ca53ed390b3211c2f +oid sha256:54dbbde928486a22a7b0d0edcc49b08abc35d617a008fecef285fccf274251de size 1242 diff --git a/Data/Baseline/Examples/Projections/vectorDataProjectionExample.shp b/Data/Baseline/Examples/Projections/vectorDataProjectionExample.shp index 0500f6fad6c289a7b5a16cb250eae3b5b6975d1c..49986967cb5d494cc197ee8ff871c4bf5693d09f 100644 --- a/Data/Baseline/Examples/Projections/vectorDataProjectionExample.shp +++ b/Data/Baseline/Examples/Projections/vectorDataProjectionExample.shp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b2ceb97f018187a48821b228f3ee73fd162614cf2d7e809580df69ebdfb95955 +oid sha256:945bcb8fc61dec6192a806fcf153755254039ea97802fc10c5926261f6087cea size 5108 diff --git a/Data/Baseline/Examples/Projections/vectorDataProjectionExample.shx b/Data/Baseline/Examples/Projections/vectorDataProjectionExample.shx index 96318910bc498b9962a95f3265777954d8499f1d..193d063a11040801ccc83bcafe9ea85e2a27212b 100644 --- a/Data/Baseline/Examples/Projections/vectorDataProjectionExample.shx +++ b/Data/Baseline/Examples/Projections/vectorDataProjectionExample.shx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a50f2a7d39fb606fe3b4105d1a5f363a12f5199879679abc8ee7290ec9629222 +oid sha256:2f48d605a5612f5cf8782e1352d46fa17075b077cef366aeec83136753acd3d7 size 180 diff --git a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.dbf b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.dbf index 60750febc582ffe56227424757115c55edeb136d..6e67fe38cad2f080f8340ab2694be519655f5981 100644 --- a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.dbf +++ b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.dbf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2eced35eb80654e1ee53b8085e586c610356dcdeba771b8dcdbbfe8a9c4c767f +oid sha256:fd0e02d284913a4c56b4fdfe7cb20b85dbc9dcda21981ba02d2e020dd93f2655 size 186 diff --git a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.prj b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.prj index a30c00a55de19be195abf9e942f6cff93bf0a825..f45cbadf0074d8b7b2669559a93bc50bb95f82d4 100644 --- a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.prj +++ b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.prj @@ -1 +1 @@ -GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] \ No newline at end of file +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] \ No newline at end of file diff --git a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.shp b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.shp index adbeb9a3ee72737b9636e855294e66235e90c57c..33a00480823cf32f0a2c7fccb1bc88a166677922 100644 --- a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.shp +++ b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.shp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:35e01407d0258fbb42870ce508c06cd68bc6d917394e4a0838e239e0adf16fd0 +oid sha256:bf4462f4cd91ee269bdd374f2841e18a5936e4507d0293bddb4ad60907edc92d size 980 diff --git a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.shx b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.shx index 1c46319c9b054443a3b314064a73b2de6cc11d25..eb16adcd2103def879a2ad7755f20f62fa2a628a 100644 --- a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.shx +++ b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI.shx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b36574ce2feda398c5f1815a3bd2176b5330e7c0c1fbb073d11652db96b825a9 +oid sha256:be8d859e3384f3f31946e2d2b7754e419f83c9b64df72282afa5f8e9cb5af96f size 180 diff --git a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.dbf b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.dbf index 60750febc582ffe56227424757115c55edeb136d..6e67fe38cad2f080f8340ab2694be519655f5981 100644 --- a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.dbf +++ b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.dbf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2eced35eb80654e1ee53b8085e586c610356dcdeba771b8dcdbbfe8a9c4c767f +oid sha256:fd0e02d284913a4c56b4fdfe7cb20b85dbc9dcda21981ba02d2e020dd93f2655 size 186 diff --git a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.prj b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.prj index a30c00a55de19be195abf9e942f6cff93bf0a825..f45cbadf0074d8b7b2669559a93bc50bb95f82d4 100644 --- a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.prj +++ b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.prj @@ -1 +1 @@ -GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] \ No newline at end of file +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] \ No newline at end of file diff --git a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.shp b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.shp index 0170aff2e0b2257089c7d1b651d049892ffe9d1a..b92f34ad25a3289c14a6e2d742531405ef8607f7 100644 --- a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.shp +++ b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.shp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:abdfe81670c95a33e1068fc471105989a71e0f7fa957dd99decde5ed11fc8d78 +oid sha256:80f280fa98fea4fddb3f964110bca0fe9a812e1835a8f791abaa9a8d06433eb1 size 980 diff --git a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.shx b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.shx index 77feb9b08ef6d29716e08e4015595efb0fa2f4d0..19462241fc86a938badb92de7a334fced0ecfdda 100644 --- a/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.shx +++ b/Data/Baseline/OTB-Applications/Files/feTvLineSegmentDetection_LI_NoRescale.shx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:32b827341d5bbe6c5612784a4a86a5d8f97f2797983d95cdfc32eacb07cdac37 +oid sha256:363cbcfc5c71b7ea4ba2d139f8f87afb99ff0874122742aede2fad55aae350d8 size 180 diff --git a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.dbf b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.dbf index ac6c853e44c1a0b6d116d80286d159d647b5e1f9..c964ee351249949a9ac5b18d9cea7cce4d04c5a3 100644 --- a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.dbf +++ b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.dbf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ccc8fdfff077ae99dd918b6dbb9e3c003b66088ddaa3657735b730a295bc7de +oid sha256:4929d9967ad0dece178ebf4fc916cdffe4b43cef180c7c777edb2f422e634261 size 110 diff --git a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.prj b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.prj index da98376fa44ea626ab3c6ca1debe4660482e548b..a46c6c43edd87973633a512926c8dbaf68b9dd8e 100644 --- a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.prj +++ b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.prj @@ -1 +1 @@ -PROJCS["WGS_1984_UTM_Zone_31N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]] \ No newline at end of file +PROJCS["WGS_1984_UTM_Zone_31N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",3.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] \ No newline at end of file diff --git a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.shp b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.shp index 82e347e520a49cc895e2f1395d78d37e68da3ca6..b54a1c85c8aa454b8c04b8861c7da965e1501703 100644 --- a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.shp +++ b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.shp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b24ad95b78029f22b61cd9611225bcfc0e888a44994923631bb0439e2b0eb270 +oid sha256:657ee49e40a237f1ca2a93051b77ddaf2ab009f17d40bbe044643fbe888f88ec size 692 diff --git a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.shx b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.shx index ce56994c7810ff1c41d236aa9e1731c215eb4ac8..867b391ff8101405616b851548193430690a942e 100644 --- a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.shx +++ b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Rotation.shx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:13f084b04d7626ce498e468a650096ff7ab8efade100ba0b4e8a64f4cc8ecb1f +oid sha256:3ff683d706a78445b8a17d6c759e9e0976eba6d1b505f8390db7e19f69d26a15 size 132 diff --git a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.dbf b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.dbf index ac6c853e44c1a0b6d116d80286d159d647b5e1f9..c964ee351249949a9ac5b18d9cea7cce4d04c5a3 100644 --- a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.dbf +++ b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.dbf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ccc8fdfff077ae99dd918b6dbb9e3c003b66088ddaa3657735b730a295bc7de +oid sha256:4929d9967ad0dece178ebf4fc916cdffe4b43cef180c7c777edb2f422e634261 size 110 diff --git a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.prj b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.prj index da98376fa44ea626ab3c6ca1debe4660482e548b..a46c6c43edd87973633a512926c8dbaf68b9dd8e 100644 --- a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.prj +++ b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.prj @@ -1 +1 @@ -PROJCS["WGS_1984_UTM_Zone_31N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]] \ No newline at end of file +PROJCS["WGS_1984_UTM_Zone_31N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",3.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] \ No newline at end of file diff --git a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.shp b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.shp index 2fa2141509228d3b8b5264bcfa54972dc596b9f8..d9fab7a5d702df8ed3709312b020bfbb5ca45bf1 100644 --- a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.shp +++ b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.shp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:42598cd07c71e621782e5cd553395593ff122ae2dd66b2b896bcddc82ca0f8a5 +oid sha256:b108225576ea00f28894bea65ceecd9cce452ddb6c151dbe8e9481845f1354eb size 692 diff --git a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.shx b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.shx index 3731bf0e31668dd79118e283514727861656b866..8dc7a1a87ababa4060391dbcd135c2d6034dad2b 100644 --- a/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.shx +++ b/Data/Baseline/OTB-Applications/Files/utTvVectorDataTransformFilter_Translation_rotation.shx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e688397829e2df5a7bed91de45a93a6f95fa3be4253b1c80540b40a60ffb3c4 +oid sha256:c2b9b6e1aee8db1672b0a037d04a23fd43f46a600a99c4142767a09491803651 size 132 diff --git a/Data/Baseline/OTB/Files/apTvHomologousPointsExtractionGeoBins.txt b/Data/Baseline/OTB/Files/apTvHomologousPointsExtractionGeoBins.txt index 7f0d109268b052ea55c148112301f61832c0d9e5..e6891e310086065504bab2b41326c1a8f8d9a3fa 100644 --- a/Data/Baseline/OTB/Files/apTvHomologousPointsExtractionGeoBins.txt +++ b/Data/Baseline/OTB/Files/apTvHomologousPointsExtractionGeoBins.txt @@ -124,7 +124,7 @@ 2048.228271484375 2207.046142578125 1.419642686844 43.609886169434 2044.248168945312 2211.722167968750 1.419517397881 43.609771728516 2013.301269531250 2213.351806640625 1.418538570404 43.609725952148 -2026.732299804688 2214.723876953125 1.418963670731 43.609695434570 +2026.732299804688 2214.723876953125 1.418963551521 43.609695434570 2072.679443359375 2271.293701171875 1.420424103737 43.608314514160 2068.220214843750 2271.551757812500 1.420282602310 43.608306884766 2022.040039062500 2274.913574218750 1.418822526932 43.608222961426 @@ -243,7 +243,7 @@ 2039.404907226562 2474.421386718750 1.419397354126 43.603378295898 2045.069946289062 2474.154052734375 1.419576406479 43.603382110596 2064.522705078125 2476.241455078125 1.420191884041 43.603332519531 -2042.500000000000 2477.500000000000 1.419495701790 43.603302001953 +2042.500000000000 2477.500000000000 1.419495582581 43.603302001953 2083.011474609375 2477.650634765625 1.420776367188 43.603298187256 2083.184814453125 2482.960937500000 1.420794606209 43.603172302246 2178.157714843750 2014.663696289062 1.423729658127 43.614547729492 @@ -276,7 +276,7 @@ 2197.770996093750 2041.287109375000 1.424353361130 43.613906860352 2207.354248046875 2042.595947265625 1.424656748772 43.613876342773 2165.751953125000 2043.925292968750 1.423340439796 43.613830566406 -2176.238281250000 2044.675781250000 1.423672437668 43.613819122314 +2176.238281250000 2044.675781250000 1.423672318459 43.613819122314 2162.559570312500 2045.927734375000 1.423239588737 43.613780975342 2180.227050781250 2045.198364257812 1.423798680305 43.613807678223 2168.579833984375 2047.652709960938 1.423430323601 43.613742828369 @@ -293,7 +293,7 @@ 2179.166015625000 2058.129394531250 1.423766613007 43.613491058350 2157.010742187500 2059.379882812500 1.423065662384 43.613456726074 2170.758544921875 2060.633544921875 1.423500776291 43.613426208496 -2205.504150390625 2060.900146484375 1.424600362778 43.613430023193 +2205.504150390625 2060.900146484375 1.424600243568 43.613430023193 2183.301025390625 2062.900634765625 1.423897981644 43.613380432129 2189.843750000000 2062.955078125000 1.424105048180 43.613380432129 2213.074462890625 2062.842529296875 1.424839973450 43.613384246826 @@ -403,7 +403,7 @@ 2188.500000000000 2308.500000000000 1.424091696739 43.607421875000 2162.648437500000 2309.036865234375 1.423274040222 43.607402801514 2185.337402343750 2309.660400390625 1.423991799355 43.607395172119 -2154.638916015625 2310.226806640625 1.423020958900 43.607372283936 +2154.638916015625 2310.226806640625 1.423020839691 43.607372283936 2161.173583984375 2311.442871093750 1.423227787018 43.607345581055 2158.500000000000 2311.500000000000 1.423143148422 43.607345581055 2153.823730468750 2312.165527343750 1.422995328903 43.607326507568 @@ -498,7 +498,7 @@ 2293.594238281250 2018.725463867188 1.427382707596 43.614463806152 2322.712646484375 2022.664306640625 1.428304553032 43.614372253418 2307.556884765625 2025.567016601562 1.427825212479 43.614295959473 -2319.582275390625 2025.710571289062 1.428205847740 43.614299774170 +2319.582275390625 2025.710571289062 1.428205728531 43.614299774170 2335.151123046875 2025.703247070312 1.428698301315 43.614295959473 2282.782470703125 2027.103149414062 1.427041411400 43.614253997803 2325.271484375000 2029.104003906250 1.428386211395 43.614215850830 @@ -531,7 +531,7 @@ 2337.793701171875 2066.861572265625 1.428786516190 43.613300323486 2274.392578125000 2067.227050781250 1.426780819893 43.613285064697 2303.735595703125 2069.161865234375 1.427709221840 43.613239288330 -2286.241210937500 2070.923339843750 1.427155971527 43.613197326660 +2286.241210937500 2070.923339843750 1.427155852318 43.613197326660 2330.604980468750 2070.536865234375 1.428559422493 43.613208770752 2275.756835937500 2073.452880859375 1.426824569702 43.613136291504 2306.877685546875 2075.271240234375 1.427809238434 43.613090515137 @@ -638,7 +638,7 @@ 2333.028808593750 2316.598632812500 1.428663969040 43.607242584229 2293.766113281250 2317.523681640625 1.427422285080 43.607219696045 2288.115478515625 2320.186279296875 1.427243947983 43.607154846191 -2295.912109375000 2323.376220703125 1.427490949631 43.607078552246 +2295.912109375000 2323.376220703125 1.427490830421 43.607078552246 2310.004882812500 2324.773437500000 1.427936792374 43.607048034668 2321.083007812500 2324.096923828125 1.428287148476 43.607063293457 2276.504150390625 2326.402099609375 1.426877021790 43.607002258301 @@ -651,7 +651,7 @@ 2327.906250000000 2332.923583984375 1.428503990173 43.606853485107 2291.397460937500 2334.210693359375 1.427349328995 43.606815338135 2293.721679687500 2338.765625000000 1.427423357964 43.606704711914 -2339.874267578125 2339.271484375000 1.428883314133 43.606704711914 +2339.874267578125 2339.271484375000 1.428883194923 43.606704711914 2310.500000000000 2395.500000000000 1.427960753441 43.605331420898 2308.561279296875 2398.573242187500 1.427899837494 43.605258941650 2300.614257812500 2399.192871093750 1.427648425102 43.605243682861 @@ -700,14 +700,14 @@ 2330.500000000000 2455.500000000000 1.428599953651 43.603858947754 2278.506103515625 2457.698730468750 1.426956057549 43.603797912598 2298.527343750000 2462.762207031250 1.427589654922 43.603668212891 -2317.743164062500 2465.254882812500 1.428197622299 43.603607177734 +2317.743164062500 2465.254882812500 1.428197503090 43.603607177734 2337.260253906250 2465.493896484375 1.428814768791 43.603603363037 2286.646972656250 2471.717773437500 1.427214860916 43.603439331055 2339.721191406250 2472.238281250000 1.428893208504 43.603431701660 2296.351318359375 2474.377197265625 1.427521944046 43.603370666504 2325.683593750000 2474.375976562500 1.428449630737 43.603374481201 2272.243408203125 2475.440429687500 1.426759600639 43.603343963623 -2310.970703125000 2475.608642578125 1.427984476089 43.603343963623 +2310.970703125000 2475.608642578125 1.427984356880 43.603343963623 2331.017089843750 2477.857177734375 1.428619027138 43.603290557861 2320.421386718750 2478.561279296875 1.428283810616 43.603271484375 2341.008056640625 2478.269775390625 1.428934454918 43.603279113770 @@ -853,7 +853,7 @@ 2450.574218750000 2284.466064453125 1.432377934456 43.608020782471 2433.599365234375 2285.465087890625 1.431841135025 43.607990264893 2400.757324218750 2286.261962890625 1.430802464485 43.607975006104 -2408.731933593750 2286.493164062500 1.431054830551 43.607967376709 +2408.731933593750 2286.493164062500 1.431054711342 43.607967376709 2450.500000000000 2287.500000000000 1.432376027107 43.607948303223 2459.329589843750 2289.986328125000 1.432655572891 43.607887268066 2433.046630859375 2290.675537109375 1.431824207306 43.607864379883 @@ -888,18 +888,18 @@ 2422.954833984375 2314.871093750000 1.431507825851 43.607280731201 2429.220458984375 2314.904541015625 1.431705951691 43.607280731201 2436.500000000000 2314.500000000000 1.431936144829 43.607292175293 -2446.352539062500 2315.927490234375 1.432247996330 43.607257843018 +2446.352539062500 2315.927490234375 1.432247877121 43.607257843018 2433.684082031250 2317.641357421875 1.431847453117 43.607215881348 2478.212890625000 2317.534423828125 1.433257937431 43.607227325439 2465.732421875000 2318.323486328125 1.432861208916 43.607204437256 2419.500000000000 2321.500000000000 1.431399345398 43.607124328613 2415.780273437500 2322.814208984375 1.431281805038 43.607089996338 -2450.800048828125 2322.106689453125 1.432389378548 43.607109069824 +2450.800048828125 2322.106689453125 1.432389259338 43.607109069824 2431.886230468750 2323.784423828125 1.431791305542 43.607067108154 2421.631103515625 2324.301269531250 1.431467056274 43.607055664062 2466.618896484375 2324.223144531250 1.432889938354 43.607063293457 2409.415039062500 2325.359375000000 1.431080818176 43.607032775879 -2428.961425781250 2325.462890625000 1.431699037552 43.607025146484 +2428.961425781250 2325.462890625000 1.431698918343 43.607025146484 2483.942871093750 2325.331787109375 1.433431267738 43.607040405273 2427.012207031250 2326.107910156250 1.431637406349 43.607009887695 2438.218750000000 2326.528564453125 1.431991934776 43.607002258301 @@ -940,14 +940,14 @@ 2444.392333984375 2417.815185546875 1.432197451591 43.604797363281 2404.082519531250 2418.214355468750 1.430922746658 43.604778289795 2476.500000000000 2420.500000000000 1.433213114738 43.604732513428 -2474.789062500000 2421.788085937500 1.433159232140 43.604701995850 +2474.789062500000 2421.788085937500 1.433159112930 43.604701995850 2435.394042968750 2422.404296875000 1.431913375854 43.604682922363 2471.769531250000 2422.509521484375 1.433063626289 43.604682922363 2460.496582031250 2423.639892578125 1.432707428932 43.604656219482 2475.412597656250 2424.590087890625 1.433179140091 43.604633331299 2404.419677734375 2425.259033203125 1.430934190750 43.604606628418 2445.429931640625 2426.730224609375 1.432231307030 43.604579925537 -2398.413330078125 2427.511474609375 1.430744528770 43.604549407959 +2398.413330078125 2427.511474609375 1.430744409561 43.604549407959 2421.534912109375 2427.873535156250 1.431475639343 43.604545593262 2469.556640625000 2427.768310546875 1.432994365692 43.604553222656 2441.001464843750 2430.184326171875 1.432091593742 43.604492187500 diff --git a/Data/Baseline/OTB/Files/apTvHomologousPointsExtractionGeoBinsAnisotropic.txt b/Data/Baseline/OTB/Files/apTvHomologousPointsExtractionGeoBinsAnisotropic.txt index 9b45da3ca59463c8f3dc4f6bb81bf95726b3f74f..238d48870e01352a24580c99482787a4b975a4cb 100644 --- a/Data/Baseline/OTB/Files/apTvHomologousPointsExtractionGeoBinsAnisotropic.txt +++ b/Data/Baseline/OTB/Files/apTvHomologousPointsExtractionGeoBinsAnisotropic.txt @@ -86,7 +86,7 @@ 2054.955810546875 2112.151367187500 1.419843196869 43.612167358398 2077.500000000000 2113.500000000000 1.420556664467 43.612136840820 2075.399658203125 2115.218017578125 1.420490384102 43.612094879150 -2047.833984375000 2118.247802734375 1.419618725777 43.612018585205 +2047.833984375000 2118.247802734375 1.419618606567 43.612018585205 2074.415039062500 2119.332275390625 1.420459747314 43.611995697021 2050.564941406250 2121.598876953125 1.419705510139 43.611938476562 2067.573242187500 2121.572265625000 1.420243620872 43.611942291260 @@ -106,7 +106,7 @@ 2084.273437500000 2134.147216796875 1.420773506165 43.611640930176 2019.522094726562 2137.045410156250 1.418725490570 43.611568450928 2061.092773437500 2137.289062500000 1.420040607452 43.611564636230 -2068.564941406250 2181.307373046875 1.420282244682 43.610507965088 +2068.564941406250 2181.307373046875 1.420282125473 43.610507965088 2072.220703125000 2181.862548828125 1.420398354530 43.610496520996 2020.803100585938 2183.804199218750 1.418772459030 43.610446929932 2043.500000000000 2183.500000000000 1.419490218163 43.610458374023 @@ -123,7 +123,7 @@ 2048.228271484375 2207.046142578125 1.419642686844 43.609886169434 2044.248168945312 2211.722167968750 1.419517397881 43.609771728516 2013.301269531250 2213.351806640625 1.418538570404 43.609725952148 -2026.732299804688 2214.723876953125 1.418963670731 43.609695434570 +2026.732299804688 2214.723876953125 1.418963551521 43.609695434570 2075.136230468750 2217.776855468750 1.420495152473 43.609626770020 2016.575073242188 2218.036376953125 1.418642759323 43.609611511230 2021.290161132812 2218.514404296875 1.418791890144 43.609600067139 @@ -227,7 +227,7 @@ 2033.059448242188 2364.660400390625 1.419182538986 43.606044769287 2046.597534179688 2364.525878906250 1.419610738754 43.606048583984 2029.307373046875 2365.591308593750 1.419063925743 43.606018066406 -2070.900146484375 2367.098876953125 1.420379638672 43.605987548828 +2070.900146484375 2367.098876953125 1.420379519463 43.605987548828 2059.539550781250 2369.349121093750 1.420020580292 43.605934143066 2047.548217773438 2370.924072265625 1.419641613960 43.605892181396 2080.313720703125 2370.790771484375 1.420677661896 43.605895996094 @@ -329,7 +329,7 @@ 2197.770996093750 2041.287109375000 1.424353361130 43.613906860352 2207.354248046875 2042.595947265625 1.424656748772 43.613876342773 2165.751953125000 2043.925292968750 1.423340439796 43.613830566406 -2176.238281250000 2044.675781250000 1.423672437668 43.613819122314 +2176.238281250000 2044.675781250000 1.423672318459 43.613819122314 2162.559570312500 2045.927734375000 1.423239588737 43.613780975342 2180.227050781250 2045.198364257812 1.423798680305 43.613807678223 2168.579833984375 2047.652709960938 1.423430323601 43.613742828369 @@ -346,7 +346,7 @@ 2179.166015625000 2058.129394531250 1.423766613007 43.613491058350 2157.010742187500 2059.379882812500 1.423065662384 43.613456726074 2170.758544921875 2060.633544921875 1.423500776291 43.613426208496 -2205.504150390625 2060.900146484375 1.424600362778 43.613430023193 +2205.504150390625 2060.900146484375 1.424600243568 43.613430023193 2183.301025390625 2062.900634765625 1.423897981644 43.613380432129 2189.843750000000 2062.955078125000 1.424105048180 43.613380432129 2213.074462890625 2062.842529296875 1.424839973450 43.613384246826 @@ -372,15 +372,15 @@ 2180.387207031250 2087.253906250000 1.423808693886 43.612785339355 2176.165039062500 2088.169921875000 1.423675179482 43.612762451172 2172.200683593750 2090.235351562500 1.423549890518 43.612709045410 -2196.610351562500 2090.838134765625 1.424322485924 43.612705230713 +2196.610351562500 2090.838134765625 1.424322366714 43.612705230713 2182.489746093750 2092.467773437500 1.423875808716 43.612663269043 2166.658691406250 2093.679443359375 1.423374891281 43.612625122070 -2177.673095703125 2093.742919921875 1.423723578453 43.612628936768 +2177.673095703125 2093.742919921875 1.423723459244 43.612628936768 2213.331787109375 2096.187988281250 1.424852013588 43.612575531006 2199.294921875000 2098.724853515625 1.424408316612 43.612514495850 2156.613525390625 2099.088867187500 1.423057794571 43.612491607666 2182.426269531250 2099.590820312500 1.423874616623 43.612487792969 -2168.553710937500 2103.366455078125 1.423436164856 43.612392425537 +2168.553710937500 2103.366455078125 1.423436045647 43.612392425537 2174.862548828125 2103.654541015625 1.423635840416 43.612388610840 2214.853271484375 2103.675781250000 1.424901008606 43.612392425537 2155.864501953125 2105.382080078125 1.423034906387 43.612342834473 @@ -407,7 +407,7 @@ 2187.611328125000 2133.054443359375 1.424042820930 43.611686706543 2177.667968750000 2135.388427734375 1.423728585243 43.611629486084 2158.670410156250 2138.076660156250 1.423127770424 43.611560821533 -2187.762451171875 2138.567871093750 1.424048304558 43.611553192139 +2187.762451171875 2138.567871093750 1.424048185349 43.611553192139 2189.141357421875 2184.603271484375 1.424097180367 43.610431671143 2172.426025390625 2187.848632812500 1.423568606377 43.610347747803 2211.844726562500 2188.064453125000 1.424815654755 43.610343933105 @@ -484,7 +484,7 @@ 2184.728759765625 2295.326904296875 1.423971056938 43.607749938965 2208.297607421875 2297.159423828125 1.424716711044 43.607704162598 2169.776611328125 2341.468505859375 1.423503518105 43.606616973877 -2204.219970703125 2343.579833984375 1.424593091011 43.606563568115 +2204.219970703125 2343.579833984375 1.424592971802 43.606563568115 2185.026123046875 2344.719726562500 1.423986196518 43.606536865234 2204.645263671875 2348.602050781250 1.424607157707 43.606441497803 2184.429199218750 2349.915527343750 1.423967838287 43.606410980225 @@ -559,7 +559,7 @@ 2293.594238281250 2018.725463867188 1.427382707596 43.614463806152 2322.712646484375 2022.664306640625 1.428304553032 43.614372253418 2307.556884765625 2025.567016601562 1.427825212479 43.614295959473 -2319.582275390625 2025.710571289062 1.428205847740 43.614299774170 +2319.582275390625 2025.710571289062 1.428205728531 43.614299774170 2335.151123046875 2025.703247070312 1.428698301315 43.614295959473 2282.782470703125 2027.103149414062 1.427041411400 43.614253997803 2325.271484375000 2029.104003906250 1.428386211395 43.614215850830 @@ -592,7 +592,7 @@ 2337.793701171875 2066.861572265625 1.428786516190 43.613300323486 2274.392578125000 2067.227050781250 1.426780819893 43.613285064697 2303.735595703125 2069.161865234375 1.427709221840 43.613239288330 -2286.241210937500 2070.923339843750 1.427155971527 43.613197326660 +2286.241210937500 2070.923339843750 1.427155852318 43.613197326660 2330.604980468750 2070.536865234375 1.428559422493 43.613208770752 2275.756835937500 2073.452880859375 1.426824569702 43.613136291504 2306.877685546875 2075.271240234375 1.427809238434 43.613090515137 @@ -717,7 +717,7 @@ 2300.255859375000 2269.798095703125 1.427621960640 43.608375549316 2276.597656250000 2271.632568359375 1.426873803139 43.608329772949 2327.989990234375 2271.719726562500 1.428499341011 43.608325958252 -2269.269775390625 2276.102294921875 1.426643967628 43.608222961426 +2269.269775390625 2276.102294921875 1.426643848419 43.608222961426 2299.541015625000 2276.791992187500 1.427600145340 43.608203887939 2328.963867187500 2276.464111328125 1.428530693054 43.608211517334 2336.500000000000 2277.500000000000 1.428769111633 43.608184814453 @@ -751,7 +751,7 @@ 2286.665039062500 2349.433105468750 1.427201509476 43.606445312500 2320.103759765625 2350.117187500000 1.428259253502 43.606437683105 2331.789794921875 2353.150146484375 1.428629159927 43.606365203857 -2285.103271484375 2356.800048828125 1.427152991295 43.606262207031 +2285.103271484375 2356.800048828125 1.427152872086 43.606262207031 2305.770996093750 2358.823486328125 1.427806854248 43.606220245361 2273.612548828125 2360.780761718750 1.426789879799 43.606163024902 2283.166015625000 2361.401855468750 1.427092194557 43.606151580811 @@ -1043,7 +1043,7 @@ 2450.574218750000 2284.466064453125 1.432377934456 43.608020782471 2433.599365234375 2285.465087890625 1.431841135025 43.607990264893 2400.757324218750 2286.261962890625 1.430802464485 43.607975006104 -2408.731933593750 2286.493164062500 1.431054830551 43.607967376709 +2408.731933593750 2286.493164062500 1.431054711342 43.607967376709 2450.500000000000 2287.500000000000 1.432376027107 43.607948303223 2459.329589843750 2289.986328125000 1.432655572891 43.607887268066 2433.046630859375 2290.675537109375 1.431824207306 43.607864379883 @@ -1142,14 +1142,14 @@ 2444.392333984375 2417.815185546875 1.432197451591 43.604797363281 2404.082519531250 2418.214355468750 1.430922746658 43.604778289795 2476.500000000000 2420.500000000000 1.433213114738 43.604732513428 -2474.789062500000 2421.788085937500 1.433159232140 43.604701995850 +2474.789062500000 2421.788085937500 1.433159112930 43.604701995850 2435.394042968750 2422.404296875000 1.431913375854 43.604682922363 2471.769531250000 2422.509521484375 1.433063626289 43.604682922363 2460.496582031250 2423.639892578125 1.432707428932 43.604656219482 2475.412597656250 2424.590087890625 1.433179140091 43.604633331299 2404.419677734375 2425.259033203125 1.430934190750 43.604606628418 2445.429931640625 2426.730224609375 1.432231307030 43.604579925537 -2398.413330078125 2427.511474609375 1.430744528770 43.604549407959 +2398.413330078125 2427.511474609375 1.430744409561 43.604549407959 2421.534912109375 2427.873535156250 1.431475639343 43.604545593262 2469.556640625000 2427.768310546875 1.432994365692 43.604553222656 2441.001464843750 2430.184326171875 1.432091593742 43.604492187500 diff --git a/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.dbf b/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.dbf index eded4e612fb493dd27374e400e415d23c48fe2cc..8bd80904b7701f5190ba486ea2328de6501318b8 100644 --- a/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.dbf +++ b/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.dbf @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3e2f875ec030b660881013b02b323ddbbdcf09b295c834b3db00acbc443f717e +oid sha256:41b407ac61bfc6bbe9cc30003daab13e39ba0a994e6ba88f544c07b0a41d5b12 size 78 diff --git a/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.prj b/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.prj index a30c00a55de19be195abf9e942f6cff93bf0a825..f45cbadf0074d8b7b2669559a93bc50bb95f82d4 100644 --- a/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.prj +++ b/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.prj @@ -1 +1 @@ -GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] \ No newline at end of file +GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] \ No newline at end of file diff --git a/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.shp b/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.shp index 09f82ed29167a10cee48eebe12aae7f5d8a098c8..e48430590fddc7e466affa01228060ea4a185dda 100644 --- a/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.shp +++ b/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.shp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd4e52b494e3c554e6db06130a01998f2a7b17ec66a121454ee85756013d3677 +oid sha256:cc0fed96c3b96e86fa50b8c7a83a6d88923a89e863d4b433c4315234f03701c3 size 236 diff --git a/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.shx b/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.shx index c95fcff4343febc60e4c0dfa54cfa11bea7ff5f3..597f3b678de09f980bd53810deb4b394210e93f7 100644 --- a/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.shx +++ b/Data/Baseline/OTB/Files/apTvPrImageEnvelopeTest.shx @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ef7ef9215cecbb1c686cfec3a8ebc4a728a10dd51ee5b49469810cca432f2599 +oid sha256:53e34f332bd6e4305c5a69fffd3bc26cf640e921133ec9e2c5d98f4f5d0e637b size 108 diff --git a/Data/Baseline/OTB/Files/ioOtbVectorImageTestCOSMOSKYMED.txt b/Data/Baseline/OTB/Files/ioOtbVectorImageTestCOSMOSKYMED.txt index 4a92f40dd81e2a3948ed5a96c3f40f8b004e74b2..e3665544fb8d7aadb8f7a59ffcd216a5d7fb1474 100644 --- a/Data/Baseline/OTB/Files/ioOtbVectorImageTestCOSMOSKYMED.txt +++ b/Data/Baseline/OTB/Files/ioOtbVectorImageTestCOSMOSKYMED.txt @@ -1,27 +1,7 @@ ------ IMAGE -------- Spacing [1, 1] Origin [0.5, 0.5] -Projection REF PROJCS["Transverse_Mercator", - GEOGCS["WGS 84", - DATUM["WGS_1984", - SPHEROID["WGS 84",6378137,298.257223563, - AUTHORITY["EPSG","7030"]], - AUTHORITY["EPSG","6326"]], - PRIMEM["Greenwich",0, - AUTHORITY["EPSG","8901"]], - UNIT["degree",0.0174532925199433, - AUTHORITY["EPSG","9122"]], - AUTHORITY["EPSG","4326"]], - PROJECTION["Transverse_Mercator"], - PARAMETER["latitude_of_origin",0], - PARAMETER["central_meridian",3], - PARAMETER["scale_factor",0.9996], - PARAMETER["false_easting",500000], - PARAMETER["false_northing",0], - UNIT["metre",1, - AUTHORITY["EPSG","9001"]], - AXIS["Easting",EAST], - AXIS["Northing",NORTH]] +Projection REF PROJCS["Transverse_Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",3],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH]] GCP Projection GCP Count 0 Geo Transform diff --git a/Data/Baseline/OTB/Files/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt b/Data/Baseline/OTB/Files/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt index 7761f86a7b7a63af355160e4e1e01d307aa8fa85..bef7d330228075214cc9660493b3c27b572df4f1 100644 --- a/Data/Baseline/OTB/Files/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt +++ b/Data/Baseline/OTB/Files/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt @@ -1,130 +1,2 @@ - Ossim Keyword list: - adjustment_0.adj_param_0.center: 0 -adjustment_0.adj_param_0.description: intrack_offset -adjustment_0.adj_param_0.lock_flag: 0 -adjustment_0.adj_param_0.parameter: 0 -adjustment_0.adj_param_0.sigma: 50 -adjustment_0.adj_param_0.units: pixel -adjustment_0.adj_param_1.center: 0 -adjustment_0.adj_param_1.description: crtrack_offset -adjustment_0.adj_param_1.lock_flag: 0 -adjustment_0.adj_param_1.parameter: 0 -adjustment_0.adj_param_1.sigma: 50 -adjustment_0.adj_param_1.units: pixel -adjustment_0.adj_param_2.center: 0 -adjustment_0.adj_param_2.description: intrack_scale -adjustment_0.adj_param_2.lock_flag: 0 -adjustment_0.adj_param_2.parameter: 0 -adjustment_0.adj_param_2.sigma: 50 -adjustment_0.adj_param_2.units: unknown -adjustment_0.adj_param_3.center: 0 -adjustment_0.adj_param_3.description: crtrack_scale -adjustment_0.adj_param_3.lock_flag: 0 -adjustment_0.adj_param_3.parameter: 0 -adjustment_0.adj_param_3.sigma: 50 -adjustment_0.adj_param_3.units: unknown -adjustment_0.adj_param_4.center: 0 -adjustment_0.adj_param_4.description: map_rotation -adjustment_0.adj_param_4.lock_flag: 0 -adjustment_0.adj_param_4.parameter: 0 -adjustment_0.adj_param_4.sigma: 0.1 -adjustment_0.adj_param_4.units: degrees -adjustment_0.description: Initial adjustment -adjustment_0.dirty_flag: 0 -adjustment_0.number_of_params: 5 -current_adjustment: 0 -height_off: 0 -height_scale: 4.5035996273705e+15 -lat_off: 43.608891 -lat_scale: 1 -line_den_coeff_0: 1 -line_den_coeff_1: 0.116647929191405 -line_den_coeff_10: 0 -line_den_coeff_11: 4.24205291306071e-06 -line_den_coeff_12: -1.22170433593066e-05 -line_den_coeff_13: 0 -line_den_coeff_14: -1.62292152211888e-05 -line_den_coeff_15: -1.11751035274519e-05 -line_den_coeff_16: 0 -line_den_coeff_17: 0 -line_den_coeff_18: 0 -line_den_coeff_19: 0 -line_den_coeff_2: -0.795796952135346 -line_den_coeff_3: 0 -line_den_coeff_4: -0.00176250458824308 -line_den_coeff_5: 0 -line_den_coeff_6: 0 -line_den_coeff_7: -0.69205662487881 -line_den_coeff_8: -0.725158534735126 -line_den_coeff_9: 0 -line_num_coeff_0: 0.00176507025129761 -line_num_coeff_1: 0.469825903760047 -line_num_coeff_10: 0 -line_num_coeff_11: 4.1371912315397e-05 -line_num_coeff_12: -2.66115593034605e-05 -line_num_coeff_13: 0 -line_num_coeff_14: -0.00378322572708931 -line_num_coeff_15: -0.00397219871280679 -line_num_coeff_16: 0 -line_num_coeff_17: 0 -line_num_coeff_18: 0 -line_num_coeff_19: 0 -line_num_coeff_2: -182.988749105524 -line_num_coeff_3: 1.00711799423683e-14 -line_num_coeff_4: 0.000167599353017481 -line_num_coeff_5: 4.23534328933673e-23 -line_num_coeff_6: 0 -line_num_coeff_7: -0.000132255684215101 -line_num_coeff_8: -0.00299521983182487 -line_num_coeff_9: 0 -line_off: 2224.5 -line_scale: 225.5 -long_off: 1.4252414 -long_scale: 1 -number_of_adjustments: 1 -polynomial_format: B -samp_den_coeff_0: 1 -samp_den_coeff_1: -0.0140652497583194 -samp_den_coeff_10: 0 -samp_den_coeff_11: -2.11567008497461e-07 -samp_den_coeff_12: -2.52699758468156e-06 -samp_den_coeff_13: 0 -samp_den_coeff_14: 1.28729228360665e-06 -samp_den_coeff_15: 7.0821267053196e-06 -samp_den_coeff_16: 0 -samp_den_coeff_17: 0 -samp_den_coeff_18: 0 -samp_den_coeff_19: 0 -samp_den_coeff_2: 0.056111938809245 -samp_den_coeff_3: 0 -samp_den_coeff_4: -0.00165427540398437 -samp_den_coeff_5: 0 -samp_den_coeff_6: 0 -samp_den_coeff_7: -0.720295418717795 -samp_den_coeff_8: -0.238046475331491 -samp_den_coeff_9: 0 -samp_num_coeff_0: -4.03022891014623e-05 -samp_num_coeff_1: 140.122696755472 -samp_num_coeff_10: 0 -samp_num_coeff_11: 0.00514045286544423 -samp_num_coeff_12: 0.00169871244049508 -samp_num_coeff_13: 0 -samp_num_coeff_14: 3.04771969411287e-06 -samp_num_coeff_15: 3.0597489842213e-05 -samp_num_coeff_16: 0 -samp_num_coeff_17: 0 -samp_num_coeff_18: 0 -samp_num_coeff_19: 0 -samp_num_coeff_2: 0.720548641464637 -samp_num_coeff_3: 1.72815049746881e-14 -samp_num_coeff_4: -0.000307017880169014 -samp_num_coeff_5: -1.67843825237436e-25 -samp_num_coeff_6: 0 -samp_num_coeff_7: 7.0629169037717e-05 -samp_num_coeff_8: 0.000393857191344697 -samp_num_coeff_9: 0 -samp_off: 2224.5 -samp_scale: 225.5 -type: ossimRpcProjection - +{"LineOffset": "2224.5", "SampleOffset": "2224.5", "LatOffset": "43.6089", "LonOffset": "1.42524", "HeightOffset": "0", "LineScale": "225.5", "SampleScale": "225.5", "LatScale": "1", "LonScale": "1", "HeightScale": "1", "LineNum": [ "0.00176507", "0.469826", "-182.989", "-3.97557e-14", "0.000167599", "-4.11403e-23", "4.64211e-36", "-0.000132256", "-0.00299522", "0", "0", "4.13719e-05", "-2.66116e-05", "0", "-0.00378323", "-0.0039722", "0", "0", "0", "0", ], "LineDen": [ "1", "0.116648", "-0.795797", "0", "-0.0017625", "0", "0", "-0.692057", "-0.725159", "0", "0", "4.24205e-06", "-1.2217e-05", "0", "-1.62292e-05", "-1.11751e-05", "0", "0", "0", "0", ], "SampleNum": [ "-4.03023e-05", "140.123", "0.720549", "-3.96237e-14", "-0.000307018", "-6.10744e-25", "3.08505e-39", "7.06292e-05", "0.000393857", "0", "0", "0.00514045", "0.00169871", "0", "3.04772e-06", "3.05975e-05", "0", "0", "0", "0", ], "SampleDen": [ "1", "-0.0140652", "0.0561119", "0", "-0.00165428", "0", "0", "-0.720295", "-0.238046", "0", "0", "-2.11567e-07", "-2.527e-06", "0", "1.28729e-06", "7.08213e-06", "0", "0", "0", "0", ], } Residual ground error: 1.2432282311 diff --git a/Data/Baseline/OTB/Files/prTvImageToGenericRSOutputParametersOutput.txt b/Data/Baseline/OTB/Files/prTvImageToGenericRSOutputParametersOutput.txt index dd23f6ab41d09dbc6e877f6c9547bf493e150717..2f4738c9e697933f3338787f7ffc2781fc31270f 100644 --- a/Data/Baseline/OTB/Files/prTvImageToGenericRSOutputParametersOutput.txt +++ b/Data/Baseline/OTB/Files/prTvImageToGenericRSOutputParametersOutput.txt @@ -5,7 +5,7 @@ Output Size : [27551, 29108] Output Parameters for SRID : 32631 (UTM 31 N) Output Origin : [367031, 4.83474e+06] -Output Spacing : [0.641015, -0.671574] +Output Spacing : [0.641015, -0.671575] Output Size : [27919, 29498] Output Parameters for SRS : Lambert II Etendu diff --git a/Data/Baseline/OTB/Files/prTvTestCreateInverseForwardSensorModel_Cevennes.txt b/Data/Baseline/OTB/Files/prTvTestCreateInverseForwardSensorModel_Cevennes.txt deleted file mode 100644 index f6912a7e0190d8c2db917952b9482ae7ed21c3a4..0000000000000000000000000000000000000000 --- a/Data/Baseline/OTB/Files/prTvTestCreateInverseForwardSensorModel_Cevennes.txt +++ /dev/null @@ -1,4 +0,0 @@ -Testing geopoint: [3.740934, 44.107956] - -Testing InverseSensorModel: [3.740934, 44.107956] -> [14190.558, 13591.703] -Testing ForwardSensorModel: [14190.558, 13591.703] -> [3.7409338, 44.107956] diff --git a/Data/Baseline/OTB/Files/prTvTestCreateInverseForwardSensorModel_DEM.txt b/Data/Baseline/OTB/Files/prTvTestCreateInverseForwardSensorModel_DEM.txt deleted file mode 100644 index aea250dfdc1fc9d554d7c19154f530cebf2b5d70..0000000000000000000000000000000000000000 --- a/Data/Baseline/OTB/Files/prTvTestCreateInverseForwardSensorModel_DEM.txt +++ /dev/null @@ -1,4 +0,0 @@ -Testing geopoint: [1.4434869, 43.604688] - -Testing InverseSensorModel: [1.4434869, 43.604688] -> [11234.024, 8199.2289] -Testing ForwardSensorModel: [11234.024, 8199.2289] -> [1.4434838, 43.604235] diff --git a/Data/Baseline/OTB/Files/prTvTestCreateInverseForwardSensorModel_Toulouse.txt b/Data/Baseline/OTB/Files/prTvTestCreateInverseForwardSensorModel_Toulouse.txt deleted file mode 100644 index be467ecf20fe82253d00ccfaeafc8f8b55951436..0000000000000000000000000000000000000000 --- a/Data/Baseline/OTB/Files/prTvTestCreateInverseForwardSensorModel_Toulouse.txt +++ /dev/null @@ -1,4 +0,0 @@ -Testing geopoint: [1.4434869, 43.604688] - -Testing InverseSensorModel: [1.4434869, 43.604688] -> [11234.662, 8124.3911] -Testing ForwardSensorModel: [11234.662, 8124.3911] -> [1.4434869, 43.604688] diff --git a/Data/Baseline/OTB/Images/apTvDmStereoRectificationGridGeneratorLeftTest.tif b/Data/Baseline/OTB/Images/apTvDmStereoRectificationGridGeneratorLeftTest.tif index 32b3f4af0de26ebe9aad491483b38454804436af..429498528cf79651436b748911f4db890ce0bcd3 100644 --- a/Data/Baseline/OTB/Images/apTvDmStereoRectificationGridGeneratorLeftTest.tif +++ b/Data/Baseline/OTB/Images/apTvDmStereoRectificationGridGeneratorLeftTest.tif @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83a8f4e1ed9033dad4b86d2407917141bcda17d720450ad28527a6e174e75eb5 -size 12477 +oid sha256:b7fdaa5a947cb5ecc1b0ecfcc313a0d2aea6536702e9763e74059ebcf277cd61 +size 12601 diff --git a/Data/Baseline/OTB/Images/apTvDmStereoRectificationGridGeneratorRightTest.tif b/Data/Baseline/OTB/Images/apTvDmStereoRectificationGridGeneratorRightTest.tif index 97e4a05eccef7311136a4424189c10e8bfc1ca80..0843da6db822b0d574a7042306a4ce322d49d89e 100644 --- a/Data/Baseline/OTB/Images/apTvDmStereoRectificationGridGeneratorRightTest.tif +++ b/Data/Baseline/OTB/Images/apTvDmStereoRectificationGridGeneratorRightTest.tif @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7c66e51f14067a54fdf16da57f6a54f01bf3f44e045d62fe051e47c7053c0d05 -size 13548 +oid sha256:64d89f3e1612ce252a8ce9cf86f68f64c90c5f4ea8775050af7560fb6727a557 +size 13672 diff --git a/Data/Baseline/OTB/Images/dmTvMultiDisparityMapTo3DFilterOutput.tif b/Data/Baseline/OTB/Images/dmTvMultiDisparityMapTo3DFilterOutput.tif index 4caa4d386abccc9dffceb58b4f1e111ada59a01f..8b2cbc42e726541921f0be7c159968afdc66c7cc 100644 --- a/Data/Baseline/OTB/Images/dmTvMultiDisparityMapTo3DFilterOutput.tif +++ b/Data/Baseline/OTB/Images/dmTvMultiDisparityMapTo3DFilterOutput.tif @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e124b9735c81cae6100a96ebc3558d72af86787b7578061f0754e73022fd185e -size 4934748 +oid sha256:cb16856aeef1504e4e3fe918493cebe126a568929793a5050ca83baf04bf6ffb +size 4935793 diff --git a/Data/Baseline/OTB/Images/dmTvMultiDisparityMapTo3DFilterResidue.tif b/Data/Baseline/OTB/Images/dmTvMultiDisparityMapTo3DFilterResidue.tif index be41c8abae0620d66252178f95f55ae398ec6c8f..6dcdaec2a74eefe404ad65af333b36595d12ad13 100644 --- a/Data/Baseline/OTB/Images/dmTvMultiDisparityMapTo3DFilterResidue.tif +++ b/Data/Baseline/OTB/Images/dmTvMultiDisparityMapTo3DFilterResidue.tif @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:10f008b39c3818506d0657b4122c6482d0a33f26220bb2ca10b53a20c2764e09 -size 538350 +oid sha256:020ccfa11ac2411d3cd011854d91121174790a0e9a3ee1565b77003e6cdfb8f3 +size 538663 diff --git a/Data/Baseline/OTB/Images/feTvStereorectificationDeformationFieldSourceOutput1.tif b/Data/Baseline/OTB/Images/feTvStereorectificationDeformationFieldSourceOutput1.tif index d29af818141905a2b65456a73ff7c2fea3240c94..afcc8f56368ba4700f00d68d0341f9267a98e980 100644 --- a/Data/Baseline/OTB/Images/feTvStereorectificationDeformationFieldSourceOutput1.tif +++ b/Data/Baseline/OTB/Images/feTvStereorectificationDeformationFieldSourceOutput1.tif @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d722d165566cbd25c07feb2956648ea5a07a3e05647ac4d095c7405b418b8ed -size 76111 +oid sha256:e75b43f8e97f52c4cb2787ded98b9a93ac5281e2a0cccb0902e65a5d49639c82 +size 76209 diff --git a/Data/Baseline/OTB/Images/feTvStereorectificationDeformationFieldSourceOutput2.tif b/Data/Baseline/OTB/Images/feTvStereorectificationDeformationFieldSourceOutput2.tif index 8ad419ec4c6677d219f297a15fcd9f91f2fb4735..2a58141838f6d265c24fb2b3beea42678678f48f 100644 --- a/Data/Baseline/OTB/Images/feTvStereorectificationDeformationFieldSourceOutput2.tif +++ b/Data/Baseline/OTB/Images/feTvStereorectificationDeformationFieldSourceOutput2.tif @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d6a180ea69eaba84a82e22f217bea809afc4bf0d9b75d7c2b920da5b1e2566b7 -size 76877 +oid sha256:4a2350ccf2aeccc7c555a7e3ecac33c48dec903b1684106abe52a982d80d2eb8 +size 76921 diff --git a/Data/Baseline/OTB/Images/ioImageFileReaderExtendedFileName_Skipgeom_pr.txt b/Data/Baseline/OTB/Images/ioImageFileReaderExtendedFileName_Skipgeom_pr.txt index d5e66f05569c8bcc212b6e35a17371d9727b62fb..cfc8497c9827c19ad484ebb3b76c220762fb754a 100644 --- a/Data/Baseline/OTB/Images/ioImageFileReaderExtendedFileName_Skipgeom_pr.txt +++ b/Data/Baseline/OTB/Images/ioImageFileReaderExtendedFileName_Skipgeom_pr.txt @@ -1,10 +1,3 @@ -ProjRef: GEOGCS["WGS 84", - DATUM["WGS_1984", - SPHEROID["WGS 84",6378137,298.257223563, - AUTHORITY["EPSG","7030"]], - AUTHORITY["EPSG","6326"]], - PRIMEM["Greenwich",0], - UNIT["degree",0.0174532925199433], - AUTHORITY["EPSG","4326"]] +ProjRef: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]] Origin: [1943.5, 2364.5] Spacing: [1, 1] diff --git a/Data/Input/QB/qb-1.gcp2 b/Data/Input/QB/qb-1.gcp2 new file mode 100644 index 0000000000000000000000000000000000000000..a8346c428d53964b7f7a7f9ebc623fadac036767 --- /dev/null +++ b/Data/Input/QB/qb-1.gcp2 @@ -0,0 +1,37 @@ +# column row longitude latitude elevation +10 10 1.354182467536249 43.65450925300863 242.0 +60 10 1.3545796502142065 43.65451030207909 242.0 +110 10 1.3549768326315368 43.65451134928986 242.0 +160 10 1.355374014788645 43.65451239464097 242.0 +210 10 1.3557711966859367 43.65451343813239 242.0 +260 10 1.3561683783238172 43.654514479764146 242.0 +10 60 1.3541846522202792 43.65420477196834 242.0 +60 60 1.354581827868692 43.65420582080392 242.0 +110 60 1.3549790032579432 43.65420686777995 242.0 +160 60 1.355376178388438 43.65420791289645 242.0 +210 60 1.3557733532605816 43.65420895615342 242.0 +260 60 1.3561705278747793 43.65420999755086 242.0 +10 110 1.3541868403100408 43.65390030157949 242.0 +60 110 1.3545840089299739 43.65390135018054 242.0 +110 110 1.3549811772922107 43.6539023969222 242.0 +160 110 1.3553783453971564 43.65390344180446 242.0 +210 110 1.3557755132452167 43.653904484827336 242.0 +260 110 1.3561726808367964 43.65390552599083 242.0 +10 160 1.354189031803238 43.65359584180479 242.0 +60 160 1.354586193395755 43.65359689017168 242.0 +110 160 1.3549833547320413 43.65359793667932 242.0 +160 160 1.355380515812502 43.65359898132771 242.0 +210 160 1.3557776766375425 43.65360002411686 242.0 +260 160 1.356174837207568 43.653601065046765 242.0 +10 210 1.3541912266975757 43.65329139260708 242.0 +60 210 1.3545883812637398 43.65329244074018 242.0 +110 210 1.3549855355751386 43.65329348701417 242.0 +160 210 1.3553826896321772 43.653294531429054 242.0 +210 210 1.3557798434352613 43.653295573984835 242.0 +260 210 1.3561769969847954 43.65329661468152 242.0 +10 260 1.3541934249907601 43.65298695394936 242.0 +60 260 1.3545905725316338 43.65298800184903 242.0 +110 260 1.3549877198192075 43.65298904788973 242.0 +160 260 1.3553848668538861 43.65299009207148 242.0 +210 260 1.3557820136360756 43.652991134394256 242.0 +260 260 1.3561791601661808 43.652992174858085 242.0 diff --git a/Data/Input/TuGDALRPCTransformerTest_DEM.tif b/Data/Input/TuGDALRPCTransformerTest_DEM.tif new file mode 100644 index 0000000000000000000000000000000000000000..2e415a945d06ec22bf6a86ab814efdc24aef17d0 --- /dev/null +++ b/Data/Input/TuGDALRPCTransformerTest_DEM.tif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cdb3ff53ea8395991872756e94025a72a43d9ad11229699370e3ae92f2a9ad2f +size 10376 diff --git a/Data/Input/ikonos/ikonos-1.gcp2 b/Data/Input/ikonos/ikonos-1.gcp2 new file mode 100644 index 0000000000000000000000000000000000000000..68bae8ea0c27b9ce506bfb32df4920e2fd61dd6d --- /dev/null +++ b/Data/Input/ikonos/ikonos-1.gcp2 @@ -0,0 +1,37 @@ +# column row longitude latitude elevation +10 10 0.6658750544838034 49.923463151900904 111.0 +60 10 0.6686590046756826 49.92351917682645 111.0 +110 10 0.6714429636060101 49.92357513497311 111.0 +160 10 0.6742269312643617 49.92363102634035 111.0 +210 10 0.6770109076403149 49.923686850927645 111.0 +260 10 0.6797948927234478 49.92374260873445 111.0 +10 60 0.6659618799740855 49.92166581116278 111.0 +60 60 0.6687457268362428 49.92172183254416 111.0 +110 60 0.6715295824357131 49.92177778715086 111.0 +160 60 0.6743134467620735 49.92183367498236 111.0 +210 60 0.6770973198049026 49.92188949603812 111.0 +260 60 0.67988120155378 49.921945250317606 111.0 +10 110 0.6660486967172462 49.91986846975386 111.0 +60 110 0.6688324402600632 49.91992448759133 111.0 +110 110 0.671616192539058 49.91998043865834 111.0 +160 110 0.6743999535438092 49.92003632295436 111.0 +210 110 0.6771837232638964 49.92009214047886 111.0 +260 110 0.6799675016889003 49.920147891231295 111.0 +10 160 0.6661355047144274 49.918071127674125 111.0 +60 160 0.6689191449482844 49.91812714196796 111.0 +110 160 0.6717027939171843 49.91818308949555 111.0 +160 160 0.6744864516107071 49.91823897025636 111.0 +210 160 0.6772701180184332 49.91829478424986 111.0 +260 160 0.6800537931299447 49.91835053147551 111.0 +10 210 0.6662223039667708 49.91627378492358 111.0 +60 210 0.669005840902047 49.916329795674045 111.0 +110 210 0.6717893865712314 49.91638573966248 111.0 +160 210 0.6745729409639051 49.91644161688834 111.0 +210 210 0.6773565040696498 49.91649742735111 111.0 +260 210 0.6801400758780487 49.916553171050246 111.0 +10 260 0.6663090944754178 49.91447644150221 111.0 +60 260 0.6690925281224911 49.91453244870957 111.0 +110 260 0.671875970502338 49.91458838915912 111.0 +160 260 0.6746594216045408 49.91464426285031 111.0 +210 260 0.6774428814186826 49.91470006978261 111.0 +260 260 0.6802263499343474 49.9147558099555 111.0 diff --git a/Data/Input/pleiades/maido.geom b/Data/Input/pleiades/maido.geom index d4985c9fb8c2ae18b947695d56ac662fb7ef7fee..af7a8b8c9a505f1568334c6133c5ecc2a3e75fa8 100644 --- a/Data/Input/pleiades/maido.geom +++ b/Data/Input/pleiades/maido.geom @@ -80,7 +80,7 @@ line_num_coeff_16: 4.81457792658454e-05 line_num_coeff_17: 2.88619029525836e-07 line_num_coeff_18: -3.21946619769831e-07 line_num_coeff_19: 5.19261801580877e-07 -line_off: 3628.5 +line_off: 3628 line_scale: 3628.5 ll_lat: -21.1761546496637 ll_lon: 55.3361820080128 @@ -141,7 +141,7 @@ samp_num_coeff_16: -7.36857981217554e-07 samp_num_coeff_17: 6.99721596099962e-06 samp_num_coeff_18: 2.68058434585531e-05 samp_num_coeff_19: 2.22039097455653e-06 -samp_off: 2178 +samp_off: 2177.5 samp_scale: 5187 sensor: PHR 1A support_data.across_track_incidence_angle: """15.5053146594264 15.3626255402908 15.2247250482884 """ diff --git a/Data/Input/pleiades/pleiades-1.gcp2 b/Data/Input/pleiades/pleiades-1.gcp2 new file mode 100644 index 0000000000000000000000000000000000000000..8337a2d25b5e770001d72dac0f7067b739bd4130 --- /dev/null +++ b/Data/Input/pleiades/pleiades-1.gcp2 @@ -0,0 +1,37 @@ +# column row longitude latitude elevation +10 10 1.3619678304742049 43.685679307528154 255.0 +60 10 1.362269915752421 43.68568138233786 255.0 +110 10 1.3625720040752514 43.68568345638775 255.0 +160 10 1.3628740954430656 43.68568552967785 255.0 +210 10 1.3631761898562327 43.685687602208176 255.0 +260 10 1.3634782873151208 43.68568967397878 255.0 +10 60 1.3619690059603062 43.68545371966921 255.0 +60 60 1.362271090845755 43.685455793356994 255.0 +110 60 1.3625731787760083 43.68545786628494 255.0 +160 60 1.3628752697514357 43.685459938453086 255.0 +210 60 1.3631773637724058 43.68546200986146 255.0 +260 60 1.3634794608392868 43.685464080510094 255.0 +10 110 1.3619701802586466 43.68522813138672 255.0 +60 110 1.362272264751236 43.685230203952486 255.0 +110 110 1.3625743522888205 43.68523227575841 255.0 +160 110 1.36287644287177 43.68523434680452 255.0 +210 110 1.363178536500452 43.68523641709085 255.0 +260 110 1.3634806331752352 43.685238486617436 255.0 +10 160 1.3619713533675186 43.685002542681254 255.0 +60 160 1.3622734374671568 43.68500461412492 255.0 +110 160 1.3625755246119815 43.685006684808734 255.0 +160 160 1.3628776148023616 43.68500875473273 255.0 +210 160 1.3631797080386652 43.68501082389693 255.0 +260 160 1.3634818043212602 43.68501289230138 255.0 +10 210 1.3619725252852164 43.68477695355337 255.0 +60 210 1.362274608991812 43.68477902387485 255.0 +110 210 1.3625766957437855 43.68478109343648 255.0 +160 210 1.3628787855415057 43.684783162238276 255.0 +210 210 1.3631808783853407 43.684785230280276 255.0 +260 210 1.3634829742756576 43.68478729756251 255.0 +10 260 1.361973696010035 43.684551364003646 255.0 +60 260 1.3622757793234972 43.68455343320287 255.0 +110 260 1.362577865682529 43.68455550164222 255.0 +160 260 1.362879955087499 43.68455756932174 255.0 +210 260 1.363182047538775 43.684559636241445 255.0 +260 260 1.3634841430367244 43.68456170240138 255.0 diff --git a/Data/Input/spot6/spot6-1.gcp2 b/Data/Input/spot6/spot6-1.gcp2 new file mode 100644 index 0000000000000000000000000000000000000000..cbca276e3e58b901de1dec643bd9ed9249c4d2fa --- /dev/null +++ b/Data/Input/spot6/spot6-1.gcp2 @@ -0,0 +1,37 @@ +# column row longitude latitude elevation +10 10 1.7345564619005363 41.68106750754352 500.0 +60 10 1.7383514263665019 41.681087406108766 500.0 +110 10 1.7421461093189425 41.681107169312476 500.0 +160 10 1.745940511039318 41.68112679718585 500.0 +210 10 1.7497346318090152 41.68114628976002 500.0 +260 10 1.7535284719093507 41.68116564706613 500.0 +10 60 1.7345822813635834 41.678252222887714 500.0 +60 60 1.7383769791926376 41.67827210036069 500.0 +110 60 1.742171395960521 41.67829184249305 500.0 +160 60 1.745965531948459 41.678311449315984 500.0 +210 60 1.7497593874376067 41.678330920860574 500.0 +260 60 1.7535529627090474 41.67835025715789 500.0 +10 110 1.7346080588182125 41.67543692582202 500.0 +60 110 1.7384024901552924 41.67545678221733 500.0 +110 110 1.7421966408833551 41.67547650329298 500.0 +160 110 1.7459905112833938 41.67549608908007 500.0 +210 110 1.74978410163633 41.675515539609655 500.0 +260 110 1.7535774122230157 41.67553485491275 500.0 +10 160 1.7346337942703054 41.67262161640454 500.0 +60 160 1.7384279592602898 41.67264145173682 500.0 +110 160 1.7422218440932107 41.67266115177036 500.0 +160 160 1.746015449049829 41.67268071653621 500.0 +210 160 1.7498087744108342 41.672700146065374 500.0 +260 160 1.7536018204568462 41.67271944038882 500.0 +10 210 1.7346594877257393 41.66980629469341 500.0 +60 210 1.738453386513448 41.66982610897728 500.0 +110 210 1.7422470055958472 41.66984578798332 500.0 +160 210 1.746040345253466 41.66986533174253 500.0 +210 210 1.7498334057667624 41.669884740285845 500.0 +260 210 1.7536261874161243 41.6699040136442 500.0 +10 260 1.7346851391903855 41.666990960746745 500.0 +60 260 1.7384787719205799 41.667010753996834 500.0 +110 260 1.7422721253970195 41.66703041198998 500.0 +160 260 1.7460651999000014 41.667049934757124 500.0 +210 260 1.7498579957097529 41.667069322329176 500.0 +260 260 1.7536505131064306 41.667088574737 500.0 diff --git a/Data/Input/wv2/wv2-1.gcp2 b/Data/Input/wv2/wv2-1.gcp2 new file mode 100644 index 0000000000000000000000000000000000000000..e8b30ef9445a9a1d5e79072c0ea1f7e7495713ba --- /dev/null +++ b/Data/Input/wv2/wv2-1.gcp2 @@ -0,0 +1,37 @@ +# column row longitude latitude elevation +10 10 12.478079201221188 41.90017890789062 94.0 +60 10 12.478380306243242 41.900185524323824 94.0 +110 10 12.47868141136673 41.90019213996859 94.0 +160 10 12.478982516591667 41.900198754824906 94.0 +210 10 12.47928362191806 41.900205368892784 94.0 +260 10 12.479584727345921 41.90021198217221 94.0 +10 60 12.478088057996441 41.899953955848744 94.0 +60 60 12.47838916196374 41.89996057223006 94.0 +110 60 12.478690266032475 41.89996718782293 94.0 +160 60 12.478991370202655 41.89997380262737 94.0 +210 60 12.479292474474294 41.89998041664337 94.0 +260 60 12.4795935788474 41.89998702987093 94.0 +10 110 12.478096914670814 41.89972900379652 94.0 +60 110 12.478398017583372 41.899735620125945 94.0 +110 110 12.478699120597362 41.899742235666935 94.0 +160 110 12.4790002237128 41.8997488504195 94.0 +210 110 12.479301326929695 41.899755464383624 94.0 +260 110 12.479602430248057 41.89976207755931 94.0 +10 160 12.478105771244309 41.89950405173396 94.0 +60 160 12.478406873102134 41.89951066801149 94.0 +110 160 12.478707975061395 41.89951728350059 94.0 +160 160 12.479009077122102 41.89952389820128 94.0 +210 160 12.479310179284267 41.89953051211353 94.0 +260 160 12.479611281547898 41.89953712523735 94.0 +10 210 12.478114627716925 41.89927909966106 94.0 +60 210 12.478415728520034 41.89928571588669 94.0 +110 210 12.478716829424574 41.89929233132391 94.0 +160 210 12.479017930430564 41.89929894597272 94.0 +210 210 12.47931903153801 41.899305559833095 94.0 +260 210 12.479620132746922 41.89931217290504 94.0 +10 260 12.478123484088664 41.89905414757781 94.0 +60 260 12.478424583837064 41.89906076375155 94.0 +110 260 12.4787256836869 41.89906737913689 94.0 +160 260 12.479026783638181 41.89907399373381 94.0 +210 260 12.479327883690921 41.89908060754232 94.0 +260 260 12.479628983845126 41.8990872205624 94.0 diff --git a/Examples/Projections/EstimateRPCSensorModelExample.cxx b/Examples/Projections/EstimateRPCSensorModelExample.cxx index ffb11c3704f836c9d7533c30b8ed926f61f42620..01be179c96f4e8d9224f065df4237aadce331b2d 100644 --- a/Examples/Projections/EstimateRPCSensorModelExample.cxx +++ b/Examples/Projections/EstimateRPCSensorModelExample.cxx @@ -28,7 +28,7 @@ // The \doxygen{otb}{GCPsToRPCSensorModelImageFilter} estimates a RPC // sensor model from a list of user defined GCPs. Internally, it uses -// an ossimRpcSolver, which performs the estimation using the well +// an RpcSolver, which performs the estimation using the well // known least-square method. // Let's look at the minimal code required to use this @@ -119,7 +119,7 @@ int main(int argc, char* argv[]) rpcEstimator->GetOutput()->UpdateOutputInformation(); // The result of the RPC model estimation and the residual ground - // error is then save in a txt file. Note that This filter does + // error is then saved in a txt file. Note that This filter does // not modify the image buffer, but only the metadata. std::ofstream ofs; @@ -129,7 +129,9 @@ int main(int argc, char* argv[]) ofs.setf(std::ios::fixed, std::ios::floatfield); ofs.precision(10); - ofs << (ImageType::Pointer)rpcEstimator->GetOutput() << std::endl; + auto outputRPC = boost::any_cast(rpcEstimator->GetOutput()->GetImageMetadata()[otb::MDGeom::RPC]); + + ofs << outputRPC.ToJSON() << std::endl; ofs << "Residual ground error: " << rpcEstimator->GetRMSGroundError() << std::endl; ofs.close(); diff --git a/Examples/Projections/GeometriesProjectionExample.cxx b/Examples/Projections/GeometriesProjectionExample.cxx index 77845a2c5e798e5ea7f77149ee6a18ef926a00e8..64e45b9241bb387032862000c166a6fa45de3ce5 100644 --- a/Examples/Projections/GeometriesProjectionExample.cxx +++ b/Examples/Projections/GeometriesProjectionExample.cxx @@ -84,7 +84,7 @@ int main(int argc, char* argv[]) // the image: // necessary for sensors - filter->SetOutputKeywordList(imageReader->GetOutput()->GetImageKeywordlist()); + filter->SetOutputImageMetadata(&(imageReader->GetOutput()->GetImageMetadata())); // necessary for sensors filter->SetOutputOrigin(imageReader->GetOutput()->GetOrigin()); // necessary for sensors diff --git a/Examples/Projections/VectorDataProjectionExample.cxx b/Examples/Projections/VectorDataProjectionExample.cxx index ea8c3c99f879caf6bc05a872aa91c76038aa4cd0..06aab6e1105de4366968f6504b42b08e85703fb7 100644 --- a/Examples/Projections/VectorDataProjectionExample.cxx +++ b/Examples/Projections/VectorDataProjectionExample.cxx @@ -92,7 +92,7 @@ int main(int argc, char* argv[]) // Information about the target projection is retrieved directly from // the image: - vectorDataProjection->SetOutputKeywordList(imageReader->GetOutput()->GetImageKeywordlist()); + vectorDataProjection->SetOutputImageMetadata(&imageReader->GetOutput()->GetImageMetadata()); vectorDataProjection->SetOutputOrigin(imageReader->GetOutput()->GetOrigin()); vectorDataProjection->SetOutputSpacing(imageReader->GetOutput()->GetSignedSpacing()); vectorDataProjection->SetOutputProjectionRef(imageReader->GetOutput()->GetProjectionRef()); diff --git a/Examples/Projections/test/CMakeLists.txt b/Examples/Projections/test/CMakeLists.txt index e73c5f0164cd8a747f28765ad736e5ca08ae8cca..7ef28fa28516ebf2ed29b4a039603c562a8347cf 100644 --- a/Examples/Projections/test/CMakeLists.txt +++ b/Examples/Projections/test/CMakeLists.txt @@ -82,28 +82,108 @@ otb_add_test(NAME prTeEstimateRPCSensorModelExampleTest COMMAND ${OTB_TEST_DRIVE ${TEMP}/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt --ignore-lines-with 6 PipelineMTime ImportImageContaine Source: Image Time: Pointer: Execute $ - LARGEINPUT{SPOT4/RIO_DE_JANEIRO/IMAG_01.DAT} + ${INPUTDATA}/QB_TOULOUSE_MUL_Extract_500_500.tif ${TEMP}/otbGCPsToRPCSensorModelImageFilterWithoutDEMOutput.txt - 1199 1259 -22.76847 -43.168043 0. - 1497 727 -22.688931 -43.066686 0. - 699 1146 -22.7254 -43.288651 0. - 1379 2457 -22.986073 -43.193502 0. - 2592 1846 -22.932684 -42.854215 0. - 1430 1797 -22.872988 -43.136813 0. - 587 2654 -22.983847 -43.393297 0. - 2398 2422 -23.025664 -42.928778 0. - 1436 2946 -23.074483 -43.192431 0. - 963 2915 -23.047382 -43.310011 0. - 1081 1024 -22.721919 -43.18523 0. - 1395 1213 -22.769191 -43.116752 0. - 1781 2202 -22.959556 -43.069911 0. - 2803 1942 -22.958868 -42.808235 0. - 980 2734 -22.99534 -43.309672 0. - 713 2754 -23.007862 -43.365307 0. - 72 2955 -23.012153 -43.541331 0. - 2884 1898 -22.954691 -42.786188 0. - 2539 47 -22.616041 -42.777877 0. - 577 183 -22.551654 -43.271813 0. + 2000 2000 1.41809 43.6143 0 + 2000 2050 1.4181 43.6131 0 + 2000 2100 1.4181 43.6119 0 + 2000 2150 1.41811 43.6107 0 + 2000 2200 1.41812 43.6095 0 + 2000 2250 1.41812 43.6083 0 + 2000 2300 1.41813 43.6071 0 + 2000 2350 1.41814 43.6058 0 + 2000 2400 1.41814 43.6046 0 + 2000 2450 1.41815 43.6034 0 + 2050 2000 1.41967 43.6143 0 + 2050 2050 1.41968 43.6131 0 + 2050 2100 1.41969 43.6119 0 + 2050 2150 1.41969 43.6107 0 + 2050 2200 1.4197 43.6095 0 + 2050 2250 1.41971 43.6083 0 + 2050 2300 1.41971 43.6071 0 + 2050 2350 1.41972 43.6059 0 + 2050 2400 1.41973 43.6046 0 + 2050 2450 1.41973 43.6034 0 + 2100 2000 1.42126 43.6143 0 + 2100 2050 1.42126 43.6131 0 + 2100 2100 1.42127 43.6119 0 + 2100 2150 1.42128 43.6107 0 + 2100 2200 1.42128 43.6095 0 + 2100 2250 1.42129 43.6083 0 + 2100 2300 1.4213 43.6071 0 + 2100 2350 1.4213 43.6059 0 + 2100 2400 1.42131 43.6046 0 + 2100 2450 1.42132 43.6034 0 + 2150 2000 1.42284 43.6143 0 + 2150 2050 1.42285 43.6131 0 + 2150 2100 1.42285 43.6119 0 + 2150 2150 1.42286 43.6107 0 + 2150 2200 1.42286 43.6095 0 + 2150 2250 1.42287 43.6083 0 + 2150 2300 1.42288 43.6071 0 + 2150 2350 1.42288 43.6059 0 + 2150 2400 1.42289 43.6046 0 + 2150 2450 1.4229 43.6034 0 + 2200 2000 1.42442 43.6144 0 + 2200 2050 1.42443 43.6131 0 + 2200 2100 1.42443 43.6119 0 + 2200 2150 1.42444 43.6107 0 + 2200 2200 1.42445 43.6095 0 + 2200 2250 1.42445 43.6083 0 + 2200 2300 1.42446 43.6071 0 + 2200 2350 1.42447 43.6059 0 + 2200 2400 1.42447 43.6046 0 + 2200 2450 1.42448 43.6034 0 + 2250 2000 1.42601 43.6144 0 + 2250 2050 1.42601 43.6131 0 + 2250 2100 1.42602 43.6119 0 + 2250 2150 1.42602 43.6107 0 + 2250 2200 1.42603 43.6095 0 + 2250 2250 1.42604 43.6083 0 + 2250 2300 1.42604 43.6071 0 + 2250 2350 1.42605 43.6059 0 + 2250 2400 1.42605 43.6047 0 + 2250 2450 1.42606 43.6034 0 + 2300 2000 1.42759 43.6144 0 + 2300 2050 1.42759 43.6131 0 + 2300 2100 1.4276 43.6119 0 + 2300 2150 1.42761 43.6107 0 + 2300 2200 1.42761 43.6095 0 + 2300 2250 1.42762 43.6083 0 + 2300 2300 1.42762 43.6071 0 + 2300 2350 1.42763 43.6059 0 + 2300 2400 1.42764 43.6047 0 + 2300 2450 1.42764 43.6034 0 + 2350 2000 1.42917 43.6144 0 + 2350 2050 1.42918 43.6131 0 + 2350 2100 1.42918 43.6119 0 + 2350 2150 1.42919 43.6107 0 + 2350 2200 1.42919 43.6095 0 + 2350 2250 1.4292 43.6083 0 + 2350 2300 1.42921 43.6071 0 + 2350 2350 1.42921 43.6059 0 + 2350 2400 1.42922 43.6047 0 + 2350 2450 1.42922 43.6034 0 + 2400 2000 1.43075 43.6144 0 + 2400 2050 1.43076 43.6131 0 + 2400 2100 1.43076 43.6119 0 + 2400 2150 1.43077 43.6107 0 + 2400 2200 1.43078 43.6095 0 + 2400 2250 1.43078 43.6083 0 + 2400 2300 1.43079 43.6071 0 + 2400 2350 1.43079 43.6059 0 + 2400 2400 1.4308 43.6047 0 + 2400 2450 1.43081 43.6034 0 + 2450 2000 1.43234 43.6144 0 + 2450 2050 1.43234 43.6132 0 + 2450 2100 1.43235 43.6119 0 + 2450 2150 1.43235 43.6107 0 + 2450 2200 1.43236 43.6095 0 + 2450 2250 1.43236 43.6083 0 + 2450 2300 1.43237 43.6071 0 + 2450 2350 1.43238 43.6059 0 + 2450 2400 1.43238 43.6047 0 + 2450 2450 1.43239 43.6034 0 ) otb_add_test(NAME prTePlaceNameToLonLatExampleTest COMMAND ${OTB_TEST_DRIVER} diff --git a/Modules/Adapters/OSSIMAdapters/test/CMakeLists.txt b/Modules/Adapters/OSSIMAdapters/test/CMakeLists.txt index 6768ac1fb2a8ae5b8b4c8d357dd73c4f3ef2a7bf..5d240997cf5706ba979abe41469092a07b28cba7 100644 --- a/Modules/Adapters/OSSIMAdapters/test/CMakeLists.txt +++ b/Modules/Adapters/OSSIMAdapters/test/CMakeLists.txt @@ -27,7 +27,6 @@ otbOssimJpegFileResourceLeakTest.cxx otbOssimElevManagerTest2.cxx otbOssimElevManagerTest4.cxx otbDEMHandlerTest.cxx -otbRPCSolverAdapterTest.cxx ) add_executable(otbOSSIMAdaptersTestDriver ${OTBOSSIMAdaptersTests}) @@ -418,32 +417,32 @@ otb_add_test(NAME uaTvDEMHandler_AboveEllipsoid_SRTM_NoGeoid_NoData COMMAND otbO 0.001 ) -otb_add_test(NAME uaTvRPCSolverAdapterNoDEMValidationTest COMMAND otbOSSIMAdaptersTestDriver - otbRPCSolverAdapterTest - LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} - 10 0.25 0.35 - no - no - ) - -otb_add_test(NAME uaTvRPCSolverAdapterNotEnoughPointsForElevationTest COMMAND otbOSSIMAdaptersTestDriver - otbRPCSolverAdapterTest - LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} - 5 0.25 0.35 - no - no - ) - -otb_add_test(NAME uaTvRPCSolverAdapterNotEnoughPointsTest COMMAND otbOSSIMAdaptersTestDriver - otbRPCSolverAdapterTest - LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} - 4 0.25 0.35 - ${INPUTDATA}/DEM/srtm_directory/ - ${INPUTDATA}/DEM/egm96.grd - ) -if (OTB_DATA_USE_LARGEINPUT) - set_property(TEST uaTvRPCSolverAdapterNotEnoughPointsTest PROPERTY WILL_FAIL TRUE) -endif() +# otb_add_test(NAME uaTvRPCSolverAdapterNoDEMValidationTest COMMAND otbOSSIMAdaptersTestDriver +# otbRPCSolverAdapterTest +# LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} +# 10 0.25 0.35 +# no +# no +# ) + +# otb_add_test(NAME uaTvRPCSolverAdapterNotEnoughPointsForElevationTest COMMAND otbOSSIMAdaptersTestDriver +# otbRPCSolverAdapterTest +# LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} +# 5 0.25 0.35 +# no +# no +# ) + +# otb_add_test(NAME uaTvRPCSolverAdapterNotEnoughPointsTest COMMAND otbOSSIMAdaptersTestDriver +# otbRPCSolverAdapterTest +# LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} +# 4 0.25 0.35 +# ${INPUTDATA}/DEM/srtm_directory/ +# ${INPUTDATA}/DEM/egm96.grd +# ) +# if (OTB_DATA_USE_LARGEINPUT) +# set_property(TEST uaTvRPCSolverAdapterNotEnoughPointsTest PROPERTY WILL_FAIL TRUE) +# endif() #otb_add_test(NAME uaTvRPCSolverAdapterOutGeomTest COMMAND otbOSSIMAdaptersTestDriver #--compare-ascii ${EPSILON_9} @@ -457,11 +456,11 @@ endif() #${TEMP}/uaTvRPCSolverAdapterOutGeomTest.geom #) -otb_add_test(NAME uaTvRPCSolverAdapterValidationTest COMMAND otbOSSIMAdaptersTestDriver - otbRPCSolverAdapterTest - LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} - 10 0.25 0.35 - ${INPUTDATA}/DEM/srtm_directory/ - ${INPUTDATA}/DEM/egm96.grd - ) +# otb_add_test(NAME uaTvRPCSolverAdapterValidationTest COMMAND otbOSSIMAdaptersTestDriver +# otbRPCSolverAdapterTest +# LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} +# 10 0.25 0.35 +# ${INPUTDATA}/DEM/srtm_directory/ +# ${INPUTDATA}/DEM/egm96.grd +# ) diff --git a/Modules/Adapters/OSSIMAdapters/test/otbOSSIMAdaptersTestDriver.cxx b/Modules/Adapters/OSSIMAdapters/test/otbOSSIMAdaptersTestDriver.cxx index b598f02738169ad9e10b2b4563b6999c9d6406cc..9deb8f2a3ce7ce917ec297ce3cecab8f40d5c711 100644 --- a/Modules/Adapters/OSSIMAdapters/test/otbOSSIMAdaptersTestDriver.cxx +++ b/Modules/Adapters/OSSIMAdapters/test/otbOSSIMAdaptersTestDriver.cxx @@ -27,5 +27,4 @@ void RegisterTests() REGISTER_TEST(otbOssimElevManagerTest2); REGISTER_TEST(otbOssimElevManagerTest4); REGISTER_TEST(otbDEMHandlerTest); - REGISTER_TEST(otbRPCSolverAdapterTest); } diff --git a/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx b/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx index 0a7979ba28a76b5f3605ce2dbb5117d8efd81f2f..82ca93f27421baf0dc1f52e63da4eee330979cfd 100644 --- a/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx +++ b/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx @@ -209,7 +209,7 @@ private: geometriesProjFilter->SetInput(inputGeomSet); if (imageProjectionRef.empty()) { - geometriesProjFilter->SetOutputKeywordList(inputImg->GetImageKeywordlist()); // nec qd capteur + geometriesProjFilter->SetOutputImageMetadata(&(inputImg->GetImageMetadata())); } geometriesProjFilter->SetOutputProjectionRef(imageProjectionRef); geometriesProjFilter->SetOutput(outputGeomSet); diff --git a/Modules/Applications/AppClassification/app/otbSampleSelection.cxx b/Modules/Applications/AppClassification/app/otbSampleSelection.cxx index daf849099eab74263cdde84ffdb4accb64b52516..8395ce54611080bdee2e1a449b60d41377c12c97 100644 --- a/Modules/Applications/AppClassification/app/otbSampleSelection.cxx +++ b/Modules/Applications/AppClassification/app/otbSampleSelection.cxx @@ -375,7 +375,7 @@ private: geometriesProjFilter->SetInput(inputGeomSet); if (imageProjectionRef.empty()) { - geometriesProjFilter->SetOutputKeywordList(inputImg->GetImageKeywordlist()); // nec qd capteur + geometriesProjFilter->SetOutputImageMetadata(&(inputImg->GetImageMetadata())); } geometriesProjFilter->SetOutputProjectionRef(imageProjectionRef); geometriesProjFilter->SetOutput(outputGeomSet); diff --git a/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx b/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx index 371f7212e96624d5da0fdbb95421adf448a5dda1..a682a59b5bad14daecaea5a853fb54b4315044b0 100644 --- a/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx +++ b/Modules/Applications/AppDescriptors/app/otbHomologousPointsExtraction.cxx @@ -333,17 +333,17 @@ private: // Setting up RS Transform RSTransformType::Pointer rsTransform = RSTransformType::New(); - rsTransform->SetInputKeywordList(image1->GetImageKeywordlist()); + rsTransform->SetInputImageMetadata(&(image1->GetImageMetadata())); rsTransform->SetInputProjectionRef(image1->GetProjectionRef()); - rsTransform->SetOutputKeywordList(image2->GetImageKeywordlist()); + rsTransform->SetOutputImageMetadata(&(image2->GetImageMetadata())); rsTransform->SetOutputProjectionRef(image2->GetProjectionRef()); RSTransformType::Pointer rsTransform1ToWGS84 = RSTransformType::New(); - rsTransform1ToWGS84->SetInputKeywordList(image1->GetImageKeywordlist()); + rsTransform1ToWGS84->SetInputImageMetadata(&(image1->GetImageMetadata())); rsTransform1ToWGS84->SetInputProjectionRef(image1->GetProjectionRef()); RSTransformType::Pointer rsTransform2ToWGS84 = RSTransformType::New(); - rsTransform2ToWGS84->SetInputKeywordList(image2->GetImageKeywordlist()); + rsTransform2ToWGS84->SetInputImageMetadata(&(image2->GetImageMetadata())); rsTransform2ToWGS84->SetInputProjectionRef(image2->GetProjectionRef()); // Setting up output file diff --git a/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx b/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx index 53914202dad6d5a3af75e1431d3d065d5522c81e..56c3d6b629b2b391be6d10d267da4eb8ecb31972 100644 --- a/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx +++ b/Modules/Applications/AppEdge/app/otbLineSegmentDetection.cxx @@ -172,7 +172,7 @@ private: VectorDataProjectionFilterType::Pointer vproj = VectorDataProjectionFilterType::New(); vproj->SetInput(vd); - vproj->SetInputKeywordList(GetParameterImage("in")->GetImageKeywordlist()); + vproj->SetInputImageMetadata(&GetParameterImage("in")->GetImageMetadata()); // vproj->SetInputOrigin(GetParameterImage("in")->GetOrigin()); // vproj->SetInputSpacing(GetParameterImage("in")->GetSignedSpacing()); diff --git a/Modules/Applications/AppImageUtils/app/otbDownloadSRTMTiles.cxx b/Modules/Applications/AppImageUtils/app/otbDownloadSRTMTiles.cxx index 2c56e6150599cf6bdb7e73145c93903c2c7a1d28..40baab33dbaed83ece960040cab3bafed99af30c 100644 --- a/Modules/Applications/AppImageUtils/app/otbDownloadSRTMTiles.cxx +++ b/Modules/Applications/AppImageUtils/app/otbDownloadSRTMTiles.cxx @@ -291,7 +291,7 @@ private: auto inImage = inList->GetNthElement(i); auto rsTransformToWGS84 = RSTransformType::New(); - rsTransformToWGS84->SetInputKeywordList(inImage->GetImageKeywordlist()); + rsTransformToWGS84->SetInputImageMetadata(&(inImage->GetImageMetadata())); rsTransformToWGS84->SetInputProjectionRef(inImage->GetProjectionRef()); rsTransformToWGS84->SetOutputProjectionRef(static_cast(otb::SpatialReference::FromWGS84().ToWkt())); rsTransformToWGS84->InstantiateTransform(); diff --git a/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx b/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx index bdb7aefdc1ed1d55c48e94591a3b2f04331bb409..bf13a5051f52605a5d509cd92f6d8fbe68bd071b 100644 --- a/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx +++ b/Modules/Applications/AppImageUtils/app/otbExtractROI.cxx @@ -427,7 +427,7 @@ private: { RSTransformType::Pointer rsTransform = RSTransformType::New(); ImageType* inImage = GetParameterImage("in"); - rsTransform->SetOutputKeywordList(inImage->GetImageKeywordlist()); + rsTransform->SetOutputImageMetadata(&(inImage->GetImageMetadata())); rsTransform->SetOutputProjectionRef(inImage->GetProjectionRef()); rsTransform->InstantiateTransform(); itk::Point ulp_in, lrp_in, ulp_out, lrp_out; @@ -486,7 +486,7 @@ private: else // if ( GetParameterString( "mode.extent.unit" ) == "lonlat" ) { RSTransformType::Pointer rsTransform = RSTransformType::New(); - rsTransform->SetInputKeywordList(input->GetImageKeywordlist()); + rsTransform->SetInputImageMetadata(&(input->GetImageMetadata())); rsTransform->SetInputProjectionRef(input->GetProjectionRef()); rsTransform->InstantiateTransform(); itk::Point ulp_in, lrp_in, ulp_out, lrp_out; @@ -544,7 +544,7 @@ private: { RSTransformType::Pointer rsTransform = RSTransformType::New(); ImageType* inImage = GetParameterImage("in"); - rsTransform->SetOutputKeywordList(inImage->GetImageKeywordlist()); + rsTransform->SetOutputImageMetadata(&(inImage->GetImageMetadata())); rsTransform->SetOutputProjectionRef(inImage->GetProjectionRef()); rsTransform->InstantiateTransform(); itk::Point centerp_in, centerp_out; @@ -586,7 +586,7 @@ private: else // if ( GetParameterString( "mode.radius.unitc" ) == "lon/lat" ) { RSTransformType::Pointer rsTransform = RSTransformType::New(); - rsTransform->SetOutputKeywordList(inImage->GetImageKeywordlist()); + rsTransform->SetOutputImageMetadata(&(inImage->GetImageMetadata())); rsTransform->SetOutputProjectionRef(inImage->GetProjectionRef()); rsTransform->InstantiateTransform(); itk::Point centerp_in; @@ -659,7 +659,7 @@ private: else // if ( GetParameterString("mode.radius.unitc") == "lonlat" ) { RSTransformType::Pointer rsTransform = RSTransformType::New(); - rsTransform->SetInputKeywordList(input->GetImageKeywordlist()); + rsTransform->SetInputImageMetadata(&(input->GetImageMetadata())); rsTransform->SetInputProjectionRef(input->GetProjectionRef()); rsTransform->InstantiateTransform(); itk::Point centerp_in, centerp_out; @@ -724,7 +724,7 @@ private: } RSTransformType::Pointer rsTransform = RSTransformType::New(); rsTransform->SetInputProjectionRef(inputProjectionRef); - rsTransform->SetOutputKeywordList(inImage->GetImageKeywordlist()); + rsTransform->SetOutputImageMetadata(&(inImage->GetImageMetadata())); rsTransform->SetOutputProjectionRef(inImage->GetProjectionRef()); rsTransform->InstantiateTransform(); itk::Point ulp_in, urp_in, llp_in, lrp_in; @@ -768,9 +768,9 @@ private: RSTransformType::Pointer rsTransform = RSTransformType::New(); - rsTransform->SetInputKeywordList(referencePtr->GetImageKeywordlist()); + rsTransform->SetInputImageMetadata(&(referencePtr->GetImageMetadata())); rsTransform->SetInputProjectionRef(referencePtr->GetProjectionRef()); - rsTransform->SetOutputKeywordList(inImage->GetImageKeywordlist()); + rsTransform->SetOutputImageMetadata(&(inImage->GetImageMetadata())); rsTransform->SetOutputProjectionRef(inImage->GetProjectionRef()); rsTransform->InstantiateTransform(); diff --git a/Modules/Applications/AppImageUtils/app/otbPixelValue.cxx b/Modules/Applications/AppImageUtils/app/otbPixelValue.cxx index 9998ee8965f5a50d90777a528ccb843bf0c2212d..0acaf3e5a6666cb0d73bf87e7ea7301f46795bdd 100644 --- a/Modules/Applications/AppImageUtils/app/otbPixelValue.cxx +++ b/Modules/Applications/AppImageUtils/app/otbPixelValue.cxx @@ -167,7 +167,7 @@ private: std::string wktFromEpsg = otb::SpatialReference::FromEPSG(GetParameterInt("mode.epsg.code")).ToWkt(); inverse->SetOutputProjectionRef(wktFromEpsg); } - inverse->SetInputKeywordList(inImage->GetImageKeywordlist()); + inverse->SetInputImageMetadata(&(inImage->GetImageMetadata())); inverse->SetInputProjectionRef(inImage->GetProjectionRef()); inverse->InstantiateTransform(); itk::Point minPOut(0), maxPOut(0), minP(0), maxP(0); @@ -239,7 +239,7 @@ private: std::string wktFromEpsg = otb::SpatialReference::FromEPSG(GetParameterInt("mode.epsg.code")).ToWkt(); rsTransform->SetInputProjectionRef(wktFromEpsg); } - rsTransform->SetOutputKeywordList(inImage->GetImageKeywordlist()); + rsTransform->SetOutputImageMetadata(&(inImage->GetImageMetadata())); rsTransform->SetOutputProjectionRef(inImage->GetProjectionRef()); rsTransform->InstantiateTransform(); itk::Point pixelIn(0), pixelOut(0); diff --git a/Modules/Applications/AppProjection/app/otbConvertSensorToGeoPoint.cxx b/Modules/Applications/AppProjection/app/otbConvertSensorToGeoPoint.cxx index 2104388cd21d0fc41cf2fd8592b83c54aa0543c3..21235d057c6a20dab1c1adbdc054dc311ab9eccf 100644 --- a/Modules/Applications/AppProjection/app/otbConvertSensorToGeoPoint.cxx +++ b/Modules/Applications/AppProjection/app/otbConvertSensorToGeoPoint.cxx @@ -21,7 +21,7 @@ #include "otbWrapperApplication.h" #include "otbWrapperApplicationFactory.h" -#include "otbForwardSensorModel.h" +#include "otbRPCForwardTransform.h" #include "otbCoordinateToName.h" namespace otb @@ -44,7 +44,7 @@ public: itkTypeMacro(ConvertSensorToGeoPoint, otb::Application); /** Filters typedef */ - typedef otb::ForwardSensorModel ModelType; + typedef otb::RPCForwardTransform ModelType; typedef itk::Point PointType; private: @@ -111,7 +111,7 @@ private: // Instantiate a ForwardSensor Model ModelType::Pointer model = ModelType::New(); - model->SetImageGeometry(inImage->GetImageKeywordlist()); + model->SetMetadata(inImage->GetImageMetadata()); if (model->IsValidSensorModel() == false) { itkGenericExceptionMacro(<< "Unable to create a model"); diff --git a/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx b/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx index 244e43fea80185fc146ac472301233dd5bf4cab6..e3c84ce79957dd2edfff724cc8256fd9c7ced282 100644 --- a/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx +++ b/Modules/Applications/AppProjection/app/otbOrthoRectification.cxx @@ -565,7 +565,7 @@ private: // Set the output projection Ref m_ResampleFilter->SetInputProjectionRef(inImage->GetProjectionRef()); - m_ResampleFilter->SetInputKeywordList(inImage->GetImageKeywordlist()); + m_ResampleFilter->SetInputImageMetadata(&(inImage->GetImageMetadata())); m_ResampleFilter->SetOutputProjectionRef(m_OutputProjectionRef); // Check size diff --git a/Modules/Applications/AppProjection/app/otbSuperimpose.cxx b/Modules/Applications/AppProjection/app/otbSuperimpose.cxx index 469fd1a1f6cd34d1ffa19246c90c96bc93a843da..0148f79d0457c7bea257fd1065235d92c05bb3d4 100644 --- a/Modules/Applications/AppProjection/app/otbSuperimpose.cxx +++ b/Modules/Applications/AppProjection/app/otbSuperimpose.cxx @@ -242,11 +242,11 @@ private: } m_Resampler->SetDisplacementFieldSpacing(defSpacing); - // Setup transform through projRef and Keywordlist - m_Resampler->SetInputKeywordList(movingImage->GetImageKeywordlist()); + // Setup transform through projRef and ImageMetadata + m_Resampler->SetInputImageMetadata(&(movingImage->GetImageMetadata())); m_Resampler->SetInputProjectionRef(movingImage->GetProjectionRef()); - m_Resampler->SetOutputKeywordList(refImage->GetImageKeywordlist()); + m_Resampler->SetOutputImageMetadata(&(refImage->GetImageMetadata())); m_Resampler->SetOutputProjectionRef(refImage->GetProjectionRef()); m_Resampler->SetInput(movingImage); diff --git a/Modules/Applications/AppProjection/app/otbVectorDataReprojection.cxx b/Modules/Applications/AppProjection/app/otbVectorDataReprojection.cxx index 0b4656b1251e833deb40dec44b5e9b01b351bc69..c433582b63b53afc4f924f82f39e45f97cd8ace8 100644 --- a/Modules/Applications/AppProjection/app/otbVectorDataReprojection.cxx +++ b/Modules/Applications/AppProjection/app/otbVectorDataReprojection.cxx @@ -134,7 +134,7 @@ private: if (HasValue("in.kwl")) { FloatVectorImageType::Pointer inImage = GetParameterFloatVectorImage("in.kwl"); - m_GeometriesProjFilter->SetInputKeywordList(inImage->GetImageKeywordlist()); + m_GeometriesProjFilter->SetInputImageMetadata(&(inImage->GetImageMetadata())); // otbAppLogINFO(<<"kwl."<GetProjectionRef(); // ~ wkt if (m_OutputProjectionRef.empty()) { - m_GeometriesProjFilter->SetOutputKeywordList(outImage->GetImageKeywordlist()); // nec qd capteur + m_GeometriesProjFilter->SetOutputImageMetadata(&(outImage->GetImageMetadata())); } } else diff --git a/Modules/Applications/AppSegmentation/app/otbConnectedComponentSegmentation.cxx b/Modules/Applications/AppSegmentation/app/otbConnectedComponentSegmentation.cxx index b11319eda717b2f35e71e9d869cd5cc0206e55e4..4e6f5316263dfbbba33a98d6cb7904e902ce3625 100644 --- a/Modules/Applications/AppSegmentation/app/otbConnectedComponentSegmentation.cxx +++ b/Modules/Applications/AppSegmentation/app/otbConnectedComponentSegmentation.cxx @@ -176,7 +176,7 @@ private: // Reproject VectorData in image projection m_Vproj = VectorDataProjectionFilterType::New(); m_Vproj->SetInput(m_Connected->GetFilter()->GetOutputVectorData()); - m_Vproj->SetInputKeywordList(inputImage->GetImageKeywordlist()); + m_Vproj->SetInputImageMetadata(&inputImage->GetImageMetadata()); // m_Vproj->SetInputOrigin(inputImage->GetOrigin()); // m_Vproj->SetInputSpacing(inputImage->GetSignedSpacing()); diff --git a/Modules/Applications/AppStereo/app/otbGeneratePlyFile.cxx b/Modules/Applications/AppStereo/app/otbGeneratePlyFile.cxx index c7f79b7e2b5fc5c669053a2a6c8bb2f74caca1d1..83653248a201eed6cbb5e8d7ba0131774e66895f 100644 --- a/Modules/Applications/AppStereo/app/otbGeneratePlyFile.cxx +++ b/Modules/Applications/AppStereo/app/otbGeneratePlyFile.cxx @@ -165,7 +165,7 @@ private: } rsTransform->SetOutputProjectionRef(colorPtr->GetProjectionRef()); - rsTransform->SetOutputKeywordList(colorPtr->GetImageKeywordlist()); + rsTransform->SetOutputImageMetadata(&(colorPtr->GetImageMetadata())); rsTransform->InstantiateTransform(); toMap->InstantiateTransform(); diff --git a/Modules/Applications/AppStereo/app/otbStereoFramework.cxx b/Modules/Applications/AppStereo/app/otbStereoFramework.cxx index 6bd5d3377ca74223cbdde429258e6209a1641a58..f03397630379da9a4a7fb7c9fa934368a642246d 100644 --- a/Modules/Applications/AppStereo/app/otbStereoFramework.cxx +++ b/Modules/Applications/AppStereo/app/otbStereoFramework.cxx @@ -1141,11 +1141,11 @@ private: } // transform disparity into 3D map - m_MultiDisparityTo3DFilterList[i]->SetReferenceKeywordList(inleft->GetImageKeywordlist()); + m_MultiDisparityTo3DFilterList[i]->SetReferenceImageMetadata(&(inleft->GetImageMetadata())); m_MultiDisparityTo3DFilterList[i]->SetNumberOfMovingImages(1); m_MultiDisparityTo3DFilterList[i]->SetHorizontalDisparityMapInput(0, hDispOutput2); m_MultiDisparityTo3DFilterList[i]->SetVerticalDisparityMapInput(0, vDispOutput2); - m_MultiDisparityTo3DFilterList[i]->SetMovingKeywordList(0, inright->GetImageKeywordlist()); + m_MultiDisparityTo3DFilterList[i]->SetMovingImageMetadata(0, &(inright->GetImageMetadata())); m_MultiDisparityTo3DFilterList[i]->SetDisparityMaskInput(0, translatedMaskImage); m_MultiDisparityTo3DFilterList[i]->UpdateOutputInformation(); diff --git a/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx b/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx index 6a995450dff580101d7c13864a93eb6865d5aa3f..d069c8d9fca9a93d1f112c9758958b194f9fae2a 100644 --- a/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx +++ b/Modules/Applications/AppStereo/app/otbStereoRectificationGridGenerator.cxx @@ -303,7 +303,7 @@ private: m_DEMToImageGenerator->SetOutputSize(size); m_DEMToImageGenerator->SetOutputSpacing(spacing); m_DEMToImageGenerator->SetOutputProjectionRef(GetParameterImage("io.inleft")->GetProjectionRef()); - m_DEMToImageGenerator->SetOutputKeywordList(GetParameterImage("io.inleft")->GetImageKeywordlist()); + m_DEMToImageGenerator->SetOutputImageMetadata(&(GetParameterImage("io.inleft")->GetImageMetadata())); m_DEMToImageGenerator->AboveEllipsoidOn(); m_StatisticsFilter->SetInput(m_DEMToImageGenerator->GetOutput()); diff --git a/Modules/Applications/AppVectorUtils/app/otbVectorDataTransform.cxx b/Modules/Applications/AppVectorUtils/app/otbVectorDataTransform.cxx index 272b526252ac0acabf0b7ae229649707bdd0faac..79e45cb57bf9cad2cf7e39dfa4ea6ac33f49eb1b 100644 --- a/Modules/Applications/AppVectorUtils/app/otbVectorDataTransform.cxx +++ b/Modules/Applications/AppVectorUtils/app/otbVectorDataTransform.cxx @@ -148,7 +148,7 @@ private: m_VectorDataProj = VectorDataProjectionFilterType::New(); m_VectorDataProj->SetInput(vd); m_VectorDataProj->SetInputProjectionRef(vd->GetProjectionRef()); - m_VectorDataProj->SetOutputKeywordList(inImage->GetImageKeywordlist()); + m_VectorDataProj->SetOutputImageMetadata(&inImage->GetImageMetadata()); m_VectorDataProj->SetOutputProjectionRef(inImage->GetProjectionRef()); // Set up the transform @@ -174,7 +174,7 @@ private: m_ReverseVectorDataProj = VectorDataProjectionFilterType::New(); m_ReverseVectorDataProj->SetInput(m_TransformFilter->GetOutput()); m_ReverseVectorDataProj->SetOutputProjectionRef(vd->GetProjectionRef()); - m_ReverseVectorDataProj->SetInputKeywordList(inImage->GetImageKeywordlist()); + m_ReverseVectorDataProj->SetInputImageMetadata(&inImage->GetImageMetadata()); m_ReverseVectorDataProj->SetInputProjectionRef(inImage->GetProjectionRef()); // Set the output image diff --git a/Modules/Core/ImageBase/include/otbImageCommons.h b/Modules/Core/ImageBase/include/otbImageCommons.h index db863ea5bba4c6ccc109b2541ffc4919db923c84..3b2a7b7dd049cdbadd5f0cb7195ecabbba923d45 100644 --- a/Modules/Core/ImageBase/include/otbImageCommons.h +++ b/Modules/Core/ImageBase/include/otbImageCommons.h @@ -66,7 +66,7 @@ public: /** Returns true if a sensor geometric model is present */ bool HasSensorGeometry() const; -private: + /** Image metadata */ ImageMetadata m_Imd; }; diff --git a/Modules/Core/Metadata/include/otbCosmoImageMetadataInterface.h b/Modules/Core/Metadata/include/otbCosmoImageMetadataInterface.h index e82987bc211f8873d50d5501a6f1d90e8322a993..f68225fe95b8399d39c8ed4135ab6b672b04cfc0 100644 --- a/Modules/Core/Metadata/include/otbCosmoImageMetadataInterface.h +++ b/Modules/Core/Metadata/include/otbCosmoImageMetadataInterface.h @@ -22,7 +22,7 @@ #define otbCosmoImageMetadataInterface_h #include "otbSarImageMetadataInterface.h" - +#include "otbSARMetadata.h" namespace otb { diff --git a/Modules/Core/Metadata/include/otbGeometryMetadata.h b/Modules/Core/Metadata/include/otbGeometryMetadata.h index a7da75eecf3e9d086f455d833973e85103066a92..b2be4192455ba1b15fbac1401d81a0879dee26ea 100644 --- a/Modules/Core/Metadata/include/otbGeometryMetadata.h +++ b/Modules/Core/Metadata/include/otbGeometryMetadata.h @@ -116,6 +116,11 @@ struct OTBMetadata_EXPORT GCPParam */ struct OTBMetadata_EXPORT RPCParam { + // Constructors + RPCParam() = default; + RPCParam(const RPCParam &) = default; // CopyConstructible required for boost::any + RPCParam& operator=(RPCParam &) = default; //CopyAssignment optional for boost::any + // Offsets double LineOffset = 0.0; double SampleOffset = 0.0; diff --git a/Modules/Core/Metadata/include/otbImageMetadata.h b/Modules/Core/Metadata/include/otbImageMetadata.h index d0260ba571eca3a39d99465b9edd695bc0ed7e1d..c36809548ab91724c901ceca01bd475b1884c691 100644 --- a/Modules/Core/Metadata/include/otbImageMetadata.h +++ b/Modules/Core/Metadata/include/otbImageMetadata.h @@ -22,20 +22,15 @@ #define otbImageMetadata_h #include "otbGeometryMetadata.h" -#include "otbSARMetadata.h" #include "otbMetaDataKey.h" #include "OTBMetadataExport.h" #include "otbMacro.h" -#include "itkMath.h" #include #include #include -#include -#include #include #include -//~ #include namespace otb { @@ -104,34 +99,36 @@ public: DictType timeKeys, DictType extraKeys); - // TODO : iterators ? - - bool HasSensorGeometry() const; - - bool HasProjectedGeometry() const; - - size_t RemoveSensorGeometry(); + // -------------------- Geom utility function ---------------------------- - size_t RemoveProjectedGeometry(); + /** Read-only accessor to geometric keys */ + const boost::any & operator[](const MDGeom& key) const; const Projection::GCPParam & GetGCPParam() const; + std::string GetProjectedGeometry() const; + std::string GetProjectionWKT() const; - // -------------------- Geom utility function ---------------------------- - - /** Read-only accessor to geometric keys */ - const boost::any & operator[](const MDGeom& key) const; + std::string GetProjectionProj() const; /** Setter for geometric keys */ void Add(const MDGeom& key, const boost::any &value); /** Remove a key from the dictionary (even if the key is already missing) */ size_t Remove(const MDGeom& key); + + size_t RemoveSensorGeometry(); + + size_t RemoveProjectedGeometry(); /** Test if a key is available */ bool Has(const MDGeom& key) const; + bool HasSensorGeometry() const; + + bool HasProjectedGeometry() const; + // -------------------- Double utility function ---------------------------- /** Read-only accessor to numeric keys */ diff --git a/Modules/Core/Metadata/include/otbImageMetadataInterfaceBase.h b/Modules/Core/Metadata/include/otbImageMetadataInterfaceBase.h index ee549981068686b652bea3c8bc04e8c6ecd82df0..8fa2036234223434868f05904f7005a4cdc972d6 100644 --- a/Modules/Core/Metadata/include/otbImageMetadataInterfaceBase.h +++ b/Modules/Core/Metadata/include/otbImageMetadataInterfaceBase.h @@ -245,7 +245,7 @@ public: const std::string& Fetch(std::string key, const MetadataSupplierInterface & mds, const char *path, int band=-1); - const boost::any& FetchRPC(const MetadataSupplierInterface & mds); + const boost::any& FetchRPC(const MetadataSupplierInterface & mds, const double lineOffset = 0.0, const double sampleOffset = 0.0); /** Reads into the MetaDataDictionary to find an OSSIM ImageKeywordlist, * then translate it into ImageMetadata. diff --git a/Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h b/Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h index cf182bd279c27d8273f1ef588a320e2d2a30a64d..27420d84b7d6f3f1a976c00cc838fd00c42c07b4 100644 --- a/Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h +++ b/Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h @@ -23,6 +23,7 @@ #include "otbSarImageMetadataInterface.h" #include "otbXMLMetadataSupplier.h" +#include "otbSARMetadata.h" namespace otb { diff --git a/Modules/Core/Metadata/otb-module.cmake b/Modules/Core/Metadata/otb-module.cmake index 326c7532ff8cf04c68826954fcd710b0e18d2b32..759ad454aa33f322abc7684e206b5436cfa63f78 100644 --- a/Modules/Core/Metadata/otb-module.cmake +++ b/Modules/Core/Metadata/otb-module.cmake @@ -30,6 +30,7 @@ ENABLE_SHARED OTBITK OTBOSSIMAdapters OTBCommon + OTBGdalAdapters TEST_DEPENDS OTBTestKernel diff --git a/Modules/Core/Metadata/src/CMakeLists.txt b/Modules/Core/Metadata/src/CMakeLists.txt index e25cc1adfb7c4552fd4d82aa69bacf633886f2ae..7c10ac7ebe9af6dedff31da2c85660032a96cf21 100644 --- a/Modules/Core/Metadata/src/CMakeLists.txt +++ b/Modules/Core/Metadata/src/CMakeLists.txt @@ -85,7 +85,7 @@ target_link_libraries(OTBMetadata ${OTBCommon_LIBRARIES} ${OTBOSSIMAdapters_LIBRARIES} ${Boost_LIBRARIES} - + ${OTBGdalAdapters_LIBRARIES} ) otb_module_target(OTBMetadata) diff --git a/Modules/Core/Metadata/src/otbCosmoImageMetadataInterface.cxx b/Modules/Core/Metadata/src/otbCosmoImageMetadataInterface.cxx index 28c868a692c6cef2a64b8bb7206e018ab67f4fbe..77a19294ce4682adc8031572b35954f35e2ac550 100644 --- a/Modules/Core/Metadata/src/otbCosmoImageMetadataInterface.cxx +++ b/Modules/Core/Metadata/src/otbCosmoImageMetadataInterface.cxx @@ -357,8 +357,6 @@ std::vector CosmoImageMetadataInterface::getOrbits(const MetadataSupplier void CosmoImageMetadataInterface::Parse(const MetadataSupplierInterface & mds) { - assert(mds.GetNbBands() == this->m_Imd.Bands.size()); - // Check Mission Id, acquisition mode and product type Fetch(MDStr::Mission, mds, "MISSION_ID"); @@ -431,7 +429,6 @@ void CosmoImageMetadataInterface::Parse(const MetadataSupplierInterface & mds) sarParam.orbits = this->getOrbits(mds, reference_UTC); m_Imd.Bands[0].Add(MDGeom::SAR, sarParam); - } diff --git a/Modules/Core/Metadata/src/otbGeomMetadataSupplier.cxx b/Modules/Core/Metadata/src/otbGeomMetadataSupplier.cxx index 94c161052794ea266ab0f55c56d985ae73f38221..73c2b7215fc34d39cd6d034b59296e8186fa1613 100644 --- a/Modules/Core/Metadata/src/otbGeomMetadataSupplier.cxx +++ b/Modules/Core/Metadata/src/otbGeomMetadataSupplier.cxx @@ -65,11 +65,14 @@ int GeomMetadataSupplier::GetNbBands() const ret = this->GetMetadataValue("support_data.band_name_list", hasValue); boost::algorithm::trim_if(ret, boost::algorithm::is_any_of("\" ")); - if (!hasValue) - otbGenericExceptionMacro(MissingMetadataException,<<"Missing metadata 'support_data.band_name_list'") - std::vector ret_vect; - otb::Utils::ConvertStringToVector(ret, ret_vect, "band name"); - return ret_vect.size(); + if (hasValue) + { + std::vector ret_vect; + otb::Utils::ConvertStringToVector(ret, ret_vect, "band name"); + return ret_vect.size(); + } + + return 1; } bool GeomMetadataSupplier::FetchRPC(ImageMetadata & imd) @@ -123,9 +126,9 @@ bool GeomMetadataSupplier::FetchRPC(ImageMetadata & imd) coeff = this->GetAs(path.str()); } - boost::any any_rpcStruct = rpcStruct; - imd.Add(MDGeom::RPC, std::move(any_rpcStruct)); - auto toto = imd[MDGeom::RPC]; + imd.Add(MDGeom::RPC, rpcStruct); + assert(imd.Has(MDGeom::RPC)); + assert(rpcStruct == boost::any_cast(imd[MDGeom::RPC])); return true; } diff --git a/Modules/Core/Metadata/src/otbImageMetadata.cxx b/Modules/Core/Metadata/src/otbImageMetadata.cxx index a7e9306a80015e00aa7d795820aa1ee79c2d2e4a..402e1fde28732ebe06a160e056505e9ce9cebfe9 100644 --- a/Modules/Core/Metadata/src/otbImageMetadata.cxx +++ b/Modules/Core/Metadata/src/otbImageMetadata.cxx @@ -19,6 +19,8 @@ */ #include "otbImageMetadata.h" +#include "otbSpatialReference.h" + namespace otb { // ---------------------- [ImageMetadataBase] ------------------------------ @@ -43,37 +45,53 @@ ImageMetadataBase::ImageMetadataBase(DictType geometryKeys, ExtraKeys(std::move(extraKeys)) {} -bool ImageMetadataBase::HasSensorGeometry() const +// -------------------- Geom utility function ---------------------------- +const boost::any & ImageMetadataBase::operator[](const MDGeom& key) const { - return Has(MDGeom::RPC) || Has(MDGeom::SAR) || Has(MDGeom::SensorGeometry); + return GeometryKeys.at(key); } -bool ImageMetadataBase::HasProjectedGeometry() const +const Projection::GCPParam & ImageMetadataBase::GetGCPParam() const { - return Has(MDGeom::ProjectionWKT) || Has(MDGeom::ProjectionEPSG) || Has(MDGeom::ProjectionProj); + return boost::any_cast(GeometryKeys.at(MDGeom::GCP)); } -size_t ImageMetadataBase::RemoveSensorGeometry() +std::string ImageMetadataBase::GetProjectedGeometry() const { - return Remove(MDGeom::RPC) + Remove(MDGeom::SAR) + Remove(MDGeom::SensorGeometry); -} - -size_t ImageMetadataBase::RemoveProjectedGeometry() -{ - return Remove(MDGeom::ProjectionWKT) + Remove(MDGeom::ProjectionEPSG) + Remove(MDGeom::ProjectionProj); + if (this->Has(MDGeom::ProjectionWKT)) + { + // MDGeom::ProjectionWKT is a std::string stored as a boost::any + return boost::any_cast(GeometryKeys.at(MDGeom::ProjectionWKT)); + } + else if (this->Has(MDGeom::ProjectionEPSG)) + { + // MDGeom::ProjectionEPSG is an integer stored as a boost::any + return std::to_string(boost::any_cast(GeometryKeys.at(MDGeom::ProjectionEPSG))); + } + else if (this->Has(MDGeom::ProjectionProj)) + { + // MDGeom::ProjectionProj is a std::string stored as a boost::any + return boost::any_cast(GeometryKeys.at(MDGeom::ProjectionProj)); + } + else + return ""; } -const Projection::GCPParam & ImageMetadataBase::GetGCPParam() const +std::string ImageMetadataBase::GetProjectionWKT() const { - return boost::any_cast(GeometryKeys.at(MDGeom::GCP)); + auto theProj = this->GetProjectedGeometry(); + if (theProj.empty()) + return ""; + else + return SpatialReference::FromDescription(theProj).ToWkt(); } -std::string ImageMetadataBase::GetProjectionWKT() const +std::string ImageMetadataBase::GetProjectionProj() const { - auto projWKT = GeometryKeys.find(MDGeom::ProjectionWKT); - if (projWKT != GeometryKeys.end()) + auto proj = GeometryKeys.find(MDGeom::ProjectionProj); + if (proj != GeometryKeys.end()) { - return boost::any_cast(projWKT->second); + return boost::any_cast(proj->second); } else { @@ -81,12 +99,6 @@ std::string ImageMetadataBase::GetProjectionWKT() const } } -// -------------------- Geom utility function ---------------------------- -const boost::any & ImageMetadataBase::operator[](const MDGeom& key) const -{ - return GeometryKeys.at(key); -} - void ImageMetadataBase::Add(const MDGeom& key, const boost::any &value) { GeometryKeys[key] = value; @@ -97,11 +109,31 @@ size_t ImageMetadataBase::Remove(const MDGeom& key) return GeometryKeys.erase(key); } +size_t ImageMetadataBase::RemoveSensorGeometry() +{ + return Remove(MDGeom::RPC) + Remove(MDGeom::SAR) + Remove(MDGeom::SensorGeometry); +} + +size_t ImageMetadataBase::RemoveProjectedGeometry() +{ + return Remove(MDGeom::ProjectionWKT) + Remove(MDGeom::ProjectionEPSG) + Remove(MDGeom::ProjectionProj); +} + bool ImageMetadataBase::Has(const MDGeom& key) const { return (GeometryKeys.find(key) != GeometryKeys.end()); } +bool ImageMetadataBase::HasSensorGeometry() const +{ + return Has(MDGeom::RPC) || Has(MDGeom::SAR) || Has(MDGeom::SensorGeometry); +} + +bool ImageMetadataBase::HasProjectedGeometry() const +{ + return Has(MDGeom::ProjectionWKT) || Has(MDGeom::ProjectionEPSG) || Has(MDGeom::ProjectionProj); +} + // -------------------- Double utility function ---------------------------- const double & ImageMetadataBase::operator[](const MDNum& key) const @@ -468,7 +500,7 @@ void ImageMetadata::Merge(const ImageMetadata& imd) { ImageMetadataBase::Fuse(imd); - for (unsigned int i = 0; i < std::min(Bands.size(), imd.Bands.size()); i++) + for (unsigned int i = 0; i < std::min(Bands.size(), imd.Bands.size()); ++i) { Bands[i].Fuse(imd.Bands[i]); } diff --git a/Modules/Core/Metadata/src/otbImageMetadataInterfaceBase.cxx b/Modules/Core/Metadata/src/otbImageMetadataInterfaceBase.cxx index 76d65f619e85a082794fe2d832ac3cb6fb3756bb..18f806e976b2298f4264518d1a7d69c05cbeb249 100644 --- a/Modules/Core/Metadata/src/otbImageMetadataInterfaceBase.cxx +++ b/Modules/Core/Metadata/src/otbImageMetadataInterfaceBase.cxx @@ -689,8 +689,8 @@ ImageMetadataInterfaceBase::Fetch( return m_Imd[key]; } -const boost::any& ImageMetadataInterfaceBase::FetchRPC( - const MetadataSupplierInterface & mds) +const boost::any& ImageMetadataInterfaceBase::FetchRPC(const MetadataSupplierInterface & mds, + const double lineOffset, const double sampleOffset) { Projection::RPCParam rpcStruct; @@ -723,8 +723,8 @@ const boost::any& ImageMetadataInterfaceBase::FetchRPC( } }; - rpcStruct.LineOffset = GetMetadataWithoutUnit("RPC/LINE_OFF", mds); - rpcStruct.SampleOffset = GetMetadataWithoutUnit("RPC/SAMP_OFF", mds); + rpcStruct.LineOffset = GetMetadataWithoutUnit("RPC/LINE_OFF", mds) + lineOffset; + rpcStruct.SampleOffset = GetMetadataWithoutUnit("RPC/SAMP_OFF", mds) + sampleOffset; rpcStruct.LatOffset = GetMetadataWithoutUnit("RPC/LAT_OFF", mds); rpcStruct.LonOffset = GetMetadataWithoutUnit("RPC/LONG_OFF", mds); rpcStruct.HeightOffset = GetMetadataWithoutUnit("RPC/HEIGHT_OFF", mds); @@ -750,6 +750,8 @@ const boost::any& ImageMetadataInterfaceBase::FetchRPC( std::copy(coeffs.begin(), coeffs.end(), rpcStruct.SampleDen); m_Imd.Add(MDGeom::RPC, rpcStruct); + assert(m_Imd.Has(MDGeom::RPC)); + assert(rpcStruct == boost::any_cast(m_Imd[MDGeom::RPC])); return m_Imd[MDGeom::RPC]; } diff --git a/Modules/Core/Metadata/src/otbPleiadesImageMetadataInterface.cxx b/Modules/Core/Metadata/src/otbPleiadesImageMetadataInterface.cxx index f6722defbea9a3215edbd5473ee35ccba9fdc016..0de9ab58b1c0dffb53d4aa76bb55a926b9ccfc94 100644 --- a/Modules/Core/Metadata/src/otbPleiadesImageMetadataInterface.cxx +++ b/Modules/Core/Metadata/src/otbPleiadesImageMetadataInterface.cxx @@ -2232,7 +2232,7 @@ void PleiadesImageMetadataInterface::Parse(const MetadataSupplierInterface & mds // fill RPC model if (m_Imd[MDStr::GeometricLevel] == "SENSOR") { - FetchRPC(mds); + FetchRPC(mds, -0.5, -0.5); } } // Geom case diff --git a/Modules/Core/Metadata/src/otbRadarsat2ImageMetadataInterface.cxx b/Modules/Core/Metadata/src/otbRadarsat2ImageMetadataInterface.cxx index 4b6454dc7a48edee2c28cfb31d676e80562a0bb5..fb188400175e1572f8c03926f683621b73aedcb8 100644 --- a/Modules/Core/Metadata/src/otbRadarsat2ImageMetadataInterface.cxx +++ b/Modules/Core/Metadata/src/otbRadarsat2ImageMetadataInterface.cxx @@ -21,6 +21,7 @@ #include "otbSarImageMetadataInterface.h" #include "otbRadarsat2ImageMetadataInterface.h" +#include "otbSARMetadata.h" #include "otbMacro.h" #include "itkMetaDataObject.h" @@ -245,8 +246,6 @@ Radarsat2ImageMetadataInterface::UIntVectorType Radarsat2ImageMetadataInterface: void Radarsat2ImageMetadataInterface::Parse(const MetadataSupplierInterface & mds) { - assert(mds.GetNbBands() == this->m_Imd.Bands.size()); - // Metadata read by GDAL Fetch(MDTime::AcquisitionStartTime, mds, "ACQUISITION_START_TIME"); // Fetch(MDTime::AcquisitionStopTime, mds, "PROCESSING_TIME"); @@ -284,6 +283,8 @@ void Radarsat2ImageMetadataInterface::Parse(const MetadataSupplierInterface & md m_Imd.Add(MDNum::CenterIncidenceAngle, this->GetCenterIncidenceAngle()); + assert(mds.GetNbBands() == this->m_Imd.Bands.size()); + SARParam sarParam; for (int bandId = 0 ; bandId < mds.GetNbBands() ; ++bandId) { @@ -294,4 +295,4 @@ void Radarsat2ImageMetadataInterface::Parse(const MetadataSupplierInterface & md } -} // end namespace otb \ No newline at end of file +} // end namespace otb diff --git a/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx b/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx index dc36ca33234a5ef3f69601395e06be342be0f822..0ee576b3f23bb6afe86586d8cb76e4b8e604f982 100644 --- a/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx +++ b/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx @@ -526,7 +526,6 @@ double Sentinel1ImageMetadataInterface::getBandTerrainHeight(const XMLMetadataSu void Sentinel1ImageMetadataInterface::Parse(const MetadataSupplierInterface & mds) { - assert(mds.GetNbBands() == this->m_Imd.Bands.size()); // Metadata read by GDAL Fetch(MDTime::AcquisitionStartTime, mds, "ACQUISITION_START_TIME"); Fetch(MDTime::AcquisitionStopTime, mds, "ACQUISITION_STOP_TIME"); @@ -555,6 +554,7 @@ void Sentinel1ImageMetadataInterface::Parse(const MetadataSupplierInterface & md ManifestMS.GetFirstAs("xfdu:XFDU.metadataSection.metadataObject_#.metadataWrap.xmlData.safe:acquisitionPeriod.safe:startTime")); } + assert(mds.GetNbBands() == this->m_Imd.Bands.size()); // Band metadata for (int bandId = 0 ; bandId < mds.GetNbBands() ; ++bandId) { @@ -599,6 +599,7 @@ void Sentinel1ImageMetadataInterface::Parse(const MetadataSupplierInterface & md if (NoiseFilePath.empty()) otbGenericExceptionMacro(MissingMetadataException,<<"Missing Noise file for band '"<GetNoiseVector(NoiseMS); m_Imd.Bands[bandId].Add(MDGeom::SAR, sarParam); } diff --git a/Modules/Core/Metadata/src/otbSpot6ImageMetadataInterface.cxx b/Modules/Core/Metadata/src/otbSpot6ImageMetadataInterface.cxx index 7633e3105e68651f4e13a913288268fadfc3c348..440a1ae9cf8186512dbb00ffdb340617ba788a11 100644 --- a/Modules/Core/Metadata/src/otbSpot6ImageMetadataInterface.cxx +++ b/Modules/Core/Metadata/src/otbSpot6ImageMetadataInterface.cxx @@ -1254,7 +1254,6 @@ Spot6ImageMetadataInterface::WavelengthSpectralBandVectorType Spot6ImageMetadata return wavelengthSpectralBand; } - void Spot6ImageMetadataInterface::FetchSpectralSensitivity(const std::string & sensorId) { std::unordered_map> BandNameToSpectralSensitivityTable; diff --git a/Modules/Core/Metadata/src/otbTerraSarImageMetadataInterface.cxx b/Modules/Core/Metadata/src/otbTerraSarImageMetadataInterface.cxx index 753694d875b2b2228ddc69985dd8df142ccb62d3..7ffc3af854a703ccc341f42c3a6264e5a47de90c 100644 --- a/Modules/Core/Metadata/src/otbTerraSarImageMetadataInterface.cxx +++ b/Modules/Core/Metadata/src/otbTerraSarImageMetadataInterface.cxx @@ -27,7 +27,7 @@ #include "itkMetaDataObject.h" #include "otbImageKeywordlist.h" #include "otbXMLMetadataSupplier.h" - +#include "otbSARMetadata.h" #include @@ -1248,8 +1248,6 @@ void TerraSarImageMetadataInterface::PrintSelf(std::ostream& os, itk::Indent ind void TerraSarImageMetadataInterface::Parse(const MetadataSupplierInterface & mds) { - assert(mds.GetNbBands() == this->m_Imd.Bands.size()); - // Metadata read by GDAL Fetch(MDNum::LineSpacing, mds, "ROW_SPACING"); Fetch(MDStr::Mode, mds, "IMAGING_MODE"); @@ -1286,6 +1284,8 @@ void TerraSarImageMetadataInterface::Parse(const MetadataSupplierInterface & mds } + assert(mds.GetNbBands() == this->m_Imd.Bands.size()); + SARParam sarParam; for (int bandId = 0 ; bandId < mds.GetNbBands() ; ++bandId) { diff --git a/Modules/Core/Transform/include/otbCompositeTransform.hxx b/Modules/Core/Transform/include/otbCompositeTransform.hxx index 2b3e3dd09cd748660323018267a8a62de9d9b83d..ac6fa48320d93f9fe8257acc45bb9c4b11a21131 100644 --- a/Modules/Core/Transform/include/otbCompositeTransform.hxx +++ b/Modules/Core/Transform/include/otbCompositeTransform.hxx @@ -24,8 +24,6 @@ #include "otbCompositeTransform.h" #include "otbGenericMapProjection.h" -#include "otbForwardSensorModel.h" -#include "otbInverseSensorModel.h" #include "itkIdentityTransform.h" namespace otb diff --git a/Modules/Core/Transform/include/otbForwardSensorModel.hxx b/Modules/Core/Transform/include/otbForwardSensorModel.hxx deleted file mode 100644 index b2417e68b5c79832c60a0e5c5c67bfff72748f3c..0000000000000000000000000000000000000000 --- a/Modules/Core/Transform/include/otbForwardSensorModel.hxx +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) - * - * This file is part of Orfeo Toolbox - * - * https://www.orfeo-toolbox.org/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef otbForwardSensorModel_hxx -#define otbForwardSensorModel_hxx - -#include "otbForwardSensorModel.h" -#include "otbMacro.h" - -namespace otb -{ - -template -ForwardSensorModel::ForwardSensorModel() -{ -} - -template -ForwardSensorModel::~ForwardSensorModel() -{ -} - -template -typename ForwardSensorModel::OutputPointType -ForwardSensorModel::TransformPoint(const InputPointType& point) const -{ - double x = point[0]; - double y = point[1]; - - double lon, lat, h; - - if (InputPointType::PointDimension == 3) - { - double z = point[2]; - - this->m_Model->ForwardTransformPoint(x, y, z, lon, lat, h); - } - else - { - this->m_Model->ForwardTransformPoint(x, y, lon, lat, h); - } - - OutputPointType outputPoint; - outputPoint[0] = lon; - outputPoint[1] = lat; - - if (OutputPointType::PointDimension == 3) - { - outputPoint[2] = h; - } - return outputPoint; -} - -template -void ForwardSensorModel::PrintSelf(std::ostream& os, itk::Indent indent) const -{ - Superclass::PrintSelf(os, indent); -} - -} // namespace otb - -#endif diff --git a/Modules/Core/Transform/include/otbGenericRSTransform.h b/Modules/Core/Transform/include/otbGenericRSTransform.h index e0ac8ba8eb0a3eda5e76c894ec9a3b6f5bb50c3e..89cafc1b317c7527eb11e01cb48606eb1cfeb14e 100644 --- a/Modules/Core/Transform/include/otbGenericRSTransform.h +++ b/Modules/Core/Transform/include/otbGenericRSTransform.h @@ -22,6 +22,7 @@ #define otbGenericRSTransform_h #include "otbCompositeTransform.h" +#include "otbImageMetadata.h" #include namespace otb @@ -100,46 +101,26 @@ public: itkSetStringMacro(OutputProjectionRef); itkGetStringMacro(OutputProjectionRef); - /** Set/Get Dictionary - * \deprecated - */ - const itk::MetaDataDictionary& GetInputDictionary() const + /** Set/Get ImageMetadata*/ + const ImageMetadata* GetInputImageMetadata() const { - return m_InputDictionary; + return m_InputImd; } - void SetInputDictionary(const itk::MetaDataDictionary& dictionary) + void SetInputImageMetadata(const ImageMetadata* imd) { - m_InputDictionary = dictionary; + m_InputImd = imd; this->Modified(); } - const itk::MetaDataDictionary& GetOutputDictionary() const + const ImageMetadata* GetOutputImageMetadata() const { - return m_OutputDictionary; + return m_OutputImd; } - void SetOutputDictionary(const itk::MetaDataDictionary& dictionary) + void SetOutputImageMetadata(const ImageMetadata* imd) { - m_OutputDictionary = dictionary; - this->Modified(); - } - - /** Set/Get Keywordlist - * \deprecated - */ - - itkGetMacro(InputKeywordList, ImageKeywordlist); - void SetInputKeywordList(const ImageKeywordlist& kwl) - { - this->m_InputKeywordList = kwl; - this->Modified(); - } - - itkGetMacro(OutputKeywordList, ImageKeywordlist); - void SetOutputKeywordList(const ImageKeywordlist& kwl) - { - this->m_OutputKeywordList = kwl; + m_OutputImd = imd; this->Modified(); } @@ -211,11 +192,8 @@ private: GenericRSTransform(const Self&) = delete; void operator=(const Self&) = delete; - ImageKeywordlist m_InputKeywordList; - ImageKeywordlist m_OutputKeywordList; - - itk::MetaDataDictionary m_InputDictionary; - itk::MetaDataDictionary m_OutputDictionary; + const ImageMetadata* m_InputImd; + const ImageMetadata* m_OutputImd; std::string m_InputProjectionRef; std::string m_OutputProjectionRef; diff --git a/Modules/Core/Transform/include/otbGenericRSTransform.hxx b/Modules/Core/Transform/include/otbGenericRSTransform.hxx index b1794715ff7f577ab8ee28c27e5133ba6010197e..cdbd9ccd3639e87f61a27cd414bfe88c642b4b80 100644 --- a/Modules/Core/Transform/include/otbGenericRSTransform.hxx +++ b/Modules/Core/Transform/include/otbGenericRSTransform.hxx @@ -23,8 +23,8 @@ #include "otbGenericRSTransform.h" #include "otbMacro.h" -#include "otbMetaDataKey.h" -#include "itkMetaDataObject.h" +#include "otbRPCForwardTransform.h" +#include "otbRPCInverseTransform.h" #include "otbSpatialReference.h" @@ -38,13 +38,13 @@ GenericRSTransform::GenericRST { m_InputProjectionRef.clear(); m_OutputProjectionRef.clear(); - m_InputKeywordList.Clear(); - m_OutputKeywordList.Clear(); m_InputSpacing.Fill(1); m_InputOrigin.Fill(0); m_OutputSpacing.Fill(1); m_OutputOrigin.Fill(0); + m_InputImd = nullptr; + m_OutputImd = nullptr; m_Transform = nullptr; m_InputTransform = nullptr; m_OutputTransform = nullptr; @@ -73,21 +73,17 @@ void GenericRSTransform::Insta { m_Transform = TransformType::New(); - if (m_InputKeywordList.GetSize() == 0) + if (m_InputProjectionRef.empty() && m_InputImd != nullptr && m_InputImd->HasProjectedGeometry()) { - itk::ExposeMetaData(m_InputDictionary, MetaDataKey::OSSIMKeywordlistKey, m_InputKeywordList); - } - if (m_InputProjectionRef.empty()) - { - itk::ExposeMetaData(m_InputDictionary, MetaDataKey::ProjectionRefKey, m_InputProjectionRef); + m_InputProjectionRef = m_InputImd->GetProjectionWKT(); } otbMsgDevMacro(<< "Information to instantiate transform: "); otbMsgDevMacro(<< " * Input Origin: " << m_InputOrigin); otbMsgDevMacro(<< " * Input Spacing: " << m_InputSpacing); - otbMsgDevMacro(<< " * Input keyword list: " << ((m_InputKeywordList.GetSize() == 0) ? "Empty" : "Full")); + otbMsgDevMacro(<< " * Input metadata: " << ((m_InputImd == nullptr) ? "Empty" : "Full")); otbMsgDevMacro(<< " * Input projection: " << m_InputProjectionRef); - otbMsgDevMacro(<< " * Output keyword list: " << ((m_OutputKeywordList.GetSize() == 0) ? "Empty" : "Full")); + otbMsgDevMacro(<< " * Output metadata: " << ((m_OutputImd == nullptr) ? "Empty" : "Full")); otbMsgDevMacro(<< " * Output projection: " << m_OutputProjectionRef); otbMsgDevMacro(<< " * Output Origin: " << m_OutputOrigin); otbMsgDevMacro(<< " * Output Spacing: " << m_OutputSpacing); @@ -120,19 +116,19 @@ void GenericRSTransform::Insta } } - // If not, try to make a sensor model - if ((m_InputTransform.IsNull()) && (m_InputKeywordList.GetSize() > 0)) + // If not, try to make a RPC sensor model + if ((m_InputTransform.IsNull()) && (m_InputImd != nullptr) && (m_InputImd->Has(MDGeom::RPC))) { - typedef otb::ForwardSensorModel ForwardSensorModelType; - typename ForwardSensorModelType::Pointer sensorModel = ForwardSensorModelType::New(); + typedef otb::RPCForwardTransform RPCForwardTransformType; + typename RPCForwardTransformType::Pointer sensorModel = RPCForwardTransformType::New(); - sensorModel->SetImageGeometry(m_InputKeywordList); + sensorModel->SetMetadata(*m_InputImd); if (sensorModel->IsValidSensorModel()) { m_InputTransform = sensorModel.GetPointer(); inputTransformIsSensor = true; - otbMsgDevMacro(<< "Input projection set to sensor model."); + otbMsgDevMacro(<< "Input projection set to RPC model."); } } @@ -152,19 +148,19 @@ void GenericRSTransform::Insta } } - // If not, try to make a sensor model - if ((m_OutputTransform.IsNull()) && (m_OutputKeywordList.GetSize() > 0)) + // If not, try to make a RPC sensor model + if ((m_OutputTransform.IsNull()) && (m_OutputImd != nullptr) && (m_OutputImd->Has(MDGeom::RPC))) { - typedef otb::InverseSensorModel InverseSensorModelType; - typename InverseSensorModelType::Pointer sensorModel = InverseSensorModelType::New(); + typedef otb::RPCInverseTransform RPCInverseTransformType; + typename RPCInverseTransformType::Pointer sensorModel = RPCInverseTransformType::New(); - sensorModel->SetImageGeometry(m_OutputKeywordList); + sensorModel->SetMetadata(*m_OutputImd); if (sensorModel->IsValidSensorModel()) { m_OutputTransform = sensorModel.GetPointer(); outputTransformIsSensor = true; - otbMsgDevMacro(<< "Output projection set to sensor model"); + otbMsgDevMacro(<< "Output projection set to RPC model"); } } @@ -178,6 +174,7 @@ void GenericRSTransform::Insta } m_InputTransform = itk::IdentityTransform::New(); + otbMsgDevMacro(<< "Input projection set to identity"); } @@ -257,13 +254,9 @@ bool GenericRSTransform::GetIn inverseTransform->SetInputProjectionRef(m_OutputProjectionRef); inverseTransform->SetOutputProjectionRef(m_InputProjectionRef); - // Switch keywordlists - inverseTransform->SetInputKeywordList(m_OutputKeywordList); - inverseTransform->SetOutputKeywordList(m_InputKeywordList); - - // Switch dictionnaries - inverseTransform->SetInputDictionary(m_OutputDictionary); - inverseTransform->SetOutputDictionary(m_InputDictionary); + // Switch ImageMetadatas + inverseTransform->SetInputImageMetadata(m_OutputImd); + inverseTransform->SetOutputImageMetadata(m_InputImd); // Switch spacings inverseTransform->SetInputSpacing(m_OutputSpacing); diff --git a/Modules/Core/Transform/include/otbImageToGenericRSOutputParameters.h b/Modules/Core/Transform/include/otbImageToGenericRSOutputParameters.h index 1a17eac31c9222d9f6a7ab77b27a38d0bb90a4d7..869ca3776a87d28a3e4873b26d1ed2d5fed7bbfe 100644 --- a/Modules/Core/Transform/include/otbImageToGenericRSOutputParameters.h +++ b/Modules/Core/Transform/include/otbImageToGenericRSOutputParameters.h @@ -23,6 +23,7 @@ #include "itkObject.h" #include "otbGenericRSTransform.h" +#include "otbImageMetadata.h" #include namespace otb @@ -148,18 +149,17 @@ public: return m_Transform->GetOutputProjectionRef(); } - /** Set/Get Input Keywordlist - * \deprecated + /** Set/Get Input ImageMetadata */ - void SetInputKeywordList(const ImageKeywordlist& kwl) + void SetInputImageMetadata(ImageMetadata* imd) { - m_Transform->SetOutputKeywordList(kwl); + m_Transform->SetOutputImageMetadata(imd); this->Modified(); } - const ImageKeywordlist GetInputKeywordList() + const ImageMetadata* GetInputImageMetadata() { - return m_Transform->GetOutputKeywordList(); + return m_Transform->GetOutputImageMetadata(); } /** Method to trigger the output parameters */ diff --git a/Modules/Core/Transform/include/otbImageToGenericRSOutputParameters.hxx b/Modules/Core/Transform/include/otbImageToGenericRSOutputParameters.hxx index 896dab248dcb7f6de35836582fd29c8b467d059b..caece7a40cbfb4abb001e086940d005c0e9eab09 100644 --- a/Modules/Core/Transform/include/otbImageToGenericRSOutputParameters.hxx +++ b/Modules/Core/Transform/include/otbImageToGenericRSOutputParameters.hxx @@ -48,7 +48,7 @@ void ImageToGenericRSOutputParameters::Compute() if (m_Input.IsNull()) itkExceptionMacro(<< "The input is null , please set a non null input image"); - if (m_Input->GetProjectionRef().empty() && m_Input->GetImageKeywordlist().GetSize() == 0) + if (!m_Input->GetImageMetadata().HasSensorGeometry() && !m_Input->GetImageMetadata().HasProjectedGeometry()) itkExceptionMacro(<< "No information in the metadata, please set an image with non empty metadata"); // First Call to UpdateTransform : Initialize with the input image @@ -73,9 +73,8 @@ void ImageToGenericRSOutputParameters::Compute() template void ImageToGenericRSOutputParameters::UpdateTransform() { - m_Transform->SetOutputDictionary(this->GetInput()->GetMetaDataDictionary()); + m_Transform->SetOutputImageMetadata(&(this->GetInput()->GetImageMetadata())); m_Transform->SetOutputProjectionRef(this->GetInput()->GetProjectionRef()); - m_Transform->SetOutputKeywordList(this->GetInput()->GetImageKeywordlist()); m_Transform->InstantiateTransform(); } diff --git a/Modules/Core/Transform/include/otbInverseSensorModel.h b/Modules/Core/Transform/include/otbInverseSensorModel.h deleted file mode 100644 index fa2591f91486548d92619b3eed20d3bb062534f9..0000000000000000000000000000000000000000 --- a/Modules/Core/Transform/include/otbInverseSensorModel.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) - * - * This file is part of Orfeo Toolbox - * - * https://www.orfeo-toolbox.org/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef otbInverseSensorModel_h -#define otbInverseSensorModel_h - -#include "otbSensorModelBase.h" - -#include "itkMacro.h" -#include "itkObject.h" - -namespace otb -{ - -/** \class InverseSensorModel - * - * \brief Class for inverse sensor models - * - * Based on ossimProjectionFactoryRegistry and ossimProjection methods. - * It takes as input a world point and computes the index position of the - * corresponding point in the input image. - * (lon, lat, h) -> (i, j). - * Notice that the elevation h is optional. - * - * \ingroup Transform - * \ingroup Projection - * - * \ingroup OTBTransform - */ -template -class ITK_EXPORT InverseSensorModel : public SensorModelBase -{ - -public: - /** Standard class typedefs. */ - typedef InverseSensorModel Self; - typedef SensorModelBase Superclass; - typedef itk::SmartPointer Pointer; - typedef itk::SmartPointer ConstPointer; - - typedef typename Superclass::InputPointType InputPointType; - typedef typename Superclass::OutputPointType OutputPointType; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(InverseSensorModel, SensorModelBase); - - itkStaticConstMacro(InputSpaceDimension, unsigned int, NInputDimensions); - itkStaticConstMacro(OutputSpaceDimension, unsigned int, NOutputDimensions); - - // Transform of geographic point in image sensor index - OutputPointType TransformPoint(const InputPointType& point) const override; - // Transform of geographic point in image sensor index -- Backward Compatibility - // OutputPointType TransformPoint(const InputPointType &point, double height) const; - -protected: - InverseSensorModel(); - ~InverseSensorModel() override; - - /** PrintSelf method */ - void PrintSelf(std::ostream& os, itk::Indent indent) const override; - -private: - InverseSensorModel(const Self&) = delete; - void operator=(const Self&) = delete; -}; - -} // namespace otb - -#ifndef OTB_MANUAL_INSTANTIATION -#include "otbInverseSensorModel.hxx" -#endif - -#endif diff --git a/Modules/Core/Transform/include/otbInverseSensorModel.hxx b/Modules/Core/Transform/include/otbInverseSensorModel.hxx deleted file mode 100644 index dedfc59e6c881ede2ba35459b2cefc5b5ba686eb..0000000000000000000000000000000000000000 --- a/Modules/Core/Transform/include/otbInverseSensorModel.hxx +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) - * - * This file is part of Orfeo Toolbox - * - * https://www.orfeo-toolbox.org/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef otbInverseSensorModel_hxx -#define otbInverseSensorModel_hxx - -#include "otbInverseSensorModel.h" -#include "otbMacro.h" - -namespace otb -{ - -template -InverseSensorModel::InverseSensorModel() -{ -} - -template -InverseSensorModel::~InverseSensorModel() -{ -} - -template -typename InverseSensorModel::OutputPointType -InverseSensorModel::TransformPoint(const InputPointType& point) const -{ - double lon = point[0]; - double lat = point[1]; - double x, y, z; - - if (InputPointType::PointDimension == 3) - { - double h = point[2]; - - this->m_Model->InverseTransformPoint(lon, lat, h, x, y, z); - } - else - { - this->m_Model->InverseTransformPoint(lon, lat, x, y, z); - } - - OutputPointType outputPoint; - - outputPoint[0] = x; - outputPoint[1] = y; - - if (OutputPointType::PointDimension == 3) - { - outputPoint[2] = z; - } - - return outputPoint; -} - - -template -void InverseSensorModel::PrintSelf(std::ostream& os, itk::Indent indent) const -{ - Superclass::PrintSelf(os, indent); -} - -} // namespace otb - -#endif diff --git a/Modules/Core/Transform/include/otbForwardSensorModel.h b/Modules/Core/Transform/include/otbRPCForwardTransform.h similarity index 51% rename from Modules/Core/Transform/include/otbForwardSensorModel.h rename to Modules/Core/Transform/include/otbRPCForwardTransform.h index 0165810e3482c8325809996b39545bd355adf30d..05b058fd2f829d14f0e213acc65b575365a46b4b 100644 --- a/Modules/Core/Transform/include/otbForwardSensorModel.h +++ b/Modules/Core/Transform/include/otbRPCForwardTransform.h @@ -18,74 +18,64 @@ * limitations under the License. */ +#ifndef otbRPCForwardTransform_h +#define otbRPCForwardTransform_h -#ifndef otbForwardSensorModel_h -#define otbForwardSensorModel_h - -#include "otbSensorModelBase.h" -#include "itkMacro.h" -#include "itkObject.h" +#include "otbRPCTransformBase.h" namespace otb { - -/** \class ForwardSensorModel - - * \brief Class for direct sensor models - * - * Based on ossimProjectionFactoryRegistry and ossimProjection methods. - * It takes as input an index and computes the world coordinates. - * (i, j, h) -> (lon, lat). - * Notice that the elevation h is optional. +/** \class RPCForwardTransform + * \brief Projection class based on the RPC method. * - * \ingroup Transform - * \ingroup Projection + * This is a projection class, based on a RPC sensor model. This + * class computes a forward transformation of a point in the sensor + * geometry (i, j) to a geographic point in (lat, long) * * \ingroup OTBTransform */ - -template -class ITK_EXPORT ForwardSensorModel : public SensorModelBase +template +class ITK_EXPORT RPCForwardTransform : public RPCTransformBase { - public: - /** Standard class typedefs. */ - typedef ForwardSensorModel Self; - typedef SensorModelBase Superclass; - typedef itk::SmartPointer Pointer; - typedef itk::SmartPointer ConstPointer; - - typedef typename Superclass::InputPointType InputPointType; - typedef typename Superclass::OutputPointType OutputPointType; + /** @name Standard class type definitions */ + //@{ + using Self = RPCForwardTransform; + using Superclass = RPCTransformBase; + using Pointer = itk::SmartPointer; + using ConstPointer = itk::SmartPointer ; + + typedef itk::Point InputPointType; + typedef itk::Point OutputPointType; + using PixelType =TScalarType; + //@} /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ - itkTypeMacro(ForwardSensorModel, SensorModelBase); + itkTypeMacro(RPCForwardTransform, RPCTransformBase); itkStaticConstMacro(InputSpaceDimension, unsigned int, NInputDimensions); itkStaticConstMacro(OutputSpaceDimension, unsigned int, NOutputDimensions); - /** Compute the world coordinates. */ + /** Method to transform a point. */ OutputPointType TransformPoint(const InputPointType& point) const override; protected: - ForwardSensorModel(); - ~ForwardSensorModel() override; - - /** PrintSelf method */ + RPCForwardTransform() = default; + ~RPCForwardTransform() = default; void PrintSelf(std::ostream& os, itk::Indent indent) const override; private: - ForwardSensorModel(const Self&) = delete; + RPCForwardTransform(const Self&) = delete; void operator=(const Self&) = delete; }; -} // namespace otb +} #ifndef OTB_MANUAL_INSTANTIATION -#include "otbForwardSensorModel.hxx" +#include "otbRPCForwardTransform.hxx" #endif #endif diff --git a/Modules/Core/Transform/include/otbRPCForwardTransform.hxx b/Modules/Core/Transform/include/otbRPCForwardTransform.hxx new file mode 100644 index 0000000000000000000000000000000000000000..c780f2f8350c7bb83e8c2118f1e29577a8e7e421 --- /dev/null +++ b/Modules/Core/Transform/include/otbRPCForwardTransform.hxx @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef otbRPCForwardTransform_hxx +#define otbRPCForwardTransform_hxx + +#include "otbRPCForwardTransform.h" + +namespace otb +{ + +template +typename RPCForwardTransform::OutputPointType +RPCForwardTransform::TransformPoint(const InputPointType& point) const +{ + GDALRPCTransformer::PointType zePoint; + zePoint[0] = static_cast(point[0]); + zePoint[1] = static_cast(point[1]); + if (NInputDimensions > 2) + zePoint[2] = static_cast(point[2]); + else + zePoint[2] = 0.0; + + zePoint = this->m_Transformer->ForwardTransform(zePoint); + + OutputPointType pOut; + pOut[0] = static_cast(zePoint[0]); + pOut[1] = static_cast(zePoint[1]); + if (NOutputDimensions > 2) + pOut[2] = static_cast(zePoint[2]); + return pOut; +} + +/** + * PrintSelf method + */ +template +void RPCForwardTransform::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "Transformation direction: Forward" << std::endl; +} + +} + +#endif diff --git a/Modules/Core/Transform/include/otbRPCInverseTransform.h b/Modules/Core/Transform/include/otbRPCInverseTransform.h new file mode 100644 index 0000000000000000000000000000000000000000..c05ea1b32c5c117b3ca1e152be016500fc05004f --- /dev/null +++ b/Modules/Core/Transform/include/otbRPCInverseTransform.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef otbRPCInverseTransform_h +#define otbRPCInverseTransform_h + +#include "otbRPCTransformBase.h" + +namespace otb +{ +/** \class RPCInverseTransform + * \brief Projection class based on the RPC method. + * + * This is a projection class, based on a RPC sensor model. This + * class computes an inverse transformation of a a geographic + * point in (lat, long) to a point in the sensor geometry (i, j). + * + * \ingroup OTBTransform + */ +template +class ITK_EXPORT RPCInverseTransform : public RPCTransformBase +{ +public: + /** @name Standard class type definitions */ + //@{ + using Self = RPCInverseTransform; + using Superclass = RPCTransformBase; + using Pointer = itk::SmartPointer; + using ConstPointer = itk::SmartPointer ; + + typedef itk::Point InputPointType; + typedef itk::Point OutputPointType; + using PixelType =TScalarType; + //@} + + /** Method for creation through the object factory. */ + itkNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(RPCInverseTransform, RPCTransformBase); + + itkStaticConstMacro(InputSpaceDimension, unsigned int, NInputDimensions); + itkStaticConstMacro(OutputSpaceDimension, unsigned int, NOutputDimensions); + + /** Method to transform a point. */ + OutputPointType TransformPoint(const InputPointType& point) const override; + +protected: + RPCInverseTransform() = default; + ~RPCInverseTransform() = default; + void PrintSelf(std::ostream& os, itk::Indent indent) const override; + +private: + RPCInverseTransform(const Self&) = delete; + void operator=(const Self&) = delete; +}; + +} + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbRPCInverseTransform.hxx" +#endif + +#endif diff --git a/Modules/Core/Transform/include/otbRPCInverseTransform.hxx b/Modules/Core/Transform/include/otbRPCInverseTransform.hxx new file mode 100644 index 0000000000000000000000000000000000000000..0513c28a480629e3be35726a8e5bf73e4f9314f8 --- /dev/null +++ b/Modules/Core/Transform/include/otbRPCInverseTransform.hxx @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef otbRPCInverseTransform_hxx +#define otbRPCInverseTransform_hxx + +#include "otbRPCInverseTransform.h" + +namespace otb +{ + +template +typename RPCInverseTransform::OutputPointType +RPCInverseTransform::TransformPoint(const InputPointType& point) const +{ + GDALRPCTransformer::PointType zePoint; + zePoint[0] = static_cast(point[0]); + zePoint[1] = static_cast(point[1]); + if (NInputDimensions > 2) + zePoint[2] = static_cast(point[2]); + else + zePoint[2] = 0.; + + zePoint = this->m_Transformer->InverseTransform(zePoint); + + OutputPointType pOut; + pOut[0] = static_cast(zePoint[0]); + pOut[1] = static_cast(zePoint[1]); + + if (NOutputDimensions > 2) + pOut[2] = static_cast(zePoint[2]); + + return pOut; +} + +/** + * PrintSelf method + */ +template +void RPCInverseTransform::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "Transformation direction: Inverse" << std::endl; +} + +} + +#endif diff --git a/Modules/Core/Transform/include/otbRPCTransformBase.h b/Modules/Core/Transform/include/otbRPCTransformBase.h new file mode 100644 index 0000000000000000000000000000000000000000..a54e5d4c079ed4cccc28015d565b3bba3ccbeafb --- /dev/null +++ b/Modules/Core/Transform/include/otbRPCTransformBase.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef otbRPCTransformBase_h +#define otbRPCTransformBase_h + +#include "otbSensorTransformBase.h" +#include "otbGeometryMetadata.h" +#include "otbGDALRPCTransformer.h" + +namespace otb +{ +/** \class RPCTransformBase + * \brief Base projection class based on the RPC method. + * + * This is a projection class, based on a RPC sensor model. This + * class allows: + * + * - Forward Transformation of a point in the sensor geometry (i, j) + * to a geographic point in (lat, long) + * + * - Inverse Transformation of a a geographic point in (lat, long) to + * a point in the sensor geometry (i, j). + * + * \ingroup OTBTransform + */ +template +class ITK_EXPORT RPCTransformBase : public SensorTransformBase +{ +public: + /** @name Standard class type definitions */ + //@{ + using Self = RPCTransformBase; + using Superclass = SensorTransformBase; + using Pointer = itk::SmartPointer; + using ConstPointer = itk::SmartPointer ; + + using InputPointType = itk::Point; + using OutputPointType = itk::Point; + using PixelType =TScalarType; + //@} + + /** Run-time type information (and related methods). */ + itkTypeMacro(RPCTransformBase, SensorTransformBase); + + itkStaticConstMacro(InputSpaceDimension, unsigned int, NInputDimensions); + itkStaticConstMacro(OutputSpaceDimension, unsigned int, NOutputDimensions); + + /* + * Provide the ImageMetadata in order to set the model. + * Return false if model not valid. + */ + bool SetMetadata(const ImageMetadata& imd) override; + + /** Check model validity */ + bool IsValidSensorModel() const override; + +protected: + RPCTransformBase() = default; + ~RPCTransformBase() = default; + void PrintSelf(std::ostream& os, itk::Indent indent) const override; + + std::unique_ptr m_RPCParam; + std::unique_ptr m_Transformer; + +private: + RPCTransformBase(const Self&) = delete; + void operator=(const Self&) = delete; +}; + +} + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbRPCTransformBase.hxx" +#endif + +#endif diff --git a/Modules/Core/Transform/include/otbRPCTransformBase.hxx b/Modules/Core/Transform/include/otbRPCTransformBase.hxx new file mode 100644 index 0000000000000000000000000000000000000000..e723d1f936a0d0c4ab24b78b22124b53c047afa9 --- /dev/null +++ b/Modules/Core/Transform/include/otbRPCTransformBase.hxx @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef otbRPCTransformBase_hxx +#define otbRPCTransformBase_hxx + +#include "otbRPCTransformBase.h" + +namespace otb +{ + +template +bool RPCTransformBase::SetMetadata(const ImageMetadata& imd) +{ + if (!imd.Has(MDGeom::RPC)) + return false; + const boost::any any_rpc = imd[MDGeom::RPC]; + if (any_rpc.empty()) + return false; + try + { + this->m_RPCParam = std::make_unique(boost::any_cast(imd[MDGeom::RPC])); + } + catch (boost::bad_any_cast) + { + return false; + } + + constexpr bool useDEM = NInputDimensions == 2 ? true : false; + this->m_Transformer = std::make_unique(*m_RPCParam, useDEM); + return true; +} + +template +bool RPCTransformBase::IsValidSensorModel() const +{ + return m_Transformer != nullptr; +} + +/** + * PrintSelf method + */ +template +void RPCTransformBase::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); + os << indent << "RPC Model: " << this->m_RPCParam.get()->ToJSON() << std::endl; +} + +} + +#endif diff --git a/Modules/Core/Transform/include/otbSensorModelBase.h b/Modules/Core/Transform/include/otbSensorModelBase.h deleted file mode 100644 index 9071bce41fcfd8eb311e2e603a28585aaa879227..0000000000000000000000000000000000000000 --- a/Modules/Core/Transform/include/otbSensorModelBase.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) - * - * This file is part of Orfeo Toolbox - * - * https://www.orfeo-toolbox.org/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef otbSensorModelBase_h -#define otbSensorModelBase_h - - -#include "otbMacro.h" -#include "otbImageKeywordlist.h" -#include "otbSensorModelAdapter.h" - -#include "otbTransform.h" -#include "itkSmartPointer.h" - -namespace otb -{ -/** \class SensorModelBase - * \brief Base class for the sensor model projection classes. - * - * This class allows transforming a geographic point in (lat, long) to a point - * in the sensor geometry. (lat, lon) -> (i, j) or (lat, lon, h) -> (i, j) - * - * \ingroup Projection - * - * - * \ingroup OTBTransform - */ -template -class ITK_EXPORT SensorModelBase : public Transform -{ - -public: - /** Standard class typedefs. */ - typedef SensorModelBase Self; - typedef Transform Superclass; - typedef itk::SmartPointer Pointer; - typedef itk::SmartPointer ConstPointer; - - typedef itk::Point InputPointType; - typedef itk::Point OutputPointType; - - typedef TScalarType PixelType; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(SensorModelBase, Transform); - - itkStaticConstMacro(InputSpaceDimension, unsigned int, NInputDimensions); - itkStaticConstMacro(OutputSpaceDimension, unsigned int, NOutputDimensions); - - /* Get the ImageKeywordlist */ - ImageKeywordlist GetImageGeometryKeywordlist(void) const; - - /* - * Set the Imagekeywordlist and affect the ossim projection ( m_Model) - * Return false if not model found. - * \deprecated - */ - virtual void SetImageGeometry(const ImageKeywordlist& image_kwl); - - /** Is sensor model valid method. return false if the sensor model is null */ - bool IsValidSensorModel() - { - return m_Model->IsValidSensorModel(); - } - -protected: - SensorModelBase(); - ~SensorModelBase() override; - - /** PrintSelf method */ - void PrintSelf(std::ostream& os, itk::Indent indent) const override; - - /** ImageKeywordlist */ - ImageKeywordlist m_ImageKeywordlist; - /** Pointer on an ossim projection (created with the keywordlist) */ - SensorModelAdapter::Pointer m_Model; - -private: - SensorModelBase(const Self&) = delete; - void operator=(const Self&) = delete; -}; - -} // namespace otb - -#ifndef OTB_MANUAL_INSTANTIATION -#include "otbSensorModelBase.hxx" -#endif - -#endif diff --git a/Modules/Core/Transform/include/otbSensorModelBase.hxx b/Modules/Core/Transform/include/otbSensorModelBase.hxx deleted file mode 100644 index 3056fe57c0426e257a4ff8de0ec24707b575e3be..0000000000000000000000000000000000000000 --- a/Modules/Core/Transform/include/otbSensorModelBase.hxx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) - * - * This file is part of Orfeo Toolbox - * - * https://www.orfeo-toolbox.org/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef otbSensorModelBase_hxx -#define otbSensorModelBase_hxx - -#include "otbSensorModelBase.h" - - -namespace otb -{ - -template -SensorModelBase::SensorModelBase() : Superclass(0) -{ - m_Model = SensorModelAdapter::New(); -} - -template -SensorModelBase::~SensorModelBase() -{ -} - -/// Get the Geometry Keyword list -template -ImageKeywordlist SensorModelBase::GetImageGeometryKeywordlist(void) const -{ - return m_ImageKeywordlist; -} - -/** Set the Imagekeywordlist and affect the ossim projection ( m_Model) */ -template -void SensorModelBase::SetImageGeometry(const ImageKeywordlist& image_kwl) -{ - m_ImageKeywordlist = image_kwl; - m_Model->CreateProjection(m_ImageKeywordlist); -} - -/** - * PrintSelf method - */ -template -void SensorModelBase::PrintSelf(std::ostream& os, itk::Indent indent) const -{ - Superclass::PrintSelf(os, indent); - os << indent << "Model: " << m_Model << std::endl; - os << indent << "Keywordlist: " << m_ImageKeywordlist << std::endl; -} - -} // namespace otb - -#endif diff --git a/Modules/Core/Transform/include/otbSensorTransformBase.h b/Modules/Core/Transform/include/otbSensorTransformBase.h new file mode 100644 index 0000000000000000000000000000000000000000..ca1607bba47544f78181d0247dee3b0fc4e1bd79 --- /dev/null +++ b/Modules/Core/Transform/include/otbSensorTransformBase.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef otbSensorTransformBase_h +#define otbSensorTransformBase_h + +#include "otbMacro.h" +#include "otbImageMetadata.h" + +#include "otbTransform.h" +#include "itkSmartPointer.h" + +namespace otb +{ +/** \class SensorTransformBase + * \brief Base class for the sensor model projection classes. + * + * This is the base class for sensor model projection classes. Those + * classes allow: + * + * - Forward Transformation of a point in the sensor geometry (i, j) + * to a geographic point in (lat, long) + * + * - Inverse Transformation of a a geographic point in (lat, long) to + * a point in the sensor geometry (i, j). + * + * \ingroup Projection + * \ingroup OTBTransform + */ +template +class ITK_EXPORT SensorTransformBase : public Transform +{ + +public: + /** @name Standard class type definitions */ + //@{ + using Self = SensorTransformBase; + using Superclass = Transform; + using Pointer = itk::SmartPointer; + using ConstPointer = itk::SmartPointer ; + + using InputPointType = itk::Point; + using OutputPointType = itk::Point; + using PixelType =TScalarType; + //@} + + /** Run-time type information (and related methods). */ + itkTypeMacro(Self, Superclass); + + itkStaticConstMacro(InputSpaceDimension, unsigned int, NInputDimensions); + itkStaticConstMacro(OutputSpaceDimension, unsigned int, NOutputDimensions); + + /* + * Provide the ImageMetadata in order to set the model. + * Return false if model not valid. + */ + virtual bool SetMetadata(const ImageMetadata& imd) = 0; + + /** Check model validity */ + virtual bool IsValidSensorModel() const = 0; + +protected: + SensorTransformBase() : Superclass(0) {} + ~SensorTransformBase() = default; + +private: + SensorTransformBase(const Self&) = delete; + void operator=(const Self&) = delete; +}; + +} // namespace otb + +#endif diff --git a/Modules/Core/Transform/include/otbTransform.h b/Modules/Core/Transform/include/otbTransform.h index e4cd1745f73b8c495283ee706aa02bb91c4ce281..3ce58fbb3f9b489320a9443022c8840a5162e173 100644 --- a/Modules/Core/Transform/include/otbTransform.h +++ b/Modules/Core/Transform/include/otbTransform.h @@ -30,8 +30,6 @@ namespace otb /** \class Transform * \brief Class to overload method passed to virtual pure in ITK V4. * - * - * * \ingroup OTBTransform */ template -#include - -#include "otbVectorImage.h" -#include "otbImageFileReader.h" -#include "otbForwardSensorModel.h" -#include "otbInverseSensorModel.h" - -// Exercise the Spot5 sensor model on the image border -int main(int argc, char* argv[]) -{ - if (argc != 3) - { - std::cout << argv[0] << " " << std::endl; - - return EXIT_FAILURE; - } - - char* filename = argv[1]; - char* outFilename = argv[2]; - - - typedef otb::VectorImage ImageType; - typedef otb::ImageFileReader ReaderType; - - otb::DEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(16.19688987731934); - - ReaderType::Pointer reader = ReaderType::New(); - reader->SetFileName(filename); - reader->UpdateOutputInformation(); - - ImageType::Pointer image = reader->GetOutput(); - ImageType::RegionType region = image->GetLargestPossibleRegion(); - - typedef otb::ForwardSensorModel ForwardSensorModelType; - ForwardSensorModelType::Pointer forwardSensorModel = ForwardSensorModelType::New(); - forwardSensorModel->SetImageGeometry(reader->GetOutput()->GetImageKeywordlist()); - if (forwardSensorModel->IsValidSensorModel() == false) - { - std::cout << "Invalid Model pointer m_Model == NULL!\n The ossim keywordlist is invalid!" << std::endl; - return EXIT_FAILURE; - } - - typedef otb::InverseSensorModel InverseSensorModelType; - InverseSensorModelType::Pointer inverseSensorModel = InverseSensorModelType::New(); - inverseSensorModel->SetImageGeometry(reader->GetOutput()->GetImageKeywordlist()); - if (inverseSensorModel->IsValidSensorModel() == false) - { - std::cout << "Invalid Model pointer m_Model == NULL!\n The ossim keywordlist is invalid!" << std::endl; - return EXIT_FAILURE; - } - - const int radius = 10; - const double gridstep = 0.1; - - itk::Point imagePoint; - - // Test upper left corner - std::cout << " --- upper left corner ---" << std::endl; - for (imagePoint[0] = region.GetIndex(0) - radius; imagePoint[0] < region.GetIndex(0) + radius; imagePoint[0] += gridstep) - { - - for (imagePoint[1] = region.GetIndex(1) - radius; imagePoint[1] < region.GetIndex(1) + radius; imagePoint[1] += gridstep) - { - - itk::Point geoPoint; - geoPoint = forwardSensorModel->TransformPoint(imagePoint); - std::cout << "Image to geo: " << imagePoint << " -> " << geoPoint << "\n"; - - if (vnl_math_isnan(geoPoint[0]) || vnl_math_isnan(geoPoint[1])) - { - return EXIT_FAILURE; - } - - itk::Point reversedImagePoint; - reversedImagePoint = inverseSensorModel->TransformPoint(geoPoint); - - std::cout << "Geo to image: " << geoPoint << " -> " << reversedImagePoint << "\n"; - - if (vnl_math_isnan(reversedImagePoint[0]) || vnl_math_isnan(reversedImagePoint[1])) - { - return EXIT_FAILURE; - } - } - } - - // Test lower left corner - std::cout << " --- lower left corner ---" << std::endl; - for (imagePoint[0] = region.GetIndex(0) - radius; imagePoint[0] < region.GetIndex(0) + radius; imagePoint[0] += gridstep) - { - for (imagePoint[1] = region.GetIndex(1) + region.GetSize(1) - radius; imagePoint[1] < region.GetIndex(1) + region.GetSize(1) + radius; - imagePoint[1] += gridstep) - { - - itk::Point geoPoint; - geoPoint = forwardSensorModel->TransformPoint(imagePoint); - std::cout << "Image to geo: " << imagePoint << " -> " << geoPoint << "\n"; - - if (vnl_math_isnan(geoPoint[0]) || vnl_math_isnan(geoPoint[1])) - { - return EXIT_FAILURE; - } - - itk::Point reversedImagePoint; - reversedImagePoint = inverseSensorModel->TransformPoint(geoPoint); - - std::cout << "Geo to image: " << geoPoint << " -> " << reversedImagePoint << "\n"; - - if (vnl_math_isnan(reversedImagePoint[0]) || vnl_math_isnan(reversedImagePoint[1])) - { - return EXIT_FAILURE; - } - } - } - - // Test lower right corner - std::cout << " --- lower right corner ---" << std::endl; - for (imagePoint[0] = region.GetIndex(0) + region.GetSize(0) - radius; imagePoint[0] < region.GetIndex(0) + region.GetSize(0) + radius; - imagePoint[0] += gridstep) - { - for (imagePoint[1] = region.GetIndex(1) + region.GetSize(1) - radius; imagePoint[1] < region.GetIndex(1) + region.GetSize(1) + radius; - imagePoint[1] += gridstep) - { - - itk::Point geoPoint; - geoPoint = forwardSensorModel->TransformPoint(imagePoint); - std::cout << "Image to geo: " << imagePoint << " -> " << geoPoint << "\n"; - - if (vnl_math_isnan(geoPoint[0]) || vnl_math_isnan(geoPoint[1])) - { - return EXIT_FAILURE; - } - - itk::Point reversedImagePoint; - reversedImagePoint = inverseSensorModel->TransformPoint(geoPoint); - - std::cout << "Geo to image: " << geoPoint << " -> " << reversedImagePoint << "\n"; - - if (vnl_math_isnan(reversedImagePoint[0]) || vnl_math_isnan(reversedImagePoint[1])) - { - return EXIT_FAILURE; - } - } - } - - // Test upper right corner - std::cout << " --- upper right corner ---" << std::endl; - for (imagePoint[0] = region.GetIndex(0) + region.GetSize(0) - radius; imagePoint[0] < region.GetIndex(0) + region.GetSize(0) + radius; - imagePoint[0] += gridstep) - { - for (imagePoint[1] = region.GetIndex(1) - radius; imagePoint[1] < region.GetIndex(1) + radius; imagePoint[1] += gridstep) - { - - itk::Point geoPoint; - geoPoint = forwardSensorModel->TransformPoint(imagePoint); - std::cout << "Image to geo: " << imagePoint << " -> " << geoPoint << "\n"; - - if (vnl_math_isnan(geoPoint[0]) || vnl_math_isnan(geoPoint[1])) - { - return EXIT_FAILURE; - } - - itk::Point reversedImagePoint; - reversedImagePoint = inverseSensorModel->TransformPoint(geoPoint); - - std::cout << "Geo to image: " << geoPoint << " -> " << reversedImagePoint << "\n"; - - if (vnl_math_isnan(reversedImagePoint[0]) || vnl_math_isnan(reversedImagePoint[1])) - { - return EXIT_FAILURE; - } - } - } - - - // generat the output value along a segment crossing the lower image border - // at the center position - itk::Point imagePoint1; - imagePoint1[0] = region.GetIndex(0) + region.GetSize(0) / 2; - imagePoint1[1] = region.GetIndex(1) + region.GetSize(1) - radius; - - itk::Point imagePoint2; - imagePoint2[0] = region.GetIndex(0) + region.GetSize(0) / 2; - imagePoint2[1] = region.GetIndex(1) + region.GetSize(1) + radius; - - itk::Point geoPoint1, geoPoint2; - geoPoint1 = forwardSensorModel->TransformPoint(imagePoint1); - geoPoint2 = forwardSensorModel->TransformPoint(imagePoint2); - - itk::Vector geoDir; - geoDir[0] = geoPoint2[0] - geoPoint1[0]; - geoDir[1] = geoPoint2[1] - geoPoint1[1]; - - const int nbStep = 50; - itk::Vector geoStep = geoDir / nbStep; - - std::ofstream file; - file.open(outFilename); - - file << "# image_x image_y geo_x geo_y reversed_image_x reversed_image_y" << std::endl; - file << std::setprecision(15); - - for (int i = 0; i < nbStep; ++i) - { - itk::Point geoPoint; - geoPoint[0] = geoPoint1[0] + geoStep[0] * i; - geoPoint[1] = geoPoint1[1] + geoStep[1] * i; - - itk::Point reversedImagePoint; - reversedImagePoint = inverseSensorModel->TransformPoint(geoPoint); - - file << geoPoint[0] << "\t" << geoPoint[1] << "\t" << reversedImagePoint[0] << "\t" << reversedImagePoint[1] << std::endl; - - if (vnl_math_isnan(geoPoint[0]) || vnl_math_isnan(geoPoint[1])) - { - return EXIT_FAILURE; - } - } - - file.close(); - - return EXIT_SUCCESS; -} diff --git a/Modules/Core/Transform/test/otbCreateInverseForwardSensorModel.cxx b/Modules/Core/Transform/test/otbCreateInverseForwardSensorModel.cxx index 21fb7eceb06c6d416f7b9036d0fd6bd43204a0ef..c0382b3d73f615d936c871b9604bfebfdd34cf4f 100644 --- a/Modules/Core/Transform/test/otbCreateInverseForwardSensorModel.cxx +++ b/Modules/Core/Transform/test/otbCreateInverseForwardSensorModel.cxx @@ -27,9 +27,9 @@ #include "otbImage.h" #include "otbImageFileReader.h" - -#include "otbInverseSensorModel.h" -#include "otbForwardSensorModel.h" +#include "otbRPCInverseTransform.h" +#include "otbRPCForwardTransform.h" +#include "otbMetaDataKey.h" #include "otbDEMHandler.h" int otbCreateInverseForwardSensorModel(int argc, char* argv[]) @@ -51,52 +51,60 @@ int otbCreateInverseForwardSensorModel(int argc, char* argv[]) return EXIT_FAILURE; } - typedef otb::Image ImageType; - typedef otb::ImageFileReader ReaderType; - typedef otb::InverseSensorModel InverseModelType; - typedef otb::ForwardSensorModel ForwardModelType; + using ImageType = otb::Image; + using ReaderType = otb::ImageFileReader; + using ForwardRPCModelType = otb::RPCForwardTransform; + using InverseRPCModelType = otb::RPCInverseTransform; // Allocate pointer - InverseModelType::Pointer inverse_model = InverseModelType::New(); - ForwardModelType::Pointer forward_model = ForwardModelType::New(); - ReaderType::Pointer reader = ReaderType::New(); + auto inverse_rpc_model = InverseRPCModelType::New(); + auto forward_rpc_model = ForwardRPCModelType::New(); + auto reader = ReaderType::New(); - // Set parameters ... + // Set parameters reader->SetFileName(InputFilename); - // Read meta data (ossimKeywordlist) + // Read metadata reader->GenerateOutputInformation(); ImageType::Pointer inputImage = reader->GetOutput(); otbGenericMsgDebugMacro(<< "Inverse model creation..."); - inverse_model->SetImageGeometry(inputImage->GetImageKeywordlist()); - if (inverse_model->IsValidSensorModel() == false) + if (!inverse_rpc_model->SetMetadata(inputImage->GetImageMetadata())) + { + std::cout << "Error while reading model. This is not a RPC model!" << std::endl; + return EXIT_FAILURE; + } + if (!inverse_rpc_model->IsValidSensorModel()) { - std::cout << "Invalid Model pointer m_Model == NULL!\n The ossim keywordlist is invalid!" << std::endl; + std::cout << "Model not set!" << std::endl; return EXIT_FAILURE; } otbGenericMsgDebugMacro(<< "Forward model creation..."); - forward_model->SetImageGeometry(inputImage->GetImageKeywordlist()); - if (forward_model->IsValidSensorModel() == false) + if (!forward_rpc_model->SetMetadata(inputImage->GetImageMetadata())) + { + std::cout << "Error while reading model. This is not a RPC model!" << std::endl; + return EXIT_FAILURE; + } + if (!forward_rpc_model->IsValidSensorModel()) { - std::cout << "Invalid Model pointer m_Model == NULL!\n The ossim keywordlist is invalid!" << std::endl; + std::cout << "Model not set!" << std::endl; return EXIT_FAILURE; } std::ofstream ofs(OutputFilename, std::ofstream::out); ofs.precision(8); - InverseModelType::InputPointType geoPoint; + InverseRPCModelType::InputPointType geoPoint; geoPoint[0] = atof(pointX.c_str()); geoPoint[1] = atof(pointY.c_str()); ofs << "Testing geopoint: " << geoPoint << "\n\n"; - auto indexPoint = inverse_model->TransformPoint(geoPoint); + auto indexPoint = inverse_rpc_model->TransformPoint(geoPoint); ofs << "Testing InverseSensorModel: " << geoPoint << " -> " << indexPoint << "\n"; - auto newGeoPoint = forward_model->TransformPoint(indexPoint); + auto newGeoPoint = forward_rpc_model->TransformPoint(indexPoint); ofs << "Testing ForwardSensorModel: " << indexPoint << " -> " << newGeoPoint << "\n"; return EXIT_SUCCESS; diff --git a/Modules/Core/Transform/test/otbCreateProjectionWithOSSIM.cxx b/Modules/Core/Transform/test/otbCreateProjectionWithOSSIM.cxx deleted file mode 100644 index 640e6b93cc8e3c64e6cefaaf20ddb660cfd0e6fb..0000000000000000000000000000000000000000 --- a/Modules/Core/Transform/test/otbCreateProjectionWithOSSIM.cxx +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) - * - * This file is part of Orfeo Toolbox - * - * https://www.orfeo-toolbox.org/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -/*! - * - * PURPOSE: - * - * Application pour projeter une region d'une image en coordonnees geographiques - * en utilisant un Interpolator+regionextractor et un Iterator. - * - */ - -// iostream is used for general output -#include -#include -#include - -#include "otbImage.h" -#include "otbImageFileReader.h" -#include "otbImageFileWriter.h" -#include "otbImageFileWriter.h" - -#include "itkUnaryFunctorImageFilter.h" -#include "itkExtractImageFilter.h" -#include "itkRescaleIntensityImageFilter.h" -#include "itkImageRegionIteratorWithIndex.h" -#include "itkLinearInterpolateImageFunction.h" - -#include "otbInverseSensorModel.h" - -#include "otb_ossim.h" - -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#pragma GCC diagnostic ignored "-Woverloaded-virtual" -#pragma GCC diagnostic ignored "-Wshadow" -#include "ossim/imaging/ossimImageHandler.h" -#include "ossim/base/ossimKeywordlist.h" -#include "ossim/imaging/ossimImageHandlerRegistry.h" -#include "ossim/projection/ossimProjectionFactoryRegistry.h" -#pragma GCC diagnostic pop -#else -#include "ossim/imaging/ossimImageHandler.h" -#include "ossim/base/ossimKeywordlist.h" -#include "ossim/imaging/ossimImageHandlerRegistry.h" -#include "ossim/projection/ossimProjectionFactoryRegistry.h" -#endif - -int otbCreateProjectionWithOSSIM(int argc, char* argv[]) -{ - if (argc != 2) - { - std::cout << argv[0] << " " << std::endl; - return EXIT_FAILURE; - } - - otbGenericMsgDebugMacro(<< "Creating handler..."); - ossimImageHandler* handler = ossimImageHandlerRegistry::instance()->open(ossimFilename(argv[1])); - if (!handler) - { - itkGenericExceptionMacro(<< "Unable to open input image " << argv[1]); - } - - ossimKeywordlist geom; - otbGenericMsgDebugMacro(<< "Read ossim Keywordlist..."); - handler->getImageGeometry()->getProjection()->saveState(geom); - ossimGpt ossimGPoint(0, 0); - ossimDpt ossimDPoint; - otbGenericMsgDebugMacro(<< "Creating projection..."); - ossimProjection* model = nullptr; - model = ossimProjectionFactoryRegistry::instance()->createProjection(geom); - if (model == nullptr) - { - itkGenericExceptionMacro(<< "Invalid Model * == NULL !"); - } - - otbGenericMsgDebugMacro(<< "Creating RefPtr of projection..."); - ossimRefPtr ptrmodel = model; - if (ptrmodel.valid() == false) - { - itkGenericExceptionMacro(<< "Invalid Model pointer .valid() == false !"); - } - - return EXIT_SUCCESS; -} diff --git a/Modules/Core/Transform/test/otbCreateProjectionWithOTB.cxx b/Modules/Core/Transform/test/otbCreateProjectionWithOTB.cxx index a8ef948f51b800780d9d9c5eaf8f54d30190e285..64c20948a8296bb7b5d0dc4c3c9d813fc5da5911 100644 --- a/Modules/Core/Transform/test/otbCreateProjectionWithOTB.cxx +++ b/Modules/Core/Transform/test/otbCreateProjectionWithOTB.cxx @@ -43,8 +43,6 @@ #include "itkImageRegionIteratorWithIndex.h" #include "itkLinearInterpolateImageFunction.h" -#include "otbInverseSensorModel.h" - #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" diff --git a/Modules/Core/Transform/test/otbRPCTransformTest.cxx b/Modules/Core/Transform/test/otbRPCTransformTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..fab017309e05eb2165e0ecfa6bdb56b53baff0fc --- /dev/null +++ b/Modules/Core/Transform/test/otbRPCTransformTest.cxx @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "itkPoint.h" +#include "itkEuclideanDistanceMetric.h" +#include "otbGeographicalDistance.h" +#include "otbImageMetadata.h" +#include "otbMetaDataKey.h" +#include "otbGeomMetadataSupplier.h" +#include "otbImageMetadataInterfaceFactory.h" +#include "otbMacro.h" +#include "otbDEMHandler.h" +#include "otbImage.h" +#include "otbImageFileReader.h" +#include "otbRPCForwardTransform.h" +#include "otbRPCInverseTransform.h" +#include "otbGenericRSTransform.h" + +using PointType = itk::Point; +using PointsContainerType = std::vector; +using ForwardTransformType = otb::RPCForwardTransform; +using InverseTransformType = otb::RPCInverseTransform; +using GenericRSTransformType = otb::GenericRSTransform; +using DistanceType = itk::Statistics::EuclideanDistanceMetric; +using GeographicalDistanceType = otb::GeographicalDistance; + +int otbRPCTransformTest(int itkNotUsed(argc), char* argv[]) +{ + bool success = true; + PointType imagePoint; + PointType geo3dPoint; + + // Inputs + std::string rpcFile(argv[1]); + std::string gcpFileName(argv[2]); + double geoTol(atof(argv[3])); + double imgTol(atof(argv[4])); + + // Tools + auto imgDistance = DistanceType::New(); + auto geoDistance = GeographicalDistanceType::New(); + OGRSpatialReference oSRS; + oSRS.SetWellKnownGeogCS("WGS84"); + char* wgsRef = nullptr; + oSRS.exportToWkt(&wgsRef); + + otb::ImageMetadata imd; + if (0 == rpcFile.compare(rpcFile.length() - 4, 4, "geom")) + { + // Fetching the RPC model from a GEOM file + otb::GeomMetadataSupplier geomSupplier(rpcFile); + for (int loop = 0 ; loop < geomSupplier.GetNbBands() ; ++loop) + imd.Bands.emplace_back(); + auto imi = otb::ImageMetadataInterfaceFactory::CreateIMI(imd, geomSupplier); + imd = imi->GetImageMetadata(); + geomSupplier.FetchRPC(imd); + } + else + { + // Fetching the RPC model from a product + using ImageType = otb::Image; + using ImageFileReaderType = otb::ImageFileReader; + auto reader = ImageFileReaderType::New(); + reader->SetFileName(rpcFile); + reader->UpdateOutputInformation(); + imd = reader->GetOutput()->GetImageMetadata(); + imd.Remove(otb::MDGeom::ProjectionWKT); + } + + // Setting the transforms + auto ForwardTransform = ForwardTransformType::New(); + ForwardTransform->SetMetadata(imd); + + auto InverseTransform = InverseTransformType::New(); + InverseTransform->SetMetadata(imd); + + auto GenericRSTransform_img2wgs = GenericRSTransformType::New(); + GenericRSTransform_img2wgs->SetInputProjectionRef(""); + GenericRSTransform_img2wgs->SetOutputProjectionRef(wgsRef); + GenericRSTransform_img2wgs->SetInputImageMetadata(&imd); + GenericRSTransform_img2wgs->InstantiateTransform(); + + auto GenericRSTransform_wgs2img = GenericRSTransformType::New(); + GenericRSTransform_wgs2img->SetInputProjectionRef(wgsRef); + GenericRSTransform_wgs2img->SetOutputProjectionRef(""); + GenericRSTransform_wgs2img->SetOutputImageMetadata(&imd); + GenericRSTransform_wgs2img->InstantiateTransform(); + + // Loading the GCP + PointsContainerType pointsContainer; + PointsContainerType geo3dPointsContainer; + std::ifstream file(gcpFileName, std::ios::in); + if (file) + { + std::string line; + while (getline(file, line)) + { + if (line.find_first_of("#") != 0) + { + std::istringstream iss(line); + + iss >> imagePoint[0] >> imagePoint[1] >> geo3dPoint[0] >> geo3dPoint[1] >> geo3dPoint[2]; + imagePoint[2] = geo3dPoint[2]; + + pointsContainer.push_back(imagePoint); + geo3dPointsContainer.push_back(geo3dPoint); + } + } + file.close(); + } + + // For each CGP + double distance; + for (PointsContainerType::iterator pointsIt = pointsContainer.begin(), geo3dPointsIt = geo3dPointsContainer.begin() ; + (pointsIt != pointsContainer.end()) && (geo3dPointsIt != geo3dPointsContainer.end()) ; + ++pointsIt, ++geo3dPointsIt) + { + // Testing forward transform + // geo3dPoint = ForwardTransform->TransformPoint(*pointsIt); + // distance = geoDistance->Evaluate(geo3dPoint, *geo3dPointsIt); + // if (distance > geoTol) + // { + // std::cerr << "Geo distance between ForwardTransform->TransformPoint and GCP too high :\n" + // << "GCP: " << *geo3dPointsIt << " / computed: " << geo3dPoint << "\n" + // << "dist = " << distance << " (tol = " << geoTol << ")" << std::endl; + // success = false; + // } + + // // Testing inverse transform + // imagePoint = InverseTransform->TransformPoint(*geo3dPointsIt); + // distance = imgDistance->Evaluate(imagePoint, *pointsIt); + // if (distance > imgTol) + // { + // std::cerr << "Distance between InverseTransform->TransformPoint and GCP too high :\n" + // << "GCP: " << *pointsIt << " / computed: " << imagePoint << "\n" + // << "dist = " << distance << " (tol = " << imgTol << ")" << std::endl; + // success = false; + // } + + // Testing image to wgs transform + geo3dPoint = GenericRSTransform_img2wgs->TransformPoint(*pointsIt); + distance = geoDistance->Evaluate(geo3dPoint, *geo3dPointsIt); + if (distance > geoTol) + { + std::cerr << "Geo distance between GenericRSTransform_img2wgs->TransformPoint and GCP too high :\n" + << "GCP: " << *geo3dPointsIt << " / computed: " << geo3dPoint << "\n" + << "dist = " << distance << " (tol = " << geoTol << ")" << std::endl; + success = false; + } + + // Testing wgs to image transform + // imagePoint = GenericRSTransform_wgs2img->TransformPoint(*geo3dPointsIt); + // distance = imgDistance->Evaluate(imagePoint, *pointsIt); + // if (distance > imgTol) + // { + // std::cerr << "Distance between GenericRSTransform_wgs2img->TransformPoint and GCP too high :\n" + // << "GCP: " << *pointsIt << " / computed: " << imagePoint << "\n" + // << "dist = " << distance << " (tol = " << imgTol << ")" << std::endl; + // success = false; + // } + } + + if (success) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; +} diff --git a/Modules/Core/Transform/test/otbTransformTestDriver.cxx b/Modules/Core/Transform/test/otbTransformTestDriver.cxx index 8d586ab78184c76faba041c7e99036697ce49411..f4a2e817cf8e4c216e118f9e1e3f575e4004a5d1 100644 --- a/Modules/Core/Transform/test/otbTransformTestDriver.cxx +++ b/Modules/Core/Transform/test/otbTransformTestDriver.cxx @@ -23,8 +23,6 @@ void RegisterTests() { REGISTER_TEST(otbGenericRSTransformWithSRID); - REGISTER_TEST(otbCreateInverseForwardSensorModel); - REGISTER_TEST(otbCreateProjectionWithOSSIM); REGISTER_TEST(otbLogPolarTransformResample); REGISTER_TEST(otbLogPolarTransform); REGISTER_TEST(otbGeocentricTransform); @@ -36,4 +34,5 @@ void RegisterTests() REGISTER_TEST(otbInverseLogPolarTransformResample); REGISTER_TEST(otbStreamingResampleImageFilterWithAffineTransform); REGISTER_TEST(otbSarSensorModelAdapterTest); + REGISTER_TEST(otbRPCTransformTest); } diff --git a/Modules/Filtering/DEM/include/otbDEMToImageGenerator.h b/Modules/Filtering/DEM/include/otbDEMToImageGenerator.h index 7d1a6ec0dc40efdd5a52bde2f2e13168a2f2be0d..0bc41ebf612881e53ba55407d2e04952337e8499 100644 --- a/Modules/Filtering/DEM/include/otbDEMToImageGenerator.h +++ b/Modules/Filtering/DEM/include/otbDEMToImageGenerator.h @@ -111,7 +111,6 @@ public: /** * Set/Get input & output projections. - * Set/Get input & output keywordlist * The macro are not used here cause the input and the output are * inversed. */ @@ -137,27 +136,25 @@ public: return m_Transform->GetInputProjectionRef(); } - /** Set/Get Input Keywordlist*/ - void SetInputKeywordList(const ImageKeywordlist& kwl) + /** Set/Get ImageMetadata*/ + const ImageMetadata* GetInputImageMetadata() const { - m_Transform->SetOutputKeywordList(kwl); - this->Modified(); + return m_Transform->GetOutputImageMetadata(); } - const ImageKeywordlist GetInputKeywordList() + void SetInputImageMetadata(const ImageMetadata* imd) { - return m_Transform->GetOutputKeywordList(); + m_Transform->SetOutputImageMetadata(imd); + this->Modified(); } - /** Set/Get output Keywordlist*/ - void SetOutputKeywordList(const ImageKeywordlist& kwl) + const ImageMetadata* GetOutputImageMetadata() const { - m_Transform->SetInputKeywordList(kwl); - this->Modified(); + return m_Transform->GetInputImageMetadata(); } - - const ImageKeywordlist GetOutputKeywordList() + void SetOutputImageMetadata(const ImageMetadata* imd) { - return m_Transform->GetInputKeywordList(); + m_Transform->SetInputImageMetadata(imd); + this->Modified(); } /** Useful to set the output parameters from an existing image*/ @@ -169,7 +166,7 @@ public: // this->SetOutputStartIndex ( image->GetLargestPossibleRegion().GetIndex() ); this->SetOutputSize(image->GetLargestPossibleRegion().GetSize()); this->SetOutputProjectionRef(image->GetProjectionRef()); - this->SetOutputKeywordList(image->GetImageKeywordlist()); + this->SetOutputImageMetadata(&(image->GetImageMetadata())); InstantiateTransform(); } diff --git a/Modules/Filtering/DEM/include/otbDEMToImageGenerator.hxx b/Modules/Filtering/DEM/include/otbDEMToImageGenerator.hxx index 24b3dac2bae628c0791208520e679d7881f1068a..1d865fa83b91536281dcb021fa19f2cbc8fd40cb 100644 --- a/Modules/Filtering/DEM/include/otbDEMToImageGenerator.hxx +++ b/Modules/Filtering/DEM/include/otbDEMToImageGenerator.hxx @@ -47,8 +47,7 @@ DEMToImageGenerator::DEMToImageGenerator() template void DEMToImageGenerator::GenerateOutputInformation() { - DEMImageType* output; - output = this->GetOutput(0); + DEMImageType* output = this->GetOutput(0); IndexType start; start[0] = 0; @@ -63,17 +62,10 @@ void DEMToImageGenerator::GenerateOutputInformation() output->SetSignedSpacing(m_OutputSpacing); output->SetOrigin(m_OutputOrigin); - - // Get the Output MetaData Dictionary - itk::MetaDataDictionary& dict = output->GetMetaDataDictionary(); - - // Encapsulate the metadata set by the user - itk::EncapsulateMetaData(dict, MetaDataKey::ProjectionRefKey, m_Transform->GetInputProjectionRef()); - - if (this->GetOutputKeywordList().GetSize() > 0) - { - itk::EncapsulateMetaData(dict, MetaDataKey::OSSIMKeywordlistKey, m_Transform->GetInputKeywordList()); - } + // Add the metadata set by the user to the output + output->m_Imd.Add(MDGeom::ProjectionProj, std::string(m_Transform->GetInputProjectionRef())); + if (m_Transform->GetInputImageMetadata() != nullptr) + output->m_Imd.Merge(*m_Transform->GetInputImageMetadata()); } // InstantiateTransform method diff --git a/Modules/Filtering/DEM/test/otbDEMToImageGeneratorFromImageTest.cxx b/Modules/Filtering/DEM/test/otbDEMToImageGeneratorFromImageTest.cxx index 2d86d9743e8652770fba980e7488c04a189310dd..19f8ce59ce9e5cc64fa9e5f6b8e4e6cdc1c74540 100644 --- a/Modules/Filtering/DEM/test/otbDEMToImageGeneratorFromImageTest.cxx +++ b/Modules/Filtering/DEM/test/otbDEMToImageGeneratorFromImageTest.cxx @@ -111,7 +111,6 @@ int otbDEMToImageGeneratorFromImageTest(int argc, char* argv[]) { char* outputName2 = argv[4]; generatorFilter2->SetOutputParametersFromImage(reader->GetOutput()); - generatorFilter2->InstantiateTransform(); extract2->SetInput(generatorFilter2->GetOutput()); extract2->SetSizeX(atoi(argv[7])); diff --git a/Modules/Filtering/ImageManipulation/test/otbRegionProjectionResampler.cxx b/Modules/Filtering/ImageManipulation/test/otbRegionProjectionResampler.cxx index 8a82d15eb460ef99bccaeca9cb163f8e1c866f8c..45d264e5fc500a0130855600a8e693876567af6f 100644 --- a/Modules/Filtering/ImageManipulation/test/otbRegionProjectionResampler.cxx +++ b/Modules/Filtering/ImageManipulation/test/otbRegionProjectionResampler.cxx @@ -43,7 +43,7 @@ #include "itkImageRegionIteratorWithIndex.h" #include "itkTranslationTransform.h" -#include "otbInverseSensorModel.h" +#include "otbRPCInverseTransform.h" #include "otbCompositeTransform.h" int otbRegionProjectionResampler(int argc, char* argv[]) @@ -59,9 +59,9 @@ int otbRegionProjectionResampler(int argc, char* argv[]) typedef otb::Image CharImageType; typedef otb::Image ImageType; - typedef otb::ImageFileReader ReaderType; - typedef otb::ImageFileWriter WriterType; - typedef otb::InverseSensorModel ModelType; + typedef otb::ImageFileReader ReaderType; + typedef otb::ImageFileWriter WriterType; + typedef otb::RPCInverseTransform ModelType; typedef itk::LinearInterpolateImageFunction InterpolatorType; typedef itk::RescaleIntensityImageFilter RescalerType; typedef otb::StreamingResampleImageFilter ResamplerType; @@ -90,7 +90,7 @@ int otbRegionProjectionResampler(int argc, char* argv[]) reader->GenerateOutputInformation(); ImageType::ConstPointer inputImage = reader->GetOutput(); - model->SetImageGeometry(reader->GetOutput()->GetImageKeywordlist()); + model->SetMetadata(reader->GetOutput()->GetImageMetadata()); if (model->IsValidSensorModel() == false) { diff --git a/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.h b/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.h index eb167b2fa46b3ae22e88c0c5b86da44e3dff7e6a..993063ba96bc5de757ecbe287857f4d35fc23048 100644 --- a/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.h +++ b/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.h @@ -140,9 +140,6 @@ public: /** Set the GCP container */ void SetGCPsContainer(const GCPsContainerType& container); - /** Get Keywordlist */ - itkGetConstReferenceMacro(Keywordlist, ImageKeywordlist); - /** Add a GCP to the GCPContainer. This version of the AddGCP method * accepts a 3D ground point and does not use DEM or MeanElevation * to handle the elevation */ @@ -205,8 +202,8 @@ private: /** Container of GCPs */ GCPsContainerType m_GCPsContainer; - /** Keywordlist */ - ImageKeywordlist m_Keywordlist; + /** ImageMetadata */ + ImageMetadata m_ImageMetadata; /** Flag to see if model is up-to-date */ mutable bool m_ModelUpToDate; diff --git a/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.hxx b/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.hxx index a3df285e01aa01b83f4029c7b1a3690c9abb9204..75ab2ab0870dbc8fe6ee45a8e34c509a835ebcda 100644 --- a/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.hxx +++ b/Modules/Filtering/Projection/include/otbGCPsToRPCSensorModelImageFilter.hxx @@ -24,6 +24,9 @@ #include "otbGCPsToRPCSensorModelImageFilter.h" #include "otbRPCSolverAdapter.h" +#include "otbRPCSolver.h" + + #include "otbGenericRSTransform.h" #include "itkMetaDataObject.h" @@ -216,17 +219,12 @@ void GCPsToRPCSensorModelImageFilter::LoadImageGCPs() template void GCPsToRPCSensorModelImageFilter::ComputeErrors() { - typedef GenericRSTransform RSTransformType; + using RSTransformType = GenericRSTransform; RSTransformType::Pointer rsTransform = RSTransformType::New(); - rsTransform->SetInputKeywordList(m_Keywordlist); - rsTransform->InstantiateTransform(); + rsTransform->SetInputImageMetadata(&m_ImageMetadata); - ContinuousIndexType idFix, idOut; - Continuous3DIndexType idOut3D, idTrans3D; - - Point2DType sensorPoint; - Point3DType groundPoint; + rsTransform->InstantiateTransform(); double sum = 0.; m_MeanError = 0.; @@ -237,30 +235,22 @@ void GCPsToRPCSensorModelImageFilter::ComputeErrors() for (unsigned int i = 0; i < m_GCPsContainer.size(); ++i) { // GCP value - sensorPoint = m_GCPsContainer[i].first; - groundPoint = m_GCPsContainer[i].second; + const auto & sensorPoint = m_GCPsContainer[i].first; + const auto & groundPoint = m_GCPsContainer[i].second; // Compute Transform Point3DType groundPointTemp, sensorPointTemp; sensorPointTemp[0] = sensorPoint[0]; sensorPointTemp[1] = sensorPoint[1]; - sensorPointTemp[2] = groundPoint[2]; - groundPointTemp = rsTransform->TransformPoint(sensorPointTemp); + auto outPoint = rsTransform->TransformPoint(sensorPoint); - // Compute Euclidian distance - idFix[0] = sensorPoint[0]; - idFix[1] = sensorPoint[1]; + Point2DType groundPoint2D; - idOut3D[0] = groundPoint[0]; - idOut3D[1] = groundPoint[1]; - idOut3D[2] = groundPoint[2]; + groundPoint2D[0] = groundPoint[0]; + groundPoint2D[1] = groundPoint[1]; - idTrans3D[0] = groundPointTemp[0]; - idTrans3D[1] = groundPointTemp[1]; - idTrans3D[2] = groundPointTemp[2]; - - double error = idOut3D.EuclideanDistanceTo(idTrans3D); + double error = outPoint.EuclideanDistanceTo(outPoint); // Add error to the container m_ErrorsContainer.push_back(error); @@ -279,30 +269,28 @@ void GCPsToRPCSensorModelImageFilter::GenerateOutputInformation() Superclass::GenerateOutputInformation(); // First, retrieve the image pointer - typename TImage::Pointer imagePtr = this->GetOutput(); + auto imagePtr = this->GetOutput(); if (!m_ModelUpToDate) { - double rmsError; - ImageKeywordlist otb_kwl; - otb::RPCSolverAdapter::Solve(m_GCPsContainer, rmsError, otb_kwl); + double rmsError; + + Projection::RPCParam rpcParams; + otb::RPCSolver::Solve(m_GCPsContainer, rmsError, rpcParams); // Retrieve the residual ground error m_RMSGroundError = rmsError; + m_ImageMetadata = imagePtr->GetImageMetadata(); + m_ImageMetadata.Add(MDGeom::RPC, rpcParams); + // Compute errors this->ComputeErrors(); - m_Keywordlist = otb_kwl; - m_ModelUpToDate = true; } - // Update image keywordlist. We need to do it at each stream - // because it will be overwritten by up-stream - // GenerateOutputInformation() calls. - itk::MetaDataDictionary& dict = imagePtr->GetMetaDataDictionary(); - itk::EncapsulateMetaData(dict, MetaDataKey::OSSIMKeywordlistKey, m_Keywordlist); + imagePtr->SetImageMetadata(m_ImageMetadata); } template diff --git a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.h b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.h index 0bdf9b11d514bba30129dfca86b3cafa0b58acdd..8301515621108a92bef5dd1b6d28d8d2ac00f03f 100644 --- a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.h +++ b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.h @@ -166,31 +166,30 @@ public: return m_Transform->GetInputProjectionRef(); } - /** Set/Get Input Keywordlist - * \deprecated + /** Set/Get Input ImageMetadata */ - void SetInputKeywordList(const ImageKeywordlist& kwl) + void SetInputImageMetadata(const ImageMetadata* imd) { - m_Transform->SetOutputKeywordList(kwl); + m_Transform->SetOutputImageMetadata(imd); this->Modified(); } - const ImageKeywordlist GetInputKeywordList() + + const ImageMetadata* GetInputImageMetadata() { - return m_Transform->GetOutputKeywordList(); + return m_Transform->GetOutputImageMetadata(); } - /** Set/Get output Keywordlist - * \deprecated + /** Set/Get Output ImageMetadata */ - void SetOutputKeywordList(const ImageKeywordlist& kwl) + void SetOutputImageMetadata(const ImageMetadata* imd) { - m_Transform->SetInputKeywordList(kwl); + m_Transform->SetInputImageMetadata(imd); this->Modified(); } - const ImageKeywordlist GetOutputKeywordList() + const ImageMetadata* GetOutputImageMetadata() { - return m_Transform->GetInputKeywordList(); + return m_Transform->GetInputImageMetadata(); } /** Useful to set the output parameters from an existing image*/ diff --git a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.hxx b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.hxx index 9706a6754f134777873d8d3ac82d16e2da19777f..7ad6281fb1a5303a222462f9932e6abef7f48f1a 100644 --- a/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.hxx +++ b/Modules/Filtering/Projection/include/otbGenericRSResampleImageFilter.hxx @@ -24,7 +24,6 @@ #include "otbGenericRSResampleImageFilter.h" #include "itkMetaDataObject.h" -#include "otbMetaDataKey.h" #include "itkProgressAccumulator.h" @@ -100,15 +99,10 @@ void GenericRSResampleImageFilter::GenerateOutputInfo m_Resampler->UpdateOutputInformation(); this->GraftOutput(m_Resampler->GetOutput()); - // Encapsulate output projRef and keywordlist - itk::MetaDataDictionary& dict = this->GetOutput()->GetMetaDataDictionary(); - itk::EncapsulateMetaData(dict, MetaDataKey::ProjectionRefKey, this->GetOutputProjectionRef()); - if (this->GetOutputKeywordList().GetSize() > 0) - { - itk::EncapsulateMetaData(dict, MetaDataKey::OSSIMKeywordlistKey, this->GetOutputKeywordList()); - } - - this->GetOutput()->SetProjectionRef(this->GetOutputProjectionRef()); + // Encapsulate output projRef and metadata + if (this->GetOutputImageMetadata() != nullptr) + this->GetOutput()->m_Imd.Merge(*(this->GetOutputImageMetadata())); + this->GetOutput()->m_Imd.Add(MDGeom::ProjectionWKT, this->GetOutputProjectionRef()); } /** @@ -127,20 +121,15 @@ void GenericRSResampleImageFilter::EstimateOutputRpcM tempPtr->SetRegions(region); // Encapsulate the output metadata in the temp image - itk::MetaDataDictionary& tempDict = tempPtr->GetMetaDataDictionary(); - itk::EncapsulateMetaData(tempDict, MetaDataKey::ProjectionRefKey, this->GetOutputProjectionRef()); - itk::EncapsulateMetaData(tempDict, MetaDataKey::OSSIMKeywordlistKey, this->GetOutputKeywordList()); + tempPtr->m_Imd.Add(MDGeom::ProjectionWKT, this->GetOutputProjectionRef()); + tempPtr->SetImageMetadata(*(this->GetOutputImageMetadata())); // Estimate the rpc model from the temp image m_OutputRpcEstimator->SetInput(tempPtr); m_OutputRpcEstimator->UpdateOutputInformation(); - // Encapsulate the estimated rpc model in the output - if (m_OutputRpcEstimator->GetOutput()->GetImageKeywordlist().GetSize() > 0) - { - // Fill the transform with the right kwl - m_Transform->SetInputKeywordList(m_OutputRpcEstimator->GetOutput()->GetImageKeywordlist()); - } + // Fill the transform with the right metadata + m_Transform->SetInputImageMetadata(&(m_OutputRpcEstimator->GetOutput()->GetImageMetadata())); } /** @@ -152,9 +141,8 @@ void GenericRSResampleImageFilter::UpdateTransform() { if (!m_EstimateInputRpcModel) { - m_Transform->SetOutputDictionary(this->GetInput()->GetMetaDataDictionary()); + m_Transform->SetOutputImageMetadata(&(this->GetInput()->GetImageMetadata())); m_Transform->SetOutputProjectionRef(this->GetInput()->GetProjectionRef()); - m_Transform->SetOutputKeywordList(this->GetInput()->GetImageKeywordlist()); } m_Transform->InstantiateTransform(); } @@ -189,10 +177,8 @@ void GenericRSResampleImageFilter::EstimateInputRpcMo m_InputRpcEstimator->SetInput(tempPtr); m_InputRpcEstimator->UpdateOutputInformation(); - // No need to override the input kwl, just setup the - // transform with the kwl estimated - if (m_InputRpcEstimator->GetInput()->GetImageKeywordlist().GetSize() > 0) - m_Transform->SetOutputKeywordList(m_InputRpcEstimator->GetOutput()->GetImageKeywordlist()); + // setup the transform with the estimated RPC model + m_Transform->SetOutputImageMetadata(&(m_InputRpcEstimator->GetOutput()->GetImageMetadata())); // Update the flag for input rpcEstimation in order to not compute // the rpc model for each stream @@ -213,7 +199,7 @@ void GenericRSResampleImageFilter::SetOutputParameter this->SetOutputStartIndex(src->GetLargestPossibleRegion().GetIndex()); this->SetOutputSize(src->GetLargestPossibleRegion().GetSize()); this->SetOutputProjectionRef(src->GetProjectionRef()); - this->SetOutputKeywordList(src->GetImageKeywordlist()); + this->GetOutput()->SetImageMetadata(src->GetImageMetadata()); } /** @@ -229,7 +215,7 @@ void GenericRSResampleImageFilter::SetOutputParameter this->SetOutputStartIndex(image->GetLargestPossibleRegion().GetIndex()); this->SetOutputSize(image->GetLargestPossibleRegion().GetSize()); this->SetOutputProjectionRef(image->GetProjectionRef()); - this->SetOutputKeywordList(image->GetImageKeywordlist()); + this->GetOutput()->SetImageMetadata(image->GetImageMetadata()); } /** diff --git a/Modules/Filtering/Projection/include/otbGeometriesProjectionFilter.h b/Modules/Filtering/Projection/include/otbGeometriesProjectionFilter.h index 6ee68daec0d6a26f6c9fab3471a4ea765d0c33ae..a6667df9dd54af176f97046ef850c52957bbd3eb 100644 --- a/Modules/Filtering/Projection/include/otbGeometriesProjectionFilter.h +++ b/Modules/Filtering/Projection/include/otbGeometriesProjectionFilter.h @@ -26,6 +26,7 @@ #include "otbImageReference.h" #include "itkTransform.h" #include "otbGenericRSTransform.h" +#include "otbImageMetadata.h" #include "OTBProjectionExport.h" #include @@ -143,21 +144,20 @@ private: * \since OTB v 3.14.0 * * \param[in] InputGeometriesSet - * \param[in] InputKeywordList if the \em InputGeometriesSet doesn't have a + * \param[in] InputImageMetadata if the \em InputGeometriesSet doesn't have a * projection reference (i.e. a \c OGRSpatialReference), this filter will use - * the \em InputKeywordList to describe the positionning of the geometries set. + * the \em InputImageMetadata to describe the positionning of the geometries set. * * \param[in,out] OutputGeometriesSet This set of geometries needs to be given to * the filter (in order to set the exact output file/OGR driver). However the * filter is in charge of filling the geometries set. * \param[in] OutputProjectionRef wkt description of the \c OGRSpatialReference * to project the \em InputGeometriesSet into. - * \param[in] OutputKeywordList if no \em OutputProjectionRef is set, the - * projection will be done according to the \em OutputKeywordList. + * \param[in] OutputImageMetadata if no \em OutputProjectionRef is set, the + * projection will be done according to the \em OutputImageMetadata. * * \note Unlike \c VectorDataProjectionFilter, we have to explicitly set which - * to use between projection reference or keyword list. There is no \em - * MetaDataDictionary property. + * to use between projection reference or ImageMetadata. * * \note This filter does not support \em in-place transformation as the spatial * references of the new layer are expected to change. @@ -252,13 +252,28 @@ public: void SetInputOrigin(ImageReference::OriginType const& origin); void SetOutputOrigin(ImageReference::OriginType const& origin); //@} - /**\name Keywords lists accessors and mutators */ + + /**\name ImageMetadata accessors and mutators */ //@{ - itkGetMacro(InputKeywordList, ImageKeywordlist); - void SetInputKeywordList(const ImageKeywordlist& kwl); + const ImageMetadata* GetInputImageMetadata() const + { + return m_InputImageMetadata; + } + void SetInputImageMetadata(const ImageMetadata* imd) + { + m_InputImageMetadata = imd; + this->Modified(); + } - itkGetMacro(OutputKeywordList, ImageKeywordlist); - void SetOutputKeywordList(const ImageKeywordlist& kwl); + const ImageMetadata* GetOutputImageMetadata() const + { + return m_OutputImageMetadata; + } + void SetOutputImageMetadata(const ImageMetadata* imd) + { + m_OutputImageMetadata = imd; + this->Modified(); + } //@} /**\name Projection references accessors and mutators @@ -296,8 +311,8 @@ private: //@} std::string m_OutputProjectionRef; // in WKT format! - ImageKeywordlist m_InputKeywordList; - ImageKeywordlist m_OutputKeywordList; + const ImageMetadata* m_InputImageMetadata = nullptr; + const ImageMetadata* m_OutputImageMetadata = nullptr; }; } // end namespace otb diff --git a/Modules/Filtering/Projection/include/otbGeometriesProjectionFilter.hxx b/Modules/Filtering/Projection/include/otbGeometriesProjectionFilter.hxx index b62b6978f901834a7636f5fe544443b128de79c1..818f5b6893f2af162be19753f575d0e53c0a911a 100644 --- a/Modules/Filtering/Projection/include/otbGeometriesProjectionFilter.hxx +++ b/Modules/Filtering/Projection/include/otbGeometriesProjectionFilter.hxx @@ -79,17 +79,4 @@ inline void otb::GeometriesProjectionFilter::SetOutputOrigin(ImageReference::Ori m_OutputImageReference.SetOrigin(origin); } - -inline void otb::GeometriesProjectionFilter::SetInputKeywordList(const ImageKeywordlist& kwl) -{ - this->m_InputKeywordList = kwl; - this->Modified(); -} - -inline void otb::GeometriesProjectionFilter::SetOutputKeywordList(const ImageKeywordlist& kwl) -{ - this->m_OutputKeywordList = kwl; - this->Modified(); -} - #endif diff --git a/Modules/Filtering/Projection/include/otbGroundSpacingImageFunction.hxx b/Modules/Filtering/Projection/include/otbGroundSpacingImageFunction.hxx index c327b5758e8f17ab402cd6a42140b28e31974bb3..89f317d7686a46cbf31ef070a04c730cd3c38b31 100644 --- a/Modules/Filtering/Projection/include/otbGroundSpacingImageFunction.hxx +++ b/Modules/Filtering/Projection/include/otbGroundSpacingImageFunction.hxx @@ -116,8 +116,7 @@ GroundSpacingImageFunction::GetPixelLocation(const Index } TransformType::Pointer transform = TransformType::New(); - const itk::MetaDataDictionary& inputDict = this->GetInputImage()->GetMetaDataDictionary(); - transform->SetInputDictionary(inputDict); + transform->SetOutputImageMetadata(&(this->GetInputImage()->GetImageMetadata())); transform->SetInputOrigin(this->GetInputImage()->GetOrigin()); transform->SetInputSpacing(this->GetInputImage()->GetSignedSpacing()); diff --git a/Modules/Filtering/Projection/include/otbImageToEnvelopeVectorDataFilter.hxx b/Modules/Filtering/Projection/include/otbImageToEnvelopeVectorDataFilter.hxx index 29322b3254681c5c61daf87d8cb44f5f10c63fc3..d0ad9de2f12d97fac7fe2e99eb45fa2a1caca81c 100644 --- a/Modules/Filtering/Projection/include/otbImageToEnvelopeVectorDataFilter.hxx +++ b/Modules/Filtering/Projection/include/otbImageToEnvelopeVectorDataFilter.hxx @@ -101,7 +101,7 @@ void ImageToEnvelopeVectorDataFilter::Instantiat m_Transform = InternalTransformType::New(); m_Transform->SetOutputProjectionRef(m_OutputProjectionRef); m_Transform->SetInputProjectionRef(inputPtr->GetProjectionRef()); - m_Transform->SetInputKeywordList(inputPtr->GetImageKeywordlist()); + m_Transform->SetInputImageMetadata(&(inputPtr->GetImageMetadata())); m_Transform->InstantiateTransform(); } diff --git a/Modules/Filtering/Projection/include/otbPhysicalToRPCSensorModelImageFilter.hxx b/Modules/Filtering/Projection/include/otbPhysicalToRPCSensorModelImageFilter.hxx index 1e2cbc68a081fb954e8fe574734da7199866a3af..07535bf781d4eec5b9ae8f8da0c19ec095dbb380 100644 --- a/Modules/Filtering/Projection/include/otbPhysicalToRPCSensorModelImageFilter.hxx +++ b/Modules/Filtering/Projection/include/otbPhysicalToRPCSensorModelImageFilter.hxx @@ -65,7 +65,7 @@ void PhysicalToRPCSensorModelImageFilter::GenerateOutputInformation() // Build the grid // Generate GCPs from physical sensor model RSTransformPointerType rsTransform = RSTransformType::New(); - rsTransform->SetInputKeywordList(input->GetImageKeywordlist()); + rsTransform->SetInputImageMetadata(&(input->GetImageMetadata())); rsTransform->InstantiateTransform(); // Compute the size of the grid @@ -91,9 +91,8 @@ void PhysicalToRPCSensorModelImageFilter::GenerateOutputInformation() otbGenericMsgDebugMacro(<< "RPC model estimated. RMS ground error: " << m_GCPsToSensorModelFilter->GetRMSGroundError() << ", Mean error: " << m_GCPsToSensorModelFilter->GetMeanError()); - // Encapsulate the keywordlist - itk::MetaDataDictionary& dict = this->GetOutput()->GetMetaDataDictionary(); - itk::EncapsulateMetaData(dict, MetaDataKey::OSSIMKeywordlistKey, m_GCPsToSensorModelFilter->GetKeywordlist()); + + this->GetOutput()->SetImageMetadata(m_GCPsToSensorModelFilter->GetOutput()->GetImageMetadata()); // put the flag to true m_OutputInformationGenerated = true; diff --git a/Modules/Filtering/Projection/include/otbRPCSolver.h b/Modules/Filtering/Projection/include/otbRPCSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..0f79525d8c48bae0f5bf2e392ca9c05d47c901fc --- /dev/null +++ b/Modules/Filtering/Projection/include/otbRPCSolver.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef otbRPCSolver_h +#define otbRPCSolver_h + +#include "itkPoint.h" +#include "otbGeometryMetadata.h" + +namespace otb +{ + namespace RPCSolver + { + using Point2DType = itk::Point; + using Point3DType = itk::Point; + using GCPType = std::pair; + using GCPsContainerType = std::vector; + + /** Solve RPC modelling from a set of GCPs and image bounds. + * The estimated RPC model is written in a RPCParam structure that can + * for instance be added to an ImageMetadata object. + * Please note that at least 20 points are required to estimate the + * RPC model. Between 20 and 40 points, the estimated model will + * not provide elevation support, since there are not enough points + * to estimate all the coefficients. Starting at 40 points, a full + * RPC model is estimated. + */ + void Solve(const GCPsContainerType& gcpContainer, double& rmsError, Projection::RPCParam& outputParams); + }; + +} + + +#endif diff --git a/Modules/Filtering/Projection/include/otbVectorDataIntoImageProjectionFilter.hxx b/Modules/Filtering/Projection/include/otbVectorDataIntoImageProjectionFilter.hxx index 7dc369726b0bc22c9b5dacb98ba053cb818a88de..a69ff6819817161c852d3f91f9904790da78f653 100644 --- a/Modules/Filtering/Projection/include/otbVectorDataIntoImageProjectionFilter.hxx +++ b/Modules/Filtering/Projection/include/otbVectorDataIntoImageProjectionFilter.hxx @@ -176,7 +176,7 @@ void VectorDataIntoImageProjectionFilter::Generat if (m_InputImage->GetProjectionRef().empty() || boost::algorithm::istarts_with(m_InputImage->GetProjectionRef(), "LOCAL_CS")) { - m_VdProjFilter->SetOutputKeywordList(m_InputImage->GetImageKeywordlist()); + m_VdProjFilter->SetOutputImageMetadata(&m_InputImage->GetImageMetadata()); } else { diff --git a/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.h b/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.h index e1ef3df95421795d08ad05035b07cdf0dc845a64..79cf867c4e50202f71e20684ed266371f096e65c 100644 --- a/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.h +++ b/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.h @@ -127,20 +127,6 @@ public: itkSetStringMacro(OutputProjectionRef); itkGetStringMacro(OutputProjectionRef); - itkGetMacro(InputKeywordList, ImageKeywordlist); - void SetInputKeywordList(const ImageKeywordlist& kwl) - { - this->m_InputKeywordList = kwl; - this->Modified(); - } - - itkGetMacro(OutputKeywordList, ImageKeywordlist); - void SetOutputKeywordList(const ImageKeywordlist& kwl) - { - this->m_OutputKeywordList = kwl; - this->Modified(); - } - /** Set the origin of the vector data. * \sa GetOrigin() */ itkSetMacro(InputOrigin, OriginType); @@ -173,6 +159,29 @@ public: itkGetConstReferenceMacro(OutputSpacing, SpacingType); + /**\name ImageMetadata accessors and mutators */ + //@{ + const ImageMetadata* GetInputImageMetadata() const + { + return m_InputImageMetadata; + } + void SetInputImageMetadata(const ImageMetadata* imd) + { + m_InputImageMetadata = imd; + this->Modified(); + } + + const ImageMetadata* GetOutputImageMetadata() const + { + return m_OutputImageMetadata; + } + void SetOutputImageMetadata(const ImageMetadata* imd) + { + m_OutputImageMetadata = imd; + this->Modified(); + } + //@} + protected: VectorDataProjectionFilter(); ~VectorDataProjectionFilter() override @@ -196,8 +205,8 @@ private: InternalTransformPointerType m_Transform; std::string m_InputProjectionRef; std::string m_OutputProjectionRef; - ImageKeywordlist m_InputKeywordList; - ImageKeywordlist m_OutputKeywordList; + const ImageMetadata* m_InputImageMetadata = nullptr; + const ImageMetadata* m_OutputImageMetadata = nullptr; SpacingType m_InputSpacing; OriginType m_InputOrigin; diff --git a/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.hxx b/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.hxx index 286e061e6443c61d724c0d93926621938c27642b..1153ca2d4c8a9ad135c37460e6ba6b2d18eda73b 100644 --- a/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.hxx +++ b/Modules/Filtering/Projection/include/otbVectorDataProjectionFilter.hxx @@ -37,8 +37,6 @@ VectorDataProjectionFilter::VectorDataProje { m_InputProjectionRef.clear(); m_OutputProjectionRef.clear(); - m_InputKeywordList.Clear(); - m_OutputKeywordList.Clear(); m_InputSpacing.Fill(1); m_InputOrigin.Fill(0); m_OutputSpacing.Fill(1); @@ -241,35 +239,24 @@ VectorDataProjectionFilter::ProcessPolygonL template void VectorDataProjectionFilter::InstantiateTransform(void) { - - // otbMsgDevMacro(<< "Information to instantiate transform (VectorDataProjectionFilter): "); - // otbMsgDevMacro(<< " * Input Origin: " << m_InputOrigin); - // otbMsgDevMacro(<< " * Input Spacing: " << m_InputSpacing); - // otbMsgDevMacro(<< " * Input keyword list: " - // << ((m_InputKeywordList.GetSize() == 0)?"Empty":"Full")); - // otbMsgDevMacro(<< " * Input projection: " << m_InputProjectionRef); - // otbMsgDevMacro(<< " * Output keyword list: " - // << ((m_OutputKeywordList.GetSize() == 0)?"Empty":"Full")); - // otbMsgDevMacro(<< " * Output projection: " << m_OutputProjectionRef); - // otbMsgDevMacro(<< " * Output Origin: " << m_OutputOrigin); - // otbMsgDevMacro(<< " * Output Spacing: " << m_OutputSpacing); - m_Transform = InternalTransformType::New(); - InputVectorDataPointer input = this->GetInput(); + InputVectorDataPointer input = this->GetInput(); const itk::MetaDataDictionary& inputDict = input->GetMetaDataDictionary(); OutputVectorDataPointer output = this->GetOutput(); itk::MetaDataDictionary& outputDict = output->GetMetaDataDictionary(); - // m_Transform->SetInputDictionary(input->GetMetaDataDictionary()); - m_Transform->SetInputDictionary(inputDict); - m_Transform->SetOutputDictionary(output->GetMetaDataDictionary()); + m_Transform->SetInputImageMetadata(m_InputImageMetadata); + m_Transform->SetOutputImageMetadata(m_OutputImageMetadata); + + if (m_InputProjectionRef.empty()) + { + itk::ExposeMetaData(inputDict, MetaDataKey::ProjectionRefKey, m_InputProjectionRef); + } m_Transform->SetInputProjectionRef(m_InputProjectionRef); m_Transform->SetOutputProjectionRef(m_OutputProjectionRef); - m_Transform->SetInputKeywordList(m_InputKeywordList); - m_Transform->SetOutputKeywordList(m_OutputKeywordList); m_Transform->SetInputSpacing(m_InputSpacing); m_Transform->SetInputOrigin(m_InputOrigin); m_Transform->SetOutputSpacing(m_OutputSpacing); @@ -282,11 +269,6 @@ void VectorDataProjectionFilter::Instantiat m_OutputProjectionRef = m_Transform->GetOutputProjectionRef(); // If the projection information for the output is provided, propagate it - - if (m_OutputKeywordList.GetSize() != 0) - { - itk::EncapsulateMetaData(outputDict, MetaDataKey::OSSIMKeywordlistKey, m_OutputKeywordList); - } if (!m_OutputProjectionRef.empty()) { itk::EncapsulateMetaData(outputDict, MetaDataKey::ProjectionRefKey, m_OutputProjectionRef); diff --git a/Modules/Filtering/Projection/src/CMakeLists.txt b/Modules/Filtering/Projection/src/CMakeLists.txt index 2cbbcba088dc305858c10963da2f13aa7b60746f..5b63fdaf1eb0b799f505335a78877e9f04117e77 100644 --- a/Modules/Filtering/Projection/src/CMakeLists.txt +++ b/Modules/Filtering/Projection/src/CMakeLists.txt @@ -21,6 +21,7 @@ set(OTBProjection_SRC otbGeometriesProjectionFilter.cxx otbPleiadesPToXSAffineTransformCalculator.cxx + otbRPCSolver.cxx ) add_library(OTBProjection ${OTBProjection_SRC}) diff --git a/Modules/Filtering/Projection/src/otbGeometriesProjectionFilter.cxx b/Modules/Filtering/Projection/src/otbGeometriesProjectionFilter.cxx index 53d9503ee596318c58dd60d7775f74c497fea3ae..cf243035fc79bff56d77ce58dd61c7bca48b5f30 100644 --- a/Modules/Filtering/Projection/src/otbGeometriesProjectionFilter.cxx +++ b/Modules/Filtering/Projection/src/otbGeometriesProjectionFilter.cxx @@ -178,8 +178,8 @@ void otb::GeometriesProjectionFilter::DoFinalizeInitialization() // process is known // m_Transform->SetInputProjectionRef(m_InputProjectionRef); m_Transform->SetOutputProjectionRef(m_OutputProjectionRef); - m_Transform->SetInputKeywordList(m_InputKeywordList); - m_Transform->SetOutputKeywordList(m_OutputKeywordList); + m_Transform->SetInputImageMetadata(m_InputImageMetadata); + m_Transform->SetOutputImageMetadata(m_OutputImageMetadata); m_Transform->SetInputSpacing(m_InputImageReference.GetSpacing()); m_Transform->SetInputOrigin(m_InputImageReference.GetOrigin()); diff --git a/Modules/Filtering/Projection/src/otbRPCSolver.cxx b/Modules/Filtering/Projection/src/otbRPCSolver.cxx new file mode 100644 index 0000000000000000000000000000000000000000..eeded82126cd45c59a3770e2eec1f8071646c52e --- /dev/null +++ b/Modules/Filtering/Projection/src/otbRPCSolver.cxx @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbRPCSolver.h" +#include "otbMacro.h" + +#include "vnl/algo/vnl_svd.h" +#include "vnl/algo/vnl_matrix_inverse.h" + +#include "otbGDALRPCTransformer.h" + +namespace otb +{ + +using PrecisionType = double; +using VectorType = vnl_vector; +using MatrixType = vnl_matrix; +using DiagonalMatrixType = vnl_diag_matrix; + +const PrecisionType epsilon = 1e-7; + +void UpdateMatrix(const VectorType & f, + const std::vector & x, + const std::vector & y, + const std::vector & z, + MatrixType & M) +{ + for(unsigned int i = 0; i < f.size(); i++) + { + M[i][0] = 1; + M[i][1] = x[i]; + M[i][2] = y[i]; + M[i][3] = z[i]; + M[i][4] = x[i]*y[i]; + M[i][5] = x[i]*z[i]; + M[i][6] = y[i]*z[i]; + M[i][7] = x[i]*x[i]; + M[i][8] = y[i]*y[i]; + M[i][9] = z[i]*z[i]; + M[i][10] = x[i]*y[i]*z[i]; + M[i][11] = x[i]*x[i]*x[i]; + M[i][12] = x[i]*y[i]*y[i]; + M[i][13] = x[i]*z[i]*z[i]; + M[i][14] = x[i]*x[i]*y[i]; + M[i][15] = y[i]*y[i]*y[i]; + M[i][16] = y[i]*z[i]*z[i]; + M[i][17] = x[i]*x[i]*z[i]; + M[i][18] = y[i]*y[i]*z[i]; + M[i][19] = z[i]*z[i]*z[i]; + M[i][20] = -f[i]*x[i]; + M[i][21] = -f[i]*y[i]; + M[i][22] = -f[i]*z[i]; + M[i][23] = -f[i]*x[i]*y[i]; + M[i][24] = -f[i]*x[i]*z[i]; + M[i][25] = -f[i]*y[i]*z[i]; + M[i][26] = -f[i]*x[i]*x[i]; + M[i][27] = -f[i]*y[i]*y[i]; + M[i][28] = -f[i]*z[i]*z[i]; + M[i][29] = -f[i]*x[i]*y[i]*z[i]; + M[i][30] = -f[i]*x[i]*x[i]*x[i]; + M[i][31] = -f[i]*x[i]*y[i]*y[i]; + M[i][32] = -f[i]*x[i]*z[i]*z[i]; + M[i][33] = -f[i]*x[i]*x[i]*y[i]; + M[i][34] = -f[i]*y[i]*y[i]*y[i]; + M[i][35] = -f[i]*y[i]*z[i]*z[i]; + M[i][36] = -f[i]*x[i]*x[i]*z[i]; + M[i][37] = -f[i]*y[i]*y[i]*z[i]; + M[i][38] = -f[i]*z[i]*z[i]*z[i]; + } +} + +void UpdateWeights(const std::vector & x, + const std::vector & y, + const std::vector & z, + const VectorType & coeff, + DiagonalMatrixType & W) +{ + std::vector row(coeff.size()); + + for(unsigned int i = 0; i < x.size(); i++) + { + W[i] = 0.; + + row[0] = 1; + row[1] = x[i]; + row[2] = y[i]; + row[3] = z[i]; + row[4] = x[i]*y[i]; + row[5] = x[i]*z[i]; + row[6] = y[i]*z[i]; + row[7] = x[i]*x[i]; + row[8] = y[i]*y[i]; + row[9] = z[i]*z[i]; + row[10] = x[i]*y[i]*z[i]; + row[11] = x[i]*x[i]*x[i]; + row[12] = x[i]*y[i]*y[i]; + row[13] = x[i]*z[i]*z[i]; + row[14] = x[i]*x[i]*y[i]; + row[15] = y[i]*y[i]*y[i]; + row[16] = y[i]*z[i]*z[i]; + row[17] = x[i]*x[i]*z[i]; + row[18] = y[i]*y[i]*z[i]; + row[19] = z[i]*z[i]*z[i]; + + for (unsigned int j =0; j < row.size(); j++) + { + W[i] += row[j]*coeff[j]; + } + + if(W[i] > epsilon) + { + W[i] = 1.0/W[i]; + } + } +} + +void computeCoefficients(const std::vector & f, + const std::vector & x, + const std::vector & y, + const std::vector & z, + std::vector & outCoeffs) +{ + auto numberOfPoints = f.size(); + + // Iteratively reweighted least square + + MatrixType M(numberOfPoints, 39); + VectorType r(numberOfPoints, numberOfPoints, f.data()); + DiagonalMatrixType weights(numberOfPoints, 1.); + + PrecisionType res = std::numeric_limits::max(); + VectorType coeffs; + + for (int i =0; i<10; i++) + { + if (res < epsilon) + { + break; + } + auto w2 = weights * weights; + + UpdateMatrix(r, x, y ,z ,M); + + vnl_svd svd(M.transpose()*w2*M); + + auto diag = svd.W(); + for (unsigned int idx = 0; idx < diag.size(); idx++) + { + if(diag[idx] > epsilon) + { + diag[idx] = 1.0/diag[idx]; + } + else + { + diag[idx] = 0.0; + } + } + + // "svd.V() * diag * svd.U().transpose()" is the inverse of M.transpose()*w2*M + coeffs = svd.V() * diag * svd.U().transpose() * M.transpose()*w2*r; + + auto denominator = VectorType(&(coeffs[19]), 20); + denominator[0] = 1; + + UpdateWeights( x, y ,z , denominator, weights); + + // compute the residual + auto residual = M.transpose()*w2*(M*coeffs-r); + + res = inner_product(residual,residual); + } + + outCoeffs.assign(coeffs.begin(), coeffs.end()); +} + + +void RPCSolver::Solve(const GCPsContainerType& gcpContainer, PrecisionType& rmsError, Projection::RPCParam& outputParams) +{ + // By default, use elevation provided with ground control points + bool useElevation = true; + auto numberOfPoints = gcpContainer.size(); + + std::vector colNorm; + colNorm.reserve(numberOfPoints); + + std::vector lineNorm; + lineNorm.reserve(numberOfPoints); + + std::vector lonNorm; + lonNorm.reserve(numberOfPoints); + + std::vector latNorm; + latNorm.reserve(numberOfPoints); + + std::vector altNorm; + altNorm.reserve(numberOfPoints); + + // Check for enough points + if (numberOfPoints < 20) + { + itkGenericExceptionMacro(<< "At least 20 points are required to estimate the 40 parameters of a RPC model without elevation support, and 40 are required " + "to estimate the 80 parameters of a RPC model with elevation support. Only " + << numberOfPoints << " points were given."); + } + + // If not enough points are given for a proper estimation of RPC + // with elevation support, disable elevation. This will result in + // all coefficients related to elevation set to zero. + if (numberOfPoints < 40) + { + otbGenericWarningMacro("Only " << numberOfPoints << " ground control points are provided, can not estimate a RPC model with elevation support (at " + "least 40 points required). Elevation support will be disabled for RPC estimation. All " + "coefficients related to elevation will be set to zero, and elevation will have no effect on the " + "resulting transform."); + useElevation = false; + } + + // Compute Offsets + + // Find the ground points center of mass + PrecisionType accLat = 0.; + PrecisionType accLon = 0.; + PrecisionType accAlt = 0.; + + for (const auto & gcp : gcpContainer) + { + const auto & groundPoint = gcp.second; + + accLon += groundPoint[0]; + accLat += groundPoint[1]; + if (useElevation) + { + accAlt += groundPoint[2]; + } + } + + Point3DType groundCenter; + groundCenter[0] = accLon / numberOfPoints; + groundCenter[1] = accLat /numberOfPoints; + groundCenter[2] = useElevation ? accAlt / numberOfPoints : 0.; + + + PrecisionType minc = std::numeric_limits::max(); + PrecisionType minl = std::numeric_limits::max(); + PrecisionType maxc = std::numeric_limits::min(); + PrecisionType maxl = std::numeric_limits::min(); + + for (const auto & gcp : gcpContainer) + { + const auto & imagePoint = gcp.first; + + minc = std::min(imagePoint[0], minc); + maxc = std::max(imagePoint[0], maxc); + + minl = std::min(imagePoint[1], minl); + maxl = std::max(imagePoint[1], maxl); + } + + Point2DType imageCenter; + imageCenter[0] = (minc + maxc -1)/2.0; + imageCenter[1] = (minl + maxl -1)/2.0; + + auto height = std::abs(minl - maxl) +1; + auto width = std::abs(minc - maxc) +1; + + PrecisionType maxDeltaLon = std::numeric_limits::min(); + PrecisionType maxDeltaLat = std::numeric_limits::min(); + PrecisionType maxDeltaAlt = std::numeric_limits::min(); + + for (const auto & gcp : gcpContainer) + { + const auto & imagePoint = gcp.first; + const auto & groundPoint = gcp.second; + auto deltaLon = groundPoint[0] - groundCenter[0]; + auto deltaLat = groundPoint[1] - groundCenter[1]; + auto deltaAlt = useElevation ? groundPoint[2] - groundCenter[2] : 0.; + auto alt = useElevation ? groundPoint[2] : 0.; + + maxDeltaLon = std::max(maxDeltaLon, std::abs(deltaLon)); + maxDeltaLat = std::max(maxDeltaLat, std::abs(deltaLat)); + maxDeltaAlt = std::max(maxDeltaAlt, std::abs(alt)); + + colNorm.push_back( (imagePoint[0]- imageCenter[0] -0.5) / width * 2.); + lineNorm.push_back( (imagePoint[1]- imageCenter[1] -0.5)/ height * 2.); + lonNorm.push_back(deltaLon); + latNorm.push_back(deltaLat); + altNorm.push_back(deltaAlt); + } + + if(maxDeltaLat < 1.0) + { + maxDeltaLat = 1.0; + } + else + { + for (auto & lat: latNorm) + { + lat /= maxDeltaLat; + } + } + + + if(maxDeltaLon < 1.0) + { + maxDeltaLon = 1.0; + } + else + { + for (auto & lon: lonNorm) + { + lon /= maxDeltaLon; + } + } + + if(maxDeltaAlt < 1.0) + { + maxDeltaAlt = 1.0; + } + else + { + for (auto & alt: altNorm) + { + alt /= maxDeltaAlt; + } + } + + std::vector colCoeffs; + computeCoefficients(colNorm, lonNorm, latNorm, altNorm, colCoeffs); + + std::vector lineCoeffs; + computeCoefficients(lineNorm, lonNorm, latNorm, altNorm, lineCoeffs); + + // Offsets + outputParams.SampleOffset = imageCenter[0]; + outputParams.LineOffset = imageCenter[1]; + outputParams.LonOffset = groundCenter[0]; + outputParams.LatOffset = groundCenter[1]; + outputParams.HeightOffset = groundCenter[2]; + + // Scales + outputParams.SampleScale = width/2.0; + outputParams.LineScale = height/2.0; + outputParams.LatScale = maxDeltaLat; + outputParams.LonScale = maxDeltaLon; + outputParams.HeightScale = maxDeltaAlt; + + // Line numerator coefficients + std::copy(lineCoeffs.begin(), lineCoeffs.begin() +20, outputParams.LineNum); + // Line denominator coefficients + outputParams.LineDen[0] = 1.; + std::copy(lineCoeffs.begin()+20, lineCoeffs.end(), outputParams.LineDen +1); + + // Sample numerator coefficients + std::copy(colCoeffs.begin(), colCoeffs.begin() +20, outputParams.SampleNum); + // Sample denominator coefficients + outputParams.SampleDen[0] = 1.; + std::copy(colCoeffs.begin()+20, colCoeffs.end(), outputParams.SampleDen +1); + + // Compute rmse between input ground point and transformed image points + GDALRPCTransformer transformer(outputParams, false); + + PrecisionType rmseAcc = 0.; + + for (const auto & gcp : gcpContainer) + { + auto outPoint = transformer.InverseTransform(gcp.second); + rmseAcc += (gcp.first[0] - outPoint[0]) * (gcp.first[0] - outPoint[0]) + + (gcp.first[1] - outPoint[1]) * (gcp.first[1] - outPoint[1]); + } + + rmsError = std::sqrt(rmseAcc/numberOfPoints); +} + +} \ No newline at end of file diff --git a/Modules/Filtering/Projection/test/CMakeLists.txt b/Modules/Filtering/Projection/test/CMakeLists.txt index e06b1613f13106d032fb9f137c71df3a1c059212..f14471bb33761bc456de57f8053477d55e377176 100644 --- a/Modules/Filtering/Projection/test/CMakeLists.txt +++ b/Modules/Filtering/Projection/test/CMakeLists.txt @@ -55,6 +55,7 @@ otbGeometriesProjectionFilterFromMapToImage.cxx otbGeometriesProjectionFilterFromMapToEPSG.cxx otbVectorDataProjectionFilter.cxx otbImportGeoInformationImageFilter.cxx +otbRPCSolverTest.cxx ) @@ -65,7 +66,7 @@ set(GEOMGCP "QB/qb-1" #LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} "ikonos/ikonos-1" #LARGEINPUT{IKONOS/BLOSSEVILLE/po_2619900_nir_0000000.tif} "rapideye/rapideye-1" #LARGEINPUT{RAPIDEYE/level1B/2008-12-25T005918_RE3_1B-NAC_397971_12345_band3.ntf} -"sentinel1/sentinel1-1" #LARGEINPUT{SENTINEL1/S1A_S6_SLC__1SSV_20150619T195043/measurement/s1a-s6-slc-vv-20150619t195043-20150619t195101-006447-00887d-001.tiff} +#"sentinel1/sentinel1-1" #LARGEINPUT{SENTINEL1/S1A_S6_SLC__1SSV_20150619T195043/measurement/s1a-s6-slc-vv-20150619t195043-20150619t195101-006447-00887d-001.tiff} TODO: Reactivate when new SARModel is implemented ) set(NEEDEDKW @@ -127,8 +128,8 @@ endforeach() #Other sensor : no keyword check set(GEOMGCP -"ers2/ers2-1" #LARGEINPUT{SAR_ERS2_SLCI_SCENE1/DAT_01.001} -"spot5/spot5-1" #LARGEINPUT{SPOT5/TEHERAN/IMAGERY.TIF} +#"ers2/ers2-1" #LARGEINPUT{SAR_ERS2_SLCI_SCENE1/DAT_01.001} TODO: Reactivate when new SARModel is implemented +# "spot5/spot5-1" #LARGEINPUT{SPOT5/TEHERAN/IMAGERY.TIF} TODO: Reactivate when new SensorModel is implemented "geoeye1/geoeye1-1" #LARGEINPUT{GEOEYE/MARCILLOLES/po_350134_bgrn_0000001.tif} ) @@ -183,7 +184,7 @@ SPOT6/600143101-Primary-Bundle-JP2-LOSSLESS/PROD_SPOT6_001/VOL_SPOT6_001_A/IMG_S QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF IKONOS/BLOSSEVILLE/po_2619900_nir_0000000.tif RAPIDEYE/level1B/2008-12-25T005918_RE3_1B-NAC_397971_12345_band3.ntf -SENTINEL1/S1A_S6_SLC__1SSV_20150619T195043/measurement/s1a-s6-slc-vv-20150619t195043-20150619t195101-006447-00887d-001.tiff +#SENTINEL1/S1A_S6_SLC__1SSV_20150619T195043/measurement/s1a-s6-slc-vv-20150619t195043-20150619t195101-006447-00887d-001.tiff # TODO Reactivate when SARModel is implemented ) set(TOLERANCE_RATIO @@ -581,6 +582,35 @@ otb_add_test(NAME prTvLeastSquareAffineTransformEstimator COMMAND otbProjectionT 352 807 919 10023 12102 14181 ) + +otb_add_test(NAME prTvRPCSolverNoDEMValidationTest COMMAND otbProjectionTestDriver + otbRPCSolverTest + LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} + 10 0.25 0.35 + no + no + ) + +otb_add_test(NAME prTvRPCSolverNotEnoughPointsForElevationTest COMMAND otbProjectionTestDriver + otbRPCSolverTest + LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} + 5 0.25 0.35 + no + no + ) + +otb_add_test(NAME prTvRPCSolverNotEnoughPointsTest COMMAND otbProjectionTestDriver + otbRPCSolverTest + LARGEINPUT{QUICKBIRD/TOULOUSE/000000128955_01_P001_PAN/02APR01105228-P1BS-000000128955_01_P001.TIF} + 4 0.25 0.35 + ${INPUTDATA}/DEM/srtm_directory/ + ${INPUTDATA}/DEM/egm96.grd + ) +if (OTB_DATA_USE_LARGEINPUT) + set_property(TEST prTvRPCSolverNotEnoughPointsTest PROPERTY WILL_FAIL TRUE) +endif() + + set(VALID_CONDITION err=12) if(OTB_OSSIM_VERSION LESS 20200) set(VALID_CONDITION err=10) diff --git a/Modules/Filtering/Projection/test/otbCompositeTransform.cxx b/Modules/Filtering/Projection/test/otbCompositeTransform.cxx index 0f69fe3c3257ad76c81da14edc869d85e6ec2f09..e52c27357ddde65cfc70e4682e32d347b346743a 100644 --- a/Modules/Filtering/Projection/test/otbCompositeTransform.cxx +++ b/Modules/Filtering/Projection/test/otbCompositeTransform.cxx @@ -27,7 +27,8 @@ #include "otbGenericMapProjection.h" #include "otbSpatialReference.h" #include "otbCompositeTransform.h" -#include "otbInverseSensorModel.h" +#include "otbRPCInverseTransform.h" +#include "otbMetaDataKey.h" int otbCompositeTransform(int argc, char* argv[]) { @@ -54,9 +55,9 @@ int otbCompositeTransform(int argc, char* argv[]) // UTM31N mapProjection->SetWkt(otb::SpatialReference::FromEPSG(32631).ToWkt()); - typedef otb::InverseSensorModel SensorModelType; + typedef otb::RPCInverseTransform SensorModelType; SensorModelType::Pointer sensorModel = SensorModelType::New(); - sensorModel->SetImageGeometry(reader->GetOutput()->GetImageKeywordlist()); + sensorModel->SetMetadata(reader->GetOutput()->GetImageMetadata()); if (sensorModel->IsValidSensorModel() == false) { diff --git a/Modules/Filtering/Projection/test/otbGCPsToRPCSensorModelImageFilterCheckRpcModel.cxx b/Modules/Filtering/Projection/test/otbGCPsToRPCSensorModelImageFilterCheckRpcModel.cxx index 0370201ff9b03d23497679bc119d902a4c63e39a..1cf120dbf05bc0de3ce2dc63a8a7488be9a823dd 100644 --- a/Modules/Filtering/Projection/test/otbGCPsToRPCSensorModelImageFilterCheckRpcModel.cxx +++ b/Modules/Filtering/Projection/test/otbGCPsToRPCSensorModelImageFilterCheckRpcModel.cxx @@ -37,9 +37,14 @@ int otbGCPsToRPCSensorModelImageFilterCheckRpcModel(int argc, char* argv[]) nbPoints--; // last argument in not a gcp pairs point tol = stoi(s_tol.substr(s_tol.find("=") + 1)); } + + // Set the DEM Directory + if (std::string(argv[2]).compare("no_output") != 0) + { + otb::DEMHandler::GetInstance().OpenDEMDirectory(argv[2]); + } + // Check if the number of gcp pairs point is consistent - - if (nbPoints % 5 != 0) { std::cerr << "Inconsistent GCPs description!" << std::endl; @@ -51,7 +56,7 @@ int otbGCPsToRPCSensorModelImageFilterCheckRpcModel(int argc, char* argv[]) typedef otb::GCPsToRPCSensorModelImageFilter GCPsToSensorModelFilterType; typedef GCPsToSensorModelFilterType::Point2DType Point2DType; typedef GCPsToSensorModelFilterType::Point3DType Point3DType; - typedef otb::GenericRSTransform GenericRSTransformType; + typedef otb::GenericRSTransform GenericRSTransformType; typedef otb::GeographicalDistance GeoDistanceType; ReaderType::Pointer reader = ReaderType::New(); @@ -90,14 +95,8 @@ int otbGCPsToRPCSensorModelImageFilterCheckRpcModel(int argc, char* argv[]) // geographical coordinates. GenericRSTransformType::Pointer grsTrasnform = GenericRSTransformType::New(); - grsTrasnform->SetInputKeywordList(rpcEstimator->GetKeywordlist()); - otbLogMacro(Debug, << rpcEstimator->GetKeywordlist()); + grsTrasnform->SetInputImageMetadata(&rpcEstimator->GetOutput()->GetImageMetadata()); grsTrasnform->SetOutputProjectionRef("EPSG:4326"); - - // Set the DEM Directory - if (std::string(argv[2]).compare("no_output") != 0) - otb::DEMHandler::GetInstance().OpenDEMDirectory(argv[2]); - grsTrasnform->InstantiateTransform(); // Test @@ -106,17 +105,11 @@ int otbGCPsToRPCSensorModelImageFilterCheckRpcModel(int argc, char* argv[]) for (unsigned int gcpId = 0; gcpId < nbGCPs; ++gcpId) { - Point3DType point; + Point2DType point; point[0] = std::stof(argv[3 + gcpId * 5]); point[1] = std::stof(argv[4 + gcpId * 5]); - point[2] = std::stof(argv[7 + gcpId * 5]); - - Point3DType transformedPoint; - transformedPoint = grsTrasnform->TransformPoint(point); - Point2DType transformedPoint2D; - transformedPoint2D[0] = transformedPoint[0]; - transformedPoint2D[1] = transformedPoint[1]; + auto transformedPoint = grsTrasnform->TransformPoint(point); // reference point Point2DType geoPoint; @@ -124,18 +117,18 @@ int otbGCPsToRPCSensorModelImageFilterCheckRpcModel(int argc, char* argv[]) geoPoint[1] = std::stof(argv[6 + gcpId * 5]); // Search for nans - if (vnl_math_isnan(transformedPoint2D[0]) || vnl_math_isnan(transformedPoint2D[1])) + if (vnl_math_isnan(transformedPoint[0]) || vnl_math_isnan(transformedPoint[1])) { - otbLogMacro(Warning, << "Reference : " << geoPoint << " --> Result of the reprojection using the estimated RpcModel " << transformedPoint2D); + otbLogMacro(Warning, << "Reference : " << geoPoint << " --> Result of the reprojection using the estimated RpcModel " << transformedPoint); otbLogMacro(Warning, << "The result of the projection is nan, there is a problem with the estimated RpcModel"); isErrorDetected = true; } // Search for wrong projection results - double residual = geoDistance->Evaluate(geoPoint, transformedPoint2D); + double residual = geoDistance->Evaluate(geoPoint, transformedPoint); if (residual > tol) { - otbLogMacro(Warning, << "Reference : " << geoPoint << " --> Result of the reprojection using the estimated RpcModel " << transformedPoint2D << std::endl + otbLogMacro(Warning, << "Reference : " << geoPoint << " --> Result of the reprojection using the estimated RpcModel " << transformedPoint << std::endl << " Residual [" << residual << "] is higher than the tolerance [" << tol << "], there is a problem with the estimated RpcModel"); isErrorDetected = true; } diff --git a/Modules/Filtering/Projection/test/otbGCPsToRPCSensorModelImageFilterWithoutDEM.cxx b/Modules/Filtering/Projection/test/otbGCPsToRPCSensorModelImageFilterWithoutDEM.cxx index 4320d792e7cfcb390b856844bf2ccab83ac379de..b2bce33a3c785e87ef5839ff4ede86148eaa1aaf 100644 --- a/Modules/Filtering/Projection/test/otbGCPsToRPCSensorModelImageFilterWithoutDEM.cxx +++ b/Modules/Filtering/Projection/test/otbGCPsToRPCSensorModelImageFilterWithoutDEM.cxx @@ -80,7 +80,9 @@ int otbGCPsToRPCSensorModelImageFilterWithoutDEM(int argc, char* argv[]) ofs.setf(std::ios::fixed, std::ios::floatfield); ofs.precision(10); - ofs << rpcEstimator->GetOutput()->GetImageKeywordlist() << std::endl; + auto outputRPC = boost::any_cast(rpcEstimator->GetOutput()->GetImageMetadata()[otb::MDGeom::RPC]); + + ofs << outputRPC.ToJSON() << std::endl; ofs << "Residual ground error: " << rpcEstimator->GetRMSGroundError() << std::endl; ofs.close(); diff --git a/Modules/Filtering/Projection/test/otbGenericRSTransformFromImage.cxx b/Modules/Filtering/Projection/test/otbGenericRSTransformFromImage.cxx index 1410fceaf98001ca50b7768e91896a1fef7dd49d..7bdfb1ad02d229858c5ad41ecba3eab6eb75cc28 100644 --- a/Modules/Filtering/Projection/test/otbGenericRSTransformFromImage.cxx +++ b/Modules/Filtering/Projection/test/otbGenericRSTransformFromImage.cxx @@ -65,13 +65,13 @@ int otbGenericRSTransformFromImage(int itkNotUsed(argc), char* argv[]) TransformType::Pointer wgs2img = TransformType::New(); wgs2img->SetInputProjectionRef(wgsRef); wgs2img->SetOutputProjectionRef(reader->GetOutput()->GetProjectionRef()); - wgs2img->SetOutputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + wgs2img->SetOutputImageMetadata(&(reader->GetOutput()->GetImageMetadata())); wgs2img->InstantiateTransform(); // Instantiate Image->WGS transform TransformType::Pointer img2wgs = TransformType::New(); img2wgs->SetInputProjectionRef(reader->GetOutput()->GetProjectionRef()); - img2wgs->SetInputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + img2wgs->SetInputImageMetadata(&(reader->GetOutput()->GetImageMetadata())); img2wgs->SetOutputProjectionRef(wgsRef); img2wgs->InstantiateTransform(); @@ -126,13 +126,13 @@ int otbGenericRSTransformImageAndMNTToWGS84ConversionChecking(int itkNotUsed(arg TransformType::Pointer wgs2img = TransformType::New(); wgs2img->SetInputProjectionRef(wgsRef); wgs2img->SetOutputProjectionRef(reader->GetOutput()->GetProjectionRef()); - wgs2img->SetOutputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + wgs2img->SetOutputImageMetadata(&(reader->GetOutput()->GetImageMetadata())); wgs2img->InstantiateTransform(); // Instantiate Image->WGS transform TransformType::Pointer img2wgs = TransformType::New(); img2wgs->SetInputProjectionRef(reader->GetOutput()->GetProjectionRef()); - img2wgs->SetInputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + img2wgs->SetInputImageMetadata(&(reader->GetOutput()->GetImageMetadata())); img2wgs->SetOutputProjectionRef(wgsRef); img2wgs->InstantiateTransform(); @@ -141,13 +141,13 @@ int otbGenericRSTransformImageAndMNTToWGS84ConversionChecking(int itkNotUsed(arg Transform3DType::Pointer wgs2img3d = Transform3DType::New(); wgs2img3d->SetInputProjectionRef(wgsRef); wgs2img3d->SetOutputProjectionRef(reader->GetOutput()->GetProjectionRef()); - wgs2img3d->SetOutputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + wgs2img3d->SetOutputImageMetadata(&(reader->GetOutput()->GetImageMetadata())); wgs2img3d->InstantiateTransform(); // Instantiate Image->WGS transform 3D Transform3DType::Pointer img2wgs3d = Transform3DType::New(); img2wgs3d->SetInputProjectionRef(reader->GetOutput()->GetProjectionRef()); - img2wgs3d->SetInputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + img2wgs3d->SetInputImageMetadata(&(reader->GetOutput()->GetImageMetadata())); img2wgs3d->SetOutputProjectionRef(wgsRef); img2wgs3d->InstantiateTransform(); diff --git a/Modules/Filtering/Projection/test/otbGenericRSTransformGenericTest.cxx b/Modules/Filtering/Projection/test/otbGenericRSTransformGenericTest.cxx index cbc42748a502c25d1465a6c312e0f332ce146379..b7b393d153e0aeec868b43f7c1111e5164997fc0 100644 --- a/Modules/Filtering/Projection/test/otbGenericRSTransformGenericTest.cxx +++ b/Modules/Filtering/Projection/test/otbGenericRSTransformGenericTest.cxx @@ -75,7 +75,7 @@ int otbGenericRSTransformGenericTest(int argc, char* argv[]) reader->UpdateOutputInformation(); transform->SetInputProjectionRef(reader->GetOutput()->GetProjectionRef()); - transform->SetInputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + transform->SetInputImageMetadata(&(reader->GetOutput()->GetImageMetadata())); std::cout << "Input projection read from image: " << argv[6] << std::endl; } @@ -111,7 +111,7 @@ int otbGenericRSTransformGenericTest(int argc, char* argv[]) reader->UpdateOutputInformation(); transform->SetOutputProjectionRef(reader->GetOutput()->GetProjectionRef()); - transform->SetOutputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + transform->SetOutputImageMetadata(&(reader->GetOutput()->GetImageMetadata())); std::cout << "Output projection read from image: " << argv[8] << std::endl; } diff --git a/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromMapToSensor.cxx b/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromMapToSensor.cxx index e7319be24a4b3b74b15733b19f678a16eeaa940f..c8044ea2f6a0c3c4cda163828057892fd64ac97e 100644 --- a/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromMapToSensor.cxx +++ b/Modules/Filtering/Projection/test/otbGeometriesProjectionFilterFromMapToSensor.cxx @@ -61,7 +61,7 @@ int otbGeometriesProjectionFilterFromMapToSensor(int argc, char* argv[]) GeometriesFilterType::Pointer filter = GeometriesFilterType::New(); filter->SetInput(in_set); filter->SetOutput(out_set); - filter->SetOutputKeywordList(imageReader->GetOutput()->GetImageKeywordlist()); + filter->SetOutputImageMetadata(&(imageReader->GetOutput()->GetImageMetadata())); filter->SetOutputOrigin(imageReader->GetOutput()->GetOrigin()); filter->SetOutputSpacing(imageReader->GetOutput()->GetSignedSpacing()); diff --git a/Modules/Filtering/Projection/test/otbImageToGenericRSOutputParameters.cxx b/Modules/Filtering/Projection/test/otbImageToGenericRSOutputParameters.cxx index 7ad2438a903a5d8a223a0a3d26ea11ae7d103d96..2c34a5d33ab6950a0de4e9d12d6574e289a2bf96 100644 --- a/Modules/Filtering/Projection/test/otbImageToGenericRSOutputParameters.cxx +++ b/Modules/Filtering/Projection/test/otbImageToGenericRSOutputParameters.cxx @@ -43,15 +43,6 @@ int otbImageToGenericRSOutputParameters(int itkNotUsed(argc), char* argv[]) reader->SetFileName(infname); reader->UpdateOutputInformation(); - // ForceSize - SizeType size; - size[0] = 400; - size[1] = 399; - - SpacingType spacing; - spacing[0] = 0.000006; - spacing[1] = -0.000006; - // Filter : Target SRS : WGS84 FilterType::Pointer filter = FilterType::New(); filter->SetInput(reader->GetOutput()); @@ -61,20 +52,20 @@ int otbImageToGenericRSOutputParameters(int itkNotUsed(argc), char* argv[]) // Output file std::ofstream outfile(outfname); - outfile << "Output Parameters for SRID : 4326 (WGS84)" << std::endl; - outfile << "Output Origin : " << filter->GetOutputOrigin() << std::endl; - outfile << "Output Spacing : " << filter->GetOutputSpacing() << std::endl; - outfile << "Output Size : " << filter->GetOutputSize() << std::endl; + outfile << "Output Parameters for SRID : 4326 (WGS84)\n"; + outfile << "Output Origin : " << filter->GetOutputOrigin() << "\n"; + outfile << "Output Spacing : " << filter->GetOutputSpacing() << "\n"; + outfile << "Output Size : " << filter->GetOutputSize() << "\n"; outfile << std::endl; // Target SRS : 32631 UTM 31 N filter->SetOutputProjectionRef("EPSG:32631"); // UTM 31 N filter->Compute(); - outfile << "Output Parameters for SRID : 32631 (UTM 31 N)" << std::endl; - outfile << "Output Origin : " << filter->GetOutputOrigin() << std::endl; - outfile << "Output Spacing : " << filter->GetOutputSpacing() << std::endl; - outfile << "Output Size : " << filter->GetOutputSize() << std::endl; + outfile << "Output Parameters for SRID : 32631 (UTM 31 N)\n"; + outfile << "Output Origin : " << filter->GetOutputOrigin() << "\n"; + outfile << "Output Spacing : " << filter->GetOutputSpacing() << "\n"; + outfile << "Output Size : " << filter->GetOutputSize() << "\n"; outfile << std::endl; // Target SRS : lambertII @@ -83,10 +74,10 @@ int otbImageToGenericRSOutputParameters(int itkNotUsed(argc), char* argv[]) filter->SetOutputProjectionRef(lambertRef); filter->Compute(); - outfile << "Output Parameters for SRS : Lambert II Etendu" << std::endl; - outfile << "Output Origin : " << filter->GetOutputOrigin() << std::endl; - outfile << "Output Spacing : " << filter->GetOutputSpacing() << std::endl; - outfile << "Output Size : " << filter->GetOutputSize() << std::endl; + outfile << "Output Parameters for SRS : Lambert II Etendu" << "\n"; + outfile << "Output Origin : " << filter->GetOutputOrigin() << "\n"; + outfile << "Output Spacing : " << filter->GetOutputSpacing() << "\n"; + outfile << "Output Size : " << filter->GetOutputSize() << "\n"; outfile << std::endl; diff --git a/Modules/Filtering/Projection/test/otbProjectionTestDriver.cxx b/Modules/Filtering/Projection/test/otbProjectionTestDriver.cxx index 121e3f3355886d59e0612bb938c65661bfd000d9..0405c730d2717cbc2b041bec85b47fcb47d9ad8f 100644 --- a/Modules/Filtering/Projection/test/otbProjectionTestDriver.cxx +++ b/Modules/Filtering/Projection/test/otbProjectionTestDriver.cxx @@ -56,4 +56,5 @@ void RegisterTests() REGISTER_TEST(otbVectorDataProjectionFilter); REGISTER_TEST(otbTileMapTransform); REGISTER_TEST(otbImportGeoInformationImageFilter); + REGISTER_TEST(otbRPCSolverTest); } diff --git a/Modules/Adapters/OSSIMAdapters/test/otbRPCSolverAdapterTest.cxx b/Modules/Filtering/Projection/test/otbRPCSolverTest.cxx similarity index 71% rename from Modules/Adapters/OSSIMAdapters/test/otbRPCSolverAdapterTest.cxx rename to Modules/Filtering/Projection/test/otbRPCSolverTest.cxx index e617e32bc2bbb0cda4a5a4faa1cd305e4f3582e2..d29976c75c8919d629e10604cde8fc3a1bc0da80 100644 --- a/Modules/Adapters/OSSIMAdapters/test/otbRPCSolverAdapterTest.cxx +++ b/Modules/Filtering/Projection/test/otbRPCSolverTest.cxx @@ -18,42 +18,41 @@ * limitations under the License. */ -#include "otbMacro.h" -#include "otbImage.h" +#include "otbRPCSolver.h" +#include "otbDEMHandler.h" #include "otbImageFileReader.h" #include "otbGenericRSTransform.h" #include "otbGeographicalDistance.h" #include "itkEuclideanDistanceMetric.h" -#include "otbSensorModelAdapter.h" -#include "otbRPCSolverAdapter.h" -#include "otbDEMHandler.h" -typedef otb::Image ImageType; -typedef otb::ImageFileReader ReaderType; -typedef otb::GenericRSTransform<> RSTranformType; -typedef otb::RPCSolverAdapter::Point2DType Point2DType; -typedef otb::RPCSolverAdapter::Point3DType Point3DType; -typedef otb::GenericRSTransform RSTranform3dType; -typedef itk::Statistics::EuclideanDistanceMetric EuclideanDistanceMetricType; -typedef otb::GeographicalDistance GeoDistanceType; - -int otbRPCSolverAdapterTest(int argc, char* argv[]) -{ +int otbRPCSolverTest(int argc, char* argv[]) +{ + using ImageType = otb::Image; + using ReaderType = otb::ImageFileReader; + using RSTranformType = otb::GenericRSTransform<>; + using Point2DType = otb::RPCSolver::Point2DType; + using Point3DType = otb::RPCSolver::Point3DType; + using RSTranform3dType = otb::GenericRSTransform; + using EuclideanDistanceMetricType = itk::Statistics::EuclideanDistanceMetric; + using GeoDistanceType = otb::GeographicalDistance; + + if (argc < 7) { std::cout << "Usage: test_driver input grid_size geo_tol img_tol dem_dir geoid" << std::endl; return EXIT_FAILURE; } + // This test takes a sensor model (possibly a rpc one), use it to // generate gcps and estimate a rpc model. It then checks the // precision of both forward and inverse transform - std::string infname = argv[1]; + const std::string infname = argv[1]; const unsigned int gridSize = atoi(argv[2]); const double geoTol = atof(argv[3]); const double imgTol = atof(argv[4]); const std::string demdir = argv[5]; const std::string geoid = argv[6]; - + if (gridSize == 0) { std::cerr << "Grid size is null!" << std::endl; @@ -75,15 +74,17 @@ int otbRPCSolverAdapterTest(int argc, char* argv[]) reader->UpdateOutputInformation(); RSTranformType::Pointer fwd2dTransform = RSTranformType::New(); - fwd2dTransform->SetInputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + + fwd2dTransform->SetInputImageMetadata(&(reader->GetOutput()->GetImageMetadata())); fwd2dTransform->InstantiateTransform(); - ImageType::SizeType size = reader->GetOutput()->GetLargestPossibleRegion().GetSize(); - unsigned int stepx = size[0] / gridSize; - unsigned int stepy = size[1] / gridSize; + ImageType::SizeType size = reader->GetOutput()->GetLargestPossibleRegion().GetSize(); + + unsigned int stepx = size[0] / gridSize; + unsigned int stepy = size[1] / gridSize; - otb::RPCSolverAdapter::GCPsContainerType gcps; + otb::RPCSolver::GCPsContainerType gcps; // Generate gcps for (unsigned int i = 0; i < gridSize; ++i) @@ -108,51 +109,39 @@ int otbRPCSolverAdapterTest(int argc, char* argv[]) gcps.push_back(std::make_pair(currentPoint, current3DWgs84Point)); - std::cout << currentPoint[0] << " " << currentPoint[1] << " " << current3DWgs84Point[0] << " " << current3DWgs84Point[1] << " " << current3DWgs84Point[2] - << std::endl; } } - // Solve rpc - otb::ImageKeywordlist rpcKwl; - double rmse; + double rmse; + otb::Projection::RPCParam params; + + otb::RPCSolver::Solve(gcps, rmse, params); - // Call solver: either write geom and exit, or evaluate model precision - if (argc == 8) - { - const std::string outgeom = argv[7]; - bool success = otb::RPCSolverAdapter::Solve(gcps, rmse, outgeom); - if (success) - return EXIT_SUCCESS; - else - return EXIT_FAILURE; - } - - otb::RPCSolverAdapter::Solve(gcps, rmse, rpcKwl); - - std::cout << "Optimization done, RMSE=" << rmse << std::endl; + auto outputMetadata = reader->GetOutput()->GetImageMetadata(); + + outputMetadata.Add(otb::MDGeom::RPC, params); // Build forward and inverse rpc transform RSTranform3dType::Pointer rpcFwdTransform = RSTranform3dType::New(); - rpcFwdTransform->SetInputKeywordList(rpcKwl); + rpcFwdTransform->SetInputImageMetadata(&outputMetadata); rpcFwdTransform->InstantiateTransform(); RSTranformType::Pointer rpcInvTransform = RSTranformType::New(); - rpcInvTransform->SetOutputKeywordList(rpcKwl); + rpcInvTransform->SetOutputImageMetadata(&outputMetadata); rpcInvTransform->InstantiateTransform(); - + EuclideanDistanceMetricType::Pointer euclideanDistanceMetric = EuclideanDistanceMetricType::New(); GeoDistanceType::Pointer geoDistance = GeoDistanceType::New(); bool fail = false; - for (otb::RPCSolverAdapter::GCPsContainerType::iterator it = gcps.begin(); it != gcps.end(); ++it) + for (auto it = gcps.begin(); it != gcps.end(); ++it) { Point2DType imgPoint, groundPoint, groundPoint2dRef; Point3DType imgPoint3D, groundPoint3D; groundPoint2dRef[0] = it->second[0]; groundPoint2dRef[1] = it->second[1]; - + // Check forward transform imgPoint3D[0] = it->first[0]; imgPoint3D[1] = it->first[1]; @@ -162,7 +151,7 @@ int otbRPCSolverAdapterTest(int argc, char* argv[]) groundPoint[0] = groundPoint3D[0]; groundPoint[1] = groundPoint3D[1]; - + double groundRes = geoDistance->Evaluate(groundPoint, groundPoint2dRef); if (groundRes > geoTol) diff --git a/Modules/Filtering/Projection/test/otbSensorModel.cxx b/Modules/Filtering/Projection/test/otbSensorModel.cxx index 083ab6edec793295e0386642deddbcbba732ca87..22713f8c97e0d73cd9b81c0b13ac7b3f1c7e7692 100644 --- a/Modules/Filtering/Projection/test/otbSensorModel.cxx +++ b/Modules/Filtering/Projection/test/otbSensorModel.cxx @@ -26,14 +26,17 @@ #include #include "otbVectorImage.h" -#include "otbImageFileReader.h" -#include "otbForwardSensorModel.h" -#include "otbInverseSensorModel.h" +#include "otbImageMetadata.h" +#include "otbRPCForwardTransform.h" +#include "otbRPCInverseTransform.h" #include "otbDEMHandler.h" #include #include "itkEuclideanDistanceMetric.h" #include "otbGeographicalDistance.h" #include "otbGenericRSTransform.h" +#include "otbImageMetadata.h" +#include "otbImageMetadataInterfaceFactory.h" +#include "otbGeomMetadataSupplier.h" #include "otbMacro.h" typedef std::list> pointsContainerType; @@ -42,18 +45,18 @@ typedef otb::VectorImage ImageType; typedef itk::Statistics::EuclideanDistanceMetric DistanceType; typedef otb::GeographicalDistance GeographicalDistanceType; -int produceGCP(char* outputgcpfilename, const otb::ImageKeywordlist& kwlist, double z = 16.19688987731934) +int produceGCP(char* outputgcpfilename, const otb::ImageMetadata& imd, bool useForwardSensorModel = true, double z = 16.19688987731934) { itk::Point imagePoint; itk::Point geoPoint; // otbForwardSensorModel - typedef otb::ForwardSensorModel ForwardSensorModelType; + typedef otb::RPCForwardTransform ForwardSensorModelType; ForwardSensorModelType::Pointer forwardSensorModel = ForwardSensorModelType::New(); - forwardSensorModel->SetImageGeometry(kwlist); + forwardSensorModel->SetMetadata(imd); if (forwardSensorModel->IsValidSensorModel() == false) { - otbLogMacro(Warning, << "Invalid Model pointer m_Model == NULL!\n The ossim keywordlist is invalid!"); + otbLogMacro(Warning, << "Invalid Model pointer m_Model == NULL!\n The metadata is invalid!"); return EXIT_FAILURE; } @@ -136,6 +139,13 @@ int otbSensorModel(int argc, char* argv[]) // Some instantiations // ------------------- otb::ImageKeywordlist kwlist = otb::ReadGeometryFromGEOMFile(geomfilename); + otb::ImageMetadata imd; + otb::GeomMetadataSupplier geomSupplier(geomfilename); + for (int loop = 0 ; loop < geomSupplier.GetNbBands() ; ++loop) + imd.Bands.emplace_back(); + otb::ImageMetadataInterfaceBase::Pointer imi = otb::ImageMetadataInterfaceFactory::CreateIMI(imd, geomSupplier); + imd = imi->GetImageMetadata(); + geomSupplier.FetchRPC(imd); if (!(kwlist.GetSize() > 0)) { @@ -145,39 +155,39 @@ int otbSensorModel(int argc, char* argv[]) if (writeBaseline) { - return produceGCP(outFilename, kwlist); + return produceGCP(outFilename, imd); } typedef otb::ImageKeywordlist::KeywordlistMap KeywordlistMapType; KeywordlistMapType kwmap = kwlist.GetKeywordlist(); // otbForwardSensorModel - typedef otb::ForwardSensorModel ForwardSensorModelType; + typedef otb::RPCForwardTransform ForwardSensorModelType; ForwardSensorModelType::Pointer forwardSensorModel = ForwardSensorModelType::New(); if (!forwardSensorModel) { std::cerr << "Invalid sensor model (ForwardSensorModelType::Pointer is NULL)" << std::endl; return EXIT_FAILURE; } - forwardSensorModel->SetImageGeometry(kwlist); + forwardSensorModel->SetMetadata(imd); if (forwardSensorModel->IsValidSensorModel() == false) { - std::cerr << "Invalid Model pointer m_Model == NULL!\n The ossim keywordlist is invalid!" << std::endl; + std::cerr << "Invalid Model pointer m_Model == NULL!\n The metadata is invalid!" << std::endl; return EXIT_FAILURE; } // otbInverseSensorModel - typedef otb::InverseSensorModel InverseSensorModelType; + typedef otb::RPCInverseTransform InverseSensorModelType; InverseSensorModelType::Pointer inverseSensorModel = InverseSensorModelType::New(); if (!inverseSensorModel) { std::cerr << "Invalid sensor model (InverseSensorModelType::Pointer is NULL)" << std::endl; return EXIT_FAILURE; } - inverseSensorModel->SetImageGeometry(kwlist); + inverseSensorModel->SetMetadata(imd); if (inverseSensorModel->IsValidSensorModel() == false) { - std::cerr << "Invalid Model pointer m_Model == NULL!\n The ossim keywordlist is invalid!" << std::endl; + std::cerr << "Invalid Model pointer m_Model == NULL!\n The metadata is invalid!" << std::endl; return EXIT_FAILURE; } @@ -199,7 +209,7 @@ int otbSensorModel(int argc, char* argv[]) } img2wgs->SetInputProjectionRef(""); img2wgs->SetOutputProjectionRef(wgsRef); - img2wgs->SetInputKeywordList(kwlist); + img2wgs->SetInputImageMetadata(&imd); img2wgs->InstantiateTransform(); @@ -212,7 +222,7 @@ int otbSensorModel(int argc, char* argv[]) } wgs2img->SetInputProjectionRef(wgsRef); wgs2img->SetOutputProjectionRef(""); - wgs2img->SetOutputKeywordList(kwlist); + wgs2img->SetOutputImageMetadata(&imd); wgs2img->InstantiateTransform(); itk::Point imagePoint; @@ -286,7 +296,6 @@ int otbSensorModel(int argc, char* argv[]) pointsContainerType::iterator pointsIt = pointsContainer.begin(); geo3dPointsContainerType::iterator geo3dPointsIt = geo3dPointsContainer.begin(); pointsContainerType::iterator ossimIt = ossimContainer.begin(); - // for(; pointsIt!=pointsContainer.end(); ++pointsIt) while ((pointsIt != pointsContainer.end()) && (geo3dPointsIt != geo3dPointsContainer.end()) && (ossimIt != ossimContainer.end())) { imagePoint = *pointsIt; diff --git a/Modules/Filtering/Projection/test/otbTileImageFilterRSTransformTest.cxx b/Modules/Filtering/Projection/test/otbTileImageFilterRSTransformTest.cxx index c91665f6a4f784925b2c419c1d032fd5af168cf8..d27c56848c054623e28e717872a5a9db20e8f104 100644 --- a/Modules/Filtering/Projection/test/otbTileImageFilterRSTransformTest.cxx +++ b/Modules/Filtering/Projection/test/otbTileImageFilterRSTransformTest.cxx @@ -23,6 +23,7 @@ #include "otbImageFileReader.h" #include "otbGeographicalDistance.h" #include "otbGenericRSTransform.h" +#include "otbDEMHandler.h" #include #include "otbDEMHandler.h" @@ -74,7 +75,7 @@ int otbTileImageFilterRSTransformTest(int argc, char* argv[]) // Set-up transform RSTransformType::Pointer rsTransform = RSTransformType::New(); - rsTransform->SetInputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + rsTransform->SetInputImageMetadata(&(reader->GetOutput()->GetImageMetadata())); rsTransform->InstantiateTransform(); transforms.push_back(rsTransform); @@ -85,7 +86,7 @@ int otbTileImageFilterRSTransformTest(int argc, char* argv[]) // Build RS transform for tiled image RSTransformType::Pointer mosaicRsTransform = RSTransformType::New(); - mosaicRsTransform->SetInputKeywordList(tileFilter->GetOutput()->GetImageKeywordlist()); + mosaicRsTransform->SetInputImageMetadata(&(tileFilter->GetOutput()->GetImageMetadata())); mosaicRsTransform->InstantiateTransform(); // Check that individual RSTransform gives the same result as tiled diff --git a/Modules/Filtering/Projection/test/otbVectorDataIntoImageProjectionFilterTest.cxx b/Modules/Filtering/Projection/test/otbVectorDataIntoImageProjectionFilterTest.cxx index 36a3335abfa0a62920c2b7035a47a9658de33c49..f37e0e15a0d4b936a8dba2a740103d94cc10d254 100644 --- a/Modules/Filtering/Projection/test/otbVectorDataIntoImageProjectionFilterTest.cxx +++ b/Modules/Filtering/Projection/test/otbVectorDataIntoImageProjectionFilterTest.cxx @@ -221,7 +221,7 @@ int otbVectorDataIntoImageProjectionFilterCompareImplTest(int itkNotUsed(argc), vproj = VectorDataProjectionFilterType::New(); vproj->SetInput(vdextract->GetOutput()); vproj->SetInputProjectionRef(vdReader->GetOutput()->GetProjectionRef()); - vproj->SetOutputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + vproj->SetOutputImageMetadata(&reader->GetOutput()->GetImageMetadata()); vproj->SetOutputProjectionRef(reader->GetOutput()->GetProjectionRef()); vproj->SetOutputOrigin(reader->GetOutput()->GetOrigin()); vproj->SetOutputSpacing(reader->GetOutput()->GetSignedSpacing()); diff --git a/Modules/Filtering/Projection/test/otbVectorDataProjectionFilterFromMapToSensor.cxx b/Modules/Filtering/Projection/test/otbVectorDataProjectionFilterFromMapToSensor.cxx index 5a77d94b12042326f63930cad2f7a5178e9d6d44..c58269157cecdb11bf15f3f8630d10df84a0aaf4 100644 --- a/Modules/Filtering/Projection/test/otbVectorDataProjectionFilterFromMapToSensor.cxx +++ b/Modules/Filtering/Projection/test/otbVectorDataProjectionFilterFromMapToSensor.cxx @@ -58,7 +58,7 @@ int otbVectorDataProjectionFilterFromMapToSensor(int argc, char* argv[]) vectorDataProjection->SetInput(reader->GetOutput()); - vectorDataProjection->SetOutputKeywordList(imageReader->GetOutput()->GetImageKeywordlist()); + vectorDataProjection->SetOutputImageMetadata(&imageReader->GetOutput()->GetImageMetadata()); vectorDataProjection->SetOutputOrigin(imageReader->GetOutput()->GetOrigin()); vectorDataProjection->SetOutputSpacing(imageReader->GetOutput()->GetSignedSpacing()); diff --git a/Modules/Filtering/Projection/test/otbVectorDataTransformFilter.cxx b/Modules/Filtering/Projection/test/otbVectorDataTransformFilter.cxx index f2790fe9a67a258969ecbf0a703da9eabe54288e..94c0b6ce8b8f4713dff695fd12fcbbb121db2d14 100644 --- a/Modules/Filtering/Projection/test/otbVectorDataTransformFilter.cxx +++ b/Modules/Filtering/Projection/test/otbVectorDataTransformFilter.cxx @@ -56,7 +56,7 @@ int otbVectorDataTransformFilter(int itkNotUsed(argc), char* argv[]) VDProjectionFilterType::Pointer vdproj = VDProjectionFilterType::New(); vdproj->SetInput(vdreader->GetOutput()); vdproj->SetInputProjectionRef(vdreader->GetOutput()->GetProjectionRef()); - vdproj->SetOutputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + vdproj->SetOutputImageMetadata(&reader->GetOutput()->GetImageMetadata()); vdproj->SetOutputProjectionRef(reader->GetOutput()->GetProjectionRef()); // Test the translation using the ApplyTransformTo @@ -78,7 +78,7 @@ int otbVectorDataTransformFilter(int itkNotUsed(argc), char* argv[]) VDProjectionFilterType::Pointer reverseVdProj = VDProjectionFilterType::New(); reverseVdProj->SetInput(transformFilter->GetOutput()); reverseVdProj->SetOutputProjectionRef(vdreader->GetOutput()->GetProjectionRef()); - reverseVdProj->SetInputKeywordList(reader->GetOutput()->GetImageKeywordlist()); + reverseVdProj->SetInputImageMetadata(&reader->GetOutput()->GetImageMetadata()); reverseVdProj->SetInputProjectionRef(reader->GetOutput()->GetProjectionRef()); // Write the vectordata diff --git a/Modules/Filtering/VectorDataManipulation/include/otbVectorDataExtractROI.hxx b/Modules/Filtering/VectorDataManipulation/include/otbVectorDataExtractROI.hxx index 76f8da8307c7d984a985f1ed80df9311a3dbe0a7..9923e7db2cafe03f2adf8bbd0c0d7d6060654d05 100644 --- a/Modules/Filtering/VectorDataManipulation/include/otbVectorDataExtractROI.hxx +++ b/Modules/Filtering/VectorDataManipulation/include/otbVectorDataExtractROI.hxx @@ -428,10 +428,10 @@ void VectorDataExtractROI::ProjectRegionToInputVectorProjection() /** Set up the projection */ genericTransform->SetInputProjectionRef(m_ROI.GetRegionProjection()); - genericTransform->SetInputKeywordList(m_ROI.GetKeywordList()); + //TODO: genericTransform->SetInputImageMetadata(m_ROI.GetImageMetadata()); genericTransform->SetOutputProjectionRef(this->GetInput()->GetProjectionRef()); const itk::MetaDataDictionary& inputDict = this->GetInput()->GetMetaDataDictionary(); - genericTransform->SetOutputDictionary(inputDict); + //TODO: genericTransform->SetOutputImageMetadata(this->GetInput()->GetImageMetadata()); genericTransform->SetOutputOrigin(this->GetInput()->GetOrigin()); genericTransform->SetOutputSpacing(this->GetInput()->GetSpacing()); genericTransform->InstantiateTransform(); diff --git a/Modules/Fusion/PanSharpening/include/otbSimpleRcsPanSharpeningFusionImageFilter.h b/Modules/Fusion/PanSharpening/include/otbSimpleRcsPanSharpeningFusionImageFilter.h index 56eedfdcbf3104b3c8a53ee897ea97a7cd3f4b2c..d3d3fb8a81ce14012466ac1295e91f7ea3687f21 100644 --- a/Modules/Fusion/PanSharpening/include/otbSimpleRcsPanSharpeningFusionImageFilter.h +++ b/Modules/Fusion/PanSharpening/include/otbSimpleRcsPanSharpeningFusionImageFilter.h @@ -209,7 +209,7 @@ private: } private: - /** No data flags and values for APN image */ + /** No data flags and values for PAN image */ bool m_NoDataValuePanAvailable; typename TPanImageType::InternalPixelType m_NoDataValuePan; diff --git a/Modules/IO/Carto/include/otbImageToOSMVectorDataGenerator.hxx b/Modules/IO/Carto/include/otbImageToOSMVectorDataGenerator.hxx index 6cec470747b6abfa51e84b4cb706529ab8811137..17e9a56c7fa06bb2d0a813eab605555353aa4dd8 100644 --- a/Modules/IO/Carto/include/otbImageToOSMVectorDataGenerator.hxx +++ b/Modules/IO/Carto/include/otbImageToOSMVectorDataGenerator.hxx @@ -84,7 +84,7 @@ void ImageToOSMVectorDataGenerator::EstimateImageExtent() // Local generic RS Transform to project the 4 corners to WGS84 typedef otb::GenericRSTransform<> TransformType; typename TransformType::Pointer transform = TransformType::New(); - transform->SetInputKeywordList(input->GetImageKeywordlist()); + transform->SetInputImageMetadata(&(input->GetImageMetadata())); transform->SetInputProjectionRef(input->GetProjectionRef()); transform->SetOutputProjectionRef(otb::SpatialReference::FromWGS84().ToWkt()); transform->InstantiateTransform(); diff --git a/Modules/IO/IOGDAL/include/otbDEMHandler.h b/Modules/IO/IOGDAL/include/otbDEMHandler.h index 830a5a90d009dbd0a38bad8118bb63c3270b758e..b77909b714f92707e8208966dc9411e20f4299f5 100644 --- a/Modules/IO/IOGDAL/include/otbDEMHandler.h +++ b/Modules/IO/IOGDAL/include/otbDEMHandler.h @@ -26,6 +26,34 @@ namespace otb { + + + +/** \class DEMObserverInterface + * + * \brief Observer design pattern to keep track of DEM configuration changes + * \ingroup OTBIOGDAL + */ +class DEMObserverInterface { + public: + virtual ~DEMObserverInterface() = default; + virtual void Update() = 0; +}; + +/** \class DEMSubjectInterface + * + * \brief Observer design pattern to keep track of DEM configuration changes + * \ingroup OTBIOGDAL + */ +class DEMSubjectInterface { + public: + virtual ~DEMSubjectInterface() = default; + virtual void AttachObserver(DEMObserverInterface *observer) = 0; + virtual void DetachObserver(DEMObserverInterface *observer) = 0; + virtual void Notify() const = 0; +}; + + /** \class DEMHandler * * \brief Single access point for DEM data retrieval @@ -33,7 +61,7 @@ namespace otb * This class is the single configuration and access point for * elevation handling in images projections and localization * functions. Since this class is a singleton, there is no New() method. The - * DEMHandler::Instance() method should be used instead. + * DEMHandler::GetInstance() method should be used instead. * * Please be aware that a proper instantiation and parameter setting * of this class is advised before any call to geometric filters or @@ -67,7 +95,7 @@ namespace otb * * \ingroup OTBIOGDAL */ -class DEMHandler +class DEMHandler : public DEMSubjectInterface { public: using Self = DEMHandler; @@ -140,6 +168,21 @@ public: /** Clear the DEM list and close all DEM datasets */ void ClearDEMs(); + + /** Add an element to the current list of observers. The obsever will be updated whenever the DEM configuration + is modified*/ + void AttachObserver(DEMObserverInterface *observer) override {m_ObserverList.push_back(observer);}; + + /** Remove an element of the current list of observers. */ + void DetachObserver(DEMObserverInterface *observer) override {m_ObserverList.remove(observer);}; + + /** Update all observers */ + void Notify() const override; + + /** Path to the in-memory vrt */ + const std::string DEM_DATASET_PATH = "/vsimem/otb_dem_dataset.vrt"; + const std::string DEM_WARPED_DATASET_PATH = "/vsimem/otb_dem_warped_dataset.vrt"; + const std::string DEM_SHIFTED_DATASET_PATH = "/vsimem/otb_dem_shifted_dataset.vrt"; protected: DEMHandler(); @@ -149,7 +192,10 @@ protected: private: DEMHandler(const Self&) = delete; - void operator=(const Self&) = delete; + void operator=(const Self&) = delete; + + void CreateShiftedDataset(); + /** List of RAII capsules on all opened DEM datasets for memory management */ std::vector m_DatasetList; @@ -159,6 +205,9 @@ private: /** Pointer to the geoid dataset */ GDALDataset* m_GeoidDS; + /** Pointer to the sifted dataset */ + GDALDataset* m_ShiftedDS; + /** Default height above elliposid, used when no DEM or geoid height is available. */ double m_DefaultHeightAboveEllipsoid; @@ -168,6 +217,8 @@ private: /** Filename of the current geoid */ std::string m_GeoidFilename; + /** Observers on the DEM */ + std::list m_ObserverList; }; } diff --git a/Modules/IO/IOGDAL/include/otbGDALRPCTransformer.h b/Modules/IO/IOGDAL/include/otbGDALRPCTransformer.h new file mode 100644 index 0000000000000000000000000000000000000000..8fd131596926aa4b6654d0003fdfa2844534b7c2 --- /dev/null +++ b/Modules/IO/IOGDAL/include/otbGDALRPCTransformer.h @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef otbGDALRPCTransformer_h +#define otbGDALRPCTransformer_h + +#include "itkPoint.h" +#include "gdal_alg.h" + +#include "otbDEMHandler.h" +#include "otbGeometryMetadata.h" + +#include + +namespace otb +{ +/** + * \class GDALRPCTransformer + * \brief This class is a wrapper around GDALCreateRPCTransformer and GDALRPCTransform + * + * This class aims at manipulating RPC transformations within OTB, + * in a safe and easy way. + * + * To use this wrapper, one needs to call the constructor with the correct + * parameters. Then, one can set the options, and the threshold. Finally, + * one can call ForwardTransform or BackwardTransform, depending in the + * desired result. + * + * The parameters provided to the constructor are those found in the + * RPCParam structure defined in the otbGeometryMetadata.h file. They + * are quite similar to what can be found in GDALRPCInfo. + * + * \ingroup OTBIOGDAL + */ + +class GDALRPCTransformer : public DEMObserverInterface +{ +public: + + using PointType = itk::Point; + + /** + * Build a GDALRPCTransformer + * + * The parameters describe the RPC model. They can be found in the + * RPCParam structure defined in the otbGeometryMetadata.h file. They + * are quite similar to what can be found in GDALRPCInfo. See also + * http://geotiff.maptools.org/rpc_prop.html + * + */ + GDALRPCTransformer(double LineOffset, double SampleOffset, double LatOffset, double LonOffset, double HeightOffset, + double LineScale, double SampleScale, double LatScale, double LonScale, double HeightScale, + const double (&LineNum)[20], const double (&LineDen)[20], const double (&SampleNum)[20], const double (&SampleDen)[20], bool useDEM); + + GDALRPCTransformer(const Projection::RPCParam &, bool useDEM); + + ~GDALRPCTransformer(); + + /** + * Set additional options to the transformer + * + *
    + *
  • RPC_HEIGHT: a fixed height offset to be applied to all points passed + * in. In this situation the Z passed into the transformation function is + * assumed to be height above ground, and the RPC_HEIGHT is assumed to be + * an average height above sea level for ground in the target scene.
  • + * + *
  • RPC_HEIGHT_SCALE: a factor used to multiply heights above ground. + * Useful when elevation offsets of the DEM are not expressed in meters.
  • + * + *
  • RPC_DEM: the name of a GDAL dataset (a DEM file typically) used to + * extract elevation offsets from. In this situation the Z passed into the + * transformation function is assumed to be height above ground. This option + * should be used in replacement of RPC_HEIGHT to provide a way of defining + * a non uniform ground for the target scene
  • + * + *
  • RPC_DEMINTERPOLATION: the DEM interpolation ("near", "bilinear" or "cubic"). + * Default is "bilinear".
  • + * + *
  • RPC_DEM_MISSING_VALUE: value of DEM height that must be used in case + * the DEM has nodata value at the sampling point, or if its extent does not + * cover the requested coordinate. When not specified, missing values will cause + * a failed transform.
  • + * + *
  • RPC_DEM_SRS: (GDAL >= 3.2) WKT SRS, or any string recognized by + * OGRSpatialReference::SetFromUserInput(), to be used as an override for DEM SRS. + * Useful if DEM SRS does not have an explicit vertical component.
  • + * + *
  • RPC_DEM_APPLY_VDATUM_SHIFT: whether the vertical component of a compound + * SRS for the DEM should be used (when it is present). This is useful so as to + * be able to transform the "raw" values from the DEM expressed with respect to + * a geoid to the heights with respect to the WGS84 ellipsoid. When this is + * enabled, the GTIFF_REPORT_COMPD_CS configuration option will be also set + * temporarily so as to get the vertical information from GeoTIFF + * files. Defaults to TRUE. (GDAL >= 2.1.0)
  • + * + *
  • RPC_PIXEL_ERROR_THRESHOLD: overrides the dfPixErrThreshold parameter, ie + * the error (measured in pixels) allowed in the + * iterative solution of pixel/line to lat/long computations (the other way + * is always exact given the equations). (GDAL >= 2.1.0)
  • + * + *
  • RPC_MAX_ITERATIONS: maximum number of iterations allowed in the + * iterative solution of pixel/line to lat/long computations. Default value is + * 10 in the absence of a DEM, or 20 if there is a DEM. (GDAL >= 2.1.0)
  • + * + *
  • RPC_FOOTPRINT: WKT or GeoJSON polygon (in long / lat coordinate space) + * with a validity footprint for the RPC. Any coordinate transformation that + * goes from or arrive outside this footprint will be considered invalid. This + * is useful in situations where the RPC values become highly unstable outside + * of the area on which they have been computed for, potentially leading to + * undesirable "echoes" / false positives. This requires GDAL to be built against + * GEOS.
  • + *
+ * + * \param[in] Name a string containing the name of the option + * \param[in] Value a string containing the value of the option + * + */ + void SetOption(const std::string& Name, const std::string& Value); + + /** + * Set the error (measured in pixels) allowed in the + * iterative solution of pixel/line to lat/long computations (the other way + * is always exact given the equations). Starting with GDAL 2.1, this may also + * be set through the RPC_PIXEL_ERROR_THRESHOLD transformer option. + * If a negative or null value is provided, then this defaults to 0.1 pixel. + * + * \param[in] PixErrThreshold the new value of the error + * + */ + void SetPixErrThreshold(double PixErrThreshold); + + /** + * Compute a forward transformation + * + * This method performs a transformation from column/row to long/lat/height space. + * It can work with an arbitrary number of points. + * + * \param[in,out] x array of the X coordinate of the points to convert + * \param[in,out] y array of the Y coordinate of the points to convert + * \param[in,out] z array of the Z coordinate of the points to convert + * \param[in] nPointCount the number of points to convert + * \return true if all points were correctly transformed + * \pre `x, y, z != nullptr` + * + */ + bool ForwardTransform(double* x, double* y, double* z, int nPointCount); + + /** + * Compute an forward transformation + * + * This method performs a transformation from column/row to long/lat/height space. + * It works with only one point. + * + * \param[in] p coordinates of the point to convert + * \return the coordinates of the converted point + */ + PointType ForwardTransform(PointType p); + + /** + * Compute an inverse transformation + * + * This method performs a transformation from long/lat/height to column/row space. + * It can work with an arbitrary number of points. + * + * \param[in,out] x array of the X coordinate of the points to convert + * \param[in,out] y array of the Y coordinate of the points to convert + * \param[in,out] z array of the Z coordinate of the points to convert + * \param[in] nPointCount the number of points to convert + * \return true if all points were correctly transformed + * \pre `x, y, z != nullptr` + * + */ + bool InverseTransform(double* x, double* y, double* z, int nPointCount); + + /** + * Compute an inverse transformation + * + * This method performs a transformation from long/lat/height to column/row space. + * It works with only one point. + * + * \param[in] p coordinates of the point to convert + * \return the coordinates of the converted point + */ + PointType InverseTransform(PointType p); + +protected: + /** + * Regenerate the transformer + * + * Called when performing a transformation and some options were modified. + */ + void Update() override; + +private: + /** Used to know if Update is required after a change in the options */ + bool m_Modified = true; + + /** The RPC model */ + GDALRPCInfo m_GDALRPCInfo; + + /** The options */ + char ** m_Options = nullptr; + + /** The error allowed in the iterative solution */ + double m_PixErrThreshold = 0.1; + + /** The transformer arguments */ + void * m_TransformArg = nullptr; + + /** Lock threads when instantiating the GDAL RPC transformer */ + std::mutex m_Mutex; + + /** Use the DEM singleton in DEM computations */ + bool m_UseDEM = true; + +}; +} +#endif diff --git a/Modules/IO/IOGDAL/otb-module.cmake b/Modules/IO/IOGDAL/otb-module.cmake index 5b185de6abbf94eabf5f32cadbb90639111fde62..84003b7e8c7af59c096c0fda9205aac0e4bf196f 100644 --- a/Modules/IO/IOGDAL/otb-module.cmake +++ b/Modules/IO/IOGDAL/otb-module.cmake @@ -38,6 +38,7 @@ ENABLE_SHARED TEST_DEPENDS OTBTestKernel OTBImageIO + OTBProjection DESCRIPTION "${DOCUMENTATION}" diff --git a/Modules/IO/IOGDAL/src/CMakeLists.txt b/Modules/IO/IOGDAL/src/CMakeLists.txt index 4ccae4de9d36eb02393e6772017593ac7a9a14a9..c18da2d8cc3c0a5587e99efd67cfc058a1638016 100644 --- a/Modules/IO/IOGDAL/src/CMakeLists.txt +++ b/Modules/IO/IOGDAL/src/CMakeLists.txt @@ -29,6 +29,7 @@ set(OTBIOGDAL_SRC otbOGRVectorDataIOFactory.cxx otbDEMHandler.cxx otbGDALImageMetadataInterface.cxx + otbGDALRPCTransformer.cxx ) add_library(OTBIOGDAL ${OTBIOGDAL_SRC}) @@ -41,7 +42,7 @@ target_link_libraries(OTBIOGDAL ${OTBGDAL_LIBRARIES} ${OTBBoost_LIBRARIES} ${OTBOSSIMAdapters_LIBRARIES} - ${Boost_LIBRARIES} + ${Boost_LIBRARIES} ) otb_module_target(OTBIOGDAL) diff --git a/Modules/IO/IOGDAL/src/otbDEMHandler.cxx b/Modules/IO/IOGDAL/src/otbDEMHandler.cxx index ee175b97dd2e020f306f90de8146d10f59f8c829..7886230cf8c4effcf677c06192f4260392d1ccc2 100644 --- a/Modules/IO/IOGDAL/src/otbDEMHandler.cxx +++ b/Modules/IO/IOGDAL/src/otbDEMHandler.cxx @@ -24,6 +24,10 @@ #include #include "gdal_utils.h" +//Warp utility +#include "gdalwarper.h" +#include "vrtdataset.h" + //TODO C++ 17 : use std::optional instead #include @@ -181,20 +185,41 @@ DEMHandler::~DEMHandler() } ClearDEMs(); + + VSIUnlink(DEM_DATASET_PATH.c_str()); + VSIUnlink(DEM_WARPED_DATASET_PATH.c_str()); + VSIUnlink(DEM_SHIFTED_DATASET_PATH.c_str()); } void DEMHandler::OpenDEMFile(const std::string& path) { m_DatasetList.push_back(otb::GDALDriverManagerWrapper::GetInstance().Open(path)); - m_Dataset = m_DatasetList.back()->GetDataSet(); + std::vector vrtDatasetList(1); + vrtDatasetList[0] = m_DatasetList[0]->GetDataSet(); + auto close_me = GDALBuildVRT(DEM_DATASET_PATH.c_str(), 1, vrtDatasetList.data(), + nullptr, nullptr, nullptr); + // Need to close the dataset, so it is flushed into memory. + GDALClose(close_me); + m_Dataset = static_cast(GDALOpen(DEM_DATASET_PATH.c_str(), GA_ReadOnly)); m_DEMDirectories.push_back(path); + + if(m_GeoidDS) + { + CreateShiftedDataset(); + } + + Notify(); } void DEMHandler::OpenDEMDirectory(const std::string& DEMDirectory) -{ +{ // TODO : RemoveOSSIM OssimDEMHandler::Instance()->OpenDEMDirectory(DEMDirectory); + // Free the previous in-memory dataset (if any) + if (!m_DatasetList.empty()) + VSIUnlink(DEM_DATASET_PATH.c_str()); + auto demFiles = DEMDetails::GetFilesInDirectory(DEMDirectory); for (const auto & file : demFiles) { @@ -207,36 +232,36 @@ void DEMHandler::OpenDEMDirectory(const std::string& DEMDirectory) int vrtSize = m_DatasetList.size(); - // Don't build a vrt if there is less than two dataset + // Don't build a vrt if there is no dataset if (m_DatasetList.empty()) { m_Dataset = nullptr; } else { - if (vrtSize == 1) - { - m_Dataset = m_DatasetList[0]->GetDataSet(); - m_DEMDirectories.push_back(DEMDirectory); - } - else + std::vector vrtDatasetList(vrtSize); + for (int i = 0; i < vrtSize; i++) { - std::vector vrtDatasetList(vrtSize); - for (int i = 0; i < vrtSize; i++) - { - vrtDatasetList[i] = m_DatasetList[i]->GetDataSet(); - } - - m_Dataset = static_cast (GDALBuildVRT(nullptr, vrtSize, vrtDatasetList.data(), - nullptr, nullptr, nullptr)); - m_DEMDirectories.push_back(DEMDirectory); + vrtDatasetList[i] = m_DatasetList[i]->GetDataSet(); } - + + auto close_me = GDALBuildVRT(DEM_DATASET_PATH.c_str(), vrtSize, vrtDatasetList.data(), + nullptr, nullptr, nullptr); + // Need to close the dataset, so it is flushed into memory. + GDALClose(close_me); + m_Dataset = static_cast(GDALOpen(DEM_DATASET_PATH.c_str(), GA_ReadOnly)); + m_DEMDirectories.push_back(DEMDirectory); } + + if(m_GeoidDS) + { + CreateShiftedDataset(); + } + Notify(); } bool DEMHandler::OpenGeoidFile(const std::string& geoidFile) -{ +{ // TODO : RemoveOSSIM OssimDEMHandler::Instance()->OpenGeoidFile(geoidFile); @@ -255,9 +280,111 @@ bool DEMHandler::OpenGeoidFile(const std::string& geoidFile) m_GeoidFilename = geoidFile; } + if(m_Dataset) + { + CreateShiftedDataset(); + } + + Notify(); return pbError; } + +void DEMHandler::CreateShiftedDataset() +{ + + // WIP : no data is not handed at the moment + + double geoTransform[6]; + m_Dataset->GetGeoTransform(geoTransform); + + // Warp geoid dataset + auto warpOptions = GDALCreateWarpOptions();; + warpOptions->hSrcDS = m_GeoidDS; + //warpOptions->hDstDS = m_Dataset; + warpOptions->eResampleAlg = GRA_Bilinear; + warpOptions->eWorkingDataType = GDT_Float64; + warpOptions->nBandCount = 1; + warpOptions->panSrcBands = + (int *) CPLMalloc(sizeof(int) * warpOptions->nBandCount ); + warpOptions->panSrcBands[0] = 1; + warpOptions->panDstBands = + (int *) CPLMalloc(sizeof(int) * warpOptions->nBandCount ); + warpOptions->panDstBands[0] = 1; + + // Establish reprojection transformer. + warpOptions->pTransformerArg = + GDALCreateGenImgProjTransformer( m_GeoidDS, + GDALGetProjectionRef(m_GeoidDS), + m_Dataset, + GDALGetProjectionRef(m_Dataset), + FALSE, 0.0, 1 ); + warpOptions->pfnTransformer = GDALGenImgProjTransform; + + auto ds = static_cast (GDALCreateWarpedVRT(m_GeoidDS, + m_Dataset->GetRasterXSize(), + m_Dataset->GetRasterYSize(), + geoTransform, + warpOptions)); + +/* + auto warpedDataset = dynamic_cast(ds); + if(warpedDataset) + { + auto xmlWarpedDs= CPLSerializeXMLTree(warpedDataset->SerializeToXML(nullptr)); + std::cout << xmlWarpedDs << std::endl; + } +*/ + + ds->SetDescription(DEM_WARPED_DATASET_PATH.c_str()); + GDALClose(ds); + + GDALDriver *poDriver = (GDALDriver *) GDALGetDriverByName( "VRT" ); + GDALDataset *poVRTDS; + + poVRTDS = poDriver->Create( DEM_SHIFTED_DATASET_PATH.c_str(), m_Dataset->GetRasterXSize(), m_Dataset->GetRasterYSize(), 0, GDT_Float64, NULL ); + + poVRTDS->SetGeoTransform(geoTransform); + + poVRTDS->SetProjection(m_Dataset->GetProjectionRef()); + + char** derivedBandOptions = NULL; + + derivedBandOptions = CSLAddNameValue(derivedBandOptions, "subclass", "VRTDerivedRasterBand"); + derivedBandOptions = CSLAddNameValue(derivedBandOptions, "PixelFunctionType", "sum"); + poVRTDS->AddBand(GDT_Float64, derivedBandOptions); + + GDALRasterBand *poBand = poVRTDS->GetRasterBand( 1 ); + +// TODO use std string (and boost format ?) or stream + char demVrtXml[10000]; + + sprintf( demVrtXml, + "" + " %s" + " 1" + "", + DEM_DATASET_PATH.c_str()); + + poBand->SetMetadataItem( "source_0", demVrtXml, "new_vrt_sources" ); + + + char geoidVrtXml[10000]; + + sprintf( geoidVrtXml, + "" + " %s" + " 1" + "", + DEM_WARPED_DATASET_PATH.c_str()); + + + poBand->SetMetadataItem( "source_1", geoidVrtXml, "new_vrt_sources" ); + + GDALClose(poVRTDS); +} + + double DEMHandler::GetHeightAboveEllipsoid(double lon, double lat) const { double result = 0.; @@ -363,6 +490,7 @@ void DEMHandler::ClearDEMs() // This will call GDALClose on all datasets m_DatasetList.clear(); + Notify(); } void DEMHandler::SetDefaultHeightAboveEllipsoid(double height) @@ -370,6 +498,7 @@ void DEMHandler::SetDefaultHeightAboveEllipsoid(double height) OssimDEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(height); m_DefaultHeightAboveEllipsoid = height; + Notify(); } double DEMHandler::GetDefaultHeightAboveEllipsoid() const @@ -377,4 +506,12 @@ double DEMHandler::GetDefaultHeightAboveEllipsoid() const return m_DefaultHeightAboveEllipsoid; } +void DEMHandler::Notify() const +{ + for (const auto & observer: m_ObserverList) + { + observer->Update(); + } +}; + } // namespace otb diff --git a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx index eed293374b0c37722b4cdcb8c3aa25f0c158339a..9388469de9850608306aaddeece188fd406fbc6b 100644 --- a/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx +++ b/Modules/IO/IOGDAL/src/otbGDALImageIO.cxx @@ -1504,6 +1504,11 @@ void GDALImageIO::InternalWriteImageInformation(const void* buffer) std::string projectionRef( m_Imd.GetProjectionWKT() ); dataset->SetProjection(projectionRef.c_str()); } + else if (m_Imd.Has(MDGeom::ProjectionProj)) + { + std::string projectionRef( m_Imd.GetProjectionProj() ); + dataset->SetProjection(projectionRef.c_str()); + } /* -------------------------------------------------------------------- */ /* Case 2: Sensor geometry */ /* -------------------------------------------------------------------- */ @@ -1946,9 +1951,9 @@ void GDALImageIO::KeywordlistToMetadata(ImageMetadataBase::Keywordlist kwl, int { // GCPs have already been exported (see InternalWriteImageInformation) } - else if (kv.first == MetaData::MDGeomNames.left.at(MDGeom::ProjectionWKT)) + else if ((kv.first == MetaData::MDGeomNames.left.at(MDGeom::ProjectionWKT)) || (kv.first == MetaData::MDGeomNames.left.at(MDGeom::ProjectionProj))) { - // WKT projection have already been exported (see InternalWriteImageInformation) + // Projection have already been exported (see InternalWriteImageInformation) } else SetMetadataValue(kv.first.c_str(), kv.second.c_str(), band); diff --git a/Modules/IO/IOGDAL/src/otbGDALRPCTransformer.cxx b/Modules/IO/IOGDAL/src/otbGDALRPCTransformer.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5fcc4146ae22cfdd24a8beeb9bd5c012b652a00a --- /dev/null +++ b/Modules/IO/IOGDAL/src/otbGDALRPCTransformer.cxx @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbGDALRPCTransformer.h" +#include +#include "cpl_string.h" +#include "otbDEMHandler.h" + +namespace otb +{ +GDALRPCTransformer::GDALRPCTransformer(double LineOffset, double SampleOffset, double LatOffset, double LonOffset, double HeightOffset, + double LineScale, double SampleScale, double LatScale, double LonScale, double HeightScale, + const double (&LineNum)[20], const double (&LineDen)[20], const double (&SampleNum)[20], const double (&SampleDen)[20], + bool useDEM) + : m_UseDEM(useDEM) +{ + // Offsets + this->m_GDALRPCInfo.dfLINE_OFF = LineOffset; + this->m_GDALRPCInfo.dfSAMP_OFF = SampleOffset; + this->m_GDALRPCInfo.dfLAT_OFF = LatOffset; + this->m_GDALRPCInfo.dfLONG_OFF = LonOffset; + this->m_GDALRPCInfo.dfHEIGHT_OFF = HeightOffset; + // Scales + this->m_GDALRPCInfo.dfLINE_SCALE = LineScale; + this->m_GDALRPCInfo.dfSAMP_SCALE = SampleScale; + this->m_GDALRPCInfo.dfLAT_SCALE = LatScale; + this->m_GDALRPCInfo.dfLONG_SCALE = LonScale; + this->m_GDALRPCInfo.dfHEIGHT_SCALE = HeightScale; + // Coefficients + std::copy_n(LineNum, 20, this->m_GDALRPCInfo.adfLINE_NUM_COEFF); + std::copy_n(LineDen, 20, this->m_GDALRPCInfo.adfLINE_DEN_COEFF); + std::copy_n(SampleNum, 20, this->m_GDALRPCInfo.adfSAMP_NUM_COEFF); + std::copy_n(SampleDen, 20, this->m_GDALRPCInfo.adfSAMP_DEN_COEFF); + + // min/max longitude and latitude (default values) + this->m_GDALRPCInfo.dfMIN_LONG = -180.0; + this->m_GDALRPCInfo.dfMIN_LAT = -90.0; + this->m_GDALRPCInfo.dfMAX_LONG = 180.0; + this->m_GDALRPCInfo.dfMAX_LAT = 90.0; + + otb::DEMHandler::GetInstance().AttachObserver(this); + + this->SetOption("RPC_MAX_ITERATIONS", "40"); + this->SetOption("RPC_PIXEL_ERROR_THRESHOLD", "0.000001"); +} + +GDALRPCTransformer::GDALRPCTransformer(const Projection::RPCParam & param, bool useDEM) + : GDALRPCTransformer( param.LineOffset, param.SampleOffset, param.LatOffset, param.LonOffset, param.HeightOffset, + param.LineScale, param.SampleScale, param.LatScale, param.LonScale, param.HeightScale, + param.LineNum, param.LineDen, param.SampleNum, param.SampleDen, + useDEM) +{ +} + +GDALRPCTransformer::~GDALRPCTransformer() +{ + if(m_TransformArg != nullptr) + GDALDestroyTransformer(m_TransformArg); + CSLDestroy(m_Options); + + otb::DEMHandler::GetInstance().DetachObserver(this); +} + +void GDALRPCTransformer::SetOption(const std::string& Name, const std::string& Value) +{ + this->m_Options = CSLSetNameValue(m_Options, Name.c_str(), Value.c_str()); + this->m_Modified = true; +} + +void GDALRPCTransformer::SetPixErrThreshold(double PixErrThreshold) +{ + this->m_PixErrThreshold = PixErrThreshold; + this->m_Modified = true; +} + +void GDALRPCTransformer::Update() +{ + // We need a lock here because Update() is not called until the first call + // to Forward/InverseTransform(), which might be done in a thread. + const std::lock_guard lock(m_Mutex); + + auto & demHandler = otb::DEMHandler::GetInstance(); + + if (m_UseDEM) + { + if (demHandler.GetDEMCount() > 0) + { + if (demHandler.GetGeoidFile().empty()) + { + this->SetOption("RPC_DEM", demHandler.DEM_DATASET_PATH); + } + else + { + this->SetOption("RPC_DEM", demHandler.DEM_SHIFTED_DATASET_PATH); + } + this->SetOption("RPC_DEM_MISSING_VALUE", std::to_string(demHandler.GetDefaultHeightAboveEllipsoid())); + } + else + { + // RPC height is used as a constant height offset applied to all points in case no DEM is set. + this->SetOption("RPC_HEIGHT", std::to_string(demHandler.GetDefaultHeightAboveEllipsoid())); + } + } + + if(m_TransformArg != nullptr) + GDALDestroyTransformer(m_TransformArg); + this->m_TransformArg = GDALCreateRPCTransformer(&this->m_GDALRPCInfo, false, this->m_PixErrThreshold, this->m_Options); + this->m_Modified = false; +} + +bool GDALRPCTransformer::ForwardTransform(double* x, double* y, double* z, int nPointCount) +{ + assert(x); + assert(y); + assert(z); + if (this->m_Modified) + this->Update(); + std::vector success(nPointCount); + { + const std::lock_guard lock(m_Mutex); + GDALRPCTransform(this->m_TransformArg, false, nPointCount, x, y, z, success.data()); + } + bool finalSuccess = std::all_of(success.begin(), success.end(), [](int i){return i;}); + return finalSuccess; +} + +GDALRPCTransformer::PointType GDALRPCTransformer::ForwardTransform(GDALRPCTransformer::PointType p) +{ + if (m_Modified) + this->Update(); + int success; + { + const std::lock_guard lock(m_Mutex); + GDALRPCTransform(this->m_TransformArg, false, 1, &p[0], &p[1], &p[2], &success); + } + if (!success) + throw std::runtime_error("GDALRPCTransform was not able to process the ForwardTransform."); + return p; +} + + +bool GDALRPCTransformer::InverseTransform(double* x, double* y, double* z, int nPointCount) +{ + assert(x); + assert(y); + assert(z); + if (this->m_Modified) + this->Update(); + std::vector success(nPointCount); + { + const std::lock_guard lock(m_Mutex); + GDALRPCTransform(this->m_TransformArg, true, nPointCount, x, y, z, success.data()); + } + bool finalSuccess = std::all_of(success.begin(), success.end(), [](int i){return i;}); + return finalSuccess; +} + +GDALRPCTransformer::PointType GDALRPCTransformer::InverseTransform(GDALRPCTransformer::PointType p) +{ + if (m_Modified) + this->Update(); + int success; + { + const std::lock_guard lock(m_Mutex); + GDALRPCTransform(this->m_TransformArg, true, 1, &p[0], &p[1], &p[2], &success); + } + if (!success) + throw std::runtime_error("GDALRPCTransform was not able to process the InverseTransform."); + return p; +} +} diff --git a/Modules/IO/IOGDAL/test/CMakeLists.txt b/Modules/IO/IOGDAL/test/CMakeLists.txt index 9c239d2514cb3fb2097e59ed7749aad98d68a89a..c20b2a072a52cde0f67cdc867c6c89b91712e97d 100644 --- a/Modules/IO/IOGDAL/test/CMakeLists.txt +++ b/Modules/IO/IOGDAL/test/CMakeLists.txt @@ -32,6 +32,8 @@ otbGDALImageIOTestCanRead.cxx otbMultiDatasetReadingInfo.cxx otbOGRVectorDataIOCanRead.cxx otbGDALImageIOImportExportMetadata.cxx +otbGDALRPCTransformerTest.cxx +otbGDALRPCTransformerTest2.cxx ) add_executable(otbIOGDALTestDriver ${OTBIOGDALTests}) @@ -260,3 +262,73 @@ foreach(INPUTFILE_PIXELTYPE ${INPUTFILE_PIXELTYPES_LIST}) 1 5 10 2) #old file hdr sans extensions endforeach() + +otb_add_test(NAME TuGDALRPCTransformerTest + COMMAND otbIOGDALTestDriver + otbGDALRPCTransformerTest + ${INPUTDATA}/TuGDALRPCTransformerTest_DEM.tif + ) + +otb_add_test(NAME ioTvGDALRPCTransformerTest_ikonos_geom + COMMAND otbIOGDALTestDriver + otbGDALRPCTransformerTest2 + ${INPUTDATA}/ikonos/ikonos-1.geom # Geom + ${INPUTDATA}/ikonos/ikonos-1.gcp2 # GCP + 0.04 # GeoTol + 0.1 # ImgTol + ) + +otb_add_test(NAME ioTvGDALRPCTransformerTest_ikonos_product + COMMAND otbIOGDALTestDriver + otbGDALRPCTransformerTest2 + LARGEINPUT{IKONOS/BLOSSEVILLE/po_2619900_blu_0000000.tif} # Product + ${INPUTDATA}/ikonos/ikonos-1.gcp2 # GCP + 0.04 # GeoTol + 0.1 # ImgTol + ) + +otb_add_test(NAME ioTvGDALRPCTransformerTest_quickbird + COMMAND otbIOGDALTestDriver + otbGDALRPCTransformerTest2 + ${INPUTDATA}/QB/qb-1.geom # Geom + ${INPUTDATA}/QB/qb-1.gcp2 # GCP + 0.024 # GeoTol + 0.1 # ImgTol + ) + +otb_add_test(NAME ioTvGDALRPCTransformerTest_spot6 + COMMAND otbIOGDALTestDriver + otbGDALRPCTransformerTest2 + ${INPUTDATA}/spot6/spot6-1.geom # Geom + ${INPUTDATA}/spot6/spot6-1.gcp2 # GCP + 0.06 # GeoTol + 0.1 # ImgTol + ) + +otb_add_test(NAME ioTvGDALRPCTransformerTest_worldview2 + COMMAND otbIOGDALTestDriver + otbGDALRPCTransformerTest2 + ${INPUTDATA}/wv2/wv2-1.geom # Geom + ${INPUTDATA}/wv2/wv2-1.gcp2 # GCP + 0.0185 # GeoTol + 0.1 # ImgTol + ) + +otb_add_test(NAME ioTvGDALRPCTransformerTest_pl_hnord_geom + COMMAND otbIOGDALTestDriver + otbGDALRPCTransformerTest2 + ${INPUTDATA}/pleiades/pleiades-1.geom # Geom + ${INPUTDATA}/pleiades/pleiades-1.gcp2 # GCP + 0.02 # GeoTol + 0.1 # ImgTol + ) + +otb_add_test(NAME ioTvGDALRPCTransformerTest_pl_hnord_product + COMMAND otbIOGDALTestDriver + otbGDALRPCTransformerTest2 + LARGEINPUT{PLEIADES/TLSE_JP2_DIMAPv2_PRIMARY_PMS_lossless_12bits/IMGPHR_201222215194743808/IMG_PHR1A_PMS_201201151100183_SEN_IPU_20120222_0901-001_R1C1.JP2} # Product + ${INPUTDATA}/pleiades/pleiades-1.gcp2 # GCP + 0.02 # GeoTol + 0.1 # ImgTol + ) + diff --git a/Modules/IO/IOGDAL/test/otbGDALRPCTransformerTest.cxx b/Modules/IO/IOGDAL/test/otbGDALRPCTransformerTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a790797846ef28a0b27ceb885190ae9baa300ea7 --- /dev/null +++ b/Modules/IO/IOGDAL/test/otbGDALRPCTransformerTest.cxx @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "otbGDALRPCTransformer.h" +#include "otbMacro.h" +#include "otbImageMetadata.h" +#include "gdal_utils.h" +#include +#include "otbDEMHandler.h" + +int otbGDALRPCTransformerTest(int itkNotUsed(argc), char* argv[]) +{ + bool success = true; + + double LineOffset = 16201.0, SampleOffset = 15184.0, + LatOffset = 39.7792, LonOffset = 125.7510, HeightOffset = 97.0, + LineScale = 16480.0, SampleScale = 15217.0, + LatScale = 0.0900, LonScale = 0.1096, HeightScale = 501.0; + const double line_num_coeff[20] = { + +5.105608E-04, -2.921055E-02, -1.010407E+00, -1.743729E-02, -6.604239E-05, + -7.871396E-05, +3.027877E-04, -4.323587E-04, -2.624751E-04, +6.186490E-06, + +1.084676E-06, +5.389738E-05, +4.145232E-06, +3.911486E-07, +1.772434E-05, + +3.302960E-06, +3.006106E-06, +1.662606E-05, +6.051677E-06, -2.657667E-08}; + const double line_den_coeff[20] = { + +1.000000E+00, -9.652128E-05, +2.488346E-04, +3.089019E-04, -2.120170E-06, + +4.117913E-07, +1.370009E-06, +1.357281E-05, -4.174324E-06, -3.146787E-06, + -7.724587E-06, +3.524480E-04, -1.303224E-05, -8.507679E-07, -1.670972E-05, + +6.781061E-06, +5.602262E-07, +1.161421E-05, +4.681872E-06, +5.593931E-08}; + const double samp_num_coeff[20] = { + -2.429563E-04, +1.028320E+00, -3.360972E-02, +3.519600E-03, -6.568341E-04, + +5.951139E-04, -3.875716E-04, +1.260622E-04, -5.273817E-05, -4.418981E-06, + -3.520581E-06, -2.502760E-04, -4.167704E-05, -5.973233E-05, -1.438949E-04, + +7.603041E-06, +2.358136E-06, -2.275274E-05, +1.602657E-06, -1.716541E-07}; + const double samp_den_coeff[20] = { + +1.000000E+00, +7.765620E-05, +6.568707E-04, -6.270621E-04, +5.163170E-05, + +6.979463E-06, +2.476334E-07, +1.083558E-04, -4.043734E-05, -5.819288E-05, + +1.778201E-07, +5.665202E-05, +6.927205E-06, +6.793485E-07, +3.604209E-05, + -4.057103E-07, -8.291254E-07, +1.010650E-05, -2.875552E-06, +5.142751E-08}; + + otb::GDALRPCTransformer transformer(LineOffset, SampleOffset, LatOffset, LonOffset, HeightOffset, + LineScale, SampleScale, LatScale, LonScale, HeightScale, + line_num_coeff, line_den_coeff, samp_num_coeff, samp_den_coeff, true); + + // Test ForwardTransform + std::vector x = {20.5, 20.5}; + std::vector y = {10.5, 10.5}; + std::vector z = {0, 0}; + double exp_x = 125.64830100509131; + double exp_y = 39.869433991997553; + double exp_z = 0.0; + std::cout << "Test ForwardTransform with double interface." << '\n'; + if(!transformer.ForwardTransform(x.data(), y.data(), z.data(), 2)) + { + std::cout << "ForwardTransform failed, returned False." << '\n'; + success = false; + } else { + if (x[0] - exp_x > 0.000001) + { + std::cout << "Bad value for latitude. Expected " << exp_x << " but computed " << x[0] << "\n"; + success = false; + } + if (y[0] - exp_y > 0.000001) + { + std::cout << "Bad value for longitude. Expected " << exp_y << " but computed " << y[0] << "\n"; + success = false; + } + if (z[0] - exp_z > 0.1) + { + std::cout << "Bad value for height. Expected " << exp_z << " but computed " << z[0] << "\n"; + success = false; + } + } + otb::GDALRPCTransformer::PointType zePoint; + zePoint[0] = 20.5; + zePoint[1] = 10.5; + zePoint[2] = 0.0; + std::cout << "Test ForwardTransform with point interface." << '\n'; + zePoint = transformer.ForwardTransform(zePoint); + if (zePoint[0] - exp_x > 0.000001) + { + std::cout << "Bad value for latitude. Expected " << exp_x << " but computed " << zePoint[0] << "\n"; + success = false; + } + if (zePoint[1] - exp_y > 0.000001) + { + std::cout << "Bad value for longitude. Expected " << exp_y << " but computed " << zePoint[1] << "\n"; + success = false; + } + if (zePoint[2] - exp_z > 0.1) + { + std::cout << "Bad value for height. Expected " << exp_z << " but computed " << zePoint[2] << "\n"; + success = false; + } + + // Test InverseTransform + x = {exp_x, exp_x}; + y = {exp_y, exp_y}; + zePoint[0] = exp_x; + zePoint[1] = exp_y; + zePoint[2] = 0.0; + exp_x = 20.5; + exp_y = 10.5; + std::cout << "Test InverseTransform with double interface." << '\n'; + if(!transformer.InverseTransform(x.data(), y.data(), z.data(), 2)) + { + std::cout << "InverseTransform failed, returned False." << '\n'; + success = false; + } else { + if (x[0] - exp_x > 0.05) + { + std::cout << "Bad value for latitude. Expected " << exp_x << " but computed " << x[0] << "\n"; + success = false; + } + if (y[0] - exp_y > 0.05) + { + std::cout << "Bad value for longitude. Expected " << exp_y << " but computed " << y[0] << "\n"; + success = false; + } + if (z[0] - exp_z > 0.1) + { + std::cout << "Bad value for height. Expected " << exp_z << " but computed " << z[0] << "\n"; + success = false; + } + } + std::cout << "Test InverseTransform with point interface." << '\n'; + zePoint = transformer.InverseTransform(zePoint); + if (zePoint[0] - exp_x > 0.05) + { + std::cout << "Bad value for latitude. Expected " << exp_y << " but computed " << zePoint[1] << "\n"; + success = false; + } + if (zePoint[1] - exp_y > 0.05) + { + std::cout << "Bad value for longitude. Expected " << exp_y << " but computed " << zePoint[1] << "\n"; + success = false; + } + if (zePoint[2] - exp_z > 0.1) + { + std::cout << "Bad value for height. Expected " << exp_z << " but computed " << zePoint[2] << "\n"; + success = false; + } + + // Test with a DEM + otb::DEMHandler& dem = otb::DEMHandler::GetInstance(); + dem.OpenDEMFile(argv[1]); + zePoint[0] = 20.5; + zePoint[1] = 10.5; + zePoint[2] = 0.0; + exp_x = 125.64828521533849; + exp_y = 39.869345204440144; + transformer.SetOption("RPC_DEM", dem.DEM_DATASET_PATH); + transformer.SetOption("RPC_HEIGHT_SCALE", "2"); + + std::cout << "Test ForwardTransform with DEM." << '\n'; + zePoint = transformer.ForwardTransform(zePoint); + if (zePoint[0] - exp_x > 0.000001) + { + std::cout << "Bad value for latitude. Expected " << exp_y << " but computed " << zePoint[1] << "\n"; + success = false; + } + if (zePoint[1] - exp_y > 0.000001) + { + std::cout << "Bad value for longitude. Expected " << exp_y << " but computed " << zePoint[1] << "\n"; + success = false; + } + if (zePoint[2] - exp_z > 0.1) + { + std::cout << "Bad value for height. Expected " << exp_z << " but computed " << zePoint[2] << "\n"; + success = false; + } + + exp_x = 20.5; + exp_y = 10.5; + std::cout << "Test InverseTransform with DEM." << '\n'; + zePoint = transformer.InverseTransform(zePoint); + if (zePoint[0] - exp_x > 0.05) + { + std::cout << "Bad value for latitude. Expected " << exp_y << " but computed " << zePoint[1] << "\n"; + success = false; + } + if (zePoint[1] - exp_y > 0.05) + { + std::cout << "Bad value for longitude. Expected " << exp_y << " but computed " << zePoint[1] << "\n"; + success = false; + } + if (zePoint[2] - exp_z > 0.1) + { + std::cout << "Bad value for height. Expected " << exp_z << " but computed " << zePoint[2] << "\n"; + success = false; + } + + if (success) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; +} diff --git a/Modules/IO/IOGDAL/test/otbGDALRPCTransformerTest2.cxx b/Modules/IO/IOGDAL/test/otbGDALRPCTransformerTest2.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b2195b6c4780f66c45ce8208025efb1503e41886 --- /dev/null +++ b/Modules/IO/IOGDAL/test/otbGDALRPCTransformerTest2.cxx @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES) + * + * This file is part of Orfeo Toolbox + * + * https://www.orfeo-toolbox.org/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "itkPoint.h" +#include "otbGDALRPCTransformer.h" +#include "itkEuclideanDistanceMetric.h" +#include "otbGeographicalDistance.h" +#include "otbImageMetadata.h" +#include "otbMetaDataKey.h" +#include "otbGeomMetadataSupplier.h" +#include "otbImageMetadataInterfaceFactory.h" +#include "otbMacro.h" +#include "otbDEMHandler.h" +#include "otbImage.h" +#include "otbImageFileReader.h" + +//typedef otb::Image ImageType; +typedef std::vector> pointsContainerType; +typedef itk::Statistics::EuclideanDistanceMetric DistanceType; +typedef otb::GeographicalDistance GeographicalDistanceType; + +int otbGDALRPCTransformerTest2(int itkNotUsed(argc), char* argv[]) +{ + bool success = true; + otb::GDALRPCTransformer::PointType imagePoint; + otb::GDALRPCTransformer::PointType geo3dPoint; + + // Inputs + std::string rpcFile(argv[1]); + std::string gcpFileName(argv[2]); + double geoTol(atof(argv[3])); + double imgTol(atof(argv[4])); + + // Tools + auto distance = DistanceType::New(); + auto geoDistance = GeographicalDistanceType::New(); + + otb::ImageMetadata imd; + if (0 == rpcFile.compare(rpcFile.length() - 4, 4, "geom")) + { + // Fetching the RPC model from a GEOM file + otb::GeomMetadataSupplier geomSupplier(rpcFile); + for (int loop = 0 ; loop < geomSupplier.GetNbBands() ; ++loop) + imd.Bands.emplace_back(); + auto imi = otb::ImageMetadataInterfaceFactory::CreateIMI(imd, geomSupplier); + imd = imi->GetImageMetadata(); + geomSupplier.FetchRPC(imd); + } + else + { + // Fetching the RPC model from a product + typedef otb::Image ImageType; + typedef otb::ImageFileReader ImageFileReaderType; + auto reader = ImageFileReaderType::New(); + reader->SetFileName(rpcFile); + reader->UpdateOutputInformation(); + imd = reader->GetOutput()->GetImageMetadata(); + } + auto rpcModel = boost::any_cast(imd[otb::MDGeom::RPC]); + + // Setting the RPCTransformer + // otb::DEMHandler::GetInstance().SetDefaultHeightAboveEllipsoid(0.0); + otb::GDALRPCTransformer transformer(rpcModel.LineOffset, rpcModel.SampleOffset, rpcModel.LatOffset, rpcModel.LonOffset, rpcModel.HeightOffset, + rpcModel.LineScale, rpcModel.SampleScale, rpcModel.LatScale, rpcModel.LonScale, rpcModel.HeightScale, + rpcModel.LineNum, rpcModel.LineDen, rpcModel.SampleNum, rpcModel.SampleDen, false); + + // Loading the GCP + pointsContainerType pointsContainer; + pointsContainerType geo3dPointsContainer; + std::ifstream file(gcpFileName, std::ios::in); + if (file) + { + std::string line; + while (getline(file, line)) + { + if (line.find_first_of("#") != 0) + { + std::istringstream iss(line); + + iss >> imagePoint[0] >> imagePoint[1] >> geo3dPoint[0] >> geo3dPoint[1] >> geo3dPoint[2]; + imagePoint[2] = geo3dPoint[2]; + + pointsContainer.push_back(imagePoint); + geo3dPointsContainer.push_back(geo3dPoint); + } + } + file.close(); + } + + // For each CGP + for (pointsContainerType::iterator pointsIt = pointsContainer.begin(), geo3dPointsIt = geo3dPointsContainer.begin() ; + (pointsIt != pointsContainer.end()) && (geo3dPointsIt != geo3dPointsContainer.end()) ; + ++pointsIt, ++geo3dPointsIt) + { + // std::cout << "Point: " << *pointsIt << " GeoPoint: " << *geo3dPointsIt << "\n"; + // Testing forward transform + geo3dPoint = transformer.ForwardTransform(*pointsIt); + auto forwardPointDistance = geoDistance->Evaluate(geo3dPoint, *geo3dPointsIt); + if (forwardPointDistance > geoTol) + { + std::cerr << "Geo distance between otbGDALRPCTransformer->ForwardTransform and GCP too high :\n" + << "GCP: " << *geo3dPointsIt << " / computed: " << geo3dPoint << "\n" + << "dist = " << forwardPointDistance << " (tol = " << geoTol << ")" << std::endl; + success = false; + } + + // Testing inverse transform + imagePoint = transformer.InverseTransform(*geo3dPointsIt); + auto inversePointDistance = distance->Evaluate(imagePoint, *pointsIt); + if (inversePointDistance > imgTol) + { + std::cerr << "Distance between otbGDALRPCTransformer->InverseTransform and GCP too high :\n" + << "GCP: " << *pointsIt << " / computed: " << imagePoint << "\n" + << "dist = " << inversePointDistance << " (tol = " << imgTol << ")" << std::endl; + success = false; + } + } + + if (success) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; +} diff --git a/Modules/IO/IOGDAL/test/otbIOGDALTestDriver.cxx b/Modules/IO/IOGDAL/test/otbIOGDALTestDriver.cxx index 5458ac35a60dc97dea80a6f36e8b91db43066c6f..bb98f59e829bb7a25a2ad7b26aecaa6ae7ccccba 100644 --- a/Modules/IO/IOGDAL/test/otbIOGDALTestDriver.cxx +++ b/Modules/IO/IOGDAL/test/otbIOGDALTestDriver.cxx @@ -34,4 +34,6 @@ void RegisterTests() REGISTER_TEST(otbMultiDatasetReadingInfo); REGISTER_TEST(otbOGRVectorDataIOTestCanRead); REGISTER_TEST(otbGDALImageIOImportExportMetadata); + REGISTER_TEST(otbGDALRPCTransformerTest); + REGISTER_TEST(otbGDALRPCTransformerTest2); } diff --git a/Modules/IO/KMZWriter/include/otbKmzProductWriter.hxx b/Modules/IO/KMZWriter/include/otbKmzProductWriter.hxx index f2de585ae6b7d9f429c46c384335f7a94bf66b19..2e6227c6d250588ad952effa3394b7774654aa8c 100644 --- a/Modules/IO/KMZWriter/include/otbKmzProductWriter.hxx +++ b/Modules/IO/KMZWriter/include/otbKmzProductWriter.hxx @@ -415,7 +415,7 @@ void KmzProductWriter::Tiling() /** TODO : Generate KML for this tile */ // Search Lat/Lon box m_Transform = TransformType::New(); - m_Transform->SetInputKeywordList(m_ResampleVectorImage->GetImageKeywordlist()); + m_Transform->SetInputImageMetadata(&(m_ResampleVectorImage->GetImageMetadata())); m_Transform->SetInputProjectionRef(m_VectorImage->GetProjectionRef()); m_Transform->SetOutputProjectionRef(wgsRef); m_Transform->InstantiateTransform(); diff --git a/Modules/Registration/DisparityMap/include/otbDisparityMapTo3DFilter.hxx b/Modules/Registration/DisparityMap/include/otbDisparityMapTo3DFilter.hxx index 9913889176920c0e0eba9f342b99df2f23a471d3..6bd8416b88202ce90c3b77d99c9c299e2cbf1fb3 100644 --- a/Modules/Registration/DisparityMap/include/otbDisparityMapTo3DFilter.hxx +++ b/Modules/Registration/DisparityMap/include/otbDisparityMapTo3DFilter.hxx @@ -200,8 +200,9 @@ void DisparityMapTo3DFilterSetInputKeywordList(m_LeftKeywordList); - m_RightToGroundTransform->SetInputKeywordList(m_RightKeywordList); + //TODO: Replace KeywordLists by ImageMetadatas + //m_LeftToGroundTransform->SetInputKeywordList(m_LeftKeywordList); + //m_RightToGroundTransform->SetInputKeywordList(m_RightKeywordList); m_LeftToGroundTransform->InstantiateTransform(); m_RightToGroundTransform->InstantiateTransform(); diff --git a/Modules/Registration/DisparityMap/include/otbDisparityMapToDEMFilter.hxx b/Modules/Registration/DisparityMap/include/otbDisparityMapToDEMFilter.hxx index 67cda3d5208fff9cc198e39b879424268fb7a1b6..762de49fa22b36204bcc0ce3d766dcdc33a177b6 100644 --- a/Modules/Registration/DisparityMap/include/otbDisparityMapToDEMFilter.hxx +++ b/Modules/Registration/DisparityMap/include/otbDisparityMapToDEMFilter.hxx @@ -211,11 +211,11 @@ void DisparityMapToDEMFilter RSTransform2DType; RSTransform2DType::Pointer leftToGroundTransform = RSTransform2DType::New(); - leftToGroundTransform->SetInputKeywordList(leftImgPtr->GetImageKeywordlist()); + leftToGroundTransform->SetInputImageMetadata(&(leftImgPtr->GetImageMetadata())); leftToGroundTransform->InstantiateTransform(); RSTransform2DType::Pointer rightToGroundTransform = RSTransform2DType::New(); - rightToGroundTransform->SetInputKeywordList(rightImgPtr->GetImageKeywordlist()); + rightToGroundTransform->SetInputImageMetadata(&(rightImgPtr->GetImageMetadata())); rightToGroundTransform->InstantiateTransform(); // left image @@ -335,7 +335,7 @@ void DisparityMapToDEMFilterGetSignedSpacing(); RSTransformType::Pointer groundToLeftTransform = RSTransformType::New(); - groundToLeftTransform->SetOutputKeywordList(leftSensor->GetImageKeywordlist()); + groundToLeftTransform->SetOutputImageMetadata(&(leftSensor->GetImageMetadata())); groundToLeftTransform->InstantiateTransform(); // For the disparity maps and mask @@ -591,8 +591,8 @@ void DisparityMapToDEMFilterSetInputKeywordList(leftSensor->GetImageKeywordlist()); - m_RightToGroundTransform->SetInputKeywordList(rightSensor->GetImageKeywordlist()); + m_LeftToGroundTransform->SetInputImageMetadata(&(leftSensor->GetImageMetadata())); + m_RightToGroundTransform->SetInputImageMetadata(&(rightSensor->GetImageMetadata())); m_LeftToGroundTransform->InstantiateTransform(); m_RightToGroundTransform->InstantiateTransform(); diff --git a/Modules/Registration/DisparityMap/include/otbMultiDisparityMapTo3DFilter.h b/Modules/Registration/DisparityMap/include/otbMultiDisparityMapTo3DFilter.h index d56467748ba250a25b65d3918a30391f6efb94c5..6ffdf60b8708ac945b41a36706bb4ee582ca58fa 100644 --- a/Modules/Registration/DisparityMap/include/otbMultiDisparityMapTo3DFilter.h +++ b/Modules/Registration/DisparityMap/include/otbMultiDisparityMapTo3DFilter.h @@ -94,8 +94,6 @@ public: typedef typename PointSetType::PointsContainer PointsContainer; typedef typename PointSetType::PointDataContainer LabelContainer; - typedef otb::ImageKeywordlist ImageKeywordListType; - typedef std::map> DispMapIteratorList; typedef std::map> MaskIteratorList; @@ -126,24 +124,24 @@ public: const TResidueImage* GetResidueOutput() const; TResidueImage* GetResidueOutput(); - /** Set keywordlist of the reference image */ - void SetReferenceKeywordList(const ImageKeywordListType kwl) + /** Set ImageMetadata of the reference image */ + void SetReferenceImageMetadata(const ImageMetadata* imd) { - this->m_ReferenceKeywordList = kwl; + this->m_ReferenceImageMetadata = imd; this->Modified(); } - /** Get keywordlist of the reference image */ - const ImageKeywordListType& GetReferenceKeywordList() const + /** Get ImageMetadata of the reference image */ + const ImageMetadata* GetReferenceImageMetadata() const { - return this->m_ReferenceKeywordList; + return this->m_ReferenceImageMetadata; } - /** Set keywordlist of the moving image 'index' */ - void SetMovingKeywordList(unsigned int index, const ImageKeywordListType kwl); + /** Set ImageMetadata of the moving image 'index' */ + void SetMovingImageMetadata(unsigned int index, const ImageMetadata* imd); - /** Get keywordlist of the moving image 'index' */ - const ImageKeywordListType& GetMovingKeywordList(unsigned int index) const; + /** Get ImageMetadata of the moving image 'index' */ + const ImageMetadata* GetMovingImageMetadata(unsigned int index) const; protected: /** Constructor */ @@ -158,9 +156,6 @@ protected: /** Generate input requested region */ void GenerateInputRequestedRegion() override; - /** Before threaded generate data */ - void BeforeThreadedGenerateData() override; - /** Threaded generate data */ void ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType threadId) override; @@ -168,17 +163,13 @@ private: MultiDisparityMapTo3DFilter(const Self&) = delete; void operator=(const Self&) = delete; - /** Keywordlist of reference sensor image */ - ImageKeywordListType m_ReferenceKeywordList; - - /** Keywordlists of moving sensor images */ - std::vector m_MovingKeywordLists; + /** ImageMetadata of reference sensor image */ + const ImageMetadata* m_ReferenceImageMetadata = nullptr; + + /** ImageMetadata of moving sensor images */ + std::vector m_MovingImageMetadatas; - /** Reference sensor image transform */ - RSTransformType::Pointer m_ReferenceToGroundTransform; - /** Moving sensor image transforms */ - std::vector m_MovingToGroundTransform; }; } // end namespace otb diff --git a/Modules/Registration/DisparityMap/include/otbMultiDisparityMapTo3DFilter.hxx b/Modules/Registration/DisparityMap/include/otbMultiDisparityMapTo3DFilter.hxx index 8439caf6a01fd899059137ed419da3041563184a..1b5e23390934b6a565ff410cb2ff90e83ebc1ee4 100644 --- a/Modules/Registration/DisparityMap/include/otbMultiDisparityMapTo3DFilter.hxx +++ b/Modules/Registration/DisparityMap/include/otbMultiDisparityMapTo3DFilter.hxx @@ -34,7 +34,7 @@ MultiDisparityMapTo3DFilter 3 inputs) this->SetNumberOfRequiredInputs(3); this->SetNumberOfRequiredInputs(1); - this->m_MovingKeywordLists.resize(1); + this->m_MovingImageMetadatas.resize(1); // Set the outputs this->SetNumberOfRequiredOutputs(2); @@ -53,14 +53,14 @@ void MultiDisparityMapTo3DFilter 0) { this->SetNumberOfRequiredInputs(3 * nb); - this->m_MovingKeywordLists.resize(nb); + this->m_MovingImageMetadatas.resize(nb); } } template unsigned int MultiDisparityMapTo3DFilter::GetNumberOfMovingImages() { - return this->m_MovingKeywordLists.size(); + return this->m_MovingImageMetadatas.size(); } template @@ -143,24 +143,24 @@ TResidueImage* MultiDisparityMapTo3DFilter -void MultiDisparityMapTo3DFilter::SetMovingKeywordList(unsigned int index, - const ImageKeywordListType kwl) +void MultiDisparityMapTo3DFilter::SetMovingImageMetadata(unsigned int index, + const ImageMetadata* imd) { - if (this->m_MovingKeywordLists.size() > index) + if (this->m_MovingImageMetadatas.size() > index) { - this->m_MovingKeywordLists[index] = kwl; + this->m_MovingImageMetadatas[index] = imd; } } template -const typename MultiDisparityMapTo3DFilter::ImageKeywordListType& -MultiDisparityMapTo3DFilter::GetMovingKeywordList(unsigned int index) const +const ImageMetadata* +MultiDisparityMapTo3DFilter::GetMovingImageMetadata(unsigned int index) const { - if (this->m_MovingKeywordLists.size() <= index) + if (this->m_MovingImageMetadatas.size() <= index) { - itkExceptionMacro(<< "Keywordlist index is outside the container"); + itkExceptionMacro(<< "ImageMetadata index is outside the container"); } - return this->m_MovingKeywordLists[index]; + return this->m_MovingImageMetadatas[index]; } template @@ -185,14 +185,17 @@ void MultiDisparityMapTo3DFilterSetOrigin(horizDisp->GetOrigin()); residuePtr->SetSignedSpacing(horizDisp->GetSignedSpacing()); - if (this->m_ReferenceKeywordList.GetSize() > 0) + if (this->m_ReferenceImageMetadata) { - itk::EncapsulateMetaData(outputPtr->GetMetaDataDictionary(), MetaDataKey::OSSIMKeywordlistKey, this->m_ReferenceKeywordList); - itk::EncapsulateMetaData(residuePtr->GetMetaDataDictionary(), MetaDataKey::OSSIMKeywordlistKey, this->m_ReferenceKeywordList); + auto outputmetadata = *m_ReferenceImageMetadata; + // Don't copy band metadata, as output bands are not related to input bands. + outputmetadata.Bands.clear(); + outputPtr->SetImageMetadata(outputmetadata); + residuePtr->SetImageMetadata(outputmetadata); } else { - itkExceptionMacro(<< "Reference keywordlist is missing"); + itkExceptionMacro(<< "Reference ImageMetadata is missing"); } } else @@ -264,38 +267,37 @@ void MultiDisparityMapTo3DFilterm_MovingKeywordLists.size(); ++k) + // Check moving ImageMetadata + for (unsigned int k = 0; k < this->m_MovingImageMetadatas.size(); ++k) { - if (this->m_MovingKeywordLists[k].GetSize() == 0) + if (!this->m_MovingImageMetadatas[k]) { - itkExceptionMacro(<< "Keywordlist of moving image at position " << k << " is empty"); + itkExceptionMacro(<< "ImageMetadata of moving image at position " << k << " is empty"); } } } template -void MultiDisparityMapTo3DFilter::BeforeThreadedGenerateData() -{ - // Instantiate all transforms - this->m_ReferenceToGroundTransform = RSTransformType::New(); - this->m_ReferenceToGroundTransform->SetInputKeywordList(this->m_ReferenceKeywordList); - this->m_ReferenceToGroundTransform->InstantiateTransform(); +void MultiDisparityMapTo3DFilter::ThreadedGenerateData(const RegionType& outputRegionForThread, + itk::ThreadIdType itkNotUsed(threadId)) +{ // Instantiate all transforms + auto referenceToGroundTransform = RSTransformType::New(); + + referenceToGroundTransform->SetInputImageMetadata(this->m_ReferenceImageMetadata); + referenceToGroundTransform->InstantiateTransform(); - this->m_MovingToGroundTransform.clear(); - for (unsigned int k = 0; k < this->m_MovingKeywordLists.size(); ++k) + /** Moving sensor image transforms */ + std::vector movingToGroundTransform; + + for (unsigned int k = 0; k < this->m_MovingImageMetadatas.size(); ++k) { RSTransformType::Pointer transfo = RSTransformType::New(); - transfo->SetInputKeywordList(this->m_MovingKeywordLists[k]); + transfo->SetInputImageMetadata(this->m_MovingImageMetadatas[k]); transfo->InstantiateTransform(); - this->m_MovingToGroundTransform.push_back(transfo); + movingToGroundTransform.push_back(transfo); } -} -template -void MultiDisparityMapTo3DFilter::ThreadedGenerateData(const RegionType& outputRegionForThread, - itk::ThreadIdType itkNotUsed(threadId)) -{ + TOutputImage* outputPtr = this->GetOutput(); TResidueImage* residuePtr = this->GetResidueOutput(); @@ -308,7 +310,7 @@ void MultiDisparityMapTo3DFilterm_MovingKeywordLists.size(); ++k) + for (unsigned int k = 0; k < this->m_MovingImageMetadatas.size(); ++k) { // Iterators over horizontal disparity maps hDispIts[k] = itk::ImageRegionConstIterator(this->GetHorizontalDisparityMapInput(k), outputRegionForThread); @@ -355,10 +357,11 @@ void MultiDisparityMapTo3DFilterm_ReferenceToGroundTransform->TransformPoint(currentPoint); + + pointA = referenceToGroundTransform->TransformPoint(currentPoint); currentPoint[2] = altiMin; - pointB = this->m_ReferenceToGroundTransform->TransformPoint(currentPoint); + pointB = referenceToGroundTransform->TransformPoint(currentPoint); pointSetA->SetPoint(0, pointA); pointSetB->SetPoint(0, pointB); @@ -367,7 +370,7 @@ void MultiDisparityMapTo3DFilterm_MovingKeywordLists.size(); ++k) + for (unsigned int k = 0; k < this->m_MovingImageMetadatas.size(); ++k) { // Compute the N moving lines of sight TDPointType pointAi, pointBi; @@ -385,11 +388,9 @@ void MultiDisparityMapTo3DFilterm_MovingToGroundTransform[k]->TransformPoint(currentPoint); - + pointAi = movingToGroundTransform[k]->TransformPoint(currentPoint); currentPoint[2] = altiMin; - pointBi = this->m_MovingToGroundTransform[k]->TransformPoint(currentPoint); - + pointBi = movingToGroundTransform[k]->TransformPoint(currentPoint); pointSetA->SetPoint(nbPoints, pointAi); pointSetB->SetPoint(nbPoints, pointBi); pointSetA->SetPointData(nbPoints, k + 1); diff --git a/Modules/Registration/DisparityMap/test/otbDisparityMapToDEMFilter.cxx b/Modules/Registration/DisparityMap/test/otbDisparityMapToDEMFilter.cxx index 31cea8f936eb4198f89ffce5a223febc650beff3..4501a5bdb4491b3fdf6721fc2886b9ec339dbe47 100644 --- a/Modules/Registration/DisparityMap/test/otbDisparityMapToDEMFilter.cxx +++ b/Modules/Registration/DisparityMap/test/otbDisparityMapToDEMFilter.cxx @@ -25,6 +25,7 @@ #include "otbImageList.h" #include "otbVectorImageToImageListFilter.h" +#include "otbDEMHandler.h" #include "otbDEMHandler.h" diff --git a/Modules/Registration/DisparityMap/test/otbMultiDisparityMapTo3DFilter.cxx b/Modules/Registration/DisparityMap/test/otbMultiDisparityMapTo3DFilter.cxx index 7524bc4387d5bdb79719fb722bc85549c65b35c9..7b3b62a24fe7fb7eba051b8627351ae2c0e63494 100644 --- a/Modules/Registration/DisparityMap/test/otbMultiDisparityMapTo3DFilter.cxx +++ b/Modules/Registration/DisparityMap/test/otbMultiDisparityMapTo3DFilter.cxx @@ -84,19 +84,19 @@ int otbMultiDisparityMapTo3DFilter(int argc, char* argv[]) vectorToListFilter2->UpdateOutputInformation(); Multi3DFilterType::Pointer multiFilter = Multi3DFilterType::New(); - multiFilter->SetReferenceKeywordList(masterReader->GetOutput()->GetImageKeywordlist()); + multiFilter->SetReferenceImageMetadata(&(masterReader->GetOutput()->GetImageMetadata())); multiFilter->SetNumberOfMovingImages(2); multiFilter->SetHorizontalDisparityMapInput(0, vectorToListFilter1->GetOutput()->GetNthElement(0)); multiFilter->SetVerticalDisparityMapInput(0, vectorToListFilter1->GetOutput()->GetNthElement(1)); multiFilter->SetDisparityMaskInput(0, mask1Reader->GetOutput()); - multiFilter->SetMovingKeywordList(0, slave1Reader->GetOutput()->GetImageKeywordlist()); + multiFilter->SetMovingImageMetadata(0, &(slave1Reader->GetOutput()->GetImageMetadata())); multiFilter->SetHorizontalDisparityMapInput(1, vectorToListFilter2->GetOutput()->GetNthElement(0)); multiFilter->SetVerticalDisparityMapInput(1, vectorToListFilter2->GetOutput()->GetNthElement(1)); multiFilter->SetDisparityMaskInput(1, mask2Reader->GetOutput()); - multiFilter->SetMovingKeywordList(1, slave2Reader->GetOutput()->GetImageKeywordlist()); + multiFilter->SetMovingImageMetadata(1, &(slave2Reader->GetOutput()->GetImageMetadata())); WriterType::Pointer writer = WriterType::New(); writer->SetInput(multiFilter->GetOutput()); diff --git a/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.hxx b/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.hxx index 74db81b6567c140ffa479ff359bb0f86f64ae918..8826e2faa9a2daf56259f46ea0d9524fcf1fa572 100644 --- a/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.hxx +++ b/Modules/Registration/Stereo/include/otbMulti3DMapToDEMFilter.hxx @@ -25,7 +25,6 @@ #include "itkImageRegionConstIteratorWithIndex.h" #include "itkImageRegionIterator.h" #include "otbStreamingStatisticsVectorImageFilter.h" -#include "otbInverseSensorModel.h" namespace otb { @@ -176,8 +175,7 @@ void Multi3DMapToDEMFilter::SetOutputPara T3DImage* imgPtr = const_cast(this->Get3DMapInput(k)); RSTransform2DType::Pointer mapToGroundTransform = RSTransform2DType::New(); - ImageKeywordListType imageKWL = imgPtr->GetImageKeywordlist(); - mapToGroundTransform->SetInputKeywordList(imageKWL); + mapToGroundTransform->SetInputImageMetadata(&(imgPtr->GetImageMetadata())); /*if(!m_ProjectionRef.empty()) { @@ -220,12 +218,6 @@ void Multi3DMapToDEMFilter::SetOutputPara box_xmax = std::max(box_xmax, xmax); box_ymin = std::min(box_ymin, ymin); box_ymax = std::max(box_ymax, ymax); - - /* if (imageKWL.GetSize() > 0) - { - itk::EncapsulateMetaData(outputPtr->GetMetaDataDictionary(), - MetaDataKey::OSSIMKeywordlistKey, imageKWL); - }*/ } // Compute step : @@ -397,7 +389,7 @@ void Multi3DMapToDEMFilter::GenerateInput // groundToSensorTransform->SetInputSpacing(outputDEM->GetSignedSpacing()); groundToSensorTransform->SetInputProjectionRef(m_ProjectionRef); - groundToSensorTransform->SetOutputKeywordList(imgPtr->GetImageKeywordlist()); + groundToSensorTransform->SetOutputImageMetadata(&(imgPtr->GetImageMetadata())); groundToSensorTransform->SetOutputOrigin(imgPtr->GetOrigin()); groundToSensorTransform->SetOutputSpacing(imgPtr->GetSignedSpacing()); groundToSensorTransform->InstantiateTransform(); diff --git a/Modules/Registration/Stereo/include/otbStereoSensorModelToElevationMapFilter.hxx b/Modules/Registration/Stereo/include/otbStereoSensorModelToElevationMapFilter.hxx index f60c12cfeebbf5d654aecbefe806e1cc5a587f1e..90327236d51a568b99b4db6cf2037932a7f457be 100644 --- a/Modules/Registration/Stereo/include/otbStereoSensorModelToElevationMapFilter.hxx +++ b/Modules/Registration/Stereo/include/otbStereoSensorModelToElevationMapFilter.hxx @@ -146,8 +146,8 @@ void StereoSensorModelToElevationFilter::GenerateInp // Build the transform to switch from the master to the slave image typename GenericRSTransformType::Pointer transform = GenericRSTransformType::New(); - transform->SetInputKeywordList(masterPtr->GetImageKeywordlist()); - transform->SetOutputKeywordList(slavePtr->GetImageKeywordlist()); + transform->SetInputImageMetadata(&(masterPtr->GetImageMetadata())); + transform->SetOutputImageMetadata(&(slavePtr->GetImageMetadata())); transform->InstantiateTransform(); @@ -266,7 +266,7 @@ void StereoSensorModelToElevationFilter::BeforeThrea OutputImageType* outputPtr = this->GetOutput(); typename GenericRSTransformType::Pointer rsTransform = GenericRSTransformType::New(); - rsTransform->SetInputKeywordList(outputPtr->GetImageKeywordlist()); + rsTransform->SetInputImageMetadata(&(outputPtr->GetImageMetadata())); rsTransform->InstantiateTransform(); // Fill output @@ -288,8 +288,8 @@ void StereoSensorModelToElevationFilter::BeforeThrea // Set-up the forward-inverse sensor model transform m_MasterToSlave = GenericRSTransform3DType::New(); - m_MasterToSlave->SetInputKeywordList(masterPtr->GetImageKeywordlist()); - m_MasterToSlave->SetOutputKeywordList(slavePtr->GetImageKeywordlist()); + m_MasterToSlave->SetInputImageMetadata(&(masterPtr->GetImageMetadata())); + m_MasterToSlave->SetOutputImageMetadata(&(slavePtr->GetImageMetadata())); m_MasterToSlave->InstantiateTransform(); } diff --git a/Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.hxx b/Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.hxx index b6f001219adc201df5c1f38a7e962a51355e5a8a..66105d6392124424313f54d8015520b70d672931 100644 --- a/Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.hxx +++ b/Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.hxx @@ -124,7 +124,7 @@ void StereorectificationDisplacementFieldSource::Gene // Set-up a transform to use the DEMHandler typedef otb::GenericRSTransform<> RSTransform2DType; RSTransform2DType::Pointer leftToGroundTransform = RSTransform2DType::New(); - leftToGroundTransform->SetInputKeywordList(m_LeftImage->GetImageKeywordlist()); + leftToGroundTransform->SetInputImageMetadata(&(m_LeftImage->GetImageMetadata())); leftToGroundTransform->InstantiateTransform(); @@ -132,13 +132,13 @@ void StereorectificationDisplacementFieldSource::Gene OutputImageType* leftDFPtr = this->GetLeftDisplacementFieldOutput(); OutputImageType* rightDFPtr = this->GetRightDisplacementFieldOutput(); - // Set up the RS transforms - m_LeftToRightTransform->SetInputKeywordList(m_LeftImage->GetImageKeywordlist()); - m_LeftToRightTransform->SetOutputKeywordList(m_RightImage->GetImageKeywordlist()); + // Set up the RS transforms + m_LeftToRightTransform->SetInputImageMetadata(&(m_LeftImage->GetImageMetadata())); + m_LeftToRightTransform->SetOutputImageMetadata(&(m_RightImage->GetImageMetadata())); m_LeftToRightTransform->InstantiateTransform(); - m_RightToLeftTransform->SetInputKeywordList(m_RightImage->GetImageKeywordlist()); - m_RightToLeftTransform->SetOutputKeywordList(m_LeftImage->GetImageKeywordlist()); + m_RightToLeftTransform->SetInputImageMetadata(&(m_RightImage->GetImageMetadata())); + m_RightToLeftTransform->SetOutputImageMetadata(&(m_LeftImage->GetImageMetadata())); m_RightToLeftTransform->InstantiateTransform(); // Now, we must determine the optimized size, spacing and origin of the @@ -301,7 +301,7 @@ void StereorectificationDisplacementFieldSource::Gene typedef otb::GenericRSTransform<> RSTransform2DType; RSTransform2DType::Pointer leftToGroundTransform = RSTransform2DType::New(); - leftToGroundTransform->SetInputKeywordList(m_LeftImage->GetImageKeywordlist()); + leftToGroundTransform->SetInputImageMetadata(&(m_LeftImage->GetImageMetadata())); leftToGroundTransform->InstantiateTransform(); diff --git a/Modules/Remote/diapotb.remote.cmake b/Modules/Remote/diapotb.remote.cmake index 4de2362eed02c7592e62acffc761ec1c8e299fd7..d9edc8c0c7bd11cfdd521d851f359878daa4dddb 100644 --- a/Modules/Remote/diapotb.remote.cmake +++ b/Modules/Remote/diapotb.remote.cmake @@ -22,5 +22,5 @@ otb_fetch_module(DiapOTBModule "OTB module for SAR processing in Diapason." GIT_REPOSITORY https://gitlab.orfeo-toolbox.org/remote_modules/diapotb.git - GIT_TAG 130f9286533414faf4b1a2bae3ff2496d2541d0f + GIT_TAG 69bc3588a51b9a52291e415f0822dadd8a8951fc ) diff --git a/Modules/Visualization/Ice/src/otbGlImageActor.cxx b/Modules/Visualization/Ice/src/otbGlImageActor.cxx index 9ebcb2a5fd321dc66dbfe4ad571f102942bad59e..2df1a4d5d0320d58aa599cc1748b0f29b2710ec9 100644 --- a/Modules/Visualization/Ice/src/otbGlImageActor.cxx +++ b/Modules/Visualization/Ice/src/otbGlImageActor.cxx @@ -1114,11 +1114,12 @@ void GlImageActor::UpdateTransforms() // << std::hex << this << std::dec // << " WKT-changed: " << isEqualOrNot << std::endl; + //TODO OSSIM: Replace KeywordList by ImageMetadata in the settings object geometryChanged = geometryChanged || (m_ViewportToImageTransform.IsNotNull() && m_ViewportToImageTransform->GetInputProjectionRef() != settings->GetWkt()) || (m_ImageToViewportTransform.IsNotNull() && m_ImageToViewportTransform->GetOutputProjectionRef() != settings->GetWkt()) - || (m_ViewportToImageTransform.IsNotNull() && !(m_ViewportToImageTransform->GetInputKeywordList() == settings->GetKeywordList())) - || (m_ImageToViewportTransform.IsNotNull() && !(m_ImageToViewportTransform->GetOutputKeywordList() == settings->GetKeywordList())); + || (m_ViewportToImageTransform.IsNotNull() /*&& !(m_ViewportToImageTransform->GetInputKeywordList() == settings->GetKeywordList())*/) + || (m_ImageToViewportTransform.IsNotNull() /*&& !(m_ImageToViewportTransform->GetOutputKeywordList() == settings->GetKeywordList())*/); if(settings->GetUseProjection() && geometryChanged) { @@ -1130,14 +1131,16 @@ void GlImageActor::UpdateTransforms() m_ImageToViewportTransform = RSTransformType::New(); m_ViewportToImageTransform->SetInputProjectionRef(settings->GetWkt()); - m_ViewportToImageTransform->SetInputKeywordList(settings->GetKeywordList()); + //TODO OSSIM: Replace KeywordList by ImageMetadata in the settings object + //m_ViewportToImageTransform->SetInputKeywordList(settings->GetKeywordList()); m_ViewportToImageTransform->SetOutputProjectionRef(m_FileReader->GetOutput()->GetProjectionRef()); - m_ViewportToImageTransform->SetOutputKeywordList(m_FileReader->GetOutput()->GetImageKeywordlist()); + m_ViewportToImageTransform->SetOutputImageMetadata(&(m_FileReader->GetOutput()->GetImageMetadata())); m_ImageToViewportTransform->SetOutputProjectionRef(settings->GetWkt()); - m_ImageToViewportTransform->SetOutputKeywordList(settings->GetKeywordList()); + //TODO OSSIM: Replace KeywordList by ImageMetadata in the settings object + //m_ImageToViewportTransform->SetOutputKeywordList(settings->GetKeywordList()); m_ImageToViewportTransform->SetInputProjectionRef(m_FileReader->GetOutput()->GetProjectionRef()); - m_ImageToViewportTransform->SetInputKeywordList(m_FileReader->GetOutput()->GetImageKeywordlist()); + m_ImageToViewportTransform->SetInputImageMetadata(&(m_FileReader->GetOutput()->GetImageMetadata())); hasChanged = true; } diff --git a/Modules/Visualization/Ice/src/otbGlROIActor.cxx b/Modules/Visualization/Ice/src/otbGlROIActor.cxx index 182af261eb680c6f269b74725cdea18b68cfdea7..75fdf9142073b0c36c9e6ec04969c5cdff60ab94 100644 --- a/Modules/Visualization/Ice/src/otbGlROIActor.cxx +++ b/Modules/Visualization/Ice/src/otbGlROIActor.cxx @@ -251,14 +251,15 @@ void GlROIActor::UpdateTransforms() m_ViewportToImageTransform = RSTransformType::New(); m_ViewportToImageTransform->SetInputProjectionRef( settings->GetWkt() ); - m_ViewportToImageTransform->SetInputKeywordList( settings->GetKeywordList() ); + //TODO: Replace KeywordList by ImageMetadata in the settings object + //m_ViewportToImageTransform->SetInputKeywordList( settings->GetKeywordList() ); m_ViewportToImageTransform->SetOutputProjectionRef( m_Wkt ); - m_ViewportToImageTransform->SetOutputKeywordList( m_Kwl ); + //TODO: m_ViewportToImageTransform->SetOutputKeywordList( m_Kwl ); m_ImageToViewportTransform->SetInputProjectionRef( m_Wkt ); - m_ImageToViewportTransform->SetInputKeywordList( m_Kwl ); + //TODO: m_ImageToViewportTransform->SetInputKeywordList( m_Kwl ); m_ImageToViewportTransform->SetOutputProjectionRef( settings->GetWkt() ); - m_ImageToViewportTransform->SetOutputKeywordList( settings->GetKeywordList() ); + //TODO: m_ImageToViewportTransform->SetOutputKeywordList( settings->GetKeywordList() ); m_ViewportToImageTransform->InstantiateTransform(); m_ImageToViewportTransform->InstantiateTransform(); diff --git a/Modules/Visualization/Ice/src/otbGlVectorActor.cxx b/Modules/Visualization/Ice/src/otbGlVectorActor.cxx index f13f93cbccf2c4c795df35a1a9c3ab9d69a35457..9f236dd74e1146cd3f0f32070d033358307107d0 100644 --- a/Modules/Visualization/Ice/src/otbGlVectorActor.cxx +++ b/Modules/Visualization/Ice/src/otbGlVectorActor.cxx @@ -663,11 +663,12 @@ void GlVectorActor::UpdateTransforms() if(settings->GetUseProjection()) { m_ViewportToVectorTransform->SetInputProjectionRef(settings->GetWkt()); - m_ViewportToVectorTransform->SetInputKeywordList(settings->GetKeywordList()); + //TODO OSSIM: Replace KeywordList by ImageMetadata in the settings object + //m_ViewportToVectorTransform->SetInputKeywordList(settings->GetKeywordList()); m_ViewportToVectorTransform->SetOutputProjectionRef((m_OGRDataSource->GetLayerChecked(m_CurrentLayer).GetProjectionRef())); m_VectorToViewportTransform->SetOutputProjectionRef(settings->GetWkt()); - m_VectorToViewportTransform->SetOutputKeywordList(settings->GetKeywordList()); + //TODO OSSIM: m_VectorToViewportTransform->SetOutputKeywordList(settings->GetKeywordList()); m_VectorToViewportTransform->SetInputProjectionRef((m_OGRDataSource->GetLayerChecked(m_CurrentLayer).GetProjectionRef())); } m_ViewportToVectorTransform->InstantiateTransform(); diff --git a/Modules/Visualization/Ice/src/otbViewSettings.cxx b/Modules/Visualization/Ice/src/otbViewSettings.cxx index 520ef1eeb137dcedbfc9cea2bf2003416b0b0ffd..49df9e7dbda2c9e171568f1b59e03f15e5e2159b 100644 --- a/Modules/Visualization/Ice/src/otbViewSettings.cxx +++ b/Modules/Visualization/Ice/src/otbViewSettings.cxx @@ -129,13 +129,13 @@ void ViewSettings::SetPersepectiveAngle() typedef otb::GenericRSTransform RSTransformType; // Build the RS transform RSTransformType::Pointer forwardTransform = RSTransformType::New(); - forwardTransform->SetInputKeywordList(m_KeywordList); + //TODO OSSIM: forwardTransform->SetInputKeywordList(m_KeywordList); forwardTransform->SetInputProjectionRef(m_Wkt); forwardTransform->InstantiateTransform(); RSTransformType::Pointer inverseTransform = RSTransformType::New(); inverseTransform->SetOutputProjectionRef(m_Wkt); - inverseTransform->SetOutputKeywordList(m_KeywordList); + //TODO OSSIM: inverseTransform->SetOutputKeywordList(m_KeywordList); inverseTransform->InstantiateTransform(); PointType centerPoint = GetViewportCenter(); @@ -163,13 +163,13 @@ void ViewSettings::SetNorthUpAngle() typedef otb::GenericRSTransform RSTransformType; // Build the RS transform RSTransformType::Pointer forwardTransform = RSTransformType::New(); - forwardTransform->SetInputKeywordList(m_KeywordList); + //TODO OSSIM: forwardTransform->SetInputKeywordList(m_KeywordList); forwardTransform->SetInputProjectionRef(m_Wkt); forwardTransform->InstantiateTransform(); RSTransformType::Pointer inverseTransform = RSTransformType::New(); inverseTransform->SetOutputProjectionRef(m_Wkt); - inverseTransform->SetOutputKeywordList(m_KeywordList); + //TODO OSSIM: inverseTransform->SetOutputKeywordList(m_KeywordList); inverseTransform->InstantiateTransform(); PointType centerPoint = GetViewportCenter(); diff --git a/Modules/Visualization/MonteverdiCore/src/mvdVectorImageModel.cxx b/Modules/Visualization/MonteverdiCore/src/mvdVectorImageModel.cxx index cb4d35168cfc425b84472d702008b46459b302a6..ab2a67e58c6f508fb04b0704dc820abc560d3454 100644 --- a/Modules/Visualization/MonteverdiCore/src/mvdVectorImageModel.cxx +++ b/Modules/Visualization/MonteverdiCore/src/mvdVectorImageModel.cxx @@ -121,7 +121,7 @@ void VectorImageModel::SetFilename(const QString& filename, int w, int h) // Setup GenericRSTransform m_ToWgs84 = otb::GenericRSTransform<>::New(); - m_ToWgs84->SetInputDictionary(m_ImageFileReader->GetOutput()->GetMetaDataDictionary()); + m_ToWgs84->SetInputImageMetadata(&(m_ImageFileReader->GetOutput()->GetImageMetadata())); m_ToWgs84->SetOutputProjectionRef(otb::SpatialReference::FromWGS84().ToWkt()); m_ToWgs84->InstantiateTransform();