如何从 android 中的 kml 文件获取数组点

How to get arraypoints from kml file in android

我有 kml 文件,我用 KmlLayer class 在我的地图中显示它。 (它是显示在地图中的多边形形状) 现在我需要检查用户位置是否在多边形中。 如何获取多边形的坐标并检查用户是否在其中?

这是 mapActivity

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener {

private GoogleMap mMap;
private  LocationManager manager;
private double lat, lng;
private KmlLayer layer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    manager = (LocationManager) getSystemService(LOCATION_SERVICE);

}

@Override
protected void onResume() {
    super.onResume();
    String provider = LocationManager.GPS_PROVIDER;

    try {
        manager.requestLocationUpdates(provider, 1000, 100, this);
    }catch (SecurityException e){

    }
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

}


@Override
public void onLocationChanged(Location location) {
    // Add a marker in user location

    mMap.clear();
    try {
        layer = new KmlLayer(mMap, R.raw.polygon_layer, this);
        layer.addLayerToMap();

    } catch (IOException e) {
        e.printStackTrace();
    } catch (XmlPullParserException e) {
        e.printStackTrace();
    }

    lat = location.getLatitude();
    lng = location.getLongitude();
    LatLng userLocation = new LatLng(lat , lng );
    mMap.addMarker(new MarkerOptions().position(userLocation).title("you are here"));
    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));
/////do somethig thith the results.../////
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {

}

@Override
public void onProviderEnabled(String provider) {

}

@Override
public void onProviderDisabled(String provider) {

  }
}

这是xml

中的kml文件
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
    <name>Allowed area.kml</name>
    <Style id="s_ylw-pushpin_hl">
        <IconStyle>
            <scale>1.3</scale>
            <Icon>
                <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
            </Icon>
            <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
        </IconStyle>
    </Style>
    <StyleMap id="m_ylw-pushpin">
        <Pair>
            <key>normal</key>
            <styleUrl>#s_ylw-pushpin</styleUrl>
        </Pair>
        <Pair>
            <key>highlight</key>
            <styleUrl>#s_ylw-pushpin_hl</styleUrl>
        </Pair>
    </StyleMap>
    <Style id="s_ylw-pushpin">
        <IconStyle>
            <scale>1.1</scale>
            <Icon>
                <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
            </Icon>
            <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
        </IconStyle>
    </Style>
    <Placemark>
        <name>Allowed area</name>
        <styleUrl>#m_ylw-pushpin</styleUrl>
        <Polygon>
            <tessellate>1</tessellate>
            <outerBoundaryIs>
                <LinearRing>
                    <coordinates>
                        34.79991805485883,32.070779943443,0 34.799829164854,32.07080649750882,0 34.79971023480251,32.07083335300256,0 34.79959122858838,32.07086022634235,0 34.79947508289758,32.07091343448649,0 34.79935881388468,32.07096669690968,0 34.79923664471844,32.07096729415576,0 34.79912177286835,32.07104658864036,0 34.79897487097949,32.07112570720702,0 34.79888722467972,32.07117851366566,0 34.79874279960763,32.07128423680869,0 34.79859521904459,32.07136355322666,0 34.79847863488154,32.07144297230025,0 34.79836191935064,32.07152248079761,0 34.79824507343032,32.0716020779166,0 34.79815930685992,32.07168178041764,0 34.79804221359166,32.07176155720244,0 34.79795616172054,32.07184141068195,0 34.79780186844395,32.07186773731328,0 34.79771004064962,32.07189410373302,0 34.79755567970174,32.07192044177337,0 34.79737002328232,32.07194676924303,0 34.79727810620915,32.07197315444336,0 34.79715489998476,32.07199952999493,0 34.79703464286722,32.07205290681115,0 34.79691221087469,32.07207970997565,0 34.79675876113444,32.07213229667552,0 34.79663616578725,32.0721590945553,0 34.7965158855734,32.07221272652451,0 34.79639416450348,32.07224005534155,0 34.79627182383982,32.0722671214403,0 34.79615136355047,32.07232087918774,0 34.79603111665515,32.07237484412778,0 34.79587977302003,32.07242903225671,0 34.79575748160032,32.07245637773539,0 34.79566802521082,32.07251032888696,0 34.79554559731859,32.0725377149133,0 34.7953920225424,32.07256527306239,0 34.79526945233749,32.0725926876614,0 34.79511746292694,32.07264708033384,0 34.79499646538875,32.07270136187387,0 34.79484421345469,32.07275585259577,0 34.79469350541614,32.07283727044721,0 34.79454094840708,32.07289188109038,0 34.79445066170941,32.07294620859783,0 34.79429947907723,32.07302786809845,0 34.79417935372582,32.07310945773398,0 34.79405908038837,32.07319114700508,0 34.79396995394126,32.07327275893679,0 34.79384894225318,32.07335428163514,0 34.79375984266765,32.07343628067046,0 34.79370429835355,32.0735459736907,0 34.7935859422501,32.07368222179287,0 34.79352747616914,32.07376408535365,0 34.79343884580583,32.0738733516459,0 34.79338184365402,32.07398284753502,0 34.79329618372842,32.07414739357892,0 34.79323897373596,32.07425729258198,0 34.79321351678169,32.07436742867609,0 34.79315774177752,32.07450527183566,0 34.7931638907124,32.07461567862387,0 34.79313756341858,32.07472559651252,0 34.79308060933013,32.07488922871619,0 34.79308668160002,32.07502628954131,0 34.79306169465262,32.07519062337077,0 34.79306654712603,32.07530060450269,0 34.7930726226885,32.07543826193546,0 34.79307748970315,32.07554853348597,0 34.79308358050082,32.07568655516418,0 34.79312100317883,32.07579772781796,0 34.79312913357973,32.07596471974184,0 34.79320073097958,32.07610491366522,0 34.79324001895942,32.07624496040656,0 34.79331184498919,32.07638565505223,0 34.79338439099767,32.07652730316914,0 34.79348948121997,32.07666948095191,0 34.79356102661898,32.07678367363563,0 34.79363277125226,32.07689815246911,0 34.79373893916443,32.07704173685054,0 34.7938780624815,32.07718612353797,0 34.79394685121213,32.07724411316636,0 34.7940845259789,32.07736014101853,0 34.7942478923755,32.07736197857023,0 34.79434418144339,32.07733449643025,0 34.79426962949542,32.0771904711012,0 34.79419157753938,32.07698960676555,0 34.79418286657731,32.07684741254325,0 34.79417208286176,32.07665030740839,0 34.79419705423733,32.07651030455318,0 34.7943117016162,32.0763370055064,0 34.79455401995362,32.07613750896425,0 34.79507732694918,32.07582724175629,0 34.79569820277227,32.07560031244044,0 34.79641301741539,32.07540067696312,0 34.79671812423208,32.07525923733243,0 34.79748225018561,32.07497531079491,0 34.79790904184041,32.07478083399741,0 34.79821638657583,32.07467026816978,0 34.79843082137442,32.07458750245045,0 34.79858377461076,32.07453211731625,0 34.79870506867704,32.07447686849413,0 34.79888439004131,32.07436670422536,0 34.79897891672719,32.07436642917416,0 34.80456863371455,32.07677736098206,0 34.80325305348363,32.08274279321805,0 34.80114526065506,32.08251913159533,0 34.7989367189419,32.08176427089727,0 34.79689106024489,32.08073788341836,0 34.79496709037093,32.07958475554416,0 34.79338530277534,32.07829895286428,0 34.7921299991481,32.07665877832899,0 34.79192403865202,32.0763383042137,0 34.79124200995466,32.07505327258005,0 34.79073442377671,32.0738210151859,0 34.79051041161056,32.07323725668621,0 34.79204628706525,32.07302959330549,0 34.79245272972145,32.07270015175266,0 34.79245107794317,32.07265092435394,0 34.79247769467587,32.0710871628869,0 34.79223057128755,32.06931261051965,0 34.79176481038415,32.06790379237363,0 34.79070020423727,32.0662614853681,0 34.78878317579658,32.06475962751786,0 34.78715720473755,32.06306907146922,0 34.78611876597962,32.06156309442464,0 34.78530437871997,32.05935205019298,0 34.78939954851906,32.05930676237435,0 34.78939814232462,32.05666867110639,0 34.80026976529742,32.05646319471511,0 34.80019035465028,32.06112887667786,0 34.79906659112366,32.06429129374197,0 34.79991805485883,32.070779943443,0 
                    </coordinates>
                </LinearRing>
            </outerBoundaryIs>
        </Polygon>
    </Placemark>
