android - 从 Google Maps API 保存 KMZ 文件

标签 android google-maps

我在 Android 开发中使用 Google Maps API;我的应用根据位置定位一组标记。
因此,每一秒它都会定位一个标记,在行程结束时我将拥有一组标记。

我需要将所有这些标记导出到 kmz 文件,以便稍后使用 google earth 打开它们。

有什么想法吗?

最佳答案

KMZ 只是压缩的 KML 格式,所以只需格式 KML -格式化的 String 与你的标记数据,如:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
  <name>Document.kml</name>
  <open>1</open>
  <Style id="exampleStyleDocument">
    <LabelStyle>
      <color>ff0000cc</color>
    </LabelStyle>
  </Style>
  <Placemark>
    <name>Document Feature 1</name>
    <styleUrl>#exampleStyleDocument</styleUrl>
    <Point>
      <coordinates>-122.371,37.816,0</coordinates>
    </Point>
  </Placemark>
  <Placemark>
    <name>Document Feature 2</name>
    <styleUrl>#exampleStyleDocument</styleUrl>
    <Point>
      <coordinates>-122.370,37.817,0</coordinates>
    </Point>
  </Placemark>
</Document>
</kml>

然后将其压缩(例如 thisscessor 的答案)并保存到 .kmz 文件。

更新:这是源代码,它在外部存储的KMZ文件夹中生成markers.kmz文件:

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

    public static final int REQUEST_PERMISSIONS_CODE = 1111;

    static final LatLng MAIDAN = new LatLng(50.450311, 30.523730);
    static final LatLng SOPHIA = new LatLng(50.452973, 30.514502);
    static final LatLng LAVRA = new LatLng(50.434692, 30.556931);

    private GoogleMap mGoogleMap;
    private MapFragment mMapFragment;

    private List<Marker> mMarkers = new ArrayList();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (!checkPermission()) {
            requestPermission();
        }

        mMapFragment = (MapFragment) getFragmentManager()
                .findFragmentById(R.id.map_fragment);
        mMapFragment.getMapAsync(this);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case REQUEST_PERMISSIONS_CODE:
                if (grantResults.length > 0) {
                    boolean storagePermission = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    if (storagePermission) {
                        exportMarkersToKMZfile(mMarkers);
                        Toast.makeText(MainActivity.this, "Permission Granted",
                                Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(MainActivity.this,"Permission Denied",Toast.LENGTH_LONG).show();
                    }
                }
                break;
        }
    }

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

        mMarkers.add(mGoogleMap.addMarker(new MarkerOptions().position(MAIDAN).title("Maidan")));
        mMarkers.add(mGoogleMap.addMarker(new MarkerOptions().position(SOPHIA).title("Sophia")));
        mMarkers.add(mGoogleMap.addMarker(new MarkerOptions().position(LAVRA).title("Lavra")));

        mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(MAIDAN, 16));

        exportMarkersToKMZfile(mMarkers);
    }

    public static String exportMarkersToKML(List<Marker> markers) {
        StringBuilder kmlStringBuilder = new StringBuilder(500 * (markers.size() + 3));

        // add KML header
        kmlStringBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        kmlStringBuilder.append("<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n");
        kmlStringBuilder.append("<Document>\n");
        kmlStringBuilder.append("<name>Document.kml</name>\n");

        // add style for marker
        kmlStringBuilder.append("<Style id=\"blueMarker\">\n");
        kmlStringBuilder.append("<LabelStyle>\n");
        kmlStringBuilder.append("<color>ff00ff00</color>\n");
        kmlStringBuilder.append("</LabelStyle>\n");
        kmlStringBuilder.append("</Style>\n");

        // add markers as KML placemarks
        for (Marker marker : markers) {
            kmlStringBuilder.append("<Placemark>\n");
            kmlStringBuilder.append(String.format("<name>%s</name>\n", marker.getTitle()));
            kmlStringBuilder.append("<styleUrl>#blueMarker</styleUrl>\n");
            kmlStringBuilder.append("<Point>\n");
            kmlStringBuilder.append(String.format("<coordinates>%8.3f,%8.3f,0</coordinates>\n",
                    marker.getPosition().longitude, marker.getPosition().latitude));
            kmlStringBuilder.append("</Point>\n");
            kmlStringBuilder.append("</Placemark>\n");
        }

        kmlStringBuilder.append("</Document>\n");
        kmlStringBuilder.append("</kml>\n");
        return kmlStringBuilder.toString();
    }

    public static void exportMarkersToKMZfile(List<Marker> markers) {
        try {

            String kmlString = exportMarkersToKML(markers);

            File kmzFolder = new File(Environment.getExternalStorageDirectory(), "KMZ");
            if (!kmzFolder.exists()) {
                kmzFolder.mkdir();
            }

            File kmzFile = new File(kmzFolder, "markers.kmz");

            ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(kmzFile));
            ZipEntry entry = new ZipEntry("markers.kml");
            zipOutputStream.putNextEntry(entry);
            zipOutputStream.write(kmlString.getBytes());
            zipOutputStream.flush();
            zipOutputStream.close();

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

    public boolean checkPermission() {
        return ContextCompat.checkSelfPermission(getApplicationContext(), WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED;
    }

    private void requestPermission() {
        ActivityCompat.requestPermissions(MainActivity.this, new
                String[]{WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSIONS_CODE);
    }
}

别忘了添加

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

到您的 AndroidManifest.xml 文件。

关于android - 从 Google Maps API 保存 KMZ 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47756468/

相关文章:

android - flutter 运行错误,并且gradle失败,退出代码为1

java - 当我尝试删除 Activity 上的操作栏时,为什么会出现此异常?

android - 如何从我自己的 Android 应用程序调用内置相机应用程序?

javascript - Google Maps API - map 未加载

google-maps - 在Google Maps-for-Rails(gmaps4rails)中毁损的缩放栏

javascript - 无法将自定义标记添加到 Google map ( JS )

android - 如何仅从我的 Android 应用写入 NFC 标签

javascript - 如何将谷歌地图标签放在顶部?

javascript - 显示/隐藏类别标记。不使用 MarkerCluster

android - Lollipop 工具栏抽屉切换不可点击