Question

How to build a fme Line from json array?

  • 20 June 2017
  • 3 replies
  • 36 views

Badge

I have a json array which a represents the shortest path between two locations. My question is how could I convert this array to a line in to use it later on LineOnAreaOverlayer transformer.

"geometry": {
          "paths": [
            [
              [
                -13660298.311,
                5735294.6307
              ],
              [
                -13660298.5799,
                5735271.5189
              ],
              [
                -13660196.166000001,
                5735271.5189
              ],
              [
                -13660188.373599999,
                5735271.5189
              ],
              [
                -13660085.9597,
                5735253.980499998
              ],
              [
                -13659999.1305,
                5735056.277500004
              ],
              [
                -13659796.529,
                5735037.145199999
              ],
              [
                -13659799.8686,
                5734917.5691
              ],
              [
                -13659798.7554,
                5734762.919799998
              ],
              [
                -13659800.981800001,
                5734649.724600002
              ],
              [
                -13659671.8512,
                5734649.724600002
              ],
              [
                -13659505.985199999,
                5734581.170500003
              ],
              [
                -13659238.8184,
                5734491.891400002
              ],
              [
                -13659235.478799999,
                5734381.888099998
              ],
              [
                -13659233.2524,
                5734310.147600003
              ],
              [
                -13659232.1392,
                5734182.610299997
              ],
              [
                -13659231.026,
                5734153.9146
              ],
              [
                -13659228.7996,
                5734050.292199999
              ],
              [
                -13659229.9128,
                5733984.931000002
              ],
              [
                -13659231.026,
                5733798.415100001
              ],
              [
                -13659232.1392,
                5733761.750100002
              ],
              [
                -13659200.2391,
                5733761.574100003
              ]
            ]
          ]
        }


3 replies

Userlevel 5
Badge +25

I think I got it... I've saved your array in to a text file and using a text line reader, set to read the whole file at once, so it ends up as 1 feature with a single attribute. I use a JSONFlattener which turns the JSON into a nested list, then 2 ListExploders to get to the stuff I need, a VertexCreator to make points and a LineBuilder to connect them into a line. Hope this helps.

textline2none.fmw

Userlevel 2
Badge +17

Hi @rrdlpl, although the "paths" array in the sample JSON document contains only a single element (segment = array of coordinates [x, y]), it can also contain two or more segments. Is there a case where a "paths" consists of multiple segments?

If yes, there are at lease three possible geometry types that can be created from the "paths" array, and you will have to decide which one is preferable.

  1. Connect all segments to form a single IFMELine geometry.
  2. Build an IFMEPath geometry consisting of the segments (only if the segments always form a consecutive polyline shape).
  3. Build an IFMEMultiCurve geometry consisting of the segments.

@redgeographics' solution creates an IFMELine geometry. If you need to build IFMEPath or IFMEMultiCurve, some improvement should be done on the workflow.

Userlevel 2
Badge +17

I believe that @redgeographics' solution is the regular tactics, but there could also be other ways depending on your preference,

for Pythonists:

0684Q00000ArKm2QAF.png

# PythonCaller Script Example
import fmeobjects, json
def buildLine(feature):
    coords = json.loads(feature.getAttribute('text_line_data'))
    feature.setGeometry(fmeobjects.FMELine([(c[0], c[1]) for c in coords]))

for XML lovers:

0684Q00000ArLCHQA3.png

(: XMLTemplater Template Expression Example:)
declare namespace gml="http://www.opengis.net/gml/3.2";
<gml:LineString><gml:posList>{
for $i in (0 to xs:integer(fme:get-attribute("_element_count")) - 1)
return fme:get-list-attribute(fn:concat("array{", $i, "}.array{}"))
}</gml:posList></gml:LineString>

[Addition] GeoJSON version:

0684Q00000ArLCPQA3.png

{
    "type" : "LineString",
    "coordinates" : fme:get-json-attribute("text_line_data")
}

Which one do you like?

Reply