Commit 60471b8e authored by Marcus Lundblad's avatar Marcus Lundblad Committed by Jonas Danielsson
Browse files

osmEdit: Add OSM shim library

The following GObject classes are defined:

MapsOSMObject: An abstract base class representing objects in the
OpenStreetMap database. Has a function to serialize objects to their XML
representation and abstract functions that implementation classes define
to add object-specific XML tags.

MapsOSMNode: Represents an object of type ”node” in OSM. Inherits from
MapsOSMObject.

MapsOSMWay: Represents an object of type ”way” in OSM. Inherits from
MapsOSMObject.

MapsOSMRelation: Represents an object of type ”relation” in OSM.
Inherits from MapsOSMObject.

MapsOSMChangeset: Represents a changeset in OSM. Has a function to
serialize the changeset (with comment and client identifier) to the
XML representation.

maps-osm.[c|h]: Contains parsing functions to read OSM objects from
the raw XML input as downloaded from the OSM database.
Also contains utility functions to initialize and destruct
the libxml2 parser.

https://bugzilla.gnome.org/show_bug.cgi?id=726628
parent e25c9940
......@@ -50,6 +50,7 @@ PKG_CHECK_MODULES(GNOME_MAPS_LIB, [
folks >= $FOLKS_MIN_VERSION
geocode-glib-1.0 >= $GEOCODE_MIN_VERSION
champlain-0.12 >= $CHAMPLAIN_MIN_VERSION
libxml-2.0
])
AC_SUBST(GNOME_MAPS_LIB_CFLAGS)
AC_SUBST(GNOME_MAPS_LIB_LIBS)
......
......@@ -9,12 +9,24 @@ libgnome_maps_headers_private = \
maps-contact.h \
mapsintl.h \
maps.h \
maps-file-tile-source.h
maps-file-tile-source.h \
maps-osm.h \
maps-osm-changeset.h \
maps-osm-node.h \
maps-osm-object.h \
maps-osm-relation.h \
maps-osm-way.h
libgnome_maps_sources = \
maps-contact-store.c \
maps-contact.c \
maps-file-tile-source.c
maps-file-tile-source.c \
maps-osm.c \
maps-osm-changeset.c \
maps-osm-node.c \
maps-osm-object.c \
maps-osm-way.c \
maps-osm-relation.c
libgnome_maps_la_SOURCES = \
$(libgnome_maps_sources) \
......
/*
* Copyright (c) 2015 Marcus Lundblad
*
* GNOME Maps is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* GNOME Maps is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with GNOME Maps; if not, see <http://www.gnu.org/licenses/>
*
* Author: Marcus Lundblad <ml@update.uu.se>
*/
#include "maps-osm-changeset.h"
#include <libxml/xpath.h>
struct _MapsOSMChangesetPrivate
{
char *comment;
char *created_by;
};
enum {
PROP_0,
PROP_COMMENT,
PROP_CREATED_BY
};
G_DEFINE_TYPE_WITH_PRIVATE (MapsOSMChangeset, maps_osm_changeset, G_TYPE_OBJECT)
static void
maps_osm_changeset_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
MapsOSMChangeset *changeset = MAPS_OSMCHANGESET (object);
switch (property_id)
{
case PROP_COMMENT:
changeset->priv->comment = g_value_dup_string (value);
break;
case PROP_CREATED_BY:
changeset->priv->created_by = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
maps_osm_changeset_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
MapsOSMChangeset *changeset = MAPS_OSMCHANGESET (object);
switch (property_id)
{
case PROP_COMMENT:
g_value_set_string (value, changeset->priv->comment);
break;
case PROP_CREATED_BY:
g_value_set_string (value, changeset->priv->created_by);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
maps_osm_changeset_dispose (GObject *object)
{
MapsOSMChangeset *changeset = MAPS_OSMCHANGESET (object);
g_free (changeset->priv->comment);
g_free (changeset->priv->created_by);
G_OBJECT_CLASS (maps_osm_changeset_parent_class)->dispose (object);
}
static void
maps_osm_changeset_class_init (MapsOSMChangesetClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
object_class->dispose = maps_osm_changeset_dispose;
object_class->get_property = maps_osm_changeset_get_property;
object_class->set_property = maps_osm_changeset_set_property;
/**
* MapsOSMChangeset:comment:
*
* The comment of the changes.
*/
pspec = g_param_spec_string ("comment",
"Comment",
"Comment",
NULL,
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_COMMENT, pspec);
/**
* MapsOSMChangeset:created_by:
*
* The identifier of the client making the changeset.
*/
pspec = g_param_spec_string ("created_by",
"Created by",
"Created by",
NULL,
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_CREATED_BY, pspec);
}
static void
maps_osm_changeset_init (MapsOSMChangeset *changeset)
{
changeset->priv = maps_osm_changeset_get_instance_private (changeset);
changeset->priv->comment = NULL;
changeset->priv->created_by = NULL;
}
MapsOSMChangeset *
maps_osm_changeset_new (const char *comment, const char *created_by)
{
return g_object_new (MAPS_TYPE_OSMCHANGESET,
"comment", comment,
"created_by", created_by, NULL);
}
xmlNodePtr
maps_osm_changeset_create_tag_node (const char *key, const char * value)
{
xmlNodePtr node;
node = xmlNewNode (NULL, "tag");
xmlNewProp (node, "k", key);
xmlNewProp (node, "v", value);
return node;
}
char *
maps_osm_changeset_serialize (const MapsOSMChangeset *changeset)
{
xmlDocPtr doc;
xmlNodePtr osm_node;
xmlNodePtr changeset_node;
xmlNodePtr comment_node;
xmlNodePtr created_by_node;
xmlChar *result;
int size;
doc = xmlNewDoc ("1.0");
osm_node = xmlNewNode (NULL, "osm");
changeset_node = xmlNewNode (NULL, "changeset");
comment_node =
maps_osm_changeset_create_tag_node ("comment", changeset->priv->comment);
created_by_node =
maps_osm_changeset_create_tag_node ("created_by",
changeset->priv->created_by);
xmlAddChild (osm_node, changeset_node);
xmlAddChild (changeset_node, comment_node);
xmlAddChild (changeset_node, created_by_node);
xmlDocSetRootElement (doc, osm_node);
xmlDocDumpMemory (doc, &result, &size);
xmlFreeDoc (doc);
return result;
}
/*
* Copyright (c) 2015 Marcus Lundblad
*
* GNOME Maps is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* GNOME Maps is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with GNOME Maps; if not, see <http://www.gnu.org/licenses/>
*
* Author: Marcus Lundblad <ml@update.uu.se>
*/
#ifndef __MAPS_OSM_CHANGESET_H__
#define __MAPS_OSM_CHANGESET_H__
#include <glib-object.h>
#define MAPS_TYPE_OSMCHANGESET maps_osm_changeset_get_type ()
G_DECLARE_FINAL_TYPE(MapsOSMChangeset, maps_osm_changeset, MAPS, OSMCHANGESET,
GObject)
typedef struct _MapsOSMChangesetPrivate MapsOSMChangesetPrivate;
struct _MapsOSMChangeset
{
GObject parent_instance;
MapsOSMChangesetPrivate *priv;
};
struct _MapsOSMChangesetClass
{
GObjectClass parent_class;
};
/**
* maps_osm_changeset_new:
* @comment: (nullable): A comment about the OSM change, optional
* @created_by: (nullable): The client identifier of the OSM change, optional
*/
MapsOSMChangeset *maps_osm_changeset_new (const char *comment,
const char *created_by);
char *maps_osm_changeset_serialize (const MapsOSMChangeset *changeset);
#endif /* __MAPS_OSM_CHANGESET_H__ */
/*
* Copyright (c) 2015 Marcus Lundblad
*
* GNOME Maps is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* GNOME Maps is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with GNOME Maps; if not, see <http://www.gnu.org/licenses/>
*
* Author: Marcus Lundblad <ml@update.uu.se>
*/
#include "maps-osm-node.h"
struct _MapsOSMNodePrivate
{
double lon;
double lat;
};
enum {
PROP_0,
PROP_LONGITUDE,
PROP_LATITUDE
};
G_DEFINE_TYPE_WITH_PRIVATE (MapsOSMNode, maps_osm_node, MAPS_TYPE_OSMOBJECT)
static void
maps_osm_node_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
MapsOSMNode *node = MAPS_OSMNODE (object);
switch (property_id)
{
case PROP_LONGITUDE:
node->priv->lon = g_value_get_double (value);
break;
case PROP_LATITUDE:
node->priv->lat = g_value_get_double (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
maps_osm_node_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
MapsOSMNode *node = MAPS_OSMNODE (object);
switch (property_id)
{
case PROP_LONGITUDE:
g_value_set_double (value, node->priv->lon);
break;
case PROP_LATITUDE:
g_value_set_double (value, node->priv->lat);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static const char *
maps_osm_node_get_xml_tag_name (void)
{
return "node";
}
static GHashTable *
maps_osm_node_get_xml_attributes (const MapsOSMObject *object)
{
const MapsOSMNode *node = MAPS_OSMNODE (object);
GHashTable *attributes;
char buf[G_ASCII_DTOSTR_BUF_SIZE];
attributes = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
g_ascii_dtostr (buf, sizeof (buf), node->priv->lon);
g_hash_table_insert (attributes, "lon", g_strdup (buf));
g_ascii_dtostr (buf, sizeof (buf), node->priv->lat);
g_hash_table_insert (attributes, "lat", g_strdup (buf));
return attributes;
}
static void
maps_osm_node_class_init (MapsOSMNodeClass *klass)
{
GObjectClass *node_class = G_OBJECT_CLASS (klass);
MapsOSMObjectClass *object_class = MAPS_OSMOBJECT_CLASS (klass);
GParamSpec *pspec;
node_class->get_property = maps_osm_node_get_property;
node_class->set_property = maps_osm_node_set_property;
object_class->get_xml_tag_name = maps_osm_node_get_xml_tag_name;
object_class->get_xml_attributes = maps_osm_node_get_xml_attributes;
/**
* MapsOSMNode:longitude:
*
* The longitude of the node.
*/
pspec = g_param_spec_double ("longitude",
"Longitude",
"Longitude",
-180.0,
180.0,
0.0,
G_PARAM_READWRITE);
g_object_class_install_property (node_class, PROP_LONGITUDE, pspec);
/**
* MapsOSMNode:latitude:
*
* The latitude of the node.
*/
pspec = g_param_spec_double ("latitude",
"Latitude",
"Latitude",
-90.0,
90.0,
0.0,
G_PARAM_READWRITE);
g_object_class_install_property (node_class, PROP_LATITUDE, pspec);
}
static void
maps_osm_node_init (MapsOSMNode *node)
{
node->priv = maps_osm_node_get_instance_private (node);
node->priv->lon = 0.0;
node->priv->lat = 0.0;
}
MapsOSMNode *
maps_osm_node_new (guint64 id, guint version, guint64 changeset,
double longitude, double latitude)
{
return g_object_new (MAPS_TYPE_OSMNODE,
"id", id,
"version", version,
"changeset", changeset,
"longitude", longitude,
"latitude", latitude, NULL);
}
/*
* Copyright (c) 2015 Marcus Lundblad
*
* GNOME Maps is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* GNOME Maps is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with GNOME Maps; if not, see <http://www.gnu.org/licenses/>
*
* Author: Marcus Lundblad <ml@update.uu.se>
*/
#ifndef __MAPS_OSM_NODE_H__
#define __MAPS_OSM_NODE_H__
#include "maps-osm-object.h"
#include <glib-object.h>
#define MAPS_TYPE_OSMNODE maps_osm_node_get_type ()
G_DECLARE_FINAL_TYPE(MapsOSMNode, maps_osm_node, MAPS, OSMNODE, MapsOSMObject)
typedef struct _MapsOSMNodePrivate MapsOSMNodePrivate;
struct _MapsOSMNode
{
MapsOSMObject parent_instance;
MapsOSMNodePrivate *priv;
};
struct _MapsOSMNodeClass
{
MapsOSMObjectClass parent_class;
};
MapsOSMNode *maps_osm_node_new (guint64 id, guint version, guint64 changeset,
double longitude, double latitude);
#endif //__MAPS_OSM_NODE_H__
/*
* Copyright (c) 2015 Marcus Lundblad
*
* GNOME Maps is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* GNOME Maps is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with GNOME Maps; if not, see <http://www.gnu.org/licenses/>
*
* Author: Marcus Lundblad <ml@update.uu.se>
*/
#include "maps-osm-object.h"
struct _MapsOSMObjectPrivate
{
guint64 id;
guint version;
guint64 changeset;
GHashTable *tags;
};
enum {
PROP_0,
PROP_ID,
PROP_VERSION,
PROP_CHANGESET
};
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MapsOSMObject, maps_osm_object,
G_TYPE_OBJECT)
static void
maps_osm_object_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
MapsOSMObject *osm_object = MAPS_OSMOBJECT (object);
MapsOSMObjectPrivate *priv =
maps_osm_object_get_instance_private (osm_object);
switch (property_id)
{
case PROP_ID:
priv->id = g_value_get_uint64 (value);
break;
case PROP_VERSION:
priv->version = g_value_get_uint (value);
break;
case PROP_CHANGESET:
priv->changeset = g_value_get_uint64 (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
maps_osm_object_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
MapsOSMObject *osm_object = MAPS_OSMOBJECT (object);
MapsOSMObjectPrivate *priv =
maps_osm_object_get_instance_private (osm_object);
switch (property_id)
{
case PROP_ID:
g_value_set_uint64 (value, priv->id);
break;
case PROP_VERSION:
g_value_set_uint (value, priv->version);
break;
case PROP_CHANGESET:
g_value_set_uint64 (value, priv->changeset);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
maps_osm_object_dispose (GObject *object)
{
MapsOSMObject *osm_object = MAPS_OSMOBJECT (object);
MapsOSMObjectPrivate *priv =
maps_osm_object_get_instance_private (osm_object);
g_hash_table_destroy (priv->tags);
priv->tags = NULL;
G_OBJECT_CLASS (maps_osm_object_parent_class)->dispose (object);
}
/* base implementation returning no object-specific XML attributes */
static GHashTable *
maps_osm_object_get_xml_attributes (const MapsOSMObject *object)
{
return NULL;
}
/* base implementation return no object-specific child XML nodes */
static xmlNodePtr
maps_osm_object_get_xml_child_nodes (const MapsOSMObject *object)
{
return NULL;
}
static void
maps_osm_object_class_init (MapsOSMObjectClass *klass)
{
GObjectClass *maps_class = G_OBJECT_CLASS (klass);
MapsOSMObjectClass *object_class = MAPS_OSMOBJECT_CLASS (klass);