{smcl} {* 21jul2025}{...} {cmd:help lhaversine} {hline} {title:Title} {p 4} {bf:lhaversine -- Mata library for distance functions} {title:Syntax} {p 8 12} {it:real matrix}{bind: } {cmd:hav_dist(}{it:lat_a, lng_a, lat_b, lng_b }[{it:, rd}]{cmd:)} {p 8 12} {it:real matrix}{bind: } {cmd:hav_distm(}{it:lat_a, lng_a, lat_b, lng_b }[{it:, rd}]{cmd:)} {p 8 12} {it:real matrix}{bind: } {cmd:hav_inrange(}{it:lat_a, lng_a, lat_b, lng_b, rn }[{it:, rd}]{cmd:)} {p 8 12} {it:real matrix}{bind: } {cmd:hav_inrangem(}{it:lat_a, lng_a, lat_b, lng_b, rn }[{it:, rd}]{cmd:)} {p 8 12} {it:real matrix}{bind: } {cmd:hav_ninrange(}{it:lat_a, lng_a, lat_b, lng_b, rn }[{it:, rd}]{cmd:)} {p 8 12} {it:real matrix}{bind: } {cmd:hav_ninrangem(}{it:lat_a, lng_a, lat_b, lng_b, rn }[{it:, rd}]{cmd:)} {p 4 4 2} where {p 8} {it:lat_a is a real colvector} {p 8} {it:lng_a is a real colvector} {p 8} {it:lat_b is real colvector} {p 8} {it:lng_b is a real colvector} {p 8} {it:rd is a real scalar} {p 8} {it:rn is a real scalar} {title:Description} {pstd} All functions in {cmd:lhaversine} use the haversine formula for great-circle distances, {browse "https://en.wikipedia.org/wiki/Haversine_formula"}. The geographical coordinates must be in signed decimal degress. Latitudes range from -90 to 90. Longitudes range from -180 to 180. To convert radians into degress, multiply by pi/180. {pstd} {cmd:hav_dist()} returns a matrix of distances between A locations and B locations. The results are in kilometres. {cmd:hav_dist()} takes the latitudes (column vector {it:lat_a}) and longitudes (column vector {it:lng_a}) of the A locations and the latitudes (column vector {it:lat_b}) and longitudes (column vector {it:lng_b}) of the B locations as inputs. The optional argument ({it:rd}) allows the user to specifiy the earth radius. The default is 6,371 kilometres. {pstd} {cmd:hav_distm()} returns a distance matrix in miles. The default radius is 3,958.76 miles. {pstd} {cmd:hav_inrange()} returns a matrix of ones and zeros, indicating if a B location is within a given range of an A location. The range ({it:rn}) needs to be specified by the user and is in kilometers. The {cmd:hav_dist()} takes the latitudes {it:lat_a} and longitudes {it:lng_b} of the A locations and the latitudes {it:lat_b} and longitudes {it:lng_b} as inputs. The optional argument ({it:rd}) allows the user to specifiy the earth radius. The default is 6,371 kilometres. {pstd} {cmd:hav_inrangem()} returns a matrix of ones and zeros, indicating if a B location is within a range of ({it:rn}) miles of an a location. The optional argument ({it:rd}) allows the user to specifiy the earth radius. The default is 3,958.76 miles. {pstd} {cmd:hav_inrange()} returns a column vector containing the number of B locations that are within a given range of an A location. The range ({it:rn}) needs to be specified by the user and is in kilometers. The optional argument ({it:rd}) allows the user to specifiy the earth radius. The default is 6,371 kilometres. {pstd} {cmd:hav_ninrangem()} returns a column vector with the number of B locations that are within a range of ({it:rn}) miles of an A location. The optional argument ({it:rd}) allows the user to specifiy the earth radius. The default is 3,958.76 miles. {title:Examples} {p 4} Define the latitudes and longitudes of two A und three B locations: {cmd::} lat_a = 53.1205306\53.2056589 {cmd::} lng_a = 8.101857\8.2530387 {cmd::} lat_b = 53.1479943\53.2450662\51.2082624 {cmd::} lng_b = 7.8664467\6.8423613\8.2001266 {p 4} Obtain distances between A und B locations in kilometres using {cmd:hav_dist()}: {cmd::} hav_dist(lat_a, lng_a, lat_b, lng_b) {res} {txt} 1 2 3 {c TLC}{hline 43}{c TRC} 1 {c |} {res} 15.99849446 229.3229587 15.31791198 {c |} 2 {c |} {res} 26.55005308 241.9975468 5.622063328 {c |} {c BLC}{hline 43}{c BRC} {p 4} Obtain distances in miles with user-specified radius of 3960 miles using {cmd:hav_distm()}: {cmd::} rd = 3960 {cmd::} hav_distm(lat_a, lng_a, lat_b, lng_b, rd) {res} {txt} 1 2 3 {c TLC}{hline 43}{c TRC} 1 {c |} {res} 9.944127774 142.5394627 9.521100523 {c |} 2 {c |} {res} 16.50262285 150.4175617 3.494486074 {c |} {c BLC}{hline 43}{c BRC} {p 4} Generate a matrix indicating which B locations are within a 25km range of the A locations using {cmd:hav_inrange()}: {cmd::} rn = 25 {cmd::} hav_inrange(lat_a, lng_a, lat_b, lng_b, rn) {res} {txt} 1 2 3 {c TLC}{hline 15}{c TRC} 1 {c |} {res} 1 0 1 {c |} 2 {c |} {res} 0 0 1 {c |} {c BLC}{hline 15}{c BRC} {p 4} Generate a column vector containing the number of B locations that are within a 25km range of the A locations using {cmd:hav_ninrange()}: {cmd::} hav_mindist(lat_a, lng_a, lat_b, lng_b, rn) {res} {txt} 1 {c TLC}{hline 7}{c TRC} 1 {c |} {res} 2 {c |} 2 {c |} {res} 1 {c |} {c BLC}{hline 7}{c BRC} {title:Conformability} {cmd:hav_dist(}{it:lat_a}{cmd:,} {it:lng_a}{cmd:,} {cmd:lat_b}{cmd:,} {cmd:lng_b} [{cmd:,} {cmd:rd}]{cmd:)}: {it:lat_a}: {it:n x} 1 {it:lng_a}: {it:n x} 1 {it:lat_b}: {it:k x} 1 {it:lng_b}: {it:k x} 1 {it:rd}: 1 {it:x} 1 {it:result}: {it:n x k}. {cmd:hav_distm()} is analogue {cmd:hav_inrange(}{it:lat_a}{cmd:,} {it:lng_a}{cmd:,} {cmd:lat_b}{cmd:,} {cmd:lng_b}{cmd:,} {cmd:rn} [{cmd:,} {cmd:rd}]{cmd:)}: {it:lat_a}: {it:n x} 1 {it:lng_a}: {it:n x} 1 {it:lat_b}: {it:k x} 1 {it:lng_b}: {it:k x} 1 {it:rn}: 1 {it:x} 1 {it:rd}: 1 {it:x} 1 {it:result}: {it:n x k}. {cmd:hav_inrangem()} is analogue {cmd:hav_ninrange(}{it:lat_a}{cmd:,} {it:lng_a}{cmd:,} {cmd:lat_b}{cmd:,} {cmd:lng_b}{cmd:,} {cmd:rn} [{cmd:,} {cmd:rd}]{cmd:)}: {it:lat_a}: {it:n x} 1 {it:lng_a}: {it:n x} 1 {it:lat_a}: {it:k x} 1 {it:lng_a}: {it:k x} 1 {it:rn}: 1 {it:x} 1 {it:rd}: 1 {it:x} 1 {it:result}: {it:n x} 1. {cmd:hav_ninrangem()} is analogue {title:Author} {pstd} Lars Zeigermann, {browse "mailto:lars.zeigermann@posteo.de":lars.zeigermann@posteo.de} {title:Acknowledgment} {pstd} {cmd:lhaversine} is based on {cmd:geodist} written bei Robert Picard und reuses some of its code. {pstd}