在多边形区域内计算

时间:2013-01-23 23:06:21

标签: java math gps

我得到以下代码,我从XML文件中读取GPS坐标,然后我想检查我的当前位置(纬度和长度)是否在此多边形区域内...不确定是否做错了:(看起来像我的IsInsideRegion方法失败了。欢迎任何建议。

公共课点{

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;
}

public RegionChecker()     {}

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;
}

1 个答案:

答案 0 :(得分:0)

我认为你必须修改你的区域检查器。

  • 它应该使用经度或纬度,但不能同时使用两者。因此,它会检查水平光线穿过顶点之间的线的次数。或者它会检查垂直线的次数。
  • 需要处理点对和索引0&amp; 1,1和&amp; 2 ... n-2&amp; n-1和n-1&amp; 0

我没看到你最后一对在哪里做,但是有很多代码需要阅读。