电子围栏是用来判定点是否在一定的范围之内的程序
1、其中电子围栏分为不规则电子围栏和规则的电子围栏,规则的电子围栏是指,圆形的电子围栏,只要设置了中心点和半径即可划分一个电子围栏,其余的还有不规则的电子围栏,比如矩形、长方形、不规则图形的电子围栏,例如这种电子围栏主要采用描边的形式进行电子围栏的划分。
1、不规则电子围栏代码
def ispointinpolygon(point, rangelist):
"""
电子围栏程序
point:目标点坐标:如point=[1.5,3]
rangelist:电子围栏的数组:如rangelist=[[118.804556,32.257551],[118.811950,32.251226],[118.814639,32.2490114]
[118.793418,32.247962],[118.804556,32.257551]].注意:电子围栏的数组第一个坐标必须和最后一个坐标相似
return:点是否在围栏内,是的话返回True,否则返回False
"""
##经度列表 维度列表
lnglist=[]
latlist=[]
for i in range(len(rangelist)-1):
lnglist.append(rangelist[i][0])
latlist.append(rangelist[i][1])
#print(lnglist, latlist)
count = 0
point1 = rangelist[0]
for i in range(1, len(rangelist)):
point2 = rangelist[i]
# 判断线段两端点是否在射线两侧 不在肯定不相交 射线(-∞,lat)(lng,lat)
if(point1[0]<=point[0]<=point2[0]) or (point2[0]<=point[0]<=point1[0]):
target_y=(point2[1]-point1[1])/(point2[0]-point1[0])*(point[0]-point2[0])+point2[1]
if target_y<=point[1]:
count=count+1
point1=point2
#print(count)
if count % 2 == 1:
#print("在圈内")
return True
else:
if ((point[0] == point1[0] and point[1] == point1[1]) or (point[0] == point2[0] and point[1] == point2[1])):
return True
else:
return False
##所有点
##测试数据
#1、广东省公安厅交通管理局
rangelist=[[113.296193,23.229597],[113.296193,23.229597],[113.29582,23.230884],
[113.296553,23.230722],[113.296193,23.229597]]
point1=[113.29622,23.230394]
point2=[113.296831,23.230581]
ispointinpolygon(point1, rangelist)
ispointinpolygon(point2, rangelist)
#其中的rangelist为电子围栏的外围经纬度,point为标记点。
2、规则电子围栏代码
主要是圆形的电子围栏
3、坐标系的转换
坐标主要分为gps坐标,高德坐标、百度坐标
import numpy as np
x_pi = 3.14159265358979324 * 3000.0 / 180.0
pi = 3.1415926535897932384626 # π
a = 6378245.0 # 长半轴
ee = 0.00669342162296594323 # 偏心率平方
#转换维度
def _transformlat(lng, lat):
ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + \
0.1 * lng * lat + 0.2 *np.sqrt(np.fabs(lng))
ret += (20.0 *np.sin(6.0 * lng * pi) + 20.0 *
np.sin(2.0 * lng * pi)) * 2.0 / 3.0
ret += (20.0 *np.sin(lat * pi) + 40.0 *
np.sin(lat / 3.0 * pi)) * 2.0 / 3.0
ret += (160.0 *np.sin(lat / 12.0 * pi) + 320 *
np.sin(lat * pi / 30.0)) * 2.0 / 3.0
return ret
# 转换经度
def _transformlng(lng, lat):
ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + \
0.1 * lng * lat + 0.1 *np.sqrt(np.fabs(lng))
ret += (20.0 *np.sin(6.0 * lng * pi) + 20.0 *
np.sin(2.0 * lng * pi)) * 2.0 / 3.0
ret += (20.0 *np.sin(lng * pi) + 40.0 *
np.sin(lng / 3.0 * pi)) * 2.0 / 3.0
ret += (150.0 *np.sin(lng / 12.0 * pi) + 300.0 *
np.sin(lng / 30.0 * pi)) * 2.0 / 3.0
return ret
###wgs84(gps坐标)转高德坐标
def wgs84_to_gcj02(lng, lat):
"""
WGS84转GCJ02(火星坐标系)
:param lng:WGS84坐标系的经度
:param lat:WGS84坐标系的纬度
:return:高德地图的坐标
经检验有效
"""
dlng=np.array(lng)
dlat=np.array(lat)
dlat = _transformlat(lng - 105.0, lat - 35.0)
dlng = _transformlng(lng - 105.0, lat - 35.0)
radlat = lat / 180.0 * pi
magic =np.sin(radlat)
magic = 1 - ee * magic * magic
sqrtmagic =np.sqrt(magic)
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
dlng = (dlng * 180.0) / (a / sqrtmagic *np.cos(radlat) * pi)
mglat = lat + dlat
mglng = lng + dlng
return [mglng, mglat]
###百度坐标转换为高德坐标
def bd09_to_gcj02(bd_lon, bd_lat):
"""
百度坐标系(BD-09)转火星坐标系(GCJ-02)
百度——>谷歌、高德
:param bd_lat:百度坐标纬度
:param bd_lon:百度坐标经度
:return:转换后的坐标列表形式
"""
bd_lon=np.array(bd_lon)
bd_lat=np.array(bd_lat)
x = bd_lon - 0.0065
y = bd_lat - 0.006
z =np.sqrt(x * x + y * y) - 0.00002 *np.sin(y * x_pi)
theta =np.arctan2(y, x) - 0.000003 *np.cos(x * x_pi)
gg_lng = z *np.cos(theta)
gg_lat = z *np.sin(theta)
return [gg_lng, gg_lat]
##高德坐标转换为gps坐标
def gcj02_to_wgs84(lng, lat):
"""
GCJ02(火星坐标系)转GPS84
:param lng:火星坐标系的经度
:param lat:火星坐标系纬度
:return:
"""
dlat = _transformlat(lng - 105.0, lat - 35.0)
dlng = _transformlng(lng - 105.0, lat - 35.0)
radlat = lat / 180.0 * pi
magic = np.sin(radlat)
magic = 1 - ee * magic * magic
sqrtmagic = np.sqrt(magic)
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
dlng = (dlng * 180.0) / (a / sqrtmagic * np.cos(radlat) * pi)
mglat = lat + dlat
mglng = lng + dlng
return [lng * 2 - mglng, lat * 2 - mglat]
##百度坐标转化为gps坐标
def bd09_to_wgs84(bd_lon, bd_lat):
lon, lat = bd09_to_gcj02(bd_lon, bd