是否有一种方法可以使用KML(JAK)的Java API将图像文件添加到kmz文件中?我可以创建一个没有问题的kml文件,但我试图只嵌入一个资源(如带有一些图像文件的图像文件夹),但marshalAsKmz方法仅将Kml对象作为附加文件,所以我无法确定了解如何添加额外的图像。用于KML(JAK)的Java API将图像嵌入到kmz文件中
4
A
回答
7
我一直在项目上使用JAK一年多。我用它来创建KML,然后我将它编组为仅仅是普通的KML(不是KMZ)。我创建了一个单独的实用程序类,它使用Java SE'Zip'类手动创建KMZ。它工作得很好。 KMZ只不过是一个包含一个.kml文件和0个或多个资源文件(如图像等)的.zip存档文件。唯一的区别是,在输出文件时,将文件命名为.kmz而不是.zip。在KML文档<Style>
定义中,使用与KML文档本身相关的路径来引用您的资源文件。 KML文件被认为是KMZ归档的“根”。如果您的资源文件也位于KMZ(.zip)的根目录下,那么您不需要路径,只需要文件名即可。
编辑:事实上,我忘了我除去编组JAK Kml
对象到一个文件之前,我压缩它的中间步骤。我下面的实用方法会将Kml
对象直接编号为ZipOutputStream
。
这是我创建的一个实用工具类,用于完成我所描述的工作。我在这里发布它,希望别人发布一个只使用JAK的备用解决方案,这样我就可以在将来退役此代码。现在,这将为你做好工作。
注意:如果您不使用slf4j,Apache Commons Lang或Commons I/O,那么只需对代码进行一些调整即可使用您自己的代码删除/替换这些位。很显然,这段代码需要JAK库。
package com.jimtough;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.micromata.opengis.kml.v_2_2_0.Kml;
/**
* Uses the classes in java.util.zip to package a KML file and its
* supplementary files as a ZIP-compressed KMZ file.
*
* @author JTOUGH
*/
public final class KMZPackager {
private final static Logger logger =
LoggerFactory.getLogger(KMZPackager.class);
/**
* Container for data that represents a single entry that will be added
* to a compressed archive.
* @author JTOUGH
*/
public static abstract class DataSource {
protected String archivedFileName;
/**
* Write the contents of this data source to the supplied
* zip output stream.
*
* @param zipOutputStream
* @throws IOException
*/
public abstract void writeToStream(ZipOutputStream zipOutputStream)
throws IOException;
}
/**
* Container for data that represents a single file that will be added
* to a compressed archive.
* @author JTOUGH
*/
public static final class FileDataSource extends DataSource {
private File sourceFile;
/**
* Constructor
*
* @param sourceFile Actual file that will be added to the
* compressed archive.
* @param archivedFileName Name that will be assigned to the compressed
* file within the archive. Caller must ensure that this value is
* unique within the archive otherwise an exception will be thrown
* when a name clash occurs during creation of the archive.
* This string must be non-null and non-empty. Any forward-slash
* characters in the string will be treated as directory separators
* when the KMZ/ZIP archive is created.
* @throws IllegalArgumentException If either of these parameters
* is a null reference
*/
public FileDataSource(
File sourceFile,
String archivedFileName)
throws IllegalArgumentException {
Validate.notNull(sourceFile);
Validate.notEmpty(archivedFileName);
this.sourceFile = sourceFile;
this.archivedFileName = archivedFileName;
}
@Override
public void writeToStream(ZipOutputStream zipOutputStream)
throws IOException {
Validate.notNull(zipOutputStream);
// Check that the file exists, and throw an appropriate exception
// before reading it
if (!sourceFile.exists()) {
throw new IllegalArgumentException(
"File referenced in parameter [" +
sourceFile.getAbsolutePath() + "] does not exist");
}
FileInputStream fis = new FileInputStream(sourceFile);
if (logger.isDebugEnabled()) {
logger.debug("Adding file to KMZ archive" +
" | archive name: " + archivedFileName +
" | original name: " +
sourceFile.getCanonicalPath());
}
// Mark the start of this new file in the ZIP stream
ZipEntry entry = new ZipEntry(archivedFileName);
zipOutputStream.putNextEntry(entry);
// Use the Apache commons-io library to do a buffered
// stream-to-stream copy
try {
IOUtils.copy(fis, zipOutputStream);
} finally {
fis.close();
}
}
}
/**
* Container for a single JAK Kml object that will be marshalled
* directly to a compressed KMZ archive as it is created
* @author JTOUGH
*/
public static final class KMLDataSource extends DataSource {
private Kml kml;
/**
* Constructor
*
* @param kml JAK Kml object that will be marshalled directly to the
* compressed archive.
* @param archivedFileName Name that will be assigned to the compressed
* file within the archive. Caller must ensure that this value is
* unique within the archive otherwise an exception will be thrown
* when a name clash occurs during creation of the archive.
* This string must be non-null and non-empty. Any forward-slash
* characters in the string will be treated as directory separators
* when the KMZ/ZIP archive is created.
* @throws IllegalArgumentException If either of these parameters
* is a null reference
*/
public KMLDataSource(
Kml kml,
String archivedFileName)
throws IllegalArgumentException {
Validate.notNull(kml);
Validate.notEmpty(archivedFileName);
this.kml = kml;
this.archivedFileName = archivedFileName;
}
@Override
public void writeToStream(ZipOutputStream zipOutputStream) throws IOException {
Validate.notNull(zipOutputStream);
// Mark the start of this new file in the ZIP stream
ZipEntry entry = new ZipEntry(archivedFileName);
zipOutputStream.putNextEntry(entry);
// Marshal the Kml object directly to the ZipOutputStream
if (logger.isDebugEnabled()) {
logger.debug("Marshalling KML to KMZ archive" +
" | archive name: " + archivedFileName);
}
kml.marshal(zipOutputStream);
}
}
/**
* Container for a stream holding a Kml document. This will be written
* directly to a compressed KMZ archive as it is created.
*/
public static final class StreamDataSource extends DataSource {
private InputStream inputStream;
/**
* Constructor
*
* @param inputStream the inputStream holding the KML text
* @param archivedFileName Name that will be assigned to the compressed
* file within the archive. Caller must ensure that this value is
* unique within the archive otherwise an exception will be thrown
* when a name clash occurs during creation of the archive.
* This string must be non-null and non-empty. Any forward-slash
* characters in the string will be treated as directory separators
* when the KMZ/ZIP archive is created.
* @throws IllegalArgumentException If either of these parameters
* is a null reference
*/
public StreamDataSource(
InputStream inputStream,
String archivedFileName)
throws IllegalArgumentException {
Validate.notNull(inputStream);
Validate.notEmpty(archivedFileName);
this.inputStream = inputStream;
this.archivedFileName = archivedFileName;
}
@Override
public void writeToStream(ZipOutputStream zipOutputStream) throws IOException {
Validate.notNull(zipOutputStream);
// Mark the start of this new file in the ZIP stream
ZipEntry entry = new ZipEntry(archivedFileName);
zipOutputStream.putNextEntry(entry);
// Use the Apache commons-io library to do a buffered
// stream-to-stream copy
if (logger.isDebugEnabled()) {
logger.debug("Copying KML from stream to KMZ archive" +
" | archive name: " + archivedFileName);
}
try {
IOUtils.copy(inputStream, zipOutputStream);
} finally {
inputStream.close();
}
}
}
/**
* Use ZIP compression to package a KML file and its supplementary files
* as a KMZ archive. The compressed archive will be written to the
* supplied output stream.
*
* @param os OutputStream to which the compressed archive will be written.
* This parameter must be a non-null reference to an OutputStream that
* is open for write operations.
* @param kmlDataSource KML to be added to the compressed archive.
* This parameter must not be null. The archivedFileName attribute must
* end with the .kml extension. The file is added to the compressed
* archive. The KMZ specification states that a KMZ archive must only
* contain a single KML file.
* @param supplementaryFileList List of file locations for supplementary
* files that will be included in the KMZ archive. A common example
* would be icons or image overlays that are referenced in the KML file.
* This parameter can be null or an empty list if there are no
* supplementary files to include in the KMZ. Each source that is included
* in the list must refer to an existing file that does NOT have the
* file extension '.kml'.
* @throws RuntimeException Thrown if anything unexpected occurs
* that prevents execution from continuing or if any of the stated
* conditions for the input parameters are violated
*/
public void packageAsKMZ(
OutputStream os,
DataSource kmlDataSource,
List<FileDataSource> supplementaryFileList)
throws RuntimeException {
ZipOutputStream zipOutputStream = null;
boolean isExceptionThrown = false;
Exception caughtException = null;
List<FileDataSource> supplFileList = supplementaryFileList;
try {
Validate.notNull(os, "os parameter cannot be null");
Validate.notNull(kmlDataSource,
"kmlFileDataSource parameter cannot be null");
// Treat a null parameter just like an empty list (which is OK)
if (supplFileList == null) {
supplFileList = Collections.emptyList();
}
if (logger.isDebugEnabled()) {
logger.debug(
"Creating KMZ archive" +
" | supplementary files: " + supplFileList.size());
}
// Create a buffered output stream for the new KMZ file
zipOutputStream = new ZipOutputStream(new BufferedOutputStream(os));
Validate.isTrue(
kmlDataSource.archivedFileName.endsWith(".kml"),
"KML archived file name must end with .kml");
kmlDataSource.writeToStream(zipOutputStream);
// Now process the list of supplementary files
if (logger.isDebugEnabled()) {
logger.debug("Adding supplementary files to KMZ archive" +
" | archive name: ");
}
for (FileDataSource ds : supplFileList) {
Validate.isTrue(
!ds.archivedFileName.endsWith(".kml"),
"Not legal to include .kml files in supplementary list");
ds.writeToStream(zipOutputStream);
}
// Close the output stream to complete the ZIP creation
zipOutputStream.flush();
zipOutputStream.close();
logger.info("KMZ archive created successfully");
} catch (IOException e) {
isExceptionThrown = true;
caughtException = e;
logger.error("IOException while creating ZIP stream");
} catch (IllegalArgumentException e) {
isExceptionThrown = true;
caughtException = e;
} catch (RuntimeException e) {
isExceptionThrown = true;
caughtException = e;
} finally {
if (isExceptionThrown) {
try {
if (zipOutputStream != null) {
zipOutputStream.close();
}
} catch (IOException ioe) {
// Don't care
}
throw new RuntimeException(caughtException);
}
}
}
}
相关问题
- 1. JAK KML java将文本合并到kml
- 2. 适用于KML的Java API(JAK) - 删除额外的ns2注释(kml)
- 3. 如何在我的网页中嵌入kml或kmz文件
- 4. 嵌套KMZ文件
- 5. Python:在kmz中嵌入图像
- 6. 如何使用JAK库或libkml -java导出KML文件?
- 7. 如何使用NetworkLinkControl和KML(JAK)的Java API正确更新Google地球KML?
- 8. 使用Java API链接地标的航班路径对于Kml(JAK)
- 9. JAK生成的KML不适用于Google我的地图
- 10. 如何在谷歌驱动KML文件中嵌入preserveViewport,用于地图API V3
- 11. PHP:将KML转换为KMZ
- 12. 如何从KML使用Java动态创建KMZ文件
- 13. 将vbs文件嵌入到图像
- 14. 如何在Google地图api v3中切换KML/KMZ图层
- 15. 带图标的KMZ文件
- 16. 在谷歌地图上使用KML/KMZ
- 17. 如何使用javascript将KMZ文件转换为KML?
- 18. 如何在Google Maps API的kml/kmz文件中使用透明度?
- 19. 在Google地图中使用KMZ文件
- 20. Google地球 - KMZ - 开放嵌入式图像
- 21. 将图像嵌入到HTML邮件中
- 22. 如何KML文件转换为KMZ文件在C#中
- 23. 以编程方式在C#中创建KMZ文件KML文件
- 24. 链接到Google Drive上的kml/kmz文件
- 25. 将Java Applet嵌入到.html文件中
- 26. 将KML文件加载到Google地图中API
- 27. 使KML/KMZ图层透明/不透明
- 28. Google地球显示KMZ中嵌入图像的红叉十字架
- 29. 在CHM帮助文件中将图像嵌入到Sandcastles中
- 30. 图像嵌入到自己的文件