Java 多边形内区域计算
我从一个XML文件中读取GPS坐标,然后我想检查我的当前位置(纬度和经度)是否在这个多边形区域内。。。不确定我是否做错了:(看起来我的IsInsideRegion方法失败了。欢迎任何建议 公共课点{Java 多边形内区域计算,java,math,gps,Java,Math,Gps,我从一个XML文件中读取GPS坐标,然后我想检查我的当前位置(纬度和经度)是否在这个多边形区域内。。。不确定我是否做错了:(看起来我的IsInsideRegion方法失败了。欢迎任何建议 公共课点{ private double _latitude = 0d; private double _longitude = 0d; public Point() { } public Point(double aLatitude, double aLongitude) { _latitude
private double _latitude = 0d;
private double _longitude = 0d;
public Point() {
}
public Point(double aLatitude, double aLongitude) {
_latitude = aLatitude;
_longitude = aLongitude;
}
public Point(String pointData) throws Exception {
FromString(pointData);
}
public static String ToString(Point point) {
StringBuilder result = new StringBuilder();
result.append(point._latitude).append(",").append(point._longitude);
return result.toString();
}
public void FromString(String pointData) throws Exception {
String[] fields = pointData.split(",");
if (fields.length != 2)
throw new FormatException("Invalid input data: " + pointData + " in " + this.getClass().getName());
_latitude = parseDouble(fields[0]);
_longitude = parseDouble(fields[1]);
}
private double parseDouble(String aValue) {
double result = 0d;
try {
result = Double.parseDouble(aValue);
} catch (Exception ex) {
}
return result;
}
public double getLatitude() {
return _latitude;
}
public double getLongitude() {
return _longitude;
}
public boolean IsInsideRegion(double latitude, double longitude)
{
//Log.d("<GPD><POLY>","PR :" + String.valueOf(_pointList));
Boolean result = false;
if (_pointList != null && _pointList.size() > 0) {
int Index1 = 0;
int Index2 = _pointList.size() - 1;
while (Index1 < _pointList.size())
{
if ((((_pointList.get(Index1).getLongitude() <= longitude) && (longitude < _pointList.get(Index2).getLongitude())) || ((_pointList.get(Index2).getLongitude() <= longitude) && (longitude < _pointList.get(Index1).getLongitude()))))
{
if (latitude < (_pointList.get(Index2).getLatitude() - _pointList.get(Index1).getLatitude()) * (longitude - _pointList.get(Index1).getLongitude()) / (_pointList.get(Index2).getLongitude() - _pointList.get(Index1).getLongitude()) + _pointList.get(Index1).getLatitude())
result = !result;
}
Index2 = Index1;
Index1++;
}
}
if (result)
Log.d("<GPD><POLY>", "In Polygon Region:" + this.getId());
return result;
}
private void calculateMinMaxLatLong(double aMinLatitude, double aMaxLatitude, double aMinLongitude, double aMaxLongitude)
{
/*
_minLatitude = 0d;
_maxLatitude = 0d;
_minLongitude = 0d;
_maxLongitude = 0d;
for (Point currentPoint: _pointList)
{
if (currentPoint.getLatitude() < aMinLatitude)
_minLatitude = currentPoint.getLatitude();
if (currentPoint.getLatitude() > aMaxLatitude)
_maxLatitude = currentPoint.getLatitude();
if (currentPoint.getLongitude() < aMinLongitude)
_minLongitude = currentPoint.getLongitude();
if (currentPoint.getLongitude() > aMaxLongitude)
_maxLongitude = currentPoint.getLongitude();
}*/
double smallestLat = _pointList.get(0).getLatitude();
double largestLat = _pointList.get(0).getLatitude();
double smallestLong = _pointList.get(0).getLongitude();
double largestLong = _pointList.get(0).getLongitude();
for (int x = 0; x < _pointList.size(); x++){
if(smallestLat > _pointList.get(x).getLatitude())
smallestLat = _pointList.get(x).getLatitude();
if(largestLat < _pointList.get(x).getLatitude())
largestLat = _pointList.get(x).getLatitude();
if(smallestLong > _pointList.get(x).getLongitude())
smallestLong = _pointList.get(x).getLongitude();
if(largestLong < _pointList.get(x).getLongitude())
largestLong = _pointList.get(x).getLongitude();
}
_minLatitude = smallestLat;
_maxLatitude = largestLat;
_minLongitude = smallestLong;
_maxLongitude = largestLong;
}
private double\u lation=0d;
专用双经度=0d;
公共点(){
}
公共点(双音、双音){
_纬度=纬度;
_经度=经度;
}
公共点(字符串点数据)引发异常{
FromString(pointData);
}
公共静态字符串到字符串(点){
StringBuilder结果=新建StringBuilder();
结果。追加(点纬度)。追加(“,”)。追加(点经度);
返回result.toString();
}
public void FromString(String pointData)引发异常{
字符串[]字段=pointData.split(“,”);
如果(fields.length!=2)
抛出新的FormatException(“无效的输入数据:“+this.getClass().getName()中的+pointData+”);
_纬度=parseDouble(字段[0]);
_经度=parseDouble(字段[1]);
}
专用双解析双解析(字符串aValue){
双结果=0d;
试一试{
结果=Double.parseDouble(aValue);
}捕获(例外情况除外){
}
返回结果;
}
公共双纬度(){
返回纬度;
}
公共双getLongitude(){
返回经度;
}
公共布尔值区域(双纬度、双经度)
{
//Log.d(“,”PR:“+String.valueOf(_pointList));
布尔结果=假;
如果(_pointList!=null&&_pointList.size()>0){
int Index1=0;
int Index2=_pointList.size()-1;
while(Index1<\u pointList.size())
{
if((_pointList.get(Index1.getLongitude()aMaxLatitude)
_maxLatitude=currentPoint.getLatitude();
if(currentPoint.getLongitude()amaxlongity)
_Max经度=currentPoint.getLongitude();
}*/
double smallestLat=_pointList.get(0.getLatitude();
双最大纬度=_pointList.get(0.getLatitude();
double smallestLong=_pointList.get(0.getLongitude();
double largestLong=_pointList.get(0.getLongitude();
对于(int x=0;x<_pointList.size();x++){
if(smallestLat>\u pointList.get(x.getLatitude())
smallestLat=_pointList.get(x.getLatitude();
if(最大纬度<_pointList.get(x.getLatitude())
largestLat=_pointList.get(x.getLatitude();
if(smallestLong>\u pointList.get(x).getLongitude()
smallestLong=_pointList.get(x).getLongitude();
if(最大长度<_pointList.get(x).getLongitude()
largestLong=_pointList.get(x).getLongitude();
}
_最小纬度=最小纬度;
_最大纬度=最大纬度;
_最小经度=最小长度;
_最大经度=最大长度;
}
公共区域检查器()
{}
public RegionChecker(仅限布尔值){
_enterFirstOnly=aEnterFirstOnly;
}
公共列表检查位置(列表A活动区域、列表A区域列表、我的位置列表、IRegionEventListener列表){
列表结果=新建ArrayList();
Log.i(“RegionChecker”、“aRegionList”+String.valueOf(aRegionList.size());
布尔区域更改=false;
列表重叠位置列表=新区域();
如果(仅限输入)
{
if(overlappingPositionsList!=null&&overlappingPositionsList.size()>0)
{
Region firstRegion=overlappingPositionsList.get(0);
重叠位置列表。清除();
重叠位置列表添加(第一个区域);
}
}
Log.i(“RegionChecker”,“_activeRegions”+String.valueOf(aActiveRegion.size());
Log.i(“RegionChecker”、“overlappingPositionsList”+String.valueOf(overlappingPositionsList.size());
用于(区域currentRegion:overlappingPositionsList){
Log.i(“重叠检查”,String.valueOf(aActiveRegion.contains(currentRegion));
如果(!aaActiveRegion.contains(currentRegion)){
regionChanges=true;
aListener.OnRegionNet(当前区域,位置);
}
}
对于(区域当前区域:aActiveRegion){
如果(!overlappingPositionsList.contains(currentRegion)){
regionChanges=true;
aListener.OnRegionExit(当前区域,位置);
}
}
结果=重叠位置列表;
如果(区域变化)
aListener.oncurrentregionchanged(结果);
返回结果;
}
我认为您必须修改您的区域检查器
- 它应该使用经度或纬度,但不能同时使用经度或纬度。因此,它会检查水平光线穿过顶点之间的线的次数。或者它会检查垂直线穿过顶点之间的线的次数
- 它需要处理点对和索引0和1、1和2…n-2和n-1以及n-1和0
我不知道你在哪里做最后一对,但是有很多代码要读。当你说它失败时,你到底是什么意思?我得到的:我得到了一张地图,并将街道的一个区域定义为一个区域……当你进入街道/区域时,当你离开该区域或街道时,它需要通过触发上面的onRegionEnter事件让我知道需要启动onRegionExit等。在我的情况下,它从不让我知道onRegionEnter。您的列表是否总是按照一定的顺序,从1到2到3,以此类推,并且这些线永远不会交叉?如果您花一些时间检查代码,并将其相关部分放在这里,会更好。请使用一些好的方法运行这些方法已知值并检查答案是否为预期值,然后发布不起作用的值。仅转储所有代码就更难帮助您。
public RegionChecker(boolean aEnterFirstOnly) {
_enterFirstOnly = aEnterFirstOnly;
}
public List<Region> CheckGpsPosition(List<Region> aActiveRegion, List<Region> aRegionList, MyLocation aLocation, IRegionEventListener aListener) {
List<Region> result = new ArrayList<Region>();
Log.i("RegionChecker", "aRegionList " + String.valueOf(aRegionList.size()));
boolean regionChanges = false;
List<Region> overlappingPositionsList = new Regions().InsideRegions(aRegionList, aLocation.getLatitude(), aLocation.getLongitude());
if (_enterFirstOnly)
{
if (overlappingPositionsList != null && overlappingPositionsList.size() > 0)
{
Region firstRegion = overlappingPositionsList.get(0);
overlappingPositionsList.clear();
overlappingPositionsList.add(firstRegion);
}
}
Log.i("RegionChecker", "_activeRegions " + String.valueOf(aActiveRegion.size()));
Log.i("RegionChecker", "overlappingPositionsList " + String.valueOf(overlappingPositionsList.size()));
for(Region currentRegion: overlappingPositionsList) {
Log.i("overlap check", String.valueOf(aActiveRegion.contains(currentRegion)));
if (!aActiveRegion.contains(currentRegion)) {
regionChanges = true;
aListener.onRegionEnter(currentRegion, aLocation);
}
}
for(Region currentRegion: aActiveRegion) {
if (!overlappingPositionsList.contains(currentRegion)) {
regionChanges = true;
aListener.OnRegionExit(currentRegion, aLocation);
}
}
result = overlappingPositionsList;
if (regionChanges)
aListener.OnCurrentRegionsChanged(result);
return result;
}