gitweixin
  • 首页
  • 小程序代码
    • 资讯读书
    • 工具类
    • O2O
    • 地图定位
    • 社交
    • 行业软件
    • 电商类
    • 互联网类
    • 企业类
    • UI控件
  • 大数据开发
    • Hadoop
    • Spark
    • Hbase
    • Elasticsearch
    • Kafka
    • Flink
    • 数据仓库
    • 数据挖掘
    • flume
    • Kafka
    • Hive
    • shardingsphere
    • solr
  • 开发博客
    • Android
    • php
    • python
    • 运维
    • 技术架构
    • 数据库
  • 程序员网赚
  • bug清单
  • 量化投资
  • 在线查询工具
    • 去行号
    • 在线时间戳转换工具
    • 免费图片批量修改尺寸在线工具
    • SVG转JPG在线工具
    • SVG转PDF/Word
    • SVG转Draw.io可二次编辑格式
    • js代码混淆

分类归档大数据开发

精品微信小程序开发门户,代码全部亲测可用

  • 首页   /  
  • 分类归档: "大数据开发"
  • ( 页面36 )
Spark, 大数据开发 6月 25,2020

大数据利用基站或GPS推断是家和工作地

如果有某个手机用户的GPS轨迹或基站,是可以利用大数据来推断他的家和工作地。

思路应该从时空2个维度进行考虑:

1、从时间上考虑:对于一般人来说,一天最早的出发地通常是家,晚上最后的目的地通常是家。而上班的地方,普通是6-10点出发的,在17点到22点后回来的,工作地通常是停留时间很长。(可以把轨迹按天归类,并按每天时间排序,从而计算最早、最晚、白天停留时间最长的地点)





2、从空间上考虑:家和工作点应该是2个不同的聚类中心。 可以利用轨迹绘制集群中每个集群中GPS或基站数据点的时间分布。 应该可以推断出从早上9点到晚上18点,用户停留在集群1区域,而在午夜到早上8点,用户倾向于留在集群2。从而大概率推断出集群1是家,集群2是工作地(可以用 DBSCAN算法来识别此数据集中的聚类。 DBSCAN是一种聚类算法,对于聚类具有许多异常值的空间数据特别有用 )

作者 east
spring 6月 10,2020

Springboot读取excel工具类

public List<DeviceInfo> readXls() throws IOException {
InputStream is = new FileInputStream(EXCEL_PATH);
XSSFWorkbook hssfWorkbook = new XSSFWorkbook(is);
DeviceInfo student = null;
List<DeviceInfo> list = new ArrayList<DeviceInfo>();
// 循环工作表Sheet
for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) {
XSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);
if (hssfSheet == null) {
continue;
}
// 循环行Row
for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
XSSFRow hssfRow = hssfSheet.getRow(rowNum);
if(CheckRowNull(hssfRow)){
continue;
}
if (hssfRow != null) {
student = new DeviceInfo();
XSSFCell no = hssfRow.getCell(0);
no.setCellType(no.CELL_TYPE_STRING);
XSSFCell name = hssfRow.getCell(3);
XSSFCell longitude = hssfRow.getCell(1);
XSSFCell latitude = hssfRow.getCell(2);
student.setDeviceId(getValue(no));
student.setDeviceName(getValue(name));
student.setLongitude(new BigDecimal(getValue(longitude)));
student.setLatitude(new BigDecimal(getValue(latitude)));
list.add(student);
}
}
}
return list;
}

@SuppressWarnings("static-access")
private String getValue(XSSFCell hssfCell) {
if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
// 返回布尔类型的值
return String.valueOf(hssfCell.getBooleanCellValue());
} else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
// 返回数值类型的值
return String.valueOf(hssfCell.getNumericCellValue());
} else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_FORMULA) {
return String.valueOf(hssfCell.getCellFormula());
} else {
// 返回字符串类型的值
return String.valueOf(hssfCell.getStringCellValue());
}
}

//判断行为空
private boolean CheckRowNull(XSSFRow hssfRow){
Iterator<Cell> cellItr =hssfRow.iterator();
while(cellItr.hasNext()){
Cell c =cellItr.next();
if(c != null && c.getCellType() !=XSSFCell.CELL_TYPE_BLANK){
return false;
}
}
return true;
}

