I'm trying to convert a kml layer to a note using the ArcGIS Explorer Desktop SDK. I know that AGX can do this because if you right click on a kml layer in the application itself you get the option to save or share it as a note. But I can't see anywhere in the SDK how to do this programmatically. Any ideas? Thanks!
~Ellen
Hey Ellen,
I'm pretty sure you have to do this in a few steps, simply because a kml layer can contain any number of different geometry types.
Best way to do it would be to create a mapitemcollection using the KmlLayer.Descendants method, which should grab all mapitems in child kml layers as well. Note, all of these items will be KmlNode objects
Then iterate through that list, creating clones of each mapitem that is a graphics type of kml node. (You may want to do overlay as well as graphics nodes)
Note that you will probably have to get the node as a mapitem to actually convert to a note? I'm a little unsure.
ESRI.ArcGISExplorer.Mapping.KmlLayer lyr = new ESRI.ArcGISExplorer.Mapping.KmlLayer
ESRI.ArcGISExplorer.Mapping.MapItemCollection kmlitems = lyr.Descendants
foreach (KmlNode node in kmlitems)
{
if (node.Type == KmlNodeType.Graphics) //if it is we can likely turn it into a note)
{
switch (node.GraphicsType)
{
case kmlGraphicsType.Icon:
//make a point note
break;
case KmlGraphicsType.Path:
//make a line note
break;
case KmlGraphicsType.Polygon:
//make a polygon note
break;
default:
break;
{
}
}
I'm just guessing on the code above, but hopefully it gives you a place to start.
Norm
Hi Norm
thanks very much for the ideas. I was able to do a lot with the code you supplied. In particular the Descendents was very helpful and I didn't know about that before.
I'm still having trouble though. I don't seem to be able to clone the kml node into a map item. I get the message "esri.arcgisexplorer.mapping.kmlnode.createfromxmlstring not found. I know the clone is causing it as I've got error messages before and after. Any thoughts?
Here's the code I've got so far. (I had to create VBA from what I think was c#.)
'the following assumes that you have a kml item as the first item in the map | |
Dim kml As KmlLayer = mapDisplay.Map.ChildItems.GetFirst' |
'create a collection of kmlNodes I can work through | |
Dim kmlNodes As System.Collections.Generic.IEnumerable(Of MapItem) = Nothing | |
kmlNodes = kml.Descendants |
Dim indItem As KmlNode | |
Dim kmlType As KmlNodeType | |
For Each indItem In kmlNodes | |
kmlType = indItem.GraphicsType() | |
Select Case (kmlType) |
Case KmlGraphicsType.Icon | |
MsgBox("at the kml graphics type equal to icon") | |
'i get the above message. | |
Dim mapItem As MapItem = indItem.Clone | |
'I don't get the following message. Line above bombs. | |
MsgBox("here's the cloned map item " & mapItem.Name) | |
mapDisplay.Map.ChildItems.Add(mapItem) | |
' | |
Case (KmlGraphicsType.Path) | |
'its a path |
Case (KmlGraphicsType.Polygon) | |
'its a polygon | |
MsgBox("I found a polygon") | |
Dim theGeometryStr As String = indItem.Tag |
Case Else | |
MsgBox("not a point, line or polygon. ignore for now") |
End Select |
Next |
End Sub |
I think I'm missing how to get the placemark's geometry. Any suggestions? And thanks again for the ideas.
Ellen
Hi Ellen,
I think there are two options for this. The first method is to serialize the node to xml, then parse the xml string for the coordinates.
The second method is to use an undocumented method in the SDK called KmlNode.TargetLocation. I found this by using the object browser in Microsoft Studio.
Dim kPoint As ESRI.ArcGISExplorer.Geometry.Point = kmlNode.TargetLocation
After that you can add in all the other properties from the node (popup, viewpoint, name, etc) to that point
While the above will work for point icons, I am pretty sure you are going to have to serialize the xml string in order to deal with the lines and polygons, so you might as well do it for the points as well. If you only need the points, then the TargetLocation method is nice and easy.
It's to bad ESRI didn't add a GetCenter method for KML nodes like they have done in the Runtime SDKs
Norm
Hi Norm
I was able to use TargetLocation and get a new point. Thanks for that. As you suspected, it doesn't work for polygons and probably not paths either, which I did not test.
I had previously created a polygon by serializing (I believe I did anyway, I read an http response as xml and 'manually' created the polygon by working through the coordinate pairs.)
For anyone interested, create an ArcGIS Explorer Note of the Point type, using my coding above and using the kmlNode.TargetLocation to create a new point. Then,
Dim newNote As ESRI.arcgisexplorer.Mapping.Note
newNote = New Note("A new note",kPoint)
mapdisp.Map.ChildItems.Add(newNote)
Again Norm, thanks very much!
Next item on my task list? Create xslt to take kml to nmc?
Ellen