1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/* Подсчёт расстояний по поверхности земли между центрами округов, заданных zip-кодами или почтовыми индексами, */
/* где для этих центров известна широта и долгота. */

/* (zip-коды - специфика США. На самом деле код универсален - можно использовать просто для */
/* подсчётов расстояний между двумя точками с известными координатами на земном шаре. */
/* Южная широта и западная долгота вводятся с отрицательным знаком - А.Б.)*/

/* Входные данные: 2 zip-кода, 2 широты, 2 долготы */
/* Выходные: расстояния между двумя точками в милях и километрах */
/* Автор: Simon Freidin, 6 июня 2003 */

* Следующие данные предложены Реем для иллюстративных целей.
data list list /zip1 zip2 lat1 lat2 long1 long2.
begin data
1 2 125 126 98 100
1 3 125 126 99 99
end data.

/* ведём расчёт лишь в том случае, если введённые коды, а также широта и долгота не одинаковы*/
do if ~(zip1 = zip2) and ~((lat1=lat2) and (long1=long2)).
/* расчёт расстояний по дуге большого круга */
/* http://codewalkers.com/getcode.php?id=247 */
compute theta = long2 - long1.
compute d1 = (sin((artan(1)/45)*(lat2)) * sin((artan(1)/45)*(lat1))) +
              (cos((artan(1)/45)*(lat2)) * cos((artan(1)/45)*(lat1)) * 
		cos((artan(1)/45)*(theta))).
if range(d1,-1,1) d2 = 2*artan(1) - arsin(d1) .
compute d3 = (45/artan(1))*(d2).
compute distmile = d3 * 60 * 1.1515 .
compute distkm = distmile * 1.609344.
else.
/* если координаты совпадают */
compute distmile=0.
compute distkm=0.
end if.

compute distkm=rnd(distkm).
compute distmile=rnd(distmile).
execute.
variable labels
  distmile 'DV: Distance (miles)'/
  distkm   'DV: Distance (kilometers)'/.

*Менеджер-аналитик исследовательских баз данных
*Мельбурнский институт прикладной экономики и социальных исследований
*Университет Мельбурна
*MELBOURNE VIC 3010
*Tel: (03) 8344 3601 Fax: (03) 8344 5630.