作者 east
大数据开发 6月 10,2020

ShardingSphere不支持的SQL操作(having等复杂统计及子查询)

在大数据时代,面对海量数据存储和处理,除了nosql方案外,很多时候还是需要关系型数据库。mysql单表在千万级别时性能就明显下降,这时靠加索引等也难根本性解决,这时需要分库分表。shardingshpere是一款轻巧绿色的分库分表利器。不是它也是有局限性,下面是它不支持的sql操作。


路由至多数据节点

不支持CASE WHEN、HAVING、UNION (ALL),有限支持子查询。

除了分页子查询的支持之外(详情请参考分页),也支持同等模式的子查询。无论嵌套多少层,ShardingSphere都可以解析至第一个包含数据表的子查询,一旦在下层嵌套中再次找到包含数据表的子查询将直接抛出解析异常。

例如,以下子查询可以支持:

SELECT COUNT(*) FROM (SELECT * FROM t_order o)

以下子查询不支持:

SELECT COUNT(*) FROM (SELECT * FROM t_order o WHERE o.id IN (SELECT id FROM t_order WHERE status = ?))

简单来说,通过子查询进行非功能需求,在大部分情况下是可以支持的。比如分页、统计总数等;而通过子查询实现业务查询当前并不能支持。

由于归并的限制,子查询中包含聚合函数目前无法支持。

不支持包含schema的SQL。因为ShardingSphere的理念是像使用一个数据源一样使用多数据源,因此对SQL的访问都是在同一个逻辑schema之上。

对分片键进行操作

运算表达式和函数中的分片键会导致全路由。

假设create_time为分片键,则无法精确路由形如SQL:

SELECT * FROM t_order WHERE to_date(create_time, 'yyyy-mm-dd') = '2019-01-01';

由于ShardingSphere只能通过SQL字面提取用于分片的值,因此当分片键处于运算表达式或函数中时,ShardingSphere无法提前获取分片键位于数据库中的值,从而无法计算出真正的分片值。

当出现此类分片键处于运算表达式或函数中的SQL时,ShardingSphere将采用全路由的形式获取结果。

示例

支持的SQL

SQL必要条件
SELECT * FROM tbl_name
SELECT * FROM tbl_name WHERE (col1 = ? or col2 = ?) and col3 = ?
SELECT * FROM tbl_name WHERE col1 = ? ORDER BY col2 DESC LIMIT ?
SELECT COUNT(*), SUM(col1), MIN(col1), MAX(col1), AVG(col1) FROM tbl_name WHERE col1 = ?
SELECT COUNT(col1) FROM tbl_name WHERE col2 = ? GROUP BY col1 ORDER BY col3 DESC LIMIT ?, ?
INSERT INTO tbl_name (col1, col2,…) VALUES (?, ?, ….)
INSERT INTO tbl_name VALUES (?, ?,….)
INSERT INTO tbl_name (col1, col2, …) VALUES (?, ?, ….), (?, ?, ….)
UPDATE tbl_name SET col1 = ? WHERE col2 = ?
DELETE FROM tbl_name WHERE col1 = ?
CREATE TABLE tbl_name (col1 int, …)
ALTER TABLE tbl_name ADD col1 varchar(10)
DROP TABLE tbl_name
TRUNCATE TABLE tbl_name
CREATE INDEX idx_name ON tbl_name
DROP INDEX idx_name ON tbl_name
DROP INDEX idx_name
SELECT DISTINCT * FROM tbl_name WHERE col1 = ?
SELECT COUNT(DISTINCT col1) FROM tbl_name

不支持的SQL

