On Sun, Oct 11, 2009 at 10:01:46PM +0200, Guilhem Bonnefille wrote:
G> 2009/10/6 Gleb Smirnoff <gleb...@glebius.int.ru>:
G> > On Wed, Sep 30, 2009 at 10:17:32PM +0200, Guilhem Bonnefille wrote:
G> > G> Yes, you correctly found the entry point. VikMapSource is the
G> > G> "interface", the really base class of the MapSource tree. In order to
G> > G> implement a MapSource, you have to prefer to derive from
G> > G> VikMapSourceDefault, a less abstract class, adding a property based
G> > G> implementation for some aspects of the VikMapSource interface.
G> > G> Then, you have to provide implementation for coord_to_mapcoord,
G> > G> mapcoord_to_center_coord and download methods.
G> > G>
G> > G> I'm not really familliar with some aspect of Viking's internals. With
G> > G> my knowledge, Viking is built around the concept of tiles. Probably
G> > G> because the first Maps supported are based on tiles map servers. But I
G> > G> also think because an interesting part of Viking is its ability to
G> > G> browse maps OFFLINE. So you need to store image on disk, and using
G> > G> tiles is a good system for this.
G> > G>
G> > G> Do you think it is possible to request many tiles to a WMS server?
G> > G>
G> > G> An other big difference between WMS and current supported "protocols"
G> > G> (if I can call this stuff as is) is the "variables":
G> > G> - tiles based systems requires three variables: X, Y and Zoom
G> > G> - WMS require a bounding box.
G> > G> When the Viking engine reclaim a new tile to a MapSource, it gives a
G> > G> MapCoord, a struct containing x, y, z and scale. So the difficulty is
G> > G> to compute the bounding box from this info.
G> >
G> > The more I ponder into code the more I want to create WMS as a new layer,
G> > do not inherit anything from Map layer. It is too tile based and proj
G> > coordinates based. While WMS doesn't have tiles and doesn't need any
G> > latlon(VikCoord) <-> xy(MapCoord) conversions.
G> >
G> > Also, the killer feature I'd need in WMS layer would be dragging of the
G> > layer, to fit badly georefed satellite imagery to GPS traces. Looks like
G> > it won't be easy to implement this in maps layer.
G> >
G> > What do you think about creating new VikLayer for WMS?
G> >
G> I suggest you to expose you ideas on the list. And most of all, feel
G> free to implement your needs as you feel it. If you think it would be
G> easier to implement this as a new Layer, let's go. We will then
G> discuss around code.
Yes, implementing it as a VikLayer is very cheap. No calculations at all.
Just pass the corner coordinates to server and it will return an image.
Well, this approach quite hungry for traffic... But I'm now targeting at
localhost WMS server. I want to use Viking in a car PC for navigation
w/o internet access.
Attached is a simplemost WMS support. Can't even be called a work in progress,
just a proof of concept. It has hardcoded URL, and it doesn't have separate
thread for downloading. However it works:
http://glebius.int.ru/tmp/viking-wms.png
I'm going to add three more things to it:
1) separate download thread
2) choosing URL via menu
3) drag'n'drop the layer, to fix poorly georeferenced data
And then tidy up code.
All other implementations, I know, they use a tiled approach to WMS. Once
attached to WMS source, they select a tile size based on current zoom level,
and split their requests into a serie of tiles and then merge the tiles in
local pix buffer. The pros of this approach is decent caching, within one
browsing session however. The cons are that once started with given tile size
they stick to it, so if user zooms in, the client would still request a large
tile and then cut a small piece out of it and stretch it resulting in a
poor image; or if user zooms out, the client make a lot of small requests
to server, overloading both server and himself.
--
Totus tuus, Glebius.
GLEB-RIPE
#include "globals.h"
#include <locale.h>
#include <glib/gstdio.h>
#include "download.h"
#include "vikviewport.h"
#include "viklayer.h"
#include "vikwmslayer.h"
#include "icons/icons.h"
static VikWMSLayer *wms_layer_new(VikViewport *);
static void wms_layer_draw (VikWMSLayer *, VikViewport *);
VikLayerInterface vik_wms_layer_interface = {
.name = "WMS",
.icon = &vikmapslayer_pixbuf,
.menu_items_selection = VIK_MENU_ITEM_ALL,
.create = (VikLayerFuncCreate )wms_layer_new,
.draw = (VikLayerFuncDraw )wms_layer_draw,
};
struct _VikWMSLayer {
VikLayer vl;
};
static DownloadOptions options = { NULL, 0, NULL };
static VikWMSLayer *wms_layer_new(VikViewport *vvp)
{
VikWMSLayer *vwl = VIK_WMS_LAYER(g_object_new(VIK_WMS_LAYER_TYPE,
NULL));
vik_layer_init(VIK_LAYER(vwl), VIK_LAYER_WMS);
return (vwl);
}
static void wms_layer_draw (VikWMSLayer *vwl, VikViewport *vp)
{
gdouble minx, miny, maxx, maxy;
gint width, height;
gchar *locale, *uri;
GdkPixbuf *pixbuf;
GError *gx = NULL;
int res;
vik_viewport_get_min_max_lat_lon(vp, &miny, &maxy, &minx, &maxx);
width = vik_viewport_get_width(vp);
height = vik_viewport_get_height(vp);
locale = setlocale(LC_NUMERIC, "C");
uri = g_strdup_printf("/wms/sovmil?Request=GetMap&srs=EPSG:4326&bbox=%2.8f,%2.8f,%2.8f,%2.8f&width=%u&height=%u",
minx, miny, maxx, maxy, width, height);
setlocale(LC_NUMERIC, locale);
#define FNAME "/tmp/viktest.jpg"
g_unlink(FNAME);
res = a_http_download_get_url("localhost", uri, FNAME, &options);
g_free(uri);
pixbuf = gdk_pixbuf_new_from_file(FNAME, &gx);
if (gx != NULL) {
g_warning ("Couldn't open image file: %s", gx->message);
g_error_free(gx);
if (pixbuf)
g_object_unref(G_OBJECT(pixbuf));
pixbuf = NULL;
return;
}
vik_viewport_draw_pixbuf(vp, pixbuf, 0, 0, 0, 0, -1, -1);
}
GType vik_wms_layer_get_type()
{
static GType vwl_type = 0;
if (!vwl_type) {
static const GTypeInfo vwl_info = {
.class_size = sizeof (VikWMSLayerClass),
.instance_size = sizeof (VikWMSLayer),
};
vwl_type = g_type_register_static(VIK_LAYER_TYPE, "VikWMSLayer",
&vwl_info, 0 );
}
return (vwl_type);
}
#ifndef _VIKING_WMSLAYER_H
#define _VIKING_WMSLAYER_H
#define VIK_WMS_LAYER_TYPE (vik_wms_layer_get_type())
#define VIK_WMS_LAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
VIK_WMS_LAYER_TYPE, VikWMSLayer))
#define VIK_WMS_LAYER_CLASS(class) (G_TYPE_CHECK_CLASS_CAST((class), \
VIK_WMS_LAYER_TYPE, VikWMSLayerClass))
#define IS_VIK_WMS_LAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
VIK_WMS_LAYER_TYPE))
#define IS_VIK_WMS_LAYER_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE((class), \
VIK_WMS_LAYER_TYPE))
GType vik_wms_layer_get_type();
typedef struct _VikWMSLayerClass VikWMSLayerClass;
struct _VikWMSLayerClass
{
VikLayerClass object_class;
};
typedef struct _VikWMSLayer VikWMSLayer;
#endif /* _VIKING_WMSLAYER_H */
diff --git a/configure.ac b/configure.ac
index 6b86f99..a107f2c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -221,6 +221,19 @@ case $ac_cv_enable_dem24k in
esac
AM_CONDITIONAL([DEM24K], [test x$ac_cv_enable_dem24k = xyes])
+AC_ARG_ENABLE(wms, AC_HELP_STRING([--enable-wms],
+ [enable WMS support (default is enable)]),
+ [ac_cv_enable_wms=$enableval],
+ [ac_cv_enable_wms=yes])
+AC_CACHE_CHECK([whether to enable WMS support],
+ [ac_cv_enable_wms], [ac_cv_enable_wms=yes])
+case $ac_cv_enable_wms in
+ yes)
+ AC_DEFINE(VIK_CONFIG_WMS, [], [WMS SUPPORT])
+ ;;
+esac
+AM_CONDITIONAL([WMS], [test x$ac_cv_enable_wms = xyes])
+
# Realtime GPS tracking
AC_ARG_ENABLE(realtime-gps-tracking, AC_HELP_STRING([--enable-realtime-gps-tracking],
[enable realtime GPS tracking (default is enable)]),
diff --git a/src/Makefile.am b/src/Makefile.am
index 796ca74..e2e9a7b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -139,6 +139,11 @@ libviking_a_SOURCES += \
geonamessearch.c geonamessearch.h
endif
+if WMS
+libviking_a_SOURCES += \
+ vikwmslayer.c vikwmslayer.h
+endif
+
viking_SOURCES = main.c
LDADD = libviking.a $(PACKAGE_LIBS) @EXPAT_LIBS@ @LIBCURL@ icons/libicons.a
diff --git a/src/viklayer.c b/src/viklayer.c
index e85427e..f3e6406 100644
--- a/src/viklayer.c
+++ b/src/viklayer.c
@@ -38,6 +38,7 @@ extern VikLayerInterface vik_coord_layer_interface;
extern VikLayerInterface vik_georef_layer_interface;
extern VikLayerInterface vik_gps_layer_interface;
extern VikLayerInterface vik_dem_layer_interface;
+extern VikLayerInterface vik_wms_layer_interface;
enum {
VL_UPDATE_SIGNAL,
@@ -126,6 +127,7 @@ static VikLayerInterface *vik_layer_interfaces[VIK_LAYER_NUM_TYPES] = {
&vik_gps_layer_interface,
&vik_maps_layer_interface,
&vik_dem_layer_interface,
+ &vik_wms_layer_interface,
};
VikLayerInterface *vik_layer_get_interface ( gint type )
diff --git a/src/viklayer.h b/src/viklayer.h
index 0225fe5..df8beda 100644
--- a/src/viklayer.h
+++ b/src/viklayer.h
@@ -71,6 +71,7 @@ enum {
VIK_LAYER_GPS,
VIK_LAYER_MAPS,
VIK_LAYER_DEM,
+ VIK_LAYER_WMS,
VIK_LAYER_NUM_TYPES
};
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Viking-devel mailing list
Viking-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/viking-devel
Viking home page: http://viking.sf.net/