Created
October 24, 2017 03:34
-
-
Save liujbo/f870b7ab206196c344ec6afa8eca3148 to your computer and use it in GitHub Desktop.
计算当前坐标是否在不规则多变形内
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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