SQL不支持原因
INSERT INTO tbl_name (col1, col2, …) VALUES(1+2, ?, …)VALUES语句不支持运算表达式
INSERT INTO tbl_name (col1, col2, …) SELECT col1, col2, … FROM tbl_name WHERE col3 = ?INSERT .. SELECT
SELECT COUNT(col1) as count_alias FROM tbl_name GROUP BY col1 HAVING count_alias > ?HAVING
SELECT * FROM tbl_name1 UNION SELECT * FROM tbl_name2UNION
SELECT * FROM tbl_name1 UNION ALL SELECT * FROM tbl_name2UNION ALL
SELECT * FROM ds.tbl_name1包含schema
SELECT SUM(DISTINCT col1), SUM(col1) FROM tbl_name详见DISTINCT支持情况详细说明
SELECT * FROM tbl_name WHERE to_date(create_time, ‘yyyy-mm-dd’) = ?会导致全路由

DISTINCT支持情况详细说明

支持的SQL

SQL
SELECT DISTINCT * FROM tbl_name WHERE col1 = ?
SELECT DISTINCT col1 FROM tbl_name
SELECT DISTINCT col1, col2, col3 FROM tbl_name
SELECT DISTINCT col1 FROM tbl_name ORDER BY col1
SELECT DISTINCT col1 FROM tbl_name ORDER BY col2
SELECT DISTINCT(col1) FROM tbl_name
SELECT AVG(DISTINCT col1) FROM tbl_name
SELECT SUM(DISTINCT col1) FROM tbl_name
SELECT COUNT(DISTINCT col1) FROM tbl_name
SELECT COUNT(DISTINCT col1) FROM tbl_name GROUP BY col1
SELECT COUNT(DISTINCT col1 + col2) FROM tbl_name
SELECT COUNT(DISTINCT col1), SUM(DISTINCT col1) FROM tbl_name
SELECT COUNT(DISTINCT col1), col1 FROM tbl_name GROUP BY col1
SELECT col1, COUNT(DISTINCT col1) FROM tbl_name GROUP BY col1

不支持的SQL

SQL不支持原因
SELECT SUM(DISTINCT col1), SUM(col1) FROM tbl_name同时使用普通聚合函数和DISTINCT聚合函数


作者 east
Java 6月 10,2020

千万级别数据实时复杂统计效率优化

有个业务需求:千万级别数据,要根据位置、白天出现时间、晚上不出现时间,出现次数大于某个范围的复杂组合统计。

mysql在千万级别的数据时,查询效率就有明细的下降。而时间数据从上千万级上升到上亿级,查询效率很慢,等待很久。

除了加索引等常规优化,想到用
shardingsphere 来分库分表,调研之后,发现
shardingsphere 不支持having等统计查询,对子查询支持也不是非常友好。后来发现这些数据,大部分数据其实是很难用到到,因为业务要统计大于多少次的,并按次数倒序,于是把那些出现次数少的进行删除,数据一下降到百万级别的,查询效率明细提升。

优化不光是考虑技术上的,一些技术难做到的,还要结合业务进行优化。

作者 east
bug清单, Hbase 6月 10,2020

华为FusionInsight HD集群Can’t get Kerberos realm

华为FusionInsight HD采用安全登录认证的方式,但是一直报Can’t get kerberos realm的错误,反复检查hbase的安全认证没问题,但线上运行就会时不时出现这个问题。

经过反复对比排查,发现是另个地方redis,也用到安全认证,但把配置文件写错导致失败。而想不到的是,redis安全认证失败,也导致了hbase这里安全认证失败。

作者 east
spring 6月 10,2020

Mybatis的and拼接问题

在具体业务开发中,有些业务涉及到多个可选的查询条件,例如要查询白天出现的时间段,晚上不出现时间段,这就涉及多个and拼接问题。

<select id="listSelectAll">
        select * from ***
        where 
        <if test="a!= null">
            a = #{a}
        </if>
        <if test="b!= null">
            and b = #{b}
            </foreach>
        </if>
        <if test="c!= null">
            and c = #{c}
        </if>
            order by id desc
            limit #{limit} offset #{page}
</select>

这样写的错误是如果a==null那么第二个条件中就会多一个and,语句会变成select * from *** where and b =#{b},而如果条件全都不满足的话SQL会变成select * from *** where order by id desc limit…解决办法:加上<where>标签,如下:

