He intentado utilizar el código anterior, y las respuestas estaban fuera por el exceso cuando la distancia entre los puntos estaba en el rango de 20-30 millas, y yo estoy bien con unas pocas millas de error. Hablé con un compañero de mapas mío y en su lugar creamos este. El código es python, pero puedes traducirlo con bastante facilidad. Para evitar la conversión constante a radianes, rehice mi base de datos, convirtiendo los puntos lat/lng de grados a radianes. La parte buena de esto es que la mayor parte de las matemáticas se realiza principalmente una vez.
ra = 3963.1906 # radius @ equator in miles, change to km if you want distance in km
rb = 3949.90275 # radius @ poles in miles, change to km if you want distance in km
ra2 = ra * ra
rb2 = rb * rb
phi = self.lat
big_ol_constant = (math.pow(ra2*math.cos(phi), 2) + pow(rb2*math.sin(phi), 2))/ (pow(ra*math.cos(phi), 2) + pow(rb*math.sin(phi), 2))
sqlWhere = "%(distance)g > sqrt((power(lat - %(lat)g,2) + power(lng-%(lng)g,2)) * %(big_ol_constant)g)" % {
'big_ol_constant': big_ol_constant, 'lat': self.lat, 'lng': self.lng, 'distance': distance}
# This is the Django portion of it, where the ORM kicks in. sqlWhere is what you would put after the WHERE part of your SQL Query.
qs = ZipData.objects.extra(where=[sqlWhere]);
Parece ser muy preciso cuando se distancia de separación es pequeña, y dentro de 10 millas más o menos como la distancia crece a 200 millas, (por supuesto, para entonces, usted tiene problemas con "a vuelo de pájaro" vs " caminos pavimentados ").
Aquí es el modelo ZipData que menciono arriba.
class ZipData(models.Model):
zipcode = ZipCodeField(null=False, blank=False, verbose_name="ZipCode", primary_key=True)
city = models.CharField(max_length=32, null=False, blank=False)
state = models.CharField(max_length=2)
lat = models.FloatField(null=False, blank=False)
lng = models.FloatField(null=False, blank=False)
una nota extra, es que se puede recibe gran cantidad de datos geográficos relacionados con los códigos postales en GeoNames.org e incluso tienen algunas API de servicio web que puede utilizar también.
siempre podría obtener la función usted mismo ... esto parece cálculo de nivel de secundaria, o incluso trigonometría si realmente lo simplifica ... – rmeador
Pensaría que sí, pero la Tierra no es una esfera perfecta, y la variación entre 1 grado de longitud en el ecuador y 1 grado de longitud en otro lugar es sorprendentemente grande. ¡Definitivamente no es tan simple como uno esperaría! –
(vea mi respuesta a continuación :)) –