Commit 4c810237 by chamberone

提交行政区模块

1 parent 73770501
Showing with 2976 additions and 3 deletions
......@@ -8,4 +8,5 @@ PRAISE_PROVIDER_PORT=8015
PRAISE_CONSUMER_PORT=8014
USER_PORT=8000
GIS_PORT=8001
GEOMETRY_PORT=8002
\ No newline at end of file
GEOMETRY_PORT=8002
DISTRICT_PORT=8003
\ No newline at end of file
......@@ -268,5 +268,19 @@ services:
- ${GEOMETRY_PORT}:${GEOMETRY_PORT}
depends_on:
- nacos
# district module
project-district:
image: project-district
restart: always
build:
dockerfile: ./project-district/Dockerfile
context: ../
env_file:
- .env
container_name: project-district
ports:
- ${DISTRICT_PORT}:${DISTRICT_PORT}
depends_on:
- nacos
\ No newline at end of file
......@@ -57,6 +57,7 @@
<module>project-user</module>
<module>project-gis</module>
<module>project-geometry</module>
<module>project-district</module>
</modules>
<!-- 用来统一管理jar包依赖的版本,但是不会引入依赖,只有当在某个模块中显示引入某个依赖的时候才会真正的引入jar包 -->
......
FROM registry.cn-hangzhou.aliyuncs.com/dituhui/smo:j11-s9.1.0
COPY ./target/project-district-*.jar /app.jar
EXPOSE 8003
CMD cd /opt/SMO/Support/aksusbd-2.2.1-i386/ && (./dinst &) && sleep 10 && pkill -9 hasp_update && cd / && java -version && java -jar app.jar
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-parent</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>project-district</artifactId>
<name>district</name>
<description>district module</description>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<smo.version>9.1.0.15802</smo.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>com.supermap</groupId>
<artifactId>com.supermap.data</artifactId>
<version>${smo.version}</version>
</dependency>
<dependency>
<groupId>com.supermap</groupId>
<artifactId>com.supermap.data.topology</artifactId>
<version>${smo.version}</version>
</dependency>
<dependency>
<groupId>com.supermap</groupId>
<artifactId>com.supermap.analyst.spatialanalyst</artifactId>
<version>${smo.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>net.jpountz.lz4</groupId>
<artifactId>lz4</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<!-- elasticsearch start -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>elasticsearch</artifactId>
</exclusion>
</exclusions>
<version>5.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>6.4.2</version>
</dependency>
<!-- download from http://mvnrepository.com/artifact/org.elasticsearch.client/transport -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>transport-netty4-client</artifactId>
</exclusion>
</exclusions>
<version>5.3.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty4-client</artifactId>
<version>5.3.2</version>
</dependency>
<!-- elasticsearch end -->
<!-- json -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.36</version>
</dependency>
<!-- json -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>project-interface</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.dituhui.mp.district;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
package com.dituhui.mp.district.constants;
/**
* ElasticsearchField
* 用于的类
*
* @author zhouyun
* 2021/6/8 15:00
* <p>Company: 成都地图慧科技有限公司</p>
*/
public class DistrictElasticsearchField {
public static final String ES_FIELD_LEVEL = "level";
public static final String ES_FIELD_ADMINCODE = "admincode";
public static final String ES_FIELD_NAME = "name";
public static final String ES_FIELD_FULLNAME = "fullName";
public static final String ES_FIELD_SUBNAMES = "subNames";
public static final String ES_FIELD_ABBREVIATION = "abbreviation";
public static final String ES_FIELD_REGION = "region";
public static final String ES_FIELD_MKTREGION = "mktRegion";
public static final String ES_FIELD_BAIDUREGION = "baiduRegion";
public static final String ES_FIELD_USERKEY = "userKey";
public static final String ES_FIELD_VERSION = "version";
public static final String ES_FIELD_DESC = "desc";
public static final String ES_FIELD_ESINDEX = "esIndex";
public static final String ES_Field_CENTER = "center";
public static final String ES_Field_GOVPOSITION = "govPosition";
public static final String ES_Field_ACODE = "aCode";
public static final String ES_Field_ZIPCODE = "zipcode";
}
package com.dituhui.mp.district.controller;
import com.dituhui.mp.district.IDistrict;
import com.dituhui.mp.district.service.DistrictService;
import com.dituhui.mp.district.util.ParameterParser;
import com.dituhui.mp.district.util.Point;
import com.dituhui.mp.district.util.Region;
import com.dituhui.mp.district.vo.District;
import com.dituhui.mp.district.vo.DistrictsResult;
import com.dituhui.mp.enums.CoordTypeEnum;
import com.dituhui.mp.enums.StatusCodeEnum;
import com.dituhui.mp.exception.BusinessException;
import com.dituhui.mp.pojo.WebResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
/**
* DistrictController
* 用于行政区的Controller
*
* @author zhouyun
* 2021/6/1 15:26
* <p>Company: 成都地图慧科技有限公司</p>
*/
@Slf4j
@RestController
@RefreshScope
public class DistrictController implements IDistrict {
@Autowired
private DistrictService districtService;
@Override
public WebResult query(String admincode, String name, Integer level, Boolean includeRegion, String coordType,
Integer rarefiedNum, Integer version, Boolean custom, String ak) {
// 参数检查
if ((version != 0) && (version < 10000 || version > 99999)) {
// "version不是5位数"
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
if (rarefiedNum != 0 && rarefiedNum != 200) {
// "rarefiedNum不是0或200"
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
// "coordType不是\"gcj02ll\",\"gcj02mc\"或\"bd09ll\""
try {
CoordTypeEnum.valueOf(coordType.toUpperCase());
} catch (Exception e) {
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
if (StringUtils.isEmpty(admincode) && StringUtils.isEmpty(name) && level == 0) {
// "admincode和name都为空时,level不允许为0"
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
DistrictsResult districtsResult = districtService.query(version, rarefiedNum, ak, !custom, admincode, name, level, includeRegion, coordType);
// 组装返回结果
return WebResult.ok(districtsResult);
}
@Override
public WebResult queryByPoint(String points, Integer level, Boolean includeRegion, String coordType,
Integer rarefiedNum, Integer version, Boolean custom, String ak) {
DistrictsResult districtsResult = new DistrictsResult();
long startTime = System.currentTimeMillis();
// 参数检查
if ((version != 0) && (version < 10000 || version > 99999)) {
// "version不是5位数"
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
if (rarefiedNum != 0 && rarefiedNum != 200) {
// "rarefiedNum不是0或200"
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
try {
CoordTypeEnum.valueOf(coordType.toUpperCase());
} catch (Exception e) {
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
if (points.length() == 0) {
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
if (level <= 0 || level >= 5) {
// "行政区的值只能是1,2,3,4"
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
List<Point> pointList = ParameterParser.parsePoints(points);
// 调用DUBBO服务
District[] partDistrictList = new District[pointList.size()];
for (int i = 0; i < pointList.size(); i++) {
Point point = pointList.get(i);
List<? extends District> partDistricts = districtService.queryByPoint(version, rarefiedNum, ak, !custom, null, level, point, includeRegion,
coordType);
if (partDistricts != null && partDistricts.size() > 0) {
// 如果queryByPoint有结果,应该只有一个行政区
partDistrictList[i] = partDistricts.get(0);
} else {
// 如果queryByPoint没有结果,则记录null
partDistrictList[i] = null;
}
}
List<? extends District> districts = Arrays.asList(partDistrictList);
long endTime = System.currentTimeMillis();
log.debug("queryByPoint cost(ms):" + (endTime - startTime));
// 组装返回结果
districtsResult.setDistricts(districts);
return WebResult.ok(districtsResult);
}
@Override
public WebResult queryByRegion(String points, String parts, String spatialQueryMode, Integer level,
Boolean includeRegion, String coordType, Integer rarefiedNum, Integer version,
Boolean custom, String ak) {
DistrictsResult districtsResult = new DistrictsResult();
// 参数检查
if ((version != 0) && (version < 10000 || version > 99999)) {
// "version不是5位数"
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
try {
CoordTypeEnum.valueOf(coordType.toUpperCase());
} catch (Exception e) {
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
if (!spatialQueryMode.equals("CONTAIN") && !spatialQueryMode.equals("INTERSECT")) {
// "queryMode只能是:\"CONTAIN\",\"INTERSECT\",且不能为空。"
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
if (level <= 0 || level >= 5) {
throw new BusinessException(StatusCodeEnum.COMMON_PARAM_ERROR);
}
Region region = new Region();
region.setPoints(ParameterParser.parsePoints(points));
region.setParts(ParameterParser.parseParts(parts));
List<? extends District> districtList = districtService.getDistrictByRegion(version, ak, !custom, region, includeRegion, level, spatialQueryMode,
coordType, rarefiedNum);
if (districtList == null) {
return WebResult.ok(districtsResult);
}
for (District district : districtList) {
String districtAdmincode = district.getAdmincode();
if (districtAdmincode != null && districtAdmincode.length() == 12) {
// towncode是12位编码,admincode是6位编码。
district.setTowncode(districtAdmincode);
district.setAdmincode(districtAdmincode.substring(0, 6));
}
}
// 组装返回结果
districtsResult.setDistricts(districtList);
return WebResult.ok(districtsResult);
}
}
package com.dituhui.mp.district.util;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Properties;
/**
* 配置文件读取工具
*
* @author liweigu
*
*/
public class Constants {
private static final Logger LOGGER = Logger.getLogger(Constants.class);
// 用于缓存
private static HashMap<String, Properties> props = new HashMap<String, Properties>();
/**
* 读取配置值
*
* @param key 配置key
* @param file 配置文件,如"openapi-util_constants.properties"
* @return 配置值
*/
public static String getValue(String key, String file) {
Properties prop;
String value = null;
try {
if (props.containsKey(file)) {
prop = props.get(file);
} else {
prop = readPropertiesFile(file, Constants.class);
}
if (prop != null) {
value = prop.getProperty(key);
}
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
private static Properties readPropertiesFile(String fileName, Class clazz) {
InputStream inStream = readFromUsrDir(fileName);
if (inStream == null) {
inStream = readFromClassPath(fileName, clazz);
}
Properties prop = new Properties();
try {
if (inStream != null) {
prop.load(inStream);
inStream.close();
} else {
prop = null;
}
} catch (Exception e) {
e.printStackTrace();
prop = null;
}
return prop;
}
private static InputStream readFromUsrDir(String fileName) {
String filePath = System.getProperty("user.dir") + File.separator + fileName;
InputStream inStream = null;
try {
inStream = new FileInputStream(filePath);
} catch (FileNotFoundException localFileNotFoundException) {
LOGGER.debug("读取配置文件发生异常:" + localFileNotFoundException.getMessage());
}
return inStream;
}
private static InputStream readFromClassPath(String fileName, Class clazz) {
return clazz.getClassLoader().getResourceAsStream(fileName);
}
}
package com.dituhui.mp.district.util;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.log4j.Logger;
import com.supermap.data.GeoLine;
import com.supermap.data.Geometrist;
import com.supermap.data.Geometry;
import com.supermap.data.Point2D;
import com.supermap.data.Point2Ds;
import com.supermap.data.ResampleType;
import net.sf.json.JSONArray;
/**
* 线对象
*
* @author liweigu
*
*/
public class Line implements Serializable {
private static final Logger LOGGER = Logger.getLogger(Line.class);
private static final long serialVersionUID = -9130756934923632152L;
// 点列表
private List<Point> points = new ArrayList<>();
/**
* 构造函数
*/
public Line() {
}
/**
* 构造函数
*
* @param points 点串。points应包含至少2个点。
*/
public Line(List<Point> points) {
if (points == null || points.size() < 2) {
throw new IllegalArgumentException("points必须包含至少2个点");
}
this.points = points;
}
/**
* 获取点列表
*
* @return 点列表
*/
public List<Point> getPoints() {
return this.points;
}
/**
* 设置点列表
*
* @param points 点列表
*/
public void setPoints(List<Point> points) {
this.points = points;
}
/**
* 获取长度
*
* @return 长度。单位是米。
*/
public double getLength() {
double length = 0;
if (this.points != null && this.points.size() > 1) {
List<Point> pointsToCaculate;
if (this.points.get(0).getX() < 360) {
// 如果是经纬度坐标,拷贝一份对象,然后将坐标转换为墨卡托
Line copiedLine = (Line) this.clone();
pointsToCaculate = copiedLine.points;
} else {
// 墨卡托坐标不需要转换
pointsToCaculate = this.points;
}
for (int i = 1; i < pointsToCaculate.size(); i++) {
Point startPoint = pointsToCaculate.get(i - 1);
Point endPoint = pointsToCaculate.get(i);
if (startPoint != null) {
double distance = startPoint.distanceTo(endPoint);
length += distance;
}
}
}
return length;
}
/**
* 去重
*
* @param points 点串
* @return 去重后的点串
*/
public static List<? extends Point> distinct(List<? extends Point> points) {
// 复制集合
List<Point> dupPoints = new ArrayList<Point>();
for (Point point : points) {
dupPoints.add(point);
}
// 去重
if (dupPoints != null) {
for (int i = dupPoints.size() - 1; i >= 1; i--) {
for (int j = 0; j < i; j++) {
if (dupPoints.get(i).equals(dupPoints.get(j))) {
dupPoints.remove(i);
break;
}
}
}
}
return dupPoints;
}
/**
* 排序。根据X/Y排序。
*
* @param points 点串
* @return 排序后的点串
*/
public static List<? extends Point> sort(List<? extends Point> points) {
// 根据Y值排序
Collections.sort(points, new PointComparator());
return points;
}
/**
* 坐标点的X/Y值比较器
*
* @author liweigu
*
*/
static class PointComparator implements Comparator<Point> {
@Override
public int compare(Point pointA, Point pointB) {
int result = 0;
if (pointA.getX() > pointB.getX()) {
result = 1;
} else if (pointA.getX() < pointB.getX()) {
result = -1;
} else {
// X相同时,比较Y
if (pointA.getY() > pointB.getY()) {
result = 1;
} else if (pointA.getY() < pointB.getY()) {
result = -1;
}
}
return result;
}
}
/**
* 重采样。依赖Object Java。会重新给points赋值。
*
* @param tolerance 重采样容限
*/
public void resample(double tolerance) {
GeoLine geoLine = this.toGeoLine();
// 判断坐标是经纬度还是墨卡托
Point firstPoint = this.getPoints().get(0);
if (firstPoint.getX() < 360) {
// 如果是经纬度坐标
Point mktPoint = CoordConverter.gcj02llToGcj02mc(firstPoint);
Point movedMktPoint = new Point(mktPoint.getX() + tolerance, mktPoint.getY());
Point movedLlPoint = CoordConverter.gcj02mcToGcj02ll(movedMktPoint);
// 修正tolerance为经纬度的值
tolerance = movedLlPoint.getX() - firstPoint.getX();
}
ResampleType resampleType = ResampleType.RTGENERAL;
// resampleType = ResampleType.RTBEND;
Geometry geometry = Geometrist.resample(geoLine, resampleType, tolerance);
geoLine = (GeoLine) geometry;
Point2Ds point2Ds = geoLine.getPart(0);
this.points = new ArrayList<Point>();
for (int i = 0; i < point2Ds.getCount(); i++) {
Point2D point2D = point2Ds.getItem(i);
this.points.add(new Point(point2D.getX(), point2D.getY()));
}
}
/**
* 转换为GeoLine。依赖Object Java。
*
* @return GeoLine
*/
public GeoLine toGeoLine() {
GeoLine geoLine = null;
if (this.points.size() > 1) {
Point2Ds point2Ds = new Point2Ds();
for (Point point : this.points) {
point2Ds.add(new Point2D(point.getX(), point.getY()));
}
geoLine = new GeoLine(point2Ds);
} else {
LOGGER.info("转换为GeoLine失败。this.points.size()=" + this.points.size());
}
return geoLine;
}
/**
* 解析GeoLine
*
* @param geoLine GeoLine
* @return Line
*/
public static Line fromGeoLine(GeoLine geoLine) {
Line line = null;
if (geoLine == null || geoLine.getPartCount() == 0) {
throw new IllegalArgumentException("geoLine为空");
} else {
List<Point> points = new ArrayList<Point>();
int partCount = geoLine.getPartCount();
// if (partCount > 1) {
// System.out.println("partCount = " + partCount);
// }
int[] parts = new int[partCount];
for (int i = 0; i < partCount; i++) {
Point2Ds point2Ds = geoLine.getPart(i);
int count = point2Ds.getCount();
for (int j = 0; j < count; j++) {
Point2D point2D = point2Ds.getItem(j);
Point point = new Point(point2D.getX(), point2D.getY());
points.add(point);
}
parts[i] = count;
if (count < 2) {
LOGGER.warn("Line.fromGeoLine() count = " + count);
}
}
line = new Line(points);
}
return line;
}
/**
* 解析GeoLine
*
* @param geoLine GeoLine
* @return GeoLine
*/
public static List<Line> fromGeoLine2(GeoLine geoLine) {
List<Line> lines = new ArrayList<Line>();
if (geoLine == null || geoLine.getPartCount() == 0) {
throw new IllegalArgumentException("geoLine为空");
} else {
int partCount = geoLine.getPartCount();
// if (partCount > 1) {
// System.out.println("partCount = " + partCount);
// }
int[] parts = new int[partCount];
for (int i = 0; i < partCount; i++) {
List<Point> points = new ArrayList<Point>();
Point2Ds point2Ds = geoLine.getPart(i);
int count = point2Ds.getCount();
for (int j = 0; j < count; j++) {
Point2D point2D = point2Ds.getItem(j);
Point point = new Point(point2D.getX(), point2D.getY());
points.add(point);
}
parts[i] = count;
if (count < 2) {
LOGGER.warn("Line.fromGeoLine() count = " + count);
}
Line line = new Line(points);
lines.add(line);
}
}
return lines;
}
/**
* 解析线
*
* @param s 字符串。以分号分隔点,以逗号分隔x和y值。
* @return 线
*/
public static Line parseLine(String s) {
Line line = null;
if (null != s && s.contains(StringUtil.COMMA)) {
String[] arr;
if (s.contains(StringUtil.SEMICOLON)) {
arr = s.split(StringUtil.SEMICOLON);
} else {
arr = new String[] { s };
}
List<Point> points = new ArrayList<Point>();
for (String item : arr) {
Point point = Point.parsePoint(item);
points.add(point);
}
if (points.size() > 1) {
line = new Line(points);
} else {
LOGGER.warn("点数小于2,不能构成线。s = " + s);
}
}
return line;
}
/**
* 复制线对象
*
* @return 线对象
*/
@Override
public Object clone() {
Line copiedLine = new Line();
if (this.points != null) {
List<Point> copiedPoints = new ArrayList<Point>();
for (Point point : this.points) {
Point copiedPoint = new Point(point);
copiedPoints.add(copiedPoint);
}
copiedLine.setPoints(copiedPoints);
}
return copiedLine;
}
/**
* 解析json字符串
*
* @param json json字符串
* @return 线
*/
public static Line parseJson(String json) {
Line line = null;
if (null != json && json.length() > 0) {
JSONArray jsonArray = JSONArray.fromObject(json);
List<Point> points = new ArrayList<Point>();
for (int i = 0; i < jsonArray.size(); i++) {
String s = jsonArray.getString(i);
Point point = Point.parseJson(s);
points.add(point);
}
line = new Line(points);
}
return line;
}
/**
* toString方法
*
* @return String
*/
@Override
public String toString() {
if (this.points == null) {
return StringUtil.EMPTY;
} else {
StringBuilder stringBuilder = new StringBuilder();
boolean isFirst = true;
for (Point point : this.points) {
if (isFirst) {
isFirst = false;
} else {
stringBuilder.append(StringUtil.SEMICOLON);
}
stringBuilder.append(point.toString());
}
return stringBuilder.toString();
}
}
/**
* 获取哈希值
*
* @return 哈希值
*/
@Override
public int hashCode() {
return this.toString().hashCode();
}
}
package com.dituhui.mp.district.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import java.util.ArrayList;
import java.util.List;
/**
* 参数解析器
*
* @author liweigu
*/
@Slf4j
public class ParameterParser {
private static final Point ZeroPoint = new Point(0, 0);
/**
* 解析点
*
* @param str 字符串
* @return 点
*/
public static Point parsePoint(String str) {
Point objPoint = null;
if (str != null && str.contains(StringUtil.COMMA)) {
String[] xyPoint = str.split(StringUtil.COMMA);
try {
objPoint = new Point(Double.valueOf(xyPoint[0].trim()), Double.valueOf(xyPoint[1].trim()));
} catch (NumberFormatException e) {
log.debug("parsePoint发生异常。point=" + str, e);
}
}
return objPoint;
}
/**
* 解析点串
*
* @param str 字符串
* @return 点串。
*/
public static List<Point> parsePoints(String str) {
List<Point> pointList = new ArrayList<Point>();
if (str.indexOf(StringUtil.SEMICOLON) != -1) {
String[] pointsArray = str.split(StringUtil.SEMICOLON);
// logger.debug("pointsArray.length = " + pointsArray.length);
for (String pointStr : pointsArray) {
Point point = parsePoint(pointStr);
if (point == null) {
log.debug("parsePoints里的部分点无法解析。pointStr=" + pointStr);
}
// null也要添加,否则个数对不上。
pointList.add(point);
}
// logger.debug("pointList.size() = " + pointList.size());
} else {
Point point = parsePoint(str);
if (point != null) {
pointList.add(point);
} else {
log.debug("parsePoints里的点无法解析。str=" + str);
}
}
return pointList;
}
/**
*
* @param str
* @return
*/
public static int[] parseParts(String str) {
try {
if (!StringUtils.isEmpty(str)) {
String[] partsStr = str.split(StringUtil.COMMA);
int[] partsInt = new int[partsStr.length];
for (int i = 0; i < partsStr.length; i++) {
partsInt[i] = Integer.parseInt(partsStr[i]);
}
return partsInt;
}
} catch (Exception e) {
log.debug("parts无法解析。str=" + str);
}
return new int[] {};
}
}
package com.dituhui.mp.district.util;
import com.supermap.data.GeoPoint;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 点对象
*
* @author liweigu
*
*/
public class Point implements Serializable {
private static final Logger LOGGER = Logger.getLogger(Point.class);
public static final Point ZeroPoint = new Point();
private static final long serialVersionUID = -1754805998584325163L;
// 经纬度坐标的上限值
private static final int MAX_GPS_DEGREE = 360;
// 用于计算距离
private static final double EARTH_RADIUS = 6378137;
// 中国边界的经纬度
static final double CHINA_LEFT = 73.502355;
static final double CHINA_BOTTOM = 3.837031;
static final double CHINA_RIGHT = 135.09567;
static final double CHINA_TOP = 53.563624;
/**
* X坐标
*/
private double x;
/**
* Y坐标
*/
private double y;
/**
* 构造函数
*/
public Point() {
}
/**
* 构造函数
*
* @param x X坐标
* @param y Y坐标
*/
public Point(double x, double y) {
this.x = x;
this.y = y;
}
/**
* 构造函数
*
* @param point 点
*/
public Point(Point point) {
this.x = point.x;
this.y = point.y;
}
/**
* 获取X坐标
*
* @return X坐标
*/
public double getX() {
return this.x;
}
/**
* 获取Y坐标
*
* @return Y坐标
*/
public double getY() {
return this.y;
}
/**
* 设置X坐标
*
* @param x X坐标
*/
public void setX(double x) {
this.x = x;
}
/**
* 设置Y坐标
*
* @param y Y坐标
*/
public void setY(double y) {
this.y = y;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Point) {
Point point = (Point) obj;
if (point != null) {
if (Math.abs(this.x - point.x) < 0.00000001 && Math.abs(this.y - point.y) < 0.00000001) {
return true;
}
}
}
return false;
}
@Override
public int hashCode() {
return this.toString().hashCode();
}
@Override
/**
* 转换为字符串。字符串内容为:x1,y1。摩卡托坐标,保留小数点后1位;经纬度坐标,保留小数点后6位。
*/
public String toString() {
String strX, strY;
if (this.x > MAX_GPS_DEGREE) {
// 摩卡托坐标,保留小数点后1位
strX = StringUtil.formatDouble(this.x, StringUtil.TWO_FRACTION_FORMAT);
strY = StringUtil.formatDouble(this.y, StringUtil.TWO_FRACTION_FORMAT);
} else {
// 经纬度坐标,保留小数点后6位
strX = StringUtil.formatDouble(this.x, StringUtil.SIX_FRACTION_FORMAT);
strY = StringUtil.formatDouble(this.y, StringUtil.SIX_FRACTION_FORMAT);
}
StringBuilder stringBuilder = new StringBuilder(strX);
stringBuilder.append(StringUtil.COMMA);
stringBuilder.append(strY);
return stringBuilder.toString();
}
/**
* 转换为整数列表
*
* @return 整数列表
*/
public List<Integer> toIntList() {
List<Integer> intList = new ArrayList<Integer>();
if (this.x > MAX_GPS_DEGREE) {
// 墨卡托
int intX = (int) Math.round(this.x);
int intY = (int) Math.round(this.y);
intList.add(intX);
intList.add(intY);
} else {
// 经纬度
double x = this.x - CHINA_LEFT;
double y = this.y - CHINA_BOTTOM;
int intX = (int) Math.round(x * Math.pow(10, 6));
int intY = (int) Math.round(y * Math.pow(10, 6));
intList.add(intX);
intList.add(intY);
}
return intList;
}
/**
* 从整数列表转换
*
* @param intList 整数列表
*
* @return 点
*/
public static Point fromIntList(List<Integer> intList) {
Point point;
int intX = intList.get(0);
int intY = intList.get(1);
if (false) {
// 墨卡托
point = new Point(intX, intY);
} else {
// 经纬度
double x = ((double) intX) / Math.pow(10, 6);
double y = ((double) intY) / Math.pow(10, 6);
point = new Point(x + CHINA_LEFT, y + CHINA_BOTTOM);
}
return point;
}
/**
* 拷贝对象
*
* @return 点
*/
public Point copy() {
Point point = new Point(this.getX(), this.getY());
return point;
}
/**
* 转换为GeoPoint
*
* @return GeoPoint
*/
public GeoPoint toGeoPoint() {
return new GeoPoint(this.getX(), this.getY());
}
// 用于计算距离
private static double rad(double d) {
return d * Math.PI / 180.0;
}
/**
* 解析点
*
* @param s 字符串。以逗号分隔x和y值。
* @return 点
*/
public static Point parsePoint(String s) {
Point point = null;
if (null != s && s.contains(StringUtil.COMMA)) {
String[] points = s.split(StringUtil.COMMA);
point = new Point(Double.parseDouble(points[0]), Double.parseDouble(points[1]));
}
return point;
}
/**
* 解析json字符串
*
* @param json json字符串
* @return 点
*/
public static Point parseJson(String json) {
Point point = null;
if (null != json && json.length() > 0) {
JSONObject jsonObject = JSONObject.fromObject(json);
point = new Point(jsonObject.getDouble("x"), jsonObject.getDouble("y"));
}
return point;
}
/**
* 计算两点的距离
*
* @param point 另一个点
* @return 距离,单位是米
*/
public double distanceTo(Point point) {
Point startPoint = this;
Point endPoint = point;
if (startPoint.getX() > 360 || startPoint.getY() > 360) {
// 如果是摩卡托坐标,则转换为经纬度。
startPoint = CoordConverter.gcj02mcToGcj02ll(startPoint);
}
if (endPoint.getX() > 360 || endPoint.getY() > 360) {
// 如果是摩卡托坐标,则转换为经纬度。
endPoint = CoordConverter.gcj02mcToGcj02ll(endPoint);
}
double lng1 = startPoint.getX();
double lat1 = startPoint.getY();
double lng2 = endPoint.getX();
double lat2 = endPoint.getY();
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
s = s * EARTH_RADIUS;
// 精确到小数点后一位
s = Math.round(s * 10) / 10.0;
return s;
}
}
package com.dituhui.mp.district.util;
import org.apache.log4j.Logger;
/**
* 用多线程运行的工具
*
* @author liweigu
*
*/
public class ThreadTool {
private static Logger LOGGER = Logger.getLogger(ThreadTool.class);
public static void run(Worker worker) {
MyRunnable myRunnable = new MyRunnable(worker);
Thread thread = new Thread(myRunnable);
LOGGER.info("启动1个线程");
thread.start();
LOGGER.info("线程已启动");
}
public static class MyRunnable implements Runnable {
private Worker worker;
public MyRunnable(Worker worker) {
this.worker = worker;
}
@Override
public void run() {
this.worker.run();
}
}
public static interface Worker {
void run();
}
}
package com.dituhui.mp.district.util.elasticsearch;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Properties;
/**
* 读取配置文件工具
*
* @author liweigu
*
*/
public class AppPropertiesUtil {
private static final Logger LOGGER = Logger.getLogger(AppPropertiesUtil.class);
/**
* 读取配置文件
* @param fileName 文件名
* @param clazz 类名
* @return 配置信息
*/
public static Properties readPropertiesFile(String fileName, Class clazz) {
InputStream inStream = readFromUsrDir(fileName);
if (inStream == null) {
inStream = readFromClassPath(fileName, clazz);
}
if (inStream == null) {
inStream = readFromResource(fileName, clazz);
}
Properties prop = new Properties();
try {
if (inStream != null) {
prop.load(inStream);
inStream.close();
LOGGER.info("## 加载配置" + fileName + "成功");
} else {
prop = null;
LOGGER.error("## 加载配置文件" + fileName + "出错");
}
} catch (Exception e) {
prop = null;
LOGGER.error("## 加载配置文件失败");
}
return prop;
}
private static InputStream readFromUsrDir(String fileName) {
String filePath = System.getProperty("user.dir") + File.separator + fileName;
InputStream inStream = null;
try {
inStream = new FileInputStream(filePath);
} catch (FileNotFoundException localFileNotFoundException) {
LOGGER.warn("readFromUsrDir发生异常:" + localFileNotFoundException.getMessage());
}
return inStream;
}
private static InputStream readFromClassPath(String fileName, Class clazz) {
return clazz.getClassLoader().getResourceAsStream(fileName);
}
private static InputStream readFromResource(String fileName, Class clazz) {
return clazz.getClass().getResourceAsStream(fileName);
}
}
package com.dituhui.mp.district.util.elasticsearch;
import java.util.Properties;
/***
* 常量
*
* @author wangjian@supermap.com
*/
public class Constants {
/**
* 加载配置文件
*/
private static Properties prop = AppPropertiesUtil.readPropertiesFile("elasticsearch-util.config.properties", Constants.class);
/***
* elasticsearch 的集群名称
*/
public static final String ES_CLUSTER_NAME = prop.getProperty("ELASTICSEARCH.UTIL.CLUSTER.NAME");
}
\ No newline at end of file
package com.dituhui.mp.district.util.elasticsearch;
import com.dituhui.mp.district.util.elasticsearch.api.ElasticSearchAPI;
import com.dituhui.mp.district.util.elasticsearch.bean.QueryBean;
import net.sf.json.JSONObject;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.stereotype.Component;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* ES工具
*
* @author liweigu
*
*/
@Component
public class ElasticsearchUtil extends ElasticSearchAPI {
private static final String DEFAULT_SEARCH_TYPE = "1";
private String index;
private String type;
/***
* ES的写入方法
*
* @param datas 数据集map
* @param host ES服务地址
* @return 写入结果
*/
public String write(List<Map<String, Object>> datas, String host) {
String routing = null;
return write(datas, routing, host);
}
/***
* ES的写入方法
*
* @param datas 数据集map
* @param routing ES routing,如果值是null,ES会默认使用id字段。
* @param host ES服务地址
* @return 写入结果
*/
public String write(List<Map<String, Object>> datas, String routing, String host) {
// 构建json对象,便于es解析
JSONObject jData = new JSONObject();
jData.accumulate("index", this.getIndex());
jData.accumulate("_type", this.getType());
if (routing != null) {
jData.accumulate("routing", routing);
}
jData.accumulate("datas", datas);
return update(jData, host); // 调用更新
}
/***
* ES的读取方法
*
* @param queryBean QueryBean
* @param host ES服务地址
* @return list中封装的为json字符串
*/
public List<String> read(QueryBean queryBean, String host) {
String routing = null;
return read(queryBean, routing, host);
}
/***
* ES的读取方法
*
* @param queryBean QueryBean
* @param routing ES routing,如果值是null,ES会默认使用id字段。
* @param host ES服务地址
* @return list中封装的为json字符串
*/
public List<String> read(QueryBean queryBean, String routing, String host) {
JSONObject jsonObject = JSONObject.fromObject(convert(queryBean));
if (!jsonObject.containsKey("searchtype")) {
jsonObject.accumulate("searchtype", DEFAULT_SEARCH_TYPE);
}
// 如果routing不为空并且jsonObject里没有routing时,就进行设置。
if (routing != null && !jsonObject.containsKey("routing")) {
jsonObject.accumulate("routing", routing);
}
SearchHit[] hits = search(jsonObject, host).getHits().getHits();
List<String> list = new ArrayList<>();
for (SearchHit hit : hits) {
// 5.2.x
String id = hit.getId();
// System.out.println("id = " + id);
String source = hit.getSourceAsString();
JSONObject jsonObject2 = JSONObject.fromObject(source);
// 返回"_id"
jsonObject2.accumulate("_id", id);
source = jsonObject2.toString();
// System.out.println("source = " + source);
list.add(source);
// 2.2.0
// if (queryBean.getReturnFields() == null || queryBean.getReturnFields().length == 0) {
// // {"desc":"for testing","userKey":"00000000000000000000000000000000","version":"1.0.0"}
// list.add(hit.getSourceAsString());
// } else {
// // 设置了查询字段
// JSONObject resultJson = new JSONObject();
// SearchHitField searchHitField = hit.field("admincode");
// System.out.println("searchHitField=" + searchHitField);
// System.out.println("hits[i].fields().size()=" + hit.fields().size());
// System.out.println("hits[i].getFields().size()=" + hit.getFields().size());
// System.out.println("hit.getSourceAsString()=" + hit.getSourceAsString());
// for (String fieldName : hit.fields().keySet()) {
// resultJson.accumulate(fieldName, hit.getFields().get(fieldName).getValue());
// }
// list.add(resultJson.toString());
// break;
// }
}
// System.out.println("hits.length = " + hits.length);
return list;
}
/***
* ES的读取方法
*
* @param queryBean QueryBean
* @param host ES服务地址
* @return list中封装的为json字符串
*/
public List<Map<String, Object>> readToMapList(QueryBean queryBean, String host) {
String routing = null;
return readToMapList(queryBean, routing, host);
}
/***
* ES的读取方法
*
* @param queryBean QueryBean
* @param routing ES routing,如果值是null,ES会默认使用id字段。
* @param host ES服务地址
* @return list中封装的为json字符串
*/
public List<Map<String, Object>> readToMapList(QueryBean queryBean, String routing, String host) {
JSONObject jsonObject = JSONObject.fromObject(convert(queryBean));
if (!jsonObject.containsKey("searchtype")) {
jsonObject.accumulate("searchtype", DEFAULT_SEARCH_TYPE);
}
// 如果routing不为空并且jsonObject里没有routing时,就进行设置。
if (routing != null && !jsonObject.containsKey("routing")) {
jsonObject.accumulate("routing", routing);
}
List<Map<String, Object>> list = new ArrayList<>();
SearchResponse searchResponse = search(jsonObject, host);
if (searchResponse != null) {
SearchHits searchHits = searchResponse.getHits();
for (SearchHit searchHit : searchHits) {
Map<String, Object> map = new HashMap<>();
map.put("_index", searchHit.getIndex());
map.put("_type", searchHit.getType());
map.put("_source", searchHit.getSource());
map.put("_id", searchHit.getId());
list.add(map);
}
}
return list;
}
/***
* 数据更新
*
* @param index 索引名称
* @param id "_id"值
* @param fieldNames 字段名列表。表示要更新的字段。
* @param fieldValues 字段值列表。表示要更新的值。
* @param host ES服务地址
* @return 更新是否成功
*/
public boolean update(String index, String id, List<String> fieldNames, List<String> fieldValues, String host) {
return update(index, DEFAULT_SEARCH_TYPE, id, fieldNames, fieldValues, host);
}
/***
* 删除数据
*
* @param index 索引名称
* @param fieldNames 过滤字段
* @param fieldValues 过滤字段。值要跟fieldNames对应。
* @param host host
* @return 删除结果
*/
public long deleteData(String index, List<String> fieldNames, List<String> fieldValues, String host) {
return deleteData(index, fieldNames, fieldValues, host);
}
/***
* 批量精确查询数据
*
* @param index 索引名称
* @param fieldName 过滤字段
* @param fieldValues 过滤字段。值要跟fieldNames对应。
* @param host host
* @return 删除结果
*/
public List<Map<String, Object>> termsData(String index, String fieldName, List<String> fieldValues, List<String> returnFields, String host) {
return termsData(index, fieldName, fieldValues, returnFields, host);
}
/***
* 删除数据
*
* @param index 索引名称
* @param fieldNames 过滤字段
* @param fieldValues 过滤字段。值要跟fieldNames对应。
* @param host host
* @return 删除结果
*/
public long bathDeleteData(String index, List<String> fieldNames, List<String> fieldValues, String host) {
return bathDeleteData(index, fieldNames, fieldValues, host);
}
/***
* 删除数据
*
* @param index 索引名称
* @param ids
* @param host host
* @return 删除结果
*/
public long bulkDeleteData(String index, List<String> ids, String host) {
return bulkDeleteData(index, ids, host);
}
/***
* 删除索引
*
* @param indexToDelete 索引
* @param host ES服务地址
*/
public void deleteIndex(String indexToDelete, String host) {
deleteIndex(indexToDelete, host);
}
/***
* 将querybean转化为Map对象
*
* @param querybean querybean
* @return Map对象
*/
protected Map<String, Object> convert(Object querybean) {
Map<String, Object> returnMap = new HashMap<>();
Class clazz = querybean.getClass(); // 获取类名
try {
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor descriptor : propertyDescriptors) {
String propertyName = descriptor.getName();
if (!propertyName.equals("class")) {
Method readMethod = descriptor.getReadMethod();
Object result = readMethod.invoke(querybean);
if (result != null) { // 属性为null时,不加载至返回参数
returnMap.put(propertyName, result);
} // if
} // if
} // for
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return returnMap;
}
/**
* 获取索引
*
* @return 索引
*/
public String getIndex() {
return this.index;
}
/***
* 设置写入的索引名称
*
* @param index 索引
*/
public void setIndex(String index) {
this.index = index;
}
/**
* 获取Type
*
* @return Type
*/
public String getType() {
return this.type;
}
/***
* 设置写入数据的type属性值
*
* @param type Type
*/
public void setType(String type) {
this.type = type;
}
}
package com.dituhui.mp.district.util.elasticsearch.bean;
import java.util.Map;
/**
* elasticsearch 查询参数bean
*
* @author wangjian@supermap.com
*
*/
public class QueryBean {
/**
* 查询过滤条件,key为数据属性名,value为值集
*/
private Map<String, Object> term;
/**
* 返回字段
*/
private String[] returnFields;
/**
* 排序字段
*/
private String[] orderFields;
/**
* 排序顺序
*/
private String sortOrder;
/**
* 查询索引,必须有值
*/
private String index;
/**
* 查询type
*/
private String type;
/**
* 查询结果起点数定义,默认值是null,代表从第0个记录开始。
*/
private String from;
/**
* 查询结果数定义,默认值是null,代表返回10个记录。
*/
private String size;
/**
* 执行检索的类别 ,可选值集为 0、1、2、3、4、5,默认为 1.
*/
private String searchtype;
/**
* 获取执行检索的类别
*
* @return 执行检索的类别
*/
public String getSearchtype() {
return searchtype;
}
/**
* 设置 执行检索的类别 ,可选值集为 0到5,默认值为1。
* 0 - DFS_QUERY_THEN_FETCH
* 查询是针对所有的块执行的,但返回的是足够的信息,而不是文档内容"Document"。
* 这对于有许多块的index来说是很便利的,返回结果不会有重复的,因为块被分组了;
* 1 - QUERY_THEN_FETCH
* 最原始(也可能是最快的)实现就是简单的在所有相关的shard上执行检索并返回结果。
* 2 - DFS_QUERY_AND_FETCH
* 与QUERY_THEN_FETCH相同,预期一个初始的散射相伴用来为更准确的score计算分配了的term频率。
* 3 - QUERY_AND_FETCH
* 与QUERY_AND_FETCH相同,预期一个初始的散射相伴用来为更准确的score计算分配了的term频率。
* 4 - SCAN
* 在执行了没有进行任何排序的检索时执行浏览。此时将会自动的开始滚动结果集。
* 5 - COUNT
* 只计算结果的数量,也会执行facet。
*
* @param searchtype 执行检索的类别
*/
public void setSearchtype(String searchtype) {
this.searchtype = searchtype;
}
/**
* 获取查询条件
*
* @return 查询条件
*/
public Map<String, Object> getTerm() {
return term;
}
/**
* 设置查询条件
*
* @param term 查询条件
*/
public void setTerm(Map<String, Object> term) {
this.term = term;
}
/**
* 获取返回字段
*
* @return 返回字段
*/
public String[] getReturnFields() {
return returnFields;
}
/**
* 设置返回字段
*
* @param returnFields 返回字段
*/
public void setReturnFields(String[] returnFields) {
this.returnFields = returnFields;
}
/**
* 获取排序字段
*
* @return 排序字段
*/
public String[] getOrderFields() {
return orderFields;
}
/**
* 设置排序字段
*
* @param orderFields 排序字段
*/
public void setOrderFields(String[] orderFields) {
this.orderFields = orderFields;
}
/**
* 获取排序顺序
*
* @return 排序顺序
*/
public String getSortOrder() {
return sortOrder;
}
/**
* 设置排序顺序
*
* @param sortOrder 排序顺序
*/
public void setSortOrder(String sortOrder) {
this.sortOrder = sortOrder;
}
/**
* 获取查询索引
*
* @return 查询索引
*/
public String getIndex() {
return index;
}
/**
* 设置查询索引,多个索引之间使用逗号隔开,如:"index1,index2,index3"
*
* @param index 查询索引
*/
public void setIndex(String index) {
this.index = index;
}
/**
* 获取type属性内容
*
* @return type属性内容
*/
public String getType() {
return type;
}
/***
* 设置查询的type属性内容
*
* @param type type属性内容
*/
public void setType(String type) {
this.type = type;
}
/**
* 获取查询结果起点数
*
* @return 查询结果起点数
*/
public String getFrom() {
return from;
}
/***
* 设置查询结果起点数
*
* @param from 查询结果起点数
*/
public void setFrom(String from) {
this.from = from;
}
/**
* 获取查询结果集大小
*
* @return 查询结果集大小
*/
public String getSize() {
return size;
}
/***
* 设置查询结果集大小
*
* @param size 查询结果集大小
*/
public void setSize(String size) {
this.size = size;
}
}
package com.dituhui.mp.district.vo;
import com.dituhui.mp.district.util.Point;
import org.apache.log4j.Logger;
import java.io.Serializable;
/**
* 行政区
*
* @author liweigu
*
*/
public class District implements Serializable {
private static final long serialVersionUID = 64758112170112590L;
private static final Logger LOGGER = Logger.getLogger(District.class);
private String admincode;
private String towncode;
private String name;
private SubNames subNames;
private String fullName;
private String abbreviation;
private String level = "0";
private String aCode;
private String zipcode;
private Point govPosition;
public static final String SZG = "ShengZhiGuan";
/**
* 构造函数。对于发布服务必须要显示定义构造函数。
*/
public District() {
}
/**
* 构造函数。对于发布服务必须要显示定义构造函数。
*/
public District(District district) {
if (district != null) {
this.setAdmincode(district.admincode);
this.setTowncode(district.towncode);
this.setName(district.name);
this.setFullName(district.fullName);
this.setAbbreviation(district.abbreviation);
this.setLevel(district.level);
this.setACode(district.aCode);
this.setZipcode(district.getZipcode());
this.setSubNames(district.subNames);
this.setGovPosition(district.govPosition);
}
}
/**
* 获取行政区级别。1代表省级,2代表市级,3代表区县级,4代表乡镇级,0代表未赋值。
*
* @return 行政区级别
*/
public String getLevel() {
return this.level;
}
/**
* 设置行政区级别。1代表省级,2代表市级,3代表区县级,4代表乡镇级。
*
* @param level 行政区级别
*/
public void setLevel(String level) {
this.level = level;
}
/**
* 获取行政区编码
*
* @return 获取行政区编码
*/
public String getAdmincode() {
return this.admincode;
}
/**
* 计算数值型的行政区编码
*
* @return 获取数值型的行政区编码
*/
public int caculateAdmincode() {
int i = -1;
if (this.admincode != null && this.admincode.length() > 0) {
String s = this.admincode;
if (s.endsWith(District.SZG)) {
s = s.replaceAll(District.SZG, "");
}
try {
i = Integer.parseInt(s);
} catch (Exception e) {
LOGGER.debug("admincode=" + this.admincode + ",s=" + s);
}
}
return i;
}
/**
* 设置行政区编码
*
* @param admincode 行政区编码
*/
public void setAdmincode(String admincode) {
this.admincode = admincode;
}
/**
* 获取行政区名称
*
* @return 行政区名称
*/
public String getName() {
return this.name;
}
/**
* 设置行政区名称
*
* @param name 行政区名称
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取行政区全名
*
* @return 行政区全名
*/
public String getFullName() {
return fullName;
}
/**
* 设置行政区全名
*
* @param fullName 行政区全名
*/
public void setFullName(String fullName) {
this.fullName = fullName;
}
/**
* 获取行政区简称
*
* @return 行政区简称。如果值为null则返回空字符串。
*/
public String getAbbreviation() {
return abbreviation == null ? "" : abbreviation;
}
/**
* 设置行政区简称
*
* @param abbreviation 行政区简称
*/
public void setAbbreviation(String abbreviation) {
this.abbreviation = abbreviation;
}
/**
* 返回区号
*
* @return 区号
*/
public String getACode() {
return aCode;
}
/**
* 设置区号
*
* @param aCode 区号
*/
public void setACode(String aCode) {
this.aCode = aCode;
}
/**
* 构造函数
*
* @param admincode 行政区编码
* @param name 行政区名称
*/
public District(String admincode, String name) {
this.admincode = admincode;
this.name = name;
}
@Override
public String toString() {
return "District{" +
"admincode='" + admincode + '\'' +
", towncode='" + towncode + '\'' +
", name='" + name + '\'' +
", subNames=" + subNames +
", fullName='" + fullName + '\'' +
", abbreviation='" + abbreviation + '\'' +
", level='" + level + '\'' +
", aCode='" + aCode + '\'' +
", zipcode='" + zipcode + '\'' +
", govPosition=" + govPosition +
'}';
}
/**
* 拷贝对象
*
* @return 行政区
*/
public District copy() {
District district = new District();
district.setAdmincode(this.admincode);
district.setTowncode(this.towncode);
district.setName(this.name);
district.setFullName(this.fullName);
district.setAbbreviation(this.abbreviation);
district.setLevel(this.level);
district.setACode(this.aCode);
district.setZipcode(this.zipcode);
district.setSubNames(this.subNames);
district.setGovPosition(this.govPosition);
return district;
}
/**
* 返回分级名称
*
* @return 分级名称
*/
public SubNames getSubNames() {
return subNames;
}
/**
* 设置分级名称
*
* @param subNames 分级名称
*/
public void setSubNames(SubNames subNames) {
this.subNames = subNames;
}
/**
* 返回政府所在位置
*
* @return 政府所在位置
*/
public Point getGovPosition() {
return govPosition;
}
/**
* 设置政府所在位置
*
* @param govPosition 政府所在位置
*/
public void setGovPosition(Point govPosition) {
this.govPosition = govPosition;
}
/**
* 返回邮编
*
* @return 邮编
*/
public String getZipcode() {
return zipcode;
}
/**
* 设置邮编
*
* @param zipcode 邮编
*/
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
/**
* 返回12位行政区编码
*
* @return 12位行政区编码
*/
public String getTowncode() {
return towncode;
}
/**
* 设置12位行政区编码
*
* @param towncode 12位行政区编码
*/
public void setTowncode(String towncode) {
this.towncode = towncode;
}
}
package com.dituhui.mp.district.vo;
import java.io.Serializable;
/**
* 行政区字典项
*
* @author liweigu
*
*/
public class DistrictDictItem implements Serializable {
private static final long serialVersionUID = -2196115508928205845L;
/**
* 默认用户Key
*/
public static final String DEFAULT_USER_KEY = "00000000000000000000000000000000";
private String userKey;
private int version;
private String desc;
private String esIndex;
/**
* 获取用户Key
*
* @return 用户Key
*/
public String getUserKey() {
return userKey;
}
/**
* 设置用户Key
*
* @param userKey 用户Key
*/
public void setUserKey(String userKey) {
this.userKey = userKey;
}
/**
* 获取数据版本
*
* @return 数据版本
*/
public int getVersion() {
return version;
}
/**
* 设置数据版本
*
* @param version 数据版本
*/
public void setVersion(int version) {
this.version = version;
}
/**
* 获取数据描述
*
* @return 数据描述
*/
public String getDesc() {
return desc;
}
/**
* 设置数据描述
*
* @param desc 数据描述
*/
public void setDesc(String desc) {
this.desc = desc;
}
/**
* 返回ES索引
*
* @return ES索引
*/
public String getEsIndex() {
return esIndex;
}
/**
* 设置ES索引
*
* @param esIndex ES索引
*/
public void setEsIndex(String esIndex) {
this.esIndex = esIndex;
}
}
package com.dituhui.mp.district.vo;
import javax.swing.plaf.synth.Region;
import java.io.Serializable;
import java.util.List;
/**
* 行政区信息
*
* @author liweigu
*
*/
public class DistrictInfo extends DistrictRegion implements Serializable {
private static final long serialVersionUID = 2653344739528623544L;
private String parentAdmincode;
private String alias;
private Region mktRegion;
private Region baiduRegion;
private List<District> childDistricts;
private List<Region> childRegions;
private List<Region> childMktRegions;
private List<Region> childBaiduRegions;
private String custom;
/**
* 获取子百度区域
*
* @return 子百度区域
*/
public List<Region> getChildBaiduRegions() {
return childBaiduRegions;
}
/**
* 设置子百度区域
*
* @param childBaiduRegions 子百度区域
*/
public void setChildBaiduRegions(List<Region> childBaiduRegions) {
this.childBaiduRegions = childBaiduRegions;
}
/**
* 获取子墨卡托区域
*
* @return 子墨卡托区域
*/
public List<Region> getChildMktRegions() {
return childMktRegions;
}
/**
* 设置子墨卡托区域
*
* @param childMktRegions 子墨卡托区域
*/
public void setChildMktRegions(List<Region> childMktRegions) {
this.childMktRegions = childMktRegions;
}
/**
* 获取父行政区编码
*
* @return 父行政区编码
*/
public String getParentAdmincode() {
return parentAdmincode;
}
/**
* 设置父行政区编码
*
* @param parentAdmincode 父行政区编码
*/
public void setParentAdmincode(String parentAdmincode) {
this.parentAdmincode = parentAdmincode;
}
/**
* 获取别名
*
* @return 别名
*/
public String getAlias() {
return alias;
}
/**
* 设置别名
*
* @param alias 别名
*/
public void setAlias(String alias) {
this.alias = alias;
}
/**
* 获取墨卡托区域
*
* @return 墨卡托区域
*/
public Region getMktRegion() {
return mktRegion;
}
/**
* 设置墨卡托区域
*
* @param mktRegion 墨卡托区域
*/
public void setMktRegion(Region mktRegion) {
this.mktRegion = mktRegion;
}
/**
* 获取百度区域
*
* @return 百度区域
*/
public Region getBaiduRegion() {
return baiduRegion;
}
/**
* 设置百度区域
*
* @param baiduRegion 百度区域
*/
public void setBaiduRegion(Region baiduRegion) {
this.baiduRegion = baiduRegion;
}
/**
* 获取子行政区
*
* @return 子行政区
*/
public List<District> getChildDistricts() {
return childDistricts;
}
/**
* 设置子行政区
*
* @param childDistricts 子行政区
*/
public void setChildDistricts(List<District> childDistricts) {
this.childDistricts = childDistricts;
}
/**
* 获取子区域
*
* @return 子区域
*/
public List<Region> getChildRegions() {
return childRegions;
}
/**
* 设置子区域
*
* @param childRegions 子区域
*/
public void setChildRegions(List<Region> childRegions) {
this.childRegions = childRegions;
}
/**
* 获取自定义属性
*
* @return 自定义属性
*/
public String getCustom() {
return custom;
}
/**
* 设置自定义属性
*
* @param custom 自定义属性
*/
public void setCustom(String custom) {
this.custom = custom;
}
/**
* 构造函数
*
* @param adminCode 行政区编码
* @param name 行政区名称
*/
public DistrictInfo(String adminCode, String name) {
super(adminCode, name);
}
}
package com.dituhui.mp.district.vo;
import com.dituhui.mp.district.util.Point;
import com.dituhui.mp.district.util.Region;
import org.apache.log4j.Logger;
import java.io.Serializable;
/**
* 行政区边界
*
* @author liweigu
*
*/
public class DistrictRegion extends District implements Serializable {
private static final long serialVersionUID = 3501735587653063069L;
private static final Logger LOGGER = Logger.getLogger(DistrictRegion.class);
private Region region;
private Point center;
/**
* 构造函数。对于发布服务必须要显示定义构造函数。
*/
public DistrictRegion() {
super();
}
/**
* 返回行政区边界
*
* @return 行政区边界
*/
public Region getRegion() {
return region;
}
/**
* 设置行政区边界
*
* @param region 行政区边界
*/
public void setRegion(Region region) {
this.region = region;
}
/**
* 构造函数
*
* @param district 行政区
*/
public DistrictRegion(District district) {
super(district.getAdmincode(), district.getName());
}
/**
* 构造函数
*
* @param admincode 行政区编码
* @param name 行政区名称
*/
public DistrictRegion(String admincode, String name) {
super(admincode, name);
}
/**
* 构造函数
*
* @param adminCode 行政区编码
* @param name 行政区名称
* @param region 行政区边界
*/
public DistrictRegion(String adminCode, String name, Region region) {
super(adminCode, name);
this.region = region;
}
/**
* 返回中心点
*
* @return 中心点
*/
public Point getCenter() {
return this.center;
}
/**
* 设置中心点
*
* @param center 中心点
*/
public void setCenter(Point center) {
this.center = center;
}
}
package com.dituhui.mp.district.vo;
/**
* 行政区查询结果
*
* @author liweigu
*
*/
public class DistrictResult {
private static final long serialVersionUID = -6912829559552611277L;
private District district;
/**
* 返回行政区
*
* @return 行政区
*/
public District getDistrict() {
return district;
}
/**
* 设置行政区
*
* @param district 行政区
*/
public void setDistrict(District district) {
this.district = district;
}
}
package com.dituhui.mp.district.vo;
import java.util.List;
/**
* 行政区列表查询结果
*
* @author liweigu
*
*/
public class DistrictsResult {
private static final long serialVersionUID = -6912829559552611277L;
private List<? extends District> districts;
/**
* 返回行政区列表
*
* @return 行政区列表
*/
public List<? extends District> getDistricts() {
return districts;
}
/**
* 设置行政区列表
*
* @param districts 行政区列表
*/
public void setDistricts(List<? extends District> districts) {
this.districts = districts;
}
}
package com.dituhui.mp.district.vo;
import java.io.Serializable;
/**
* 行政区级别
*
* @author liweigu
*
*/
public class Level implements Serializable {
private static final long serialVersionUID = 2745188660341776676L;
/**
* 省级。值为1。
*/
public static final String PROVICE_LEVEL = "1";
/**
* 市级。值为2。
*/
public static final String CITY_LEVEL = "2";
/**
* 区县级。值为3。
*/
public static final String COUNTY_LEVEL = "3";
/**
* 乡镇级。值为4。
*/
public static final String TOWN_LEVEL = "4";
}
package com.dituhui.mp.district.vo;
import java.io.Serializable;
/**
* 行政区子名称
*
* @author liweigu
*
*/
public class SubNames implements Serializable {
private static final long serialVersionUID = -4339833085455676700L;
private String province;
private String city;
private String county;
private String town;
/**
* 返回省
*
* @return 省
*/
public String getProvince() {
return province;
}
/**
* 设置省
*
* @param province 省
*/
public void setProvince(String province) {
this.province = province;
}
/**
* 返回市
*
* @return 市
*/
public String getCity() {
return city;
}
/**
* 设置市
*
* @param city 市
*/
public void setCity(String city) {
this.city = city;
}
/**
* 返回区县
*
* @return 区县
*/
public String getCounty() {
return county;
}
/**
* 设置区县
*
* @param county 区县
*/
public void setCounty(String county) {
this.county = county;
}
/**
* 返回乡镇
*
* @return 乡镇
*/
public String getTown() {
return town;
}
/**
* 设置乡镇
*
* @param town 乡镇
*/
public void setTown(String town) {
this.town = town;
}
@Override
public String toString() {
return "SubNames{" +
"province='" + province + '\'' +
", city='" + city + '\'' +
", county='" + county + '\'' +
", town='" + town + '\'' +
'}';
}
/**
* hashCode方法
*
* @return hashCode
*/
@Override
public int hashCode() {
return this.toString().hashCode();
}
}
server:
port: 8003
spring:
application:
name: project-district
serverlet:
encoding:
charset: utf-8
force: true
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
server-addr: nacos-server:8848
group: project
config:
server-addr: nacos-server:8848
group: project
file-extension: yaml
# DistrictService es配置
district:
es:
host: 121.37.145.153:52302
cluster:
name: openapi-cluster
dict:
name: district_dict
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
<!-- Example for logging into the build folder of your project -->
<property name="LOG_FILE" value="logs/${springAppName}"/>
<!-- You can override this to have a custom pattern -->
<property name="CONSOLE_LOG_PATTERN"
value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!-- Appender to log to console -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!-- Minimum logging level to be presented in the console logs-->
<level>DEBUG</level>
</filter>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!-- Appender to log to file -->
<appender name="flatfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.gz</fileNamePattern>
<maxHistory>7</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="console"/>
<!-- uncomment this to have also JSON logs
<appender-ref ref="logstash"/> -->
<!--<appender-ref ref="flatfile"/>-->
</root>
</configuration>
\ No newline at end of file
package com.dituhui.mp.district.test;
import static org.junit.Assert.assertTrue;
import com.dituhui.mp.enums.CoordTypeEnum;
import org.junit.Test;
/**
* Unit test for simple App.
*/
public class AppTest {
@Test
public void demoTest() {
assertTrue(true);
}
@Test
public void name() {
System.out.println(CoordTypeEnum.valueOf("gg"));
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!