如何更新KML以包括具有值的新元素 [英] How to update a KML to include a new Element with a value

查看:105
本文介绍了如何更新KML以包括具有值的新元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个KML,它在元素地标"下没有元素名称".因此,使用Google Earth打开KML时,树下的每个多边形旁边都没有显示名称.

I have a KML that does not have the Element "name" under Element Placemark. As such, when opening the KML using Google Earth, there is no name appearing next to each polygon under the tree.

在下面的原始kml中,有2个地标.每个都有一个元素simpleData name ="ID".与它们关联的2个值分别是FM2和FM3.

In the original kml below, there are 2 Placemark. Each has an Element simpleData name="ID". The 2 values associated with them are FM2 and FM3 respectively.

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" 
xmlns:gx="http://www.google.com/kml/ext/2.2" 
xmlns:kml="http://www.opengis.net/kml/2.2" 
xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
    <name>Test.kml</name>
    <open>1</open>
    <Schema name="test" id="S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
        <SimpleField type="string" name="ID"> <displayName>&lt;b&gt;ID&lt;/b&gt;</displayName>
    </SimpleField>
    <SimpleField type="string" name="cname"><displayName>&lt;b&gt;cname&lt;/b&gt;</displayName>
    </SimpleField>
    </Schema>
    <Style id="falseColor01">
        <BalloonStyle>
            <text><![CDATA[<table border="0"><tr> 
            <td>b>ID</b>/td>td>$[test/ID]</td></tr>
            <tr><td><b>cname</b></td><td>$[test/cname]</td></tr>
            </table>]]></text>
        </BalloonStyle>
        <LineStyle>
            <color>ffffff00</color>
            <width>3</width>
        </LineStyle>
        <PolyStyle>
            <color>ffffff00</color>
            <colorMode>random</colorMode>
            <fill>0</fill>
        </PolyStyle>
    </Style>
    <StyleMap id="falseColor0">
        <Pair>
            <key>normal</key>
            <styleUrl>#falseColor00</styleUrl>
        </Pair>
        <Pair>
            <key>highlight</key>
            <styleUrl>#falseColor01</styleUrl>
       </Pair>
    </StyleMap>
    <Style id="falseColor00">
      <BalloonStyle>   
      </BalloonStyle>
        <LineStyle>
            <color>ffffff00</color>
            <width>3</width>
        </LineStyle>
        <PolyStyle>
            <color>ffffff00</color>
            <colorMode>random</colorMode>
            <fill>0</fill>
        </PolyStyle>
    </Style>
    <Folder id="layer 0">
        <name>Test_1</name>
        <open>1</open>
        <Placemark>
            <styleUrl>#falseColor0</styleUrl>
            <ExtendedData>
                <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
                    <SimpleData name="ID">FM2</SimpleData>
                    <SimpleData name="cname">FM2</SimpleData>
                </SchemaData>
            </ExtendedData>
            <Polygon>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>150.889999,-32.17281600000001,0 
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
        <Placemark>
            <styleUrl>#falseColor0</styleUrl>
            <ExtendedData>
                <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
                    <SimpleData name="ID">FM3</SimpleData>
                    <SimpleData name="cname">FM3</SimpleData>
                </SchemaData>
            </ExtendedData>
            <Polygon>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>150.90104,-32.15662800000001,0
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
    </Folder>
</Document>
</kml>

在@DanielHaley的帮助下,我能够读取元素值FM2和FM3.

With the help of @DanielHaley, I was able to read the Element values FM2 and FM3.

如何从通过使用lmxl

然后,我尝试使用lxml etree教程在每个元素下添加一个元素名称",分别具有值"FM2"和"FM3".我没有运气.

I then tried to used lxml etree tutorial to add an Element "name" under each , with values "FM2" and "FM3" respectively. I didn't have any luck.

这是我期望得到的:

    <Folder id="layer 0">
        <name>Test_1</name>
        <open>1</open>
        <Placemark>
            <name>FM2</name>
            <styleUrl>#falseColor0</styleUrl>
            <ExtendedData>
                <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
                    <SimpleData name="ID">FM2</SimpleData>
                    <SimpleData name="cname">FM2</SimpleData>
                </SchemaData>
            </ExtendedData>
            <Polygon>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>150.889999,-32.17281600000001,0 
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
        <Placemark>
            <name>FM3</name>
            <styleUrl>#falseColor0</styleUrl>
            <ExtendedData>
                <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
                    <SimpleData name="ID">FM3</SimpleData>
                    <SimpleData name="cname">FM3</SimpleData>
                </SchemaData>
            </ExtendedData>
            <Polygon>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>150.90104,-32.15662800000001,0
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
    </Folder>

有人可以给我一个提示吗?

