Voy a explicar la solución que he encontrado (quizás no sea la mejor).
De acuerdo con la imagen posterior, supongamos que estamos en el punto A y que va a ir al punto B . Como expliqué anteriormente, estos puntos no son vértices (fuente / objetivos en la tabla generada con la herramienta osm2po).
Debido a esto, necesitamos saber la dirección para caminar / conducir. Si pasamos del vértice más cercano al Punto A (punto verde) a través del camino naranja, tendríamos que restar el desplazamiento entre el Punto A y el punto verde (vértice más cercano). Pero si tuviéramos que pasar por la calle Almirante Bonifaz , entonces deberíamos agregar el desplazamiento a la longitud de este borde (desde el punto verde hasta la intersección entre la calle Almirante Bonifaz y la calle San Juan ).
Ejecuto la siguiente consulta para obtener la ruta más corta (necesita la extensión pgRouting explicada aquí pgRouting - instalación y requisitos aquí instalación y requisitos ):
SELECT gid, cost, st_astext(the_geom) as the_geom FROM dijkstra_sp_delta('xx_2po_4pgr', source_vertex, target_vertex, 0.1);
Esto da como resultado un conjunto de aristas que representa la ruta completa. Por ejemplo, una salida posible para esta consulta podría ser:
Donde el gid de campo ( id en la tabla generada osm2po) representa el identificador de borde. Bueno, debemos verificar las compensaciones al principio y al final (Puntos A / B).
Si comprobamos el desplazamiento inicial, hay que comprobar si el primer borde del conjunto de aristas obtenidos en la consulta anterior es igual a la trayectoria más cercana a Punto A . Si coinciden, restaremos el desplazamiento. Si no coinciden, agregaremos el desplazamiento. Para obtener el enlace más cercano a un punto, ejecuto la siguiente consulta:
SELECT * FROM find_node_by_nearest_link_within_distance(point, 0.1, 'xx_2po_4pgr') as id;
Debe adaptar esta función para que devuelva el borde más cercano. Primero debe modificar el tipo de punto de enlace (agregar el campo de enlace más cercano ):
CREATE TYPE link_point AS
(id integer,
name character varying,
nearest_link integer);
ALTER TYPE link_point
OWNER TO postgres;
También debe modificar find_node_by_nearest_link_within_distance . Simplemente agregue la última línea (solo muestro un extracto de la función):
-- Searching for a nearest link
FOR row in EXECUTE 'select id from find_nearest_link_within_distance('''||point||''', '||distance||', '''||tbl||''') as id'
LOOP
END LOOP;
IF row.id is null THEN
res.id = -1;
RETURN res;
END IF;
link:=row.id;
res.nearest_link:=link;
Luego, necesita saber cuál es la distancia entre el punto ( Punto A / Punto B ) y el borde más cercano (desplazamiento). Para este propósito ejecuto esta consulta:
SELECT ST_Line_Locate_Point(geom , point)as offset;
Donde geom es la the_geom campo en osm2po tabla generada.
En este punto, tendríamos el desplazamiento para sumar o restar.
Finalmente, necesitaría conocer la longitud del borde para aplicar el valor obtenido en la consulta anterior y ajustar el real (si trabaja con el tipo de geometría, tendrá que normalizar a metros el valor obtenido. Simplemente multiplique 111000 por la longitud obtenida en la consulta):
select st_length(the_geom) from (select ST_ASTEXT(the_geom) as the_geom FROM dr_2po_4pgr WHERE id= edge_identifier)t";
Si verificamos el desplazamiento final, entonces tendríamos que verificar si la última ruta del conjunto de rutas obtenidas en la consulta anterior es la misma que la ruta más cercana al punto final ( Punto B ) y sumaríamos / restaríamos en de la misma manera que antes.
Disculpa mi inglés.