예제 #1
0
        /// <summary>
        /// Gets the Kml of all the features in the plug-in
        /// </summary>
        /// <param name="ge">The plug-in</param>
        /// <returns>String of all the Kml from the plug-in - or an empty string</returns>
        public static string GetAllFeaturesKml(dynamic ge)
        {
            if (!IsGE(ge))
            {
                throw new ArgumentException("ge is not of the type GEPlugin");
            }

            StringBuilder kml = new StringBuilder();

            try
            {
                dynamic children = KmlHelpers.GetChildNodes(ge);
                for (int i = 0; i < children.getLength(); i++)
                {
                    dynamic child = children.item(i);

                    if (child != null)
                    {
                        kml.Append(child.getKml());
                    }
                }
            }
            catch (RuntimeBinderException rbex)
            {
                Debug.WriteLine("GetAllFeaturesKml: " + rbex.Message, "GEHelpers");
            }

            return(kml.ToString());
        }
        /// <summary>
        /// Asynchronous method for building a list of nodes
        /// </summary>
        /// <param name="sender">The object that raised the event.</param>
        /// <param name="e">Event arguments.</param>
        private void NodeBuilderDoWork(object sender, DoWorkEventArgs e)
        {
            // node passed in from RunWorkerAsync
            KmlTreeViewNode baseNode = (KmlTreeViewNode)e.Argument;

            baseNode.IsLoading = true;

            // create a stack to hold the children we will create
            Stack <KmlTreeViewNode> children = new Stack <KmlTreeViewNode>();
            bool linkFailed = false;

            if (baseNode.ApiType == ApiType.KmlNetworkLink)
            {
                // fetch the network link data
                string  url = KmlHelpers.GetUrl(baseNode.ApiObject).ToString();
                dynamic data;
                bool    rebuild = false;

                // can't use the new FetchAndParse with archive files...
                if (url.EndsWith("kmz", StringComparison.OrdinalIgnoreCase) ||
                    url.EndsWith("dae", StringComparison.OrdinalIgnoreCase))
                {
                    data = this.browser.FetchKmlSynchronous(url);
                }
                else
                {
                    data    = this.browser.FetchAndParse(url);
                    rebuild = true;
                }

                if (data != null)
                {
                    KmlTreeViewNode link = CreateNode(data);

                    if (rebuild)
                    {
                        // The KmlObjects are created via parseKml so they need their id's need to be rebuilt
                        // so that the Url is still present (e.g. http://foo.com/#id vs. #id)
                        // the `baseurl` of the node is set so that any child nodes can also have there id's rebuilt
                        // when they are created.
                        link.Name    = GenerateId(url, data.getId());
                        link.BaseUrl = url;
                    }

                    // create a new tree node from the data and push it on to the stack
                    children.Push(link);
                }
                else
                {
                    // no data, so push a new place holder node in and set the loadError flag
                    baseNode.IsLoading = false;
                    children.Push(new KmlTreeViewNode());
                    linkFailed = true;
                }
            }
            else
            {
                // the feature must be a KmlFolder or a KmlDocument (KmlContainer)
                // ...so get the child nodes from it
                dynamic kmlChildNodes = KmlHelpers.GetChildNodes(baseNode.ApiObject);

                if (kmlChildNodes != null)
                {
                    int count = kmlChildNodes.getLength();
                    for (int i = 0; i < count; i++)
                    {
                        // create a new KmlTreeViewNode from each feature in the KmlContainer
                        // and push it on to the stack.
                        try
                        {
                            children.Push(CreateNode(kmlChildNodes.item(i)));
                        }
                        catch (COMException)
                        {
                            children.Clear();
                            return;
                        }
                    }
                }
            }

            // pass the base node, child stack and error flag as the result.
            e.Result = new object[] { baseNode, children, linkFailed };
        }
        /// <summary>
        /// Based on kmldomwalk.js
        /// see: http://code.google.com/p/earth-api-samples/source/browse/trunk/lib/kmldomwalk.js
        /// </summary>
        /// <param name="feature">The KML object to parse</param>
        /// <param name="callback">A delegate action, each node visited will be passed to this as the single parameter</param>
        /// <param name="walkFeatures">Optionally walk features, default is true</param>
        /// <param name="walkGeometries">Optionally walk geometries, default is false</param>
        /// <remarks>This method is used by <see cref="KmlTreeView"/> to build the nodes</remarks>
        public static void WalkKmlDom(
            dynamic feature,
            Action <dynamic> callback,
            bool walkFeatures   = true,
            bool walkGeometries = false)
        {
            if (feature == null)
            {
                return;
            }

            dynamic objectContainer = null;
            ApiType type            = GEHelpers.GetApiType(feature);

            switch (type)
            {
            // objects that support getFeatures
            case ApiType.KmlDocument:
            case ApiType.KmlFolder:
            case ApiType.KmlLayer:
            case ApiType.KmlLayerRoot:
            {
                if (walkFeatures)
                {
                    objectContainer = feature.getFeatures();          // GESchemaObjectContainer
                }
            }

            break;

            // objects that support getGeometry
            case ApiType.KmlPlacemark:
            {
                if (walkGeometries)
                {
                    WalkKmlDom(feature.getGeometry(), callback, walkFeatures, true);
                }
            }

            break;

            // object that support getInnerBoundaries
            case ApiType.KmlPolygon:
            {
                if (walkGeometries)
                {
                    WalkKmlDom(feature.getOuterBoundary(), callback, walkFeatures, true);
                }
            }

            break;

            // objects that support getGeometries
            case ApiType.KmlMultiGeometry:
            {
                if (walkGeometries)
                {
                    objectContainer = feature.getGeometries();          // GESchemaObjectContainer
                    ////WalkKmlDom(feature.getOuterBoundary(), callback, walkFeatures, walkGeometries);
                }
            }

            break;
            }

            callback(feature);

            if (objectContainer != null && HasChildNodes(objectContainer))
            {
                // 'GetChildNodes' returns null in some circumstances.
                // see: Issue 96
                dynamic childNodes = KmlHelpers.GetChildNodes(objectContainer);
                int     count      = childNodes == null ? 0 : childNodes.getLength();
                for (int i = 0; i < count; i++)
                {
                    dynamic node = childNodes.item(i);
                    WalkKmlDom(node, callback, walkFeatures, walkGeometries);
                    callback(node);
                }
            }
        }