2016-07-16 14 views
2

私は、ほぼ1年前に作られたものを再構築するための苦労をしています(旧バージョンのどこに行ったのか尋ねないでください)。PostgreSQL GeoJSON <- php -> JavaScript

コア機能は、JSONオブジェクトを作成して返すPostgreSQLクエリを実行するPHPスクリプトを実行するjavascriptで$.getJSONajax -ish)呼び出しを使用します。 (息をするために一時停止する)。

この問題は、PostgreSQLが光り輝くときに吐き出すものです。

私はPostgreSQL 9.4以降でbuild_json_object()build_json_array()の機能を認識していますが、これを実行する必要があるDBの1つは9.2からアップグレードされていないため、月程度です。

今のところ、私はGeoJSONコレクションを構築するためにrow_to_json()(そして幾何学的にはST_AsGeoJSON())を使用しています。これは、コールバックを介してクライアントに戻ってきます。

this very nice post(およびそのポストのクエリ構造の非常に小さなイプシロン内に留まる)から私の合図を取ると、私は次のクエリを実行します。

select row_to_json(fc) 
from (SELECT 'FeatureCollection' As type, 
     array_to_json(array_agg(f)) As features 
from (SELECT 'Feature' as type, 
     row_to_json((select l from (select $vars) as l)) as properties, 
     ST_AsGeoJSON(ST_Transform(lg.g1,4326)) as geometry  
     from $source_table as lg 
where g1 && ST_Transform(ST_SetSRID(ST_MakeEnvelope($bounds),4326),4283) 
) as f) as fc; 

$vars$source_table$boundsPOST変数からPHPによって供給されています) 。

I fetchAll(PDO::FETCH_ASSOC)$resultにそのクエリ、およびjson_encode($result[0]["row_to_json"])、オブジェクトはJavaScriptに戻っ期待を持たせるJSON.parse()「D(順番にFeature Sの束が含まれていFeatureCollectionObject、いずれかになりますオブジェクトでありますそのうちgeometry)。

これまでのところ、とても良いです。クイック - データを取得して1秒後に戻ってきます。

問題は、クエリの段階では、幾何学に関連するものの配列は、二重引用符で囲まれていることである。個々のFeatureのためのJSONの関連するセグメントは

{"type":"Feature","geometry":"{\\"type\\":\\"Polygon\\", 
           \\"coordinates\\":"[[[146.885447408,-36.143199088], 
               [146.884964384,-36.143136232], 
               ... etc 
              ]]" 
           }", 
           "properties":{"address_pfi":"126546461", 
              "address":"blah blah", 
              ...etc } 
} 

ように見える。これは何私でありますPostgreSQLのクエリ結果をファイルにコピーするかどうかを確認します。これは、出力が誤って処理される前です。

注ジオメトリ{type, coordinates}の(非JSONの意味での)属性のみに影響を与える(ダブルエスケープ)二重引用符を:「幾何学」のビットが

"geometry":"{stuff}" 

代わりの

のように見えます
"geometry":{stuff} 

PostgreSQLで作成されたJSONがGeoJSONLintのパーサー/チェッカーに置かれていると、それは悲鳴を上げるヒープで死にます(これは絶対に 'スペック'ではありません)。そして、レンダリングすることは決してありません。あなたが期待しているように、「無効なタイプ」を出してしまいます。

私はそれをkludge(私の普通のM.O.) - $.getJSONが、文字列に、私は

  1. ターンそれを、オブジェクトを返す場合
  2. .replace(/"{/g, '{').replace(/}"/g, '}').replace(/\\/g, '')、次いで
  3. ターンそれはバックオブジェクトへとペテンを進めます。

これは良いことではありません(最低限):クエリ自体が有効なGeoJSONを返すように勧められれば、はるかに良いでしょう。

問題はrow_to_json()の段階であることが明らかです:「ジオメトリ」の属性セットを見て、それを「プロパティ」の属性セットとは違って扱います。「ジオメトリ」を「間違って」エスケープします。 (すべての二重引用符をスラッシュエスケープした後に)1つではなく、(正しく)「プロパティ」をそのまま残します。

この本の後ろのプレリュード...質問。

私が紛失しているか無視しているクエリについて、いくつかのニュアンスはありますか?私は関連するPostgreSQLコマンドのRTFDを持っていますが、prettificationスイッチは別として私が知っているものは何もありません。

もちろん、往復全体をやっている間違った方法があれば、私はそれを受け入れます:唯一の注意点は、「ライブフェッチ」性質を保持しなければならないからです。$.getJSONは、 Googleマップで「アイドル」に設定されており、ソーステーブル、関心のある変数、ズーム($boundsを決定)はユーザが決定します。

(それは、パンとズームで更新するマップレイヤーを、一度に~200-300個のシンプルアイ(コーダスト)フィーチャをフェッチするだけで、それよりもはるかに優れていると考えてください。私は誰かがすでにbl.ocksにそのようなことをしていると思うが、私はそれを見つけていない)。

答えて

2

jsonへのキャストが不足しているようです。 それはキャストなし

ST_AsGeoJSON(ST_Transform(lg.g1,4326))::json 

する必要があり、st_asgeojsonはそれは二重エンコードされ、文字列を返します。

しかし、json_decodeよりjson_decodeにPHPを使用してgeoJsonのフィーチャーコレクション配列を作成し、最後にjson_encode全体の結果を属性とgeoJsonで取得することもできます。

+0

** D'oh!**は文字通り私がチェックするつもりはないと思ったこと - 自分自身を 'ST_AsGeoJSON()'と呼ぶ関数が '' json'にキャストされる必要があったこと。私はいつも自分が 'RTFD'(ドキュメンテーションバージョンの' RTFM')に自分自身を公開しないようにしようとしますが、今回は十分にRTFDしませんでした。 PHPですべての 'json_encode'-ing属性を行うことの提案も優れています(今実装されています)。ありがとう、フランチェスコ。 –

関連する問題