Anunţ

Caută printre mesajele de pe forum înainte de a scrie unul nou!
Formulează corect întrebarea sau problema pe care o ai.
Respectă regulile forumului și Codul de Conduită!

#1 26 Dec 2018 02:50:27

moromete
Membru
Locaţie: Hunedoara
Înregistrat: 24 Nov 2009
Mesaje: 50
Site web

libchamplain routing problema

Salut,

Am reusit sa gasesc cum sa determin ruta optima intre doua noduri pe o harta a orasului. Dar lucreaza numai intre doua noduri ale retelei de drumuri, citeodata apar rezultate aiurea.
Daca punctele start final nu sunt in apropierea nodurilor se risca rezultate aiurea.
In plus cum as putea optimiza secventa de cautare noduri ?
Pe distante mari dureaza foarte mult cautarea acestor noduri, eventual indexare.
SQLite3 nu cunosc, obisnuit cu MySQL, am constatat ca nu prea seamana in SQL.
Cum as putea sa introduc corectiile necesare ?
Codul sursa mai jos.
Primul click cu mouse-ul determina punctul de plecare, al doilea punctul final.

Cod:

#include <curl/curl.h>
#include <gtk/gtk.h>
#include <sqlite3.h>
#include <spatialite.h>
#include <champlain/champlain.h>
#include <champlain-gtk/champlain-gtk.h>
#include <clutter-gtk/clutter-gtk.h>

#define SPATIAL "romania-latest.sqlite"

static gboolean destroying = FALSE;

gboolean            bFirst      = TRUE;
gint                nod1        = 0;
gint                nod2        = 0;
ChamplainPathLayer *route_layer = NULL;

static void on_destroy( GtkWidget *widget,
                        gpointer   data ) {
   destroying  = TRUE;
   gtk_main_quit();
}

static gboolean mouse_click_cb( ClutterActor       *actor,
                                ClutterButtonEvent *event,
                                ChamplainView      *view ) {
   gdouble lat, lon, lat_r, lon_r;
   gdouble lat1, lon1, lat2, lon2;
   char    sql[256];
   int ret, n_rows, n_columns, i, points;
   char **results = NULL;
   char *err_msg = NULL;
   sqlite3 *handle;
   ChamplainCoordinate *coord;
   GList *dash = NULL;


   lon = champlain_view_x_to_longitude( view, event->x );
   lat = champlain_view_y_to_latitude( view, event->y );
   if ( !sqlite3_open_v2( SPATIAL, &handle, SQLITE_OPEN_READONLY, NULL )) {
      sprintf( sql, "SELECT node_from,MIN(ST_DISTANCE(Startpoint(geometry), ST_POINT( %lf,%lf))) FROM roads", lon, lat );
      ret = sqlite3_get_table( handle, sql, &results, &n_rows, &n_columns, &err_msg );
      if ( ret == SQLITE_OK)  {
         if (( n_rows != 0 ) &&  ( results[ 1 ] != 0 )) {
            if ( bFirst ) {
               lon1 = lon;
               lat1 = lat;
               sscanf( results[ 2 ], "%d", &nod1 );
               bFirst = FALSE;
               if ( route_layer != NULL )
                  champlain_view_remove_layer( CHAMPLAIN_VIEW( actor ), CHAMPLAIN_LAYER( route_layer ));
            } else {
               lon2 = lon;
               lat2 = lat;
               sscanf( results[ 2 ], "%d", &nod2 );
               bFirst = TRUE;
               g_print( "Noduri: %d %d\n", nod1, nod2 );
               sprintf( sql, "SELECT NumPoints(Geometry) FROM Roads_net WHERE nodeFrom = %d AND nodeTo = %d LIMIT 1", nod1, nod2 );
               ret = sqlite3_get_table( handle, sql, &results, &n_rows, &n_columns, &err_msg );
               points = atoi( results[ 1 ] );
               route_layer = champlain_path_layer_new ();
               for ( i = 1; i <= points; i++ ) {
                  sprintf( sql, "SELECT X(PointN(Geometry, %d)), Y(PointN(Geometry, %d)) FROM Roads_net WHERE nodeFrom = %d and nodeTo = %d LIMIT 1", i, i, nod1, nod2 );
                  ret = sqlite3_get_table( handle, sql, &results, &n_rows, &n_columns, &err_msg );
                  if ( ret != SQLITE_OK ) {
                     printf("SQL error: %s\n", err_msg);
                     sqlite3_free(err_msg);
                     return( TRUE );
                  }
                  sscanf(results[2], "%lf", &lon_r );
                  sscanf(results[3], "%lf", &lat_r );
                  coord = champlain_coordinate_new_full( lat_r, lon_r );
                  champlain_path_layer_add_node( route_layer, CHAMPLAIN_LOCATION( coord ));
                  g_print( "Lat: %lf Lon: %lf\n", lat_r, lon_r );
               }
//               coord = champlain_coordinate_new_full( lat2, lon2 );
//               champlain_path_layer_add_node( route_layer, CHAMPLAIN_LOCATION( coord ));
               champlain_path_layer_set_stroke_width( route_layer, 4.0 );
               champlain_view_add_layer( CHAMPLAIN_VIEW( actor ), CHAMPLAIN_LAYER( route_layer ));
               dash = g_list_append(dash, GUINT_TO_POINTER(6));
               dash = g_list_append(dash, GUINT_TO_POINTER(2));
               champlain_path_layer_set_dash( route_layer, dash );
            }
         } else {
            printf( "Fara nod apropiat\n" );
         }
      } else {
         printf("SQL error: %s\n", err_msg);
         sqlite3_free( err_msg );
      }
      sqlite3_free_table( results );
      sqlite3_close( handle );
   }
   g_print( "Mouse click at: %f %f\n", lat, lon );

   return TRUE;
}

