3 votos

¿Por qué ogr2ogr silencio omitir algunas filas?

Tengo un archivo CSV llamado office_locations.csv que contiene datos de puntos. Quiero cargar en un Servidor SQL server base de datos geoespacial mediante ogr2ogr.

El archivo CSV está codificado en UTF-8. Contiene un encabezado y 14902 registros.

Las primeras líneas de este aspecto:

Id,Name,Lat,Lng,CountryCode,Address,CityName,Airport,AirportCode,RailwayStation,PostalCode,StateCode,StateProv,Country_Id
"7188","Tirana Airport","41.42108838","19.71271276","AL","Tirana Airport Muhamet Gjollesha Str., Muhamet Gjollesha Str., Tirana","Tirana","1","TIA","0","","","",0
"30768","Tirana Downtown","41.332","19.832","AL","Rruga E Durresit. Nr 61, Tirana","Tirana","0","","0","","","",0
"52400","Sheraton Italia Square","0.0","0.0","AL","Square Italia Hotel Sheraton , Tirana,","Tirana","0","","0","","","",0
"4650","Escaldes","42.511","1.548","AD","Avda. Miquel Mateu, 25, Escaldes-engordany , Andorra, Ad700","Andorra","0","","0","AD700","","",1
"152576","Andorra","42.508","1.522","AD","Avda D Enclar, 142, Andorra La Vella, Ad500","Andorra La Vella","0","","0","AD500","","",1

Estoy trabajando en una estación de trabajo Windows 7.

Mi GDAL versión 1.9.2.

ogr2ogr importar registros de salta

Para importar datos CSV utilizando ogr2ogr usted necesita para crear un archivo VRT. He creado uno que se parece a esto:

<OGRVRTDataSource>
    <OGRVRTLayer name="office_locations">
        <SrcDataSource>office_locations.csv</SrcDataSource>
        <GeometryType>wkbPoint</GeometryType>
        <LayerSRS>WGS84</LayerSRS>
        <GeometryField encoding="PointFromColumns" x="Lng" y="Lat"/>
    </OGRVRTLayer>
</OGRVRTDataSource>

Cuando yo uso el archivo VRT, ogr2ogr sólo lee y escribe 4977 características:

$ ogr2ogr --debug ON -overwrite -f MSSQLSpatial  "MSSQL:server=.;database=OfficeImport;trusted_connection=yes" office_locations.vrt
OGR: OGROpen(office_locations.vrt/02F28328) succeeded as VRT.
OGR_MSSQLSpatial: EstablishSession(Connection:"server=.;database=OfficeImport;trusted_connection=yes")
ODBC: SQLDriverConnect(DRIVER=SQL Server;server=.;database=OfficeImport;trusted_connection=yes)
OGR: OGROpen(MSSQL:server=.;database=OfficeImport;trusted_connection=yes/02F3CFB8) succeeded as MSSQLSpatial.
OGR: OGROpen(office_locations.csv/02F3C808) succeeded as CSV.
OGR_MSSQLSpatial: Using column ogr_fid as FID for table office_locations.
OGR2OGR: 4977 features written in layer 'office_locations'
ODBC: SQLDisconnect()
VRT: 4977 features read on layer 'office_locations'.
CSV: 4977 features read on layer 'office_locations'.

Dos tercios de los de los registros han sido silenciosamente saltado!

Encontrar los registros que faltan

En la columna id en el archivo CSV contiene un identificador único para cada oficina. Puedo ordenar por que para encontrar los registros que faltan.

Para ordenar las filas en la base de datos he utilizado un comando como este:

$ sqlcmd -d OfficeImport -Q "SELECT id, name FROM office_locations ORDER BY CAST(id AS INT);" | more
id   name


---- -------------------------------------------------------
11   Dublin - Airport
21   Dublin - Finglas
36   Brussels - Charleroi Airport
42   Crete - Chania Marna
79   Lesvos - Airport
83   Corfu - New Port
[...]

Para ordenar las filas en la hoja de cálculo que utiliza Excel 2010 es una Especie característica de la ficha Datos.

Descubrí que la oficina de 47 es la primera falta de registro:

 "47","Fuerteventura - Airport","28.452","-13.87","ES","Aeropuerto Fue L.7, El Matorral.pto Del Rosario, Fuerteventura, 35610","Fuerteventura","1","FUE","0","35610","","",136

El aislamiento de la fila omitida

He creado un nuevo archivo CSV llamado test_import.csv que contiene sólo la oficina de 47 y un encabezado:

