首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在ReasonML中解码GeoJson?

如何在ReasonML中解码GeoJson?
EN

Stack Overflow用户
提问于 2019-12-22 14:32:46
回答 2查看 274关注 0票数 1

请评论如何在ReasonML中解码GeoJson文件?我尝试在解码器中解码没有“字段纬度和经度”的坐标,但我找不到如何在JSON文件中解析字段坐标的任何信息。

GeoJson文件

代码语言:javascript
复制
 "features": [
     {
       "type": "Feature",
       "geometry": {
         "type": "Point",
         "coordinates": [
           131.469670264,
           33.3158712032
         ]
       },
       "properties": {
         "index": 0,
         "alias": "海地獄-別府市",
         "name": "Umi-Jigoku",
         "image_url": "https://s3-media1.fl.yelpcdn.com/bphoto/7T1aXG9Q3CAtEbwqFm3Nlw/o.jpg"
       }

ReasonML中的JsonDecoder (bs-json)

代码语言:javascript
复制
[@genType]
type properties = {
  index: int,
  alias: string,
  name: string,
  image_url: string,
  geometry: coordinates,
}
and coordinates = {
  latitude: float,
  longitude: float,
};

let places = "../json/alljapan.json";

module Decode = {
  let coordinates = json =>
    Json.Decode.{
      latitude: json |> field("latitude", float),
      longitude: json |> field("longitude", float),
    };

  let properties = json =>
    Json.Decode.{
      index: json |> field("index", int),
      alias: json |> field("alias", string),
      name: json |> field("name", string),
      image_url: json |> field("image_url", string),
      geometry: json |> field("geometry", coordinates),
    };
};

let line = places |> Json.parseOrRaise |> Decode.line;
EN

回答 2

Stack Overflow用户

发布于 2019-12-23 02:22:34

在工作中,我们编写了一个名为GeoReason的库,目标是在RFC-7946 spec之后为GeoJSON数据结构提供原因类型、构造函数、编码器和解码器(以及一些辅助函数,如eq)。

我还没有尝试将该库与React Native一起使用,但我假设它应该可以在任何可以将Reason编译为JS的地方工作。

概述

  • GeoJSON模拟了许多“或”(要素或几何,其中几何是点或线或...)关系,这很容易表达为原因variants
  • GeoJSON是紧凑的,更喜欢数组(作为元组),这很难阅读。我们使用bs-decode
  • "Features“解码带有额外元数据(”属性“字段)的值,它可以是任何带有元数据的
  • 对象……我们不会试图超出一个关键的=> json字典来解码它:Js.Dict.t(Js.Json.t)

用法

假设您有一个Js.Json.t类型的JSON值,并且您已经按照自述文件中的说明安装了GeoReason,您可以这样解码和使用您的数据:

代码语言:javascript
复制
// this is a `Belt.Result` that is either `Ok` with the GeoJSON data, or
// Error with information describing what went wrong while decoding
let decoded = GeoJSON.decode(myFileData);

switch (decoded) {
| Error(parseError) =>
  Decode.ParseError.failureToDebugString(parseError) |> Js.log;

// if the GeoJSON value is a "Feature", it may have the following fields,
// but note that technically all of them are optional according to the spec.
// if you want to decode the dictionary of properties, you can do so here
| Ok(GeoJSON.Feature({id, geometry, properties})) =>
  properties
  ->Belt.Option.flatMap(dict => Js.Dict.get(dict, "image_url"))
  ->Belt.Option.flatMap(json => Js.Json.decodeString(json))
  ->Belt.Option.map(url => /* do something with the url? */);

| Ok(Geometry(Point({latlong, altitude})) =>
  /* use latitude and longitude? */

| Ok(Geometry(Polygon(data))) => /* ... */

| Ok(_) =>
  // lots more cases to handle, like line geometries,
  // geometry collections, feature collections, etc...
};

正如您所看到的,匹配GeoJSON值可能涉及的所有内容是一个相当复杂的过程,因此它有点取决于您希望如何处理这些值。我已经向库中添加了一些辅助函数,比如GeoJSON.getPolygons,它将尝试获取任何类型GeoJSON值的多边形列表(如果没有多边形,则返回一个空列表)。如果有其他有用的帮助器,请随时打开问题。

票数 2
EN

Stack Overflow用户

发布于 2019-12-23 04:53:33

您可能应该使用GeoReason,正如@mlms13建议的那样,但是如果您仍然希望使用bs-json自己解码它,您可以利用BuckleScript中元组作为数组实现的事实,并使用pair解码器来获取值,然后将其转换为您的记录类型:

代码语言:javascript
复制
let coordinates = json =>
  Json.Decode.(
    pair(float, float)
    |> map(((latitude, longitude)) => {latitude, longitude})
  );
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59442145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档