<select id="listSelectAll">
        select * from ***
       <where>
        <if test="a!= null">
            a = #{a}
        </if>
        <if test="b!= null">
            and b = #{b}
            </foreach>
        </if>
        <if test="c!= null">
            and c = #{c}
        </if>
        </where>
            order by id desc
            limit #{limit} offset #{page}
</select>

如上代码所示,加上一个<where>标签即可,where标签会自动识别,如果前面条件不满足的话,会自己去掉and。

作者 east
Java, spring 5月 31,2020

分库分表利器sharding-sphere入门学习资料


当mysql达到单表1千万数据以上时,性能就下降得厉害,添加索引等方式还是不能根本解决问题,需要进行分库分表。sharding-sphere是开源的分布式数据库中间件解决方案 ,只需要开发人员像添加普通jar依赖一样添加依赖,不需要运维人员额外配置。是一个轻量级、性能较好的解决方案。但sharding-sphere学习资料较少,下面推荐一下入门学习资料。

学习视频https://www.bilibili.com/video/BV1rJ411n7QH

官网

官网是必须要学习的一手材料。

http://shardingjdbc.io/

Github

https://github.com/sharding-sphere

很好入门例子:https://github.com/yudiandemingzi/spring-boot-sharding-sphere

作者 east
Java 5月 30,2020

springboot如何多线程异步执行定时任务

 在后台开发时,经常需要执行后台任务,相比使用quartz等复杂定时框架,使用springboot自带定时框架,能简单轻松满足大部分定时任务。

工具/原料

  • 已经配置好springboot依赖

方法/步骤

  1. 创建一个后台定时任务的类,并标明@Component标注。创建一个普通方式,加上@Scheduled标注,例如:@Scheduled(cron = “0 27 10 * * ?”)

2.在Scheduled标注加上cron的定时标注。cron的6或7个字段从前到后对应的是: 秒 分钟 小时 日期 月份 星期 年例如:要每天10点27分执行   @Scheduled(cron = “0 27 10 * * ?”)每小时执行1次            @Scheduled(cron = “0 0 0/1 * * ?”)


3.在启动类BootApplication添加@EnableScheduling标注,这时定时任务就可以执行了。完成了上面3步,如果有多个定时任务,这时是串行的,只有前面1个定时任务执行完,后面的定时任务才能执行。要异步执行,首先在在启动类BootApplication添加@EnableAsync标注

4.在定时任务执行方法上添加@Async标注

5.添加多线程配置类,设置线程池并发个数等。


@Configuration
@EnableAsync
public class SpringAsycConfigurer implements AsyncConfigurer {

@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(12);
executor.setMaxPoolSize(20);
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds( 60 * 15);
executor.setThreadNamePrefix("MyAsync-");
executor.initialize();
return executor;
}

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
作者 east
Hbase 5月 24,2020

hbase常用查询命令

根据rowKey查询某个记录

get <table>,<rowkey>,[<family:column>,….]

get ‘User’, ‘row2’


查询所有记录

(1)正序扫描

scan <table>, {COLUMNS => [ <family:column>,…. ], LIMIT => num}

scan ‘User’

(2)倒序扫描

scan ‘table’, {REVERSED => TRUE}

(3)扫描前2条

scan ‘User’, {LIMIT => 2}

(4)范围查询

scan ‘User’, {STARTROW => ‘row2’, ENDROW => ‘row2’}

作者 east
bug清单, Java, spring 5月 24,2020

MyBaits 无法打印sql,日志冲突解决

springboot的mybatis之前能打印出日志,后来一直没打印,不方便调试。刚开始以为是设置问题,但application.yml已经设置开启了。

logging:
level:
com:
xxx:
xxx:
mapper: debug

后来怀疑是加入了别的日志jar包,日志冲突。然后搜索这方面关键字找到解决方案。

对于不同日志框架:SLF4J、 Apache Commons Logging、 Log4j 2、 Log4j
JDK logging 具体选择哪个日志实现由MyBatis的内置日志工厂确定。它会使用最先找到的(按上文列举的顺序查找)。 如果一个都未找到,日志功能就会被禁用。
因此当您的maven工程中引入了SLF4J-API和Log4J, 而您使用Log4j.properties进行日志配置时,便无法打印sql语句到控制台,按照优先级他会先选择使用SLF4J





