首先是要获取geojson数据

geojson

离线区域地图数据,由经纬度数组组成

http://datav.aliyun.com/tools/atlas/#&lat=27.059125784374068&lng=105.205078125&zoom=3

# 流程

判断一个gps的经纬度处于哪个区域,国内按省市划分

判断算法:

向量直线相交,交点为偶数就不处于该区域,奇数则在

算法地址: http://turfjs.org/docs/#pointOnFeature

# GeoJSON

http://geojson.io/

地理要素 描述
Point
MultiPoint 多点
LineString 线
MultiLineString 多线
Polygon 多边形
MultiPolygon 多个多边形 列表的层级不一样会出现不一样的效果
GeometryCollection 多种基本地理要素的集合

一个行政区域的Geo边界为 MultiPolygon 对象,及其领域为多个多边形组成,另需注意多边形的层级差异,中空多边形行成等

# 判断点在多边形内部的方法

射线法:

以被测点Q为端点,向任意方向作射线(一般水平向右作射线),统计该射线与多边形的交点数。如果为奇数,Q在多边形内;如果为偶数,Q在多边形外。

// c
const double eps = 1e-6;
const double PI = acos(-1);
//三态函数,判断两个double在eps精度下的大小关系
int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    else
        return x<0?-1:1;
}
//判断点Q是否在P1和P2的线段上
bool OnSegment(Point P1,Point P2,Point Q)
{
    //前一个判断点Q在P1P2直线上 后一个判断在P1P2范围上
    return dcmp((P1-Q)^(P2-Q))==0&&dcmp((P1-Q)*(P2-Q))<=0;
}
//判断点P在多边形内-射线法
bool InPolygon(Point P)
{
    bool flag = false; //相当于计数
    Point P1,P2; //多边形一条边的两个顶点
    for(int i=1,j=n;i<=n;j=i++)
    {
        //polygon[]是给出多边形的顶点
        P1 = polygon[i];
        P2 = polygon[j];
        if(OnSegment(P1,P2,P)) return true; //点在多边形一条边上
        //前一个判断min(P1.y,P2.y)<P.y<=max(P1.y,P2.y)
        //这个判断代码我觉得写的很精妙 我网上看的 应该是大神模版
        //后一个判断被测点 在 射线与边交点 的左边
        if( (dcmp(P1.y-P.y)>0 != dcmp(P2.y-P.y)>0) 
           && dcmp(P.x - (P.y-P1.y)*(P1.x-P2.x)/(P1.y-P2.y)-P1.x)<0)
            flag = !flag;
    }
    return flag;
}

另一种做法:

如果多边形是凸的,则可以将多边形视为从第一个顶点开始的“路径”。如果一个点始终位于构成路径的所有线段的同一侧,则该点位于该多边形的内部。

给定P0(x0,y0)和P1(x1,y1)之间的线段,另一个点P(x,y)与该线段具有以下关系。计算(y-y0)(x1-x0)-(x-x0)(y1-y0)

如果小于0,则P位于线段的右侧;如果大于0,则P位于线段的左侧;如果等于0,则其位于线段上。

// c#
/// <summary>
/// 确定给定点是否在多边形内
/// </summary>
/// <param name="polygon">多边形的顶点</param>
/// <param name="point">给定的点</param>
/// <returns>在内部为真,否则假</returns>
public static bool IsPointInPolygon(this List<List<float>> polygon, List<float> point)
{
    bool result = false;
    int j = polygon.Count() - 1;
    for (int i = 0; i < polygon.Count(); i++)
    {
        // 相交
        if ((polygon[i][1] < point[1] && polygon[j][1] >= point[1]) || (polygon[j][1] < point[1] && polygon[i][1] >= point[1]))
        {
            // 判断被测点 在 射线与边交点 的左边(X更小)
            if (polygon[i][0] + (point[1] - polygon[i][1]) / (polygon[j][1] - polygon[i][1]) * (polygon[j][0] - polygon[i][0]) < point[0])
            {
                result = !result;
            }
        }
        j = i;
    }
    return result;
}
上次更新: 2020年 02月 26日 17:40:03