fastkml icon indicating copy to clipboard operation
fastkml copied to clipboard

Feature Request: pass optional dictionary of namespaces and optional doc type string

Open wesley-murray opened this issue 1 year ago • 4 comments

I extended the KML class so I could add a from_geojson function. Ideally this concept can be taken further to include other types such as shape files. The raw data formats dont have kml specific logic like xml doc type and namespaces. It would be very helpful if the to_string or constructor method had optional args that allow you to pass on the doctype and a dictionary of namespaces. The namespaces would also need to be passed along to the etree_element function. I had good results with this in my case.

In the below example I used inheritance to overwrite the parent. It assumes use of LXML.

def to_string(self, prettyprint=False, namespaces=None, doctype='<?xml version="1.0" encoding="UTF-8"?>') -> str:
        """Returns the KML object as a string."""
        return etree.tostring(
            self.etree_element(namespaces=namespaces),
            encoding="utf-8",
            pretty_print=prettyprint,
            doctype=doctype,
        ).decode("UTF-8")

wesley-murray avatar Aug 29 '24 21:08 wesley-murray

@cleder I'd like to work on this feature under Hacktoberfest. Can you please assign it to me?

HazemAbdo avatar Sep 28 '24 07:09 HazemAbdo

Please have a look at the contributing guidelines.

cleder avatar Sep 28 '24 10:09 cleder

I think instead of adding it to the to_string method, it would be better to add a save method to fastkml.kml.KML like the parse method, taking the file or filename to write to. I don't think you will need to pass the namespaces as @wesley-murray suggested, they are already present on the object.

cleder avatar Sep 28 '24 10:09 cleder

In this context, I think it is worth a look if we want to register the namespaces on import time or when the object is serialized to XML -> https://github.com/cleder/fastkml/blob/develop/fastkml/config.py

cleder avatar Sep 30 '24 09:09 cleder

@cleder I would like to give this a try. Can you assign me this issue?

apurvabanka avatar Oct 27 '24 20:10 apurvabanka

@cleder Do we want to add "doctype" as a input parameter while trying to parse a KML file? OR Do we want to add a "save" functionality with "doctype" as an input parameter?

apurvabanka avatar Oct 30 '24 04:10 apurvabanka

Stay close to the API fastkml is built on: A write function like lxml or xml.etree would do the trick

cleder avatar Oct 30 '24 09:10 cleder

I think write should just take a pathlib.Path, not an open file. If the filename ends with .kmz the file should be zipped. It should be a method of fastkml.kml.KML e.g:

     def write(self, file_name:pathlib.Path, *, pretty_print:bool=False, xml_declaration:bool=False) -> None:

Lxml:

The doctype option allows passing in a plain string that will be serialised before the XML tree. Note that passing in non well-formed content here will make the XML output non well-formed. Also, an existing doctype in the document tree will not be removed when serialising an ElementTree instance.

xml.etree:

xml_declaration=None, xml_declaration controls if an XML declaration should be added to the file. Use False for never, True for always, None for only if not US-ASCII or UTF-8 or Unicode (default is None)

I think true or false are enough for xml_declaration as it is either '<?xml version="1.0" encoding="UTF-8"?>' or '', no other doctypes are allowed anyway.

The other parameters that lxml or xml.etree define make not much sense for writing kml in 2024:

  • encoding: who encodes in anything else than UTF-8 today?
  • method is always xml

and some are not implemented in one of the two, e.g

  • default_namespace (would always be kml in this case)
  • short_empty_elements (always true)

cleder avatar Oct 30 '24 09:10 cleder

@wesley-murray what is the need for namespaces? When you create a fastkml object it always has name_spaces defined, defaulting to config.NAME_SPACES

Have a look at the documentation, the shapefile.__geo_interface__ exposes a GeoJson like interface.

cleder avatar Oct 30 '24 13:10 cleder

created draft PR for this issue https://github.com/cleder/fastkml/pull/378

apurvabanka avatar Nov 07 '24 05:11 apurvabanka

@cleder Created the PR.....let me know your thoughts on the write function implementation

apurvabanka avatar Nov 12 '24 06:11 apurvabanka