<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.6</version>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
</dependency>
<!-- 添加该jar, 解决MyBaits 无法打印sql语句到控制台, -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.6</version>
</dependency>

然后修改log4j.properties


###显示SQL语句部分
# MyBatis logging configuration...
log4j.logger.cn.com.softvan.cms.dao=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
### mybatis loggers ###
log4j.logger.com.ibatis=DEBUG,stdout
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG,stdout
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG,stdout
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG,stdout
# sql loggers
log4j.logger.java.sql.Connection=DEBUG,stdout
log4j.logger.java.sql.Statement=DEBUG,stdout
log4j.logger.java.sql.PreparedStatement=DEBUG,stdout
log4j.logger.java.sql.ResultSet=DEBUG,stdout

log4j.logger.cn.com.softvan.cms.dao=TRACE 这句一定要加 不然无法打印SQL,其它的自己看情况简化

cn.com.softvan.cms.dao为包路径

作者 east
bug清单, Hadoop 4月 24,2020

namenode 日志提示 storage directory does not exist or is not accessible

移植hadoop到另一台机器,启动hadoop时,发现namenode没启动起来。检查配置文件没问题,ssh又免登录了,于是删除hadoop几个临时文件夹,重新格式化,果然就正常了。

作者 east
Java 4月 24,2020

空间几何运算方法

private static final Logger logger = LoggerFactory.getLogger(AnalyseKit.class);
/***************************************************************************
* 边界
*/
private static final double dis = 0.0000000001;
// 地图常量
public final static double _C_P = 0.017453292519943295;
// 地球经纬度, 偏差度
public final static double EARTH_RADIUS = 6371008.77141506;
// 单位经度
public static final long LONGITUDE_METER = 111413;
// 单位纬度
public static final long LATITUDE_METER = 111133;

/**
* 求亮点之间的距离
*
* @param str 坐标1
* @param str2 坐标2
* @return
*/
public static double getDistance(String str, String str2) {

PointBean point1 = new PointBean();
point1.setX(Double.parseDouble(str.split(",")[0]));
point1.setY(Double.parseDouble(str.split(",")[1]));

PointBean point2 = new PointBean();
point2.setX(Double.parseDouble(str2.split(",")[0]));
point2.setY(Double.parseDouble(str2.split(",")[1]));

double meter = getDistance(point1, point2);
return meter;
}

/**
* 计算点是否在圆内
*
* @param point 点坐标
* @param pointPolygon 面边框坐标
* @return
*/
public static boolean judgeMeetCircle(String point, String criclePoint, float r) {
PointBean point1 = new PointBean();
point1.setX(Double.parseDouble(point.split(",")[0]));
point1.setY(Double.parseDouble(point.split(",")[1]));

PointBean point2 = new PointBean();
point2.setX(Double.parseDouble(criclePoint.split(",")[0]));
point2.setY(Double.parseDouble(criclePoint.split(",")[1]));

double d = getDistance(point1, point2);
if (d <= r)
return true;
else
return false;

}

/**
* 判断是否在矩形内
*
* @param minPt
* @param maxPt
* @param pt
* @return
*/
public static boolean judgeInRect(PointBean minPt, PointBean maxPt, PointBean pt) {
if (pt.getX() >= minPt.getX() && pt.getX() <= maxPt.getX() && pt.getY() >= minPt.getY()
&& pt.getY() <= maxPt.getY()) {
return true;
} else {
return false;
}
}

/**
* 计算点是否在多边形内
*
* @param point 点坐标
* @param pointPolygon 面边框坐标
* @return
*/
public static boolean judgeMeetPolygon(String linestr, String pointPolygon) {
String string = pointPolygon;
int index = 0;
// 判断是否是飞地
if (string.indexOf(";") != -1) {
String[] points = string.split(";");
for (String point : points) {
if (AnalyseKit.judgeMeetPoint(linestr, point)) {
return true;
} else {
index++;
}
}
return (index == 0 || index > 1) ? false : true;
} else if (string.indexOf("|") != -1) {// 判断是否是有洞
String[] points = string.split("|");
for (String point : points) {
if (AnalyseKit.judgeMeetPoint(linestr, point))
index++;
}
return (index == 0 || index > 1) ? false : true;
} else {
return AnalyseKit.judgeMeetPoint(linestr, string);
}
}

