Un array anidado está cambiando a una cadena de valores que va desde JavaScript a Rails

Usando OpenLayers (aunque creo que es un asunto de JS/Rails) Dibujo una caja,

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();

Salida del tronco de consola (los cuatro ángulos del rectángulo, pero vuelve a empezar, así es como OpenLayers maneja cajas de dibujo, es decir, es un polígono):

 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]

Lo que se escribe year_snippet_extent un campo en el formulario de edición: 977.8497980044467,710.486212043731,1341.059647947079,710.486212043731,1341.059647947079,754.3238572469668,977.8497980044467,754.3238572469668,977.8497980044467,710.486212043731

Quiero salvar esto a Postgres como un array. El tipo de datos de Postgres es texto [], el tipo de datos Rails es el mismo aunque mi migración era array, add_column :years, :snippet_extent, :text, array:true.

El campo en edición es <%= form.input :snippet_extent, label: 'Automatically filled when snippet is drawn' %>

¿Qué está reformando el array? ¿O debería usar un enfoque diferente?

No pude entender cómo tener box_coords salvados snippet_extent directamente, así que surgió este trabajo. Podría analizar lo que se salva para mis propósitos, pero pensé que debería ser capaz de hacer bien este trabajo.

Esto es lo que escribí para conseguir lo que creo que es el formato correcto (sólo necesito las esquinas izquierda y superior derecha):

 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) + "]]}"

No tanto, pero esperaba que no fuera necesario. Estoy redondeando para facilitar la lectura y la precisión no tiene sentido.

Pregunta hecha hace 3 años, 4 meses, 29 días - Por codesculptor


3 Respuestas:

  • Estamos usando folleto, pero estamos haciendo algo bastante similar: al dibujar una geometría mostramos un modal con una forma, y establecemos un campo de texto oculto para contener la geometría.

    Estamos usando postgis, así que almacenamos inmediatamente la representación geojson en ese campo oculto. No muy seguro si eso es posible usando OpenLayers (pretty seguro que es, simplemente no encontrarlo de inmediato). Pero tal vez ese no es el formato más fácil para ti? Si usted está usando postgis y gema activa-postgis, puede asignar un geojson a una geometría.

    Pero si no, usted tendrá que analizar un geojson usted mismo (que no es demasiado duro, pero definitivamente un poco más complicado).

    Así, como se menciona en los comentarios: JSON es un formato de intercambio mucho mejor, siempre utilizado en API como JS y Rails manejan muy bien.

    Así que en su JS usted podría escribir:

    document.getElementById('year_snippet_extent').innerHTML = JSON.stringify(boxCoords);
    

    y en el extremo de los ferrocarriles lo convertiría de nuevo a lo que se puso en él de la siguiente manera:

    box_coords = JSON.parse(params[:year_snippet_extent])
    

    Respondida el Dec 17, 2020 a las 03:04 - por codecatalyst

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando es que el array anidado boxCoords se está convirtiendo en una cadena de valores cuando intentas guardarlo en el campo snippet_extent. Esto se debe a que el método innerHTML de JavaScript convierte automáticamente los arrays en cadenas de texto antes de asignarlos a un elemento HTML.

    Para solucionar esto y guardar el array boxCoords como un array en tu base de datos Postgres, puedes convertir el array a formato JSON en JavaScript antes de asignarlo al campo innerHTML. De esta manera, mantendrás la estructura de array original.

    Aquí te dejo un ejemplo de cómo puedes hacerlo:

    javascript
    draw.on('drawend', function(event) {
      var boxCoords = event.feature.getGeometry().getCoordinates();
      console.log(" boxCoords: ", boxCoords);
    
      // Convertir el array a JSON
      var snippetExtent = JSON.stringify(boxCoords);
    
      document.getElementById('year_snippet_extent').innerHTML = snippetExtent;
    });
    

    Luego, en tu controlador de Rails, al momento de guardar el valor del campo snippet_extent, puedes convertir el JSON de nuevo a un array antes de guardarlo en la base de datos. Por ejemplo, podrías hacer algo así:

    ruby
    

    En tu controlador de Rails

    snippet_extent_array = JSON.parse(params[:years][:snippet_extent])

    Guardar snippet_extent_array en la base de datos

    De esta manera, deberías poder guardar el array boxCoords correctamente en tu base de datos Postgres utilizando Rails.

    Respondida el Dec 18, 2020 a las 03:02 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El problema es que el array de coordenadas se está convirtiendo en una cadena cuando se asigna a document.getElementById('year_snippet_extent').innerHTML. Para evitar esto, puedes utilizar el método JSON.stringify() para convertir el array en una cadena JSON antes de asignarla.

    
    document.getElementById('year_snippet_extent').innerHTML = JSON.stringify(boxCoords);
    

    Esto dará como resultado una cadena JSON que contiene el array de coordenadas, que Rails puede deserializar en un array.

    En tu migración, también debes asegurarte de que el tipo de datos de snippet_extent sea jsonb en lugar de text. jsonb es un tipo de datos binario optimizado para almacenar datos JSON en PostgreSQL.

    
    add_column :years, :snippet_extent, :jsonb, array: true
    

    Con estos cambios, el array de coordenadas se almacenará correctamente en la base de datos como un array JSONB.

    Respondida el Dec 18, 2020 a las 03:06 - por Gemini

    Votos positivos: 0 | Votos negativos: 0