Id,Name,Lat,Lng,CountryCode,Address,CityName,Airport,AirportCode,RailwayStation,PostalCode,StateCode,StateProv,Country_Id
"47","Fuerteventura - Airport","28.452","-13.87","ES","Aeropuerto Fue L.7, El Matorral.pto Del Rosario, Fuerteventura, 35610","Fuerteventura","1","FUE","0","35610","","",136

Y un nuevo VRT llamado test_import.vrt que se parece a esto:

<OGRVRTDataSource>
    <OGRVRTLayer name="test_import">
        <SrcDataSource>test_import.csv</SrcDataSource>
        <GeometryType>wkbPoint</GeometryType>
        <LayerSRS>WGS84</LayerSRS>
        <GeometryField encoding="PointFromColumns" x="Lng" y="Lat"/>
    </OGRVRTLayer>
</OGRVRTDataSource>

ogr2ogr la salida de depuración muestra que 1 función se leen y se escriben:

$ ogr2ogr --debug ON -overwrite -f MSSQLSpatial  "MSSQL:server=.;database=Argus;trusted_connection=yes" test_import.vrt
OGR: OGROpen(test_import.vrt/03488318) succeeded as VRT.
OGR_MSSQLSpatial: EstablishSession(Connection:"server=.;database=Argus;trusted_connection=yes")
ODBC: SQLDriverConnect(DRIVER=SQL Server;server=.;database=Argus;trusted_connection=yes)
OGR_MSSQLSpatial: Using column ogr_fid as FID for table argus_locations.
OGR_MSSQLSpatial: Using column ogr_fid as FID for table location.
OGR_MSSQLSpatial: Using column ogr_fid as FID for table location_utf8.
OGR_MSSQLSpatial: Using column ogr_fid as FID for table office_locations.
OGR_MSSQLSpatial: Using column ogr_fid as FID for table test_import.
OGR: OGROpen(MSSQL:server=.;database=Argus;trusted_connection=yes/0349CFA8) succeeded as MSSQLSpatial.
OGR: OGROpen(test_import.csv/0349D868) succeeded as CSV.
MSSQLSpatial: DeleteLayer(test_import)
OGR_MSSQLSpatial: Using column ogr_fid as FID for table test_import.
OGR2OGR: 1 features written in layer 'test_import'
ODBC: SQLDisconnect()
VRT: 1 features read on layer 'test_import'.
CSV: 1 features read on layer 'test_import'.

Esta vez la oficina de 47 es importado, pero la última vez que se ha omitido.

¿Por qué es esta fila se omite en el archivo completo, pero importados en el archivo de prueba?

¿Por qué no ogr2ogr reconoce que las filas se omiten?

Cuántas columnas de cada tabla?

MappaGnosis preguntó: "¿cuántas columnas a la única oficina (47) la importación de la tabla de atributos y cuántos no la original de importación?"

La entrada del archivo CSV tiene 14 columnas:

$ powershell -Command "(Import-Csv -Path 'office_locations.csv' | Get-Member -Type NoteProperty).Count"
14

El original de la tabla de importación se llama office_locations, y la oficina única de importación de la tabla se llama test_import. Cada uno tiene 16 columnas:

SELECT
  OBJECT_NAME(object_id) AS table_name,
  COUNT(*) AS column_count
FROM sys.columns
WHERE object_id IN (OBJECT_ID(N'test_import'), OBJECT_ID(N'office_locations'))
GROUP BY object_id;

table_name         column_count
-----------------  ------------
office_locations   16
test_import        16

ogr2ogr crea una columna para cada uno de los campos en los archivos CSV, y genera dos columnas adicionales, ogr_fid y ogr_geometry.

Importar sólo los identificadores y las coordenadas

Darren hacer Frente sugirió: "se Puede crear un segundo .csv con todos los registros, pero tira a cabo todas las columnas excepto el ID y lat/lon columnas? Intente importar que, y ver si todos los registros de venir. A veces hay un incorrectamente delimitado fila a un lugar que confundir las cosas, y es difícil elegir visualmente..."

He utilizado este comando de PowerShell para la extracción de la id, lngy lat columnas de la office_locations.csv archivo:

$ powershell -Command "(Import-Csv -Path 'office_locations.csv') | Select Id, Lng, Lat | Export-Csv -NoTypeInformation -Encoding UTF8 -Path 'office_minimal.csv'"

Creó un nuevo archivo CSV llamado office_minimal.csv. Contiene la cantidad mínima de datos para localizar e identificar cada una de las oficinas.

Las primeras líneas de este aspecto:

"Id","Lng","Lat"
"7188","19.71271276","41.42108838"
"30768","19.832","41.332"
"52400","0.0","0.0"
"4650","1.548","42.511"
"152576","1.522","42.508"

