Skip to content
This repository was archived by the owner on Jun 1, 2022. It is now read-only.

Commit b2c2ad6

Browse files
committed
Validate latitude/longitude on Locations by reverse geocoding
Uses: https://github.com/thampiman/reverse-geocoder
1 parent ce0fe4d commit b2c2ad6

File tree

4 files changed

+70
-2
lines changed

4 files changed

+70
-2
lines changed

requirements.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,6 @@ google-cloud-storage
9898

9999
# Metrics reporting
100100
prometheus_client
101+
102+
# Reverse Geocoding for validating lat/lng
103+
reverse_geocoder

requirements.txt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,34 @@ mypy-extensions==0.4.3 \
422422
# via
423423
# black
424424
# typing-inspect
425+
numpy==1.20.2 \
426+
--hash=sha256:2428b109306075d89d21135bdd6b785f132a1f5a3260c371cee1fae427e12727 \
427+
--hash=sha256:377751954da04d4a6950191b20539066b4e19e3b559d4695399c5e8e3e683bf6 \
428+
--hash=sha256:4703b9e937df83f5b6b7447ca5912b5f5f297aba45f91dbbbc63ff9278c7aa98 \
429+
--hash=sha256:471c0571d0895c68da309dacee4e95a0811d0a9f9f532a48dc1bea5f3b7ad2b7 \
430+
--hash=sha256:61d5b4cf73622e4d0c6b83408a16631b670fc045afd6540679aa35591a17fe6d \
431+
--hash=sha256:6c915ee7dba1071554e70a3664a839fbc033e1d6528199d4621eeaaa5487ccd2 \
432+
--hash=sha256:6e51e417d9ae2e7848314994e6fc3832c9d426abce9328cf7571eefceb43e6c9 \
433+
--hash=sha256:719656636c48be22c23641859ff2419b27b6bdf844b36a2447cb39caceb00935 \
434+
--hash=sha256:780ae5284cb770ade51d4b4a7dce4faa554eb1d88a56d0e8b9f35fca9b0270ff \
435+
--hash=sha256:878922bf5ad7550aa044aa9301d417e2d3ae50f0f577de92051d739ac6096cee \
436+
--hash=sha256:924dc3f83de20437de95a73516f36e09918e9c9c18d5eac520062c49191025fb \
437+
--hash=sha256:97ce8b8ace7d3b9288d88177e66ee75480fb79b9cf745e91ecfe65d91a856042 \
438+
--hash=sha256:9c0fab855ae790ca74b27e55240fe4f2a36a364a3f1ebcfd1fb5ac4088f1cec3 \
439+
--hash=sha256:9cab23439eb1ebfed1aaec9cd42b7dc50fc96d5cd3147da348d9161f0501ada5 \
440+
--hash=sha256:a8e6859913ec8eeef3dbe9aed3bf475347642d1cdd6217c30f28dee8903528e6 \
441+
--hash=sha256:aa046527c04688af680217fffac61eec2350ef3f3d7320c07fd33f5c6e7b4d5f \
442+
--hash=sha256:abc81829c4039e7e4c30f7897938fa5d4916a09c2c7eb9b244b7a35ddc9656f4 \
443+
--hash=sha256:bad70051de2c50b1a6259a6df1daaafe8c480ca98132da98976d8591c412e737 \
444+
--hash=sha256:c73a7975d77f15f7f68dacfb2bca3d3f479f158313642e8ea9058eea06637931 \
445+
--hash=sha256:d15007f857d6995db15195217afdbddfcd203dfaa0ba6878a2f580eaf810ecd6 \
446+
--hash=sha256:d76061ae5cab49b83a8cf3feacefc2053fac672728802ac137dd8c4123397677 \
447+
--hash=sha256:e8e4fbbb7e7634f263c5b0150a629342cc19b47c5eba8d1cd4363ab3455ab576 \
448+
--hash=sha256:e9459f40244bb02b2f14f6af0cd0732791d72232bbb0dc4bab57ef88e75f6935 \
449+
--hash=sha256:edb1f041a9146dcf02cd7df7187db46ab524b9af2515f392f337c7cbbf5b52cd
450+
# via
451+
# reverse-geocoder
452+
# scipy
425453
oauthlib==3.1.0 \
426454
--hash=sha256:bee41cc35fcca6e988463cacc3bcb8a96224f470ca547e697b604cc697b2f889 \
427455
--hash=sha256:df884cd6cbe20e32633f1db1072e9356f53638e4361bef4e8b03c9127c9328ea
@@ -731,6 +759,9 @@ requests==2.25.1 \
731759
# requests-mock
732760
# requests-oauthlib
733761
# social-auth-core
762+
reverse-geocoder==1.5.1 \
763+
--hash=sha256:2a2e781b5f69376d922b78fe8978f1350c84fce0ddb07e02c834ecf98b57c75c
764+
# via -r requirements.in
734765
rfc3986[idna2008]==1.4.0 \
735766
--hash=sha256:112398da31a3344dc25dbf477d8df6cb34f9278a94fee2625d89e4514be8bb9d \
736767
--hash=sha256:af9147e9aceda37c91a05f4deb128d4b4b49d6b199775fd2d2927768abdc8f50
@@ -741,6 +772,27 @@ rsa==4.7.2 \
741772
# via
742773
# google-auth
743774
# python-jose
775+
scipy==1.6.2 \
776+
--hash=sha256:03f1fd3574d544456325dae502facdf5c9f81cbfe12808a5e67a737613b7ba8c \
777+
--hash=sha256:0c81ea1a95b4c9e0a8424cf9484b7b8fa7ef57169d7bcc0dfcfc23e3d7c81a12 \
778+
--hash=sha256:1fba8a214c89b995e3721670e66f7053da82e7e5d0fe6b31d8e4b19922a9315e \
779+
--hash=sha256:37f4c2fb904c0ba54163e03993ce3544c9c5cde104bcf90614f17d85bdfbb431 \
780+
--hash=sha256:50e5bcd9d45262725e652611bb104ac0919fd25ecb78c22f5282afabd0b2e189 \
781+
--hash=sha256:6ca1058cb5bd45388041a7c3c11c4b2bd58867ac9db71db912501df77be2c4a4 \
782+
--hash=sha256:77f7a057724545b7e097bfdca5c6006bed8580768cd6621bb1330aedf49afba5 \
783+
--hash=sha256:816951e73d253a41fa2fd5f956f8e8d9ac94148a9a2039e7db56994520582bf2 \
784+
--hash=sha256:96620240b393d155097618bcd6935d7578e85959e55e3105490bbbf2f594c7ad \
785+
--hash=sha256:993c86513272bc84c451349b10ee4376652ab21f312b0554fdee831d593b6c02 \
786+
--hash=sha256:adf7cee8e5c92b05f2252af498f77c7214a2296d009fc5478fc432c2f8fb953b \
787+
--hash=sha256:bc52d4d70863141bb7e2f8fd4d98e41d77375606cde50af65f1243ce2d7853e8 \
788+
--hash=sha256:c1d3f771c19af00e1a36f749bd0a0690cc64632783383bc68f77587358feb5a4 \
789+
--hash=sha256:d744657c27c128e357de2f0fd532c09c84cd6e4933e8232895a872e67059ac37 \
790+
--hash=sha256:e3e9742bad925c421d39e699daa8d396c57535582cba90017d17f926b61c1552 \
791+
--hash=sha256:e547f84cd52343ac2d56df0ab08d3e9cc202338e7d09fafe286d6c069ddacb31 \
792+
--hash=sha256:e89091e6a8e211269e23f049473b2fde0c0e5ae0dd5bd276c3fc91b97da83480 \
793+
--hash=sha256:e9da33e21c9bc1b92c20b5328adb13e5f193b924c9b969cd700c8908f315aa59 \
794+
--hash=sha256:ffdfb09315896c6e9ac739bb6e13a19255b698c24e6b28314426fd40a1180822
795+
# via reverse-geocoder
744796
sentry-sdk==1.0.0 \
745797
--hash=sha256:71de00c9711926816f750bc0f57ef2abbcb1bfbdf5378c601df7ec978f44857a \
746798
--hash=sha256:9221e985f425913204989d0e0e1cbb719e8b7fa10540f1bc509f660c06a34e66

