/// <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); } } }