</Document>
</kml>

谢谢

您可以访问图层地标并获取其几何图形。如果它是多边形,您可以检查用户位置是否位于多边形内部(考虑到多边形可能有孔,您需要检查位置是否位于孔上,这意味着多边形不包含该位置)。

递归地检查该位置是否位于文件的任何容器中的任何多边形内。

LatLng latLngTest; // The location to test. You will initialize it with your user's location
List<KmlPolygon> polygonsInLayer = getPolygons(layer.getContainers());
boolean liesInside = liesOnPolygon(polygonsInLayer, latLngTest);

private List<KmlPolygon> getPolygons(Iterable<KmlContainer> containers) {
    List<KmlPolygon> polygons = new ArrayList<>();

    if (containers == null) {
        return polygons;
    }

    for (KmlContainer container : containers) {
        polygons.addAll(getPolygons(container));
    }

    return polygons;
}

private List<KmlPolygon> getPolygons(KmlContainer container) {
    List<KmlPolygon> polygons = new ArrayList<>();

    if (container == null) {
        return polygons;
    }

    Iterable<KmlPlacemark> placemarks = container.getPlacemarks();
    if (placemarks != null) {
        for (KmlPlacemark placemark : placemarks) {
            if (placemark.getGeometry() instanceof KmlPolygon) {
                polygons.add((KmlPolygon) placemark.getGeometry());
            }
        }
    }

    if (container.hasContainers()) {
        polygons.addAll(getPolygons(container.getContainers()));
    }

    return polygons;
}

private boolean liesOnPolygon(List<KmlPolygon> polygons, LatLng test) {
    boolean lies = false;

    if (polygons == null || test == null) {
        return lies;
    }

    for (KmlPolygon polygon : polygons) {
        if (liesOnPolygon(polygon, test)) {
            lies = true;
            break;
        }
    }

    return lies;
}

private boolean liesOnPolygon(KmlPolygon polygon, LatLng test) {
    boolean lies = false;

    if (polygon == null || test == null) {
        return lies;
    }

    // Get the outer boundary and check if the test location lies inside
    ArrayList<LatLng> outerBoundary = polygon.getOuterBoundaryCoordinates();
    lies = PolyUtil.containsLocation(test, outerBoundary, true);

    if (lies) {
        // Get the inner boundaries and check if the test location lies inside
        ArrayList<ArrayList<LatLng>> innerBoundaries = polygon.getInnerBoundaryCoordinates();
        if (innerBoundaries != null) {
            for (ArrayList<LatLng> innerBoundary : innerBoundaries) {
                // If the test location lies in a hole, the polygon doesn't contain the location
                if (PolyUtil.containsLocation(test, innerBoundary, true)) {
                    lies = false;
                    break;
                }
            }
        }
    }

    return lies;
}