Skip to content

Instantly share code, notes, and snippets.

@liujbo
Created October 24, 2017 03:34
Show Gist options
  • Save liujbo/f870b7ab206196c344ec6afa8eca3148 to your computer and use it in GitHub Desktop.
Save liujbo/f870b7ab206196c344ec6afa8eca3148 to your computer and use it in GitHub Desktop.
计算当前坐标是否在不规则多变形内
package com.xilai.cuteBoy.common.util;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;
/*************************************************************
* Description: 计算当前坐标是否在不规则多变形内
* 算法名称 Ray-casting Algorithm 光线投射算法
* https://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm
* CreateTime: 2017/7/21
************************************************************/
public class RayCastingAlgorithm {
/**
* 判断当前坐标点,是否在不规则多边形区域内
* @param point 当前坐标点(经度,纬度)
* @param points 不规则多边形坐标点集合
* 从一个点引出一条射线,与多边形的任意若干条边相交,计数器初始化为0,
* 若相交处被多边形的边从左到右切过,则计数器+1
* 若相交处被多边形的边从右到左切过,则计数器-1
* 最后检查计数器 如果是0,点在多边形外,如果!=0 点在多边形内
* @return
*/
public static Boolean isWithIn(Point point, List<Point> points){
//param nonezeroMode True
Boolean nonezeroMode = Boolean.TRUE;
int pointSize = points.size();
//2点成线,>3点成面
if(pointSize < 3){
return Boolean.FALSE;
}
int j = pointSize - 1;
Boolean oddNodes = Boolean.FALSE;
int zeroState = 0;
for (int k = 0; k < pointSize; k++){
Point point_k = points.get(k);
Point point_j = points.get(j);
BigDecimal x = point_j.getLongitude().subtract(point_k.getLongitude());
BigDecimal y = point.getLatitude().subtract(point_k.getLatitude());
BigDecimal y1 = point_j.getLatitude().subtract(point_k.getLatitude());
BigDecimal x1;
if(y1.doubleValue() != 0.0){
x1 = x.multiply(y).divide(y1,6,BigDecimal.ROUND_HALF_UP).add(point_k.getLongitude());
}else {
x1 = point_k.getLongitude();
}
if((point_k.getLatitude().doubleValue() > point.getLatitude().doubleValue()) != (point_j.getLatitude().doubleValue() > point.getLatitude().doubleValue()) &&
point.getLongitude().doubleValue() < x1.doubleValue()){
oddNodes = Boolean.TRUE;
if(point_k.getLatitude().doubleValue() > point_j.getLatitude().doubleValue()){
zeroState ++;
}else {
zeroState --;
}
}
j = k;
}
Boolean result = nonezeroMode?zeroState!=0:oddNodes;
return result;
}
public static void main(String[] args) {
List<Point> points = new LinkedList<Point>();
points.add(new Point(new BigDecimal(109.329087),new BigDecimal(34.120046)));
points.add(new Point(new BigDecimal(109.352261),new BigDecimal(34.128146)));
points.add(new Point(new BigDecimal(109.349515),new BigDecimal(34.148464)));
points.add(new Point(new BigDecimal(109.345566),new BigDecimal(34.167925)));
points.add(new Point(new BigDecimal(109.312607),new BigDecimal(34.167925)));
points.add(new Point(new BigDecimal(109.285828),new BigDecimal(34.173038)));
points.add(new Point(new BigDecimal(109.298188),new BigDecimal(34.162811)));
points.add(new Point(new BigDecimal(109.305741),new BigDecimal(34.148322)));
points.add(new Point(new BigDecimal(109.329087),new BigDecimal(34.120046)));
points.add(new Point(new BigDecimal(109.352261),new BigDecimal(34.128146)));
points.add(new Point(new BigDecimal(109.349515),new BigDecimal(34.148464)));
points.add(new Point(new BigDecimal(109.345566),new BigDecimal(34.167925)));
points.add(new Point(new BigDecimal(109.312607),new BigDecimal(34.184399)));
points.add(new Point(new BigDecimal(109.285828),new BigDecimal(34.173038)));
points.add(new Point(new BigDecimal(109.298188),new BigDecimal(34.162811)));
points.add(new Point(new BigDecimal(109.305741),new BigDecimal(34.148322)));
Point point = new Point(new BigDecimal(108.661651),new BigDecimal(33.912024));
Boolean result = isWithIn(point,points);
System.out.println(result);
}
/**
* 定义Point(x,y)
* x = longitude
* y = latitude
*/
public static class Point{
/**
* 经度
*/
private BigDecimal longitude;
/**
* 维度
*/
private BigDecimal latitude;
public Point(BigDecimal longitude, BigDecimal latitude) {
this.longitude = longitude;
this.latitude = latitude;
}
public BigDecimal getLongitude() {
return longitude;
}
public void setLongitude(BigDecimal longitude) {
this.longitude = longitude;
}
public BigDecimal getLatitude() {
return latitude;
}
public void setLatitude(BigDecimal latitude) {
this.latitude = latitude;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment