ad 2) Rozwiązania są, ale nie spotkałem w pełni darmowych i
wydajnych. Sam to kiedyś robiłem i dziś nawet mi przyszło nieco kombinować z aktualizacją jednego z nich.
Najprościej jest użyć google maps i ich API, ale ilość żądań zapewne po jakimś czasie dojdzie do limitów (
http://googlegeodevelopers.blogspot.com/20...ts-to-maps.html ).
Trudniej nieco, ale da sie to obejść, poprzez stworzenie własnego "środowiska" bazując na ogólnodostępnych danych. Jako startowe zassij dane z GUSowskiej bazy miejscowości (słowo kluczowe TERYT). Niestety trwa to troszkę i powstanie Ci (jeśli wybierzesz tylko miasta i wsie) baza około 43 tysięcy rekordów. Niestety bez współrzędnych. Tutaj wchodzi w grę geolokalizacja. Niestety
licencja stawia sprawę jasno: limit 2500 żądań na dobę i muszą te dane być wyświetlone na mapie. Każde inne wykorzystanie jest przez licencję
zabronione (to uwaga dla Ilware). Co nie oznacza, że nie możemy tego wykorzystać mimo wszystko ;) Pamiętajmy, że skoro czegoś szukamy to spodziewamy się wyników z naszej bazy. Wystarczy więc, że tak napiszemy skrypt wyświetlający, by odwołań do geokodowania było jak najmniej. Jak to osiągnąć? Prosto. Część tego co robi gmaps przerzućmy na nasz serwis i jego bazę. Starajmy się już na starcie uzupełnić bazę danych o tyle wyników ze znanymi współrzędnymi, na ile to możliwe, poprzez sprawdzenie, czy wyświetlana rzecz ma swoje współrzędne w bazie, czy może dopiero ma pociągnąć je z google, jeśli to zrobi, zapiszmy te współrzędne w bazie.
Nie będzie musiało robić tego za każdym razem i nie łamiemy licencji. Dane SĄ bowiem wyświetlane, ale dodatkowo zebrane informacje zapamiętujemy w bazie by nie ciągnąc ich ponownie i tym samym zmniejszamy stopniowo ilość żądań geokodowania dając sobie większy margines na nieoczekiwane skoki ilości żądań.
Dzięki temu budujemy bazę współrzednych miejscowości po stronie naszego serwera. Z czasem bedziemy mieli wysokie pokrycie i geokodowanie stanie się naprawdę sporadyczne. Teraz czas na trudniejszą rzecz... Trzeba zastąpić algorytm google na swój własny. Kwestia najważniejsza to zdefiniowanie odległości. Pamiętajmy, że ziemia to kula, choć na małych (w stosunku do jej promienia) odległościach można to, do pewnego stopnia, pominąć i przyjąć zwykłą definicję odległości. Wciąż jednak obliczanie go na podstawie pierwiastka z sumy kwadratów różnic współrzędnych (skonwertowanych na kilometry) w locie dla każdego miasta z tym znanym to dość duże ilości obliczeń i jednak jedziemy ostro po silniku bazy.
Nawet jeśli nie będzie ich początkowo dużo, to z czasem duże pokrycie sprawi, że liczba ta osiągnie bez problemu 30-40 tysięcy. Zapytanie obliczające dla
każdego rekordy w bazie odległośc to
nie jest wydajne rozwiązanie.
Można jednak sobie sprawę bardzo uprościć ale, niestety, kosztem dokładności. Wystarczy znać współrzędne miasta głównego i obliczyć współrzędne granic obszaru, tworząc prostokąt lub kwadrat, w którego centrum jest miasto względem którego szukamy. Takie zapytanie, gdzie będziemy znali zakres szerokości i długości geograficznych, powinno już być całkiem wydajne. Bo to tylko prosty warunek WHERE lat IN (latStart, latEnd) AND lng IN (lngStart, lngEnd) ;)