#javascript #ruby-on-rails #openlayers
#javascript #ruby-on-rails #openlayers
Вопрос:
Использование OpenLayers (хотя я думаю, что это проблема JS / Rails) Я рисую прямоугольник,
var source = new VectorSource();
function addInteraction() {
var draw = new Draw({
source: source,
type: 'Circle',
geometryFunction: createBox()
});
map.addInteraction(draw);
draw.on('drawend', function(event) {
var boxCoords = event.feature.getGeometry().getCoordinates()
console.log(" boxCoords: ", boxCoords);
document.getElementById('year_snippet_extent').innerHTML = boxCoords;
});
}
addInteraction();
Вывод журнала консоли (четыре угла прямоугольника, но возвращается к началу, именно так OpenLayers обрабатывает поля рисования, т. Е. Это многоугольник):
boxCoords:
[Array(5)]
0: Array(5)
0: (2) [977.8497980044467, 710.486212043731]
1: (2) [1341.059647947079, 710.486212043731]
2: (2) [1341.059647947079, 754.3238572469668]
3: (2) [977.8497980044467, 754.3238572469668]
4: (2) [977.8497980044467, 710.486212043731]
Что записывается в year_snippet_extent
поле в форме редактирования: 977.8497980044467,710.486212043731,1341.059647947079,710.486212043731,1341.059647947079,754.3238572469668,977.8497980044467,754.3238572469668,977.8497980044467,710.486212043731
Я хочу сохранить это в Postgres в виде массива. Тип данных Postgres — text [], тип данных Rails тот же, хотя моя миграция была array , add_column :years, :snippet_extent, :text, array:true
.
Поле в редактировании <%= form.input :snippet_extent, label: 'Automatically filled when snippet is drawn' %>
Что такое переформатирование массива? Или я должен использовать другой подход?
Я не мог понять, как box_coords
сохранить snippet_extent
напрямую, поэтому придумал этот обходной путь. Я мог бы проанализировать то, что сохранено для моих целей, но подумал, что смогу сделать эту работу правильно.
Вот что я написал, чтобы получить то, что я считаю правильным форматом (мне нужны только нижний левый и верхний правый углы):
var minx = Math.round(boxCoords.[0].[0].[0])
var miny = Math.round(boxCoords.[0].[0].[1])
var maxx = Math.round(boxCoords.[0].[2].[0])
var maxy = Math.round(boxCoords.[0].[2].[1])
var snippetExtent = "{[[" String(minx) "," String(miny) "],[" String(maxx) "," String(maxy) "]]}"
Не так сложно, но я надеялся, что это не обязательно. Я округляю, чтобы упростить чтение, а точность не имеет смысла.
Комментарии:
1. Да, вы обнаружили, что объект массива не является HtmlString . Но поскольку движок JavaScript тоже это знает, он делает все возможное, чтобы интерпретировать ваши намерения: он строит ваш массив для вас. Если вам нужен определенный формат, лучшим подходом было бы предоставить строку там, где она требуется.
2. Итак, мне нужно проанализировать массив и сделать его любой строкой, которую я хочу? Это то, что я сделал изначально, но затем мне пришлось «разобрать» его, чтобы использовать, и это показалось мне большой проблемой, поскольку Rails, JavaScript и Postgres знают о массивах. Но если это то, чего хочет JS!
3. Первое, что нужно понять при вычислениях клиент / сервер, это то, что они не связаны напрямую. Им нужен протокол связи (на самом деле несколько), чтобы помочь перенести информацию с клиента на сервер. Этот протокол HTTP — Hyper_TEXT_ — это то, что передает протокол. На этом фоне one понимает, что структуры данных на клиенте должны быть сериализованы в строки перед отправкой с использованием протокола. также понятно, что текст должен быть переведен обратно в соответствующую структуру данных на другом конце. JavaScript и Ruby используют один и тот же инструментарий:
JSON.*
4. Спасибо. Это хорошее напоминание. В Rails и JavaScript много волшебства, и это продолжается только до сих пор. Я переписываю его сейчас.
Ответ №1:
Мы используем листовку, но делаем что-то очень похожее: при рисовании геометрии мы показываем модальную форму с формой и устанавливаем скрытое текстовое поле, содержащее геометрию.
Мы используем postgis, поэтому мы сразу сохраняем представление geojson в этом скрытом поле. Не совсем уверен, возможно ли это с помощью OpenLayers (уверен, что это так, просто не сразу его нашел). Но, возможно, это не самый простой формат для вас? Если вы используете postgis и activerecord-postgis gem, вы можете просто назначить geojson геометрии.
Но если нет, вам придется самостоятельно проанализировать geojson (что не слишком сложно, но определенно немного сложнее).
Итак, как упоминалось в комментариях: JSON — гораздо лучший формат обмена, всегда используемый в API, поскольку и JS, и Rails очень хорошо с ним справляются.
Итак, в вашем JS вы могли бы написать:
document.getElementById('year_snippet_extent').innerHTML = JSON.stringify(boxCoords);
и в конце rails вы должны преобразовать его обратно в то, что было помещено в него следующим образом:
box_coords = JSON.parse(params[:year_snippet_extent])
Комментарии:
1. Рэнди Касберн: Спасибо, что указали мне правильное направление, и особенно спасибо @nathanvda за конкретику. Мне пришлось провести много рефакторинга, поскольку я устроил такой беспорядок, пытаясь делать разные вещи. Также пришлось создать столбец замены как:json. Когда я все заработаю, я покажу решение, хотя оно в значительной степени соответствует приведенному выше. КСТАТИ, хранение в (скрытом) поле — это просто JS и Rails. У меня установлен PostGIS, потому что я думал, что он мне понадобится, но до сих пор использовал с Postgres. Однако я должен попробовать PostGIS.