AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 49594
Accepted
Vladimir Oselsky
Vladimir Oselsky
Asked: 2013-09-11 04:13:09 +0800 CST2013-09-11 04:13:09 +0800 CST 2013-09-11 04:13:09 +0800 CST

Qual é a melhor maneira de armazenar coordenadas geográficas relacionadas à rota planejada?

  • 772

Aqui está o meu cenário:

A aplicação "A" produz pontos de latitude e longitude que correspondem à rota planejada. Dependendo da distância da rota, pode ter vários milhares de pontos. Conheço os tipos de dados Geography e Geometry, mesmo que tenham saído com o SQL 2008, ainda não vi ninguém usá-los e não tenho certeza de qual seria um bom cenário para usá-los. Além dos pontos que o App "A" gera, preciso armazenar os pontos do App "B" que correspondem à rota real. Depois de tudo armazenado, preciso encontrar desvios da rota planejada.

sql-server sql-server-2012
  • 2 2 respostas
  • 10276 Views

2 respostas

  • Voted
  1. Best Answer
    kkarns
    2013-09-12T08:53:43+08:002013-09-12T08:53:43+08:00

    Isso pode ser um problema NP-Complete, http://en.wikipedia.org/wiki/NP-complete Compare com o problema do caixeiro viajante, http://en.wikipedia.org/wiki/Travelling_salesman_problem Não tenho certeza se for NP-Complete, pois meus textos da faculdade estão armazenados e já faz um tempo desde minhas aulas de complexidade.

    Não quer dizer que não podemos simplesmente fazer algumas "matemáticas de desvio" simplistas usando tipos de dados espaciais do SQL Server começando com a abordagem de tabela sugerida por @kenwilsondba.

    Uma abordagem mais completa (se não NP-Complete) procuraria onde a rota real voltou aos trilhos entre outras coisas.

    No entanto, poderíamos fazer o seguinte utilizando os tipos de dados espaciais do SQL Server se tudo o que precisamos for um cálculo simplista de desvio, onde poderíamos simplesmente descartar destinos extras se a rota real for ultrapassada ou repetir o último ponto final real se a rota real for abaixo , e desconsidere todos os segmentos em que a rota voltou ao caminho certo e suponha que os IDs de parada sejam realmente sequenciais.

    Observe que essa abordagem de cálculo também penaliza as rotas reais que se desviam apenas no início e nunca se desviam no restante da rota, e recompensa aqueles que permanecem na pista até os pontos finais.

    Outra ressalva é que os campos no design da tabela abaixo são redundantes.

    Os cálculos de distância são em metros por padrão.

    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
    

    Para encontrar a quantidade total de desvio em metros:

    select sum(distance_drift) from e_drift_segment where route_id = 1
    

    Para mostrar os segmentos de rota planejada, real e de desvio de uma só vez na guia "Resultados Espaciais" do 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
    
    • 4
  2. KenWilson
    2013-09-11T06:12:42+08:002013-09-11T06:12:42+08:00

    Recomendo o uso de duas tabelas. Tabela A para a rota planejada e Tabela B para a rota real. Depois de preencher ambas as tabelas, você pode unir as duas tabelas em algum tipo de identificador e usar o método STDistance para determinar os desvios. Existem também muitos outros métodos que acho que seriam úteis nessa situação.

    Consulte http://technet.microsoft.com/en-us/library/cc280766.aspx

    • 1

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Conceder acesso a todas as tabelas para um usuário

    • 5 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve