-1

我有一个带有许多点(几百个)的 GEOJSON(我可以将其转换为 Shapefile 或其他地理参考文件),我想在所有这些点上创建地理围栏。我该怎么做呢?我有整个代码来获得一个点的地理围栏,但是如何在多个点上创建地理围栏?

在屏幕上长按时,将添加一个标记,该标记将自动获得一个地理围栏

    public void onMapLongClick(LatLng latLng) { // lange Klicken, bis Marker scheint


        if (Build.VERSION.SDK_INT >= 29) {
            // We need background permission (Manifest.xml)
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED) { // wenn permission granted
                tryAddingGeofence(latLng);
            } else {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION)){
                    //We show a dialog and ask for permission
                    ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_BACKGROUND_LOCATION}, BACKGROUND_LOCATION_ACCESS_REQUEST_CODE);
                } else {
                    ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_BACKGROUND_LOCATION}, BACKGROUND_LOCATION_ACCESS_REQUEST_CODE);
                }

            }
        } else {
            tryAddingGeofence(latLng);
        }
    }




    private void tryAddingGeofence(LatLng latLng) {
        mMap.clear();
        addMarker(latLng);
        addCircle(latLng, GEOFENCE_RADIUS);
        addGeofence(latLng, GEOFENCE_RADIUS);
    }


    private void addGeofence(LatLng latLng, float radius){
        Geofence geofence = geofenceHelper.getGeofence(GEOFENCE_ID, latLng, radius,
                Geofence.GEOFENCE_TRANSITION_ENTER |
                        // Geofence.GEOFENCE_TRANSITION_DWELL |
                        Geofence.GEOFENCE_TRANSITION_EXIT);   // wann wird geofence getriggert? -> reinlaufen, darin laufen oder rausgehen
        GeofencingRequest geofencingRequest = geofenceHelper.getGeofencingRequest(geofence);
        PendingIntent pendingIntent = geofenceHelper.getPendingIntent();
        geofencingClient.addGeofences(geofencingRequest, pendingIntent)
                .addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        Log.d(TAG, "onSuccess: Geofence Added...");
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        String errorMessage = geofenceHelper.getErrorString(e);
                        Log.d(TAG, "onFailure: " + errorMessage);

                    }
                });
    }

    private void addMarker(LatLng latLng) {
        MarkerOptions markerOptions = new MarkerOptions().position(latLng);
        mMap.addMarker(markerOptions);
    }

    private void addCircle(LatLng latLng, float radius){
        CircleOptions circleOptions = new CircleOptions();
        circleOptions.center(latLng);
        circleOptions.radius(radius);
        circleOptions.strokeColor(Color.argb(255,255,0,0));
        circleOptions.fillColor(Color.argb(64,255,0,0));
        circleOptions.strokeWidth(4);
        mMap.addCircle(circleOptions);
    } ```
4

1 回答 1

0

我为遇到此问题的任何人找到了一个简单的解决方案:我们需要创建所有坐标的列表。所以首先我们需要从geojson文件中获取坐标。在下面的解决方案中,我有一个 KML 文件,但最后它得到了相同的结果。

  1. 我创建了一个读取 txt 文件的方法(您必须先将 geojson 或 kml 转换为 .txt,然后将其复制到 src/main/res/raw。在我的情况下,我有“monitoring.txt”所以不要忘记更改name 到您的文件名中。)在第一部分中,它读取 .txt 并将其保存到 String 中。在第二部分,它从中读取位于坐标> 和</坐标之间的字符串。“(。*?)”表明它需要介于两者之间的所有内容。当您拥有 GeoJson 时,请记住查看坐标之间的字符串。然后我取这个字符串(表示坐标),将它们拆分并将纬度和经度解析为双精度,这样我就可以将它作为 LatLng 对象保护起来。它必须在一个循环中,以便将获取 kml/geojson/txt 文件中的每个坐标并将其存储到列表“dangerousArea”中。
private List<LatLng> dangerousArea = new ArrayList<>();

private void readCoordinatesFromKml() throws IOException {

        InputStream inputStream = getResources().openRawResource(R.raw.monitoring);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        int i;
        try {
            i = inputStream.read();
            while (i != -1)
            {
                byteArrayOutputStream.write(i);
                i = inputStream.read();
            }
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Pattern pattern = Pattern.compile("<coordinates>(.*?)</coordinates>", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(byteArrayOutputStream.toString());
        while (matcher.find()) {

            String[] str = matcher.group(1).split(",");
            double Longitude = Double.parseDouble(str[0]);
            double Latitude = Double.parseDouble(str[1]);

            dangerousArea.add(new LatLng(Latitude, Longitude));

        }
    }
  1. 然后您可以将存储在列表中的坐标添加为地理围栏。这取决于您调用的方法,该方法在您的点周围创建地理围栏:
dangerousArea.forEach(coordinate -> {tryAddingGeofence(coordinate);});

对于最后一件事,您必须查看您的代码在哪里执行此操作。通常它是在一个已经确保您被允许获取用户位置的功能下。

于 2020-11-27T15:22:39.430 回答