// #################################私有方法#################################
private static boolean judgeMeetPoint(String point, String pointPolygon) {
PointBean point2 = new PointBean();
point2.setX(Double.parseDouble(point.split(",")[0]));
point2.setY(Double.parseDouble(point.split(",")[1]));
List<PointBean> list = AnalyseKit.evalPoints(pointPolygon);
if (list.size() == 2) {
return AnalyseKit.judgeInRect(list.get(0), list.get(1), point2);
} else {
return AnalyseKit.judgeMeetPoint(point2, list);
}
}

/**
* 转换坐标串
*
* @param points
* @return
*/
private static List<PointBean> evalPoints(String points) {
List<PointBean> list = new ArrayList<PointBean>();
String[] split = points.split(",");
for (int i = 1; i < split.length; i++) {
if (i % 2 == 1) {
PointBean point3 = new PointBean();
point3.setX(Double.parseDouble(split[i - 1]));
point3.setY(Double.parseDouble(split[i]));
list.add(point3);
}
}
return list;
}

/**
* 判断点是否在面内的算法
*
* @param tpt 点坐标
* @param polygonPtArray 面外边框坐标集合
* @return
*/
private static boolean judgeMeetPoint(PointBean tpt, List<PointBean> polygonPtArray) {
int MeetPointNum = 0;
for (int i = 1; i < polygonPtArray.size(); i++) {
PointBean pt1 = polygonPtArray.get(i - 1);
PointBean pt2 = polygonPtArray.get(i);
if (((tpt.getX() <= pt1.getX() && tpt.getX() >= pt2.getX())
|| (tpt.getX() >= pt1.getX() && tpt.getX() <= pt2.getX()))
& (tpt.getY() >= pt1.getY() || tpt.getY() >= pt2.getY())
& (pt1.getX() != pt2.getX() && pt1.getY() != pt2.getY())) {
// 判断点是否在线上
if (judgePtInLine(pt1, pt2, tpt)) {
return true;
}
// 处理特殊情况,交点是端点的情况
double temp;
// temp相当于被除数(斜率的分母)
temp = pt1.getX() - pt2.getX();
if (temp >= -dis && temp <= dis) {
// 处理交点情况
double dx = tpt.getX() - pt1.getX();
if (dx >= -dis && dx <= dis) {
int[] indexs = new int[2];
indexs[0] = 0;
indexs[1] = 0;
getNotSame(polygonPtArray, i, indexs);
PointBean linePt1, linePt2;
linePt1 = polygonPtArray.get(indexs[0]);
linePt2 = polygonPtArray.get(indexs[1]);
if (i > indexs[0]) {
break;
} else {
i = indexs[0] + 1;
}
if (tpt.getY() > pt1.getY() && ((tpt.getX() >= linePt1.getX() && tpt.getX() <= linePt2.getX())
|| (tpt.getX() >= linePt2.getX() && tpt.getX() <= linePt1.getX())))
MeetPointNum++;
}

} else {
double kk, bb;
double MeetPtY, MeetPtX;
kk = (pt1.getY() - pt2.getY()) / (pt1.getX() - pt2.getX());
bb = pt1.getY() - kk * pt1.getX();
MeetPtY = kk * tpt.getX() + bb;
MeetPtX = tpt.getX();
// 处理特殊情况,交点是端点的情况
double dx, dy, dx2, dy2;
dx = MeetPtX - pt1.getX();
dy = MeetPtY - pt1.getY();
dx2 = MeetPtX - pt2.getX();
dy2 = MeetPtY - pt2.getY();
if ((dx >= -dis && dx <= dis && dy >= -dis && dy <= dis)) {
PointBean pt3;
if (i == 1) {
pt3 = polygonPtArray.get(polygonPtArray.size() - 2);
} else {
pt3 = polygonPtArray.get(i - 2);
}
// 提取交点的上下两点分别在垂线的两侧
if (tpt.getY() > MeetPtY && ((MeetPtX >= pt3.getY() && MeetPtX <= pt2.getX())
|| (MeetPtX >= pt2.getX() && MeetPtX <= pt3.getX())))
MeetPointNum++;
} else if (!(dx2 >= -dis && dx2 <= dis && dy2 >= -dis && dy2 <= dis)) {
if (tpt.getY() > MeetPtY) {
MeetPointNum++;
}
}
}
}
}
if (MeetPointNum % 2 == 1)
return true;
else
return false;
}

