【问题标题】:Processing KMZ in Mathematica在 Mathematica 中处理 KMZ
【发布时间】:2011-06-02 16:52:29
【问题描述】:

我被困在转换中。

我有一个带有一些坐标的 KMZ 文件。我是这样阅读文件的:

m=Import["~/Desktop/locations.kmz","Data"]

我得到这样的东西:

{{LayerName->Point Features,
  Geometry->{
    Point[{-120.934,49.3321,372}],
    Point[{-120.935,49.3275,375}],
    Point[{-120.935,49.323,371}]},
  Labels->{},LabeledData->{},ExtendedData->{},
  PlacemarkNames->{1,2,3},
  Overlays->{},NetworkLinks->{}
}}

我想从每个点中提取 {x,y,z} 以及与这些点关联的地标名称 {1,2,3}。即使我可以从 Geometry->{} 中获取点也可以,因为我可以使用 List@@@ 将它们提取到列表中,但是我迷失在无法提取几何的基本部分“规则”。

感谢您的帮助,

罗恩

【问题讨论】:

  • Ron,您能否更新您的答案以显示您从Import 获得的实际数据?它显然应该包含字符串。

标签: wolfram-mathematica rules kmz mathematica-8


【解决方案1】:

虽然 Leonid 的回答是正确的,但您可能会发现它不适用于您的代码。原因是Import 命令的输出包含字符串,例如"LayerNames",而不是符号,例如LayerNames。我已将 KML 文件上传到我的网站空间,因此我们可以使用实际的 Import 命令进行尝试。尝试以下方法:

in = Import["http://facstaff.unca.edu/mcmcclur/my.kml", "Data"];
pointList = "Geometry" /.  
    Cases[in, Verbatim[Rule]["Geometry", _], Infinity];
pointList /. Point[stuff_] -> stuff

再次注意"Geometry" 是一个字符串。其实in的内容是这样的(在InputForm中):

{{"LayerName" -> "Waypoints", 
  "Geometry" -> {Point[{-82.5, 32.5, 0}]}, 
  "Labels" -> {}, "LabeledData" -> {}, 
  "ExtendedData" -> {}, "PlacemarkNames" -> {"asheville"}, 
  "Overlays" -> {}, "NetworkLinks" -> {}}}

上下文:KML 指的是 Keyhole 标记语言。 Keyhole 是一家开发工具的公司,在被谷歌收购后最终成为谷歌地球。 KMZ 是 KML 的压缩版本。

【讨论】:

  • 天哪,伙计们,感谢您直接参与其中。我非常感谢这个小组的响应速度,尤其是对我的一些基本问题。
  • 马克,我建议的简化是否正确?我的逻辑是"Geometry" /. ... 将返回为规则"Geometry" -> ... 找到的第一个值,因此Cases[..., 1] 应该是等价的,假设这样的规则存在于in 中的某处。
  • @Mr.Wizard 您的代码运行良好。我已添加正确版本的导入 KML 文件,您可以尝试一下。
【解决方案2】:

我认为可以安全地简化 Leonid 和 Mark 的答案是删除花哨的 Verbatim 构造。那就是:

Leonid的第一个操作可以写成:

Join @@ Cases[expr, (Geometry -> x_) :> (x /. Point -> Sequence), Infinity]

列昂尼德的第二次行动:

Join @@ Cases[expr, (PlacemarkNames -> x_) :> x, Infinity]

我在导入 Mark 的数据时遇到了麻烦,但据我猜测,可以这样写:

pointList = Cases[in, ("Geometry" -> x_) :> x, Infinity, 1]

我会让这个答案的投票告诉我我是否正确。

【讨论】:

  • @Gandalf KML 导入是 V8 中的新功能。在 V7 中,您可以导入为 XML,如 Import["file.kml","XML"]。当然,你需要对结果进行相应的处理。
  • @Mr.Wizard 你在我的帖子底部看到我的替代方法了吗?我认为这很简单(尽管这并不重要,因为正如@Mark 指出的那样,它不起作用。我基于 OP 的信息,不知道这些是作为字符串返回的)
  • 感谢 Lenoid(和其他所有人),我使用了您的部件(用于地标)和 Mark 的部件。我现在正在尝试简化版本以了解它是如何工作的。
  • @Leonid,是的,我做到了。我只是认为值得指出的是(据我所知)Verbatim 不是必需的。
  • @Mr.Wizard 我明白你的意思。你说的对。如果我不使用Cases 的这种语法,而是使用更简洁的语法(只有一个模式,比如"Geometry" -> x_),那么就需要Verbatim
【解决方案3】:

鉴于你的表情

expr = {{LayerName -> Point Features, 
       Geometry -> {
         Point[{-120.934, 49.3321, 372}], 
         Point[{-120.935, 49.3275, 375}],
         Point[{-120.935, 49.323, 371}]},
     Labels -> {}, LabeledData -> {}, ExtendedData -> {}, 
     PlacemarkNames -> {1, 2, 3}, Overlays -> {}, NetworkLinks -> {}}}

这将提取点:

In[121]:= 
   Flatten[Cases[expr, Verbatim[Rule][Geometry, x_] :> (x /. Point -> Sequence),
        Infinity], 1]

Out[121]= {{-120.934, 49.3321, 372}, {-120.935, 49.3275,375}, {-120.935, 49.323, 371}}

这将提取地标:

In[124]:= Flatten[Cases[expr, Verbatim[Rule][PlacemarkNames, x_] :> x, Infinity], 1]

Out[124]= {1, 2, 3}

这是一个更优雅的方法,利用我们正在寻找的规则,它将提取两者:

In[127]:= 
{Geometry, PlacemarkNames} /.Cases[expr, _Rule, Infinity] /. Point -> Sequence

Out[127]= 
{{{-120.934, 49.3321, 372}, {-120.935, 49.3275,375}, {-120.935, 49.323, 371}}, {1, 2, 3}}

【讨论】:

    【解决方案4】:

    Transpose[{"PlacemarkNames", "Geometry"} /. m[[1]]] 怎么样?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      • 1970-01-01
      • 2011-06-13
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      相关资源
      最近更新 更多