He creado una correspondiente VR archivo llamado office_minimal.vrt. Se parece a esto:

<OGRVRTDataSource>
    <OGRVRTLayer name="office_minimal">
        <SrcDataSource>office_minimal.csv</SrcDataSource>
        <GeometryType>wkbPoint</GeometryType>
        <LayerSRS>WGS84</LayerSRS>
        <GeometryField encoding="PointFromColumns" x="Lng" y="Lat"/>
    </OGRVRTLayer>
</OGRVRTDataSource>

El uso de la nueva 'mínimo' de los archivos, ogr2ogr las importaciones de todos los 14902 filas:

$ ogr2ogr --debug ON -overwrite -f MSSQLSpatial  "MSSQL:server=.;database=OfficeImport;trusted_connection=yes" office_minimal.vrt
OGR: OGROpen(office_minimal.vrt/03388328) succeeded as VRT.
OGR_MSSQLSpatial: EstablishSession(Connection:"server=.;database=OfficeImport;trusted_connection=yes")
ODBC: SQLDriverConnect(DRIVER=SQL Server;server=.;database=OfficeImport;trusted_connection=yes)
OGR_MSSQLSpatial: Using column ogr_fid as FID for table office_locations.
OGR_MSSQLSpatial: Using column ogr_fid as FID for table test_import.
OGR: OGROpen(MSSQL:server=.;database=OfficeImport;trusted_connection=yes/0339CFB8) succeeded as MSSQLSpatial.
OGR: OGROpen(office_minimal.csv/033A0F48) succeeded as CSV.
OGR_MSSQLSpatial: Using column ogr_fid as FID for table office_minimal.
OGR2OGR: 14902 features written in layer 'office_minimal'
ODBC: SQLDisconnect()
VRT: 14902 features read on layer 'office_minimal'.
CSV: 14902 features read on layer 'office_minimal'.

5voto

Tomáš Zato Puntos 835

Hay un delimitador que faltan

Al inspeccionar el archivo me di cuenta de que Excel analiza algunos de los registros en más de 14 columnas:

enter image description here

Ver la imagen completa aquí si no está claro en el Intercambio de la Pila.

Oficina 151393 se analiza en 18 columnas. He resaltado el Address y RailwayStation columnas debido a que los valores en estas columnas contienen trailing caracteres de comillas dobles.

CSV utiliza las comillas dobles como un carácter de control, y no espero a que mis datos haber detrás de comillas dobles, por lo que sospecho que algo está mal con el formato.

En office_locations.csv el registro de la oficina de 151393 se parece a esto:

"151393","Yalta - Downtown","44.498","34.173","UA","Hotel "massandra", Drazhinskogo, 46, Yalta, 98600","Yalta","0","","0","98600","","",156

Si nos centramos en cómo la Address valor codificado:

"Hotel "massandra", Drazhinskogo, 46, Yalta, 98600"

Vemos que la codificación contiene sin escape dobles comillas, que es un formato no válido.

Es de suponer que la intención de la codificación se veía así:

"Hotel ""massandra"", Drazhinskogo, 46, Yalta, 98600"

El problema

PowerShell Import-Csv cmdlet cuenta el número de filas correcto:

$ powershell -Command "(Import-Csv -Path 'office_locations.csv').Count"
14902

Para la oficina de 151393 produce los mismos valores en cada columna, por detrás de comillas dobles incluyen:

$ powershell -Command "Import-Csv -Path 'office_locations.csv' | Where id -eq '151393'"


Id             : 151393
Name           : Yalta - Downtown
Lat            : 44.498
Lng            : 34.173
CountryCode    : UA
Address        : Hotel massandra"
CityName       : Drazhinskogo
Airport        : 46
AirportCode    : Yalta
RailwayStation : 98600"
PostalCode     : Yalta
StateCode      : 0
StateProv      :
Country_Id     : 0

Al parecer PowerShell puede analizar el archivo de Excel hasta los primeros 14 columnas. Los valores que no corresponden a un nombre de campo se eliminen en silencio.

La exportación de Csv, puede escribir a los 14 columnas a un formato correcto CSV:

$ powershell -Command "Import-Csv -Path 'office_locations.csv' | Export-Csv -NoTypeInformation -Encoding UTF8 -Path 'office_ps_filter.csv'"

Esto es como el comando que se utiliza para la extracción de la Id, Lngy Lat columnas. Porque he quitado la Seleccione filtro, todas las columnas están implícitamente exportado.

El comando crea un archivo nuevo con el nombre office_ps_filter.csv. En el registro de la oficina de 151393 se parece a esto:

 "151393","Yalta - Downtown","44.498","34.173","UA","Hotel massandra""","Drazhinskogo","46","Yalta","98600""","Yalta","0","","0"

