简体   繁体   中英

How to create KMZ file from KML on the fly using Java

I am trying to create kmz file from kml file on the fly and render it as a stream of bytes in web application.

But when I downloaded generated kmz file, I couldn't open it using archive manager on Ubuntu.

I view similar questions on this site, but it don't work.

Can someone help me and explain what I do wrong?!

This is my code.

@Public public void retrieveKmlInOldFormat() {
   File file = new File(Play.applicationPath+"/"+Play.configuration.getProperty("web.content", "../bspb-web")+"/map/map.kml");
   String kmlFileContent = null;
   try {
     String kmlUrl = file.toURI().toURL().toString();
     kmlFileContent = BSPBKml2OldFormatConverter.toOldKml(
                        kmlParserLocal.load(kmlUrl));
   } catch (MalformedURLException e) {
      e.printStackTrace();
   }
   String zippedFileName = "old_fmt_map.kmz";
   String zippedKml = compressKmlFile(kmlFileContent,zippedFileName);
   response.setContentTypeIfNotSet("application/vnd.google-earth.kmz");
   renderBinary(new ByteArrayInputStream(zippedKml.getBytes()),zippedFileName);
   return;
}

Compress method code:

private String compressKmlFile(String kmlFileContent,String zipEntryName){

String zippedContent = null;
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();

ZipOutputStream zipStream = new ZipOutputStream(new
  BufferedOutputStream(byteStream));

ZipEntry zipEntry = null;
zipEntry = new ZipEntry("doc.kml");
try {
  zipEntry.setSize(kmlFileContent.getBytes("UTF-8").length);
  zipStream.putNextEntry(zipEntry);
  zipStream.write(kmlFileContent.getBytes("UTF-8"));
  zipStream.closeEntry();      
  zippedContent = new String(byteStream.toByteArray(),"UTF-8");
} catch (IOException e) {
  logger.error("Error while zipping kml file content");
}
finally {
  try {
    byteStream.close();
    zipStream.close();
  } catch (IOException e) {
    logger.error(e.getMessage());
  }
}
return zippedContent;
}

The problem is about downloaded corrupted kmz archive. This problem can be resolved by using output stream of http response as constructor argument for ZipOutputStream class.

Solution is in this code.

@Public public void retrieveKmlInOldFormat(){
 File file = new File(Play.applicationPath+"/"+Play.configuration.getProperty("web.content", "../bspb-web")+"/map/map.kml");
 String kmlFileContent = null;
 try {
   String kmlUrl = file.toURI().toURL().toString();
   kmlFileContent = BSPBKml2OldFormatConverter.toOldKml(kmlParserLocal.load(kmlUrl));
 } catch (MalformedURLException e) {
   e.printStackTrace();
 }
 response.setContentTypeIfNotSet("application/vnd.google-earth.kmz");
 response.setHeader("Content-Disposition", "attachment; filename=\"old_fmt_map.kmz\"");
 renderAsKmz(response, kmlFileContent,"old_fmt_map.kml");
 return;
}



private void renderAsKmz(Response response,String kmlFileContent,String zipEntryName){
 ZipOutputStream zipStream = new ZipOutputStream(response.out);
 ZipEntry zipEntry = new ZipEntry(zipEntryName);
 try {
  zipStream.putNextEntry(zipEntry);
  zipStream.write(kmlFileContent.getBytes());
 } catch (IOException e) {
   logger.error("Error while zipping kml file content : " + e.getMessage());
 }
 finally {
   try {
     zipStream.closeEntry();
     zipStream.close();
   } catch (IOException e) {
    logger.error("Error while closing zipped stream : " + e.getMessage());
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM