1、返回的城市轮廓数据参考
工具方法
/**
* 判断点是否在多边形内,如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
*
* @param point 检测点
* @param polygon 多边形的顶点
* @return 点在多边形内返回true, 否则返回false
*/
public static boolean isPtInPoly(Point2D.Double point, List<Point2D.Double> polygon) {
assertParams(point, polygon);
int N = polygon.size();
//如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
boolean boundOrVertex = true;
//cross points count of x
int intersectCount = 0;
//浮点类型计算时候与0比较时候的容差
double precision = 2e-10;
//neighbour bound vertices
Point2D.Double p1, p2;
//当前点
Point2D.Double p = point;
//left vertex
p1 = polygon.get(0);
//check all rays
for (int i = 1; i <= N; ++i) {
if (p.equals(p1)) {
//p is an vertex
return boundOrVertex;
}
//right vertex
p2 = polygon.get(i % N);
//ray is outside of our interests
if (p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)) {
p1 = p2;
//next ray left point
continue;
}
//ray is crossing over by the algorithm (common part of)
if (p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)) {
//x is before of ray
if (p.y <= Math.max(p1.y, p2.y)) {
//overlies on a horizontal ray
if (p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)) {
return boundOrVertex;
}
//ray is vertical
if (p1.y == p2.y) {
//overlies on a vertical ray
if (p1.y == p.y) {
return boundOrVertex;
//before ray
} else {
++intersectCount;
}
//cross point on the left side
} else {
//cross point of y
double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;
//overlies on a ray
if (Math.abs(p.y - xinters) < precision) {
return boundOrVertex;
}
//before ray
if (p.y < xinters) {
++intersectCount;
}
}
}
//special case when ray is crossing through the vertex
} else {
//p crossing over p2
if (p.x == p2.x && p.y <= p2.y) {
//next vertex
Point2D.Double p3 = polygon.get((i + 1) % N);
//p.x lies between p1.x & p3.x
if (p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)) {
++intersectCount;
} else {
intersectCount += 2;
}
}
}
//next ray left point
p1 = p2;
}
//偶数在多边形外
if (intersectCount % 2 == 0) {
return false;
//奇数在多边形内
} else {
return true;
}
}
//格式化数据
public static List<Point2D.Double> addLocationList(JSONArray array){
List<Point2D.Double> points = new ArrayList<>();
int size = array.size() / 2;
for (int i = 0; i < size; i++) {
Point2D.Double e = new Point2D.Double(array.getDouble(i*2), array.getDouble(i*2+1));
points.add(e);
}
return points;
}
调用方法:
//JSON.parseArray(city.getCitypolygon())为腾讯接口返回的数据,
List<Point2D.Double> points = locationUtil.addLocationList(JSON.parseArray(city.getCitypolygon()));// 格式化数据
// 用户位置 经度和纬度
Point2D.Double userLocation = new Point2D.Double(Convert.toDouble(stringList.get(1)), Convert.toDouble(stringList.get(2)));
if (!locationUtil.isPtInPoly(userLocation, points)) {
// 不在城市轮廓范围内
}
// 在城市轮廓范围内