ravipesala commented on a change in pull request #3436: [WIP]Geospatial Support: Modified to create and load the table with a nonschema dimension sort column
URL: https://github.com/apache/carbondata/pull/3436#discussion_r347230147 ########## File path: core/src/main/java/org/apache/carbondata/core/util/GeoHashDefault.java ########## @@ -0,0 +1,336 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +package org.apache.carbondata.core.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.carbondata.common.exceptions.sql.MalformedCarbonCommandException; +import org.apache.carbondata.core.constants.CarbonCommonConstants; + + +public class GeoHashDefault implements CustomIndex<Long, String, List<Long[]>> { + // 角度转弧度的转换因子 + private static final double CONVERT_FACTOR = 180.0; + // 地球半径 + private static final double EARTH_RADIUS = 6371004.0; + + private static final String GEOHASH = "geohash"; + // 赤道经度1度或者纬度1度对应的地理空间距离 + private static double transValue = Math.PI / CONVERT_FACTOR * EARTH_RADIUS; + + // private double oriLongitude = 0; // 坐标原点的经度 + + private double oriLatitude = 0; // 坐标原点的纬度 + + private double userDefineMaxLongitude = 0; // 用户定义地图最大的经度 + + private double userDefineMaxLatitude = 0; // 用户定义地图最大的纬度 + + private double userDefineMinLongitude = 0; // 用户定义地图最小的经度 + + private double userDefineMinLatitude = 0; // 用户定义地图最小的纬度 + + private double CalculateMaxLongitude = 0; // 计算后得出的补齐地图最大的经度 + + private double CalculateMaxLatitude = 0; // 计算后得出的补齐地图最大的纬度 + + private int gridSize = 0; //栅格长度单位是米 + + private double mCos; // 坐标原点纬度的余玄数值 + + private double deltaY = 0; // 每一个gridSize长度对应Y轴的度数 + + private double deltaX = 0; // 每一个gridSize长度应X轴的度数 + + private double deltaYByRatio = 0; // 每一个gridSize长度对应Y轴的度数 * 系数 + + private double deltaXByRatio = 0; // 每一个gridSize长度应X轴的度数 * 系数 + + private int cutLevel = 0; // 对整个区域切的刀数(一横一竖为1刀),就是四叉树的深度 + + // private int totalRowNumber = 0; // 整个区域的行数,从左上开始到右下 + + // private int totalCloumnNumber = 0; // 整个区域的列数,从左上开始到右下 + + // private int udfRowStartNumber = 0; // 用户定义区域的开始行数 + + // private int udfRowEndNumber = 0; // 用户定义区域的结束的行数 + + // private int udfCloumnStartNumber = 0; // 用户定义区域的开始列数 + + // private int udfCloumnEndNumber = 0; // 用户定义区域的开始结束列数 + + // private double lon0 = 0; // 栅格最小数值的经度坐标,最小栅格坐标是扩展区域最左上角的经纬度坐标 + + // private double lat0 = 0; // 栅格最小数值的纬度坐标,最小栅格坐标是扩展区域最左上角的经纬度坐标 + + private double lon0ByRation = 0; // *系数的常量 + private double lat0ByRation = 0; // *系数的常量 + + private int conversionRatio = 1; // 系数,用于将double类型的经纬度,转换成int类型后计算 + + /** + * Initialize the geohash index handler instance. + * @param handlerName + * @param properties + * @throws Exception + */ + @Override + public void init(String handlerName, Map<String, String> properties) throws Exception { + String options = properties.get(CarbonCommonConstants.INDEX_HANDLER); + if (options == null || options.isEmpty()) { + throw new MalformedCarbonCommandException( + String.format("%s property is invalid.", CarbonCommonConstants.INDEX_HANDLER)); + } + options = options.toLowerCase(); + if (!options.contains(handlerName.toLowerCase())) { + throw new MalformedCarbonCommandException( + String.format("%s property is invalid. %s is not present.", + CarbonCommonConstants.INDEX_HANDLER, handlerName)); + } + + String commonKey = CarbonCommonConstants.INDEX_HANDLER + "." + handlerName + "."; + String TYPE = commonKey + "type"; + String SOURCE_COLUMNS = commonKey + "sourcecolumns"; + String SOURCE_COLUMN_TYPES = commonKey + "sourcecolumntypes"; + String TARGET_DATA_TYPE = commonKey + "datatype"; + // String ORIGIN_LONGITUDE = commonKey + "originlongitude"; + String ORIGIN_LATITUDE = commonKey + "originlatitude"; + String MIN_LONGITUDE = commonKey + "minlongitude"; + String MAX_LONGITUDE = commonKey + "maxlongitude"; + String MIN_LATITUDE = commonKey + "minlatitude"; + String MAX_LATITUDE = commonKey + "maxlatitude"; + String GRID_SIZE = commonKey + "gridsize"; + String CONVERSION_RATIO = commonKey + "conversionratio"; + + + String sourceColumnsOption = properties.get(SOURCE_COLUMNS); + if (sourceColumnsOption == null) { + throw new MalformedCarbonCommandException( + String.format("%s property is invalid. %s property is not specified.", + CarbonCommonConstants.INDEX_HANDLER, SOURCE_COLUMNS)); + } + + if (sourceColumnsOption.split(",").length != 2) { + throw new MalformedCarbonCommandException( + String.format("%s property is invalid. %s property must have 2 columns.", + CarbonCommonConstants.INDEX_HANDLER, SOURCE_COLUMNS)); + } + + String type = properties.get(TYPE); + if (type != null && !GEOHASH.equalsIgnoreCase(type)) { + throw new MalformedCarbonCommandException( + String.format("%s property is invalid. %s property must be %s for this class.", + CarbonCommonConstants.INDEX_HANDLER, TYPE, GEOHASH)); + } + + properties.put(TYPE, GEOHASH); + + String sourceDataTypes = properties.get(SOURCE_COLUMN_TYPES); + String[] srcTypes = sourceDataTypes.split(","); + for (String srcdataType : srcTypes) { + if (!"bigint".equalsIgnoreCase(srcdataType)) { + throw new MalformedCarbonCommandException( + String.format("%s property is invalid. %s datatypes must be long.", + CarbonCommonConstants.INDEX_HANDLER, SOURCE_COLUMNS)); + } + } + + String dataType = properties.get(TARGET_DATA_TYPE); + if (dataType != null && !"long".equalsIgnoreCase(dataType)) { + throw new MalformedCarbonCommandException( + String.format("%s property is invalid. %s property must be long for this class.", + CarbonCommonConstants.INDEX_HANDLER, TARGET_DATA_TYPE)); + } + + /* Set the generated column data type as long */ + properties.put(TARGET_DATA_TYPE, "long"); + + // String originLongitude = properties.get(ORIGIN_LONGITUDE); + String originLatitude = properties.get(ORIGIN_LATITUDE); + if (originLatitude == null) { + throw new MalformedCarbonCommandException( + String.format("%s property is invalid. Must specify %s property.", + CarbonCommonConstants.INDEX_HANDLER, ORIGIN_LATITUDE)); + } + + String minLongitude = properties.get(MIN_LONGITUDE); + String maxLongitude = properties.get(MAX_LONGITUDE); + String minLatitude = properties.get(MIN_LATITUDE); + String maxLatitude = properties.get(MAX_LATITUDE); + if (minLongitude == null || maxLongitude == null + || minLatitude == null || maxLatitude == null) { + throw new MalformedCarbonCommandException( + String.format("%s property is invalid. Must specify %s, %s, %s and %s properties.", + CarbonCommonConstants.INDEX_HANDLER, MIN_LONGITUDE, MAX_LONGITUDE, + MIN_LATITUDE, MAX_LATITUDE)); + } + + String gridSize = properties.get(GRID_SIZE); + if (gridSize == null) { + throw new MalformedCarbonCommandException( + String.format("%s property is invalid. %s property must be specified.", + CarbonCommonConstants.INDEX_HANDLER, GRID_SIZE)); + } + + String conversionRatio = properties.get(CONVERSION_RATIO); + if (conversionRatio == null) { + throw new MalformedCarbonCommandException( + String.format("%s property is invalid. %s property must be specified.", + CarbonCommonConstants.INDEX_HANDLER, CONVERSION_RATIO)); + } + + /* Fill the values */ + // this.oriLongitude = Double.valueOf(originLongitude); + this.oriLatitude = Double.valueOf(originLatitude); + this.userDefineMaxLongitude = Double.valueOf(maxLongitude); + this.userDefineMaxLatitude = Double.valueOf(maxLatitude); + this.userDefineMinLongitude = Double.valueOf(minLongitude); + this.userDefineMinLatitude = Double.valueOf(minLatitude); + this.gridSize = Integer.parseInt(gridSize); + this.conversionRatio = Integer.parseInt(conversionRatio); + + // 角度转弧度 radians = (Math.PI / 180) * degrees 求得原点纬度角度的余弦数值 + this.mCos = Math.cos(this.oriLatitude * Math.PI / CONVERT_FACTOR); + // 求得 δ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; + // 求得 δy=L∗360/2πR + this.deltaY = (this.gridSize * 360) / (2 * Math.PI * EARTH_RADIUS); + this.deltaYByRatio = this.deltaY * this.conversionRatio; + // 计算补齐区域并计算栅格i,j表示栅格编号 + // Xmax = x0+(2^n∗δx) Ymax = y0+(2^n∗δx) 其中N是切的刀数 + // 其中x0,y0是给定区域的最小x,y坐标, Xmax >= maxLongitude Ymax >= maxLatitude + // 计算过程先把maxLongitude, maxLatitude 代入计算出N,如果N不是整数,则取N的下一个整数,代入后求得Xmax,Ymax。 Review comment: Please write English comments, not everyone understands Chinese :) ---------------------------------------------------------------- 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: [hidden email] With regards, Apache Git Services |
Free forum by Nabble | Edit this page |