2016-12-17 2 views
2

Я использую API Карт Google на Android, чтобы создать головоломку. Эта ссылка содержит данные, которые я использовал для привлечения африканских стран: World countries coordinates.Проверьте, находится ли точка в многоугольнике с API Карт Google в Android

Когда пользователь нажимает на карту, проводится тест, чтобы проверить, было ли это в нужной стране или нет.

  • точка внутри правой страны: правая страна окрашена в зеленый

  • точки внутри другой известной страны: нынешняя страна окрашена в красный

код, приведенный ниже итерацию в списке африканских стран (страна может содержать несколько полигонов), чтобы найти ту, которая содержит щелчок, и сравнить ее с нужной страной.

mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() { 
    @Override 
    public void onMapClick(LatLng latLng) { 

     if(isPointInPolygon(latLng,answerPolygon)) { 
      // right answer 
      Toast.makeText(MapsActivity.this, "point inside the right polygon", Toast.LENGTH_SHORT).show(); 
      Polygon p = mMap.addPolygon(new PolygonOptions().addAll(answerPolygon)); 
      p.setStrokeWidth(p.getStrokeWidth()/5); 
      p.setFillColor(0x7F00FF00); 
     } 
     else { 
      // wrong answer 
      // search current polygon 
      // color current polygon in red 
      if (colorPolygonInRed(latLng)){ 
       Polygon p = mMap.addPolygon(new PolygonOptions().addAll(answerPolygon)); 
       p.setStrokeWidth(p.getStrokeWidth()/5); 
       p.setFillColor(0x7F00FF00); 
       Toast.makeText(MapsActivity.this, "point in known polygons", Toast.LENGTH_SHORT).show(); 
      } 
      else { 
       Toast.makeText(MapsActivity.this, "point in unknown polygons", Toast.LENGTH_SHORT).show(); 
      } 
     } 
    } 
}); 

Функция isPointInPolygon() работает только с одним полигоном на карте, потому что она основана на геометрии (луч пересекаются). Это не работает в моем случае. Например, когда я нажимаю внутри страны Чад (синее пятно в this picture), Египет окрашивается в красный цвет (мой список сортируется в алфавитном порядке, поэтому Египет является первым справа от точки щелчка, которая проверяет пересечение луча состояние).

public boolean rayCastIntersect(LatLng tap, LatLng vertA, LatLng vertB) { 
    double aY = vertA.latitude; 
    double bY = vertB.latitude; 
    double aX = vertA.longitude; 
    double bX = vertB.longitude; 
    double pY = tap.latitude; 
    double pX = tap.longitude; 

    if ((aY>pY && bY>pY) || (aY<pY && bY<pY) || (aX<pX && bX<pX)) { 
     return false; // a and b can't both be above or below pt.y, and a or b must be east of pt.x 
    } 

    double m = (aY-bY)/(aX-bX);    // Rise over run 
    double bee = (-aX) * m + aY;    // y = mx + b 
    double x = (pY - bee)/m;     // algebra is neat! 

    return x > pX; 
} 
public boolean colorPolygonInRed(LatLng point){ 
    for (Country country:countryList){ 
     for (ArrayList<LatLng> polygon : country.getCoordinates()){ 
      if(isPointInPolygon(point,polygon)) { 
       Polygon p = mMap.addPolygon(new PolygonOptions().addAll(polygon)); 
       p.setStrokeWidth(p.getStrokeWidth()/5); 
       p.setFillColor(0x7FE00808); 
       return true; 
      } 
     } 
    } 
    return false; 
} 

Каков правильный способ получить полигон, который был нажат из моего списка?

ответ

4

Вы можете использовать метод PolyUtil.containsLocation от Google Maps Android API Utility Library. Из the documentation:

общественной статической булевой containsLocation (LatLng точки, java.util.List полигона, булевой геодезической)

Вычисляет лежит ли заданная точка внутри заданного многоугольника. Полигон всегда считается закрытым, независимо от того, равна ли последняя точка первой или нет. Внутри определяется как не содержащий Южный полюс - Южный полюс всегда снаружи. Многоугольник сформирован из больших сегментов круга, если геодезическая истинна, а остальных - лаксодромных.

+0

спасибо @antonio за ответ! это именно то, что я искал. –

Смежные вопросы