/**
* 判断点是否在线上
*
* @param tpt1
* @param tpt2
* @param tpt
* @return
*/
private static boolean judgePtInLine(PointBean tpt1, PointBean tpt2, PointBean tpt) {
double dx1 = getDistance(tpt1, tpt2);
double dx2 = getDistance(tpt, tpt1);
double dx3 = getDistance(tpt, tpt2);
double dx = dx3 + dx2 - dx1;
if (dx >= -dis && dx <= dis) {
return true;
}
return false;
}

private static double getDistance(PointBean p1, PointBean p2) {
double k = 0.0;
double h = (p2.x - p1.x) * _C_P;
double g = (p2.y - p1.y) * _C_P;
double f = Math.sin(0.5 * g) * Math.sin(0.5 * g)
+ Math.cos(p1.y * _C_P) * Math.cos(p2.y * _C_P) * (Math.sin(0.5 * h) * Math.sin(0.5 * h));

f = Math.abs(f);

if (f > 1) {
logger.info("不合法数据:" + f + ",P1:" + p1.toString() + ",P2:" + p2.toString());
return -1;
}
double m = 2 * Math.atan2(Math.sqrt(f), Math.sqrt(1 - f));
k = m * EARTH_RADIUS;
if (Math.abs(p2.x - p1.x) > 180 || Math.abs(p2.y - p1.y) > 180) {
k = 2 * Math.PI * EARTH_RADIUS - k;
}
k = Math.ceil(k);

int meter = (int) k;

return meter;
}

/**
* 在链表中获取x轴不相同的点
*
* @param pointArray
* @param index
* @param indexs
*/
private static void getNotSame(List<PointBean> pointArray, int index, int[] indexs) {
indexs[0] = indexs[1] = -1;
int size = pointArray.size();
PointBean buftpt, tpt;
tpt = pointArray.get(index);
for (int i = index; i < size; i++) {
buftpt = pointArray.get(i);
if (buftpt.getX() != tpt.getX()) {
indexs[0] = i;
break;
}
}
if (indexs[0] == -1) {
for (int i = 0; i < size; i++) {
buftpt = (PointBean) pointArray.get(i);
if (buftpt.getX() != tpt.getX()) {
indexs[0] = i;
break;
}
}
}
for (int j = index; j >= 0; j--) {
buftpt = (PointBean) pointArray.get(j);
if (buftpt.getX() != tpt.getX()) {
indexs[1] = j;
break;
}
}
if (indexs[1] == -1) {
for (int j = size - 1; j >= 0; j--) {
buftpt = pointArray.get(j);
if (buftpt.getX() != tpt.getX()) {
indexs[1] = j;
break;
}
}
}
}

/**
* 计算指定处的距离(米)换算为距离(度) ---纬度方向上
*
* @param distance 单位m
* @return 纬度方向上
*/
public static double lenToLat(double distance) {
return distance / LATITUDE_METER;
}

/**
* 计算指定处的距离(米)换算为距离(度) ---经度方向上
*
* @param distnace 单位m
* @param r 指定点的纬度值
* @return
*/
public static double lenToLong(double distnace, double degree) {
double dLatRaian = degree * Math.PI / 180;
return distnace / (LONGITUDE_METER * Math.cos(dLatRaian));
}
作者 east

上一 1 … 35 36 37 … 42 下一个

关注公众号“大模型全栈程序员”回复“小程序”获取1000个小程序打包源码。回复”chatgpt”获取免注册可用chatgpt。回复“大数据”获取多本大数据电子书