int main( int argc, char *argv[] ) {
   GtkWidget            *window = NULL;
   GtkWidget            *widget, *vbox,*viewport;
   ChamplainView        *view;
   ClutterActor         *scale;
   ChamplainLicense     *license_actor;

   if ( gtk_clutter_init( &argc, &argv ) == CLUTTER_INIT_SUCCESS ) {
      gdk_threads_init();
      spatialite_init( 0 );
      gtk_init( &argc, &argv );
      window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
      gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
      gtk_window_set_title( GTK_WINDOW( window ), "libchamplain Gtk+ demo" );
      g_signal_connect( G_OBJECT( window ), "destroy", G_CALLBACK( on_destroy ), NULL );
      vbox   = gtk_box_new( GTK_ORIENTATION_VERTICAL, 10 );
      widget = gtk_champlain_embed_new();
      view   = gtk_champlain_embed_get_view( GTK_CHAMPLAIN_EMBED( widget ));
      clutter_actor_set_reactive( CLUTTER_ACTOR( view ), TRUE );
      g_signal_connect( view, "button-release-event", G_CALLBACK( mouse_click_cb ), view );
      g_object_set( G_OBJECT( view ), "kinetic-mode", TRUE, "zoom-level", 14, NULL );
      g_object_set_data( G_OBJECT( view ), "window", window );
      scale = champlain_scale_new();
      champlain_scale_connect_view( CHAMPLAIN_SCALE( scale ), view );
      clutter_actor_set_x_expand( scale, TRUE );
      clutter_actor_set_y_expand( scale, TRUE );
      clutter_actor_set_x_align( scale, CLUTTER_ACTOR_ALIGN_START );
      clutter_actor_set_y_align( scale, CLUTTER_ACTOR_ALIGN_END );
      clutter_actor_add_child( CLUTTER_ACTOR( view ), scale );
      license_actor = champlain_view_get_license_actor( view );
      champlain_license_set_extra_text( license_actor, "" );
      // Aici La si Lon pentru zona dorita
      champlain_view_center_on( CHAMPLAIN_VIEW (view), 45.76338, 22.90852 );
      gtk_widget_set_size_request( widget, 1280, 600 );
      viewport = gtk_frame_new( NULL );
      gtk_container_add( GTK_CONTAINER( viewport ), widget );
      gtk_container_add( GTK_CONTAINER( vbox ), viewport );
      gtk_container_add( GTK_CONTAINER( window ), vbox );
      // make sure that everything, window and label, are visible
      gtk_widget_show_all( window );
      // start the main loop
      gtk_main ();
      gdk_threads_leave();
   }
   return( 0 );
}

