Project

General

Profile

Download (9.56 KB) Statistics
| Branch: | Revision:

git_sitools_idoc / sitools-idoc / hesiod / javaExt / src / fr / ias / sitools / vo / ssa / OverlapsModeIntersection.java @ 779bac69

1
 /*******************************************************************************
2
 * Copyright 2010-2013 CNES - CENTRE NATIONAL d'ETUDES SPATIALES
3
 *
4
 * This file is part of SITools2.
5
 *
6
 * SITools2 is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * SITools2 is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with SITools2.  If not, see <http://www.gnu.org/licenses/>.
18
 ******************************************************************************/
19
package fr.ias.sitools.vo.ssa;
20

    
21
import fr.cnes.sitools.searchgeometryengine.Resampling;
22
import java.util.List;
23
import java.util.logging.Level;
24
import java.util.logging.Logger;
25

    
26
/**
27
 * Constructs SQL predicat for Overlaps mode intersection.
28
 * @author Jean-Christophe Malapert <jean-christophe.malapert@cnes.fr>
29
 */
30
public class OverlapsModeIntersection extends AbstractSqlGeometryConstraint {
31
  /**
32
   * Logger.
33
   */
34
  private static final Logger LOG = Logger.getLogger(OverlapsModeIntersection.class.getName());
35
  /**
36
   * Default value for resampling along right ascension axis.
37
   */
38
  private static final double DEFAULT_SAMPLING_VALUE_RA = 20;
39
  /**
40
   * Default value for resampling along declination axis.
41
   */
42
  private static final double DEFAULT_SAMPLING_VALUE_DEC = 20;
43
  /**
44
   * geometry attribut.
45
   */
46
  private transient String geomCol;
47

    
48
  @Override
49
  public final void setGeometry(final Object geometry) {
50
    if (geometry instanceof String) {
51
      this.geomCol = String.valueOf(geometry);
52
    }else if(geometry instanceof List) {
53
      
54
    } else {
55
      throw new IllegalArgumentException("geometry must be a String");
56
    }
57
    /* } else {
58
      throw new IllegalArgumentException("geometry must be a String");
59
    }*/
60
  }
61

    
62
  @Override
63
  public final String getSqlPredicat() {
64
    if (this.isPolesCollision()) {
65
      return null;
66
    }
67

    
68
    final List ranges = (List) computeRange();
69
    final List<Double[]> raRanges = (List<Double[]>) ranges.get(0);
70
    final double[] decRange = (double[]) ranges.get(1);
71

    
72
    String predicatDefinition;
73
    if (isNorthPoleCollision()) {
74
      LOG.log(Level.FINEST, "North collision case");
75
      predicatDefinition = String.format(" AND (spoly_overlap_polygon(%s,'{(%sd,%sd),(%sd,%sd),(%sd,%sd)}')", geomCol, 0.0, decRange[0], 45.0, 90.0, 90.0, decRange[0]);
76
      predicatDefinition = predicatDefinition.concat(String.format(" OR spoly_overlap_polygon(%s,'{(%sd,%sd),(%sd,%sd),(%sd,%sd)}')", geomCol, 90.0, decRange[MIN], 135.0, 90.0, 180.0, decRange[MIN]));
77
      predicatDefinition = predicatDefinition.concat(String.format(" OR spoly_overlap_polygon(%s,'{(%sd,%sd),(%sd,%sd),(%sd,%sd)}')", geomCol, 180.0, decRange[MIN], 225.0, 90.0, 270.0, decRange[MIN]));
78
      predicatDefinition = predicatDefinition.concat(String.format(" OR spoly_overlap_polygon(%s,'{(%sd,%sd),(%sd,%sd),(%sd,%sd)}'))", geomCol, 270.0, decRange[MIN], 325.0, 90.0, 360.0, decRange[MIN]));
79
      LOG.log(Level.FINEST, predicatDefinition);
80

    
81
    } else if (isSouthPoleCollision()) {
82
      LOG.log(Level.FINEST, "South collision case");
83
      predicatDefinition = String.format(" AND (spoly_overlap_polygon(%s,'{(%sd,%sd),(%sd,%sd),(%sd,%sd)}')", geomCol, 0.0, decRange[MAX], 45.0, -90.0, 90.0, decRange[MAX]);
84
      predicatDefinition = predicatDefinition.concat(String.format(" OR spoly_overlap_polygon(%s,'{(%sd,%sd),(%sd,%sd),(%sd,%sd)}')", geomCol, 90.0, decRange[MAX], 135.0, -90.0, 180.0, decRange[MAX]));
85
      predicatDefinition = predicatDefinition.concat(String.format(" OR spoly_overlap_polygon(%s,'{(%sd,%sd),(%sd,%sd),(%sd,%sd)}')", geomCol, 180.0, decRange[MAX], 225.0, -90.0, 270.0, decRange[MAX]));
86
      predicatDefinition = predicatDefinition.concat(String.format(" OR spoly_overlap_polygon(%s,'{(%sd,%sd),(%sd,%sd),(%sd,%sd)}'))", geomCol, 270.0, decRange[MAX], 325.0, -90.0, 360.0, decRange[MAX]));
87
      LOG.log(Level.FINEST, predicatDefinition);
88

    
89
    } else if (isRing()) {
90
      LOG.log(Level.FINEST, "Ring case");
91
      predicatDefinition = String.format(" AND (spoly_overlap_polygon(%s,'{(%sd,%sd),(%sd,%sd),(%sd,%sd), (%sd,%sd)}')", geomCol, 0.0, decRange[MIN], 90.0, decRange[MIN], 90.0, decRange[MAX], 0.0, decRange[MAX]);
92
      predicatDefinition = predicatDefinition.concat(String.format(" OR spoly_overlap_polygon(%s,'{(%sd,%sd),(%sd,%sd),(%sd,%sd), (%sd,%sd)}')", geomCol, 90.0, decRange[MIN], 180.0, decRange[MIN], 180.0, decRange[MAX], 90.0, decRange[MAX]));
93
      predicatDefinition = predicatDefinition.concat(String.format(" OR spoly_overlap_polygon(%s,'{(%sd,%sd),(%sd,%sd),(%sd,%sd), (%sd,%sd)}')", geomCol, 180.0, decRange[MIN], 270.0, decRange[MIN], 270.0, decRange[MAX], 180.0, decRange[MAX]));
94
      predicatDefinition = predicatDefinition.concat(String.format(" OR spoly_overlap_polygon(%s,'{(%sd,%sd),(%sd,%sd),(%sd,%sd), (%sd,%sd)}'))", geomCol, 270.0, decRange[MIN], 0.0, decRange[MIN], 0.0, decRange[MAX], 270.0, decRange[MAX]));
95
      LOG.log(Level.FINEST, predicatDefinition);
96

    
97
    } else if (raRanges.size() == 1 && isLargePolygon()) {
98
      LOG.log(Level.FINEST, "Large polygon case");
99
      final Double[] raRange1 = raRanges.get(0);
100
      final double mean = (raRange1[MIN] + raRange1[MAX]) / 2.0;
101
      raRanges.add(new Double[]{mean, raRange1[MAX]});
102
      raRanges.set(0, new Double[]{raRange1[MIN], mean});
103
      predicatDefinition = buildMultiPolygon(raRanges, decRange);
104
      LOG.log(Level.FINEST, predicatDefinition);
105
    } else {
106
      LOG.log(Level.FINEST, "other case");
107
      predicatDefinition = buildMultiPolygon(raRanges, decRange);
108
      LOG.log(Level.FINEST, predicatDefinition);
109
    }
110
    return predicatDefinition;
111
  }
112

    
113
  /**
114
   * Builds a multi-polygon syntax for PgSphere based on a set right ascension ranges and a declination range.
115
   *
116
   * <p>
117
   * A range is an array that is composed of two values : min and max value.
118
   * </p>
119
   *
120
   * @param raRanges set of right ascension ranges
121
   * @param decRange declination range
122
   * @return the SQL predicat
123
   */
124
  private String buildMultiPolygon(final List<Double[]> raRanges, final double[] decRange) {
125
    final StringBuilder stringBuilder = new StringBuilder(" AND (");
126
    buildPolygon(stringBuilder, raRanges.get(0), decRange);
127
    if (raRanges.size() == 2) {
128
      stringBuilder.append(" OR ");
129
      buildPolygon(stringBuilder, raRanges.get(1), decRange);
130
    }
131
    stringBuilder.append(")");
132
    return stringBuilder.toString();
133
  }
134

    
135
  /**
136
   * Build a polygon syntax for PgSphere based on the SQL predicat to complete, the right ascension and declination range.
137
   * <p>
138
   * A range is an array that is composed of two values : min and max value.
139
   * </p>
140
   * @param stringBuilder SQL predicat to complete
141
   * @param raRange right ascension range [min,max]
142
   * @param decRange declination range [min,max]
143
   */
144
  private void buildPolygon(final StringBuilder stringBuilder, final Double[] raRange, final double[] decRange) {
145
    stringBuilder.append(String.format("spoly_overlap_polygon(%s,'{", geomCol));
146
    final double[] pointsRa = Resampling.hourCircle(raRange[MIN], raRange[MAX], DEFAULT_SAMPLING_VALUE_RA);
147
    final double[] pointsDec = Resampling.decCircle(decRange[MIN], decRange[MAX], DEFAULT_SAMPLING_VALUE_DEC);
148
    buildRaLine(stringBuilder, pointsRa, decRange[MIN], false);
149
    buildDecLine(stringBuilder, pointsDec, raRange[MAX], false);
150
    buildRaLine(stringBuilder, pointsRa, decRange[MAX], true);
151
    buildDecLine(stringBuilder, pointsDec, raRange[MIN], true);
152
    stringBuilder.deleteCharAt(stringBuilder.length() - 1);
153
    stringBuilder.append("}')");
154
  }
155

    
156
  /**
157
   * Builds a line of the polygon for the SIAP request along the right ascension axis.
158
   * @param stringBuilder polygon to complete
159
   * @param raCoordinates values in the line along right ascension axis
160
   * @param staticDecCoordinate constant declination.
161
   * @param isReverseOrder indicates if the order where <code>raCoordinates</code> array must be read
162
   */
163
  private void buildRaLine(final StringBuilder stringBuilder, final double[] raCoordinates, final double staticDecCoordinate, final boolean isReverseOrder) {
164
    if (isReverseOrder) {
165
      for (int i = raCoordinates.length - 1; i > 0; i--) {
166
        stringBuilder.append(String.format("(%sd,%sd),", raCoordinates[i], staticDecCoordinate));
167
      }
168
    } else {
169
      for (int i = 0; i < raCoordinates.length - 1; i++) {
170
        stringBuilder.append(String.format("(%sd,%sd),", raCoordinates[i], staticDecCoordinate));
171
      }
172
    }
173
  }
174

    
175
    /**
176
   * Builds a line of the polygon for the SIAP request along the declination axis.
177
   * @param stringBuilder polygon to complete
178
   * @param decCoordinates values in the line along declination axis
179
   * @param staticRaCoordinate constant right ascension.
180
   * @param isReverseOrder indicates if the order where <code>raCoordinates</code> array must be read
181
   */
182
  private void buildDecLine(final StringBuilder stringBuilder, final double[] decCoordinates, final double staticRaCoordinate, final boolean isReverseOrder) {
183
    if (isReverseOrder) {
184
      for (int i = decCoordinates.length - 1; i > 0; i--) {
185
        stringBuilder.append(String.format("(%sd,%sd),", staticRaCoordinate, decCoordinates[i]));
186
      }
187
    } else {
188
      for (int i = 0; i < decCoordinates.length - 1; i++) {
189
        stringBuilder.append(String.format("(%sd,%sd),", staticRaCoordinate, decCoordinates[i]));
190
      }
191
    }
192
  }
193
}