ajantha-bhat commented on a change in pull request #3481: 
[CARBONDATA-3548]Geospatial Support: add hash id create,query condition analyze 
and generate hash id list
URL: https://github.com/apache/carbondata/pull/3481#discussion_r356547637
 
 

 ##########
 File path: geo/src/main/java/org/apache/carbondata/geo/GeoHashImpl.java
 ##########
 @@ -168,20 +238,151 @@ public String generate(List<?> sources) throws 
Exception {
     if (!(sources.get(0) instanceof Long) || !(sources.get(1) instanceof 
Long)) {
       throw new RuntimeException("Source columns must be of Long type.");
     }
-    //TODO: generate geohashId
-    return String.valueOf(0);
+    Long longitude = (Long) sources.get(0);
+    Long latitude  = (Long) sources.get(1);
+    // generate the hash code
+    int[] gridPoint = calculateID(longitude, latitude);
+    Long hashId = createHashID(gridPoint[0], gridPoint[1]);
+    return String.valueOf(hashId);
   }
 
   /**
    * Query processor for GeoHash.
-   * @param polygon
+   * example: (`LONGITUDE`, `LATITUDE`, '116270714,40112476;116217155,40028403;
+   * 
116337318,39927378;116459541,39966859;116447868,40076233;116385384,40129279;')
+   * @param polygon a group of pints, close out to form an area
    * @return Returns list of ranges of GeoHash IDs
    * @throws Exception
    */
   @Override
   public List<Long[]> query(String polygon) throws Exception {
-    List<Long[]> rangeList = new ArrayList<Long[]>();
-    // TODO: process the polygon coordinates and generate the list of ranges 
of GeoHash IDs
-    return rangeList;
+    String[] pointList = polygon.split(";");
+    if (3  > pointList.length) {
+      throw new RuntimeException("polygon need at least 3 points, really has " 
+ pointList.length);
+    } else {
+      List<double[]> queryList = new ArrayList<>();
+      for (String str: pointList) {
+        String[] points = str.split(",");
+        if (2 != points.length) {
+          throw new RuntimeException("longitude and latitude is a pair need 2 
data");
+        } else {
+          try {
+            queryList.add(new double[] {Double.valueOf(points[0]), 
Double.valueOf(points[1])});
+          } catch (NumberFormatException e) {
+            throw new RuntimeException("can not covert the string data to 
double", e);
+          }
+        }
+      }
+      if (3 > queryList.size()) {
+        throw new RuntimeException("polygon list size" + queryList.size() + " 
less than three");
+      } else {
+        List<Long[]> rangeList = getPolygonRangeList(queryList);
+        return rangeList;
+      }
+    }
+  }
+
+  /**
+   * use query polygon condition to get the hash id list, the list is merged 
and sorted.
+   * @param queryList polygon points close out to form an area
+   * @return hash id list
+   * @throws Exception
+   */
+  private  List<Long[]> getPolygonRangeList(List<double[]> queryList) throws 
Exception {
+    QuadTreeCls qTreee = new QuadTreeCls(userDefineMinLongitude, 
userDefineMinLatitude,
+        CalculateMaxLongitude, CalculateMaxLatitude, cutLevel);
+    qTreee.insert(queryList);
+    return qTreee.getNodesData();
+  }
+
+  /**
+   *  After necessary attributes, perform necessary calculation
+   * @throws Exception
+   */
+  private void calculateData() throws Exception {
+    // Angular to radian, radians = (Math.PI / 180) * degrees
+    // Cosine value of latitude angle of origin
+    this.mCos = Math.cos(this.oriLatitude / this.conversionRatio * Math.PI / 
CONVERT_FACTOR);
+    // get δx=L∗360/(2πR∗cos(lat))
+    this.deltaX = (this.gridSize * 360) / (2 * Math.PI * EARTH_RADIUS * 
this.mCos);
+    this.deltaXByRatio = this.deltaX * this.conversionRatio;
+    // get δy=L∗360/2πR
+    this.deltaY = (this.gridSize * 360) / (2 * Math.PI * EARTH_RADIUS);
+    this.deltaYByRatio = this.deltaY * this.conversionRatio;
+    LOGGER.info("after spatial calculate delta X is: " + String.format("%f", 
this.deltaX)
+                    + "the delta Y is: " + String.format("%f", this.deltaY));
+    LOGGER.info("after spatial calculate X ByRatio is: " + String.format("%f", 
this.deltaXByRatio)
+                    + "the Y ByRatio is: " + String.format("%f", 
this.deltaYByRatio));
+    // Calculate the complement area and grid i,j for grid number
+    // Xmax = x0+(2^n∗δx) Ymax = y0+(2^n∗δx) Where n is the number of cut
+    // Where x0, Y0 are the minimum x, y coordinates of a given region,
+    // Xmax >= maxLongitude Ymax >= maxLatitude
+    // In the calculation process, first substitute maxlongitude and 
maxlatitude to calculate n.
+    // if n is not an integer, then take the next integer of N, and then 
substitute to find
+    // xmax and ymax。
+    this.calculateArea();
+  }
+
+  /**
+   * Calculate the complement area, including the range of the complement 
area, t
+   * he number of knives cut and the depth of the quad tree
+   */
+  private void calculateArea() {
+    // step 1 calculate xn, yn by using maxLongitude, maxLatitude, 
minLongitude, minLatitude
+    // substitution formula
+    // Here, the user's given area is mostly rectangle, which needs to be 
extended to
+    // square processing to find the maximum value of XN and yn
+    // n=log_2 (Xmax−X0)/δx, log_2 (Ymax−Y0)/δy
+    double Xn = Math.log((userDefineMaxLongitude - userDefineMinLongitude) / 
deltaX)
+                    / Math.log(2);
+    double Yn = Math.log((userDefineMaxLatitude - userDefineMinLatitude) / 
deltaY)
+                    / Math.log(2);
+    double doubleMax = Math.max(Xn, Yn);
+    this.cutLevel = doubleMax % 1 == 0 ? (int) doubleMax : (int) (doubleMax + 
1);
+    // setep 2 recalculate the region according to the number of segmentation
 
 Review comment:
   *step

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to