geoJson & KML 沒有呈現顏色(樣式)

geoJson & KML 並沒有規範style,也就是"不支援樣式"的意思

什麼是GeoJSON

專門處理地理資訊 (GIS) 結構的 JSON 標準格式。 一個 GeoJSON 物件可以用來代表點 (Point),線 (LineString),多邊形 (Polygon) 等等的幾何結構,以及特徵 (Feature) 的集合,或是一系列的特徵 (FeatureCollection)。

每一筆資料都會是一個「Feature」物件,地理位置相關資訊會存放在 geometry 物件內,其中分別有「type」以及「coordinates」屬性,type 用來表示資料類別,可以是點,線,甚至是多邊形等;而 coordinates 用來存放經緯度座標。而其他的相關資訊則會放在「properties」內,以 key: value 方式呈現。
quote

範例

簡單的 GeoJSON 會像這樣:

{
    "type": "FeatureCollection",
    "features": [{
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [102.0, 0.5]
        },
        "properties": {
            "prop0": "value0"
        }
    }, {
        "type": "Feature",
        "geometry": {
            "type": "LineString",
            "coordinates": [
                [102.0, 0.0],
                [103.0, 1.0],
                [104.0, 0.0],
                [105.0, 1.0]
            ]
        },
        "properties": {
            "prop0": "value0",
            "prop1": 0.0
        }
    }, {
        "type": "Feature",
        "geometry": {
            "type": "Polygon",
            "coordinates": [
                [
                    [100.0, 0.0],
                    [101.0, 0.0],
                    [101.0, 1.0],
                    [100.0, 1.0],
                    [100.0, 0.0]
                ]
            ]
        },
        "properties": {
            "prop0": "value0",
            "prop1": {
                "this": "that"
            }
        }
    }]
}

想要更了解可以到 MapBox 製作的 geojson.io 玩玩

Tip: GeoJSON 明確規範了空間形狀,對於 style 並未明確規範

Tip: no circle

KML

定義

Keyhole Markup Language,是基於XML(eXtensible Markup Language,可擴展標記語言)語法標準的一種標記語言(markup language),採用標記結構,含有嵌套的元素和屬性。由Google(谷歌)旗下的Keyhole公司發展並維護,用來表達地理標記。根據KML語言編寫的文件則為KML文件,格式同樣採用的XML文件格式,應用於Google地球相關軟體中(Google Earth,Google Map, Google Maps for mobile...),用於顯示地理數據(包括點、線、面、多邊形,多面體以及模型...)

KML在2008年4月14日被OGC(Open Geospatial Consortium, Inc.開放地理信息系統協會,或譯成開放式地理空間協會)宣布為開放地理資訊編碼標準(OGC KML, OpenGIS® KML Encoding Standard)quote

包括點、線、面和影像,以及圖形、圖片、屬性和 HTML 等相關內容。單個 KML 檔可以包含不同類型的要素,並可包含影像。

範例

geoJsion.io 輸出的 kml 長這樣

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
   <Document>
      <Placemark>
         <ExtendedData>
            <Data name="stroke">
               <value>#555555</value>
            </Data>
            <Data name="stroke-width">
               <value>2</value>
            </Data>
            <Data name="stroke-opacity">
               <value>1</value>
            </Data>
            <Data name="fill">
               <value>#07a32b</value>
            </Data>
            <Data name="fill-opacity">
               <value>0.5</value>
            </Data>
         </ExtendedData>
         <Polygon>
            <outerBoundaryIs>
               <LinearRing>
                  <coordinates>121.4208984375,24.661994379101547 121.19842529296875,24.499645635732882 121.3714599609375,24.412140070651528 121.39343261718749,24.489648077028683 121.4208984375,24.661994379101547</coordinates>
               </LinearRing>
            </outerBoundaryIs>
         </Polygon>
      </Placemark>
      <Placemark>
         <ExtendedData />
         <Point>
            <coordinates>121.35223388671875,24.923804001418254</coordinates>
         </Point>
      </Placemark>
      <Placemark>
         <ExtendedData>
            <Data name="stroke">
               <value>#5c44ea</value>
            </Data>
            <Data name="stroke-width">
               <value>5</value>
            </Data>
            <Data name="stroke-opacity">
               <value>1</value>
            </Data>
         </ExtendedData>
         <LineString>
            <coordinates>121.53350830078124,24.407137917727653 121.58294677734374,24.27951614412046 121.387939453125,24.17682515045749</coordinates>
         </LineString>
      </Placemark>
   </Document>
</kml>

google map 輸出的 kml 長這樣

<?xml version='1.0' encoding='UTF-8'?>
<kml xmlns='http://www.opengis.net/kml/2.2'>
    <Document>
        <name>(無標題的圖層)</name>
        <Placemark>
            <name>線條 2</name>
            <styleUrl>#line-DB4436-4-nodesc</styleUrl>
            <LineString>
                <tessellate>1</tessellate>
                <coordinates>121.3728333,24.8627646,0.0 121.6062927,24.8689944,0.0 121.5719604,24.7817473,0.0</coordinates>
            </LineString>
        </Placemark>
        <Placemark>
            <name>點 3</name>
            <styleUrl>#icon-503-F4EB37-nodesc</styleUrl>
            <Point>
                <coordinates>121.2533569,24.8739781,0.0</coordinates>
            </Point>
        </Placemark>
        <Style id='icon-503-F4EB37-nodesc-normal'>
            <IconStyle>
                <color>ff37EBF4</color>
                <scale>1.1</scale>
                <Icon>
                    <href>http://www.gstatic.com/mapspro/images/stock/503-wht-blank_maps.png</href>
                </Icon>
                <hotSpot x='16' y='31' xunits='pixels' yunits='insetPixels'>
                </hotSpot>
            </IconStyle>
            <LabelStyle>
                <scale>0.0</scale>
            </LabelStyle>
            <BalloonStyle>
                <text><![CDATA[<h3>$[name]</h3>]]></text>
            </BalloonStyle>
        </Style>
        <Style id='icon-503-F4EB37-nodesc-highlight'>
            <IconStyle>
                <color>ff37EBF4</color>
                <scale>1.1</scale>
                <Icon>
                    <href>http://www.gstatic.com/mapspro/images/stock/503-wht-blank_maps.png</href>
                </Icon>
                <hotSpot x='16' y='31' xunits='pixels' yunits='insetPixels'>
                </hotSpot>
            </IconStyle>
            <LabelStyle>
                <scale>1.1</scale>
            </LabelStyle>
            <BalloonStyle>
                <text><![CDATA[<h3>$[name]</h3>]]></text>
            </BalloonStyle>
        </Style>
        <StyleMap id='icon-503-F4EB37-nodesc'>
            <Pair>
                <key>normal</key>
                <styleUrl>#icon-503-F4EB37-nodesc-normal</styleUrl>
            </Pair>
            <Pair>
                <key>highlight</key>
                <styleUrl>#icon-503-F4EB37-nodesc-highlight</styleUrl>
            </Pair>
        </StyleMap>
        <Style id='line-DB4436-4-nodesc-normal'>
            <LineStyle>
                <color>ff3644DB</color>
                <width>4</width>
            </LineStyle>
            <BalloonStyle>
                <text><![CDATA[<h3>$[name]</h3>]]></text>
            </BalloonStyle>
        </Style>
        <Style id='line-DB4436-4-nodesc-highlight'>
            <LineStyle>
                <color>ff3644DB</color>
                <width>6.0</width>
            </LineStyle>
            <BalloonStyle>
                <text><![CDATA[<h3>$[name]</h3>]]></text>
            </BalloonStyle>
        </Style>
        <StyleMap id='line-DB4436-4-nodesc'>
            <Pair>
                <key>normal</key>
                <styleUrl>#line-DB4436-4-nodesc-normal</styleUrl>
            </Pair>
            <Pair>
                <key>highlight</key>
                <styleUrl>#line-DB4436-4-nodesc-highlight</styleUrl>
            </Pair>
        </StyleMap>
    </Document>
</kml>

Tip: still no circle

拿點來舉例

我們從點的描述來確認一下 GeoJson 和 KML 對於 Style 的規範

geoJson

仔細看一下

geojson 的點長這樣

{
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Point",
        "coordinates": [
          61.52343749999999,
          54.97761367069625
        ]
      }
}

轉成 kml 是這樣

 <Placemark>
         <ExtendedData />
         <Point>
            <coordinates>61.52343749999999,54.97761367069625</coordinates>
         </Point>
</Placemark>

這是一個不帶 style 的樣子

