samcragg / sharpkml

SharpKML is an implementation of the Open Geospatial Consortium (OGC) KML 2.2 standard developed in C#, able to read/write both KML files and KMZ files.
MIT License
158 stars 51 forks source link

Styles with same id doesnt show corretly #37

Closed yvz-dmr closed 3 years ago

yvz-dmr commented 3 years ago

Hi i dont know if this is a bug or intended behaviour or something else but currently we are seeing different behaviour then google earth so i have to ask.

You can access the file here https://public.3.basecamp.com/p/fbjqcWDEhT5oYMR4k1jCCget The file has 6 styles in it and all of them has same id and they have relatively different colors. When i load this file via this library it finds just one style in it and when i try to resolve a style it always returns same style since it only has one. Actually this is okey but our customer is able to open the file in google earth with each placemark shows different color according to style somehow they attached to.

I know that comparing this library with google earth may be wrong but our customer wants same visual experience so i just want to know if i am doing something wrong or this is the way how this library works.

samcragg commented 3 years ago

I'm not sure how Google Earth is doing that, as the styles aren't referenced correctly (i.e. it's the same issue as #36 where the leading # is missing from them). I'm going to speculate that GE isn't actually using the styles and is just using some default colours. Nevertheless, the specification states the following for the id attribute:

The id attribute may be used to specify a unique identifier for the kml:AbstractObjectGroup within the KML document instance

So, unfortunately, the document you've supplied doesn't follow the specification and, therefore, I'm not sure how the library can help in this scenario. As I think this is quite a unique situation, I don't think there's anything that can be added to the library to support this that would also benefit others.

Having said that, the document will still parse correctly, so you can have a go at manually resolving the styles (something like this, though I've not actually tested it but should be roughly correct):

var styles = new Dictionary<string, Style>();
foreach (var element in kmlFile.Root.Flatten())
{
    if (element is Style style)
    {
        styles[style.Id] = style; // This overwrites previous values
    }
    else if (element is Placemark placemark)
    {
        styles.TryGetValue(placemark.StyleUrl.ToString(), out Style style);
        ...
    }
}