PostgreSQL GeoJSON & lt; — php — & gt; JavaScript

Я нахожусь в муках восстановления чего-то, что было построено почти год назад (не спрашивайте, куда делась старая версия — это неловко).

Основная функциональность использует $.getJSON (ajax-ish) вызов в javascript, который запускает скрипт PHP, который выполняет запрос PostgreSQL, который создает объект JSON и возвращает его. (Пауза для дыхания).

Проблема в том, что PostgreSQL выплевывает, когда наступает его очередь.

Я знаю о build_json_object() а также build_json_array() функциональность в PostgreSQL 9.4+, но одна из БД, на которой он должен работать, не была обновлена ​​с 9.2, и у меня нет времени сделать это в следующем месяце или около того.

Сейчас я использую row_to_json() (а также ST_AsGeoJSON() на геометрию), чтобы построить мою коллекцию GeoJSON, которая возвращается к клиенту через обратный вызов.

Принимая мой сигнал от это очень хороший пост (и оставаясь в очень маленьком эпсилоне структуры запроса этого поста), я запускаю следующий запрос:

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 а также $bounds предоставляются PHP от POST переменные).

Когда я fetchAll(PDO::FETCH_ASSOC) этот запрос к $result, а также json_encode($result[0]["row_to_json"]), объект, возвращаемый в JavaScript, является объектом, который может быть JSON.parse()дала ожидаемое Object с FeatureCollection который в свою очередь содержит кучу Featureс, один из которых geometry).

Все идет нормально. И быстро — получает данные и возвращается через секунду или около того.

Проблема в том, что на этапе запроса массив материала, который относится к геометрии, заключен в двойные кавычки: соответствующий сегмент JSON для отдельного человека. Feature похоже

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

Это то, что я получаю, если копирую результат запроса PostgreSQL в файл: это перед любым неправильным обращением с выводом.

Обратите внимание на (двойные экранированные) двойные кавычки, которые влияют только на атрибуты (в не-JSON-смысле) геометрии {type, coordinates}: бит «геометрия» выглядит

"geometry":"{stuff}"

вместо

"geometry":{stuff}

Если JSON, созданный PostgreSQL, пропускается через анализатор / средство проверки в GeoJSONLint, он умирает в кричащей куче (что и должно быть — это абсолютно не «spec») — и, конечно, он никогда не будет отображаться: он выплевывает «недопустимый тип» «Как вы могли ожидать.

На данный момент я разобрался по куче (мой обычный М.О.) — когда $.getJSON возвращает объект, я

  1. превратить его в строку, а затем
  2. .replace(/"{/g, '{') а также .replace(/}"/g, '}') а также .replace(/\\/g, ''), а потом
  3. превратить его обратно в объект и приступить к махинациям.

Это не очень хорошая практика (если не сказать больше): было бы гораздо лучше, если бы сам запрос заставлял возвращать корректный GeoJSON.

Кажется очевидным, что проблема заключается в row_to_json() Этап: он видит набор атрибутов для «геометрии» и обрабатывает его иначе, чем набор атрибутов для «свойств» — он (неверно) экранирует «геометрию» (после косой черты во всех двойных кавычках) один, но ( правильно) оставляет «свойства» один как есть.

Итак, после этой прелюдии на всю книгу … вопрос.

Есть ли какой-то нюанс в запросе, который я пропускаю или игнорирую? У меня есть RTFD для соответствующих команд PostgreSQL, и кроме переключателей prettification я ничего не знаю.

И, конечно, если бы существовал скупой способ совершить круговое путешествие, я бы его принял: единственное предостережение заключается в том, что он должен сохранять свою «живую» природу — $.getJSON работает под слушателем, который запускает «холостые» на карте Google, а также исходную таблицу, представляющие интерес переменные и масштаб (который определяет $bounds) определяются пользователем.

(Думайте об этом как о способе иметь слой карты, который обновляется с панорамированием и масштабированием, выбирая только ~ 200-300 простых (кадастровых) объектов за раз -0 намного лучше, чем генерировать пирамиду листов для целое состояние для масштабирования 10-19. Держу пари, кто-то уже сделал такую ​​вещь на bl.ocks, но я не нашел это).

2

Решение

Похоже, вы пропустили актерский состав в JSON.
Так должно быть

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

Без преобразования st_asgeojson возвращает строку с двойным кодированием.

Однако вы также можете получить атрибуты и geoJson, затем json_decode json с PHP, создать массив коллекций объектов geoJson с php и, наконец, json_encode весь результат.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]