标签

AIGC AI创作 bert chatgpt github GPT-3 gpt3 GTP-3 hive mysql O2O tensorflow UI控件 不含后台 交流 共享经济 出行 图像 地图定位 外卖 多媒体 娱乐 小程序 布局 带后台完整项目 开源项目 搜索 支付 效率 教育 日历 机器学习 深度学习 物流 用户系统 电商 画图 画布(canvas) 社交 签到 联网 读书 资讯 阅读 预订

官方QQ群

小程序开发群:74052405

大数据开发群: 952493060

近期文章

  • 解决gitlab配置Webhooks,提示 Invalid url given的问题
  • 如何在Chrome中设置启动时自动打开多个默认网页
  • spark内存溢出怎样区分是软件还是代码原因
  • MQTT完全解析和实践
  • 解决运行Selenium报错:self.driver = webdriver.Chrome(service=service) TypeError: __init__() got an unexpected keyword argument ‘service’
  • python 3.6使用mysql-connector-python报错:SyntaxError: future feature annotations is not defined
  • 详解Python当中的pip常用命令
  • AUTOSAR如何在多个供应商交付的配置中避免ARXML不兼容?
  • C++thread pool(线程池)设计应关注哪些扩展性问题?
  • 各类MCAL(Microcontroller Abstraction Layer)如何与AUTOSAR工具链解耦?

文章归档

  • 2025年10月
  • 2025年8月
  • 2025年7月
  • 2025年6月
  • 2025年5月
  • 2025年4月
  • 2025年3月
  • 2025年2月
  • 2025年1月
  • 2024年12月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年6月
  • 2024年5月
  • 2024年4月
  • 2024年3月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年6月
  • 2023年5月
  • 2023年4月
  • 2023年3月
  • 2023年1月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年7月
  • 2018年6月

分类目录

  • Android (73)
  • bug清单 (79)
  • C++ (34)
  • Fuchsia (15)
  • php (4)
  • python (45)
  • sklearn (1)
  • 云计算 (20)
  • 人工智能 (61)
    • chatgpt (21)
      • 提示词 (6)
    • Keras (1)
    • Tensorflow (3)
    • 大模型 (1)
    • 智能体 (4)
    • 深度学习 (14)
  • 储能 (44)
  • 前端 (5)
  • 大数据开发 (494)
    • CDH (6)
    • datax (4)
    • doris (31)
    • Elasticsearch (15)
    • Flink (79)
    • flume (7)
    • Hadoop (19)
    • Hbase (23)
    • Hive (41)
    • Impala (2)
    • Java (71)
    • Kafka (10)
    • neo4j (5)
    • shardingsphere (6)
    • solr (5)
    • Spark (100)
    • spring (11)
    • 数据仓库 (9)
    • 数据挖掘 (7)
    • 海豚调度器 (10)
    • 运维 (36)
      • Docker (3)
  • 小游戏代码 (1)
  • 小程序代码 (139)
    • O2O (16)
    • UI控件 (5)
    • 互联网类 (23)
    • 企业类 (6)
    • 地图定位 (9)
    • 多媒体 (6)
    • 工具类 (25)
    • 电商类 (22)
    • 社交 (7)
    • 行业软件 (7)
    • 资讯读书 (11)
  • 嵌入式 (71)
    • autosar (63)
    • RTOS (1)
    • 总线 (1)
  • 开发博客 (16)
    • Harmony (9)
  • 技术架构 (6)
  • 数据库 (32)
    • mongodb (1)
    • mysql (13)
    • pgsql (2)
    • redis (1)
    • tdengine (4)
  • 未分类 (8)
  • 程序员网赚 (20)
    • 广告联盟 (3)
    • 私域流量 (5)
    • 自媒体 (5)
  • 量化投资 (4)
  • 面试 (14)

功能

  • 登录
  • 文章RSS
  • 评论RSS
  • WordPress.org

All Rights Reserved by Gitweixin.本站收集网友上传代码, 如有侵犯版权,请发邮件联系yiyuyos@gmail.com删除.