vaccinate/core/models.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
import beeline
55
import pytz
6+
import reverse_geocoder
67
from django.conf import settings
8+
from django.core.exceptions import ValidationError
79
from django.db import models
810
from django.db.models import Max, Q
911
from django.db.models.signals import m2m_changed
@@ -422,6 +424,17 @@ def save(self, *args, **kwargs):
422424
if set_public_id_later:
423425
Location.objects.filter(pk=self.pk).update(public_id=self.pid)
424426

427+
def clean(self):
428+
results = reverse_geocoder.search((self.latitude, self.longitude))
429+
if len(results) == 0:
430+
raise ValidationError(
431+
"Couldn't reverse lookup that latitude and longitude!"
432+
)
433+
elif results[0]["admin1"] != self.state.name:
434+
raise ValidationError(
435+
f"That latitude and longitide are not in {self.state.name}!"
436+
)
437+
425438

426439
class Reporter(models.Model):
427440
"""

vaccinate/core/test_admin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ def test_admin_create_location_sets_public_id(admin_client):
2424
"name": "hello",
2525
"state": State.objects.get(abbreviation="OR").id,
2626
"location_type": "1",
27-
"latitude": "0",
28-
"longitude": "0",
27+
"latitude": "45.518941976546756",
28+
"longitude": "-122.70686202698961",
2929
"_save": "Save",
3030
},
3131
)

0 commit comments

Comments
 (0)