pachete necesare:

apt install spatialite-bin spatialite-gui libspatialite-dev sqlite3 libsqlite3-dev libgtk-3-dev cmake

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.9)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK "gtk+-3.0")
pkg_check_modules(GTHREAD "gthread-2.0")
pkg_check_modules(CHAMPLAIN_GTK "champlain-gtk-0.12")
pkg_check_modules(SQLITE3 "sqlite3")
pkg_check_modules(SPATIALITE "spatialite")
add_definitions(-Wno-write-strings -Wno-narrowing -fpermissive -fexceptions)
set(SOURCES src/ClientDispecerat.cpp)
include_directories(${GTK_INCLUDE_DIRS} ${CHAMPLAIN_GTK_INCLUDE_DIRS} ${GTHREAD_INCLUDE_DIRS} ${SQLITE3_INCLUDE_DIRS} ${SPATIALITE_INCLUDE_DIRS})
link_libraries("-Bstatic" "-lpthread" ${GTK_LIBRARIES} ${CHAMPLAIN_GTK_LIBRARIES} ${SQLITE3_LIBRARIES} ${SPATIALITE_LIBRARIES})
project (CLIENTDISPECERAT)
add_executable(clientdispecerat ${SOURCES})

pentru creare baza date sqlite necesara calcul rute(populate_spatialite.sh).

#!/bin/sh
# cu packetul osmosis se poate extrage o anumita zona di harta romaniei
#bzcat romania-latest.osm.bz2 | bin/osmosis  --read-xml enableDateParsing=no file=-  --bounding-box top=$1 left=$2 bottom=$3 right=$4 --write-xml file=-  | bzip2 > zona.osm.bz2

rm romania-latest.osm
rm romania-latest.sqlite
curl https://download.geofabrik.de/europe/ro … st.osm.bz2 --output romania-latest.osm.bz2
bzip2 -d romania-latest.osm.bz2
#spatialite_osm_map -o romania-latest.osm -d romania-latest.sqlite
spatialite_osm_net -o romania-latest.osm -d romania-latest.sqlite -T roads -m
echo "Populating road network data"
spatialite_network -d romania-latest.sqlite -T roads -g geometry -c cost -t node_to -f node_from -n name --oneway-fromto oneway_fromto --oneway-tofrom oneway_tofrom -o roads_net_data --overwrite-output
echo "Creating virtual table 'roads_net' for routing queries."
spatialite romania-latest.sqlite 'CREATE VIRTUAL TABLE "roads_net" USING VirtualNetwork("roads_net_data")'
echo "Done!"

libchamplain, memphis(necesar daca se lucreaza cu harta offline)

rm -rf memphis
git clone https://github.com/jiuka/memphis.git
cd memphis
./autogen.sh --enable-introspection=yes
./configure --enable-introspection=yes
make
make install
ldconfig

cd ..

rm -rf libchamplain
git clone https://github.com/GNOME/libchamplain.git
cd libchamplain
./autogen.sh --enable-memphis --enable-introspection=yes
./configure --enable-memphis --enable-introspection=yes
make
make install
ldconfig

cd ..

Ca punct de pornire am avut documentatia de la link-ul de mai jos:
Local map rendering and route finding

exemplu traseu:

http://perosoft.org/traseu.png

Editat ultima oară de moromete (26 Dec 2018 04:01:17)


Nu poti atribui decit puteri pe care le poti defini, prin urmare le poti dobindi

Offline

 
Feed

Antet forum

Powered by FluxBB