如果我想要加上顏色呢
像這樣

 

在 GeoJson 會怎麼描述

來看看在 GeoJson.io 的寫法

 {
      "type": "Feature",
      "properties": {
        "marker-color": "#f805a9",
        "marker-size": "medium",
        "marker-symbol": ""
      },
      "geometry": {
        "type": "Point",
        "coordinates": [
          61.52343749999999,
          54.97761367069625
        ]
      }
}

可以看到在 properties 當中有 mapbox 定義的style樣式。

其實 GeoJson 只有定義 style 要放到 properties 中,
但對於底下的各個屬性名稱,保留 可擴展性 ,並沒有統一。看看 WIKI 就會發現了,WIKI 的舉例非常清楚,請看下圖

 

這樣我們確定了 GeoJSON 並沒有定義樣式

KML

然後來看 KML 的狀況

我們會比較 geojson.io 和 googlemap產出的 KML

這是由 geojson.io 轉出來的 kml

<Placemark>
    <ExtendedData>
            <Data name="marker-color">
               <value>#ef0ebc</value>
            </Data>
            <Data name="marker-size">
               <value>medium</value>
            </Data>
            <Data name="marker-symbol">
               <value />
            </Data>
    </ExtendedData>
    <Point>
            <coordinates>61.52343749999999,54.97761367069625</coordinates>
    </Point>
</Placemark>

把這kml檔匯入到googleMap的地圖 會看到開啟的點是預設樣式,
google很好心的也有把屬性顯示出來

這時在 googlemap 直接編輯,修改點的顏色,一樣匯出成 KML

結果會是和 geojson.io 差異很大

<?xml version='1.0' encoding='UTF-8'?>
<kml xmlns='http://www.opengis.net/kml/2.2'>
    <Document>
        <name>(無標題的圖層)</name>
        <Placemark>
            <name></name>
            <description><![CDATA[說明: <br>marker-color: #ef0ebc<br>marker-size: medium<br>marker-symbol: ]]></description>
            <styleUrl>#icon-503-F4EB37</styleUrl>
            <ExtendedData>
                <Data name='說明'>
                    <value></value>
                </Data>
                <Data name='marker-color'>
                    <value>#ef0ebc</value>
                </Data>
                <Data name='marker-size'>
                    <value>medium</value>
                </Data>
                <Data name='marker-symbol'>
                    <value></value>
                </Data>
            </ExtendedData>
            <Point>
                <coordinates>61.523437,54.977614,0.0</coordinates>
            </Point>
        </Placemark>
        <Style id='icon-503-F4EB37-normal'>
            <IconStyle>
                <color>ff37EBF4</color>
                <scale>1.1</scale>
                <Icon>
                    <href>http://www.gstatic.com/mapspro/images/stock/503-wht-blank_maps.png</href>
                </Icon>
                <hotSpot x='16' y='31' xunits='pixels' yunits='insetPixels'>
                </hotSpot>
            </IconStyle>
            <LabelStyle>
                <scale>0.0</scale>
            </LabelStyle>
        </Style>
        <Style id='icon-503-F4EB37-highlight'>
            <IconStyle>
                <color>ff37EBF4</color>
                <scale>1.1</scale>
                <Icon>
                    <href>http://www.gstatic.com/mapspro/images/stock/503-wht-blank_maps.png</href>
                </Icon>
                <hotSpot x='16' y='31' xunits='pixels' yunits='insetPixels'>
                </hotSpot>
            </IconStyle>
            <LabelStyle>
                <scale>1.1</scale>
            </LabelStyle>
        </Style>
        <StyleMap id='icon-503-F4EB37'>
            <Pair>
                <key>normal</key>
                <styleUrl>#icon-503-F4EB37-normal</styleUrl>
            </Pair>
            <Pair>
                <key>highlight</key>
                <styleUrl>#icon-503-F4EB37-highlight</styleUrl>
            </Pair>
        </StyleMap>
    </Document>
</kml>

結論

所以,KML 和 GeoJSON 一樣沒有特別規範 style 的寫法,btw 兩者也都沒有定義圓。

在公開標準沒有統一樣式的現況( 保留可擴展性 ),所以都是自己做的系統,吃自己吐的 kml 和 geojson;不同系統間,就只能吃形狀,樣式吃不進來,除非要特別符合該系統規範才會特別去刻。

參考Links