Domanda

Ho creato la seguente tabella MySQL per memorizzare le coordinate di latitudine/longitudine insieme a un nome per ciascun punto:

CREATE TABLE `points` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(128) NOT NULL,
  `location` point NOT NULL,
  PRIMARY KEY (`id`),
  SPATIAL KEY `location` (`location`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;

Sto cercando di interrogare:

  • tutti i punti all'interno di an N raggio in miglia di un dato punto;
  • la distanza di ciascun punto restituito dal punto specificato

Tutti gli esempi che ho trovato si riferiscono all'utilizzo di un rettangolo di delimitazione minima (MBR) anziché di un raggio.La tabella contiene circa 1 milione di punti, quindi questa esigenza deve essere quanto più efficiente possibile.

È stato utile?

Soluzione 2

Vi ringrazio entrambi per le vostre risposte.

Alla fine ho trovato la soluzione a http: //www.movable -type.co.uk/scripts/latlong-db.html.

Altri suggerimenti

Per MySQL 5.7 +

Dato che abbiamo la seguente semplice tabella,

create table example (
  id bigint not null auto_increment primary key,
  lnglat point not null
);

create spatial index example_lnglat 
    on example (lnglat);

Con i seguenti dati semplice,

insert into example (lnglat) 
values
(point(-2.990435, 53.409246)),
(point(-2.990037, 53.409471)),
(point(-2.989736, 53.409676)),
(point(-2.989554, 53.409797)),
(point(-2.989350, 53.409906)),
(point(-2.989178, 53.410085)),
(point(-2.988739, 53.410309)),
(point(-2.985874, 53.412656)),
(point(-2.758019, 53.635928));

Si potrebbe ottenere i punti entro un determinato intervallo di un altro punto (nota: dobbiamo cercare all'interno di un poligono) con la seguente combinazione di funzioni st:

set @px = -2.990497;
set @py = 53.410943;
set @range = 150; -- meters
set @rangeKm = @range / 1000;

set @search_area = st_makeEnvelope (
  point((@px + @rangeKm / 111), (@py + @rangeKm / 111)),
  point((@px - @rangeKm / 111), (@py - @rangeKm / 111))
);

select id, 
       st_x(lnglat) lng, 
       st_y(lnglat) lat,
       st_distance_sphere(point(@px, @py), lnglat) as distance
  from example
 where st_contains(@search_area, lnglat);

Si dovrebbe vedere qualcosa di simile a questo come un risultato:

3   -2.989736   53.409676   149.64084252776277
4   -2.989554   53.409797   141.93232714661812
5   -2.98935    53.409906   138.11516275402533
6   -2.989178   53.410085   129.40289289527473

Per riferimento alla distanza, se togliamo il vincolo del risultato del punto di prova si presenta così:

1   -2.990435   53.409246   188.7421181457556
2   -2.990037   53.409471   166.49406509160158
3   -2.989736   53.409676   149.64084252776277
4   -2.989554   53.409797   141.93232714661812
5   -2.98935    53.409906   138.11516275402533
6   -2.989178   53.410085   129.40289289527473
7   -2.988739   53.410309   136.1875540498202
8   -2.985874   53.412656   360.78532732013963
9   -2.758019   53.635928   29360.27797292756

Nota 1 : il campo si chiama lnglat dato che è l'ordine corretto se si pensa di punti come (x, y) ed è anche l'ordine maggior parte delle funzioni (come punto) accettare il parametro

Nota 2 : non si può effettivamente usufruire dei indici spaziali, se si sceglie di usare i cerchi; anche notare che il campo punto può essere impostato per accettare indici nulli ma spaziali non può indicizzare se è annullabile (tutti i campi nell'indice devono essere non nullo).

Nota 3 : ST_Buffer è considerato (dalla documentazione) per essere un male per questo caso d'uso

Nota 4 : le funzioni di cui sopra (in particolare st_distance_sphere) sono documentati più veloce, ma non necessariamente super-accurate; se i dati è super sensibile a che aggiungono un po 'di spazio di manovra per la ricerca e fare qualche messa a punto per il set di risultati

Raggio non è efficiente indicizzabile. Si dovrebbe usare il rettangolo di delimitazione per ottenere rapidamente i punti si sono probabilmente cercando, e poi filtrare punti al di fuori del raggio.

L'ho fatto per un punto all'interno del cerchio con raggio

SELECT 
    *
FROM 
    `locator`
WHERE
    SQRT(POW(X(`center`) - 49.843317 , 2) + POW(Y(`center`) - 24.026642, 2)) * 100 < `radius`

dettagli e un'altra query di esempio qui http://dexxtr.com/post/83498801191/how-to-determine-point-inside-circle-using-mysql, spero che questo ti aiuti

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top