1、上一章讲了arcgis for android 入门与提高(九)地理查询 + 触摸事件,本节讲一个应用,给定一个地理范围,判断当前位置是否进入到划定的围栏(可以构建多个围栏,判断这个点是否在所有的多边形内)。最好基于arcgis for android 入门与提高(六)定位https://blog.csdn.net/HB_Programmer/article/details/119993487,用获取的当前位置判断是否进入地理围栏。
2、原理是一点是否在多边形内,所以只要判断当前的经纬度是否在构建的多边形内:
//判断坐标点是否落在指定的多边形区域内
public boolean IsInPolygon(double lon, double lat, List<String> list) {
double x = lon;
double y = lat;
int isum, icount, index;
double dLon1, dLon2, dLat1, dLat2, dLon;
if (list.size() < 3) {
return false;
}
isum = 0;
icount = list.size();
for (index = 0; index < icount - 1; index++) {
//防止越界
if (index == icount - 1) {
dLon1 = Double.parseDouble(list.get(index).split(",")[0]);
dLat1 = Double.parseDouble(list.get(index).split(",")[1]);
dLon2 = Double.parseDouble(list.get(0).split(",")[0]);
dLat2 = Double.parseDouble(list.get(0).split(",")[1]);
} else {
dLon1 = Double.parseDouble(list.get(index).split(",")[0]);
dLat1 = Double.parseDouble(list.get(index).split(",")[1]);
dLon2 = Double.parseDouble(list.get(index + 1).split(",")[0]);
dLat2 = Double.parseDouble(list.get(index + 1).split(",")[1]);
}
// 判断指定点的 纬度是否在 相邻两个点(不为同一点)的纬度之间
if (((y >= dLat1) && (y < dLat2)) || ((y >= dLat2) && (y < dLat1))) {
if (Math.abs(dLat1 - dLat2) > 0) {
dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - y)) / (dLat1 - dLat2);
if (dLon < x) {
isum++;
}
}
}
}
if ((isum % 2) != 0) {
return true;
} else {
return false;
}
}
当返回结果为true代表在多边形内,反之在外。
private List<List> mListList = new ArrayList<>();
mListList 存放的是多个多边形,比如mListList [0]代表第一个多边形,以此类推。
3、可以用shape导出为geojson格式的数据,https://mapshaper.org/,记得把所有的shape数据都拖到这个网址,geojson数据格式如下,需要注意的是要构成一个闭环,即第一个点和最后一个点一样:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
114.68084061102523,
34.776011272681835
],
[
114.68085373060241,
34.77571327085743
],
[
114.68117234890524,
34.775700151280255
],
[
114.6811667262293,
34.77601314690715
],
[
114.68084061102523,
34.776011272681835
]
]
]
},
"properties": {
"name": "测试"
}
}
]
}
然后解析:
//解析geojson
JSONObject jsonObject = new JSONObject(ret);
JSONArray jsonArray = jsonObject.getJSONArray("features");
for (int i = 0; i < jsonArray.length(); i++) {
List<String> temp = new ArrayList<>();
JSONObject object = jsonArray.getJSONObject(i);
JSONObject geometry = object.getJSONObject("geometry");
JSONArray coordinates = geometry.getJSONArray("coordinates").getJSONArray(0);
for (int j = 0; j < coordinates.length(); j++) {
JSONArray point = coordinates.getJSONArray(j);
temp.add(point.toString().substring(1, point.toString().length() - 1));
}
mListList.add(temp);
4、结果处理:
int len = mListList.size();
for (int i = 0; i < len; i++) {
mLon = "114";
mLat = "34";
if (IsInPolygon(Double.parseDouble(mLon), Double.parseDouble(mLat), mListList.get(i))) {
textViewStatus.setText("状态: 在电子围栏内");
break;
} else {
textViewStatus.setText("状态: 在电子围栏外");
}
}
|