2

一些背景。

在 GE 插件中有几种方法可以为事物设置动画。我能想到:

  1. 使用批处理 API 调用在“frameend”事件中移动内容。由于已知问题,这些调用在某些浏览器中相当慢。在帧率下降到无法接受的低点之前,我们可以触发大约 150 个 API 调用/帧。这还不够。

  2. 为了节省昂贵的 API 调用,为整个框架生成 KML,并在“frameend”中将它们添加/删除到 GE。这就是我目前所做的。性能也不是很好。我相信这是由于对象重新创建开销。

  3. 在 KML 中使用“更新”来更新而不是每帧重新创建对象。根据docs,“包含 NetworkLinkControl 的文件必须已由 NetworkLink 加载”。此外,parseKml 只是不接受 NetworkLinkControl。所以,看起来这种方法需要服务器交互,因此不提供所需的平滑度和交互性(是的,我确实从服务器下载了一些原始数据,但动画是基于处理过的数据和用户交互在客户端完成的)。我什至想用本地网络服务器来愚弄 GE ..

  4. 旅游。这是我目前正在调查的。我没有找到如何隐藏 TourPlayer 控件并计划使用“iframe shim”技术在其上方放置一些东西。现在,我坚持玩由 parseKml 解析的巡回赛。如果通过 fetchKml 加载它就可以正常播放 - 相机和地标移动。但是通过 parseKml 加载的同一个旅游只移动相机,而不是地标。看起来这里应用了与 #3 中相同的限制。

这是我的代码:

<script src="https://www.google.com/jsapi"></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>

google.load("earth", "1")

var originalUrl = 'http://localhost/original.xml'
var tourUrl     = 'http://localhost/tour.xml'

var ge
$(function() {
    google.earth.createInstance('ge', function(instance) {
        ge = instance
        google.earth.fetchKml(ge, originalUrl, function(o) {
            ge.getFeatures().appendChild(o)
        })
    })
})

function tour(t) {
    ge.getTourPlayer().setTour(t)
    ge.getTourPlayer().play()
}

function fetchKml() {
    google.earth.fetchKml(ge, tourUrl, tour)
}

function parseKml() {
    $.get(tourUrl, function(kml) {
        tour(ge.parseKml(kml))
    }, 'text')
}

</script>
<div id="ge"></div>
<button onclick="fetchKml()">fetchKml</button>
<button onclick="parseKml()">parseKml</button>

原始.xml:

<Folder>
    <Placemark><name>A</name><Point id="a"></Point></Placemark>
    <Placemark><name>B</name><Point id="b"></Point></Placemark>
</Folder>

和tour.xml:

<?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">
    <gx:Tour>
        <gx:Playlist>
            <gx:FlyTo>
                <gx:duration>2</gx:duration>
                <LookAt><range>50</range></LookAt>
            </gx:FlyTo>
            <gx:AnimatedUpdate>
                <gx:duration>10</gx:duration>
                <Update>
                    <targetHref>http://localhost/original.xml</targetHref>
                    <Change>
                        <Point targetId="b"><coordinates>0.0001,0.0001,0</coordinates></Point>
                    </Change>
                </Update>
            </gx:AnimatedUpdate>
            <gx:FlyTo>
                <gx:duration>10</gx:duration>
                <LookAt><range>50</range><latitude>0.0001</latitude><longitude>0.0001</longitude></LookAt>
            </gx:FlyTo>
        </gx:Playlist>
    </gx:Tour>
</kml>

按“fetchKml”将 B 移离 A,相机跟随 - 正确。按“parseKml”只会移动相机,A 和 B 保持原位 - 不正确。

还有我的问题。

Q1。我的代码有问题吗,或者#4 在没有服务器交互的情况下不起作用?

Q2。我在#1-#4 中告诉你的内容有错误吗?

Q3。还有哪些其他动画方法可以尝试?

Q4。有什么一般性建议吗?

谢谢你。

4

1 回答 1

1

Q1 - 是的。

UsingparseKml将不起作用,原因很简单,创建的元素将不再对您指定的目标 href 有任何引用。

解释一下 - 当您通过每个对象的 id 将数据加载到插件中时fetchKml,通过将其附加到加载 kml 的 url 来使其唯一。因此,在您的示例中,点 ID 将是http://localhost/original.xml#b

但是,您将 kml 作为文本加载 -然后您将解析到插件中- 所以从插件的角度来看,数据不是来自http://localhost/original.xml- 对象是使用 API 创建的,就像您调用了一样createPoint,所以点 ID 很简单b

这意味着<targetHref>http://localhost/original.xml</targetHref>错误 - 因为数据不是来自http://localhost/original.xml它来自对某些文本调用 parseKml - 插件未知的 url。

本质上,您正在尝试更新http://localhost/original.xml#b但该对象不存在 - 因为该对象不是从该 URL 创建的。

Q2 - 是的。

“...parseKml 只是不接受 NetworkLinkControl。”

您无法通过创建 NetworkLinkControl,parseKml因为您无法在 api 中创建 NetworkLinkControl 对象。没有 a 这样的东西,KmlNetworkLinkControl因此如果您解析包含 NetworkLinkControl 的 kml 文件,则无需创建任何对象。它与“服务器交互”无关。

Q3&4

至于一般建议 - 使用 API 简单地更新对象的几何形状是动画它们的最简单方法之一,将 API 调用包装在其中executeBatch可以使这个过程在处理方面的成本大大降低。

于 2013-06-22T19:58:31.030 回答