Could anyone please give me a hint?

如果可能的话,还可以请您解释一下有关命名空间的概念吗?我已经研究过Google的教程,但说明还不够完整.

If possible, could you also please explain a little bit about the concept of namespace? I have looked into Google's tutorial, but the explanation is not quite complete.

推荐答案

如果要修改Placemark,请首先选择它.

If you want to modify Placemark, select that first.

然后创建一个新的name元素,并从SimpleData中提取该值以用作其文本值.

Then create the new name element and pull the value from SimpleData to use as the text value for it.

最后将新元素插入Placemark.

示例...

Python

from lxml import etree

ns = {"kml": "http://www.opengis.net/kml/2.2"}

# Using a parser to improve formatting of new "name" elements
# and, most importantly, to preserve CDATA sections.
parser = etree.XMLParser(remove_blank_text=True, strip_cdata=False)

tree = etree.parse("test.kml", parser=parser)

for placemark in tree.xpath("//kml:Placemark", namespaces=ns):
    # Create new "name" element in kml namespace ({http://www.opengis.net/kml/2.2}name).
    name_element = etree.Element(etree.QName(ns.get("kml"), "name"), nsmap=ns)

    # Set value of "name" element to value from SimpleData.
    name_element.text = placemark.xpath("kml:ExtendedData/kml:SchemaData/kml:SimpleData[@name='ID']/text()",
                                        namespaces=ns)[0]

    # Insert the new element into "placemark" as the first child.
    placemark.insert(0, name_element)

print(etree.tostring(tree, pretty_print=True).decode("UTF-8"))

打印的XML输出

<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
  <Document>
    <name>Test.kml</name>
    <open>1</open>
    <Schema name="test" id="S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
      <SimpleField type="string" name="ID">
        <displayName>&lt;b&gt;ID&lt;/b&gt;</displayName>
      </SimpleField>
      <SimpleField type="string" name="cname">
        <displayName>&lt;b&gt;cname&lt;/b&gt;</displayName>
      </SimpleField>
    </Schema>
    <Style id="falseColor01">
      <BalloonStyle>
        <text><![CDATA[<table border="0"><tr> 
            <td>b>ID</b>/td>td>$[test/ID]</td></tr>
            <tr><td><b>cname</b></td><td>$[test/cname]</td></tr>
            </table>]]></text>
      </BalloonStyle>
      <LineStyle>
        <color>ffffff00</color>
        <width>3</width>
      </LineStyle>
      <PolyStyle>
        <color>ffffff00</color>
        <colorMode>random</colorMode>
        <fill>0</fill>
      </PolyStyle>
    </Style>
    <StyleMap id="falseColor0">
      <Pair>
        <key>normal</key>
        <styleUrl>#falseColor00</styleUrl>
      </Pair>
      <Pair>
        <key>highlight</key>
        <styleUrl>#falseColor01</styleUrl>
      </Pair>
    </StyleMap>
    <Style id="falseColor00">
      <BalloonStyle>   
            </BalloonStyle>
      <LineStyle>
        <color>ffffff00</color>
        <width>3</width>
      </LineStyle>
      <PolyStyle>
        <color>ffffff00</color>
        <colorMode>random</colorMode>
        <fill>0</fill>
      </PolyStyle>
    </Style>
    <Folder id="layer 0">
      <name>Test_1</name>
      <open>1</open>
      <Placemark>
        <name>FM2</name>
        <styleUrl>#falseColor0</styleUrl>
        <ExtendedData>
          <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
            <SimpleData name="ID">FM2</SimpleData>
            <SimpleData name="cname">FM2</SimpleData>
          </SchemaData>
        </ExtendedData>
        <Polygon>
          <outerBoundaryIs>
            <LinearRing>
              <coordinates>150.889999,-32.17281600000001,0 
                            </coordinates>
            </LinearRing>
          </outerBoundaryIs>
        </Polygon>
      </Placemark>
      <Placemark>
        <name>FM3</name>
        <styleUrl>#falseColor0</styleUrl>
        <ExtendedData>
          <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
            <SimpleData name="ID">FM3</SimpleData>
            <SimpleData name="cname">FM3</SimpleData>
          </SchemaData>
        </ExtendedData>
        <Polygon>
          <outerBoundaryIs>
            <LinearRing>
              <coordinates>150.90104,-32.15662800000001,0
                            </coordinates>
            </LinearRing>
          </outerBoundaryIs>
        </Polygon>
      </Placemark>
    </Folder>
  </Document>
</kml>

此外,请参阅此处,以获取有关XML命名空间的更多信息.解释比我在这里做得更好.

Also, see here for more information on XML Namespaces. It does a better job explaining than I could do here.

这篇关于如何更新KML以包括具有值的新元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