Voici mon scénario:
L'application "A" produit des points lat et de longs points correspondant à la route planifiée. En fonction de la distance de l'itinéraire, il pourrait avoir plusieurs milliers de points. Je connais de la géographie et des types de données géométrie, pensa même qu'ils sont sortis avec SQL 2008, je n'ai vu personne les utiliser encore et je ne sais pas ce qui serait bon scénario pour l'utiliser. En plus des points que l'application "A" génère, j'ai besoin de stocker des points d'application "B" qui correspondent à la route réelle. Une fois que tout est stocké, j'ai besoin de trouver des déviations de la route prévue.
Cela pourrait être un problème NP-complet, http://fr.wikipedia.org/wiki/np-complete Comparez-le au problème du vendeur itinérant, http: //fr.wikipedia .org/wiki/travell_salesman_problème Je ne suis pas sûr que si c'est NP-complète puisque mes textes collégiants sont en stockage, et cela fait longtemps que mes classes de complexité.
Pour ne pas dire que nous ne pouvons pas simplement faire du "Math Drift" simpliste à l'aide de types de données spatiales SQL Server à partir de l'approche de la table suggérée par @kenwilsondba.
Une approche plus approfondie (sinon NP-complète) rechercherait où l'itinéraire réel est retourné sur la piste d'autres choses.
Cependant, nous pourrions utiliser les types de données spatiaux SQL Server Server si tout ce dont nous avons besoin est un calcul simpliste de la dérive où nous pourrions simplement jeter des destinations supplémentaires si la route réelle passe ou répéter le dernier point final de la route. et ignorer tous les segments où l'itinéraire est retourné sur la bonne voie et supposons que les identifiants d'arrêt sont réellement séquentiels.
Notez que cette approche du calcul pénalise également des itinéraires réels qui ne se heurtent que lors du début et ne sont jamais égarés pour le reste de la route et récompensent ceux qui restent sur la bonne voie jusqu'aux points finaux.
Une autre mise en garde est que les champs de la conception de table ci-dessous sont redondants.
Les calculs de distance sont en mètres par défaut.
CREATE TABLE a_planned_point (
route_id INT,
stop_id INT,
lat DECIMAL(10,7),
long DECIMAL(10,7),
pointspatialdata GEOGRAPHY,
city VARCHAR(20),
state CHAR(2) )
CREATE TABLE b_actual_point (
route_id INT,
stop_id INT,
lat DECIMAL(10,7),
long DECIMAL(10,7),
pointspatialdata GEOGRAPHY,
city VARCHAR(20),
state CHAR(2) )
CREATE TABLE c_planned_segment (
route_id INT,
start_id INT,
stop_id INT,
lat_planned_stop DECIMAL(10,7),
long_planned_stop DECIMAL(10,7),
city_planned VARCHAR(20),
state_planned CHAR(2),
segmentspatialdata GEOGRAPHY)
CREATE TABLE d_actual_segment (
route_id INT,
start_id INT,
stop_id INT,
lat_actual_stop DECIMAL(10,7),
long_actual_stop DECIMAL(10,7),
city_actual VARCHAR(20),
state_actual CHAR(2),
segmentspatialdata GEOGRAPHY)
CREATE TABLE e_drift_segment (
route_id INT,
planned_stop_id INT,
actual_stop_id INT,
lat_planned_stop DECIMAL(10,7),
long_planned_stop DECIMAL(10,7),
city_planned VARCHAR(20),
state_planned CHAR(2),
lat_actual_stop DECIMAL(10,7),
long_actual_stop DECIMAL(10,7),
city_actual VARCHAR(20),
state_actual CHAR(2),
distance_drift FLOAT,
segmentspatialdata GEOGRAPHY)
INSERT INTO a_planned_point (route_id, stop_id, lat, long, pointspatialdata, city, state) VALUES
(1, 0, 33.93, -118.40, CAST('POINT(-118.40 33.93)' AS GEOGRAPHY), 'Los Angeles', 'CA'),
(1, 1, 33.43, -112.02, CAST('POINT(-112.02 33.43)' AS GEOGRAPHY), 'Phoenix', 'AZ'),
(1, 2, 39.75, -104.87, CAST('POINT(-104.87 39.75)' AS GEOGRAPHY), 'Denver', 'CO'),
(1, 3, 25.82, -80.28, CAST('POINT(-80.28 25.82)' AS GEOGRAPHY), 'Miami Intl', 'FL'),
(1, 4, 40.77, -73.98, CAST('POINT(-73.98 40.77)' AS GEOGRAPHY), 'New York', 'NY'),
(1, 5, 42.37, -71.03, CAST('POINT(-71.03 42.37)' AS GEOGRAPHY), 'Boston', 'MA')
INSERT INTO b_actual_point (route_id, stop_id, lat, long, pointspatialdata, city, state) VALUES
(1, 0, 33.93, -118.40, CAST('POINT(-118.40 33.93)' AS GEOGRAPHY), 'Los Angeles', 'CA'),
(1, 1, 39.75, -104.87, CAST('POINT(-104.87 39.75)' AS GEOGRAPHY), 'Denver', 'CO'),
(1, 2, 33.43, -112.02, CAST('POINT(-112.02 33.43)' AS GEOGRAPHY), 'Phoenix', 'AZ'),
(1, 3, 25.82, -80.28, CAST('POINT(-80.28 25.82)' AS GEOGRAPHY), 'Miami Intl', 'FL'),
(1, 4, 40.77, -73.98, CAST('POINT(-73.98 40.77)' AS GEOGRAPHY), 'New York', 'NY')
INSERT INTO c_planned_segment (
route_id,
start_id,
stop_id,
lat_planned_stop,
long_planned_stop,
city_planned,
state_planned,
segmentspatialdata
)
SELECT
x.route_id,
x.stop_id,
y.stop_id,
y.lat,
y.long,
y.city,
y.state,
CAST('LINESTRING(' + CAST(x.long AS VARCHAR) +' '+ CAST(x.lat AS VARCHAR) +', '+
CAST(y.long AS VARCHAR) +' '+ CAST(y.lat AS VARCHAR) + ')' AS GEOGRAPHY) AS segmentspatialdata
FROM
a_planned_point x
LEFT OUTER JOIN
a_planned_point y
ON
y.stop_id = x.stop_id + 1
WHERE
y.stop_id IS NOT NULL
and
x.route_id = 1
ORDER BY x.stop_id
INSERT INTO d_actual_segment (
route_id,
start_id,
stop_id,
lat_actual_stop,
long_actual_stop,
city_actual,
state_actual,
segmentspatialdata
)
SELECT
x.route_id,
x.stop_id,
y.stop_id,
y.lat,
y.long,
y.city,
y.state,
CAST('LINESTRING(' + CAST(x.long AS VARCHAR) +' '+ CAST(x.lat AS VARCHAR) +', '+
CAST(y.long AS VARCHAR) +' '+ CAST(y.lat AS VARCHAR) + ')' AS GEOGRAPHY) AS segmentspatialdata
FROM
b_actual_point x
LEFT OUTER JOIN
b_actual_point y
ON
y.stop_id = x.stop_id + 1
WHERE
y.stop_id IS NOT NULL
and
x.route_id = 1
ORDER BY x.stop_id
INSERT INTO e_drift_segment (
route_id,
planned_stop_id,
actual_stop_id,
lat_planned_stop,
long_planned_stop,
city_planned,
state_planned,
lat_actual_stop,
long_actual_stop,
city_actual,
state_actual,
distance_drift,
segmentspatialdata
)
SELECT
x.route_id,
x.stop_id,
y.stop_id,
x.lat,
x.long,
x.city,
x.state,
y.lat,
y.long,
y.city,
y.state,
x.pointspatialdata.STDistance(y.pointspatialdata),
CAST('LINESTRING(' + CAST(x.long AS VARCHAR) +' '+ CAST(x.lat AS VARCHAR) +', '+
CAST(y.long + 0.0000001 AS VARCHAR) +' '+ CAST(y.lat AS VARCHAR) + ')' AS GEOGRAPHY) AS segmentspatialdata
FROM
a_planned_point x
LEFT OUTER JOIN
b_actual_point y
ON
y.stop_id = x.stop_id
WHERE
x.stop_id IS NOT NULL
and
y.stop_id IS NOT NULL
and
x.route_id = 1
ORDER BY x.stop_id
Pour trouver la quantité totale de dérive en mètres:
select sum(distance_drift) from e_drift_segment where route_id = 1
Pour afficher des segments d'itinéraire comparés, réels et de dérive à une fois dans l'onglet "Résultats spatiaux" SQL Server:
select segmentspatialdata from c_planned_segment where route_id = 1
union all
select segmentspatialdata from d_actual_segment where route_id = 1
union all
select segmentspatialdata from e_drift_segment where route_id = 1
Recommande d'utiliser deux tables. Tableau A pour la route planifiée et le tableau B pour la route réelle. Une fois que vous avez peuplé les deux tables, vous pouvez rejoindre les deux tables sur une sorte d'identifiant et utiliser la méthode de la stdistance pour déterminer les écarts. Il y a aussi de nombreuses autres méthodes que je pense seraient utiles dans cette situation.
Voir http://technet.microsoft.com/en-us/library/cc280766.aspx