谷歌地球插件中的有效动画

时间:2013-06-21 07:45:09

标签: animation google-earth-plugin

一些背景。

有几种方法可以在GE插件中制作动画。我能想到:

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

  2. 要节省昂贵的API调用,请为整个帧生成KML,并在“frameend”中将其添加/删除到GE。 这就是我目前所做的。 表现也不太好。我相信这是由于对象重新创建的开销。

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

  4. 房。 这就是我目前正在调查的内容。 我没有找到如何隐藏TourPlayer控件并计划使用“iframe shim”技术在其上面放置一些东西。 现在,我坚持使用parseKml解析游戏。如果由fetchKml加载它会播放得很好 - 相机和地标移动。但是通过parseKml加载的同一个游览只移动摄像机,而不是地标。看起来这里适用与#3相同的限制。

  5. 这是我的代码:

    <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>
    

    original.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。有什么一般建议吗?

    谢谢。

1 个答案:

答案 0 :(得分:1)

Q1 - 是的。

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

解释 - 当您通过fetchKml将数据加载到插件中时,通过将每个对象的id附加到已加载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。”

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

Q3和4

至于一般建议 - 只需使用API​​更新对象的几何图形是设置它们的最简单方法之一,在executeBatch中包装对API的调用可以使这个过程在处理方面更便宜