1 /* Copyright 2002-2024 Thales Alenia Space 2 * Licensed to CS Communication & Systèmes (CS) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * CS licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.orekit.models.earth.troposphere.iturp834; 18 19 /** Holder for one cell of grid data surrounding one point. 20 * @author Luc Maisonobe 21 * @since 13.0 22 */ 23 class GridCell { 24 25 /** Latitude difference with respect to South cell edge. */ 26 private final double deltaSouth; 27 28 /** Longitude difference with respect to West cell edge. */ 29 private final double deltaWest; 30 31 /** Cell size in latitude. */ 32 private final double sizeLat; 33 34 /** Cell size in longitude. */ 35 private final double sizeLon; 36 37 /** North-West value. */ 38 private final double nw; 39 40 /** South-West value. */ 41 private final double sw; 42 43 /** South-East value. */ 44 private final double se; 45 46 /** North-East value. */ 47 private final double ne; 48 49 /** 50 * Build a grid cell from corner data. 51 * 52 * @param deltaSouth point latitude minus South cell edge latitude 53 * @param deltaWest point longitude minus West cell edge longitude 54 * @param sizeLat cell size in latitude 55 * @param sizeLon cell size in longitude 56 * @param nw North-West value 57 * @param sw South-West value 58 * @param se South-East value 59 * @param ne North-East value 60 */ 61 GridCell(final double deltaSouth, final double deltaWest, final double sizeLat, final double sizeLon, 62 final double nw, final double sw, final double se, final double ne) { 63 this.deltaSouth = deltaSouth; 64 this.deltaWest = deltaWest; 65 this.sizeLat = sizeLat; 66 this.sizeLon = sizeLon; 67 this.nw = nw; 68 this.sw = sw; 69 this.se = se; 70 this.ne = ne; 71 } 72 73 /** Build a grid cell by applying a function to two existing cells. 74 * <p> 75 * The cells are expected to be consistent (i.e. same locations, 76 * same sizes), but no verification is done here. It works in 77 * the context of ITR-R P.834 because the grids have similar 78 * samplings, it would not work fro general and inconsistent grids. 79 * </p> 80 * @param function function to apply to all cells corners 81 * @param cell1 first cell 82 * @param cell2 second cell 83 */ 84 GridCell(final BiFunction function, 85 final GridCell cell1, final GridCell cell2) { 86 this.deltaSouth = cell1.deltaSouth; 87 this.deltaWest = cell1.deltaWest; 88 this.sizeLat = cell1.sizeLat; 89 this.sizeLon = cell1.sizeLon; 90 this.nw = function.apply(cell1.nw, cell2.nw); 91 this.sw = function.apply(cell1.sw, cell2.sw); 92 this.se = function.apply(cell1.se, cell2.se); 93 this.ne = function.apply(cell1.ne, cell2.ne); 94 } 95 96 /** Build a grid cell by applying a function to three existing cells. 97 * <p> 98 * The cells are expected to be consistent (i.e. same locations, 99 * same sizes), but no verification is done here. It works in 100 * the context of ITR-R P.834 because the grids have similar 101 * samplings, it would not work fro general and inconsistent grids. 102 * </p> 103 * @param function function to apply to all cells corners 104 * @param cell1 first cell 105 * @param cell2 second cell 106 * @param cell3 third cell 107 */ 108 GridCell(final TriFunction function, 109 final GridCell cell1, final GridCell cell2, final GridCell cell3) { 110 this.deltaSouth = cell1.deltaSouth; 111 this.deltaWest = cell1.deltaWest; 112 this.sizeLat = cell1.sizeLat; 113 this.sizeLon = cell1.sizeLon; 114 this.nw = function.apply(cell1.nw, cell2.nw, cell3.nw); 115 this.sw = function.apply(cell1.sw, cell2.sw, cell3.sw); 116 this.se = function.apply(cell1.se, cell2.se, cell3.se); 117 this.ne = function.apply(cell1.ne, cell2.ne, cell3.ne); 118 } 119 120 /** Build a grid cell by applying a function to four existing cells. 121 * <p> 122 * The cells are expected to be consistent (i.e. same locations, 123 * same sizes), but no verification is done here. It works in 124 * the context of ITR-R P.834 because the grids have similar 125 * samplings, it would not work fro general and inconsistent grids. 126 * </p> 127 * @param function function to apply to all cells corners 128 * @param cell1 first cell 129 * @param cell2 second cell 130 * @param cell3 third cell 131 * @param cell4 fourth cell 132 */ 133 GridCell(final QuarticFunction function, 134 final GridCell cell1, final GridCell cell2, 135 final GridCell cell3, final GridCell cell4) { 136 this.deltaSouth = cell1.deltaSouth; 137 this.deltaWest = cell1.deltaWest; 138 this.sizeLat = cell1.sizeLat; 139 this.sizeLon = cell1.sizeLon; 140 this.nw = function.apply(cell1.nw, cell2.nw, cell3.nw, cell4.nw); 141 this.sw = function.apply(cell1.sw, cell2.sw, cell3.sw, cell4.sw); 142 this.se = function.apply(cell1.se, cell2.se, cell3.se, cell4.se); 143 this.ne = function.apply(cell1.ne, cell2.ne, cell3.ne, cell4.ne); 144 } 145 146 /** Build a grid cell by applying a function to five existing cells. 147 * <p> 148 * The cells are expected to be consistent (i.e. same locations, 149 * same sizes), but no verification is done here. It works in 150 * the context of ITR-R P.834 because the grids have similar 151 * samplings, it would not work fro general and inconsistent grids. 152 * </p> 153 * @param function function to apply to all cells corners 154 * @param cell1 first cell 155 * @param cell2 second cell 156 * @param cell3 third cell 157 * @param cell4 fourth cell 158 * @param cell5 fifth cell 159 */ 160 GridCell(final QuinticFunction function, 161 final GridCell cell1, final GridCell cell2, final GridCell cell3, 162 final GridCell cell4, final GridCell cell5) { 163 this.deltaSouth = cell1.deltaSouth; 164 this.deltaWest = cell1.deltaWest; 165 this.sizeLat = cell1.sizeLat; 166 this.sizeLon = cell1.sizeLon; 167 this.nw = function.apply(cell1.nw, cell2.nw, cell3.nw, cell4.nw, cell5.nw); 168 this.sw = function.apply(cell1.sw, cell2.sw, cell3.sw, cell4.sw, cell5.sw); 169 this.se = function.apply(cell1.se, cell2.se, cell3.se, cell4.se, cell5.se); 170 this.ne = function.apply(cell1.ne, cell2.ne, cell3.ne, cell4.ne, cell5.ne); 171 } 172 173 /** Evaluate cell value at point location using bi-linear interpolation. 174 * @return cell value at point location 175 */ 176 public double evaluate() { 177 final double deltaNorth = sizeLat - deltaSouth; 178 final double deltaEast = sizeLon - deltaWest; 179 return (deltaSouth * (deltaWest * ne + deltaEast * nw) + 180 deltaNorth * (deltaWest * se + deltaEast * sw)) / 181 (sizeLat * sizeLon); 182 } 183 184 /** Interface for function that can be applied to the corners of two cells. */ 185 @FunctionalInterface 186 public interface BiFunction { 187 /** Apply function to similar corners coming from two cells. 188 * @param corner1 value at corner of first cell 189 * @param corner2 value at corner of second cell 190 * @return function evaluated at similar corners of two cells 191 */ 192 double apply(double corner1, double corner2); 193 } 194 195 /** Interface for function that can be applied to the corners of three cells. */ 196 @FunctionalInterface 197 public interface TriFunction { 198 /** Apply function to similar corners coming from three cells. 199 * @param corner1 value at corner of first cell 200 * @param corner2 value at corner of second cell 201 * @param corner3 value at corner of third cell 202 * @return function evaluated at similar corners of three cells 203 */ 204 double apply(double corner1, double corner2, double corner3); 205 } 206 207 /** Interface for function that can be applied to the corners of four cells. */ 208 @FunctionalInterface 209 public interface QuarticFunction { 210 /** Apply function to similar corners coming from four cells. 211 * @param corner1 value at corner of first cell 212 * @param corner2 value at corner of second cell 213 * @param corner3 value at corner of third cell 214 * @param corner4 value at corner of fourth cell 215 * @return function evaluated at similar corners of four cells 216 */ 217 double apply(double corner1, double corner2, double corner3, double corner4); 218 } 219 220 /** Interface for function that can be applied to the corners of five cells. */ 221 @FunctionalInterface 222 public interface QuinticFunction { 223 /** Apply function to similar corners coming from five cells. 224 * @param corner1 value at corner of first cell 225 * @param corner2 value at corner of second cell 226 * @param corner3 value at corner of third cell 227 * @param corner4 value at corner of fourth cell 228 * @param corner5 value at corner of fifth cell 229 * @return function evaluated at similar corners of five cells 230 */ 231 double apply(double corner1, double corner2, double corner3, double corner4, double corner5); 232 } 233 234 }