Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KML File with 'MultiGeometry' #1

Open
sergej-singer opened this issue May 30, 2024 · 3 comments
Open

KML File with 'MultiGeometry' #1

sergej-singer opened this issue May 30, 2024 · 3 comments
Labels
enhancement New feature or request

Comments

@sergej-singer
Copy link

sergej-singer commented May 30, 2024

As I tried to feed my KML file into the script, I've got this error:

Traceback (most recent call last):
File "", line 1, in
File "D:\Documents\EuroScope EDGG Dev.github\mapbuilder\mapbuilder_main_.py", line 65, in entry
sys.exit(main(*sys.argv))
^^^^^^^^^^^^^^^
File "D:\Documents\EuroScope EDGG Dev.github\mapbuilder\mapbuilder_main_.py", line 52, in main
builder = Builder(args.source, args.target_dir, cache, config)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\Documents\EuroScope EDGG Dev.github\mapbuilder\mapbuilder\builder.py", line 38, in init
self.data[data_source] = parser.parse()
^^^^^^^^^^^^^^
File "D:\Documents\EuroScope EDGG Dev.github\mapbuilder\mapbuilder\data\kml.py", line 30, in parse
self.parse_recursively(self.xml_root["kml"]["Document"], result)
File "D:\Documents\EuroScope EDGG Dev.github\mapbuilder\mapbuilder\data\kml.py", line 41, in parse_recursively
self.parse_recursively(folder, result[name])
File "D:\Documents\EuroScope EDGG Dev.github\mapbuilder\mapbuilder\data\kml.py", line 57, in parse_recursively
raise ValueError(msg)
ValueError: Placemark {'name': 'P P4 P16 P20 P24', 'Style': {'LineStyle': {'color': 'ff0000ff'}, 'PolyStyle': {'fill': '0'}}, 'MultiGeometry': {'Polygon': {'outerBoundaryIs': {'LinearRing': {'coordinates': ... (really long line of coordinates)}

I created my KML file with QGIS. It seems like QGIS exports KML with tag 'MultiGeometry'. After removing this tag manually from the file, script worked flawlessly. Probably it would be nice, if the script could read files with these tags as well.

@fpletz fpletz added the enhancement New feature or request label May 31, 2024
@sergej-singer
Copy link
Author

sergej-singer commented May 31, 2024

So, despite I don't have any skills in Programming or whatnot, I've managed to implement support for the MultiGeometry. It's probably super rudimentary fix, but at least it works, but probably only in cases, when the MultiGeometry consists only of one type of object. Still I'm happy with it.

    def parse_recursively(self, root, result):
        if "Folder" in root:
            for folder in ensure_list(root["Folder"]):
                name = folder["name"]
                result[name] = {}
                self.parse_recursively(folder, result[name])
        if "Placemark" in root:
            for placemark in ensure_list(root["Placemark"]):
                if "MultiGeometry" in placemark:                
                    name = placemark["name"]
                    result[name] = {}
                    self.parse_recursively(placemark["MultiGeometry"], result[name])
                elif "LineString" in placemark:
                    geom = LineString(self.parse_pos_list(placemark["LineString"]["coordinates"]))
                    name = placemark["name"]
                    if name not in result:
                        result[name] = [geom]
                    else:
                        result[name].append(geom)
                elif "Polygon" in placemark:
                    geom = LinearRing(
                        self.parse_pos_list(
                            placemark["Polygon"]["outerBoundaryIs"]["LinearRing"]["coordinates"],
                        ),
                    )
                    name = placemark["name"]
                    if name not in result:
                        result[name] = [geom]
                    else:
                        result[name].append(geom)
                elif "Point" in placemark:
                    geom = Point(self.parse_pos_list(placemark["Point"]["coordinates"]))
                    name = placemark["name"]
                    if name not in result:
                        result[name] = [geom]
                    else:
                        result[name].append(geom)
                else:
                    msg = f"Placemark {placemark} unknown"
                    raise ValueError(msg)             
                
        
        if "LineString" in root:
            for linestring in ensure_list(root["LineString"]):
                geom = LineString(self.parse_pos_list(linestring["coordinates"]))
                name = ""
                if name not in result:
                    result[name] = [geom]
                else:
                    result[name].append(geom)
        
        if "Polygon" in root:
            for polygon in ensure_list(root["Polygon"]):
                geom = LinearRing(
                        self.parse_pos_list(
                           polygon["outerBoundaryIs"]["LinearRing"]["coordinates"],
                        ),
                    )
                name = ""
                if name not in result:
                    result[name] = [geom]
                else:
                    result[name].append(geom) 
        if "Point" in root:
            for point in ensure_list(root["Point"]):
                geom = Point(self.parse_pos_list(point["coordinates"]))
                name = ""
                if name not in result:
                    result[name] = [geom]
                else:
                    result[name].append(geom)

@a3li
Copy link
Collaborator

a3li commented Jul 14, 2024

but probably only in cases, when the MultiGeometry consists only of one type of object.

This is an issue indeed. Can you provide an example KML that shows this behavior?

@sergej-singer
Copy link
Author

I'm not sure if this issue actually needed to be solved. If MultiGeometry would consist for example out of LineStrings and Points, then it wouldn't make any sense, because we can use functions like to_poly or to_line only once per Geo-Feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants