Newsgroup: it.comp.appl.access
Titolo: Distanza miima

Avendo un archivio con memorizzati i dati dei comuni italiani; precisamente 
:
1) Nome
2) Latitudine
3) Longitudine
si può con una singola query individuare qual'è il comune (uno solo) che ha 
*distanza minima* da un certo punto qualsiasi di cui conosco le coordinate 
geografiche (latitudine e longitudine) ?
In altre parole :
a) input : Latitudine e Longitudine
b) output : Nome
Tutto questo è facilmente fattibile spazzolando l'intero archivio (più di 
8000 record) ma preferirei fare questa operazione con una singola query.
Grazie per l'attenzione.
AlpVir 


forse
potresti calcolarti la distanza tra i dati della tabella comuni e un'altra 
tabella dove hai scritto le coordinate che ti interessano e poi ordinarle in 
ordine crescente o decrescente. non credo si possa fare con una singola 
query, ma non sono abbastanza esperto.
io ho queste funzioni, non so se ti sono utili; altrimenti sciviti/cerca 
quella piů adatta...
ciao
Public Function CalcDistance(Lat1 As Double, Lon1 As Double, Lat2 As Double, 
Lon2 As Double, DorR As String, MorK As String) As Double
On Error GoTo Err_CalcDist
'Code works for longitudes and latitudes entered as decimals, not minutes 
and seconds
'South and West longitudes and latitudes should be entered as negative 
numbers
'DorR = The latitude and longitude are entered in Degrees or Radians
'MorK = The result should be in Miles or Kilometers
If Delta(Lat1, Lat2, 6, 1) = 0 And Delta(Lon1, Lon2, 6, 1) = 0 Then
CalcDistance = 0
Exit Function
End If
Dim x As Double
Dim negX As Double
Dim r As Single
Dim radMult As Double
Dim dblPi As Double
'convert degrees to radians, if needed
If DorR = "d" Then
dblPi = 3.14159269358979
radMult = dblPi / 180
Lat1 = Lat1 * radMult
Lon1 = Lon1 * radMult
Lat2 = Lat2 * radMult
Lon2 = Lon2 * radMult
End If
If MorK = "M" Then
  r = 3963.1
Else
  r = 6378.137
End If
x = ((Cos(Lat1) * Cos(Lat2) * Cos(Lon1) * Cos(Lon2)) + (Cos(Lat1) * 
Sin(Lon1) * Cos(Lat2) * Sin(Lon2)) + (Sin(Lat1) * Sin(Lat2)))
negX = x * -1
x = Atn(negX / (Sqr((negX * x) + 1))) + 2 * Atn(1)
CalcDistance = x * r
Exit_CalcDist:
  Exit Function
Err_CalcDist:
  MsgBox Err.Number & " - " & Err.Description
  Resume Exit_CalcDist
End Function
Public Function Delta(num1#, num2#, cifre%, max%) As Double
'Cifre= decimali da calcolare
'max=tolleranza unitaria ammessa per azzerare la differenza
Delta = Abs(Int(CDbl(num1 * 10 ^ cifre)) - Int(CDbl(num2 * 10 ^ cifre)))
If Delta > max Then
   Delta = num1 - num2
Else
   Delta = 0
End If
End Function


Grazie ma ho anch'io funzioni del genere, persino più precise.
La domanda era - com'è chiaramente scritto - rivolta alla ricerca di una 
SINGOLA QUERY, non di una o più funzioni che necessariamente devono 
calcolare la distanza per ogni singolo comune.
ciao
AlpVir 

 calcolare la distanza per ogni singolo comune.
Dunque, dette  X e Y le coordinate, io farei qualcosa tipo
SELECT Comune, Lat, Lon FROM tComuni WHERE Lat=(SELECT min(LAT) FROM
tComuni WHERE lat>X)
UNION ALL
SELECT Comune, Lat, Lon FROM tComuni WHERE Lat=(SELECT max(LAT) FROM
tComuni WHERE lat<X)
UNION ALL
SELECT Comune, Lat, Lon FROM tComuni WHERE Lon=(SELECT min(LAT) FROM
tComuni WHERE lon>X)
UNION ALL
SELECT Comune, Lat, Lon FROM tComuni WHERE Lon=(SELECT max(LAT) FROM
tComuni WHERE on<X)
così isoli i 4 comuni piu' vicini verso nord, est, sud e ovest - il
comune piu' vicino sara' per forza uno di questi quattro. Applicare
l'algoritmo che celcola la distanza solo a questi 4 non dovrebbe
essere troppo oneroso.
Ma ripensandoci, a te non serve necessariamente la distanza... secondo
me ti basta fare una cosa del tipo
SELECT Comune, Lat, Lon FROM tComuni WHERE (LAT-Y)*(LAT-Y)+(LON-
X)*(LON-X)= (SELECT MIN((LAT-Y)*(LAT-Y)+(LON-X)*(LON-X)) FROM tComuni)
L'ho provato sul mio DB dei comuni italiani (8000 record) ed e'
ragionevolmente veloce.
cia'
Max

 ha scritto nel messaggio 
news:cede482f-e3de-424c...@26g2000hsk.googlegroups.com...








O una o l'altra soluzione sembra proprio che facciano il caso mio. Domani le 
provo.
Grazie infinite
AlpVir 


Non mi funziona !
Restituisce un record vuoto con i due campi numeri Lat e Lon uguali a zero. 
Inserendo gli oppurtuni valori viene fuori questo :
SELECT * FROM TabComuni WHERE 
(Lat-44.3986364)*(Lat-44.3986364)+(Lon-6.92681069)*(Lon-6.92681069) = 
(SELECT 
MIN((Lat-44.3986364)*(Lat-44.3986364)+(Lon-6.92681069)*(Lon-6.92681069)) 
FROM TabComuni)
che non piace nè ad MsAccess nè alla pagina ASP che sto cercando di 
sviluppare.
Ovviamente i campi del mio db sono proprio Comune,Lat,Lon ed ho anch'io 
circa 8000 record.
Anche cambiando l'uguale in un IN oppure cambiando l'asterisco con 
Comune,Lat,Lon (questi ultimi due campi sono ovviamente numerici, precisione 
singola).
Anche cambiando il punto in una virgola (non si sa mai)
Grazie ancora
AlpVir.

 singola).
Credo che il problema sia qui: le coordinate che inserisci, con la
bellezza di 9 cifre significative, mi sa che travalicano la, uhm ,
"risoluzione" del calcolo.. Limita il numero di cifre decimali
(converti in single ogni coordinata con csng, per esempio) e vedi che
funziona.
cia'
Max

 ha scritto nel messaggio 
news:b1998c81-2f7f-41a2...@i76g2000hsf.googlegroups.com...






(Lat-44.3986)*(Lat-44.3986)+(Lon-6.9268)*(Lon-6.9268) = (SELECT 
MIN((Lat-44.3986)*(Lat-44.3986)+(Lon-6.9268)*(Lon-6.9268)) FROM TabComuni)
SELECT * FROM TabComuni WHERE 
(Lat-44.398)*(Lat-44.398)+(Lon-6.926)*(Lon-6.926) = (SELECT 
MIN((Lat-44.398)*(Lat-44.398)+(Lon-6.926)*(Lon-6.926)) FROM TabComuni);
Ho creato (da Visualizza Struttura di MsAccess) una query qualsiasi e poi 
nella finestra SQL (query di selezione) ho inserito (copia e incolla) prima 
una e poi l'altra soluzione sopra riportata. Messo il punto e virgola finale 
e tolto. Pensato e ripensato. Fatto innumerevoli varianti stupide, compresa 
la sostituzione del separatore decimale con una virgola (anche se ero sicuro 
che non serviva a niente).
Il mio database è sicuramente identico al tuo; stesso numero di cifre 
significative. C'è però un punto in 44.3972 e una virgola in 6,9393 ma sono 
sicuro che si tratta di un errore di digitazione.
Le due soluzione sopra indicate sono viceversa scritte con un copia e 
incolla da codice ASP; non ci sono possibilità di errorini difficili da 
individuare
Ma non ottengo nulla. Non so più cosa pensare.
A riprova del fatto che non sono uno sprovveduto (almeno credo) ti 
suggerisco di dare un'occhiata al mio sito (
www.lalpinistavirtuale.it
 - in 
particolare la sezione SCIALPINISMO), anche in considerazione che il tuo 
nikname ("Roccia") fa forse presupporre che frequenti la montagna ed il mio 
sito è appunto dedicato alla montagna.
Grazie del tuo aiuto !
AlpVir

 sito è appunto dedicato alla montagna.
Si, in effetti amo la montagna, ma il nick e' piu' un riferimento alla
consistenza della mia testa, dice chi mi ha affibbiato il nomignolo.
cia'
Max

Brevemente ...
Non funziona in nessunissimo ambiente, MsAccess (2000), ASP (3.0 con IIS) e 
compagnia bella.
Anche mettendo i valori numerici nella query e non costruendo il criterio di 
ricerca stringa dopo stringa, com'è necessario fare in ASP.
Se mi spedisci (
u...@libero.it
 o 
ugo.b...@libero.it
) il tuo archivio forse 
riesco a risolvere l'arcano.
Magari con la tua query già registrata.
Se lavori con una versione più aggiornata di MSAccess posso installare su un 
altro computer l'Access che c'è in Office XPRO.
Grazie ancora.
AlpVir 

 Magari con la tua query già registrata.
Non manchero'. Siccome sono pirla, ho dimenticato di copiarmi il DB
sulla chiavetta, quindi potro' spedirtelo solo lunedi, quando tornero'
in utticio...
cia'
Max

 ha scritto nel messaggio 
news:0d423cad-eee5-4172...@e53g2000hsa.googlegroups.com...



Non è necessario. Sono finalmente riuscito a furia di prove e controprove.
Ecco il codice ASP,  funzionante.
sY=cstr(rs("Lon"))
sX=cstr(rs("Lat"))
Criterio="SELECT TabComuni.* FROM TabComuni WHERE 
(Lat-csng("+sY+"))*(Lat-csng("+sY+")) + "
Criterio=Criterio+"(Lon-csng("+sX+"))*(Lon-csng("+sX+"))= (SELECT 
MIN((Lat-csng("+sY+"))*(Lat-csng("+sY+"))+(Lon-csng("+sX+"))*(Lon-csng("+sX+"))) 
FROM TabComuni)"
In tutta sincerità non so bene in cosa sbagliassi, ma è merito tuo se sono 
riuscito nel mio scopo.
Grazie ancora.
AlpVir 

 AlpVir
Esso, visto che ti abbiamo aiutato (!!!), caccia fuori il db coi comuni e 
lantitudine e langitudine
Grassie
RobertoA

 lantitudine e langitudine
Google is your friend :D
Si trova senza problemi un database CC pronto pronto per essere
sbattuto in mySQL
cia'
Max


Ho reso disponibile sul mio sito (
www.lalpinistavirtuale.it
 - sezione GPS) 
una versione in MSAccess