如何将谷歌地图 GeoJSON 转换为 GPX,保留位置名称

问题描述 投票:0回答:3

我已通过外卖工具导出了我的谷歌地图兴趣点(保存的地点/地点)。我如何将其转换为 GPX,以便我可以将其导入 OSMAnd?

我尝试使用 gpsbabel:

gpsbabel -i geojson -f my-saved-locations.json -o gpx -F my-saved-locations_converted.gpx

但这并没有保留每个兴趣点的标题/名称 - 而是只使用了 WPT001、WPT002 等名称。

python google-maps gps geojson gpx
3个回答
1
投票

最后我通过创建一个小的 python 脚本来在格式之间进行转换来解决这个问题。 这可以很容易地适应特定需求:

#!/usr/bin/env python3

import argparse
import json
import xml.etree.ElementTree as ET
from xml.dom import minidom


def ingestJson(geoJsonFilepath):
    poiList = []
    with open(geoJsonFilepath) as fileObj:
        data = json.load(fileObj)
        for f in data["features"]:
            poiList.append({'title': f["properties"]["Title"],
                            'lon': f["geometry"]["coordinates"][0],
                            'lat': f["geometry"]["coordinates"][1],
                            'link': f["properties"].get("Google Maps URL", ''),
                            'address': f["properties"]["Location"].get("Address", '')})
    return poiList


def dumpGpx(gpxFilePath, poiList):
    gpx = ET.Element("gpx", version="1.1", creator="", xmlns="http://www.topografix.com/GPX/1/1")
    for poi in poiList:
        wpt = ET.SubElement(gpx, "wpt", lat=str(poi["lat"]), lon=str(poi["lon"]))
        ET.SubElement(wpt, "name").text = poi["title"]
        ET.SubElement(wpt, "desc").text = poi["address"]
        ET.SubElement(wpt, "link").text = poi["link"]
    xmlstr = minidom.parseString(ET.tostring(gpx)).toprettyxml(encoding="utf-8", indent="  ")
    with open(gpxFilePath, "wb") as f:
        f.write(xmlstr)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--inputGeoJsonFilepath', required=True)
    parser.add_argument('--outputGpxFilepath', required=True)
    args = parser.parse_args()

    poiList = ingestJson(args.inputGeoJsonFilepath)
    dumpGpx(args.outputGpxFilepath, poiList=poiList)


if __name__ == "__main__":
    main()

...

可以这样调用:

./convert-googlemaps-geojson-to-gpx.py \
  --inputGeoJsonFilepath my-saved-locations.json \
  --outputGpxFilepath my-saved-locations_converted.gpx

0
投票

还有一个名为“togpx”的 NPM 脚本: https://github.com/tyrasd/togpx

我没有尝试过,但它声称保留尽可能多的信息。


0
投票

为了使 GPX 针对 OrganicMaps 进行优化并处理一堆 Google 边缘情况(例如缺少坐标和加星标的地方的描述),我修改了 @DrGecko 的代码,如下所示:

#!/usr/bin/env python3

import argparse
import json
import re
import xml.etree.ElementTree as ET
from xml.dom import minidom


def ingestJson(geoJsonFilepath):
    poiList = []
    with open(geoJsonFilepath, encoding='utf-8') as fileObj:
        data = json.load(fileObj)
        gmQuery = re.compile("http://maps.google.com/\\?q=([-0-9.]+),([-0-9.]+)")
        for f in data["features"]:
            title = f["properties"].get("location", {}).get("name", '')
            gmapsUrl = f["properties"].get("google_maps_url", '')
            lon = f["geometry"]["coordinates"][0]
            lat = f["geometry"]["coordinates"][1]
            cmt = f["properties"].get("Comment", '')
            link = f["properties"].get("google_maps_url", '')

            # Fill in blanks for Organic Maps
            if cmt == '':
                cmt = '<a href="'+link+'">'+link+'</a>'

            # Handle starred places without proper coordinates/comments
            if lat == 0 and lon == 0:
                if title == '':
                    title = "Starred Place"
                matches = gmQuery.findall(gmapsUrl)
                if len(matches) == 1 and len(matches[0]) == 2:
                    lat = matches[0][0] # Google order is backwards from GeoJSON
                    lon = matches[0][1]
                else:
                    # We have basically no information, so at least provide OM the link
                    cmt = '<a href="'+link+'">'+link+'</a>'

            poiList.append({'title': title,
                            'comment': cmt,
                            'date': f["properties"]["date"],
                            'lon': lon,
                            'lat': lat,
                            'link': link,
                            'address': f["properties"].get("location", {}).get("address", '')})
    return poiList


def dumpGpx(gpxFilePath, poiList):
    gpx = ET.Element("gpx", version="1.1", creator="", xmlns="http://www.topografix.com/GPX/1/1")
    for poi in poiList:
        wpt = ET.SubElement(gpx, "wpt", lat=str(poi["lat"]), lon=str(poi["lon"]))
        ET.SubElement(wpt, "name").text = poi["title"]
        ET.SubElement(wpt, "desc").text = poi["address"]
        ET.SubElement(wpt, "cmt").text = poi["comment"]
        ET.SubElement(wpt, "link").text = poi["link"]
        ET.SubElement(wpt, "time").text = poi["date"]
        ext = ET.SubElement(wpt, "extensions")
        ET.SubElement(ext, "color").text = "0000ff"
    xmlstr = minidom.parseString(ET.tostring(gpx)).toprettyxml(encoding="utf-8", indent="  ")
    with open(gpxFilePath, "wb") as f:
        f.write(xmlstr)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--inputGeoJsonFilepath', required=True)
    parser.add_argument('--outputGpxFilepath', required=True)
    args = parser.parse_args()

    poiList = ingestJson(args.inputGeoJsonFilepath)
    dumpGpx(args.outputGpxFilepath, poiList=poiList)


if __name__ == "__main__":
    main()
© www.soinside.com 2019 - 2024. All rights reserved.