Archivo de la etiqueta: xml

Marcando entidades eliminadas en archivos .KML

En la entrada KML pasa a ser un ciudadano de primera categoría en Digi3D.NET en el blog de Digi21 informamos que ahora podemos trabajar con archivos .kml de forma nativa.

Una de las características más importantes en Digi3D.NET es la posibilidad de marcar entidades como eliminadas. Gracias a podemos recuperar entidades eliminadas y podemos deshacer operaciones mediante la orden UNDO.

Los archivos .kml no tienen el concepto de Entidad marcada como eliminada. Si quieres eliminar la entidad, la eliminas del archivo .kml.

Pero afortunadamente los archivos .kml son archivos .xml, y existe una cosa maravillosa llamada Espacios de nombres y es gracias a esto como conseguimos eliminar entidades en un archivo .kml.

Este es el comienzo de un archivo .kml puro:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
    <Document>

Y este otro es el comienzo de un archivo .kml en el cual hemos eliminado una entidad con Digi3D.NET:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2" 
     xmlns:d3d="http://schemas.digi21.net/digi3d/extensions/1.0">
    <Document>

Como puedes comprobar, Digi3D.NET ha añadido la declaración del espacio de nombres http://schemas.digi21.net/digi3d/extensions/1.0 (no intentes entrar en esa dirección porque no es una URL, no vas a encontrar nada en esa dirección) y se indica que en el documento se va a referir a ese espacio de nombres mediante el prefijo: d3d.

Veamos ahora el comienzo de una entidad en el archivo .kml:

        <Placemark>
            <name>160101name>
            <description>LINEA DE ACERAdescription>

y ahora cómo marca Digi3D.NET esa misma entidad como eliminada:

        <Placemark d3d:Deleted="-1">
            <name>160101name>
            <description>LINEA DE ACERAdescription>

Como puedes comprobar, Digi3D.NET añade al nodo Placemark un atributo de tipo d3d:Deleted. Como este atributo pertenece al espacio de nombres http://schemas.digi21.net/digi3d/extensions/1.0 para Google Earth es como si no existiera. Hemos añadido información sin afectar en absoluto al formato original.

Para recuperar una entidad con Digi3D.NET tenemos dos posibilidades, o cambiamos el valor del atributo de -1 (en realidad sería cualquier número distinto de 0) a 0 o directamente eliminamos el atributo. Digi3D.NET se decanta por esta última opción: elimina el atributo.

Cuando comprimes el archivo de se eliminan del archivo .kml los nodos que tengan asociado un atributo de tipo d3d:Deleted con valor distinto de cero.

A continuación te muestro cómo añadimos el atributo con la definición del espacio de nombres en el nodo raíz del documento .xml (esta parte de Digi3D.NET está programada en C++), y se utiliza MSXML para manipular archivos .xml:

auto atributo = docPtr->createNode(MSXML2::NODE_ATTRIBUTE, _bstr_t("xmlns:d3d"), _bstr_t(""));
atributo->nodeValue = _variant_t("http://schemas.digi21.net/digi3d/extensions/1.0");
docPtr->documentElement->Getattributes()->setNamedItem(atributo);

De la siguiente manera añadimos a una entidad un atributo para indicar que la entidad está eliminada:

auto atributo = docPtr->createNode(MSXML2::NODE_ATTRIBUTE, _bstr_t("d3d:Deleted"), _bstr_t("http://schemas.digi21.net/digi3d/extensions/1.0"));
atributo->nodeValue = _variant_t(true);
nodo->Getattributes()->setNamedItem(atributo);

De la siguiente manera eliminamos un atributo:

nodo->Getattributes()->removeQualifiedItem(_bstr_t("Deleted"), _bstr_t("http://schemas.digi21.net/digi3d/extensions/1.0"));

…y por último, de esta manera comprobamos si la entidad está eliminada cuando cargamos el archivo de dibujo:

auto eliminado = placemark->selectSingleNode(_bstr_t("@d3d:Deleted"));
if( eliminado != NULL )
  entidad->Borrado = (bool)eliminado->nodeValue;