Esta vez, la final de dobles comillas en la Address y RailwayStation columnas están correctamente escapado.

Para importar utilizando ogr2ogr me la creación de la correspondiente VRT llamado office_ps_filter.vrt. Se parece a esto:

<OGRVRTDataSource>
    <OGRVRTLayer name="office_ps_filter">
        <SrcDataSource>office_ps_filter.csv</SrcDataSource>
        <GeometryType>wkbPoint</GeometryType>
        <LayerSRS>WGS84</LayerSRS>
        <GeometryField encoding="PointFromColumns" x="Lng" y="Lat"/>
    </OGRVRTLayer>
</OGRVRTDataSource>

ogr2ogr la salida de depuración muestra que todos los 14902 los registros se escriben en SQL Server:

$ ogr2ogr --debug ON -overwrite -f MSSQLSpatial  "MSSQL:server=.;database=OfficeImport;trusted_connection=yes" office_ps_filter.vrt
OGR: OGROpen(office_ps_filter.vrt/03353F80) succeeded as VRT.
OGR_MSSQLSpatial: EstablishSession(Connection:"server=.;database=OfficeImport;trusted_connection=yes")
ODBC: SQLDriverConnect(DRIVER=SQL Server;server=.;database=OfficeImport;trusted_connection=yes)
OGR_MSSQLSpatial: Using column ogr_fid as FID for table office_locations.
OGR_MSSQLSpatial: Using column ogr_fid as FID for table office_minimal.
OGR_MSSQLSpatial: Using column ogr_fid as FID for table test_import.
OGR: OGROpen(MSSQL:server=.;database=OfficeImport;trusted_connection=yes/030DFC38) succeeded as MSSQLSpatial.
OGR: OGROpen(office_ps_filter.csv/0333FFB8) succeeded as CSV.
OGR_MSSQLSpatial: Using column ogr_fid as FID for table office_ps_filter.
OGR2OGR: 14902 features written in layer 'office_ps_filter'
ODBC: SQLDisconnect()
VRT: 14902 features read on layer 'office_ps_filter'.
CSV: 14902 features read on layer 'office_ps_filter'.

Conclusión

Mi archivo CSV fue mal formateados. Debería ir a la fuente de el archivo para solucionar el problema de formato.

Para responder a la presentación de la pregunta, ogr2ogr se comporta de forma extraña cuando el CSV de entrada está mal formateado, sin ninguna indicación de que hay un problema de formato.

Importar Csv se maneja mal con formato de archivos CSV con mayor fuerza de ogr2ogr.

El Id, Lngy Lat campos antes de venir a la Address de campo, por lo que el formato incorrecto en el Address campo no les afectan. Tuve suerte cuando he extraído sólo las columnas y logró importar todos los registros.

XmlToCsv produce no válido CSV (Sección de bonos)

Esto proporciona el contexto a la pregunta y explica cómo la inválida CSV se ha generado.

La fuente de datos fue proporcionada en el formato XML, sin un esquema. Aunque vestida como XML, los datos fue esencialmente tabular.

Cada registro se presenta como un elemento, y cada campo se presenta como un atributo.

Me produce el archivo CSV que hemos discutido aquí pasando el archivo de origen a través de XmlToCsv, una utilidad gratuita que convierte archivos XML a CSV.

En el archivo de origen en el registro de la oficina de 151393 se parece a esto:

<Location Id="151393" Name="Yalta - Downtown" Lat="44.498" Lng="34.173" CountryCode="UA" Address="Hotel &quot;massandra&quot;, Drazhinskogo, 46, Yalta, 98600" CityName="Yalta" PostalCode="98600" Airport="0" RailwayStation="0"/>

He copiado el único elemento en un archivo llamado 151393.xml y pasó a través de XmlToCsv.Consola:

$ XmlToCsv.Console -xml 151393.xml -dir .

La utilidad produce un archivo de salida por tipo de elemento. Para esta entrada, Se produjo un archivo llamado Location.csv.

La salida se parece a esto:

Id,Name,Lat,Lng,CountryCode,Address,CityName,PostalCode,Airport,RailwayStation
"151393","Yalta - Downtown","44.498","34.173","UA","Hotel "massandra", Drazhinskogo, 46, Yalta, 98600","Yalta","98600","0","0"

La salida contiene sin escape doble-comillas que corresponden a los XML codificado con comillas dobles. En XML se parecen a esto: &quot;.

Parece XmlToCsv no manejar correctamente las comillas dobles incrustado en el campo de los valores.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X